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