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 |