Chromium Code Reviews| Index: src/gpu/gl/debug/GrGLCreateDebugInterface.cpp |
| diff --git a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp |
| index d8418fd9f0aa472943b361ea11c3edb4d6cc0f72..e2b5dea5c30b21e2174a48cb0a449ae08c99e5a4 100644 |
| --- a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp |
| +++ b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp |
| @@ -8,986 +8,1234 @@ |
| #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" |
| + |
| +#include "SkMutex.h" |
| namespace { // suppress no previous prototype warning |
| -//////////////////////////////////////////////////////////////////////////////// |
| -GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) { |
| +// Helper macro to make creating an object (where you need to get back a derived |
|
robertphillips
2016/03/21 14:52:40
Can this all go on one line ?
bsalomon
2016/03/21 15:42:49
Done.
|
| +// type) easier |
| +#define CREATE(className, classEnum) \ |
| + reinterpret_cast<className *>(this->createObj(classEnum)) |
| - // 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 |
|
robertphillips
2016/03/21 14:52:40
same here
bsalomon
2016/03/21 15:42:49
Done.
|
| +// type) easier |
| +#define FIND(id, className, classEnum) \ |
| + reinterpret_cast<className *>(this->findObject(id, classEnum)) |
| - GrDebugGL::getInstance()->setCurTextureUnit(texture); |
| -} |
| +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) |
| + , fTexture(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); |
| + } |
| -//////////////////////////////////////////////////////////////////////////////// |
| -GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, |
| - GrGLuint shaderID) { |
| + ~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(); |
| - GrProgramObj *program = GR_FIND(programID, GrProgramObj, |
| - GrDebugGL::kProgram_ObjTypes); |
| - GrAlwaysAssert(program); |
| + fArrayBuffer = nullptr; |
| + fElementArrayBuffer = nullptr; |
| + fVertexArray = nullptr; |
| - GrShaderObj *shader = GR_FIND(shaderID, |
| - GrShaderObj, |
| - GrDebugGL::kShader_ObjTypes); |
| - GrAlwaysAssert(shader); |
| + this->report(); |
| + } |
| - program->AttachShader(shader); |
| -} |
| + void abandon() const override { fAbandoned = true; } |
| -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) { |
| -} |
| + 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 debugGLBindAttribLocation(GrGLuint program, |
| - GrGLuint index, |
| - const char* name) { |
| -} |
| + GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override { |
| -//////////////////////////////////////////////////////////////////////////////// |
| -GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, |
| - GrGLuint textureID) { |
| + GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes); |
| + GrAlwaysAssert(program); |
| - // we don't use cube maps |
| - GrAlwaysAssert(target == GR_GL_TEXTURE_2D); |
| - // || target == GR_GL_TEXTURE_CUBE_MAP); |
| + GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); |
| + GrAlwaysAssert(shader); |
| - // a textureID of 0 is acceptable - it binds to the default texture target |
| - GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, |
| - GrDebugGL::kTexture_ObjTypes); |
| + program->AttachShader(shader); |
| + } |
| - GrDebugGL::getInstance()->setTexture(texture); |
| -} |
| + //////////////////////////////////////////////////////////////////////////////// |
| + GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override { |
| + GrAlwaysAssert(target == GR_GL_TEXTURE_2D || |
| + target == GR_GL_TEXTURE_RECTANGLE || |
| + target == GR_GL_TEXTURE_EXTERNAL); |
| + // a textureID of 0 is acceptable - it binds to the default texture target |
| + GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes); |
| -//////////////////////////////////////////////////////////////////////////////// |
| -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; |
| + 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; |
| + GrTextureObj* fTexture; |
| + 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; } |