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