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