diff options
Diffstat (limited to 'src/gpu/gl/debug/GrGLCreateDebugInterface.cpp')
-rw-r--r-- | src/gpu/gl/debug/GrGLCreateDebugInterface.cpp | 1942 |
1 files changed, 1093 insertions, 849 deletions
diff --git a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp index d8418fd9f0..43fc8dfad9 100644 --- a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp +++ b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp @@ -8,986 +8,1230 @@ #include "gl/GrGLInterface.h" -#include "GrDebugGL.h" -#include "GrShaderObj.h" -#include "GrProgramObj.h" + #include "GrBufferObj.h" -#include "GrTextureUnitObj.h" -#include "GrTextureObj.h" #include "GrFrameBufferObj.h" +#include "GrProgramObj.h" #include "GrRenderBufferObj.h" +#include "GrShaderObj.h" +#include "GrTextureObj.h" +#include "GrTextureUnitObj.h" #include "GrVertexArrayObj.h" -#include "SkFloatingPoint.h" -#include "../GrGLNoOpInterface.h" +#include "gl/GrGLTestInterface.h" -namespace { // suppress no previous prototype warning +#include "SkMutex.h" -//////////////////////////////////////////////////////////////////////////////// -GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) { +namespace { - // Ganesh offsets the texture unit indices - texture -= GR_GL_TEXTURE0; - GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits()); +// Helper macro to make creating an object (where you need to get back a derived type) easier +#define CREATE(className, classEnum) \ + reinterpret_cast<className *>(this->createObj(classEnum)) - GrDebugGL::getInstance()->setCurTextureUnit(texture); -} +// Helper macro to make creating an object (where you need to get back a derived type) easier +#define FIND(id, className, classEnum) \ + reinterpret_cast<className *>(this->findObject(id, classEnum)) -//////////////////////////////////////////////////////////////////////////////// -GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, - GrGLuint shaderID) { +class DebugInterface : public GrGLTestInterface { +public: + DebugInterface() + : fCurrGenericID(0) + , fCurrTextureUnit(0) + , fArrayBuffer(nullptr) + , fElementArrayBuffer(nullptr) + , fVertexArray(nullptr) + , fPackRowLength(0) + , fUnpackRowLength(0) + , fPackAlignment(4) + , fFrameBuffer(nullptr) + , fRenderBuffer(nullptr) + , fProgram(nullptr) + , fAbandoned(false) { + for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { + fTextureUnits[i] = + reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit_ObjTypes)); + fTextureUnits[i]->ref(); + fTextureUnits[i]->setNumber(i); + } + this->init(kGL_GrGLStandard); + } - GrProgramObj *program = GR_FIND(programID, GrProgramObj, - GrDebugGL::kProgram_ObjTypes); - GrAlwaysAssert(program); + ~DebugInterface() override { + // unref & delete the texture units first so they don't show up on the leak report + for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { + fTextureUnits[i]->unref(); + fTextureUnits[i]->deleteAction(); + } + for (int i = 0; i < fObjects.count(); ++i) { + delete fObjects[i]; + } + fObjects.reset(); - GrShaderObj *shader = GR_FIND(shaderID, - GrShaderObj, - GrDebugGL::kShader_ObjTypes); - GrAlwaysAssert(shader); + fArrayBuffer = nullptr; + fElementArrayBuffer = nullptr; + fVertexArray = nullptr; - program->AttachShader(shader); -} + this->report(); + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) { -} + void abandon() const override { fAbandoned = true; } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, - GrGLuint index, - const char* name) { -} + GrGLvoid activeTexture(GrGLenum texture) override { + // Ganesh offsets the texture unit indices + texture -= GR_GL_TEXTURE0; + GrAlwaysAssert(texture < kDefaultMaxTextureUnits); + fCurrTextureUnit = texture; + } -//////////////////////////////////////////////////////////////////////////////// -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, - GrGLuint textureID) { + GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override { - // we don't use cube maps - GrAlwaysAssert(target == GR_GL_TEXTURE_2D); - // || target == GR_GL_TEXTURE_CUBE_MAP); + GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes); + GrAlwaysAssert(program); - // a textureID of 0 is acceptable - it binds to the default texture target - GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, - GrDebugGL::kTexture_ObjTypes); + GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); + GrAlwaysAssert(shader); - GrDebugGL::getInstance()->setTexture(texture); -} + program->AttachShader(shader); + } + //////////////////////////////////////////////////////////////////////////////// + GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override { + GrAlwaysAssert(target == GR_GL_TEXTURE_2D || + target == GR_GL_TEXTURE_RECTANGLE || + target == GR_GL_TEXTURE_EXTERNAL); -//////////////////////////////////////////////////////////////////////////////// -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target, - GrGLsizeiptr size, - const GrGLvoid* data, - GrGLenum usage) { - GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || - GR_GL_ELEMENT_ARRAY_BUFFER == target); - GrAlwaysAssert(size >= 0); - GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || - GR_GL_STATIC_DRAW == usage || - GR_GL_DYNAMIC_DRAW == usage); - - GrBufferObj *buffer = nullptr; - switch (target) { - case GR_GL_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getArrayBuffer(); - break; - case GR_GL_ELEMENT_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); - break; - default: - SkFAIL("Unexpected target to glBufferData"); - break; - } - - GrAlwaysAssert(buffer); - GrAlwaysAssert(buffer->getBound()); - - buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); - buffer->setUsage(usage); -} - - -GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, - GrGLint param) { - - switch (pname) { - case GR_GL_UNPACK_ROW_LENGTH: - GrDebugGL::getInstance()->setUnPackRowLength(param); - break; - case GR_GL_PACK_ROW_LENGTH: - GrDebugGL::getInstance()->setPackRowLength(param); - break; - case GR_GL_UNPACK_ALIGNMENT: - break; - case GR_GL_PACK_ALIGNMENT: - GrAlwaysAssert(false); - break; - default: - GrAlwaysAssert(false); - break; - } -} - -GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, - GrGLint y, - GrGLsizei width, - GrGLsizei height, - GrGLenum format, - GrGLenum type, - GrGLvoid* pixels) { - - GrGLint pixelsInRow = width; - if (0 < GrDebugGL::getInstance()->getPackRowLength()) { - pixelsInRow = GrDebugGL::getInstance()->getPackRowLength(); - } - - GrGLint componentsPerPixel = 0; - - switch (format) { - case GR_GL_RGBA: - // fallthrough - case GR_GL_BGRA: - componentsPerPixel = 4; - break; - case GR_GL_RGB: - componentsPerPixel = 3; - break; - case GR_GL_RED: - componentsPerPixel = 1; - break; - default: - GrAlwaysAssert(false); - break; + // a textureID of 0 is acceptable - it binds to the default texture target + GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes); + + this->setTexture(texture); } - GrGLint alignment = 4; // the pack alignment (one of 1, 2, 4 or 8) - // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT + //////////////////////////////////////////////////////////////////////////////// + GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, + GrGLenum usage) override { + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || + GR_GL_ELEMENT_ARRAY_BUFFER == target); + GrAlwaysAssert(size >= 0); + GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || + GR_GL_STATIC_DRAW == usage || + GR_GL_DYNAMIC_DRAW == usage); + + GrBufferObj *buffer = nullptr; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = this->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = this->getElementArrayBuffer(); + break; + default: + SkFAIL("Unexpected target to glBufferData"); + break; + } - GrGLint componentSize = 0; // size (in bytes) of a single component + GrAlwaysAssert(buffer); + GrAlwaysAssert(buffer->getBound()); - switch (type) { - case GR_GL_UNSIGNED_BYTE: - componentSize = 1; - break; - default: - GrAlwaysAssert(false); - break; + buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); + buffer->setUsage(usage); } - GrGLint rowStride = 0; // number of components (not bytes) to skip - if (componentSize >= alignment) { - rowStride = componentsPerPixel * pixelsInRow; - } else { - float fTemp = - sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / - static_cast<float>(alignment)); - rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); - } - GrGLchar *scanline = static_cast<GrGLchar *>(pixels); - for (int y = 0; y < height; ++y) { - memset(scanline, 0, componentsPerPixel * componentSize * width); - scanline += rowStride; + GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override { + + switch (pname) { + case GR_GL_UNPACK_ROW_LENGTH: + fUnpackRowLength = param; + break; + case GR_GL_PACK_ROW_LENGTH: + fPackRowLength = param; + break; + case GR_GL_UNPACK_ALIGNMENT: + break; + case GR_GL_PACK_ALIGNMENT: + fPackAlignment = param; + break; + default: + GrAlwaysAssert(false); + break; + } } -} - GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) { + GrGLvoid readPixels(GrGLint x, + GrGLint y, + GrGLsizei width, + GrGLsizei height, + GrGLenum format, + GrGLenum type, + GrGLvoid* pixels) override { + + GrGLint pixelsInRow = width; + if (fPackRowLength > 0) { + pixelsInRow = fPackRowLength; + } - // A programID of 0 is legal - GrProgramObj *program = GR_FIND(programID, - GrProgramObj, - GrDebugGL::kProgram_ObjTypes); + GrGLint componentsPerPixel = 0; + + switch (format) { + case GR_GL_RGBA: + // fallthrough + case GR_GL_BGRA: + componentsPerPixel = 4; + break; + case GR_GL_RGB: + componentsPerPixel = 3; + break; + case GR_GL_RED: + componentsPerPixel = 1; + break; + default: + GrAlwaysAssert(false); + break; + } - GrDebugGL::getInstance()->useProgram(program); - } + GrGLint alignment = fPackAlignment; - GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, - GrGLuint frameBufferID) { + GrGLint componentSize = 0; // size (in bytes) of a single component - GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || - GR_GL_READ_FRAMEBUFFER == target || - GR_GL_DRAW_FRAMEBUFFER); + switch (type) { + case GR_GL_UNSIGNED_BYTE: + componentSize = 1; + break; + default: + GrAlwaysAssert(false); + break; + } - // a frameBufferID of 0 is acceptable - it binds to the default - // frame buffer - GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID, - GrFrameBufferObj, - GrDebugGL::kFrameBuffer_ObjTypes); + GrGLint rowStride = 0; // number of components (not bytes) to skip + if (componentSize >= alignment) { + rowStride = componentsPerPixel * pixelsInRow; + } else { + float fTemp = + sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / + static_cast<float>(alignment)); + rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); + } - GrDebugGL::getInstance()->setFrameBuffer(frameBuffer); - } + GrGLchar *scanline = static_cast<GrGLchar *>(pixels); + for (int y = 0; y < height; ++y) { + memset(scanline, 0, componentsPerPixel * componentSize * width); + scanline += rowStride; + } + } - GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) { + GrGLvoid useProgram(GrGLuint programID) override { - GrAlwaysAssert(GR_GL_RENDERBUFFER == target); + // A programID of 0 is legal + GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes); - // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer - GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID, - GrRenderBufferObj, - GrDebugGL::kRenderBuffer_ObjTypes); + this->useProgram(program); + } + + GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override { - GrDebugGL::getInstance()->setRenderBuffer(renderBuffer); - } + GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || + GR_GL_READ_FRAMEBUFFER == target || + GR_GL_DRAW_FRAMEBUFFER); - GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) { + // a frameBufferID of 0 is acceptable - it binds to the default + // frame buffer + GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj, + kFrameBuffer_ObjTypes); + + this->setFrameBuffer(frameBuffer); + } - // first potentially unbind the texture - // TODO: move this into GrDebugGL as unBindTexture? - for (unsigned int i = 0; - i < GrDebugGL::getInstance()->getMaxTextureUnits(); - ++i) { - GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i); + GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) override { - if (pTU->getTexture()) { - for (int j = 0; j < n; ++j) { + GrAlwaysAssert(GR_GL_RENDERBUFFER == target); + + // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer + GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj, + kRenderBuffer_ObjTypes); + + this->setRenderBuffer(renderBuffer); + } - if (textures[j] == pTU->getTexture()->getID()) { - // this ID is the current texture - revert the binding to 0 - pTU->setTexture(nullptr); + GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override { + // first potentially unbind the texture + for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) { + GrTextureUnitObj *pTU = this->getTextureUnit(i); + + if (pTU->getTexture()) { + for (int j = 0; j < n; ++j) { + + if (textures[j] == pTU->getTexture()->getID()) { + // this ID is the current texture - revert the binding to 0 + pTU->setTexture(nullptr); + } } } } - } - // TODO: fuse the following block with DeleteRenderBuffers? - // Open GL will remove a deleted render buffer from the active - // frame buffer but not from any other frame buffer - if (GrDebugGL::getInstance()->getFrameBuffer()) { + // TODO: fuse the following block with DeleteRenderBuffers? + // Open GL will remove a deleted render buffer from the active + // frame buffer but not from any other frame buffer + if (this->getFrameBuffer()) { - GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer(); + GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); - for (int i = 0; i < n; ++i) { + for (int i = 0; i < n; ++i) { - if (frameBuffer->getColor() && - textures[i] == frameBuffer->getColor()->getID()) { - frameBuffer->setColor(nullptr); - } - if (frameBuffer->getDepth() && - textures[i] == frameBuffer->getDepth()->getID()) { - frameBuffer->setDepth(nullptr); - } - if (frameBuffer->getStencil() && - textures[i] == frameBuffer->getStencil()->getID()) { - frameBuffer->setStencil(nullptr); + if (frameBuffer->getColor() && + textures[i] == frameBuffer->getColor()->getID()) { + frameBuffer->setColor(nullptr); + } + if (frameBuffer->getDepth() && + textures[i] == frameBuffer->getDepth()->getID()) { + frameBuffer->setDepth(nullptr); + } + if (frameBuffer->getStencil() && + textures[i] == frameBuffer->getStencil()->getID()) { + frameBuffer->setStencil(nullptr); + } } } - } - // then actually "delete" the buffers - for (int i = 0; i < n; ++i) { - GrTextureObj *buffer = GR_FIND(textures[i], - GrTextureObj, - GrDebugGL::kTexture_ObjTypes); - GrAlwaysAssert(buffer); + // then actually "delete" the buffers + for (int i = 0; i < n; ++i) { + GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_ObjTypes); + GrAlwaysAssert(buffer); - // OpenGL gives no guarantees if a texture is deleted while attached to - // something other than the currently bound frame buffer - GrAlwaysAssert(!buffer->getBound()); + // OpenGL gives no guarantees if a texture is deleted while attached to + // something other than the currently bound frame buffer + GrAlwaysAssert(!buffer->getBound()); + + GrAlwaysAssert(!buffer->getDeleted()); + buffer->deleteAction(); + } - GrAlwaysAssert(!buffer->getDeleted()); - buffer->deleteAction(); } - } + GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) override { - GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, - const GrGLuint *frameBuffers) { + // first potentially unbind the buffers + if (this->getFrameBuffer()) { + for (int i = 0; i < n; ++i) { - // first potentially unbind the buffers - if (GrDebugGL::getInstance()->getFrameBuffer()) { - for (int i = 0; i < n; ++i) { - - if (frameBuffers[i] == - GrDebugGL::getInstance()->getFrameBuffer()->getID()) { - // this ID is the current frame buffer - rebind to the default - GrDebugGL::getInstance()->setFrameBuffer(nullptr); + if (frameBuffers[i] == + this->getFrameBuffer()->getID()) { + // this ID is the current frame buffer - rebind to the default + this->setFrameBuffer(nullptr); + } } } - } - // then actually "delete" the buffers - for (int i = 0; i < n; ++i) { - GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i], - GrFrameBufferObj, - GrDebugGL::kFrameBuffer_ObjTypes); - GrAlwaysAssert(buffer); + // then actually "delete" the buffers + for (int i = 0; i < n; ++i) { + GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj, + kFrameBuffer_ObjTypes); + GrAlwaysAssert(buffer); - GrAlwaysAssert(!buffer->getDeleted()); - buffer->deleteAction(); + GrAlwaysAssert(!buffer->getDeleted()); + buffer->deleteAction(); + } } - } - GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, - const GrGLuint *renderBuffers) { + GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) override { - // first potentially unbind the buffers - if (GrDebugGL::getInstance()->getRenderBuffer()) { - for (int i = 0; i < n; ++i) { + // first potentially unbind the buffers + if (this->getRenderBuffer()) { + for (int i = 0; i < n; ++i) { - if (renderBuffers[i] == - GrDebugGL::getInstance()->getRenderBuffer()->getID()) { - // this ID is the current render buffer - make no - // render buffer be bound - GrDebugGL::getInstance()->setRenderBuffer(nullptr); + if (renderBuffers[i] == + this->getRenderBuffer()->getID()) { + // this ID is the current render buffer - make no + // render buffer be bound + this->setRenderBuffer(nullptr); + } } } - } - // TODO: fuse the following block with DeleteTextures? - // Open GL will remove a deleted render buffer from the active frame - // buffer but not from any other frame buffer - if (GrDebugGL::getInstance()->getFrameBuffer()) { + // TODO: fuse the following block with DeleteTextures? + // Open GL will remove a deleted render buffer from the active frame + // buffer but not from any other frame buffer + if (this->getFrameBuffer()) { - GrFrameBufferObj *frameBuffer = - GrDebugGL::getInstance()->getFrameBuffer(); + GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); - for (int i = 0; i < n; ++i) { + for (int i = 0; i < n; ++i) { - if (frameBuffer->getColor() && - renderBuffers[i] == frameBuffer->getColor()->getID()) { - frameBuffer->setColor(nullptr); - } - if (frameBuffer->getDepth() && - renderBuffers[i] == frameBuffer->getDepth()->getID()) { - frameBuffer->setDepth(nullptr); - } - if (frameBuffer->getStencil() && - renderBuffers[i] == frameBuffer->getStencil()->getID()) { - frameBuffer->setStencil(nullptr); + if (frameBuffer->getColor() && + renderBuffers[i] == frameBuffer->getColor()->getID()) { + frameBuffer->setColor(nullptr); + } + if (frameBuffer->getDepth() && + renderBuffers[i] == frameBuffer->getDepth()->getID()) { + frameBuffer->setDepth(nullptr); + } + if (frameBuffer->getStencil() && + renderBuffers[i] == frameBuffer->getStencil()->getID()) { + frameBuffer->setStencil(nullptr); + } } } + + // then actually "delete" the buffers + for (int i = 0; i < n; ++i) { + GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferObj, + kRenderBuffer_ObjTypes); + GrAlwaysAssert(buffer); + + // OpenGL gives no guarantees if a render buffer is deleted + // while attached to something other than the currently + // bound frame buffer + GrAlwaysAssert(!buffer->getColorBound()); + GrAlwaysAssert(!buffer->getDepthBound()); + // However, at GrContext destroy time we release all GrRsources and so stencil buffers + // may get deleted before FBOs that refer to them. + //GrAlwaysAssert(!buffer->getStencilBound()); + + GrAlwaysAssert(!buffer->getDeleted()); + buffer->deleteAction(); + } } - // then actually "delete" the buffers - for (int i = 0; i < n; ++i) { - GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i], - GrRenderBufferObj, - GrDebugGL::kRenderBuffer_ObjTypes); - GrAlwaysAssert(buffer); - - // OpenGL gives no guarantees if a render buffer is deleted - // while attached to something other than the currently - // bound frame buffer - GrAlwaysAssert(!buffer->getColorBound()); - GrAlwaysAssert(!buffer->getDepthBound()); - // However, at GrContext destroy time we release all GrRsources and so stencil buffers - // may get deleted before FBOs that refer to them. - //GrAlwaysAssert(!buffer->getStencilBound()); - - GrAlwaysAssert(!buffer->getDeleted()); - buffer->deleteAction(); + GrGLvoid framebufferRenderbuffer(GrGLenum target, + GrGLenum attachment, + GrGLenum renderbuffertarget, + GrGLuint renderBufferID) override { + + GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); + GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || + GR_GL_DEPTH_ATTACHMENT == attachment || + GR_GL_STENCIL_ATTACHMENT == attachment); + GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); + + GrFrameBufferObj *framebuffer = this->getFrameBuffer(); + // A render buffer cannot be attached to the default framebuffer + GrAlwaysAssert(framebuffer); + + // a renderBufferID of 0 is acceptable - it unbinds the current + // render buffer + GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferObj, + kRenderBuffer_ObjTypes); + + switch (attachment) { + case GR_GL_COLOR_ATTACHMENT0: + framebuffer->setColor(renderbuffer); + break; + case GR_GL_DEPTH_ATTACHMENT: + framebuffer->setDepth(renderbuffer); + break; + case GR_GL_STENCIL_ATTACHMENT: + framebuffer->setStencil(renderbuffer); + break; + default: + GrAlwaysAssert(false); + break; + }; + } - } - - GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, - GrGLenum attachment, - GrGLenum renderbuffertarget, - GrGLuint renderBufferID) { - - GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); - GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || - GR_GL_DEPTH_ATTACHMENT == attachment || - GR_GL_STENCIL_ATTACHMENT == attachment); - GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); - - GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); - // A render buffer cannot be attached to the default framebuffer - GrAlwaysAssert(framebuffer); - - // a renderBufferID of 0 is acceptable - it unbinds the current - // render buffer - GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID, - GrRenderBufferObj, - GrDebugGL::kRenderBuffer_ObjTypes); - - switch (attachment) { - case GR_GL_COLOR_ATTACHMENT0: - framebuffer->setColor(renderbuffer); - break; - case GR_GL_DEPTH_ATTACHMENT: - framebuffer->setDepth(renderbuffer); - break; - case GR_GL_STENCIL_ATTACHMENT: - framebuffer->setStencil(renderbuffer); - break; - default: - GrAlwaysAssert(false); - break; - }; - - } - - //////////////////////////////////////////////////////////////////////////////// - GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, - GrGLenum attachment, - GrGLenum textarget, - GrGLuint textureID, - GrGLint level) { - - GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); - GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || - GR_GL_DEPTH_ATTACHMENT == attachment || - GR_GL_STENCIL_ATTACHMENT == attachment); - GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); - - GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); - // A texture cannot be attached to the default framebuffer - GrAlwaysAssert(framebuffer); - - // A textureID of 0 is allowed - it unbinds the currently bound texture - GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, - GrDebugGL::kTexture_ObjTypes); - if (texture) { - // The texture shouldn't be bound to a texture unit - this - // could lead to a feedback loop - GrAlwaysAssert(!texture->getBound()); + + //////////////////////////////////////////////////////////////////////////////// + GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, + GrGLuint textureID, GrGLint level) override { + + GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); + GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || + GR_GL_DEPTH_ATTACHMENT == attachment || + GR_GL_STENCIL_ATTACHMENT == attachment); + GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); + + GrFrameBufferObj *framebuffer = this->getFrameBuffer(); + // A texture cannot be attached to the default framebuffer + GrAlwaysAssert(framebuffer); + + // A textureID of 0 is allowed - it unbinds the currently bound texture + GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes); + if (texture) { + // The texture shouldn't be bound to a texture unit - this + // could lead to a feedback loop + GrAlwaysAssert(!texture->getBound()); + } + + GrAlwaysAssert(0 == level); + + switch (attachment) { + case GR_GL_COLOR_ATTACHMENT0: + framebuffer->setColor(texture); + break; + case GR_GL_DEPTH_ATTACHMENT: + framebuffer->setDepth(texture); + break; + case GR_GL_STENCIL_ATTACHMENT: + framebuffer->setStencil(texture); + break; + default: + GrAlwaysAssert(false); + break; + }; } - GrAlwaysAssert(0 == level); + GrGLuint createProgram() override { + + GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes); - switch (attachment) { - case GR_GL_COLOR_ATTACHMENT0: - framebuffer->setColor(texture); - break; - case GR_GL_DEPTH_ATTACHMENT: - framebuffer->setDepth(texture); - break; - case GR_GL_STENCIL_ATTACHMENT: - framebuffer->setStencil(texture); - break; - default: - GrAlwaysAssert(false); - break; - }; - } + return program->getID(); + } -GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() { + GrGLuint createShader(GrGLenum type) override { - GrProgramObj *program = GR_CREATE(GrProgramObj, - GrDebugGL::kProgram_ObjTypes); + GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || + GR_GL_FRAGMENT_SHADER == type); - return program->getID(); -} + GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes); + shader->setType(type); -GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) { + return shader->getID(); + } - GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || - GR_GL_FRAGMENT_SHADER == type); + GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; } - GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes); - shader->setType(type); + GrGLvoid deleteProgram(GrGLuint programID) override { - return shader->getID(); -} + GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes); + GrAlwaysAssert(program); -GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) { + if (program->getRefCount()) { + // someone is still using this program so we can't delete it here + program->setMarkedForDeletion(); + } else { + program->deleteAction(); + } + } + + GrGLvoid deleteShader(GrGLuint shaderID) override { - GrProgramObj *program = GR_FIND(programID, - GrProgramObj, - GrDebugGL::kProgram_ObjTypes); - GrAlwaysAssert(program); + GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); + GrAlwaysAssert(shader); - if (program->getRefCount()) { - // someone is still using this program so we can't delete it here - program->setMarkedForDeletion(); - } else { - program->deleteAction(); + if (shader->getRefCount()) { + // someone is still using this shader so we can't delete it here + shader->setMarkedForDeletion(); + } else { + shader->deleteAction(); + } + } + + GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { + this->genObjs(kBuffer_ObjTypes, n, ids); + } + + GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override { + this->genObjs(kFrameBuffer_ObjTypes, n, ids); + } + + GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override { + this->genObjs(kRenderBuffer_ObjTypes, n, ids); } -} -GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) { + GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override { + this->genObjs(kTexture_ObjTypes, n, ids); + } + + GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override { + this->genObjs(kVertexArray_ObjTypes, n, ids); + } - GrShaderObj *shader = GR_FIND(shaderID, - GrShaderObj, - GrDebugGL::kShader_ObjTypes); - GrAlwaysAssert(shader); + GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); } + + GrGLenum getError() override { return GR_GL_NO_ERROR; } + + GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { + // TODO: remove from Ganesh the #defines for gets we don't use. + // We would like to minimize gets overall due to performance issues + switch (pname) { + case GR_GL_CONTEXT_PROFILE_MASK: + *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; + break; + case GR_GL_STENCIL_BITS: + *params = 8; + break; + case GR_GL_SAMPLES: + *params = 1; + break; + case GR_GL_FRAMEBUFFER_BINDING: + *params = 0; + break; + case GR_GL_VIEWPORT: + params[0] = 0; + params[1] = 0; + params[2] = 800; + params[3] = 600; + break; + case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: + case GR_GL_MAX_TEXTURE_IMAGE_UNITS: + case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + *params = 8; + break; + case GR_GL_MAX_TEXTURE_COORDS: + *params = 8; + break; + case GR_GL_MAX_VERTEX_UNIFORM_VECTORS: + *params = kDefaultMaxVertexUniformVectors; + break; + case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: + *params = kDefaultMaxFragmentUniformVectors; + break; + case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + *params = 16 * 4; + break; + case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: + *params = 0; + break; + case GR_GL_COMPRESSED_TEXTURE_FORMATS: + break; + case GR_GL_MAX_TEXTURE_SIZE: + *params = 8192; + break; + case GR_GL_MAX_RENDERBUFFER_SIZE: + *params = 8192; + break; + case GR_GL_MAX_SAMPLES: + *params = 32; + break; + case GR_GL_MAX_VERTEX_ATTRIBS: + *params = kDefaultMaxVertexAttribs; + break; + case GR_GL_MAX_VARYING_VECTORS: + *params = kDefaultMaxVaryingVectors; + break; + case GR_GL_NUM_EXTENSIONS: { + GrGLint i = 0; + while (kExtensions[i++]); + *params = i; + break; + } + default: + SkFAIL("Unexpected pname to GetIntegerv"); + } + } + + GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override { + val[0] = val[1] = 0.5f; + } - if (shader->getRefCount()) { - // someone is still using this shader so we can't delete it here - shader->setMarkedForDeletion(); - } else { - shader->deleteAction(); + GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override { + this->getShaderOrProgramiv(program, pname, params); } -} -GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type, - GrGLsizei n, - GrGLuint* ids) { + GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, + char* infolog) override { + this->getInfoLog(program, bufsize, length, infolog); + } - for (int i = 0; i < n; ++i) { - GrAlwaysAssert(ids[i] == 0); - GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type); - GrAlwaysAssert(obj); - ids[i] = obj->getID(); + GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override { + switch (pname) { + case GR_GL_CURRENT_QUERY: + *params = 0; + break; + case GR_GL_QUERY_COUNTER_BITS: + *params = 32; + break; + default: + SkFAIL("Unexpected pname passed GetQueryiv."); + } } -} -GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) { - debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids); -} + GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override { + this->queryResult(id, pname, params); + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenerateMipmap(GrGLenum level) { -} + GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override { + this->queryResult(id, pname, params); + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, - GrGLuint* ids) { - debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids); -} + GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override { + this->queryResult(id, pname, params); + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, - GrGLuint* ids) { - debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids); -} + GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override { + this->queryResult(id, pname, params); + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) { - debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids); -} + GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override { + this->getShaderOrProgramiv(shader, pname, params); + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenVertexArrays(GrGLsizei n, GrGLuint* ids) { - debugGenObjs(GrDebugGL::kVertexArray_ObjTypes, n, ids); -} + GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length, + char* infolog) override { + this->getInfoLog(shader, bufsize, length, infolog); + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteVertexArrays(GrGLsizei n, const GrGLuint* ids) { - for (GrGLsizei i = 0; i < n; ++i) { - GrVertexArrayObj* array = - GR_FIND(ids[i], GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); - GrAlwaysAssert(array); + const GrGLubyte* getString(GrGLenum name) override { + switch (name) { + case GR_GL_EXTENSIONS: + return CombinedExtensionString(); + case GR_GL_VERSION: + return (const GrGLubyte*)"4.0 Debug GL"; + case GR_GL_SHADING_LANGUAGE_VERSION: + return (const GrGLubyte*)"4.20.8 Debug GLSL"; + case GR_GL_VENDOR: + return (const GrGLubyte*)"Debug Vendor"; + case GR_GL_RENDERER: + return (const GrGLubyte*)"The Debug (Non-)Renderer"; + default: + SkFAIL("Unexpected name passed to GetString"); + return nullptr; + } + } - // Deleting the current vertex array binds object 0 - if (GrDebugGL::getInstance()->getVertexArray() == array) { - GrDebugGL::getInstance()->setVertexArray(nullptr); + const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override { + switch (name) { + case GR_GL_EXTENSIONS: { + GrGLint count; + this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count); + if ((GrGLint)i <= count) { + return (const GrGLubyte*) kExtensions[i]; + } else { + return nullptr; + } + } + default: + SkFAIL("Unexpected name passed to GetStringi"); + return nullptr; } + } - if (array->getRefCount()) { - // someone is still using this vertex array so we can't delete it here - array->setMarkedForDeletion(); - } else { - array->deleteAction(); + GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, + GrGLint* params) override { + // we used to use this to query stuff about externally created textures, + // now we just require clients to tell us everything about the texture. + SkFAIL("Should never query texture parameters."); + } + + GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override { + for (GrGLsizei i = 0; i < n; ++i) { + GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArray_ObjTypes); + GrAlwaysAssert(array); + + // Deleting the current vertex array binds object 0 + if (this->getVertexArray() == array) { + this->setVertexArray(nullptr); + } + + if (array->getRefCount()) { + // someone is still using this vertex array so we can't delete it here + array->setMarkedForDeletion(); + } else { + array->deleteAction(); + } } } -} -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) { - GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); - GrAlwaysAssert((0 == id) || array); - GrDebugGL::getInstance()->setVertexArray(array); -} + GrGLvoid bindVertexArray(GrGLuint id) override { + GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTypes); + GrAlwaysAssert((0 == id) || array); + this->setVertexArray(array); + } + + GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override { + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); + + GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes); + // 0 is a permissible bufferID - it unbinds the current buffer + + switch (target) { + case GR_GL_ARRAY_BUFFER: + this->setArrayBuffer(buffer); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + this->setElementArrayBuffer(buffer); + break; + default: + SkFAIL("Unexpected target to glBindBuffer"); + break; + } + } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) { - GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); + // deleting a bound buffer has the side effect of binding 0 + GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override { + // first potentially unbind the buffers + for (int i = 0; i < n; ++i) { + + if (this->getArrayBuffer() && + ids[i] == this->getArrayBuffer()->getID()) { + // this ID is the current array buffer + this->setArrayBuffer(nullptr); + } + if (this->getElementArrayBuffer() && + ids[i] == this->getElementArrayBuffer()->getID()) { + // this ID is the current element array buffer + this->setElementArrayBuffer(nullptr); + } + } - GrBufferObj *buffer = GR_FIND(bufferID, - GrBufferObj, - GrDebugGL::kBuffer_ObjTypes); - // 0 is a permissible bufferID - it unbinds the current buffer + // then actually "delete" the buffers + for (int i = 0; i < n; ++i) { + GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes); + GrAlwaysAssert(buffer); - switch (target) { - case GR_GL_ARRAY_BUFFER: - GrDebugGL::getInstance()->setArrayBuffer(buffer); - break; - case GR_GL_ELEMENT_ARRAY_BUFFER: - GrDebugGL::getInstance()->setElementArrayBuffer(buffer); - break; - default: - SkFAIL("Unexpected target to glBindBuffer"); - break; + GrAlwaysAssert(!buffer->getDeleted()); + buffer->deleteAction(); + } } -} -// deleting a bound buffer has the side effect of binding 0 -GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) { - // first potentially unbind the buffers - for (int i = 0; i < n; ++i) { + // map a buffer to the caller's address space + GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length, + GrGLbitfield access) override { + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || + GR_GL_ELEMENT_ARRAY_BUFFER == target); + + // We only expect read access and we expect that the buffer or range is always invalidated. + GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access)); + GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access); + + GrBufferObj *buffer = nullptr; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = this->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = this->getElementArrayBuffer(); + break; + default: + SkFAIL("Unexpected target to glMapBufferRange"); + break; + } - if (GrDebugGL::getInstance()->getArrayBuffer() && - ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) { - // this ID is the current array buffer - GrDebugGL::getInstance()->setArrayBuffer(nullptr); + if (buffer) { + GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize()); + GrAlwaysAssert(!buffer->getMapped()); + buffer->setMapped(offset, length); + return buffer->getDataPtr() + offset; } - if (GrDebugGL::getInstance()->getElementArrayBuffer() && - ids[i] == - GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) { - // this ID is the current element array buffer - GrDebugGL::getInstance()->setElementArrayBuffer(nullptr); + + GrAlwaysAssert(false); + return nullptr; // no buffer bound to the target + } + + GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { + GrAlwaysAssert(GR_GL_WRITE_ONLY == access); + + GrBufferObj *buffer = nullptr; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = this->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = this->getElementArrayBuffer(); + break; + default: + SkFAIL("Unexpected target to glMapBuffer"); + break; } + + return this->mapBufferRange(target, 0, buffer->getSize(), + GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT); } - // then actually "delete" the buffers - for (int i = 0; i < n; ++i) { - GrBufferObj *buffer = GR_FIND(ids[i], - GrBufferObj, - GrDebugGL::kBuffer_ObjTypes); - GrAlwaysAssert(buffer); + // remove a buffer from the caller's address space + // TODO: check if the "access" method from "glMapBuffer" was honored + GrGLboolean unmapBuffer(GrGLenum target) override { + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || + GR_GL_ELEMENT_ARRAY_BUFFER == target); + + GrBufferObj *buffer = nullptr; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = this->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = this->getElementArrayBuffer(); + break; + default: + SkFAIL("Unexpected target to glUnmapBuffer"); + break; + } + + if (buffer) { + GrAlwaysAssert(buffer->getMapped()); + buffer->resetMapped(); + return GR_GL_TRUE; + } - GrAlwaysAssert(!buffer->getDeleted()); - buffer->deleteAction(); - } -} - -// map a buffer to the caller's address space -GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBufferRange(GrGLenum target, GrGLintptr offset, - GrGLsizeiptr length, GrGLbitfield access) { - GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || - GR_GL_ELEMENT_ARRAY_BUFFER == target); - - // We only expect read access and we expect that the buffer or range is always invalidated. - GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access)); - GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access); - - GrBufferObj *buffer = nullptr; - switch (target) { - case GR_GL_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getArrayBuffer(); - break; - case GR_GL_ELEMENT_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); - break; - default: - SkFAIL("Unexpected target to glMapBufferRange"); - break; - } - - if (buffer) { - GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize()); - GrAlwaysAssert(!buffer->getMapped()); - buffer->setMapped(offset, length); - return buffer->getDataPtr() + offset; - } - - GrAlwaysAssert(false); - return nullptr; // no buffer bound to the target -} - -GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) { - GrAlwaysAssert(GR_GL_WRITE_ONLY == access); - - GrBufferObj *buffer = nullptr; - switch (target) { - case GR_GL_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getArrayBuffer(); - break; - case GR_GL_ELEMENT_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); - break; - default: - SkFAIL("Unexpected target to glMapBuffer"); - break; - } - - return debugGLMapBufferRange(target, 0, buffer->getSize(), - GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT); -} - -// remove a buffer from the caller's address space -// TODO: check if the "access" method from "glMapBuffer" was honored -GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) { - - GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || - GR_GL_ELEMENT_ARRAY_BUFFER == target); - - GrBufferObj *buffer = nullptr; - switch (target) { - case GR_GL_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getArrayBuffer(); - break; - case GR_GL_ELEMENT_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); - break; - default: - SkFAIL("Unexpected target to glUnmapBuffer"); - break; - } - - if (buffer) { - GrAlwaysAssert(buffer->getMapped()); - buffer->resetMapped(); - return GR_GL_TRUE; - } - - GrAlwaysAssert(false); - return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; -} - -GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlushMappedBufferRange(GrGLenum target, - GrGLintptr offset, - GrGLsizeiptr length) { - GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || - GR_GL_ELEMENT_ARRAY_BUFFER == target); - - GrBufferObj *buffer = nullptr; - switch (target) { - case GR_GL_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getArrayBuffer(); - break; - case GR_GL_ELEMENT_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); - break; - default: - SkFAIL("Unexpected target to glUnmapBuffer"); - break; - } - - if (buffer) { - GrAlwaysAssert(buffer->getMapped()); - GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength()); - } else { GrAlwaysAssert(false); + return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; } -} - - -GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, - GrGLenum value, - GrGLint* params) { - - GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || - GR_GL_ELEMENT_ARRAY_BUFFER == target); - GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || - GR_GL_BUFFER_USAGE == value); - - GrBufferObj *buffer = nullptr; - switch (target) { - case GR_GL_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getArrayBuffer(); - break; - case GR_GL_ELEMENT_ARRAY_BUFFER: - buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); - break; - } - - GrAlwaysAssert(buffer); - - switch (value) { - case GR_GL_BUFFER_MAPPED: - *params = GR_GL_FALSE; - if (buffer) - *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; - break; - case GR_GL_BUFFER_SIZE: - *params = 0; - if (buffer) - *params = SkToInt(buffer->getSize()); - break; - case GR_GL_BUFFER_USAGE: - *params = GR_GL_STATIC_DRAW; - if (buffer) - *params = buffer->getUsage(); - break; - default: - SkFAIL("Unexpected value to glGetBufferParamateriv"); - break; + + GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset, + GrGLsizeiptr length) override { + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || + GR_GL_ELEMENT_ARRAY_BUFFER == target); + + GrBufferObj *buffer = nullptr; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = this->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = this->getElementArrayBuffer(); + break; + default: + SkFAIL("Unexpected target to glUnmapBuffer"); + break; + } + + if (buffer) { + GrAlwaysAssert(buffer->getMapped()); + GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength()); + } else { + GrAlwaysAssert(false); + } } -}; -} // end of namespace -//////////////////////////////////////////////////////////////////////////////// -struct GrDebugGLInterface : public GrGLInterface { + GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) override { + + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || + GR_GL_ELEMENT_ARRAY_BUFFER == target); + GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || + GR_GL_BUFFER_USAGE == value); + + GrBufferObj *buffer = nullptr; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = this->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = this->getElementArrayBuffer(); + break; + } + + GrAlwaysAssert(buffer); + + switch (value) { + case GR_GL_BUFFER_MAPPED: + *params = GR_GL_FALSE; + if (buffer) + *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; + break; + case GR_GL_BUFFER_SIZE: + *params = 0; + if (buffer) + *params = SkToInt(buffer->getSize()); + break; + case GR_GL_BUFFER_USAGE: + *params = GR_GL_STATIC_DRAW; + if (buffer) + *params = buffer->getUsage(); + break; + default: + SkFAIL("Unexpected value to glGetBufferParamateriv"); + break; + } + } -public: - - - GrDebugGLInterface() - : fWrapped(nullptr) { - GrDebugGL::staticRef(); - } - - virtual ~GrDebugGLInterface() { - GrDebugGL::staticUnRef(); - } - - void setWrapped(GrGLInterface *interface) { - fWrapped.reset(interface); - } - - void abandon() const override { - GrDebugGL::abandon(); - } - - // TODO: there are some issues w/ wrapping another GL interface inside the - // debug interface: - // Since none of the "gl" methods are member functions they don't get - // a "this" pointer through which to access "fWrapped" - // This could be worked around by having all of them access the - // "glInterface" pointer - i.e., treating the debug interface as a - // true singleton - // - // The problem with this is that we also want to handle OpenGL - // contexts. The natural way to do this is to have multiple debug - // interfaces. Each of which represents a separate context. The - // static ID count would still uniquify IDs across all of them. - // The problem then is that we couldn't treat the debug GL - // interface as a singleton (since there would be one for each - // context). - // - // The solution to this is probably to alter SkDebugGlContext's - // "makeCurrent" method to make a call like "makeCurrent(this)" to - // the debug GL interface (assuming that the application will create - // multiple SkGLContext's) to let it switch between the active - // context. Everything in the GrDebugGL object would then need to be - // moved to a GrContextObj and the GrDebugGL object would just switch - // between them. Note that this approach would also require that - // SkDebugGLContext wrap an arbitrary other context - // and then pass the wrapped interface to the debug GL interface. - -protected: private: + // the OpenGLES 2.0 spec says this must be >= 128 + static const GrGLint kDefaultMaxVertexUniformVectors = 128; + + // the OpenGLES 2.0 spec says this must be >=16 + static const GrGLint kDefaultMaxFragmentUniformVectors = 16; + + // the OpenGLES 2.0 spec says this must be >= 8 + static const GrGLint kDefaultMaxVertexAttribs = 8; + + // the OpenGLES 2.0 spec says this must be >= 8 + static const GrGLint kDefaultMaxVaryingVectors = 8; + + // the OpenGLES 2.0 spec says this must be >= 2 + static const GrGLint kDefaultMaxTextureUnits = 8; + + static const char* kExtensions[]; + + GrGLuint fCurrGenericID; + GrGLuint fCurrTextureUnit; + GrTextureUnitObj* fTextureUnits[kDefaultMaxTextureUnits]; + GrBufferObj* fArrayBuffer; + GrBufferObj* fElementArrayBuffer; + GrVertexArrayObj* fVertexArray; + GrGLint fPackRowLength; + GrGLint fUnpackRowLength; + GrGLint fPackAlignment; + GrFrameBufferObj* fFrameBuffer; + GrRenderBufferObj* fRenderBuffer; + GrProgramObj* fProgram; + mutable bool fAbandoned; + // global store of all objects + SkTArray<GrFakeRefObj *> fObjects; + + static const GrGLubyte* CombinedExtensionString() { + static SkString gExtString; + static SkMutex gMutex; + gMutex.acquire(); + if (0 == gExtString.size()) { + int i = 0; + while (kExtensions[i]) { + if (i > 0) { + gExtString.append(" "); + } + gExtString.append(kExtensions[i]); + ++i; + } + } + gMutex.release(); + return (const GrGLubyte*) gExtString.c_str(); + } - SkAutoTUnref<GrGLInterface> fWrapped; + GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) { + for (int i = 0; i < n; ++i) { + ids[i] = ++fCurrGenericID; + } + } + + GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length, + char* infolog) { + if (length) { + *length = 0; + } + if (bufsize > 0) { + *infolog = 0; + } + } + + GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* params) { + switch (pname) { + case GR_GL_LINK_STATUS: // fallthru + case GR_GL_COMPILE_STATUS: + *params = GR_GL_TRUE; + break; + case GR_GL_INFO_LOG_LENGTH: + *params = 0; + break; + // we don't expect any other pnames + default: + SkFAIL("Unexpected pname to GetProgramiv"); + break; + } + } + + template <typename T> + void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) { + switch (pname) { + case GR_GL_QUERY_RESULT_AVAILABLE: + *params = GR_GL_TRUE; + break; + case GR_GL_QUERY_RESULT: + *params = 0; + break; + default: + SkFAIL("Unexpected pname passed to GetQueryObject."); + break; + } + } + + enum ObjTypes { + kTexture_ObjTypes = 0, + kBuffer_ObjTypes, + kRenderBuffer_ObjTypes, + kFrameBuffer_ObjTypes, + kShader_ObjTypes, + kProgram_ObjTypes, + kTextureUnit_ObjTypes, + kVertexArray_ObjTypes, + kObjTypeCount + }; + + typedef GrFakeRefObj *(*Create)(); + + static Create gFactoryFunc[kObjTypeCount]; + + GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) { + for (int i = 0; i < n; ++i) { + GrAlwaysAssert(ids[i] == 0); + GrFakeRefObj *obj = this->createObj(type); + GrAlwaysAssert(obj); + ids[i] = obj->getID(); + } + } + + GrFakeRefObj* createObj(ObjTypes type) { + GrFakeRefObj *temp = (*gFactoryFunc[type])(); + + fObjects.push_back(temp); + + return temp; + } + + GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) { + for (int i = 0; i < fObjects.count(); ++i) { + if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) { + // The application shouldn't be accessing objects + // that (as far as OpenGL knows) were already deleted + GrAlwaysAssert(!fObjects[i]->getDeleted()); + GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion()); + return fObjects[i]; + } + } + return nullptr; + } + + GrTextureUnitObj* getTextureUnit(int unit) { + GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit); + + return fTextureUnits[unit]; + } - typedef GrGLInterface INHERITED; + void setArrayBuffer(GrBufferObj *arrayBuffer) { + if (fArrayBuffer) { + // automatically break the binding of the old buffer + GrAlwaysAssert(fArrayBuffer->getBound()); + fArrayBuffer->resetBound(); + + GrAlwaysAssert(!fArrayBuffer->getDeleted()); + fArrayBuffer->unref(); + } + + fArrayBuffer = arrayBuffer; + + if (fArrayBuffer) { + GrAlwaysAssert(!fArrayBuffer->getDeleted()); + fArrayBuffer->ref(); + + GrAlwaysAssert(!fArrayBuffer->getBound()); + fArrayBuffer->setBound(); + } + } + + GrBufferObj* getArrayBuffer() { return fArrayBuffer; } + void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) { + if (fElementArrayBuffer) { + // automatically break the binding of the old buffer + GrAlwaysAssert(fElementArrayBuffer->getBound()); + fElementArrayBuffer->resetBound(); + + GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); + fElementArrayBuffer->unref(); + } + + fElementArrayBuffer = elementArrayBuffer; + + if (fElementArrayBuffer) { + GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); + fElementArrayBuffer->ref(); + + GrAlwaysAssert(!fElementArrayBuffer->getBound()); + fElementArrayBuffer->setBound(); + } + } + + GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; } + + void setVertexArray(GrVertexArrayObj* vertexArray) { + if (vertexArray) { + SkASSERT(!vertexArray->getDeleted()); + } + SkRefCnt_SafeAssign(fVertexArray, vertexArray); + } + + GrVertexArrayObj* getVertexArray() { return fVertexArray; } + + void setTexture(GrTextureObj *texture) { + fTextureUnits[fCurrTextureUnit]->setTexture(texture); + } + + void setFrameBuffer(GrFrameBufferObj *frameBuffer) { + if (fFrameBuffer) { + GrAlwaysAssert(fFrameBuffer->getBound()); + fFrameBuffer->resetBound(); + + GrAlwaysAssert(!fFrameBuffer->getDeleted()); + fFrameBuffer->unref(); + } + + fFrameBuffer = frameBuffer; + + if (fFrameBuffer) { + GrAlwaysAssert(!fFrameBuffer->getDeleted()); + fFrameBuffer->ref(); + + GrAlwaysAssert(!fFrameBuffer->getBound()); + fFrameBuffer->setBound(); + } + } + + GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; } + + void setRenderBuffer(GrRenderBufferObj *renderBuffer) { + if (fRenderBuffer) { + GrAlwaysAssert(fRenderBuffer->getBound()); + fRenderBuffer->resetBound(); + + GrAlwaysAssert(!fRenderBuffer->getDeleted()); + fRenderBuffer->unref(); + } + + fRenderBuffer = renderBuffer; + + if (fRenderBuffer) { + GrAlwaysAssert(!fRenderBuffer->getDeleted()); + fRenderBuffer->ref(); + + GrAlwaysAssert(!fRenderBuffer->getBound()); + fRenderBuffer->setBound(); + } + } + GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; } + + void useProgram(GrProgramObj *program) { + if (fProgram) { + GrAlwaysAssert(fProgram->getInUse()); + fProgram->resetInUse(); + + GrAlwaysAssert(!fProgram->getDeleted()); + fProgram->unref(); + } + + fProgram = program; + + if (fProgram) { + GrAlwaysAssert(!fProgram->getDeleted()); + fProgram->ref(); + + GrAlwaysAssert(!fProgram->getInUse()); + fProgram->setInUse(); + } + } + + void report() const { + for (int i = 0; i < fObjects.count(); ++i) { + if (!fAbandoned) { + GrAlwaysAssert(0 == fObjects[i]->getRefCount()); + GrAlwaysAssert(fObjects[i]->getDeleted()); + } + } + } + + typedef GrGLTestInterface INHERITED; +}; + +#undef CREATE +#undef FIND + +DebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = { + GrTextureObj::createGrTextureObj, + GrBufferObj::createGrBufferObj, + GrRenderBufferObj::createGrRenderBufferObj, + GrFrameBufferObj::createGrFrameBufferObj, + GrShaderObj::createGrShaderObj, + GrProgramObj::createGrProgramObj, + GrTextureUnitObj::createGrTextureUnitObj, + GrVertexArrayObj::createGrVertexArrayObj, }; +const char* DebugInterface::kExtensions[] = { + "GL_ARB_framebuffer_object", + "GL_ARB_blend_func_extended", + "GL_ARB_timer_query", + "GL_ARB_draw_buffers", + "GL_ARB_occlusion_query", + "GL_EXT_stencil_wrap", + nullptr, // signifies the end of the array. +}; + +} // anonymous namespace + //////////////////////////////////////////////////////////////////////////////// -const GrGLInterface* GrGLCreateDebugInterface() { - GrGLInterface *interface = new GrDebugGLInterface; - - interface->fStandard = kGL_GrGLStandard; - - GrGLInterface::Functions* functions = &interface->fFunctions; - functions->fActiveTexture = debugGLActiveTexture; - functions->fAttachShader = debugGLAttachShader; - functions->fBeginQuery = debugGLBeginQuery; - functions->fBindAttribLocation = debugGLBindAttribLocation; - functions->fBindBuffer = debugGLBindBuffer; - functions->fBindFragDataLocation = noOpGLBindFragDataLocation; - functions->fBindTexture = debugGLBindTexture; - functions->fBindVertexArray = debugGLBindVertexArray; - functions->fBlendColor = noOpGLBlendColor; - functions->fBlendEquation = noOpGLBlendEquation; - functions->fBlendFunc = noOpGLBlendFunc; - functions->fBufferData = debugGLBufferData; - functions->fBufferSubData = noOpGLBufferSubData; - functions->fClear = noOpGLClear; - functions->fClearColor = noOpGLClearColor; - functions->fClearStencil = noOpGLClearStencil; - functions->fColorMask = noOpGLColorMask; - functions->fCompileShader = noOpGLCompileShader; - functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; - functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D; - functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; - functions->fCreateProgram = debugGLCreateProgram; - functions->fCreateShader = debugGLCreateShader; - functions->fCullFace = noOpGLCullFace; - functions->fDeleteBuffers = debugGLDeleteBuffers; - functions->fDeleteProgram = debugGLDeleteProgram; - functions->fDeleteQueries = noOpGLDeleteIds; - functions->fDeleteShader = debugGLDeleteShader; - functions->fDeleteTextures = debugGLDeleteTextures; - functions->fDeleteVertexArrays = debugGLDeleteVertexArrays; - functions->fDepthMask = noOpGLDepthMask; - functions->fDisable = noOpGLDisable; - functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; - functions->fDrawArrays = noOpGLDrawArrays; - functions->fDrawArraysInstanced = noOpGLDrawArraysInstanced; - functions->fDrawBuffer = noOpGLDrawBuffer; - functions->fDrawBuffers = noOpGLDrawBuffers; - functions->fDrawElements = noOpGLDrawElements; - functions->fDrawElementsInstanced = noOpGLDrawElementsInstanced; - functions->fEnable = noOpGLEnable; - functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; - functions->fEndQuery = noOpGLEndQuery; - functions->fFinish = noOpGLFinish; - functions->fFlush = noOpGLFlush; - functions->fFlushMappedBufferRange = debugGLFlushMappedBufferRange; - functions->fFrontFace = noOpGLFrontFace; - functions->fGenerateMipmap = debugGLGenerateMipmap; - functions->fGenBuffers = debugGLGenBuffers; - functions->fGenQueries = noOpGLGenIds; - functions->fGenTextures = debugGLGenTextures; - functions->fGetBufferParameteriv = debugGLGetBufferParameteriv; - functions->fGetError = noOpGLGetError; - functions->fGetIntegerv = noOpGLGetIntegerv; - functions->fGetMultisamplefv = noOpGLGetMultisamplefv; - functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; - functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; - functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; - functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; - functions->fGetQueryiv = noOpGLGetQueryiv; - functions->fGetProgramInfoLog = noOpGLGetInfoLog; - functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; - functions->fGetShaderInfoLog = noOpGLGetInfoLog; - functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; - functions->fGetString = noOpGLGetString; - functions->fGetStringi = noOpGLGetStringi; - functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; - functions->fGetUniformLocation = noOpGLGetUniformLocation; - functions->fGenVertexArrays = debugGLGenVertexArrays; - functions->fLineWidth = noOpGLLineWidth; - functions->fLinkProgram = noOpGLLinkProgram; - functions->fMapBuffer = debugGLMapBuffer; - functions->fMapBufferRange = debugGLMapBufferRange; - functions->fPixelStorei = debugGLPixelStorei; - functions->fQueryCounter = noOpGLQueryCounter; - functions->fReadBuffer = noOpGLReadBuffer; - functions->fReadPixels = debugGLReadPixels; - functions->fScissor = noOpGLScissor; - functions->fShaderSource = noOpGLShaderSource; - functions->fStencilFunc = noOpGLStencilFunc; - functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; - functions->fStencilMask = noOpGLStencilMask; - functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; - functions->fStencilOp = noOpGLStencilOp; - functions->fStencilOpSeparate = noOpGLStencilOpSeparate; - functions->fTexBuffer = noOpGLTexBuffer; - functions->fTexImage2D = noOpGLTexImage2D; - functions->fTexParameteri = noOpGLTexParameteri; - functions->fTexParameteriv = noOpGLTexParameteriv; - functions->fTexSubImage2D = noOpGLTexSubImage2D; - functions->fTexStorage2D = noOpGLTexStorage2D; - functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; - functions->fUniform1f = noOpGLUniform1f; - functions->fUniform1i = noOpGLUniform1i; - functions->fUniform1fv = noOpGLUniform1fv; - functions->fUniform1iv = noOpGLUniform1iv; - functions->fUniform2f = noOpGLUniform2f; - functions->fUniform2i = noOpGLUniform2i; - functions->fUniform2fv = noOpGLUniform2fv; - functions->fUniform2iv = noOpGLUniform2iv; - functions->fUniform3f = noOpGLUniform3f; - functions->fUniform3i = noOpGLUniform3i; - functions->fUniform3fv = noOpGLUniform3fv; - functions->fUniform3iv = noOpGLUniform3iv; - functions->fUniform4f = noOpGLUniform4f; - functions->fUniform4i = noOpGLUniform4i; - functions->fUniform4fv = noOpGLUniform4fv; - functions->fUniform4iv = noOpGLUniform4iv; - functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; - functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; - functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; - functions->fUnmapBuffer = debugGLUnmapBuffer; - functions->fUseProgram = debugGLUseProgram; - functions->fVertexAttrib1f = noOpGLVertexAttrib1f; - functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv; - functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv; - functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; - functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor; - functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer; - functions->fVertexAttribPointer = noOpGLVertexAttribPointer; - functions->fViewport = noOpGLViewport; - functions->fBindFramebuffer = debugGLBindFramebuffer; - functions->fBindRenderbuffer = debugGLBindRenderbuffer; - functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; - functions->fDeleteFramebuffers = debugGLDeleteFramebuffers; - functions->fDeleteRenderbuffers = debugGLDeleteRenderbuffers; - functions->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer; - functions->fFramebufferTexture2D = debugGLFramebufferTexture2D; - functions->fGenFramebuffers = debugGLGenFramebuffers; - functions->fGenRenderbuffers = debugGLGenRenderbuffers; - functions->fGetFramebufferAttachmentParameteriv = - noOpGLGetFramebufferAttachmentParameteriv; - functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; - functions->fRenderbufferStorage = noOpGLRenderbufferStorage; - functions->fRenderbufferStorageMultisample = - noOpGLRenderbufferStorageMultisample; - functions->fBlitFramebuffer = noOpGLBlitFramebuffer; - functions->fResolveMultisampleFramebuffer = - noOpGLResolveMultisampleFramebuffer; - functions->fMatrixLoadf = noOpGLMatrixLoadf; - functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity; - - functions->fBindFragDataLocationIndexed = - noOpGLBindFragDataLocationIndexed; - - interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi, - functions->fGetIntegerv, nullptr, GR_EGL_NO_DISPLAY); - - return interface; -} + +const GrGLInterface* GrGLCreateDebugInterface() { return new DebugInterface; } |