diff options
-rw-r--r-- | bench/benchmain.cpp | 13 | ||||
-rw-r--r-- | gyp/gpu.gyp | 3 | ||||
-rw-r--r-- | include/gpu/gl/GrGLInterface.h | 10 | ||||
-rw-r--r-- | include/gpu/gl/SkDebugGLContext.h | 27 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCreateDebugInterface.cpp | 1000 | ||||
-rw-r--r-- | src/gpu/gl/SkDebugGLContext.cpp | 13 |
6 files changed, 1064 insertions, 2 deletions
diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp index 7732268759..32aace3697 100644 --- a/bench/benchmain.cpp +++ b/bench/benchmain.cpp @@ -20,6 +20,7 @@ #include "SkImageEncoder.h" #include "gl/SkNativeGLContext.h" #include "gl/SkNullGLContext.h" +#include "gl/SkDebugGLContext.h" #include "SkNWayCanvas.h" #include "SkPicture.h" #include "SkString.h" @@ -208,6 +209,12 @@ public: return true; } + void cleanup() { + fGLContext.reset(NULL); + fGrContext.reset(NULL); + fRenderTarget.reset(NULL); + } + bool isValid() { return NULL != fGLContext.get(); } @@ -231,6 +238,7 @@ private: static GLHelper gRealGLHelper; static GLHelper gNullGLHelper; +static GLHelper gDebugGLHelper; static SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size, Backend backend, GLHelper* glHelper) { @@ -512,8 +520,10 @@ int main (int argc, char * const argv[]) { determine_gpu_context_size(defineDict, &contextWidth, &contextHeight); SkAutoTUnref<SkGLContext> realGLCtx(new SkNativeGLContext); SkAutoTUnref<SkGLContext> nullGLCtx(new SkNullGLContext); + SkAutoTUnref<SkGLContext> debugGLCtx(new SkDebugGLContext); gRealGLHelper.init(realGLCtx.get(), contextWidth, contextHeight); gNullGLHelper.init(nullGLCtx.get(), contextWidth, contextHeight); + gDebugGLHelper.init(debugGLCtx.get(), contextWidth, contextHeight); #endif BenchTimer timer = BenchTimer(gRealGLHelper.glContext()); @@ -617,5 +627,8 @@ int main (int argc, char * const argv[]) { log_progress("\n"); } + // need to clean up here rather than post-main to allow leak detection to work + gDebugGLHelper.cleanup(); + return 0; } diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp index 7080ebbea2..a4d7c18db5 100644 --- a/gyp/gpu.gyp +++ b/gyp/gpu.gyp @@ -102,6 +102,7 @@ '../include/gpu/gl/SkMesaGLContext.h', '../include/gpu/gl/SkNativeGLContext.h', '../include/gpu/gl/SkNullGLContext.h', + '../include/gpu/gl/SkDebugGLContext.h', '../src/gpu/GrPrintf_skia.cpp', '../src/gpu/SkGpuCanvas.cpp', @@ -112,6 +113,7 @@ '../src/gpu/gl/SkGLContext.cpp', '../src/gpu/gl/SkNullGLContext.cpp', + '../src/gpu/gl/SkDebugGLContext.cpp', '../src/gpu/android/SkNativeGLContext_android.cpp', @@ -252,6 +254,7 @@ '../src/gpu/gl/GrGLContextInfo.h', '../src/gpu/gl/GrGLCreateNativeInterface_none.cpp', '../src/gpu/gl/GrGLCreateNullInterface.cpp', + '../src/gpu/gl/GrGLCreateDebugInterface.cpp', '../src/gpu/gl/GrGLDefaultInterface_none.cpp', '../src/gpu/gl/GrGLDefaultInterface_native.cpp', '../src/gpu/gl/GrGLIndexBuffer.cpp', diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h index 968afab0d4..0ff30344cd 100644 --- a/include/gpu/gl/GrGLInterface.h +++ b/include/gpu/gl/GrGLInterface.h @@ -71,8 +71,8 @@ GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*); * also NULL GrContext creation will fail. * * The default interface is returned by GrGLDefaultInterface. This function's - * implementation is platform-specifc. Several have been provided, along with an - * implementation that simply returns NULL. It is implementation-specific + * implementation is platform-specific. Several have been provided, along with + * an implementation that simply returns NULL. It is implementation-specific * whether the same GrGLInterface is returned or whether a new one is created * at each call. Some platforms may not be able to use a single GrGLInterface * because extension function ptrs vary across contexts. Note that GrGLInterface @@ -107,6 +107,12 @@ const GrGLInterface* GrGLCreateMesaInterface(); */ const GrGLInterface* GrGLCreateNullInterface(); +/** + * Creates a debugging GrGLInterface that doesn't draw anything. Used for + * finding memory leaks and invalid memory accesses. + */ +const GrGLInterface* GrGLCreateDebugInterface(); + typedef unsigned int GrGLenum; typedef unsigned char GrGLboolean; typedef unsigned int GrGLbitfield; diff --git a/include/gpu/gl/SkDebugGLContext.h b/include/gpu/gl/SkDebugGLContext.h new file mode 100644 index 0000000000..c51f54c7e8 --- /dev/null +++ b/include/gpu/gl/SkDebugGLContext.h @@ -0,0 +1,27 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SkDebugGLContext_DEFINED +#define SkDebugGLContext_DEFINED + +#include "SkGLContext.h" + +class SkDebugGLContext : public SkGLContext { + +public: + SkDebugGLContext() {}; + + virtual void makeCurrent() const SK_OVERRIDE {}; + +protected: + virtual const GrGLInterface* createGLContext() SK_OVERRIDE; + + virtual void destroyGLContext() SK_OVERRIDE {}; +}; + +#endif + diff --git a/src/gpu/gl/GrGLCreateDebugInterface.cpp b/src/gpu/gl/GrGLCreateDebugInterface.cpp new file mode 100644 index 0000000000..3b2a376e84 --- /dev/null +++ b/src/gpu/gl/GrGLCreateDebugInterface.cpp @@ -0,0 +1,1000 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#include "gl/GrGLInterface.h" + +#include "SkTArray.h" + +// the OpenGLES 2.0 spec says this must be >= 2 +static const GrGLint kDefaultMaxTextureUnits = 8; + +//////////////////////////////////////////////////////////////////////////////// +// This object is used to track the OpenGL objects. We don't use real +// reference counting (i.e., we don't free the objects when their ref count +// goes to 0) so that we can detect invalid memory accesses. The refs we +// are tracking in this class are actually OpenGL's references to the objects +// not "ours" +// Each object also gets a unique globally identifying ID +class GrFakeRefObj +{ +public: + GrFakeRefObj(GrGLuint ID) + : fRef(0) + , fID(ID) + , fMarkedForDeletion(false) + , fDeleted(false) { + } + virtual ~GrFakeRefObj() {}; + + void ref() { fRef++; } + void unref() { + fRef--; + // often in OpenGL a given object may still be in use when the + // delete call is made. In these cases the object is marked + // for deletion and then freed when it is no longer in use + if (0 == fRef && fMarkedForDeletion) { + this->deleteAction(); + } + } + int getRefCount() const { return fRef; } + + GrGLuint getID() const { return fID; } + + void setMarkedForDeletion() { fMarkedForDeletion = true; } + bool getMarkedForDeletion() const { return fMarkedForDeletion; } + + // setDeleted should only ever appear in deleteAction methods! + void setDeleted() { fDeleted = true; } + bool getDeleted() const { return fDeleted; } + + // The deleteAction fires if the object has been marked for deletion but + // couldn't be deleted earlier due to refs + virtual void deleteAction() = 0; + +protected: +private: + int fRef; + GrGLuint fID; + bool fMarkedForDeletion; + // The deleted flag is only set when OpenGL thinks the object is deleted + // It is obviously still allocated w/in this framework + bool fDeleted; +}; + +//////////////////////////////////////////////////////////////////////////////// +class GrBufferObj : public GrFakeRefObj +{ +public: + GrBufferObj(GrGLuint ID) + : GrFakeRefObj(ID) + , fDataPtr(NULL) + , fMapped(false) + , fBound(false) + , fSize(0) + , fUsage(GR_GL_STATIC_DRAW) { + } + virtual ~GrBufferObj() { + delete[] fDataPtr; + } + + void access() { + // cannot access the buffer if it is currently mapped + GrAlwaysAssert(!fMapped); + } + + void setMapped() { fMapped = true; } + void resetMapped() { fMapped = false; } + bool getMapped() const { return fMapped; } + + void setBound() { fBound = true; } + void resetBound() { fBound = false; } + bool getBound() const { return fBound; } + + void allocate(GrGLint size, const GrGLvoid *dataPtr) { + GrAlwaysAssert(size >= 0); + + // delete pre-existing data + delete fDataPtr; + + fSize = size; + fDataPtr = new char[size]; + if (dataPtr) { + memcpy(fDataPtr, dataPtr, fSize); + } + // TODO: w/ no dataPtr the data is unitialized - this could be tracked + } + GrGLint getSize() const { return fSize; } + GrGLvoid *getDataPtr() { return fDataPtr; } + + GrGLint getUsage() const { return fUsage; } + void setUsage(GrGLint usage) { fUsage = usage; } + + virtual void deleteAction() SK_OVERRIDE { + + // buffers are automatically unmapped when deleted + this->resetMapped(); + this->setDeleted(); + } + + +protected: +private: + + GrGLvoid* fDataPtr; + bool fMapped; // is the buffer object mapped via "glMapBuffer"? + bool fBound; // is the buffer object bound via "glBindBuffer"? + GrGLint fSize; // size in bytes + GrGLint fUsage; // one of: GL_STREAM_DRAW, GL_STATIC_DRAW, GL_DYNAMIC_DRAW + + typedef GrFakeRefObj INHERITED; +}; + + +//////////////////////////////////////////////////////////////////////////////// +class GrShaderObj : public GrFakeRefObj +{ +public: + GrShaderObj(GrGLuint ID, GrGLenum type) + : GrFakeRefObj(ID) + , fType(type) {} + + GrGLenum getType() { return fType; } + + virtual void deleteAction() SK_OVERRIDE { + + this->setDeleted(); + } + +protected: +private: + GrGLenum fType; // either GR_GL_VERTEX_SHADER or GR_GL_FRAGMENT_SHADER + + typedef GrFakeRefObj INHERITED; +}; + + +//////////////////////////////////////////////////////////////////////////////// +class GrProgramObj : public GrFakeRefObj +{ +public: + GrProgramObj(GrGLuint ID) + : GrFakeRefObj(ID) + , fInUse(false) {} + + void AttachShader(GrShaderObj *shader) + { + shader->ref(); + fShaders.push_back(shader); + } + + virtual void deleteAction() SK_OVERRIDE { + + // shaders are automatically detached from a deleted program. They will only be + // deleted if they were marked for deletion by a prior call to glDeleteShader + for (int i = 0; i < fShaders.count(); ++i) { + fShaders[i]->unref(); + } + fShaders.reset(); + + this->setDeleted(); + } + + void setInUse() { fInUse = true; } + bool getInUse() const { return fInUse; } + +protected: + +private: + SkTArray<GrShaderObj *> fShaders; + bool fInUse; // has this program been activated by a glUseProgram call? + + typedef GrFakeRefObj INHERITED; +}; + +//////////////////////////////////////////////////////////////////////////////// +// This is the main debugging object. It is a singleton and keeps track of +// all the other debug objects. +class GrDebugGL +{ +public: + // TODO: merge findBuffer, findShader & findProgram?? + GrBufferObj *findBuffer(GrGLuint ID) + { + GrFakeRefObj *obj = this->findObject(ID); + if (NULL == obj) { + return NULL; + } + + return reinterpret_cast<GrBufferObj *>(obj); + } + + GrShaderObj *findShader(GrGLuint ID) + { + GrFakeRefObj *obj = this->findObject(ID); + if (NULL == obj) { + return NULL; + } + + return reinterpret_cast<GrShaderObj *>(obj); + } + + GrProgramObj *findProgram(GrGLuint ID) + { + GrFakeRefObj *obj = this->findObject(ID); + if (NULL == obj) { + return NULL; + } + + return reinterpret_cast<GrProgramObj *>(obj); + } + + // TODO: merge createBuffer, createShader, createProgram?? + GrBufferObj *createBuffer() + { + GrBufferObj *buffer = new GrBufferObj(++fNextID); + + fObjects.push_back(buffer); + + return buffer; + } + + GrShaderObj *createShader(GrGLenum type) + { + GrShaderObj *shader = new GrShaderObj(++fNextID, type); + + fObjects.push_back(shader); + + return shader; + } + + GrProgramObj *createProgram() + { + GrProgramObj *program = new GrProgramObj(++fNextID); + + fObjects.push_back(program); + + return program; + } + + GrFakeRefObj *findObject(GrGLuint ID) + { + for (int i = 0; i < fObjects.count(); ++i) { + if (fObjects[i]->getID() == ID) { + // 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 NULL; + } + + + void setMaxTextureUnits(GrGLuint maxTextureUnits) { fMaxTextureUnits = maxTextureUnits; } + GrGLuint getMaxTextureUnits() const { return fMaxTextureUnits; } + + void setCurTextureUnit(GrGLuint curTextureUnit) { fCurTextureUnit = curTextureUnit; } + GrGLuint getCurTextureUnit() const { return fCurTextureUnit; } + + void setArrayBuffer(GrBufferObj *arrayBuffer) { fArrayBuffer = arrayBuffer; } + GrBufferObj *getArrayBuffer() { return fArrayBuffer; } + + void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) { fElementArrayBuffer = elementArrayBuffer; } + GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; } + + static GrDebugGL *getInstance() + { +// static GrDebugGL Obj; + + return &Obj; + } + + void report() const { + for (int i = 0; i < fObjects.count(); ++i) { + GrAlwaysAssert(fObjects[i]->getDeleted()); + } + } + +protected: + +private: + GrGLuint fMaxTextureUnits; + GrGLuint fCurTextureUnit; + GrBufferObj * fArrayBuffer; + GrBufferObj * fElementArrayBuffer; + + static int fNextID; // source for globally unique IDs + + static GrDebugGL Obj; + + // global store of all objects + SkTArray<GrFakeRefObj *> fObjects; + + GrDebugGL() + : fMaxTextureUnits(kDefaultMaxTextureUnits) + , fCurTextureUnit(0) + , fArrayBuffer(NULL) + , fElementArrayBuffer(NULL) + { + } + + ~GrDebugGL() { + this->report(); + + for (int i = 0; i < fObjects.count(); ++i) { + delete fObjects[i]; + } + fObjects.reset(); + fArrayBuffer = NULL; + fElementArrayBuffer = NULL; + } +}; + +int GrDebugGL::fNextID = 0; +GrDebugGL GrDebugGL::Obj; + +//////////////////////////////////////////////////////////////////////////////// +GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) +{ + + GrAlwaysAssert(0 <= texture); +// GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits()); + + GrDebugGL::getInstance()->setCurTextureUnit(texture); +} + +//////////////////////////////////////////////////////////////////////////////// +GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, GrGLuint shaderID) +{ + GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID); + GrAlwaysAssert(program); + + GrShaderObj *shader = GrDebugGL::getInstance()->findShader(shaderID); + GrAlwaysAssert(shader); + + program->AttachShader(shader); +} + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, GrGLuint texture) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocation(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendFunc(GrGLenum sfactor, GrGLenum dfactor) {} + +//////////////////////////////////////////////////////////////////////////////// +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 = NULL; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = GrDebugGL::getInstance()->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); + break; + default: + GrCrash("Unexpected target to glBufferData"); + break; + } + + GrAlwaysAssert(buffer); + GrAlwaysAssert(buffer->getBound()); + + buffer->allocate(size, data); + buffer->setUsage(usage); +} + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferSubData(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLClear(GrGLbitfield mask) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearStencil(GrGLint s) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLColorMask(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompileShader(GrGLuint shader) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompressedTexImage2D(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLCullFace(GrGLenum mode) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDepthMask(GrGLboolean flag) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisable(GrGLenum cap) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisableVertexAttribArray(GrGLuint index) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawArrays(GrGLenum mode, GrGLint first, GrGLsizei count) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffer(GrGLenum mode) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffers(GrGLsizei n, const GrGLenum* bufs) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnable(GrGLenum cap) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnableVertexAttribArray(GrGLuint index) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLEndQuery(GrGLenum target) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLFinish() {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlush() {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLFrontFace(GrGLenum mode) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLLineWidth(GrGLfloat width) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLLinkProgram(GrGLuint program) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, GrGLint param) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLQueryCounter(GrGLuint id, GrGLenum target) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadBuffer(GrGLenum src) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLScissor(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLShaderSource(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFuncSeparate(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMask(GrGLuint mask) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMaskSeparate(GrGLenum face, GrGLuint mask) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOp(GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOpSeparate(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexImage2D(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexParameteri(GrGLenum target, GrGLenum pname, GrGLint param) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexStorage2D(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1f(GrGLint location, GrGLfloat v0) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1i(GrGLint location, GrGLint v0) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1iv(GrGLint location, GrGLsizei count, const GrGLint* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2f(GrGLint location, GrGLfloat v0, GrGLfloat v1) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2i(GrGLint location, GrGLint v0, GrGLint v1) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2iv(GrGLint location, GrGLsizei count, const GrGLint* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3iv(GrGLint location, GrGLsizei count, const GrGLint* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4iv(GrGLint location, GrGLsizei count, const GrGLint* v) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix2fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix3fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix4fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {} + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) { + + GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID); + GrAlwaysAssert(program); + + program->setInUse(); +} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttribPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, GrGLuint framebuffer) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetFramebufferAttachmentParameteriv(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetRenderbufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlitFramebuffer(GrGLint srcX0, GrGLint srcY0, GrGLint srcX1, GrGLint srcY1, GrGLint dstX0, GrGLint dstY0, GrGLint dstX1, GrGLint dstY1, GrGLbitfield mask, GrGLenum filter) {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLResolveMultisampleFramebuffer() {} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocationIndexed(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name) {} + +GrGLenum GR_GL_FUNCTION_TYPE debugGLCheckFramebufferStatus(GrGLenum target) { + return GR_GL_FRAMEBUFFER_COMPLETE; +} + +GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() { + + GrProgramObj *program = GrDebugGL::getInstance()->createProgram(); + + return program->getID(); +} + +GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) { + + GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || GR_GL_FRAGMENT_SHADER == type); + + GrShaderObj *shader = GrDebugGL::getInstance()->createShader(type); + + return shader->getID(); +} + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) { + + GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID); + GrAlwaysAssert(program); + + program->unref(); + + if (program->getRefCount()) { + // someone is still using this program so we can't delete it here + program->setMarkedForDeletion(); + } else { + program->deleteAction(); + } +} + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) { + + GrShaderObj *shader = GrDebugGL::getInstance()->findShader(shaderID); + GrAlwaysAssert(shader); + + shader->unref(); + + if (shader->getRefCount()) { + // someone is still using this shader so we can't delete it here + shader->setMarkedForDeletion(); + } else { + shader->deleteAction(); + } +} + +// same function used for all glGen*(GLsize i, GLuint*) functions +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenIds(GrGLsizei n, GrGLuint* ids) { + static int gCurrID = 1; + for (int i = 0; i < n; ++i) { + ids[i] = ++gCurrID; + } +} + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) { + + for (int i = 0; i < n; ++i) { + GrBufferObj *buffer = GrDebugGL::getInstance()->createBuffer(); + GrAlwaysAssert(buffer); + ids[i] = buffer->getID(); + } +} + +// same delete function for all glDelete*(GLsize i, const GLuint*) except buffers +GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteIds(GrGLsizei n, const GrGLuint* ids) {} + + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) { + + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); + + GrBufferObj *buffer = GrDebugGL::getInstance()->findBuffer(bufferID); + // 0 is a permissable bufferID - it unbinds the current buffer + + switch (target) { + case GR_GL_ARRAY_BUFFER: + if (GrDebugGL::getInstance()->getArrayBuffer()) { + // automatically break the binding of the old buffer + GrDebugGL::getInstance()->getArrayBuffer()->resetBound(); + } + if (buffer) { + GrAlwaysAssert(!buffer->getBound()); + } + GrDebugGL::getInstance()->setArrayBuffer(buffer); + if (buffer) { + buffer->setBound(); + } + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + if (GrDebugGL::getInstance()->getElementArrayBuffer()) { + // automatically break the binding of the old buffer + GrDebugGL::getInstance()->getElementArrayBuffer()->resetBound(); + } + if (buffer) { + GrAlwaysAssert(!buffer->getBound()); + } + GrDebugGL::getInstance()->setElementArrayBuffer(buffer); + if (buffer) { + buffer->setBound(); + } + break; + default: + GrCrash("Unexpected target to glBindBuffer"); + break; + } +} + +// 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) { + + if (GrDebugGL::getInstance()->getArrayBuffer() && + ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) { + // this ID is the current array buffer + GrAlwaysAssert(GrDebugGL::getInstance()->getArrayBuffer()->getBound()); + GrDebugGL::getInstance()->getArrayBuffer()->resetBound(); + GrDebugGL::getInstance()->setArrayBuffer(NULL); + } + if (GrDebugGL::getInstance()->getElementArrayBuffer() && + ids[i] == GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) { + // this ID is the current element array buffer + GrAlwaysAssert(GrDebugGL::getInstance()->getElementArrayBuffer()->getBound()); + GrDebugGL::getInstance()->getElementArrayBuffer()->resetBound(); + GrDebugGL::getInstance()->setElementArrayBuffer(NULL); + } + } + + // then actually "delete" the buffers + for (int i = 0; i < n; ++i) { + GrBufferObj *buffer = GrDebugGL::getInstance()->findBuffer(ids[i]); + GrAlwaysAssert(buffer); + + GrAlwaysAssert(!buffer->getDeleted()); + buffer->deleteAction(); + } +} + +// map a buffer to the caller's address space +GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) { + + GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); + GrAlwaysAssert(GR_GL_WRITE_ONLY == access); // GR_GL_READ_ONLY == access || || GR_GL_READ_WRIT == access); + + GrBufferObj *buffer = NULL; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = GrDebugGL::getInstance()->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); + break; + default: + GrCrash("Unexpected target to glMapBuffer"); + break; + } + + if (buffer) { + GrAlwaysAssert(!buffer->getMapped()); + buffer->setMapped(); + return buffer->getDataPtr(); + } + + GrAlwaysAssert(false); + return NULL; // no buffer bound to the target +} + +// 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 = NULL; + switch (target) { + case GR_GL_ARRAY_BUFFER: + buffer = GrDebugGL::getInstance()->getArrayBuffer(); + break; + case GR_GL_ELEMENT_ARRAY_BUFFER: + buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); + break; + default: + GrCrash("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 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 = NULL; + 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 = buffer->getSize(); + break; + case GR_GL_BUFFER_USAGE: + *params = GR_GL_STATIC_DRAW; + if (buffer) + *params = buffer->getUsage(); + break; + default: + GrCrash("Unexpected value to glGetBufferParamateriv"); + break; + } +}; + +GrGLenum GR_GL_FUNCTION_TYPE debugGLGetError() { + return GR_GL_NO_ERROR; +} + +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetIntegerv(GrGLenum pname, GrGLint* params) { + // 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_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_TEXTURE_IMAGE_UNITS: + *params = 8; + break; + case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: + *params = 16; + 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 = 16; + break; + case GR_GL_MAX_TEXTURE_UNITS: + *params = GrDebugGL::getInstance()->getMaxTextureUnits(); + break; + default: + GrCrash("Unexpected pname to GetIntegerv"); + } +} +// used for both the program and shader info logs +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog) { + if (length) { + *length = 0; + } + if (bufsize > 0) { + *infolog = 0; + } +} + +// used for both the program and shader params +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetShaderOrProgramiv(GrGLuint program, 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: + GrCrash("Unexpected pname to GetProgramiv"); + break; + } +} + +namespace { +template <typename T> +void query_result(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: + GrCrash("Unexpected pname passed to GetQueryObject."); + break; + } +} +} + +// Queries on the null GL just don't do anything at all. We could potentially make +// the timers work. +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) { + switch (pname) { + case GR_GL_CURRENT_QUERY: + *params = 0; + break; + case GR_GL_QUERY_COUNTER_BITS: + *params = 32; + break; + default: + GrCrash("Unexpected pname passed GetQueryiv."); + } +} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) { + query_result(id, pname, params); +} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) { + query_result(id, pname, params); +} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) { + query_result(id, pname, params); +} +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) { + query_result(id, pname, params); +} + +const GrGLubyte* GR_GL_FUNCTION_TYPE debugGLGetString(GrGLenum name) { + switch (name) { + case GR_GL_EXTENSIONS: + return (const GrGLubyte*)"GL_ARB_framebuffer_object GL_ARB_blend_func_extended GL_ARB_timer_query GL_ARB_draw_buffers GL_ARB_occlusion_query GL_EXT_blend_color GL_EXT_stencil_wrap"; + case GR_GL_VERSION: + return (const GrGLubyte*)"4.0 Null GL"; + case GR_GL_SHADING_LANGUAGE_VERSION: + return (const GrGLubyte*)"4.20.8 Null GLSL"; + default: + GrCrash("Unexpected name to GetString"); + return NULL; + } +} + +// we used to use this to query stuff about externally created textures, now we just +// require clients to tell us everything about the texture. +GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params) { + GrCrash("Should never query texture parameters."); +} + +GrGLint GR_GL_FUNCTION_TYPE debugGLGetUniformLocation(GrGLuint program, const char* name) { + static int gUniLocation = 0; + return ++gUniLocation; +} + +const GrGLInterface* GrGLCreateDebugInterface() { + // The gl functions are not context-specific so we create one global + // interface + static SkAutoTUnref<GrGLInterface> glInterface; + if (!glInterface.get()) { + GrGLInterface* interface = new GrGLInterface; + glInterface.reset(interface); + interface->fBindingsExported = kDesktop_GrGLBinding; + interface->fActiveTexture = debugGLActiveTexture; + interface->fAttachShader = debugGLAttachShader; + interface->fBeginQuery = debugGLBeginQuery; + interface->fBindAttribLocation = debugGLBindAttribLocation; + interface->fBindBuffer = debugGLBindBuffer; + interface->fBindFragDataLocation = debugGLBindFragDataLocation; + interface->fBindTexture = debugGLBindTexture; + interface->fBlendColor = debugGLBlendColor; + interface->fBlendFunc = debugGLBlendFunc; + interface->fBufferData = debugGLBufferData; + interface->fBufferSubData = debugGLBufferSubData; + interface->fClear = debugGLClear; + interface->fClearColor = debugGLClearColor; + interface->fClearStencil = debugGLClearStencil; + interface->fColorMask = debugGLColorMask; + interface->fCompileShader = debugGLCompileShader; + interface->fCompressedTexImage2D = debugGLCompressedTexImage2D; + interface->fCreateProgram = debugGLCreateProgram; + interface->fCreateShader = debugGLCreateShader; + interface->fCullFace = debugGLCullFace; + interface->fDeleteBuffers = debugGLDeleteBuffers; + interface->fDeleteProgram = debugGLDeleteProgram; + interface->fDeleteQueries = debugGLDeleteIds; + interface->fDeleteShader = debugGLDeleteShader; + interface->fDeleteTextures = debugGLDeleteIds; + interface->fDepthMask = debugGLDepthMask; + interface->fDisable = debugGLDisable; + interface->fDisableVertexAttribArray = debugGLDisableVertexAttribArray; + interface->fDrawArrays = debugGLDrawArrays; + interface->fDrawBuffer = debugGLDrawBuffer; + interface->fDrawBuffers = debugGLDrawBuffers; + interface->fDrawElements = debugGLDrawElements; + interface->fEnable = debugGLEnable; + interface->fEnableVertexAttribArray = debugGLEnableVertexAttribArray; + interface->fEndQuery = debugGLEndQuery; + interface->fFinish = debugGLFinish; + interface->fFlush = debugGLFlush; + interface->fFrontFace = debugGLFrontFace; + interface->fGenBuffers = debugGLGenBuffers; + interface->fGenQueries = debugGLGenIds; + interface->fGenTextures = debugGLGenIds; + interface->fGetBufferParameteriv = debugGLGetBufferParameteriv; + interface->fGetError = debugGLGetError; + interface->fGetIntegerv = debugGLGetIntegerv; + interface->fGetQueryObjecti64v = debugGLGetQueryObjecti64v; + interface->fGetQueryObjectiv = debugGLGetQueryObjectiv; + interface->fGetQueryObjectui64v = debugGLGetQueryObjectui64v; + interface->fGetQueryObjectuiv = debugGLGetQueryObjectuiv; + interface->fGetQueryiv = debugGLGetQueryiv; + interface->fGetProgramInfoLog = debugGLGetInfoLog; + interface->fGetProgramiv = debugGLGetShaderOrProgramiv; + interface->fGetShaderInfoLog = debugGLGetInfoLog; + interface->fGetShaderiv = debugGLGetShaderOrProgramiv; + interface->fGetString = debugGLGetString; + interface->fGetTexLevelParameteriv = debugGLGetTexLevelParameteriv; + interface->fGetUniformLocation = debugGLGetUniformLocation; + interface->fLineWidth = debugGLLineWidth; + interface->fLinkProgram = debugGLLinkProgram; + interface->fPixelStorei = debugGLPixelStorei; + interface->fQueryCounter = debugGLQueryCounter; + interface->fReadBuffer = debugGLReadBuffer; + interface->fReadPixels = debugGLReadPixels; + interface->fScissor = debugGLScissor; + interface->fShaderSource = debugGLShaderSource; + interface->fStencilFunc = debugGLStencilFunc; + interface->fStencilFuncSeparate = debugGLStencilFuncSeparate; + interface->fStencilMask = debugGLStencilMask; + interface->fStencilMaskSeparate = debugGLStencilMaskSeparate; + interface->fStencilOp = debugGLStencilOp; + interface->fStencilOpSeparate = debugGLStencilOpSeparate; + interface->fTexImage2D = debugGLTexImage2D; + interface->fTexParameteri = debugGLTexParameteri; + interface->fTexSubImage2D = debugGLTexSubImage2D; + interface->fTexStorage2D = debugGLTexStorage2D; + interface->fUniform1f = debugGLUniform1f; + interface->fUniform1i = debugGLUniform1i; + interface->fUniform1fv = debugGLUniform1fv; + interface->fUniform1iv = debugGLUniform1iv; + interface->fUniform2f = debugGLUniform2f; + interface->fUniform2i = debugGLUniform2i; + interface->fUniform2fv = debugGLUniform2fv; + interface->fUniform2iv = debugGLUniform2iv; + interface->fUniform3f = debugGLUniform3f; + interface->fUniform3i = debugGLUniform3i; + interface->fUniform3fv = debugGLUniform3fv; + interface->fUniform3iv = debugGLUniform3iv; + interface->fUniform4f = debugGLUniform4f; + interface->fUniform4i = debugGLUniform4i; + interface->fUniform4fv = debugGLUniform4fv; + interface->fUniform4iv = debugGLUniform4iv; + interface->fUniformMatrix2fv = debugGLUniformMatrix2fv; + interface->fUniformMatrix3fv = debugGLUniformMatrix3fv; + interface->fUniformMatrix4fv = debugGLUniformMatrix4fv; + interface->fUseProgram = debugGLUseProgram; + interface->fVertexAttrib4fv = debugGLVertexAttrib4fv; + interface->fVertexAttribPointer = debugGLVertexAttribPointer; + interface->fViewport = debugGLViewport; + interface->fBindFramebuffer = debugGLBindFramebuffer; + interface->fBindRenderbuffer = debugGLBindRenderbuffer; + interface->fCheckFramebufferStatus = debugGLCheckFramebufferStatus; + interface->fDeleteFramebuffers = debugGLDeleteFramebuffers; + interface->fDeleteRenderbuffers = debugGLDeleteRenderbuffers; + interface->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer; + interface->fFramebufferTexture2D = debugGLFramebufferTexture2D; + interface->fGenFramebuffers = debugGLGenIds; + interface->fGenRenderbuffers = debugGLGenIds; + interface->fGetFramebufferAttachmentParameteriv = debugGLGetFramebufferAttachmentParameteriv; + interface->fGetRenderbufferParameteriv = debugGLGetRenderbufferParameteriv; + interface->fRenderbufferStorage = debugGLRenderbufferStorage; + interface->fRenderbufferStorageMultisample = debugGLRenderbufferStorageMultisample; + interface->fBlitFramebuffer = debugGLBlitFramebuffer; + interface->fResolveMultisampleFramebuffer = debugGLResolveMultisampleFramebuffer; + interface->fMapBuffer = debugGLMapBuffer; + interface->fUnmapBuffer = debugGLUnmapBuffer; + interface->fBindFragDataLocationIndexed = debugGLBindFragDataLocationIndexed; + } + glInterface.get()->ref(); + return glInterface.get(); +} diff --git a/src/gpu/gl/SkDebugGLContext.cpp b/src/gpu/gl/SkDebugGLContext.cpp new file mode 100644 index 0000000000..ae42227251 --- /dev/null +++ b/src/gpu/gl/SkDebugGLContext.cpp @@ -0,0 +1,13 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gl/SkDebugGLContext.h" + +const GrGLInterface* SkDebugGLContext::createGLContext() { + return GrGLCreateDebugInterface(); +}; |