DebugGLTestContext.cpp revision 87c6d7a99ee7fee2dcc537a1ccad95fc5a9bd26b
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 23namespace { // suppress no previous prototype warning 24 25//////////////////////////////////////////////////////////////////////////////// 26GrGLvoid 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//////////////////////////////////////////////////////////////////////////////// 36GrGLvoid 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 51GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) { 52} 53 54GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, 55 GrGLuint index, 56 const char* name) { 57} 58 59//////////////////////////////////////////////////////////////////////////////// 60GrGLvoid 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//////////////////////////////////////////////////////////////////////////////// 76GrGLvoid 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 108GrGLvoid 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 129GrGLvoid 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 207 // a frameBufferID of 0 is acceptable - it binds to the default 208 // frame buffer 209 GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID, 210 GrFrameBufferObj, 211 GrDebugGL::kFrameBuffer_ObjTypes); 212 213 GrDebugGL::getInstance()->setFrameBuffer(frameBuffer); 214 } 215 216 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) { 217 218 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 219 220 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer 221 GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID, 222 GrRenderBufferObj, 223 GrDebugGL::kRenderBuffer_ObjTypes); 224 225 GrDebugGL::getInstance()->setRenderBuffer(renderBuffer); 226 } 227 228 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) { 229 230 // first potentially unbind the texture 231 // TODO: move this into GrDebugGL as unBindTexture? 232 for (unsigned int i = 0; 233 i < GrDebugGL::getInstance()->getMaxTextureUnits(); 234 ++i) { 235 GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i); 236 237 if (pTU->getTexture()) { 238 for (int j = 0; j < n; ++j) { 239 240 if (textures[j] == pTU->getTexture()->getID()) { 241 // this ID is the current texture - revert the binding to 0 242 pTU->setTexture(NULL); 243 } 244 } 245 } 246 } 247 248 // TODO: fuse the following block with DeleteRenderBuffers? 249 // Open GL will remove a deleted render buffer from the active 250 // frame buffer but not from any other frame buffer 251 if (GrDebugGL::getInstance()->getFrameBuffer()) { 252 253 GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer(); 254 255 for (int i = 0; i < n; ++i) { 256 257 if (NULL != frameBuffer->getColor() && 258 textures[i] == frameBuffer->getColor()->getID()) { 259 frameBuffer->setColor(NULL); 260 } 261 if (NULL != frameBuffer->getDepth() && 262 textures[i] == frameBuffer->getDepth()->getID()) { 263 frameBuffer->setDepth(NULL); 264 } 265 if (NULL != frameBuffer->getStencil() && 266 textures[i] == frameBuffer->getStencil()->getID()) { 267 frameBuffer->setStencil(NULL); 268 } 269 } 270 } 271 272 // then actually "delete" the buffers 273 for (int i = 0; i < n; ++i) { 274 GrTextureObj *buffer = GR_FIND(textures[i], 275 GrTextureObj, 276 GrDebugGL::kTexture_ObjTypes); 277 GrAlwaysAssert(buffer); 278 279 // OpenGL gives no guarantees if a texture is deleted while attached to 280 // something other than the currently bound frame buffer 281 GrAlwaysAssert(!buffer->getBound()); 282 283 GrAlwaysAssert(!buffer->getDeleted()); 284 buffer->deleteAction(); 285 } 286 287 } 288 289 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, 290 const GrGLuint *frameBuffers) { 291 292 // first potentially unbind the buffers 293 if (GrDebugGL::getInstance()->getFrameBuffer()) { 294 for (int i = 0; i < n; ++i) { 295 296 if (frameBuffers[i] == 297 GrDebugGL::getInstance()->getFrameBuffer()->getID()) { 298 // this ID is the current frame buffer - rebind to the default 299 GrDebugGL::getInstance()->setFrameBuffer(NULL); 300 } 301 } 302 } 303 304 // then actually "delete" the buffers 305 for (int i = 0; i < n; ++i) { 306 GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i], 307 GrFrameBufferObj, 308 GrDebugGL::kFrameBuffer_ObjTypes); 309 GrAlwaysAssert(buffer); 310 311 GrAlwaysAssert(!buffer->getDeleted()); 312 buffer->deleteAction(); 313 } 314 } 315 316 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, 317 const GrGLuint *renderBuffers) { 318 319 // first potentially unbind the buffers 320 if (GrDebugGL::getInstance()->getRenderBuffer()) { 321 for (int i = 0; i < n; ++i) { 322 323 if (renderBuffers[i] == 324 GrDebugGL::getInstance()->getRenderBuffer()->getID()) { 325 // this ID is the current render buffer - make no 326 // render buffer be bound 327 GrDebugGL::getInstance()->setRenderBuffer(NULL); 328 } 329 } 330 } 331 332 // TODO: fuse the following block with DeleteTextures? 333 // Open GL will remove a deleted render buffer from the active frame 334 // buffer but not from any other frame buffer 335 if (GrDebugGL::getInstance()->getFrameBuffer()) { 336 337 GrFrameBufferObj *frameBuffer = 338 GrDebugGL::getInstance()->getFrameBuffer(); 339 340 for (int i = 0; i < n; ++i) { 341 342 if (NULL != frameBuffer->getColor() && 343 renderBuffers[i] == frameBuffer->getColor()->getID()) { 344 frameBuffer->setColor(NULL); 345 } 346 if (NULL != frameBuffer->getDepth() && 347 renderBuffers[i] == frameBuffer->getDepth()->getID()) { 348 frameBuffer->setDepth(NULL); 349 } 350 if (NULL != frameBuffer->getStencil() && 351 renderBuffers[i] == frameBuffer->getStencil()->getID()) { 352 frameBuffer->setStencil(NULL); 353 } 354 } 355 } 356 357 // then actually "delete" the buffers 358 for (int i = 0; i < n; ++i) { 359 GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i], 360 GrRenderBufferObj, 361 GrDebugGL::kRenderBuffer_ObjTypes); 362 GrAlwaysAssert(buffer); 363 364 // OpenGL gives no guarantees if a render buffer is deleted 365 // while attached to something other than the currently 366 // bound frame buffer 367 GrAlwaysAssert(!buffer->getColorBound()); 368 GrAlwaysAssert(!buffer->getDepthBound()); 369 GrAlwaysAssert(!buffer->getStencilBound()); 370 371 GrAlwaysAssert(!buffer->getDeleted()); 372 buffer->deleteAction(); 373 } 374 } 375 376 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, 377 GrGLenum attachment, 378 GrGLenum renderbuffertarget, 379 GrGLuint renderBufferID) { 380 381 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 382 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 383 GR_GL_DEPTH_ATTACHMENT == attachment || 384 GR_GL_STENCIL_ATTACHMENT == attachment); 385 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); 386 387 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); 388 // A render buffer cannot be attached to the default framebuffer 389 GrAlwaysAssert(NULL != framebuffer); 390 391 // a renderBufferID of 0 is acceptable - it unbinds the current 392 // render buffer 393 GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID, 394 GrRenderBufferObj, 395 GrDebugGL::kRenderBuffer_ObjTypes); 396 397 switch (attachment) { 398 case GR_GL_COLOR_ATTACHMENT0: 399 framebuffer->setColor(renderbuffer); 400 break; 401 case GR_GL_DEPTH_ATTACHMENT: 402 framebuffer->setDepth(renderbuffer); 403 break; 404 case GR_GL_STENCIL_ATTACHMENT: 405 framebuffer->setStencil(renderbuffer); 406 break; 407 default: 408 GrAlwaysAssert(false); 409 break; 410 }; 411 412 } 413 414 //////////////////////////////////////////////////////////////////////////////// 415 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, 416 GrGLenum attachment, 417 GrGLenum textarget, 418 GrGLuint textureID, 419 GrGLint level) { 420 421 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 422 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 423 GR_GL_DEPTH_ATTACHMENT == attachment || 424 GR_GL_STENCIL_ATTACHMENT == attachment); 425 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); 426 427 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); 428 // A texture cannot be attached to the default framebuffer 429 GrAlwaysAssert(NULL != framebuffer); 430 431 // A textureID of 0 is allowed - it unbinds the currently bound texture 432 GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, 433 GrDebugGL::kTexture_ObjTypes); 434 if (texture) { 435 // The texture shouldn't be bound to a texture unit - this 436 // could lead to a feedback loop 437 GrAlwaysAssert(!texture->getBound()); 438 } 439 440 GrAlwaysAssert(0 == level); 441 442 switch (attachment) { 443 case GR_GL_COLOR_ATTACHMENT0: 444 framebuffer->setColor(texture); 445 break; 446 case GR_GL_DEPTH_ATTACHMENT: 447 framebuffer->setDepth(texture); 448 break; 449 case GR_GL_STENCIL_ATTACHMENT: 450 framebuffer->setStencil(texture); 451 break; 452 default: 453 GrAlwaysAssert(false); 454 break; 455 }; 456 } 457 458GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() { 459 460 GrProgramObj *program = GR_CREATE(GrProgramObj, 461 GrDebugGL::kProgram_ObjTypes); 462 463 return program->getID(); 464} 465 466GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) { 467 468 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || 469 GR_GL_FRAGMENT_SHADER == type); 470 471 GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes); 472 shader->setType(type); 473 474 return shader->getID(); 475} 476 477GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) { 478 479 GrProgramObj *program = GR_FIND(programID, 480 GrProgramObj, 481 GrDebugGL::kProgram_ObjTypes); 482 GrAlwaysAssert(program); 483 484 if (program->getRefCount()) { 485 // someone is still using this program so we can't delete it here 486 program->setMarkedForDeletion(); 487 } else { 488 program->deleteAction(); 489 } 490} 491 492GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) { 493 494 GrShaderObj *shader = GR_FIND(shaderID, 495 GrShaderObj, 496 GrDebugGL::kShader_ObjTypes); 497 GrAlwaysAssert(shader); 498 499 if (shader->getRefCount()) { 500 // someone is still using this shader so we can't delete it here 501 shader->setMarkedForDeletion(); 502 } else { 503 shader->deleteAction(); 504 } 505} 506 507GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type, 508 GrGLsizei n, 509 GrGLuint* ids) { 510 511 for (int i = 0; i < n; ++i) { 512 GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type); 513 GrAlwaysAssert(obj); 514 ids[i] = obj->getID(); 515 } 516} 517 518GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) { 519 debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids); 520} 521 522GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, 523 GrGLuint* ids) { 524 debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids); 525} 526 527GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, 528 GrGLuint* ids) { 529 debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids); 530} 531 532GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) { 533 debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids); 534} 535 536GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenVertexArrays(GrGLsizei n, GrGLuint* ids) { 537 debugGenObjs(GrDebugGL::kVertexArray_ObjTypes, n, ids); 538} 539 540GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteVertexArrays(GrGLsizei n, const GrGLuint* ids) { 541 for (GrGLsizei i = 0; i < n; ++i) { 542 GrVertexArrayObj* array = 543 GR_FIND(ids[i], GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 544 GrAlwaysAssert(array); 545 546 // Deleting the current vertex array binds object 0 547 if (GrDebugGL::getInstance()->getVertexArray() == array) { 548 GrDebugGL::getInstance()->setVertexArray(NULL); 549 } 550 551 if (array->getRefCount()) { 552 // someone is still using this shader so we can't delete it here 553 array->setMarkedForDeletion(); 554 } else { 555 array->deleteAction(); 556 } 557 } 558} 559 560GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) { 561 GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 562 GrAlwaysAssert(array); 563 GrDebugGL::getInstance()->setVertexArray(array); 564} 565 566GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) { 567 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); 568 569 GrBufferObj *buffer = GR_FIND(bufferID, 570 GrBufferObj, 571 GrDebugGL::kBuffer_ObjTypes); 572 // 0 is a permissible bufferID - it unbinds the current buffer 573 574 switch (target) { 575 case GR_GL_ARRAY_BUFFER: 576 GrDebugGL::getInstance()->setArrayBuffer(buffer); 577 break; 578 case GR_GL_ELEMENT_ARRAY_BUFFER: 579 GrDebugGL::getInstance()->setElementArrayBuffer(buffer); 580 break; 581 default: 582 GrCrash("Unexpected target to glBindBuffer"); 583 break; 584 } 585} 586 587// deleting a bound buffer has the side effect of binding 0 588GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) { 589 // first potentially unbind the buffers 590 for (int i = 0; i < n; ++i) { 591 592 if (GrDebugGL::getInstance()->getArrayBuffer() && 593 ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) { 594 // this ID is the current array buffer 595 GrDebugGL::getInstance()->setArrayBuffer(NULL); 596 } 597 if (GrDebugGL::getInstance()->getElementArrayBuffer() && 598 ids[i] == 599 GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) { 600 // this ID is the current element array buffer 601 GrDebugGL::getInstance()->setElementArrayBuffer(NULL); 602 } 603 } 604 605 // then actually "delete" the buffers 606 for (int i = 0; i < n; ++i) { 607 GrBufferObj *buffer = GR_FIND(ids[i], 608 GrBufferObj, 609 GrDebugGL::kBuffer_ObjTypes); 610 GrAlwaysAssert(buffer); 611 612 GrAlwaysAssert(!buffer->getDeleted()); 613 buffer->deleteAction(); 614 } 615} 616 617// map a buffer to the caller's address space 618GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) { 619 620 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 621 GR_GL_ELEMENT_ARRAY_BUFFER == target); 622 // GR_GL_READ_ONLY == access || || GR_GL_READ_WRIT == access); 623 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); 624 625 GrBufferObj *buffer = NULL; 626 switch (target) { 627 case GR_GL_ARRAY_BUFFER: 628 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 629 break; 630 case GR_GL_ELEMENT_ARRAY_BUFFER: 631 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 632 break; 633 default: 634 GrCrash("Unexpected target to glMapBuffer"); 635 break; 636 } 637 638 if (buffer) { 639 GrAlwaysAssert(!buffer->getMapped()); 640 buffer->setMapped(); 641 return buffer->getDataPtr(); 642 } 643 644 GrAlwaysAssert(false); 645 return NULL; // no buffer bound to the target 646} 647 648// remove a buffer from the caller's address space 649// TODO: check if the "access" method from "glMapBuffer" was honored 650GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) { 651 652 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 653 GR_GL_ELEMENT_ARRAY_BUFFER == target); 654 655 GrBufferObj *buffer = NULL; 656 switch (target) { 657 case GR_GL_ARRAY_BUFFER: 658 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 659 break; 660 case GR_GL_ELEMENT_ARRAY_BUFFER: 661 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 662 break; 663 default: 664 GrCrash("Unexpected target to glUnmapBuffer"); 665 break; 666 } 667 668 if (buffer) { 669 GrAlwaysAssert(buffer->getMapped()); 670 buffer->resetMapped(); 671 return GR_GL_TRUE; 672 } 673 674 GrAlwaysAssert(false); 675 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; 676} 677 678GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, 679 GrGLenum value, 680 GrGLint* params) { 681 682 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 683 GR_GL_ELEMENT_ARRAY_BUFFER == target); 684 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || 685 GR_GL_BUFFER_USAGE == value); 686 687 GrBufferObj *buffer = NULL; 688 switch (target) { 689 case GR_GL_ARRAY_BUFFER: 690 buffer = GrDebugGL::getInstance()->getArrayBuffer(); 691 break; 692 case GR_GL_ELEMENT_ARRAY_BUFFER: 693 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 694 break; 695 } 696 697 GrAlwaysAssert(buffer); 698 699 switch (value) { 700 case GR_GL_BUFFER_MAPPED: 701 *params = GR_GL_FALSE; 702 if (buffer) 703 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; 704 break; 705 case GR_GL_BUFFER_SIZE: 706 *params = 0; 707 if (buffer) 708 *params = buffer->getSize(); 709 break; 710 case GR_GL_BUFFER_USAGE: 711 *params = GR_GL_STATIC_DRAW; 712 if (buffer) 713 *params = buffer->getUsage(); 714 break; 715 default: 716 GrCrash("Unexpected value to glGetBufferParamateriv"); 717 break; 718 } 719}; 720} // end of namespace 721 722//////////////////////////////////////////////////////////////////////////////// 723struct GrDebugGLInterface : public GrGLInterface { 724 725public: 726 SK_DECLARE_INST_COUNT(GrDebugGLInterface) 727 728 GrDebugGLInterface() 729 : fWrapped(NULL) { 730 GrDebugGL::staticRef(); 731 } 732 733 virtual ~GrDebugGLInterface() { 734 GrDebugGL::staticUnRef(); 735 } 736 737 void setWrapped(GrGLInterface *interface) { 738 fWrapped.reset(interface); 739 } 740 741 // TODO: there are some issues w/ wrapping another GL interface inside the 742 // debug interface: 743 // Since none of the "gl" methods are member functions they don't get 744 // a "this" pointer through which to access "fWrapped" 745 // This could be worked around by having all of them access the 746 // "glInterface" pointer - i.e., treating the debug interface as a 747 // true singleton 748 // 749 // The problem with this is that we also want to handle OpenGL 750 // contexts. The natural way to do this is to have multiple debug 751 // interfaces. Each of which represents a separate context. The 752 // static ID count would still uniquify IDs across all of them. 753 // The problem then is that we couldn't treat the debug GL 754 // interface as a singleton (since there would be one for each 755 // context). 756 // 757 // The solution to this is probably to alter SkDebugGlContext's 758 // "makeCurrent" method to make a call like "makeCurrent(this)" to 759 // the debug GL interface (assuming that the application will create 760 // multiple SkGLContextHelper's) to let it switch between the active 761 // context. Everything in the GrDebugGL object would then need to be 762 // moved to a GrContextObj and the GrDebugGL object would just switch 763 // between them. Note that this approach would also require that 764 // SkDebugGLContext wrap an arbitrary other context 765 // and then pass the wrapped interface to the debug GL interface. 766 767protected: 768private: 769 770 SkAutoTUnref<GrGLInterface> fWrapped; 771 772 typedef GrGLInterface INHERITED; 773}; 774 775SK_DEFINE_INST_COUNT(GrDebugGLInterface) 776 777//////////////////////////////////////////////////////////////////////////////// 778const GrGLInterface* GrGLCreateDebugInterface() { 779 GrGLInterface* interface = SkNEW(GrDebugGLInterface); 780 781 interface->fBindingsExported = kDesktop_GrGLBinding; 782 interface->fActiveTexture = debugGLActiveTexture; 783 interface->fAttachShader = debugGLAttachShader; 784 interface->fBeginQuery = debugGLBeginQuery; 785 interface->fBindAttribLocation = debugGLBindAttribLocation; 786 interface->fBindBuffer = debugGLBindBuffer; 787 interface->fBindFragDataLocation = noOpGLBindFragDataLocation; 788 interface->fBindTexture = debugGLBindTexture; 789 interface->fBindVertexArray = debugGLBindVertexArray; 790 interface->fBlendColor = noOpGLBlendColor; 791 interface->fBlendFunc = noOpGLBlendFunc; 792 interface->fBufferData = debugGLBufferData; 793 interface->fBufferSubData = noOpGLBufferSubData; 794 interface->fClear = noOpGLClear; 795 interface->fClearColor = noOpGLClearColor; 796 interface->fClearStencil = noOpGLClearStencil; 797 interface->fColorMask = noOpGLColorMask; 798 interface->fCompileShader = noOpGLCompileShader; 799 interface->fCompressedTexImage2D = noOpGLCompressedTexImage2D; 800 interface->fCreateProgram = debugGLCreateProgram; 801 interface->fCreateShader = debugGLCreateShader; 802 interface->fCullFace = noOpGLCullFace; 803 interface->fDeleteBuffers = debugGLDeleteBuffers; 804 interface->fDeleteProgram = debugGLDeleteProgram; 805 interface->fDeleteQueries = noOpGLDeleteIds; 806 interface->fDeleteShader = debugGLDeleteShader; 807 interface->fDeleteTextures = debugGLDeleteTextures; 808 interface->fDeleteVertexArrays = debugGLDeleteVertexArrays; 809 interface->fDepthMask = noOpGLDepthMask; 810 interface->fDisable = noOpGLDisable; 811 interface->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; 812 interface->fDrawArrays = noOpGLDrawArrays; 813 interface->fDrawBuffer = noOpGLDrawBuffer; 814 interface->fDrawBuffers = noOpGLDrawBuffers; 815 interface->fDrawElements = noOpGLDrawElements; 816 interface->fEnable = noOpGLEnable; 817 interface->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; 818 interface->fEndQuery = noOpGLEndQuery; 819 interface->fFinish = noOpGLFinish; 820 interface->fFlush = noOpGLFlush; 821 interface->fFrontFace = noOpGLFrontFace; 822 interface->fGenBuffers = debugGLGenBuffers; 823 interface->fGenQueries = noOpGLGenIds; 824 interface->fGenTextures = debugGLGenTextures; 825 interface->fGetBufferParameteriv = debugGLGetBufferParameteriv; 826 interface->fGetError = noOpGLGetError; 827 interface->fGetIntegerv = noOpGLGetIntegerv; 828 interface->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; 829 interface->fGetQueryObjectiv = noOpGLGetQueryObjectiv; 830 interface->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; 831 interface->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; 832 interface->fGetQueryiv = noOpGLGetQueryiv; 833 interface->fGetProgramInfoLog = noOpGLGetInfoLog; 834 interface->fGetProgramiv = noOpGLGetShaderOrProgramiv; 835 interface->fGetShaderInfoLog = noOpGLGetInfoLog; 836 interface->fGetShaderiv = noOpGLGetShaderOrProgramiv; 837 interface->fGetString = noOpGLGetString; 838 interface->fGetStringi = noOpGLGetStringi; 839 interface->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; 840 interface->fGetUniformLocation = noOpGLGetUniformLocation; 841 interface->fGenVertexArrays = debugGLGenVertexArrays; 842 interface->fLineWidth = noOpGLLineWidth; 843 interface->fLinkProgram = noOpGLLinkProgram; 844 interface->fPixelStorei = debugGLPixelStorei; 845 interface->fQueryCounter = noOpGLQueryCounter; 846 interface->fReadBuffer = noOpGLReadBuffer; 847 interface->fReadPixels = debugGLReadPixels; 848 interface->fScissor = noOpGLScissor; 849 interface->fShaderSource = noOpGLShaderSource; 850 interface->fStencilFunc = noOpGLStencilFunc; 851 interface->fStencilFuncSeparate = noOpGLStencilFuncSeparate; 852 interface->fStencilMask = noOpGLStencilMask; 853 interface->fStencilMaskSeparate = noOpGLStencilMaskSeparate; 854 interface->fStencilOp = noOpGLStencilOp; 855 interface->fStencilOpSeparate = noOpGLStencilOpSeparate; 856 interface->fTexImage2D = noOpGLTexImage2D; 857 interface->fTexParameteri = noOpGLTexParameteri; 858 interface->fTexParameteriv = noOpGLTexParameteriv; 859 interface->fTexSubImage2D = noOpGLTexSubImage2D; 860 interface->fTexStorage2D = noOpGLTexStorage2D; 861 interface->fUniform1f = noOpGLUniform1f; 862 interface->fUniform1i = noOpGLUniform1i; 863 interface->fUniform1fv = noOpGLUniform1fv; 864 interface->fUniform1iv = noOpGLUniform1iv; 865 interface->fUniform2f = noOpGLUniform2f; 866 interface->fUniform2i = noOpGLUniform2i; 867 interface->fUniform2fv = noOpGLUniform2fv; 868 interface->fUniform2iv = noOpGLUniform2iv; 869 interface->fUniform3f = noOpGLUniform3f; 870 interface->fUniform3i = noOpGLUniform3i; 871 interface->fUniform3fv = noOpGLUniform3fv; 872 interface->fUniform3iv = noOpGLUniform3iv; 873 interface->fUniform4f = noOpGLUniform4f; 874 interface->fUniform4i = noOpGLUniform4i; 875 interface->fUniform4fv = noOpGLUniform4fv; 876 interface->fUniform4iv = noOpGLUniform4iv; 877 interface->fUniformMatrix2fv = noOpGLUniformMatrix2fv; 878 interface->fUniformMatrix3fv = noOpGLUniformMatrix3fv; 879 interface->fUniformMatrix4fv = noOpGLUniformMatrix4fv; 880 interface->fUseProgram = debugGLUseProgram; 881 interface->fVertexAttrib4fv = noOpGLVertexAttrib4fv; 882 interface->fVertexAttribPointer = noOpGLVertexAttribPointer; 883 interface->fViewport = noOpGLViewport; 884 interface->fBindFramebuffer = debugGLBindFramebuffer; 885 interface->fBindRenderbuffer = debugGLBindRenderbuffer; 886 interface->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; 887 interface->fDeleteFramebuffers = debugGLDeleteFramebuffers; 888 interface->fDeleteRenderbuffers = debugGLDeleteRenderbuffers; 889 interface->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer; 890 interface->fFramebufferTexture2D = debugGLFramebufferTexture2D; 891 interface->fGenFramebuffers = debugGLGenFramebuffers; 892 interface->fGenRenderbuffers = debugGLGenRenderbuffers; 893 interface->fGetFramebufferAttachmentParameteriv = 894 noOpGLGetFramebufferAttachmentParameteriv; 895 interface->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; 896 interface->fRenderbufferStorage = noOpGLRenderbufferStorage; 897 interface->fRenderbufferStorageMultisample = 898 noOpGLRenderbufferStorageMultisample; 899 interface->fBlitFramebuffer = noOpGLBlitFramebuffer; 900 interface->fResolveMultisampleFramebuffer = 901 noOpGLResolveMultisampleFramebuffer; 902 interface->fMapBuffer = debugGLMapBuffer; 903 interface->fUnmapBuffer = debugGLUnmapBuffer; 904 interface->fBindFragDataLocationIndexed = 905 noOpGLBindFragDataLocationIndexed; 906 907 return interface; 908} 909