1 2 /* 3 * Copyright 2012 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "gl/GrGLInterface.h" 11 #include "GrDebugGL.h" 12 #include "GrShaderObj.h" 13 #include "GrProgramObj.h" 14 #include "GrBufferObj.h" 15 #include "GrTextureUnitObj.h" 16 #include "GrTextureObj.h" 17 #include "GrFrameBufferObj.h" 18 #include "GrRenderBufferObj.h" 19 #include "GrVertexArrayObj.h" 20 #include "SkFloatingPoint.h" 21 #include "../GrGLNoOpInterface.h" 22 23 namespace { // suppress no previous prototype warning 24 25 //////////////////////////////////////////////////////////////////////////////// 26 GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) { 27 28 // Ganesh offsets the texture unit indices 29 texture -= GR_GL_TEXTURE0; 30 GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits()); 31 32 GrDebugGL::getInstance()->setCurTextureUnit(texture); 33 } 34 35 //////////////////////////////////////////////////////////////////////////////// 36 GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, 37 GrGLuint shaderID) { 38 39 GrProgramObj *program = GR_FIND(programID, GrProgramObj, 40 GrDebugGL::kProgram_ObjTypes); 41 GrAlwaysAssert(program); 42 43 GrShaderObj *shader = GR_FIND(shaderID, 44 GrShaderObj, 45 GrDebugGL::kShader_ObjTypes); 46 GrAlwaysAssert(shader); 47 48 program->AttachShader(shader); 49 } 50 51 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) { 52 } 53 54 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, 55 GrGLuint index, 56 const char* name) { 57 } 58 59 //////////////////////////////////////////////////////////////////////////////// 60 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, 61 GrGLuint textureID) { 62 63 // we don't use cube maps 64 GrAlwaysAssert(target == GR_GL_TEXTURE_2D); 65 // || target == GR_GL_TEXTURE_CUBE_MAP); 66 67 // a textureID of 0 is acceptable - it binds to the default texture target 68 GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, 69 GrDebugGL::kTexture_ObjTypes); 70 71 GrDebugGL::getInstance()->setTexture(texture); 72 } 73 74 75 //////////////////////////////////////////////////////////////////////////////// 76 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target, 77 GrGLsizeiptr size, 78 const GrGLvoid* data, 79 GrGLenum usage) { 80 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 81 GR_GL_ELEMENT_ARRAY_BUFFER == target); 82 GrAlwaysAssert(size >= 0); 83 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || 84 GR_GL_STATIC_DRAW == usage || 85 GR_GL_DYNAMIC_DRAW == usage); 86 87 GrBufferObj *buffer = nullptr; 88 switch (target) { 89 case GR_GL_ARRAY_BUFFER: 90 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 91 break; 92 case GR_GL_ELEMENT_ARRAY_BUFFER: 93 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 94 break; 95 default: 96 SkFAIL("Unexpected target to glBufferData"); 97 break; 98 } 99 100 GrAlwaysAssert(buffer); 101 GrAlwaysAssert(buffer->getBound()); 102 103 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); 104 buffer->setUsage(usage); 105 } 106 107 108 GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, 109 GrGLint param) { 110 111 switch (pname) { 112 case GR_GL_UNPACK_ROW_LENGTH: 113 GrDebugGL::getInstance()->setUnPackRowLength(param); 114 break; 115 case GR_GL_PACK_ROW_LENGTH: 116 GrDebugGL::getInstance()->setPackRowLength(param); 117 break; 118 case GR_GL_UNPACK_ALIGNMENT: 119 break; 120 case GR_GL_PACK_ALIGNMENT: 121 GrAlwaysAssert(false); 122 break; 123 default: 124 GrAlwaysAssert(false); 125 break; 126 } 127 } 128 129 GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, 130 GrGLint y, 131 GrGLsizei width, 132 GrGLsizei height, 133 GrGLenum format, 134 GrGLenum type, 135 GrGLvoid* pixels) { 136 137 GrGLint pixelsInRow = width; 138 if (0 < GrDebugGL::getInstance()->getPackRowLength()) { 139 pixelsInRow = GrDebugGL::getInstance()->getPackRowLength(); 140 } 141 142 GrGLint componentsPerPixel = 0; 143 144 switch (format) { 145 case GR_GL_RGBA: 146 // fallthrough 147 case GR_GL_BGRA: 148 componentsPerPixel = 4; 149 break; 150 case GR_GL_RGB: 151 componentsPerPixel = 3; 152 break; 153 case GR_GL_RED: 154 componentsPerPixel = 1; 155 break; 156 default: 157 GrAlwaysAssert(false); 158 break; 159 } 160 161 GrGLint alignment = 4; // the pack alignment (one of 1, 2, 4 or 8) 162 // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT 163 164 GrGLint componentSize = 0; // size (in bytes) of a single component 165 166 switch (type) { 167 case GR_GL_UNSIGNED_BYTE: 168 componentSize = 1; 169 break; 170 default: 171 GrAlwaysAssert(false); 172 break; 173 } 174 175 GrGLint rowStride = 0; // number of components (not bytes) to skip 176 if (componentSize >= alignment) { 177 rowStride = componentsPerPixel * pixelsInRow; 178 } else { 179 float fTemp = 180 sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / 181 static_cast<float>(alignment)); 182 rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); 183 } 184 185 GrGLchar *scanline = static_cast<GrGLchar *>(pixels); 186 for (int y = 0; y < height; ++y) { 187 memset(scanline, 0, componentsPerPixel * componentSize * width); 188 scanline += rowStride; 189 } 190 } 191 192 GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) { 193 194 // A programID of 0 is legal 195 GrProgramObj *program = GR_FIND(programID, 196 GrProgramObj, 197 GrDebugGL::kProgram_ObjTypes); 198 199 GrDebugGL::getInstance()->useProgram(program); 200 } 201 202 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, 203 GrGLuint frameBufferID) { 204 205 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || 206 GR_GL_READ_FRAMEBUFFER == target || 207 GR_GL_DRAW_FRAMEBUFFER); 208 209 // a frameBufferID of 0 is acceptable - it binds to the default 210 // frame buffer 211 GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID, 212 GrFrameBufferObj, 213 GrDebugGL::kFrameBuffer_ObjTypes); 214 215 GrDebugGL::getInstance()->setFrameBuffer(frameBuffer); 216 } 217 218 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) { 219 220 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 221 222 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer 223 GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID, 224 GrRenderBufferObj, 225 GrDebugGL::kRenderBuffer_ObjTypes); 226 227 GrDebugGL::getInstance()->setRenderBuffer(renderBuffer); 228 } 229 230 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) { 231 232 // first potentially unbind the texture 233 // TODO: move this into GrDebugGL as unBindTexture? 234 for (unsigned int i = 0; 235 i < GrDebugGL::getInstance()->getMaxTextureUnits(); 236 ++i) { 237 GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i); 238 239 if (pTU->getTexture()) { 240 for (int j = 0; j < n; ++j) { 241 242 if (textures[j] == pTU->getTexture()->getID()) { 243 // this ID is the current texture - revert the binding to 0 244 pTU->setTexture(nullptr); 245 } 246 } 247 } 248 } 249 250 // TODO: fuse the following block with DeleteRenderBuffers? 251 // Open GL will remove a deleted render buffer from the active 252 // frame buffer but not from any other frame buffer 253 if (GrDebugGL::getInstance()->getFrameBuffer()) { 254 255 GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer(); 256 257 for (int i = 0; i < n; ++i) { 258 259 if (frameBuffer->getColor() && 260 textures[i] == frameBuffer->getColor()->getID()) { 261 frameBuffer->setColor(nullptr); 262 } 263 if (frameBuffer->getDepth() && 264 textures[i] == frameBuffer->getDepth()->getID()) { 265 frameBuffer->setDepth(nullptr); 266 } 267 if (frameBuffer->getStencil() && 268 textures[i] == frameBuffer->getStencil()->getID()) { 269 frameBuffer->setStencil(nullptr); 270 } 271 } 272 } 273 274 // then actually "delete" the buffers 275 for (int i = 0; i < n; ++i) { 276 GrTextureObj *buffer = GR_FIND(textures[i], 277 GrTextureObj, 278 GrDebugGL::kTexture_ObjTypes); 279 GrAlwaysAssert(buffer); 280 281 // OpenGL gives no guarantees if a texture is deleted while attached to 282 // something other than the currently bound frame buffer 283 GrAlwaysAssert(!buffer->getBound()); 284 285 GrAlwaysAssert(!buffer->getDeleted()); 286 buffer->deleteAction(); 287 } 288 289 } 290 291 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, 292 const GrGLuint *frameBuffers) { 293 294 // first potentially unbind the buffers 295 if (GrDebugGL::getInstance()->getFrameBuffer()) { 296 for (int i = 0; i < n; ++i) { 297 298 if (frameBuffers[i] == 299 GrDebugGL::getInstance()->getFrameBuffer()->getID()) { 300 // this ID is the current frame buffer - rebind to the default 301 GrDebugGL::getInstance()->setFrameBuffer(nullptr); 302 } 303 } 304 } 305 306 // then actually "delete" the buffers 307 for (int i = 0; i < n; ++i) { 308 GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i], 309 GrFrameBufferObj, 310 GrDebugGL::kFrameBuffer_ObjTypes); 311 GrAlwaysAssert(buffer); 312 313 GrAlwaysAssert(!buffer->getDeleted()); 314 buffer->deleteAction(); 315 } 316 } 317 318 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, 319 const GrGLuint *renderBuffers) { 320 321 // first potentially unbind the buffers 322 if (GrDebugGL::getInstance()->getRenderBuffer()) { 323 for (int i = 0; i < n; ++i) { 324 325 if (renderBuffers[i] == 326 GrDebugGL::getInstance()->getRenderBuffer()->getID()) { 327 // this ID is the current render buffer - make no 328 // render buffer be bound 329 GrDebugGL::getInstance()->setRenderBuffer(nullptr); 330 } 331 } 332 } 333 334 // TODO: fuse the following block with DeleteTextures? 335 // Open GL will remove a deleted render buffer from the active frame 336 // buffer but not from any other frame buffer 337 if (GrDebugGL::getInstance()->getFrameBuffer()) { 338 339 GrFrameBufferObj *frameBuffer = 340 GrDebugGL::getInstance()->getFrameBuffer(); 341 342 for (int i = 0; i < n; ++i) { 343 344 if (frameBuffer->getColor() && 345 renderBuffers[i] == frameBuffer->getColor()->getID()) { 346 frameBuffer->setColor(nullptr); 347 } 348 if (frameBuffer->getDepth() && 349 renderBuffers[i] == frameBuffer->getDepth()->getID()) { 350 frameBuffer->setDepth(nullptr); 351 } 352 if (frameBuffer->getStencil() && 353 renderBuffers[i] == frameBuffer->getStencil()->getID()) { 354 frameBuffer->setStencil(nullptr); 355 } 356 } 357 } 358 359 // then actually "delete" the buffers 360 for (int i = 0; i < n; ++i) { 361 GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i], 362 GrRenderBufferObj, 363 GrDebugGL::kRenderBuffer_ObjTypes); 364 GrAlwaysAssert(buffer); 365 366 // OpenGL gives no guarantees if a render buffer is deleted 367 // while attached to something other than the currently 368 // bound frame buffer 369 GrAlwaysAssert(!buffer->getColorBound()); 370 GrAlwaysAssert(!buffer->getDepthBound()); 371 // However, at GrContext destroy time we release all GrRsources and so stencil buffers 372 // may get deleted before FBOs that refer to them. 373 //GrAlwaysAssert(!buffer->getStencilBound()); 374 375 GrAlwaysAssert(!buffer->getDeleted()); 376 buffer->deleteAction(); 377 } 378 } 379 380 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, 381 GrGLenum attachment, 382 GrGLenum renderbuffertarget, 383 GrGLuint renderBufferID) { 384 385 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 386 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 387 GR_GL_DEPTH_ATTACHMENT == attachment || 388 GR_GL_STENCIL_ATTACHMENT == attachment); 389 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); 390 391 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); 392 // A render buffer cannot be attached to the default framebuffer 393 GrAlwaysAssert(framebuffer); 394 395 // a renderBufferID of 0 is acceptable - it unbinds the current 396 // render buffer 397 GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID, 398 GrRenderBufferObj, 399 GrDebugGL::kRenderBuffer_ObjTypes); 400 401 switch (attachment) { 402 case GR_GL_COLOR_ATTACHMENT0: 403 framebuffer->setColor(renderbuffer); 404 break; 405 case GR_GL_DEPTH_ATTACHMENT: 406 framebuffer->setDepth(renderbuffer); 407 break; 408 case GR_GL_STENCIL_ATTACHMENT: 409 framebuffer->setStencil(renderbuffer); 410 break; 411 default: 412 GrAlwaysAssert(false); 413 break; 414 }; 415 416 } 417 418 //////////////////////////////////////////////////////////////////////////////// 419 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, 420 GrGLenum attachment, 421 GrGLenum textarget, 422 GrGLuint textureID, 423 GrGLint level) { 424 425 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 426 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 427 GR_GL_DEPTH_ATTACHMENT == attachment || 428 GR_GL_STENCIL_ATTACHMENT == attachment); 429 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); 430 431 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); 432 // A texture cannot be attached to the default framebuffer 433 GrAlwaysAssert(framebuffer); 434 435 // A textureID of 0 is allowed - it unbinds the currently bound texture 436 GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, 437 GrDebugGL::kTexture_ObjTypes); 438 if (texture) { 439 // The texture shouldn't be bound to a texture unit - this 440 // could lead to a feedback loop 441 GrAlwaysAssert(!texture->getBound()); 442 } 443 444 GrAlwaysAssert(0 == level); 445 446 switch (attachment) { 447 case GR_GL_COLOR_ATTACHMENT0: 448 framebuffer->setColor(texture); 449 break; 450 case GR_GL_DEPTH_ATTACHMENT: 451 framebuffer->setDepth(texture); 452 break; 453 case GR_GL_STENCIL_ATTACHMENT: 454 framebuffer->setStencil(texture); 455 break; 456 default: 457 GrAlwaysAssert(false); 458 break; 459 }; 460 } 461 462 GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() { 463 464 GrProgramObj *program = GR_CREATE(GrProgramObj, 465 GrDebugGL::kProgram_ObjTypes); 466 467 return program->getID(); 468 } 469 470 GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) { 471 472 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || 473 GR_GL_FRAGMENT_SHADER == type); 474 475 GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes); 476 shader->setType(type); 477 478 return shader->getID(); 479 } 480 481 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) { 482 483 GrProgramObj *program = GR_FIND(programID, 484 GrProgramObj, 485 GrDebugGL::kProgram_ObjTypes); 486 GrAlwaysAssert(program); 487 488 if (program->getRefCount()) { 489 // someone is still using this program so we can't delete it here 490 program->setMarkedForDeletion(); 491 } else { 492 program->deleteAction(); 493 } 494 } 495 496 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) { 497 498 GrShaderObj *shader = GR_FIND(shaderID, 499 GrShaderObj, 500 GrDebugGL::kShader_ObjTypes); 501 GrAlwaysAssert(shader); 502 503 if (shader->getRefCount()) { 504 // someone is still using this shader so we can't delete it here 505 shader->setMarkedForDeletion(); 506 } else { 507 shader->deleteAction(); 508 } 509 } 510 511 GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type, 512 GrGLsizei n, 513 GrGLuint* ids) { 514 515 for (int i = 0; i < n; ++i) { 516 GrAlwaysAssert(ids[i] == 0); 517 GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type); 518 GrAlwaysAssert(obj); 519 ids[i] = obj->getID(); 520 } 521 } 522 523 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) { 524 debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids); 525 } 526 527 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenerateMipmap(GrGLenum level) { 528 } 529 530 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, 531 GrGLuint* ids) { 532 debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids); 533 } 534 535 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, 536 GrGLuint* ids) { 537 debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids); 538 } 539 540 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) { 541 debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids); 542 } 543 544 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenVertexArrays(GrGLsizei n, GrGLuint* ids) { 545 debugGenObjs(GrDebugGL::kVertexArray_ObjTypes, n, ids); 546 } 547 548 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteVertexArrays(GrGLsizei n, const GrGLuint* ids) { 549 for (GrGLsizei i = 0; i < n; ++i) { 550 GrVertexArrayObj* array = 551 GR_FIND(ids[i], GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 552 GrAlwaysAssert(array); 553 554 // Deleting the current vertex array binds object 0 555 if (GrDebugGL::getInstance()->getVertexArray() == array) { 556 GrDebugGL::getInstance()->setVertexArray(nullptr); 557 } 558 559 if (array->getRefCount()) { 560 // someone is still using this vertex array so we can't delete it here 561 array->setMarkedForDeletion(); 562 } else { 563 array->deleteAction(); 564 } 565 } 566 } 567 568 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) { 569 GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 570 GrAlwaysAssert((0 == id) || array); 571 GrDebugGL::getInstance()->setVertexArray(array); 572 } 573 574 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) { 575 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); 576 577 GrBufferObj *buffer = GR_FIND(bufferID, 578 GrBufferObj, 579 GrDebugGL::kBuffer_ObjTypes); 580 // 0 is a permissible bufferID - it unbinds the current buffer 581 582 switch (target) { 583 case GR_GL_ARRAY_BUFFER: 584 GrDebugGL::getInstance()->setArrayBuffer(buffer); 585 break; 586 case GR_GL_ELEMENT_ARRAY_BUFFER: 587 GrDebugGL::getInstance()->setElementArrayBuffer(buffer); 588 break; 589 default: 590 SkFAIL("Unexpected target to glBindBuffer"); 591 break; 592 } 593 } 594 595 // deleting a bound buffer has the side effect of binding 0 596 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) { 597 // first potentially unbind the buffers 598 for (int i = 0; i < n; ++i) { 599 600 if (GrDebugGL::getInstance()->getArrayBuffer() && 601 ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) { 602 // this ID is the current array buffer 603 GrDebugGL::getInstance()->setArrayBuffer(nullptr); 604 } 605 if (GrDebugGL::getInstance()->getElementArrayBuffer() && 606 ids[i] == 607 GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) { 608 // this ID is the current element array buffer 609 GrDebugGL::getInstance()->setElementArrayBuffer(nullptr); 610 } 611 } 612 613 // then actually "delete" the buffers 614 for (int i = 0; i < n; ++i) { 615 GrBufferObj *buffer = GR_FIND(ids[i], 616 GrBufferObj, 617 GrDebugGL::kBuffer_ObjTypes); 618 GrAlwaysAssert(buffer); 619 620 GrAlwaysAssert(!buffer->getDeleted()); 621 buffer->deleteAction(); 622 } 623 } 624 625 // map a buffer to the caller's address space 626 GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBufferRange(GrGLenum target, GrGLintptr offset, 627 GrGLsizeiptr length, GrGLbitfield access) { 628 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 629 GR_GL_ELEMENT_ARRAY_BUFFER == target); 630 631 // We only expect read access and we expect that the buffer or range is always invalidated. 632 GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access)); 633 GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access); 634 635 GrBufferObj *buffer = nullptr; 636 switch (target) { 637 case GR_GL_ARRAY_BUFFER: 638 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 639 break; 640 case GR_GL_ELEMENT_ARRAY_BUFFER: 641 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 642 break; 643 default: 644 SkFAIL("Unexpected target to glMapBufferRange"); 645 break; 646 } 647 648 if (buffer) { 649 GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize()); 650 GrAlwaysAssert(!buffer->getMapped()); 651 buffer->setMapped(offset, length); 652 return buffer->getDataPtr() + offset; 653 } 654 655 GrAlwaysAssert(false); 656 return nullptr; // no buffer bound to the target 657 } 658 659 GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) { 660 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); 661 662 GrBufferObj *buffer = nullptr; 663 switch (target) { 664 case GR_GL_ARRAY_BUFFER: 665 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 666 break; 667 case GR_GL_ELEMENT_ARRAY_BUFFER: 668 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 669 break; 670 default: 671 SkFAIL("Unexpected target to glMapBuffer"); 672 break; 673 } 674 675 return debugGLMapBufferRange(target, 0, buffer->getSize(), 676 GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT); 677 } 678 679 // remove a buffer from the caller's address space 680 // TODO: check if the "access" method from "glMapBuffer" was honored 681 GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) { 682 683 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 684 GR_GL_ELEMENT_ARRAY_BUFFER == target); 685 686 GrBufferObj *buffer = nullptr; 687 switch (target) { 688 case GR_GL_ARRAY_BUFFER: 689 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 690 break; 691 case GR_GL_ELEMENT_ARRAY_BUFFER: 692 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 693 break; 694 default: 695 SkFAIL("Unexpected target to glUnmapBuffer"); 696 break; 697 } 698 699 if (buffer) { 700 GrAlwaysAssert(buffer->getMapped()); 701 buffer->resetMapped(); 702 return GR_GL_TRUE; 703 } 704 705 GrAlwaysAssert(false); 706 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; 707 } 708 709 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlushMappedBufferRange(GrGLenum target, 710 GrGLintptr offset, 711 GrGLsizeiptr length) { 712 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 713 GR_GL_ELEMENT_ARRAY_BUFFER == target); 714 715 GrBufferObj *buffer = nullptr; 716 switch (target) { 717 case GR_GL_ARRAY_BUFFER: 718 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 719 break; 720 case GR_GL_ELEMENT_ARRAY_BUFFER: 721 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 722 break; 723 default: 724 SkFAIL("Unexpected target to glUnmapBuffer"); 725 break; 726 } 727 728 if (buffer) { 729 GrAlwaysAssert(buffer->getMapped()); 730 GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength()); 731 } else { 732 GrAlwaysAssert(false); 733 } 734 } 735 736 737 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, 738 GrGLenum value, 739 GrGLint* params) { 740 741 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 742 GR_GL_ELEMENT_ARRAY_BUFFER == target); 743 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || 744 GR_GL_BUFFER_USAGE == value); 745 746 GrBufferObj *buffer = nullptr; 747 switch (target) { 748 case GR_GL_ARRAY_BUFFER: 749 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 750 break; 751 case GR_GL_ELEMENT_ARRAY_BUFFER: 752 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 753 break; 754 } 755 756 GrAlwaysAssert(buffer); 757 758 switch (value) { 759 case GR_GL_BUFFER_MAPPED: 760 *params = GR_GL_FALSE; 761 if (buffer) 762 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; 763 break; 764 case GR_GL_BUFFER_SIZE: 765 *params = 0; 766 if (buffer) 767 *params = SkToInt(buffer->getSize()); 768 break; 769 case GR_GL_BUFFER_USAGE: 770 *params = GR_GL_STATIC_DRAW; 771 if (buffer) 772 *params = buffer->getUsage(); 773 break; 774 default: 775 SkFAIL("Unexpected value to glGetBufferParamateriv"); 776 break; 777 } 778 }; 779 } // end of namespace 780 781 //////////////////////////////////////////////////////////////////////////////// 782 struct GrDebugGLInterface : public GrGLInterface { 783 784 public: 785 786 787 GrDebugGLInterface() 788 : fWrapped(nullptr) { 789 GrDebugGL::staticRef(); 790 } 791 792 virtual ~GrDebugGLInterface() { 793 GrDebugGL::staticUnRef(); 794 } 795 796 void setWrapped(GrGLInterface *interface) { 797 fWrapped.reset(interface); 798 } 799 800 void abandon() const override { 801 GrDebugGL::abandon(); 802 } 803 804 // TODO: there are some issues w/ wrapping another GL interface inside the 805 // debug interface: 806 // Since none of the "gl" methods are member functions they don't get 807 // a "this" pointer through which to access "fWrapped" 808 // This could be worked around by having all of them access the 809 // "glInterface" pointer - i.e., treating the debug interface as a 810 // true singleton 811 // 812 // The problem with this is that we also want to handle OpenGL 813 // contexts. The natural way to do this is to have multiple debug 814 // interfaces. Each of which represents a separate context. The 815 // static ID count would still uniquify IDs across all of them. 816 // The problem then is that we couldn't treat the debug GL 817 // interface as a singleton (since there would be one for each 818 // context). 819 // 820 // The solution to this is probably to alter SkDebugGlContext's 821 // "makeCurrent" method to make a call like "makeCurrent(this)" to 822 // the debug GL interface (assuming that the application will create 823 // multiple SkGLContext's) to let it switch between the active 824 // context. Everything in the GrDebugGL object would then need to be 825 // moved to a GrContextObj and the GrDebugGL object would just switch 826 // between them. Note that this approach would also require that 827 // SkDebugGLContext wrap an arbitrary other context 828 // and then pass the wrapped interface to the debug GL interface. 829 830 protected: 831 private: 832 833 SkAutoTUnref<GrGLInterface> fWrapped; 834 835 typedef GrGLInterface INHERITED; 836 }; 837 838 //////////////////////////////////////////////////////////////////////////////// 839 const GrGLInterface* GrGLCreateDebugInterface() { 840 GrGLInterface *interface = new GrDebugGLInterface; 841 842 interface->fStandard = kGL_GrGLStandard; 843 844 GrGLInterface::Functions* functions = &interface->fFunctions; 845 functions->fActiveTexture = debugGLActiveTexture; 846 functions->fAttachShader = debugGLAttachShader; 847 functions->fBeginQuery = debugGLBeginQuery; 848 functions->fBindAttribLocation = debugGLBindAttribLocation; 849 functions->fBindBuffer = debugGLBindBuffer; 850 functions->fBindFragDataLocation = noOpGLBindFragDataLocation; 851 functions->fBindTexture = debugGLBindTexture; 852 functions->fBindVertexArray = debugGLBindVertexArray; 853 functions->fBlendColor = noOpGLBlendColor; 854 functions->fBlendEquation = noOpGLBlendEquation; 855 functions->fBlendFunc = noOpGLBlendFunc; 856 functions->fBufferData = debugGLBufferData; 857 functions->fBufferSubData = noOpGLBufferSubData; 858 functions->fClear = noOpGLClear; 859 functions->fClearColor = noOpGLClearColor; 860 functions->fClearStencil = noOpGLClearStencil; 861 functions->fColorMask = noOpGLColorMask; 862 functions->fCompileShader = noOpGLCompileShader; 863 functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; 864 functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D; 865 functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; 866 functions->fCreateProgram = debugGLCreateProgram; 867 functions->fCreateShader = debugGLCreateShader; 868 functions->fCullFace = noOpGLCullFace; 869 functions->fDeleteBuffers = debugGLDeleteBuffers; 870 functions->fDeleteProgram = debugGLDeleteProgram; 871 functions->fDeleteQueries = noOpGLDeleteIds; 872 functions->fDeleteShader = debugGLDeleteShader; 873 functions->fDeleteTextures = debugGLDeleteTextures; 874 functions->fDeleteVertexArrays = debugGLDeleteVertexArrays; 875 functions->fDepthMask = noOpGLDepthMask; 876 functions->fDisable = noOpGLDisable; 877 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; 878 functions->fDrawArrays = noOpGLDrawArrays; 879 functions->fDrawArraysInstanced = noOpGLDrawArraysInstanced; 880 functions->fDrawBuffer = noOpGLDrawBuffer; 881 functions->fDrawBuffers = noOpGLDrawBuffers; 882 functions->fDrawElements = noOpGLDrawElements; 883 functions->fDrawElementsInstanced = noOpGLDrawElementsInstanced; 884 functions->fEnable = noOpGLEnable; 885 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; 886 functions->fEndQuery = noOpGLEndQuery; 887 functions->fFinish = noOpGLFinish; 888 functions->fFlush = noOpGLFlush; 889 functions->fFlushMappedBufferRange = debugGLFlushMappedBufferRange; 890 functions->fFrontFace = noOpGLFrontFace; 891 functions->fGenerateMipmap = debugGLGenerateMipmap; 892 functions->fGenBuffers = debugGLGenBuffers; 893 functions->fGenQueries = noOpGLGenIds; 894 functions->fGenTextures = debugGLGenTextures; 895 functions->fGetBufferParameteriv = debugGLGetBufferParameteriv; 896 functions->fGetError = noOpGLGetError; 897 functions->fGetIntegerv = noOpGLGetIntegerv; 898 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; 899 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; 900 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; 901 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; 902 functions->fGetQueryiv = noOpGLGetQueryiv; 903 functions->fGetProgramInfoLog = noOpGLGetInfoLog; 904 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; 905 functions->fGetShaderInfoLog = noOpGLGetInfoLog; 906 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; 907 functions->fGetString = noOpGLGetString; 908 functions->fGetStringi = noOpGLGetStringi; 909 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; 910 functions->fGetUniformLocation = noOpGLGetUniformLocation; 911 functions->fGenVertexArrays = debugGLGenVertexArrays; 912 functions->fLineWidth = noOpGLLineWidth; 913 functions->fLinkProgram = noOpGLLinkProgram; 914 functions->fMapBuffer = debugGLMapBuffer; 915 functions->fMapBufferRange = debugGLMapBufferRange; 916 functions->fPixelStorei = debugGLPixelStorei; 917 functions->fQueryCounter = noOpGLQueryCounter; 918 functions->fReadBuffer = noOpGLReadBuffer; 919 functions->fReadPixels = debugGLReadPixels; 920 functions->fScissor = noOpGLScissor; 921 functions->fShaderSource = noOpGLShaderSource; 922 functions->fStencilFunc = noOpGLStencilFunc; 923 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; 924 functions->fStencilMask = noOpGLStencilMask; 925 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; 926 functions->fStencilOp = noOpGLStencilOp; 927 functions->fStencilOpSeparate = noOpGLStencilOpSeparate; 928 functions->fTexImage2D = noOpGLTexImage2D; 929 functions->fTexParameteri = noOpGLTexParameteri; 930 functions->fTexParameteriv = noOpGLTexParameteriv; 931 functions->fTexSubImage2D = noOpGLTexSubImage2D; 932 functions->fTexStorage2D = noOpGLTexStorage2D; 933 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; 934 functions->fUniform1f = noOpGLUniform1f; 935 functions->fUniform1i = noOpGLUniform1i; 936 functions->fUniform1fv = noOpGLUniform1fv; 937 functions->fUniform1iv = noOpGLUniform1iv; 938 functions->fUniform2f = noOpGLUniform2f; 939 functions->fUniform2i = noOpGLUniform2i; 940 functions->fUniform2fv = noOpGLUniform2fv; 941 functions->fUniform2iv = noOpGLUniform2iv; 942 functions->fUniform3f = noOpGLUniform3f; 943 functions->fUniform3i = noOpGLUniform3i; 944 functions->fUniform3fv = noOpGLUniform3fv; 945 functions->fUniform3iv = noOpGLUniform3iv; 946 functions->fUniform4f = noOpGLUniform4f; 947 functions->fUniform4i = noOpGLUniform4i; 948 functions->fUniform4fv = noOpGLUniform4fv; 949 functions->fUniform4iv = noOpGLUniform4iv; 950 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; 951 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; 952 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; 953 functions->fUnmapBuffer = debugGLUnmapBuffer; 954 functions->fUseProgram = debugGLUseProgram; 955 functions->fVertexAttrib1f = noOpGLVertexAttrib1f; 956 functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv; 957 functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv; 958 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; 959 functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor; 960 functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer; 961 functions->fVertexAttribPointer = noOpGLVertexAttribPointer; 962 functions->fViewport = noOpGLViewport; 963 functions->fBindFramebuffer = debugGLBindFramebuffer; 964 functions->fBindRenderbuffer = debugGLBindRenderbuffer; 965 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; 966 functions->fDeleteFramebuffers = debugGLDeleteFramebuffers; 967 functions->fDeleteRenderbuffers = debugGLDeleteRenderbuffers; 968 functions->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer; 969 functions->fFramebufferTexture2D = debugGLFramebufferTexture2D; 970 functions->fGenFramebuffers = debugGLGenFramebuffers; 971 functions->fGenRenderbuffers = debugGLGenRenderbuffers; 972 functions->fGetFramebufferAttachmentParameteriv = 973 noOpGLGetFramebufferAttachmentParameteriv; 974 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; 975 functions->fRenderbufferStorage = noOpGLRenderbufferStorage; 976 functions->fRenderbufferStorageMultisample = 977 noOpGLRenderbufferStorageMultisample; 978 functions->fBlitFramebuffer = noOpGLBlitFramebuffer; 979 functions->fResolveMultisampleFramebuffer = 980 noOpGLResolveMultisampleFramebuffer; 981 functions->fMatrixLoadf = noOpGLMatrixLoadf; 982 functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity; 983 984 functions->fBindFragDataLocationIndexed = 985 noOpGLBindFragDataLocationIndexed; 986 987 interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi, 988 functions->fGetIntegerv, nullptr, GR_EGL_NO_DISPLAY); 989 990 return interface; 991 } 992