| 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..43fc8dfad9c3eba7138fe4a1b94eaa844eeb5d52 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; }
|
|
|