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 = NULL; 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 GrCrash("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(NULL); 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 (NULL != frameBuffer->getColor() && 260 textures[i] == frameBuffer->getColor()->getID()) { 261 frameBuffer->setColor(NULL); 262 } 263 if (NULL != frameBuffer->getDepth() && 264 textures[i] == frameBuffer->getDepth()->getID()) { 265 frameBuffer->setDepth(NULL); 266 } 267 if (NULL != frameBuffer->getStencil() && 268 textures[i] == frameBuffer->getStencil()->getID()) { 269 frameBuffer->setStencil(NULL); 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(NULL); 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(NULL); 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 (NULL != frameBuffer->getColor() && 345 renderBuffers[i] == frameBuffer->getColor()->getID()) { 346 frameBuffer->setColor(NULL); 347 } 348 if (NULL != frameBuffer->getDepth() && 349 renderBuffers[i] == frameBuffer->getDepth()->getID()) { 350 frameBuffer->setDepth(NULL); 351 } 352 if (NULL != frameBuffer->getStencil() && 353 renderBuffers[i] == frameBuffer->getStencil()->getID()) { 354 frameBuffer->setStencil(NULL); 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(NULL != 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(NULL != 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 GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type); 517 GrAlwaysAssert(obj); 518 ids[i] = obj->getID(); 519 } 520 } 521 522 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) { 523 debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids); 524 } 525 526 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenerateMipmap(GrGLenum level) { 527 } 528 529 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, 530 GrGLuint* ids) { 531 debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids); 532 } 533 534 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, 535 GrGLuint* ids) { 536 debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids); 537 } 538 539 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) { 540 debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids); 541 } 542 543 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenVertexArrays(GrGLsizei n, GrGLuint* ids) { 544 debugGenObjs(GrDebugGL::kVertexArray_ObjTypes, n, ids); 545 } 546 547 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteVertexArrays(GrGLsizei n, const GrGLuint* ids) { 548 for (GrGLsizei i = 0; i < n; ++i) { 549 GrVertexArrayObj* array = 550 GR_FIND(ids[i], GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 551 GrAlwaysAssert(array); 552 553 // Deleting the current vertex array binds object 0 554 if (GrDebugGL::getInstance()->getVertexArray() == array) { 555 GrDebugGL::getInstance()->setVertexArray(NULL); 556 } 557 558 if (array->getRefCount()) { 559 // someone is still using this vertex array so we can't delete it here 560 array->setMarkedForDeletion(); 561 } else { 562 array->deleteAction(); 563 } 564 } 565 } 566 567 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) { 568 GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 569 GrAlwaysAssert((0 == id) || NULL != array); 570 GrDebugGL::getInstance()->setVertexArray(array); 571 } 572 573 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) { 574 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); 575 576 GrBufferObj *buffer = GR_FIND(bufferID, 577 GrBufferObj, 578 GrDebugGL::kBuffer_ObjTypes); 579 // 0 is a permissible bufferID - it unbinds the current buffer 580 581 switch (target) { 582 case GR_GL_ARRAY_BUFFER: 583 GrDebugGL::getInstance()->setArrayBuffer(buffer); 584 break; 585 case GR_GL_ELEMENT_ARRAY_BUFFER: 586 GrDebugGL::getInstance()->setElementArrayBuffer(buffer); 587 break; 588 default: 589 GrCrash("Unexpected target to glBindBuffer"); 590 break; 591 } 592 } 593 594 // deleting a bound buffer has the side effect of binding 0 595 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) { 596 // first potentially unbind the buffers 597 for (int i = 0; i < n; ++i) { 598 599 if (GrDebugGL::getInstance()->getArrayBuffer() && 600 ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) { 601 // this ID is the current array buffer 602 GrDebugGL::getInstance()->setArrayBuffer(NULL); 603 } 604 if (GrDebugGL::getInstance()->getElementArrayBuffer() && 605 ids[i] == 606 GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) { 607 // this ID is the current element array buffer 608 GrDebugGL::getInstance()->setElementArrayBuffer(NULL); 609 } 610 } 611 612 // then actually "delete" the buffers 613 for (int i = 0; i < n; ++i) { 614 GrBufferObj *buffer = GR_FIND(ids[i], 615 GrBufferObj, 616 GrDebugGL::kBuffer_ObjTypes); 617 GrAlwaysAssert(buffer); 618 619 GrAlwaysAssert(!buffer->getDeleted()); 620 buffer->deleteAction(); 621 } 622 } 623 624 // map a buffer to the caller's address space 625 GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) { 626 627 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 628 GR_GL_ELEMENT_ARRAY_BUFFER == target); 629 // GR_GL_READ_ONLY == access || || GR_GL_READ_WRIT == access); 630 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); 631 632 GrBufferObj *buffer = NULL; 633 switch (target) { 634 case GR_GL_ARRAY_BUFFER: 635 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 636 break; 637 case GR_GL_ELEMENT_ARRAY_BUFFER: 638 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 639 break; 640 default: 641 GrCrash("Unexpected target to glMapBuffer"); 642 break; 643 } 644 645 if (buffer) { 646 GrAlwaysAssert(!buffer->getMapped()); 647 buffer->setMapped(); 648 return buffer->getDataPtr(); 649 } 650 651 GrAlwaysAssert(false); 652 return NULL; // no buffer bound to the target 653 } 654 655 // remove a buffer from the caller's address space 656 // TODO: check if the "access" method from "glMapBuffer" was honored 657 GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) { 658 659 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 660 GR_GL_ELEMENT_ARRAY_BUFFER == target); 661 662 GrBufferObj *buffer = NULL; 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 GrCrash("Unexpected target to glUnmapBuffer"); 672 break; 673 } 674 675 if (buffer) { 676 GrAlwaysAssert(buffer->getMapped()); 677 buffer->resetMapped(); 678 return GR_GL_TRUE; 679 } 680 681 GrAlwaysAssert(false); 682 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; 683 } 684 685 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, 686 GrGLenum value, 687 GrGLint* params) { 688 689 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 690 GR_GL_ELEMENT_ARRAY_BUFFER == target); 691 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || 692 GR_GL_BUFFER_USAGE == value); 693 694 GrBufferObj *buffer = NULL; 695 switch (target) { 696 case GR_GL_ARRAY_BUFFER: 697 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 698 break; 699 case GR_GL_ELEMENT_ARRAY_BUFFER: 700 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 701 break; 702 } 703 704 GrAlwaysAssert(buffer); 705 706 switch (value) { 707 case GR_GL_BUFFER_MAPPED: 708 *params = GR_GL_FALSE; 709 if (buffer) 710 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; 711 break; 712 case GR_GL_BUFFER_SIZE: 713 *params = 0; 714 if (buffer) 715 *params = buffer->getSize(); 716 break; 717 case GR_GL_BUFFER_USAGE: 718 *params = GR_GL_STATIC_DRAW; 719 if (buffer) 720 *params = buffer->getUsage(); 721 break; 722 default: 723 GrCrash("Unexpected value to glGetBufferParamateriv"); 724 break; 725 } 726 }; 727 } // end of namespace 728 729 //////////////////////////////////////////////////////////////////////////////// 730 struct GrDebugGLInterface : public GrGLInterface { 731 732 public: 733 SK_DECLARE_INST_COUNT(GrDebugGLInterface) 734 735 GrDebugGLInterface() 736 : fWrapped(NULL) { 737 GrDebugGL::staticRef(); 738 } 739 740 virtual ~GrDebugGLInterface() { 741 GrDebugGL::staticUnRef(); 742 } 743 744 void setWrapped(GrGLInterface *interface) { 745 fWrapped.reset(interface); 746 } 747 748 // TODO: there are some issues w/ wrapping another GL interface inside the 749 // debug interface: 750 // Since none of the "gl" methods are member functions they don't get 751 // a "this" pointer through which to access "fWrapped" 752 // This could be worked around by having all of them access the 753 // "glInterface" pointer - i.e., treating the debug interface as a 754 // true singleton 755 // 756 // The problem with this is that we also want to handle OpenGL 757 // contexts. The natural way to do this is to have multiple debug 758 // interfaces. Each of which represents a separate context. The 759 // static ID count would still uniquify IDs across all of them. 760 // The problem then is that we couldn't treat the debug GL 761 // interface as a singleton (since there would be one for each 762 // context). 763 // 764 // The solution to this is probably to alter SkDebugGlContext's 765 // "makeCurrent" method to make a call like "makeCurrent(this)" to 766 // the debug GL interface (assuming that the application will create 767 // multiple SkGLContextHelper's) to let it switch between the active 768 // context. Everything in the GrDebugGL object would then need to be 769 // moved to a GrContextObj and the GrDebugGL object would just switch 770 // between them. Note that this approach would also require that 771 // SkDebugGLContext wrap an arbitrary other context 772 // and then pass the wrapped interface to the debug GL interface. 773 774 protected: 775 private: 776 777 SkAutoTUnref<GrGLInterface> fWrapped; 778 779 typedef GrGLInterface INHERITED; 780 }; 781 782 SK_DEFINE_INST_COUNT(GrDebugGLInterface) 783 784 //////////////////////////////////////////////////////////////////////////////// 785 const GrGLInterface* GrGLCreateDebugInterface() { 786 GrGLInterface* interface = SkNEW(GrDebugGLInterface); 787 788 interface->fBindingsExported = kDesktop_GrGLBinding; 789 interface->fActiveTexture = debugGLActiveTexture; 790 interface->fAttachShader = debugGLAttachShader; 791 interface->fBeginQuery = debugGLBeginQuery; 792 interface->fBindAttribLocation = debugGLBindAttribLocation; 793 interface->fBindBuffer = debugGLBindBuffer; 794 interface->fBindFragDataLocation = noOpGLBindFragDataLocation; 795 interface->fBindTexture = debugGLBindTexture; 796 interface->fBindVertexArray = debugGLBindVertexArray; 797 interface->fBlendColor = noOpGLBlendColor; 798 interface->fBlendFunc = noOpGLBlendFunc; 799 interface->fBufferData = debugGLBufferData; 800 interface->fBufferSubData = noOpGLBufferSubData; 801 interface->fClear = noOpGLClear; 802 interface->fClearColor = noOpGLClearColor; 803 interface->fClearStencil = noOpGLClearStencil; 804 interface->fColorMask = noOpGLColorMask; 805 interface->fCompileShader = noOpGLCompileShader; 806 interface->fCompressedTexImage2D = noOpGLCompressedTexImage2D; 807 interface->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; 808 interface->fCreateProgram = debugGLCreateProgram; 809 interface->fCreateShader = debugGLCreateShader; 810 interface->fCullFace = noOpGLCullFace; 811 interface->fDeleteBuffers = debugGLDeleteBuffers; 812 interface->fDeleteProgram = debugGLDeleteProgram; 813 interface->fDeleteQueries = noOpGLDeleteIds; 814 interface->fDeleteShader = debugGLDeleteShader; 815 interface->fDeleteTextures = debugGLDeleteTextures; 816 interface->fDeleteVertexArrays = debugGLDeleteVertexArrays; 817 interface->fDepthMask = noOpGLDepthMask; 818 interface->fDisable = noOpGLDisable; 819 interface->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; 820 interface->fDrawArrays = noOpGLDrawArrays; 821 interface->fDrawBuffer = noOpGLDrawBuffer; 822 interface->fDrawBuffers = noOpGLDrawBuffers; 823 interface->fDrawElements = noOpGLDrawElements; 824 interface->fEnable = noOpGLEnable; 825 interface->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; 826 interface->fEndQuery = noOpGLEndQuery; 827 interface->fFinish = noOpGLFinish; 828 interface->fFlush = noOpGLFlush; 829 interface->fFrontFace = noOpGLFrontFace; 830 interface->fGenerateMipmap = debugGLGenerateMipmap; 831 interface->fGenBuffers = debugGLGenBuffers; 832 interface->fGenQueries = noOpGLGenIds; 833 interface->fGenTextures = debugGLGenTextures; 834 interface->fGetBufferParameteriv = debugGLGetBufferParameteriv; 835 interface->fGetError = noOpGLGetError; 836 interface->fGetIntegerv = noOpGLGetIntegerv; 837 interface->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; 838 interface->fGetQueryObjectiv = noOpGLGetQueryObjectiv; 839 interface->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; 840 interface->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; 841 interface->fGetQueryiv = noOpGLGetQueryiv; 842 interface->fGetProgramInfoLog = noOpGLGetInfoLog; 843 interface->fGetProgramiv = noOpGLGetShaderOrProgramiv; 844 interface->fGetShaderInfoLog = noOpGLGetInfoLog; 845 interface->fGetShaderiv = noOpGLGetShaderOrProgramiv; 846 interface->fGetString = noOpGLGetString; 847 interface->fGetStringi = noOpGLGetStringi; 848 interface->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; 849 interface->fGetUniformLocation = noOpGLGetUniformLocation; 850 interface->fGenVertexArrays = debugGLGenVertexArrays; 851 interface->fLineWidth = noOpGLLineWidth; 852 interface->fLinkProgram = noOpGLLinkProgram; 853 interface->fPixelStorei = debugGLPixelStorei; 854 interface->fQueryCounter = noOpGLQueryCounter; 855 interface->fReadBuffer = noOpGLReadBuffer; 856 interface->fReadPixels = debugGLReadPixels; 857 interface->fScissor = noOpGLScissor; 858 interface->fShaderSource = noOpGLShaderSource; 859 interface->fStencilFunc = noOpGLStencilFunc; 860 interface->fStencilFuncSeparate = noOpGLStencilFuncSeparate; 861 interface->fStencilMask = noOpGLStencilMask; 862 interface->fStencilMaskSeparate = noOpGLStencilMaskSeparate; 863 interface->fStencilOp = noOpGLStencilOp; 864 interface->fStencilOpSeparate = noOpGLStencilOpSeparate; 865 interface->fTexImage2D = noOpGLTexImage2D; 866 interface->fTexParameteri = noOpGLTexParameteri; 867 interface->fTexParameteriv = noOpGLTexParameteriv; 868 interface->fTexSubImage2D = noOpGLTexSubImage2D; 869 interface->fTexStorage2D = noOpGLTexStorage2D; 870 interface->fDiscardFramebuffer = noOpGLDiscardFramebuffer; 871 interface->fUniform1f = noOpGLUniform1f; 872 interface->fUniform1i = noOpGLUniform1i; 873 interface->fUniform1fv = noOpGLUniform1fv; 874 interface->fUniform1iv = noOpGLUniform1iv; 875 interface->fUniform2f = noOpGLUniform2f; 876 interface->fUniform2i = noOpGLUniform2i; 877 interface->fUniform2fv = noOpGLUniform2fv; 878 interface->fUniform2iv = noOpGLUniform2iv; 879 interface->fUniform3f = noOpGLUniform3f; 880 interface->fUniform3i = noOpGLUniform3i; 881 interface->fUniform3fv = noOpGLUniform3fv; 882 interface->fUniform3iv = noOpGLUniform3iv; 883 interface->fUniform4f = noOpGLUniform4f; 884 interface->fUniform4i = noOpGLUniform4i; 885 interface->fUniform4fv = noOpGLUniform4fv; 886 interface->fUniform4iv = noOpGLUniform4iv; 887 interface->fUniformMatrix2fv = noOpGLUniformMatrix2fv; 888 interface->fUniformMatrix3fv = noOpGLUniformMatrix3fv; 889 interface->fUniformMatrix4fv = noOpGLUniformMatrix4fv; 890 interface->fUseProgram = debugGLUseProgram; 891 interface->fVertexAttrib4fv = noOpGLVertexAttrib4fv; 892 interface->fVertexAttribPointer = noOpGLVertexAttribPointer; 893 interface->fViewport = noOpGLViewport; 894 interface->fBindFramebuffer = debugGLBindFramebuffer; 895 interface->fBindRenderbuffer = debugGLBindRenderbuffer; 896 interface->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; 897 interface->fDeleteFramebuffers = debugGLDeleteFramebuffers; 898 interface->fDeleteRenderbuffers = debugGLDeleteRenderbuffers; 899 interface->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer; 900 interface->fFramebufferTexture2D = debugGLFramebufferTexture2D; 901 interface->fGenFramebuffers = debugGLGenFramebuffers; 902 interface->fGenRenderbuffers = debugGLGenRenderbuffers; 903 interface->fGetFramebufferAttachmentParameteriv = 904 noOpGLGetFramebufferAttachmentParameteriv; 905 interface->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; 906 interface->fRenderbufferStorage = noOpGLRenderbufferStorage; 907 interface->fRenderbufferStorageMultisample = 908 noOpGLRenderbufferStorageMultisample; 909 interface->fBlitFramebuffer = noOpGLBlitFramebuffer; 910 interface->fResolveMultisampleFramebuffer = 911 noOpGLResolveMultisampleFramebuffer; 912 interface->fMapBuffer = debugGLMapBuffer; 913 interface->fUnmapBuffer = debugGLUnmapBuffer; 914 interface->fBindFragDataLocationIndexed = 915 noOpGLBindFragDataLocationIndexed; 916 917 return interface; 918 } 919