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 #include "DebugGLTestContext.h" 10 11 #include "GrBufferObj.h" 12 #include "GrFrameBufferObj.h" 13 #include "GrProgramObj.h" 14 #include "GrRenderBufferObj.h" 15 #include "GrShaderObj.h" 16 #include "GrTextureObj.h" 17 #include "GrTextureUnitObj.h" 18 #include "GrVertexArrayObj.h" 19 #include "gl/GrGLTestInterface.h" 20 21 #include "SkMutex.h" 22 23 namespace { 24 25 // Helper macro to make creating an object (where you need to get back a derived type) easier 26 #define CREATE(className, classEnum) \ 27 reinterpret_cast<className *>(this->createObj(classEnum)) 28 29 // Helper macro to make creating an object (where you need to get back a derived type) easier 30 #define FIND(id, className, classEnum) \ 31 reinterpret_cast<className *>(this->findObject(id, classEnum)) 32 33 class DebugInterface : public GrGLTestInterface { 34 public: 35 DebugInterface() 36 : fCurrGenericID(0) 37 , fCurrTextureUnit(0) 38 , fVertexArray(nullptr) 39 , fPackRowLength(0) 40 , fUnpackRowLength(0) 41 , fPackAlignment(4) 42 , fFrameBuffer(nullptr) 43 , fRenderBuffer(nullptr) 44 , fProgram(nullptr) 45 , fAbandoned(false) { 46 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { 47 fTextureUnits[i] = 48 reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit_ObjTypes)); 49 fTextureUnits[i]->ref(); 50 fTextureUnits[i]->setNumber(i); 51 } 52 memset(fBoundBuffers, 0, sizeof(fBoundBuffers)); 53 this->init(kGL_GrGLStandard); 54 } 55 56 ~DebugInterface() override { 57 // unref & delete the texture units first so they don't show up on the leak report 58 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { 59 fTextureUnits[i]->unref(); 60 fTextureUnits[i]->deleteAction(); 61 } 62 for (int i = 0; i < fObjects.count(); ++i) { 63 delete fObjects[i]; 64 } 65 fObjects.reset(); 66 67 memset(fBoundBuffers, 0, sizeof(fBoundBuffers)); 68 fVertexArray = nullptr; 69 70 this->report(); 71 } 72 73 void abandon() const override { fAbandoned = true; } 74 75 GrGLvoid activeTexture(GrGLenum texture) override { 76 // Ganesh offsets the texture unit indices 77 texture -= GR_GL_TEXTURE0; 78 GrAlwaysAssert(texture < kDefaultMaxTextureUnits); 79 fCurrTextureUnit = texture; 80 } 81 82 GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override { 83 84 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes); 85 GrAlwaysAssert(program); 86 87 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); 88 GrAlwaysAssert(shader); 89 90 program->AttachShader(shader); 91 } 92 93 //////////////////////////////////////////////////////////////////////////////// 94 GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override { 95 GrAlwaysAssert(target == GR_GL_TEXTURE_2D || 96 target == GR_GL_TEXTURE_RECTANGLE || 97 target == GR_GL_TEXTURE_EXTERNAL); 98 99 // a textureID of 0 is acceptable - it binds to the default texture target 100 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes); 101 102 this->setTexture(texture); 103 } 104 105 GrGLboolean isTexture(GrGLuint textureID) override { 106 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes); 107 108 return texture ? GR_GL_TRUE : GR_GL_FALSE; 109 } 110 111 //////////////////////////////////////////////////////////////////////////////// 112 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, 113 GrGLenum usage) override { 114 GrAlwaysAssert(size >= 0); 115 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || 116 GR_GL_STATIC_DRAW == usage || 117 GR_GL_DYNAMIC_DRAW == usage); 118 119 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)]; 120 GrAlwaysAssert(buffer); 121 GrAlwaysAssert(buffer->getBound()); 122 123 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); 124 buffer->setUsage(usage); 125 } 126 127 128 GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override { 129 130 switch (pname) { 131 case GR_GL_UNPACK_ROW_LENGTH: 132 fUnpackRowLength = param; 133 break; 134 case GR_GL_PACK_ROW_LENGTH: 135 fPackRowLength = param; 136 break; 137 case GR_GL_UNPACK_ALIGNMENT: 138 break; 139 case GR_GL_PACK_ALIGNMENT: 140 fPackAlignment = param; 141 break; 142 default: 143 GrAlwaysAssert(false); 144 break; 145 } 146 } 147 148 GrGLvoid readPixels(GrGLint x, 149 GrGLint y, 150 GrGLsizei width, 151 GrGLsizei height, 152 GrGLenum format, 153 GrGLenum type, 154 GrGLvoid* pixels) override { 155 156 GrGLint pixelsInRow = width; 157 if (fPackRowLength > 0) { 158 pixelsInRow = fPackRowLength; 159 } 160 161 GrGLint componentsPerPixel = 0; 162 163 switch (format) { 164 case GR_GL_RGBA: 165 // fallthrough 166 case GR_GL_BGRA: 167 componentsPerPixel = 4; 168 break; 169 case GR_GL_RGB: 170 componentsPerPixel = 3; 171 break; 172 case GR_GL_RED: 173 componentsPerPixel = 1; 174 break; 175 default: 176 GrAlwaysAssert(false); 177 break; 178 } 179 180 GrGLint alignment = fPackAlignment; 181 182 GrGLint componentSize = 0; // size (in bytes) of a single component 183 184 switch (type) { 185 case GR_GL_UNSIGNED_BYTE: 186 componentSize = 1; 187 break; 188 default: 189 GrAlwaysAssert(false); 190 break; 191 } 192 193 GrGLint rowStride = 0; // number of components (not bytes) to skip 194 if (componentSize >= alignment) { 195 rowStride = componentsPerPixel * pixelsInRow; 196 } else { 197 float fTemp = 198 sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / 199 static_cast<float>(alignment)); 200 rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); 201 } 202 203 GrGLchar *scanline = static_cast<GrGLchar *>(pixels); 204 for (int y = 0; y < height; ++y) { 205 memset(scanline, 0, componentsPerPixel * componentSize * width); 206 scanline += rowStride; 207 } 208 } 209 210 GrGLvoid useProgram(GrGLuint programID) override { 211 212 // A programID of 0 is legal 213 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes); 214 215 this->useProgram(program); 216 } 217 218 GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override { 219 220 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || 221 GR_GL_READ_FRAMEBUFFER == target || 222 GR_GL_DRAW_FRAMEBUFFER); 223 224 // a frameBufferID of 0 is acceptable - it binds to the default 225 // frame buffer 226 GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj, 227 kFrameBuffer_ObjTypes); 228 229 this->setFrameBuffer(frameBuffer); 230 } 231 232 GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) override { 233 234 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 235 236 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer 237 GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj, 238 kRenderBuffer_ObjTypes); 239 240 this->setRenderBuffer(renderBuffer); 241 } 242 243 GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override { 244 // first potentially unbind the texture 245 for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) { 246 GrTextureUnitObj *pTU = this->getTextureUnit(i); 247 248 if (pTU->getTexture()) { 249 for (int j = 0; j < n; ++j) { 250 251 if (textures[j] == pTU->getTexture()->getID()) { 252 // this ID is the current texture - revert the binding to 0 253 pTU->setTexture(nullptr); 254 } 255 } 256 } 257 } 258 259 // TODO: fuse the following block with DeleteRenderBuffers? 260 // Open GL will remove a deleted render buffer from the active 261 // frame buffer but not from any other frame buffer 262 if (this->getFrameBuffer()) { 263 264 GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); 265 266 for (int i = 0; i < n; ++i) { 267 268 if (frameBuffer->getColor() && 269 textures[i] == frameBuffer->getColor()->getID()) { 270 frameBuffer->setColor(nullptr); 271 } 272 if (frameBuffer->getDepth() && 273 textures[i] == frameBuffer->getDepth()->getID()) { 274 frameBuffer->setDepth(nullptr); 275 } 276 if (frameBuffer->getStencil() && 277 textures[i] == frameBuffer->getStencil()->getID()) { 278 frameBuffer->setStencil(nullptr); 279 } 280 } 281 } 282 283 // then actually "delete" the buffers 284 for (int i = 0; i < n; ++i) { 285 GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_ObjTypes); 286 GrAlwaysAssert(buffer); 287 288 // OpenGL gives no guarantees if a texture is deleted while attached to 289 // something other than the currently bound frame buffer 290 GrAlwaysAssert(!buffer->getBound()); 291 292 GrAlwaysAssert(!buffer->getDeleted()); 293 buffer->deleteAction(); 294 } 295 296 } 297 298 GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) override { 299 300 // first potentially unbind the buffers 301 if (this->getFrameBuffer()) { 302 for (int i = 0; i < n; ++i) { 303 304 if (frameBuffers[i] == 305 this->getFrameBuffer()->getID()) { 306 // this ID is the current frame buffer - rebind to the default 307 this->setFrameBuffer(nullptr); 308 } 309 } 310 } 311 312 // then actually "delete" the buffers 313 for (int i = 0; i < n; ++i) { 314 GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj, 315 kFrameBuffer_ObjTypes); 316 GrAlwaysAssert(buffer); 317 318 GrAlwaysAssert(!buffer->getDeleted()); 319 buffer->deleteAction(); 320 } 321 } 322 323 GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) override { 324 325 // first potentially unbind the buffers 326 if (this->getRenderBuffer()) { 327 for (int i = 0; i < n; ++i) { 328 329 if (renderBuffers[i] == 330 this->getRenderBuffer()->getID()) { 331 // this ID is the current render buffer - make no 332 // render buffer be bound 333 this->setRenderBuffer(nullptr); 334 } 335 } 336 } 337 338 // TODO: fuse the following block with DeleteTextures? 339 // Open GL will remove a deleted render buffer from the active frame 340 // buffer but not from any other frame buffer 341 if (this->getFrameBuffer()) { 342 343 GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); 344 345 for (int i = 0; i < n; ++i) { 346 347 if (frameBuffer->getColor() && 348 renderBuffers[i] == frameBuffer->getColor()->getID()) { 349 frameBuffer->setColor(nullptr); 350 } 351 if (frameBuffer->getDepth() && 352 renderBuffers[i] == frameBuffer->getDepth()->getID()) { 353 frameBuffer->setDepth(nullptr); 354 } 355 if (frameBuffer->getStencil() && 356 renderBuffers[i] == frameBuffer->getStencil()->getID()) { 357 frameBuffer->setStencil(nullptr); 358 } 359 } 360 } 361 362 // then actually "delete" the buffers 363 for (int i = 0; i < n; ++i) { 364 GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferObj, 365 kRenderBuffer_ObjTypes); 366 GrAlwaysAssert(buffer); 367 368 // OpenGL gives no guarantees if a render buffer is deleted 369 // while attached to something other than the currently 370 // bound frame buffer 371 GrAlwaysAssert(!buffer->getColorBound()); 372 GrAlwaysAssert(!buffer->getDepthBound()); 373 // However, at GrContext destroy time we release all GrRsources and so stencil buffers 374 // may get deleted before FBOs that refer to them. 375 //GrAlwaysAssert(!buffer->getStencilBound()); 376 377 GrAlwaysAssert(!buffer->getDeleted()); 378 buffer->deleteAction(); 379 } 380 } 381 382 GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, 383 GrGLsizei height) override { 384 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 385 GrRenderBufferObj* renderBuffer = this->getRenderBuffer(); 386 GrAlwaysAssert(renderBuffer); 387 renderBuffer->setNumSamples(1); 388 } 389 390 GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, 391 GrGLenum internalformat, GrGLsizei width, 392 GrGLsizei height) override { 393 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 394 GrRenderBufferObj* renderBuffer = this->getRenderBuffer(); 395 GrAlwaysAssert(renderBuffer); 396 renderBuffer->setNumSamples(samples); 397 } 398 399 GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat, 400 GrGLsizei width, GrGLsizei height) override { 401 SK_ABORT("Not implemented"); 402 } 403 404 GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples, 405 GrGLenum GrGLinternalformat, GrGLsizei width, 406 GrGLsizei height) override { 407 SK_ABORT("Not implemented"); 408 } 409 410 GrGLvoid framebufferRenderbuffer(GrGLenum target, 411 GrGLenum attachment, 412 GrGLenum renderbuffertarget, 413 GrGLuint renderBufferID) override { 414 415 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 416 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 417 GR_GL_DEPTH_ATTACHMENT == attachment || 418 GR_GL_STENCIL_ATTACHMENT == attachment); 419 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); 420 421 GrFrameBufferObj *framebuffer = this->getFrameBuffer(); 422 // A render buffer cannot be attached to the default framebuffer 423 GrAlwaysAssert(framebuffer); 424 425 // a renderBufferID of 0 is acceptable - it unbinds the current 426 // render buffer 427 GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferObj, 428 kRenderBuffer_ObjTypes); 429 430 switch (attachment) { 431 case GR_GL_COLOR_ATTACHMENT0: 432 framebuffer->setColor(renderbuffer); 433 break; 434 case GR_GL_DEPTH_ATTACHMENT: 435 framebuffer->setDepth(renderbuffer); 436 break; 437 case GR_GL_STENCIL_ATTACHMENT: 438 framebuffer->setStencil(renderbuffer); 439 break; 440 default: 441 GrAlwaysAssert(false); 442 break; 443 }; 444 445 } 446 447 GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment, 448 GrGLenum renderbuffertarget, 449 GrGLuint renderbuffer) override { 450 SK_ABORT("Not implemented"); 451 } 452 453 //////////////////////////////////////////////////////////////////////////////// 454 GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, 455 GrGLuint textureID, GrGLint level) override { 456 457 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 458 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 459 GR_GL_DEPTH_ATTACHMENT == attachment || 460 GR_GL_STENCIL_ATTACHMENT == attachment); 461 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); 462 463 GrFrameBufferObj *framebuffer = this->getFrameBuffer(); 464 // A texture cannot be attached to the default framebuffer 465 GrAlwaysAssert(framebuffer); 466 467 // A textureID of 0 is allowed - it unbinds the currently bound texture 468 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes); 469 if (texture) { 470 // The texture shouldn't be bound to a texture unit - this 471 // could lead to a feedback loop 472 GrAlwaysAssert(!texture->getBound()); 473 } 474 475 GrAlwaysAssert(0 == level); 476 477 switch (attachment) { 478 case GR_GL_COLOR_ATTACHMENT0: 479 framebuffer->setColor(texture); 480 break; 481 case GR_GL_DEPTH_ATTACHMENT: 482 framebuffer->setDepth(texture); 483 break; 484 case GR_GL_STENCIL_ATTACHMENT: 485 framebuffer->setStencil(texture); 486 break; 487 default: 488 GrAlwaysAssert(false); 489 break; 490 }; 491 } 492 493 GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachment, 494 GrGLenum textarget, GrGLuint texture, GrGLint level, 495 GrGLsizei samples) override { 496 SK_ABORT("Not implemented"); 497 } 498 499 GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment, 500 GrGLenum textarget, GrGLuint texture, 501 GrGLint level) override { 502 SK_ABORT("Not implemented"); 503 } 504 505 GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment, 506 GrGLenum textarget, GrGLuint texture, 507 GrGLint level) override { 508 SK_ABORT("Not implemented"); 509 } 510 511 GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment, 512 GrGLenum textarget, GrGLuint texture, GrGLint level, 513 GrGLint zoffset) override { 514 SK_ABORT("Not implemented"); 515 } 516 517 GrGLuint createProgram() override { 518 519 GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes); 520 521 return program->getID(); 522 } 523 524 GrGLuint createShader(GrGLenum type) override { 525 526 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || 527 GR_GL_FRAGMENT_SHADER == type); 528 529 GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes); 530 shader->setType(type); 531 532 return shader->getID(); 533 } 534 535 GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; } 536 537 GrGLvoid deleteProgram(GrGLuint programID) override { 538 539 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes); 540 GrAlwaysAssert(program); 541 542 if (program->getRefCount()) { 543 // someone is still using this program so we can't delete it here 544 program->setMarkedForDeletion(); 545 } else { 546 program->deleteAction(); 547 } 548 } 549 550 GrGLvoid deleteShader(GrGLuint shaderID) override { 551 552 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); 553 GrAlwaysAssert(shader); 554 555 if (shader->getRefCount()) { 556 // someone is still using this shader so we can't delete it here 557 shader->setMarkedForDeletion(); 558 } else { 559 shader->deleteAction(); 560 } 561 } 562 563 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { 564 this->genObjs(kBuffer_ObjTypes, n, ids); 565 } 566 567 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override { 568 this->genObjs(kFrameBuffer_ObjTypes, n, ids); 569 } 570 571 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override { 572 this->genObjs(kRenderBuffer_ObjTypes, n, ids); 573 } 574 575 GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override { 576 this->genObjs(kTexture_ObjTypes, n, ids); 577 } 578 579 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override { 580 this->genObjs(kVertexArray_ObjTypes, n, ids); 581 } 582 583 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); } 584 585 GrGLenum getError() override { return GR_GL_NO_ERROR; } 586 587 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { 588 // TODO: remove from Ganesh the #defines for gets we don't use. 589 // We would like to minimize gets overall due to performance issues 590 switch (pname) { 591 case GR_GL_CONTEXT_PROFILE_MASK: 592 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; 593 break; 594 case GR_GL_STENCIL_BITS: 595 *params = 8; 596 break; 597 case GR_GL_SAMPLES: { 598 GrFrameBufferObj* framebuffer = this->getFrameBuffer(); 599 GrAlwaysAssert(framebuffer); 600 int numSamples = 0; 601 602 if (GrFBBindableObj* stencil = framebuffer->getStencil()) { 603 numSamples = stencil->numSamples(); 604 } 605 if (GrFBBindableObj* depth = framebuffer->getDepth()) { 606 GrAlwaysAssert(!numSamples || numSamples == depth->numSamples()); 607 numSamples = depth->numSamples(); 608 } 609 if (GrFBBindableObj* color = framebuffer->getColor()) { 610 GrAlwaysAssert(!numSamples || numSamples == color->numSamples()); 611 numSamples = color->numSamples(); 612 } 613 GrAlwaysAssert(numSamples); 614 *params = numSamples; 615 break; 616 } 617 case GR_GL_FRAMEBUFFER_BINDING: 618 *params = 0; 619 break; 620 case GR_GL_VIEWPORT: 621 params[0] = 0; 622 params[1] = 0; 623 params[2] = 800; 624 params[3] = 600; 625 break; 626 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 627 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: 628 case GR_GL_MAX_TEXTURE_IMAGE_UNITS: 629 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 630 *params = 8; 631 break; 632 case GR_GL_MAX_TEXTURE_COORDS: 633 *params = 8; 634 break; 635 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS: 636 *params = kDefaultMaxVertexUniformVectors; 637 break; 638 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: 639 *params = kDefaultMaxFragmentUniformVectors; 640 break; 641 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 642 *params = 16 * 4; 643 break; 644 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: 645 *params = 0; 646 break; 647 case GR_GL_COMPRESSED_TEXTURE_FORMATS: 648 break; 649 case GR_GL_MAX_TEXTURE_SIZE: 650 *params = 8192; 651 break; 652 case GR_GL_MAX_RENDERBUFFER_SIZE: 653 *params = 8192; 654 break; 655 case GR_GL_MAX_SAMPLES: 656 *params = 32; 657 break; 658 case GR_GL_MAX_VERTEX_ATTRIBS: 659 *params = kDefaultMaxVertexAttribs; 660 break; 661 case GR_GL_MAX_VARYING_VECTORS: 662 *params = kDefaultMaxVaryingVectors; 663 break; 664 case GR_GL_NUM_EXTENSIONS: { 665 GrGLint i = 0; 666 while (kExtensions[i++]); 667 *params = i; 668 break; 669 } 670 default: 671 SK_ABORT("Unexpected pname to GetIntegerv"); 672 } 673 } 674 675 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override { 676 val[0] = val[1] = 0.5f; 677 } 678 679 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override { 680 this->getShaderOrProgramiv(program, pname, params); 681 } 682 683 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, 684 char* infolog) override { 685 this->getInfoLog(program, bufsize, length, infolog); 686 } 687 688 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override { 689 switch (pname) { 690 case GR_GL_CURRENT_QUERY: 691 *params = 0; 692 break; 693 case GR_GL_QUERY_COUNTER_BITS: 694 *params = 32; 695 break; 696 default: 697 SK_ABORT("Unexpected pname passed GetQueryiv."); 698 } 699 } 700 701 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override { 702 this->queryResult(id, pname, params); 703 } 704 705 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override { 706 this->queryResult(id, pname, params); 707 } 708 709 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override { 710 this->queryResult(id, pname, params); 711 } 712 713 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override { 714 this->queryResult(id, pname, params); 715 } 716 717 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override { 718 this->getShaderOrProgramiv(shader, pname, params); 719 } 720 721 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length, 722 char* infolog) override { 723 this->getInfoLog(shader, bufsize, length, infolog); 724 } 725 726 const GrGLubyte* getString(GrGLenum name) override { 727 switch (name) { 728 case GR_GL_EXTENSIONS: 729 return CombinedExtensionString(); 730 case GR_GL_VERSION: 731 return (const GrGLubyte*)"4.0 Debug GL"; 732 case GR_GL_SHADING_LANGUAGE_VERSION: 733 return (const GrGLubyte*)"4.20.8 Debug GLSL"; 734 case GR_GL_VENDOR: 735 return (const GrGLubyte*)"Debug Vendor"; 736 case GR_GL_RENDERER: 737 return (const GrGLubyte*)"The Debug (Non-)Renderer"; 738 default: 739 SK_ABORT("Unexpected name passed to GetString"); 740 return nullptr; 741 } 742 } 743 744 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override { 745 switch (name) { 746 case GR_GL_EXTENSIONS: { 747 GrGLint count; 748 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count); 749 if ((GrGLint)i <= count) { 750 return (const GrGLubyte*) kExtensions[i]; 751 } else { 752 return nullptr; 753 } 754 } 755 default: 756 SK_ABORT("Unexpected name passed to GetStringi"); 757 return nullptr; 758 } 759 } 760 761 GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, 762 GrGLint* params) override { 763 // we used to use this to query stuff about externally created textures, 764 // now we just require clients to tell us everything about the texture. 765 SK_ABORT("Should never query texture parameters."); 766 } 767 768 GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override { 769 for (GrGLsizei i = 0; i < n; ++i) { 770 GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArray_ObjTypes); 771 GrAlwaysAssert(array); 772 773 // Deleting the current vertex array binds object 0 774 if (this->getVertexArray() == array) { 775 this->setVertexArray(nullptr); 776 } 777 778 if (array->getRefCount()) { 779 // someone is still using this vertex array so we can't delete it here 780 array->setMarkedForDeletion(); 781 } else { 782 array->deleteAction(); 783 } 784 } 785 } 786 787 GrGLvoid bindVertexArray(GrGLuint id) override { 788 GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTypes); 789 GrAlwaysAssert((0 == id) || array); 790 this->setVertexArray(array); 791 } 792 793 GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override { 794 GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes); 795 // 0 is a permissible bufferID - it unbinds the current buffer 796 797 this->setBuffer(GetBufferIndex(target), buffer); 798 } 799 800 // deleting a bound buffer has the side effect of binding 0 801 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override { 802 // first potentially unbind the buffers 803 for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) { 804 GrBufferObj* buffer = fBoundBuffers[buffIdx]; 805 if (!buffer) { 806 continue; 807 } 808 for (int i = 0; i < n; ++i) { 809 if (ids[i] == buffer->getID()) { 810 this->setBuffer(buffIdx, nullptr); 811 break; 812 } 813 } 814 } 815 816 // then actually "delete" the buffers 817 for (int i = 0; i < n; ++i) { 818 GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes); 819 GrAlwaysAssert(buffer); 820 821 GrAlwaysAssert(!buffer->getDeleted()); 822 buffer->deleteAction(); 823 } 824 } 825 826 // map a buffer to the caller's address space 827 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length, 828 GrGLbitfield access) override { 829 // We only expect read access and we expect that the buffer or range is always invalidated. 830 GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access)); 831 GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access); 832 833 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)]; 834 if (buffer) { 835 GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize()); 836 GrAlwaysAssert(!buffer->getMapped()); 837 buffer->setMapped(offset, length); 838 return buffer->getDataPtr() + offset; 839 } 840 841 GrAlwaysAssert(false); 842 return nullptr; // no buffer bound to the target 843 } 844 845 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { 846 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); 847 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)]; 848 return this->mapBufferRange(target, 0, buffer->getSize(), 849 GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT); 850 } 851 852 // remove a buffer from the caller's address space 853 // TODO: check if the "access" method from "glMapBuffer" was honored 854 GrGLboolean unmapBuffer(GrGLenum target) override { 855 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)]; 856 if (buffer) { 857 GrAlwaysAssert(buffer->getMapped()); 858 buffer->resetMapped(); 859 return GR_GL_TRUE; 860 } 861 862 GrAlwaysAssert(false); 863 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; 864 } 865 866 GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset, 867 GrGLsizeiptr length) override { 868 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)]; 869 if (buffer) { 870 GrAlwaysAssert(buffer->getMapped()); 871 GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength()); 872 } else { 873 GrAlwaysAssert(false); 874 } 875 } 876 877 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) override { 878 879 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || 880 GR_GL_BUFFER_USAGE == value); 881 882 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)]; 883 GrAlwaysAssert(buffer); 884 885 switch (value) { 886 case GR_GL_BUFFER_MAPPED: 887 *params = GR_GL_FALSE; 888 if (buffer) 889 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; 890 break; 891 case GR_GL_BUFFER_SIZE: 892 *params = 0; 893 if (buffer) 894 *params = SkToInt(buffer->getSize()); 895 break; 896 case GR_GL_BUFFER_USAGE: 897 *params = GR_GL_STATIC_DRAW; 898 if (buffer) 899 *params = buffer->getUsage(); 900 break; 901 default: 902 SK_ABORT("Unexpected value to glGetBufferParamateriv"); 903 break; 904 } 905 } 906 907 private: 908 inline int static GetBufferIndex(GrGLenum glTarget) { 909 switch (glTarget) { 910 default: SK_ABORT("Unexpected GL target to GetBufferIndex"); 911 case GR_GL_ARRAY_BUFFER: return 0; 912 case GR_GL_ELEMENT_ARRAY_BUFFER: return 1; 913 case GR_GL_TEXTURE_BUFFER: return 2; 914 case GR_GL_DRAW_INDIRECT_BUFFER: return 3; 915 } 916 } 917 constexpr int static kNumBufferTargets = 4; 918 919 // the OpenGLES 2.0 spec says this must be >= 128 920 static const GrGLint kDefaultMaxVertexUniformVectors = 128; 921 922 // the OpenGLES 2.0 spec says this must be >=16 923 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; 924 925 // the OpenGLES 2.0 spec says this must be >= 8 926 static const GrGLint kDefaultMaxVertexAttribs = 8; 927 928 // the OpenGLES 2.0 spec says this must be >= 8 929 static const GrGLint kDefaultMaxVaryingVectors = 8; 930 931 // the OpenGLES 2.0 spec says this must be >= 2 932 static const GrGLint kDefaultMaxTextureUnits = 8; 933 934 static const char* kExtensions[]; 935 936 GrGLuint fCurrGenericID; 937 GrGLuint fCurrTextureUnit; 938 GrTextureUnitObj* fTextureUnits[kDefaultMaxTextureUnits]; 939 GrBufferObj* fBoundBuffers[kNumBufferTargets]; 940 GrVertexArrayObj* fVertexArray; 941 GrGLint fPackRowLength; 942 GrGLint fUnpackRowLength; 943 GrGLint fPackAlignment; 944 GrFrameBufferObj* fFrameBuffer; 945 GrRenderBufferObj* fRenderBuffer; 946 GrProgramObj* fProgram; 947 mutable bool fAbandoned; 948 // global store of all objects 949 SkTArray<GrFakeRefObj *> fObjects; 950 951 static const GrGLubyte* CombinedExtensionString() { 952 static SkString gExtString; 953 static SkMutex gMutex; 954 gMutex.acquire(); 955 if (0 == gExtString.size()) { 956 int i = 0; 957 while (kExtensions[i]) { 958 if (i > 0) { 959 gExtString.append(" "); 960 } 961 gExtString.append(kExtensions[i]); 962 ++i; 963 } 964 } 965 gMutex.release(); 966 return (const GrGLubyte*) gExtString.c_str(); 967 } 968 969 GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) { 970 for (int i = 0; i < n; ++i) { 971 ids[i] = ++fCurrGenericID; 972 } 973 } 974 975 GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length, 976 char* infolog) { 977 if (length) { 978 *length = 0; 979 } 980 if (bufsize > 0) { 981 *infolog = 0; 982 } 983 } 984 985 GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* params) { 986 switch (pname) { 987 case GR_GL_LINK_STATUS: // fallthru 988 case GR_GL_COMPILE_STATUS: 989 *params = GR_GL_TRUE; 990 break; 991 case GR_GL_INFO_LOG_LENGTH: // fallthru 992 case GL_PROGRAM_BINARY_LENGTH: 993 *params = 0; 994 break; 995 // we don't expect any other pnames 996 default: 997 SK_ABORT("Unexpected pname to GetProgramiv"); 998 break; 999 } 1000 } 1001 1002 template <typename T> 1003 void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) { 1004 switch (pname) { 1005 case GR_GL_QUERY_RESULT_AVAILABLE: 1006 *params = GR_GL_TRUE; 1007 break; 1008 case GR_GL_QUERY_RESULT: 1009 *params = 0; 1010 break; 1011 default: 1012 SK_ABORT("Unexpected pname passed to GetQueryObject."); 1013 break; 1014 } 1015 } 1016 1017 enum ObjTypes { 1018 kTexture_ObjTypes = 0, 1019 kBuffer_ObjTypes, 1020 kRenderBuffer_ObjTypes, 1021 kFrameBuffer_ObjTypes, 1022 kShader_ObjTypes, 1023 kProgram_ObjTypes, 1024 kTextureUnit_ObjTypes, 1025 kVertexArray_ObjTypes, 1026 kObjTypeCount 1027 }; 1028 1029 typedef GrFakeRefObj *(*Create)(); 1030 1031 static Create gFactoryFunc[kObjTypeCount]; 1032 1033 GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) { 1034 for (int i = 0; i < n; ++i) { 1035 GrAlwaysAssert(ids[i] == 0); 1036 GrFakeRefObj *obj = this->createObj(type); 1037 GrAlwaysAssert(obj); 1038 ids[i] = obj->getID(); 1039 } 1040 } 1041 1042 GrFakeRefObj* createObj(ObjTypes type) { 1043 GrFakeRefObj *temp = (*gFactoryFunc[type])(); 1044 1045 fObjects.push_back(temp); 1046 1047 return temp; 1048 } 1049 1050 GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) { 1051 for (int i = 0; i < fObjects.count(); ++i) { 1052 if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) { 1053 // The application shouldn't be accessing objects 1054 // that (as far as OpenGL knows) were already deleted 1055 GrAlwaysAssert(!fObjects[i]->getDeleted()); 1056 GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion()); 1057 return fObjects[i]; 1058 } 1059 } 1060 return nullptr; 1061 } 1062 1063 GrTextureUnitObj* getTextureUnit(int unit) { 1064 GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit); 1065 1066 return fTextureUnits[unit]; 1067 } 1068 1069 GrGLvoid setBuffer(int buffIdx, GrBufferObj* buffer) { 1070 if (fBoundBuffers[buffIdx]) { 1071 // automatically break the binding of the old buffer 1072 GrAlwaysAssert(fBoundBuffers[buffIdx]->getBound()); 1073 fBoundBuffers[buffIdx]->resetBound(); 1074 1075 GrAlwaysAssert(!fBoundBuffers[buffIdx]->getDeleted()); 1076 fBoundBuffers[buffIdx]->unref(); 1077 } 1078 1079 if (buffer) { 1080 GrAlwaysAssert(!buffer->getDeleted()); 1081 buffer->ref(); 1082 1083 GrAlwaysAssert(!buffer->getBound()); 1084 buffer->setBound(); 1085 } 1086 1087 fBoundBuffers[buffIdx] = buffer; 1088 } 1089 1090 void setVertexArray(GrVertexArrayObj* vertexArray) { 1091 if (vertexArray) { 1092 SkASSERT(!vertexArray->getDeleted()); 1093 } 1094 SkRefCnt_SafeAssign(fVertexArray, vertexArray); 1095 } 1096 1097 GrVertexArrayObj* getVertexArray() { return fVertexArray; } 1098 1099 void setTexture(GrTextureObj *texture) { 1100 fTextureUnits[fCurrTextureUnit]->setTexture(texture); 1101 } 1102 1103 void setFrameBuffer(GrFrameBufferObj *frameBuffer) { 1104 if (fFrameBuffer) { 1105 GrAlwaysAssert(fFrameBuffer->getBound()); 1106 fFrameBuffer->resetBound(); 1107 1108 GrAlwaysAssert(!fFrameBuffer->getDeleted()); 1109 fFrameBuffer->unref(); 1110 } 1111 1112 fFrameBuffer = frameBuffer; 1113 1114 if (fFrameBuffer) { 1115 GrAlwaysAssert(!fFrameBuffer->getDeleted()); 1116 fFrameBuffer->ref(); 1117 1118 GrAlwaysAssert(!fFrameBuffer->getBound()); 1119 fFrameBuffer->setBound(); 1120 } 1121 } 1122 1123 GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; } 1124 1125 void setRenderBuffer(GrRenderBufferObj *renderBuffer) { 1126 if (fRenderBuffer) { 1127 GrAlwaysAssert(fRenderBuffer->getBound()); 1128 fRenderBuffer->resetBound(); 1129 1130 GrAlwaysAssert(!fRenderBuffer->getDeleted()); 1131 fRenderBuffer->unref(); 1132 } 1133 1134 fRenderBuffer = renderBuffer; 1135 1136 if (fRenderBuffer) { 1137 GrAlwaysAssert(!fRenderBuffer->getDeleted()); 1138 fRenderBuffer->ref(); 1139 1140 GrAlwaysAssert(!fRenderBuffer->getBound()); 1141 fRenderBuffer->setBound(); 1142 } 1143 } 1144 GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; } 1145 1146 void useProgram(GrProgramObj *program) { 1147 if (fProgram) { 1148 GrAlwaysAssert(fProgram->getInUse()); 1149 fProgram->resetInUse(); 1150 1151 GrAlwaysAssert(!fProgram->getDeleted()); 1152 fProgram->unref(); 1153 } 1154 1155 fProgram = program; 1156 1157 if (fProgram) { 1158 GrAlwaysAssert(!fProgram->getDeleted()); 1159 fProgram->ref(); 1160 1161 GrAlwaysAssert(!fProgram->getInUse()); 1162 fProgram->setInUse(); 1163 } 1164 } 1165 1166 void report() const { 1167 for (int i = 0; i < fObjects.count(); ++i) { 1168 if (!fAbandoned) { 1169 GrAlwaysAssert(0 == fObjects[i]->getRefCount()); 1170 GrAlwaysAssert(fObjects[i]->getDeleted()); 1171 } 1172 } 1173 } 1174 1175 typedef GrGLTestInterface INHERITED; 1176 }; 1177 1178 #undef CREATE 1179 #undef FIND 1180 1181 DebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = { 1182 GrTextureObj::createGrTextureObj, 1183 GrBufferObj::createGrBufferObj, 1184 GrRenderBufferObj::createGrRenderBufferObj, 1185 GrFrameBufferObj::createGrFrameBufferObj, 1186 GrShaderObj::createGrShaderObj, 1187 GrProgramObj::createGrProgramObj, 1188 GrTextureUnitObj::createGrTextureUnitObj, 1189 GrVertexArrayObj::createGrVertexArrayObj, 1190 }; 1191 1192 const char* DebugInterface::kExtensions[] = { 1193 "GL_ARB_framebuffer_object", 1194 "GL_ARB_blend_func_extended", 1195 "GL_ARB_timer_query", 1196 "GL_ARB_draw_buffers", 1197 "GL_ARB_occlusion_query", 1198 "GL_EXT_stencil_wrap", 1199 nullptr, // signifies the end of the array. 1200 }; 1201 1202 class DebugGLContext : public sk_gpu_test::GLTestContext { 1203 public: 1204 DebugGLContext() { this->init(sk_make_sp<DebugInterface>()); } 1205 1206 ~DebugGLContext() override { this->teardown(); } 1207 1208 private: 1209 void onPlatformMakeCurrent() const override {} 1210 std::function<void()> onPlatformGetAutoContextRestore() const override { return nullptr; } 1211 void onPlatformSwapBuffers() const override {} 1212 GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nullptr; } 1213 }; 1214 } // anonymous namespace 1215 1216 namespace sk_gpu_test { 1217 GLTestContext* CreateDebugGLTestContext(GLTestContext* shareContext) { 1218 if (shareContext) { 1219 return nullptr; 1220 } 1221 GLTestContext* ctx = new DebugGLContext(); 1222 if (ctx->isValid()) { 1223 return ctx; 1224 } 1225 delete ctx; 1226 return nullptr; 1227 } 1228 } 1229