1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,926 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2012 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "gl/GrGLInterface.h" 1.14 +#include "GrDebugGL.h" 1.15 +#include "GrShaderObj.h" 1.16 +#include "GrProgramObj.h" 1.17 +#include "GrBufferObj.h" 1.18 +#include "GrTextureUnitObj.h" 1.19 +#include "GrTextureObj.h" 1.20 +#include "GrFrameBufferObj.h" 1.21 +#include "GrRenderBufferObj.h" 1.22 +#include "GrVertexArrayObj.h" 1.23 +#include "SkFloatingPoint.h" 1.24 +#include "../GrGLNoOpInterface.h" 1.25 + 1.26 +namespace { // suppress no previous prototype warning 1.27 + 1.28 +//////////////////////////////////////////////////////////////////////////////// 1.29 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) { 1.30 + 1.31 + // Ganesh offsets the texture unit indices 1.32 + texture -= GR_GL_TEXTURE0; 1.33 + GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits()); 1.34 + 1.35 + GrDebugGL::getInstance()->setCurTextureUnit(texture); 1.36 +} 1.37 + 1.38 +//////////////////////////////////////////////////////////////////////////////// 1.39 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, 1.40 + GrGLuint shaderID) { 1.41 + 1.42 + GrProgramObj *program = GR_FIND(programID, GrProgramObj, 1.43 + GrDebugGL::kProgram_ObjTypes); 1.44 + GrAlwaysAssert(program); 1.45 + 1.46 + GrShaderObj *shader = GR_FIND(shaderID, 1.47 + GrShaderObj, 1.48 + GrDebugGL::kShader_ObjTypes); 1.49 + GrAlwaysAssert(shader); 1.50 + 1.51 + program->AttachShader(shader); 1.52 +} 1.53 + 1.54 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) { 1.55 +} 1.56 + 1.57 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, 1.58 + GrGLuint index, 1.59 + const char* name) { 1.60 +} 1.61 + 1.62 +//////////////////////////////////////////////////////////////////////////////// 1.63 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, 1.64 + GrGLuint textureID) { 1.65 + 1.66 + // we don't use cube maps 1.67 + GrAlwaysAssert(target == GR_GL_TEXTURE_2D); 1.68 + // || target == GR_GL_TEXTURE_CUBE_MAP); 1.69 + 1.70 + // a textureID of 0 is acceptable - it binds to the default texture target 1.71 + GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, 1.72 + GrDebugGL::kTexture_ObjTypes); 1.73 + 1.74 + GrDebugGL::getInstance()->setTexture(texture); 1.75 +} 1.76 + 1.77 + 1.78 +//////////////////////////////////////////////////////////////////////////////// 1.79 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target, 1.80 + GrGLsizeiptr size, 1.81 + const GrGLvoid* data, 1.82 + GrGLenum usage) { 1.83 + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 1.84 + GR_GL_ELEMENT_ARRAY_BUFFER == target); 1.85 + GrAlwaysAssert(size >= 0); 1.86 + GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || 1.87 + GR_GL_STATIC_DRAW == usage || 1.88 + GR_GL_DYNAMIC_DRAW == usage); 1.89 + 1.90 + GrBufferObj *buffer = NULL; 1.91 + switch (target) { 1.92 + case GR_GL_ARRAY_BUFFER: 1.93 + buffer = GrDebugGL::getInstance()->getArrayBuffer(); 1.94 + break; 1.95 + case GR_GL_ELEMENT_ARRAY_BUFFER: 1.96 + buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 1.97 + break; 1.98 + default: 1.99 + GrCrash("Unexpected target to glBufferData"); 1.100 + break; 1.101 + } 1.102 + 1.103 + GrAlwaysAssert(buffer); 1.104 + GrAlwaysAssert(buffer->getBound()); 1.105 + 1.106 + buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); 1.107 + buffer->setUsage(usage); 1.108 +} 1.109 + 1.110 + 1.111 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, 1.112 + GrGLint param) { 1.113 + 1.114 + switch (pname) { 1.115 + case GR_GL_UNPACK_ROW_LENGTH: 1.116 + GrDebugGL::getInstance()->setUnPackRowLength(param); 1.117 + break; 1.118 + case GR_GL_PACK_ROW_LENGTH: 1.119 + GrDebugGL::getInstance()->setPackRowLength(param); 1.120 + break; 1.121 + case GR_GL_UNPACK_ALIGNMENT: 1.122 + break; 1.123 + case GR_GL_PACK_ALIGNMENT: 1.124 + GrAlwaysAssert(false); 1.125 + break; 1.126 + default: 1.127 + GrAlwaysAssert(false); 1.128 + break; 1.129 + } 1.130 +} 1.131 + 1.132 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, 1.133 + GrGLint y, 1.134 + GrGLsizei width, 1.135 + GrGLsizei height, 1.136 + GrGLenum format, 1.137 + GrGLenum type, 1.138 + GrGLvoid* pixels) { 1.139 + 1.140 + GrGLint pixelsInRow = width; 1.141 + if (0 < GrDebugGL::getInstance()->getPackRowLength()) { 1.142 + pixelsInRow = GrDebugGL::getInstance()->getPackRowLength(); 1.143 + } 1.144 + 1.145 + GrGLint componentsPerPixel = 0; 1.146 + 1.147 + switch (format) { 1.148 + case GR_GL_RGBA: 1.149 + // fallthrough 1.150 + case GR_GL_BGRA: 1.151 + componentsPerPixel = 4; 1.152 + break; 1.153 + case GR_GL_RGB: 1.154 + componentsPerPixel = 3; 1.155 + break; 1.156 + case GR_GL_RED: 1.157 + componentsPerPixel = 1; 1.158 + break; 1.159 + default: 1.160 + GrAlwaysAssert(false); 1.161 + break; 1.162 + } 1.163 + 1.164 + GrGLint alignment = 4; // the pack alignment (one of 1, 2, 4 or 8) 1.165 + // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT 1.166 + 1.167 + GrGLint componentSize = 0; // size (in bytes) of a single component 1.168 + 1.169 + switch (type) { 1.170 + case GR_GL_UNSIGNED_BYTE: 1.171 + componentSize = 1; 1.172 + break; 1.173 + default: 1.174 + GrAlwaysAssert(false); 1.175 + break; 1.176 + } 1.177 + 1.178 + GrGLint rowStride = 0; // number of components (not bytes) to skip 1.179 + if (componentSize >= alignment) { 1.180 + rowStride = componentsPerPixel * pixelsInRow; 1.181 + } else { 1.182 + float fTemp = 1.183 + sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / 1.184 + static_cast<float>(alignment)); 1.185 + rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); 1.186 + } 1.187 + 1.188 + GrGLchar *scanline = static_cast<GrGLchar *>(pixels); 1.189 + for (int y = 0; y < height; ++y) { 1.190 + memset(scanline, 0, componentsPerPixel * componentSize * width); 1.191 + scanline += rowStride; 1.192 + } 1.193 +} 1.194 + 1.195 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) { 1.196 + 1.197 + // A programID of 0 is legal 1.198 + GrProgramObj *program = GR_FIND(programID, 1.199 + GrProgramObj, 1.200 + GrDebugGL::kProgram_ObjTypes); 1.201 + 1.202 + GrDebugGL::getInstance()->useProgram(program); 1.203 + } 1.204 + 1.205 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, 1.206 + GrGLuint frameBufferID) { 1.207 + 1.208 + GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || 1.209 + GR_GL_READ_FRAMEBUFFER == target || 1.210 + GR_GL_DRAW_FRAMEBUFFER); 1.211 + 1.212 + // a frameBufferID of 0 is acceptable - it binds to the default 1.213 + // frame buffer 1.214 + GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID, 1.215 + GrFrameBufferObj, 1.216 + GrDebugGL::kFrameBuffer_ObjTypes); 1.217 + 1.218 + GrDebugGL::getInstance()->setFrameBuffer(frameBuffer); 1.219 + } 1.220 + 1.221 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) { 1.222 + 1.223 + GrAlwaysAssert(GR_GL_RENDERBUFFER == target); 1.224 + 1.225 + // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer 1.226 + GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID, 1.227 + GrRenderBufferObj, 1.228 + GrDebugGL::kRenderBuffer_ObjTypes); 1.229 + 1.230 + GrDebugGL::getInstance()->setRenderBuffer(renderBuffer); 1.231 + } 1.232 + 1.233 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) { 1.234 + 1.235 + // first potentially unbind the texture 1.236 + // TODO: move this into GrDebugGL as unBindTexture? 1.237 + for (unsigned int i = 0; 1.238 + i < GrDebugGL::getInstance()->getMaxTextureUnits(); 1.239 + ++i) { 1.240 + GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i); 1.241 + 1.242 + if (pTU->getTexture()) { 1.243 + for (int j = 0; j < n; ++j) { 1.244 + 1.245 + if (textures[j] == pTU->getTexture()->getID()) { 1.246 + // this ID is the current texture - revert the binding to 0 1.247 + pTU->setTexture(NULL); 1.248 + } 1.249 + } 1.250 + } 1.251 + } 1.252 + 1.253 + // TODO: fuse the following block with DeleteRenderBuffers? 1.254 + // Open GL will remove a deleted render buffer from the active 1.255 + // frame buffer but not from any other frame buffer 1.256 + if (GrDebugGL::getInstance()->getFrameBuffer()) { 1.257 + 1.258 + GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer(); 1.259 + 1.260 + for (int i = 0; i < n; ++i) { 1.261 + 1.262 + if (NULL != frameBuffer->getColor() && 1.263 + textures[i] == frameBuffer->getColor()->getID()) { 1.264 + frameBuffer->setColor(NULL); 1.265 + } 1.266 + if (NULL != frameBuffer->getDepth() && 1.267 + textures[i] == frameBuffer->getDepth()->getID()) { 1.268 + frameBuffer->setDepth(NULL); 1.269 + } 1.270 + if (NULL != frameBuffer->getStencil() && 1.271 + textures[i] == frameBuffer->getStencil()->getID()) { 1.272 + frameBuffer->setStencil(NULL); 1.273 + } 1.274 + } 1.275 + } 1.276 + 1.277 + // then actually "delete" the buffers 1.278 + for (int i = 0; i < n; ++i) { 1.279 + GrTextureObj *buffer = GR_FIND(textures[i], 1.280 + GrTextureObj, 1.281 + GrDebugGL::kTexture_ObjTypes); 1.282 + GrAlwaysAssert(buffer); 1.283 + 1.284 + // OpenGL gives no guarantees if a texture is deleted while attached to 1.285 + // something other than the currently bound frame buffer 1.286 + GrAlwaysAssert(!buffer->getBound()); 1.287 + 1.288 + GrAlwaysAssert(!buffer->getDeleted()); 1.289 + buffer->deleteAction(); 1.290 + } 1.291 + 1.292 + } 1.293 + 1.294 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, 1.295 + const GrGLuint *frameBuffers) { 1.296 + 1.297 + // first potentially unbind the buffers 1.298 + if (GrDebugGL::getInstance()->getFrameBuffer()) { 1.299 + for (int i = 0; i < n; ++i) { 1.300 + 1.301 + if (frameBuffers[i] == 1.302 + GrDebugGL::getInstance()->getFrameBuffer()->getID()) { 1.303 + // this ID is the current frame buffer - rebind to the default 1.304 + GrDebugGL::getInstance()->setFrameBuffer(NULL); 1.305 + } 1.306 + } 1.307 + } 1.308 + 1.309 + // then actually "delete" the buffers 1.310 + for (int i = 0; i < n; ++i) { 1.311 + GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i], 1.312 + GrFrameBufferObj, 1.313 + GrDebugGL::kFrameBuffer_ObjTypes); 1.314 + GrAlwaysAssert(buffer); 1.315 + 1.316 + GrAlwaysAssert(!buffer->getDeleted()); 1.317 + buffer->deleteAction(); 1.318 + } 1.319 + } 1.320 + 1.321 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, 1.322 + const GrGLuint *renderBuffers) { 1.323 + 1.324 + // first potentially unbind the buffers 1.325 + if (GrDebugGL::getInstance()->getRenderBuffer()) { 1.326 + for (int i = 0; i < n; ++i) { 1.327 + 1.328 + if (renderBuffers[i] == 1.329 + GrDebugGL::getInstance()->getRenderBuffer()->getID()) { 1.330 + // this ID is the current render buffer - make no 1.331 + // render buffer be bound 1.332 + GrDebugGL::getInstance()->setRenderBuffer(NULL); 1.333 + } 1.334 + } 1.335 + } 1.336 + 1.337 + // TODO: fuse the following block with DeleteTextures? 1.338 + // Open GL will remove a deleted render buffer from the active frame 1.339 + // buffer but not from any other frame buffer 1.340 + if (GrDebugGL::getInstance()->getFrameBuffer()) { 1.341 + 1.342 + GrFrameBufferObj *frameBuffer = 1.343 + GrDebugGL::getInstance()->getFrameBuffer(); 1.344 + 1.345 + for (int i = 0; i < n; ++i) { 1.346 + 1.347 + if (NULL != frameBuffer->getColor() && 1.348 + renderBuffers[i] == frameBuffer->getColor()->getID()) { 1.349 + frameBuffer->setColor(NULL); 1.350 + } 1.351 + if (NULL != frameBuffer->getDepth() && 1.352 + renderBuffers[i] == frameBuffer->getDepth()->getID()) { 1.353 + frameBuffer->setDepth(NULL); 1.354 + } 1.355 + if (NULL != frameBuffer->getStencil() && 1.356 + renderBuffers[i] == frameBuffer->getStencil()->getID()) { 1.357 + frameBuffer->setStencil(NULL); 1.358 + } 1.359 + } 1.360 + } 1.361 + 1.362 + // then actually "delete" the buffers 1.363 + for (int i = 0; i < n; ++i) { 1.364 + GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i], 1.365 + GrRenderBufferObj, 1.366 + GrDebugGL::kRenderBuffer_ObjTypes); 1.367 + GrAlwaysAssert(buffer); 1.368 + 1.369 + // OpenGL gives no guarantees if a render buffer is deleted 1.370 + // while attached to something other than the currently 1.371 + // bound frame buffer 1.372 + GrAlwaysAssert(!buffer->getColorBound()); 1.373 + GrAlwaysAssert(!buffer->getDepthBound()); 1.374 + // However, at GrContext destroy time we release all GrRsources and so stencil buffers 1.375 + // may get deleted before FBOs that refer to them. 1.376 + //GrAlwaysAssert(!buffer->getStencilBound()); 1.377 + 1.378 + GrAlwaysAssert(!buffer->getDeleted()); 1.379 + buffer->deleteAction(); 1.380 + } 1.381 + } 1.382 + 1.383 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, 1.384 + GrGLenum attachment, 1.385 + GrGLenum renderbuffertarget, 1.386 + GrGLuint renderBufferID) { 1.387 + 1.388 + GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 1.389 + GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 1.390 + GR_GL_DEPTH_ATTACHMENT == attachment || 1.391 + GR_GL_STENCIL_ATTACHMENT == attachment); 1.392 + GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); 1.393 + 1.394 + GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); 1.395 + // A render buffer cannot be attached to the default framebuffer 1.396 + GrAlwaysAssert(NULL != framebuffer); 1.397 + 1.398 + // a renderBufferID of 0 is acceptable - it unbinds the current 1.399 + // render buffer 1.400 + GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID, 1.401 + GrRenderBufferObj, 1.402 + GrDebugGL::kRenderBuffer_ObjTypes); 1.403 + 1.404 + switch (attachment) { 1.405 + case GR_GL_COLOR_ATTACHMENT0: 1.406 + framebuffer->setColor(renderbuffer); 1.407 + break; 1.408 + case GR_GL_DEPTH_ATTACHMENT: 1.409 + framebuffer->setDepth(renderbuffer); 1.410 + break; 1.411 + case GR_GL_STENCIL_ATTACHMENT: 1.412 + framebuffer->setStencil(renderbuffer); 1.413 + break; 1.414 + default: 1.415 + GrAlwaysAssert(false); 1.416 + break; 1.417 + }; 1.418 + 1.419 + } 1.420 + 1.421 + //////////////////////////////////////////////////////////////////////////////// 1.422 + GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, 1.423 + GrGLenum attachment, 1.424 + GrGLenum textarget, 1.425 + GrGLuint textureID, 1.426 + GrGLint level) { 1.427 + 1.428 + GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); 1.429 + GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || 1.430 + GR_GL_DEPTH_ATTACHMENT == attachment || 1.431 + GR_GL_STENCIL_ATTACHMENT == attachment); 1.432 + GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); 1.433 + 1.434 + GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); 1.435 + // A texture cannot be attached to the default framebuffer 1.436 + GrAlwaysAssert(NULL != framebuffer); 1.437 + 1.438 + // A textureID of 0 is allowed - it unbinds the currently bound texture 1.439 + GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, 1.440 + GrDebugGL::kTexture_ObjTypes); 1.441 + if (texture) { 1.442 + // The texture shouldn't be bound to a texture unit - this 1.443 + // could lead to a feedback loop 1.444 + GrAlwaysAssert(!texture->getBound()); 1.445 + } 1.446 + 1.447 + GrAlwaysAssert(0 == level); 1.448 + 1.449 + switch (attachment) { 1.450 + case GR_GL_COLOR_ATTACHMENT0: 1.451 + framebuffer->setColor(texture); 1.452 + break; 1.453 + case GR_GL_DEPTH_ATTACHMENT: 1.454 + framebuffer->setDepth(texture); 1.455 + break; 1.456 + case GR_GL_STENCIL_ATTACHMENT: 1.457 + framebuffer->setStencil(texture); 1.458 + break; 1.459 + default: 1.460 + GrAlwaysAssert(false); 1.461 + break; 1.462 + }; 1.463 + } 1.464 + 1.465 +GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() { 1.466 + 1.467 + GrProgramObj *program = GR_CREATE(GrProgramObj, 1.468 + GrDebugGL::kProgram_ObjTypes); 1.469 + 1.470 + return program->getID(); 1.471 +} 1.472 + 1.473 +GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) { 1.474 + 1.475 + GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || 1.476 + GR_GL_FRAGMENT_SHADER == type); 1.477 + 1.478 + GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes); 1.479 + shader->setType(type); 1.480 + 1.481 + return shader->getID(); 1.482 +} 1.483 + 1.484 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) { 1.485 + 1.486 + GrProgramObj *program = GR_FIND(programID, 1.487 + GrProgramObj, 1.488 + GrDebugGL::kProgram_ObjTypes); 1.489 + GrAlwaysAssert(program); 1.490 + 1.491 + if (program->getRefCount()) { 1.492 + // someone is still using this program so we can't delete it here 1.493 + program->setMarkedForDeletion(); 1.494 + } else { 1.495 + program->deleteAction(); 1.496 + } 1.497 +} 1.498 + 1.499 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) { 1.500 + 1.501 + GrShaderObj *shader = GR_FIND(shaderID, 1.502 + GrShaderObj, 1.503 + GrDebugGL::kShader_ObjTypes); 1.504 + GrAlwaysAssert(shader); 1.505 + 1.506 + if (shader->getRefCount()) { 1.507 + // someone is still using this shader so we can't delete it here 1.508 + shader->setMarkedForDeletion(); 1.509 + } else { 1.510 + shader->deleteAction(); 1.511 + } 1.512 +} 1.513 + 1.514 +GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type, 1.515 + GrGLsizei n, 1.516 + GrGLuint* ids) { 1.517 + 1.518 + for (int i = 0; i < n; ++i) { 1.519 + GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type); 1.520 + GrAlwaysAssert(obj); 1.521 + ids[i] = obj->getID(); 1.522 + } 1.523 +} 1.524 + 1.525 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) { 1.526 + debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids); 1.527 +} 1.528 + 1.529 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenerateMipmap(GrGLenum level) { 1.530 +} 1.531 + 1.532 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, 1.533 + GrGLuint* ids) { 1.534 + debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids); 1.535 +} 1.536 + 1.537 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, 1.538 + GrGLuint* ids) { 1.539 + debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids); 1.540 +} 1.541 + 1.542 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) { 1.543 + debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids); 1.544 +} 1.545 + 1.546 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenVertexArrays(GrGLsizei n, GrGLuint* ids) { 1.547 + debugGenObjs(GrDebugGL::kVertexArray_ObjTypes, n, ids); 1.548 +} 1.549 + 1.550 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteVertexArrays(GrGLsizei n, const GrGLuint* ids) { 1.551 + for (GrGLsizei i = 0; i < n; ++i) { 1.552 + GrVertexArrayObj* array = 1.553 + GR_FIND(ids[i], GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 1.554 + GrAlwaysAssert(array); 1.555 + 1.556 + // Deleting the current vertex array binds object 0 1.557 + if (GrDebugGL::getInstance()->getVertexArray() == array) { 1.558 + GrDebugGL::getInstance()->setVertexArray(NULL); 1.559 + } 1.560 + 1.561 + if (array->getRefCount()) { 1.562 + // someone is still using this vertex array so we can't delete it here 1.563 + array->setMarkedForDeletion(); 1.564 + } else { 1.565 + array->deleteAction(); 1.566 + } 1.567 + } 1.568 +} 1.569 + 1.570 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) { 1.571 + GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); 1.572 + GrAlwaysAssert((0 == id) || NULL != array); 1.573 + GrDebugGL::getInstance()->setVertexArray(array); 1.574 +} 1.575 + 1.576 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) { 1.577 + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); 1.578 + 1.579 + GrBufferObj *buffer = GR_FIND(bufferID, 1.580 + GrBufferObj, 1.581 + GrDebugGL::kBuffer_ObjTypes); 1.582 + // 0 is a permissible bufferID - it unbinds the current buffer 1.583 + 1.584 + switch (target) { 1.585 + case GR_GL_ARRAY_BUFFER: 1.586 + GrDebugGL::getInstance()->setArrayBuffer(buffer); 1.587 + break; 1.588 + case GR_GL_ELEMENT_ARRAY_BUFFER: 1.589 + GrDebugGL::getInstance()->setElementArrayBuffer(buffer); 1.590 + break; 1.591 + default: 1.592 + GrCrash("Unexpected target to glBindBuffer"); 1.593 + break; 1.594 + } 1.595 +} 1.596 + 1.597 +// deleting a bound buffer has the side effect of binding 0 1.598 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) { 1.599 + // first potentially unbind the buffers 1.600 + for (int i = 0; i < n; ++i) { 1.601 + 1.602 + if (GrDebugGL::getInstance()->getArrayBuffer() && 1.603 + ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) { 1.604 + // this ID is the current array buffer 1.605 + GrDebugGL::getInstance()->setArrayBuffer(NULL); 1.606 + } 1.607 + if (GrDebugGL::getInstance()->getElementArrayBuffer() && 1.608 + ids[i] == 1.609 + GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) { 1.610 + // this ID is the current element array buffer 1.611 + GrDebugGL::getInstance()->setElementArrayBuffer(NULL); 1.612 + } 1.613 + } 1.614 + 1.615 + // then actually "delete" the buffers 1.616 + for (int i = 0; i < n; ++i) { 1.617 + GrBufferObj *buffer = GR_FIND(ids[i], 1.618 + GrBufferObj, 1.619 + GrDebugGL::kBuffer_ObjTypes); 1.620 + GrAlwaysAssert(buffer); 1.621 + 1.622 + GrAlwaysAssert(!buffer->getDeleted()); 1.623 + buffer->deleteAction(); 1.624 + } 1.625 +} 1.626 + 1.627 +// map a buffer to the caller's address space 1.628 +GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) { 1.629 + 1.630 + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 1.631 + GR_GL_ELEMENT_ARRAY_BUFFER == target); 1.632 + // GR_GL_READ_ONLY == access || || GR_GL_READ_WRIT == access); 1.633 + GrAlwaysAssert(GR_GL_WRITE_ONLY == access); 1.634 + 1.635 + GrBufferObj *buffer = NULL; 1.636 + switch (target) { 1.637 + case GR_GL_ARRAY_BUFFER: 1.638 + buffer = GrDebugGL::getInstance()->getArrayBuffer(); 1.639 + break; 1.640 + case GR_GL_ELEMENT_ARRAY_BUFFER: 1.641 + buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 1.642 + break; 1.643 + default: 1.644 + GrCrash("Unexpected target to glMapBuffer"); 1.645 + break; 1.646 + } 1.647 + 1.648 + if (buffer) { 1.649 + GrAlwaysAssert(!buffer->getMapped()); 1.650 + buffer->setMapped(); 1.651 + return buffer->getDataPtr(); 1.652 + } 1.653 + 1.654 + GrAlwaysAssert(false); 1.655 + return NULL; // no buffer bound to the target 1.656 +} 1.657 + 1.658 +// remove a buffer from the caller's address space 1.659 +// TODO: check if the "access" method from "glMapBuffer" was honored 1.660 +GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) { 1.661 + 1.662 + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 1.663 + GR_GL_ELEMENT_ARRAY_BUFFER == target); 1.664 + 1.665 + GrBufferObj *buffer = NULL; 1.666 + switch (target) { 1.667 + case GR_GL_ARRAY_BUFFER: 1.668 + buffer = GrDebugGL::getInstance()->getArrayBuffer(); 1.669 + break; 1.670 + case GR_GL_ELEMENT_ARRAY_BUFFER: 1.671 + buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 1.672 + break; 1.673 + default: 1.674 + GrCrash("Unexpected target to glUnmapBuffer"); 1.675 + break; 1.676 + } 1.677 + 1.678 + if (buffer) { 1.679 + GrAlwaysAssert(buffer->getMapped()); 1.680 + buffer->resetMapped(); 1.681 + return GR_GL_TRUE; 1.682 + } 1.683 + 1.684 + GrAlwaysAssert(false); 1.685 + return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; 1.686 +} 1.687 + 1.688 +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, 1.689 + GrGLenum value, 1.690 + GrGLint* params) { 1.691 + 1.692 + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || 1.693 + GR_GL_ELEMENT_ARRAY_BUFFER == target); 1.694 + GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || 1.695 + GR_GL_BUFFER_USAGE == value); 1.696 + 1.697 + GrBufferObj *buffer = NULL; 1.698 + switch (target) { 1.699 + case GR_GL_ARRAY_BUFFER: 1.700 + buffer = GrDebugGL::getInstance()->getArrayBuffer(); 1.701 + break; 1.702 + case GR_GL_ELEMENT_ARRAY_BUFFER: 1.703 + buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); 1.704 + break; 1.705 + } 1.706 + 1.707 + GrAlwaysAssert(buffer); 1.708 + 1.709 + switch (value) { 1.710 + case GR_GL_BUFFER_MAPPED: 1.711 + *params = GR_GL_FALSE; 1.712 + if (buffer) 1.713 + *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; 1.714 + break; 1.715 + case GR_GL_BUFFER_SIZE: 1.716 + *params = 0; 1.717 + if (buffer) 1.718 + *params = buffer->getSize(); 1.719 + break; 1.720 + case GR_GL_BUFFER_USAGE: 1.721 + *params = GR_GL_STATIC_DRAW; 1.722 + if (buffer) 1.723 + *params = buffer->getUsage(); 1.724 + break; 1.725 + default: 1.726 + GrCrash("Unexpected value to glGetBufferParamateriv"); 1.727 + break; 1.728 + } 1.729 +}; 1.730 +} // end of namespace 1.731 + 1.732 +//////////////////////////////////////////////////////////////////////////////// 1.733 +struct GrDebugGLInterface : public GrGLInterface { 1.734 + 1.735 +public: 1.736 + SK_DECLARE_INST_COUNT(GrDebugGLInterface) 1.737 + 1.738 + GrDebugGLInterface() 1.739 + : fWrapped(NULL) { 1.740 + GrDebugGL::staticRef(); 1.741 + } 1.742 + 1.743 + virtual ~GrDebugGLInterface() { 1.744 + GrDebugGL::staticUnRef(); 1.745 + } 1.746 + 1.747 + void setWrapped(GrGLInterface *interface) { 1.748 + fWrapped.reset(interface); 1.749 + } 1.750 + 1.751 + // TODO: there are some issues w/ wrapping another GL interface inside the 1.752 + // debug interface: 1.753 + // Since none of the "gl" methods are member functions they don't get 1.754 + // a "this" pointer through which to access "fWrapped" 1.755 + // This could be worked around by having all of them access the 1.756 + // "glInterface" pointer - i.e., treating the debug interface as a 1.757 + // true singleton 1.758 + // 1.759 + // The problem with this is that we also want to handle OpenGL 1.760 + // contexts. The natural way to do this is to have multiple debug 1.761 + // interfaces. Each of which represents a separate context. The 1.762 + // static ID count would still uniquify IDs across all of them. 1.763 + // The problem then is that we couldn't treat the debug GL 1.764 + // interface as a singleton (since there would be one for each 1.765 + // context). 1.766 + // 1.767 + // The solution to this is probably to alter SkDebugGlContext's 1.768 + // "makeCurrent" method to make a call like "makeCurrent(this)" to 1.769 + // the debug GL interface (assuming that the application will create 1.770 + // multiple SkGLContextHelper's) to let it switch between the active 1.771 + // context. Everything in the GrDebugGL object would then need to be 1.772 + // moved to a GrContextObj and the GrDebugGL object would just switch 1.773 + // between them. Note that this approach would also require that 1.774 + // SkDebugGLContext wrap an arbitrary other context 1.775 + // and then pass the wrapped interface to the debug GL interface. 1.776 + 1.777 +protected: 1.778 +private: 1.779 + 1.780 + SkAutoTUnref<GrGLInterface> fWrapped; 1.781 + 1.782 + typedef GrGLInterface INHERITED; 1.783 +}; 1.784 + 1.785 +//////////////////////////////////////////////////////////////////////////////// 1.786 +const GrGLInterface* GrGLCreateDebugInterface() { 1.787 + GrGLInterface* interface = SkNEW(GrDebugGLInterface); 1.788 + 1.789 + interface->fStandard = kGL_GrGLStandard; 1.790 + 1.791 + GrGLInterface::Functions* functions = &interface->fFunctions; 1.792 + functions->fActiveTexture = debugGLActiveTexture; 1.793 + functions->fAttachShader = debugGLAttachShader; 1.794 + functions->fBeginQuery = debugGLBeginQuery; 1.795 + functions->fBindAttribLocation = debugGLBindAttribLocation; 1.796 + functions->fBindBuffer = debugGLBindBuffer; 1.797 + functions->fBindFragDataLocation = noOpGLBindFragDataLocation; 1.798 + functions->fBindTexture = debugGLBindTexture; 1.799 + functions->fBindVertexArray = debugGLBindVertexArray; 1.800 + functions->fBlendColor = noOpGLBlendColor; 1.801 + functions->fBlendFunc = noOpGLBlendFunc; 1.802 + functions->fBufferData = debugGLBufferData; 1.803 + functions->fBufferSubData = noOpGLBufferSubData; 1.804 + functions->fClear = noOpGLClear; 1.805 + functions->fClearColor = noOpGLClearColor; 1.806 + functions->fClearStencil = noOpGLClearStencil; 1.807 + functions->fColorMask = noOpGLColorMask; 1.808 + functions->fCompileShader = noOpGLCompileShader; 1.809 + functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; 1.810 + functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; 1.811 + functions->fCreateProgram = debugGLCreateProgram; 1.812 + functions->fCreateShader = debugGLCreateShader; 1.813 + functions->fCullFace = noOpGLCullFace; 1.814 + functions->fDeleteBuffers = debugGLDeleteBuffers; 1.815 + functions->fDeleteProgram = debugGLDeleteProgram; 1.816 + functions->fDeleteQueries = noOpGLDeleteIds; 1.817 + functions->fDeleteShader = debugGLDeleteShader; 1.818 + functions->fDeleteTextures = debugGLDeleteTextures; 1.819 + functions->fDeleteVertexArrays = debugGLDeleteVertexArrays; 1.820 + functions->fDepthMask = noOpGLDepthMask; 1.821 + functions->fDisable = noOpGLDisable; 1.822 + functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; 1.823 + functions->fDrawArrays = noOpGLDrawArrays; 1.824 + functions->fDrawBuffer = noOpGLDrawBuffer; 1.825 + functions->fDrawBuffers = noOpGLDrawBuffers; 1.826 + functions->fDrawElements = noOpGLDrawElements; 1.827 + functions->fEnable = noOpGLEnable; 1.828 + functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; 1.829 + functions->fEndQuery = noOpGLEndQuery; 1.830 + functions->fFinish = noOpGLFinish; 1.831 + functions->fFlush = noOpGLFlush; 1.832 + functions->fFrontFace = noOpGLFrontFace; 1.833 + functions->fGenerateMipmap = debugGLGenerateMipmap; 1.834 + functions->fGenBuffers = debugGLGenBuffers; 1.835 + functions->fGenQueries = noOpGLGenIds; 1.836 + functions->fGenTextures = debugGLGenTextures; 1.837 + functions->fGetBufferParameteriv = debugGLGetBufferParameteriv; 1.838 + functions->fGetError = noOpGLGetError; 1.839 + functions->fGetIntegerv = noOpGLGetIntegerv; 1.840 + functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; 1.841 + functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; 1.842 + functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; 1.843 + functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; 1.844 + functions->fGetQueryiv = noOpGLGetQueryiv; 1.845 + functions->fGetProgramInfoLog = noOpGLGetInfoLog; 1.846 + functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; 1.847 + functions->fGetShaderInfoLog = noOpGLGetInfoLog; 1.848 + functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; 1.849 + functions->fGetString = noOpGLGetString; 1.850 + functions->fGetStringi = noOpGLGetStringi; 1.851 + functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; 1.852 + functions->fGetUniformLocation = noOpGLGetUniformLocation; 1.853 + functions->fGenVertexArrays = debugGLGenVertexArrays; 1.854 + functions->fLoadIdentity = noOpGLLoadIdentity; 1.855 + functions->fLoadMatrixf = noOpGLLoadMatrixf; 1.856 + functions->fLineWidth = noOpGLLineWidth; 1.857 + functions->fLinkProgram = noOpGLLinkProgram; 1.858 + functions->fMatrixMode = noOpGLMatrixMode; 1.859 + functions->fPixelStorei = debugGLPixelStorei; 1.860 + functions->fQueryCounter = noOpGLQueryCounter; 1.861 + functions->fReadBuffer = noOpGLReadBuffer; 1.862 + functions->fReadPixels = debugGLReadPixels; 1.863 + functions->fScissor = noOpGLScissor; 1.864 + functions->fShaderSource = noOpGLShaderSource; 1.865 + functions->fStencilFunc = noOpGLStencilFunc; 1.866 + functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; 1.867 + functions->fStencilMask = noOpGLStencilMask; 1.868 + functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; 1.869 + functions->fStencilOp = noOpGLStencilOp; 1.870 + functions->fStencilOpSeparate = noOpGLStencilOpSeparate; 1.871 + functions->fTexGenfv = noOpGLTexGenfv; 1.872 + functions->fTexGeni = noOpGLTexGeni; 1.873 + functions->fTexImage2D = noOpGLTexImage2D; 1.874 + functions->fTexParameteri = noOpGLTexParameteri; 1.875 + functions->fTexParameteriv = noOpGLTexParameteriv; 1.876 + functions->fTexSubImage2D = noOpGLTexSubImage2D; 1.877 + functions->fTexStorage2D = noOpGLTexStorage2D; 1.878 + functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; 1.879 + functions->fUniform1f = noOpGLUniform1f; 1.880 + functions->fUniform1i = noOpGLUniform1i; 1.881 + functions->fUniform1fv = noOpGLUniform1fv; 1.882 + functions->fUniform1iv = noOpGLUniform1iv; 1.883 + functions->fUniform2f = noOpGLUniform2f; 1.884 + functions->fUniform2i = noOpGLUniform2i; 1.885 + functions->fUniform2fv = noOpGLUniform2fv; 1.886 + functions->fUniform2iv = noOpGLUniform2iv; 1.887 + functions->fUniform3f = noOpGLUniform3f; 1.888 + functions->fUniform3i = noOpGLUniform3i; 1.889 + functions->fUniform3fv = noOpGLUniform3fv; 1.890 + functions->fUniform3iv = noOpGLUniform3iv; 1.891 + functions->fUniform4f = noOpGLUniform4f; 1.892 + functions->fUniform4i = noOpGLUniform4i; 1.893 + functions->fUniform4fv = noOpGLUniform4fv; 1.894 + functions->fUniform4iv = noOpGLUniform4iv; 1.895 + functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; 1.896 + functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; 1.897 + functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; 1.898 + functions->fUseProgram = debugGLUseProgram; 1.899 + functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; 1.900 + functions->fVertexAttribPointer = noOpGLVertexAttribPointer; 1.901 + functions->fViewport = noOpGLViewport; 1.902 + functions->fBindFramebuffer = debugGLBindFramebuffer; 1.903 + functions->fBindRenderbuffer = debugGLBindRenderbuffer; 1.904 + functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; 1.905 + functions->fDeleteFramebuffers = debugGLDeleteFramebuffers; 1.906 + functions->fDeleteRenderbuffers = debugGLDeleteRenderbuffers; 1.907 + functions->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer; 1.908 + functions->fFramebufferTexture2D = debugGLFramebufferTexture2D; 1.909 + functions->fGenFramebuffers = debugGLGenFramebuffers; 1.910 + functions->fGenRenderbuffers = debugGLGenRenderbuffers; 1.911 + functions->fGetFramebufferAttachmentParameteriv = 1.912 + noOpGLGetFramebufferAttachmentParameteriv; 1.913 + functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; 1.914 + functions->fRenderbufferStorage = noOpGLRenderbufferStorage; 1.915 + functions->fRenderbufferStorageMultisample = 1.916 + noOpGLRenderbufferStorageMultisample; 1.917 + functions->fBlitFramebuffer = noOpGLBlitFramebuffer; 1.918 + functions->fResolveMultisampleFramebuffer = 1.919 + noOpGLResolveMultisampleFramebuffer; 1.920 + functions->fMapBuffer = debugGLMapBuffer; 1.921 + functions->fUnmapBuffer = debugGLUnmapBuffer; 1.922 + functions->fBindFragDataLocationIndexed = 1.923 + noOpGLBindFragDataLocationIndexed; 1.924 + 1.925 + interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi, 1.926 + functions->fGetIntegerv); 1.927 + 1.928 + return interface; 1.929 +}