aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/debug/GrBufferObj.cpp9
-rw-r--r--src/gpu/gl/debug/GrBufferObj.h84
-rw-r--r--src/gpu/gl/debug/GrDebugGL.cpp196
-rw-r--r--src/gpu/gl/debug/GrDebugGL.h124
-rw-r--r--src/gpu/gl/debug/GrFBBindableObj.cpp9
-rw-r--r--src/gpu/gl/debug/GrFBBindableObj.h88
-rw-r--r--src/gpu/gl/debug/GrFakeRefObj.cpp9
-rw-r--r--src/gpu/gl/debug/GrFakeRefObj.h93
-rw-r--r--src/gpu/gl/debug/GrFrameBufferObj.cpp67
-rw-r--r--src/gpu/gl/debug/GrFrameBufferObj.h68
-rw-r--r--src/gpu/gl/debug/GrGLCreateDebugInterface.cpp790
-rw-r--r--src/gpu/gl/debug/GrProgramObj.cpp27
-rw-r--r--src/gpu/gl/debug/GrProgramObj.h43
-rw-r--r--src/gpu/gl/debug/GrRenderBufferObj.cpp9
-rw-r--r--src/gpu/gl/debug/GrRenderBufferObj.h40
-rw-r--r--src/gpu/gl/debug/GrShaderObj.cpp9
-rw-r--r--src/gpu/gl/debug/GrShaderObj.h38
-rw-r--r--src/gpu/gl/debug/GrTextureObj.cpp9
-rw-r--r--src/gpu/gl/debug/GrTextureObj.h60
-rw-r--r--src/gpu/gl/debug/GrTextureUnitObj.cpp32
-rw-r--r--src/gpu/gl/debug/GrTextureUnitObj.h45
21 files changed, 1067 insertions, 782 deletions
diff --git a/src/gpu/gl/debug/GrBufferObj.cpp b/src/gpu/gl/debug/GrBufferObj.cpp
new file mode 100644
index 0000000000..0cd4fc8068
--- /dev/null
+++ b/src/gpu/gl/debug/GrBufferObj.cpp
@@ -0,0 +1,9 @@
+
+/*
+ * 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 "GrBufferObj.h"
diff --git a/src/gpu/gl/debug/GrBufferObj.h b/src/gpu/gl/debug/GrBufferObj.h
new file mode 100644
index 0000000000..e4cfee2a0e
--- /dev/null
+++ b/src/gpu/gl/debug/GrBufferObj.h
@@ -0,0 +1,84 @@
+
+/*
+ * 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 GrBufferObj_DEFINED
+#define GrBufferObj_DEFINED
+
+#include "GrFakeRefObj.h"
+
+////////////////////////////////////////////////////////////////////////////////
+class GrBufferObj : public GrFakeRefObj {
+ GR_DEFINE_CREATOR(GrBufferObj);
+
+public:
+ GrBufferObj()
+ : GrFakeRefObj()
+ , 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 GrGLchar *dataPtr) {
+ GrAlwaysAssert(size >= 0);
+
+ // delete pre-existing data
+ delete[] fDataPtr;
+
+ fSize = size;
+ fDataPtr = new GrGLchar[size];
+ if (dataPtr) {
+ memcpy(fDataPtr, dataPtr, fSize);
+ }
+ // TODO: w/ no dataPtr the data is unitialized - this could be tracked
+ }
+ GrGLint getSize() const { return fSize; }
+ GrGLchar *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->INHERITED::deleteAction();
+ }
+
+
+protected:
+private:
+
+ GrGLchar* 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;
+};
+
+#endif // GrBufferObj_DEFINED
diff --git a/src/gpu/gl/debug/GrDebugGL.cpp b/src/gpu/gl/debug/GrDebugGL.cpp
new file mode 100644
index 0000000000..60971eb270
--- /dev/null
+++ b/src/gpu/gl/debug/GrDebugGL.cpp
@@ -0,0 +1,196 @@
+
+/*
+ * 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 "GrDebugGL.h"
+#include "GrTextureObj.h"
+#include "GrBufferObj.h"
+#include "GrRenderBufferObj.h"
+#include "GrFrameBufferObj.h"
+#include "GrShaderObj.h"
+#include "GrProgramObj.h"
+#include "GrTextureUnitObj.h"
+
+
+GrDebugGL GrDebugGL::Obj;
+GrDebugGL::Create GrDebugGL::gFactoryFunc[kObjTypeCount] = {
+ GrTextureObj::createGrTextureObj,
+ GrBufferObj::createGrBufferObj,
+ GrRenderBufferObj::createGrRenderBufferObj,
+ GrFrameBufferObj::createGrFrameBufferObj,
+ GrShaderObj::createGrShaderObj,
+ GrProgramObj::createGrProgramObj,
+ GrTextureUnitObj::createGrTextureUnitObj,
+};
+
+
+GrDebugGL::GrDebugGL()
+ : fCurTextureUnit(0)
+ , fArrayBuffer(NULL)
+ , fElementArrayBuffer(NULL)
+ , fFrameBuffer(NULL)
+ , fRenderBuffer(NULL)
+ , fProgram(NULL)
+ , fTexture(NULL) {
+
+ for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
+ fTextureUnits[i] = GR_CREATE(GrTextureUnitObj, GrDebugGL::kTextureUnit_ObjTypes);
+ fTextureUnits[i]->ref();
+
+ fTextureUnits[i]->setNumber(i);
+ }
+}
+
+GrDebugGL::~GrDebugGL() {
+ // 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();
+ }
+
+ this->report();
+
+ for (int i = 0; i < fObjects.count(); ++i) {
+ delete fObjects[i];
+ }
+ fObjects.reset();
+
+ fArrayBuffer = NULL;
+ fElementArrayBuffer = NULL;
+ fFrameBuffer = NULL;
+ fRenderBuffer = NULL;
+ fProgram = NULL;
+ fTexture = NULL;
+}
+
+GrFakeRefObj *GrDebugGL::findObject(GrGLuint ID, GrObjTypes 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 NULL;
+}
+
+void GrDebugGL::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();
+ }
+}
+
+void GrDebugGL::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();
+ }
+}
+
+void GrDebugGL::setTexture(GrTextureObj *texture) {
+ fTextureUnits[fCurTextureUnit]->setTexture(texture);
+}
+
+void GrDebugGL::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();
+ }
+}
+
+void GrDebugGL::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();
+ }
+}
+
+void GrDebugGL::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 GrDebugGL::report() const {
+ for (int i = 0; i < fObjects.count(); ++i) {
+ GrAlwaysAssert(0 == fObjects[i]->getRefCount());
+ GrAlwaysAssert(0 < fObjects[i]->getHighRefCount());
+ GrAlwaysAssert(fObjects[i]->getDeleted());
+ }
+}
diff --git a/src/gpu/gl/debug/GrDebugGL.h b/src/gpu/gl/debug/GrDebugGL.h
new file mode 100644
index 0000000000..d6af98ecad
--- /dev/null
+++ b/src/gpu/gl/debug/GrDebugGL.h
@@ -0,0 +1,124 @@
+
+/*
+ * 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 GrDebugGL_DEFINED
+#define GrDebugGL_DEFINED
+
+#include "SkTArray.h"
+#include "gl/GrGLInterface.h"
+
+class GrFakeRefObj;
+class GrTextureUnitObj;
+class GrBufferObj;
+class GrTextureObj;
+class GrFrameBufferObj;
+class GrRenderBufferObj;
+class GrProgramObj;
+
+////////////////////////////////////////////////////////////////////////////////
+// This is the main debugging object. It is a singleton and keeps track of
+// all the other debug objects.
+class GrDebugGL {
+public:
+ enum GrObjTypes {
+ kTexture_ObjTypes = 0,
+ kBuffer_ObjTypes,
+ kRenderBuffer_ObjTypes,
+ kFrameBuffer_ObjTypes,
+ kShader_ObjTypes,
+ kProgram_ObjTypes,
+ kTextureUnit_ObjTypes,
+ kObjTypeCount
+ };
+
+ GrFakeRefObj *createObj(GrObjTypes type) {
+ GrFakeRefObj *temp = (*gFactoryFunc[type])();
+
+ fObjects.push_back(temp);
+
+ return temp;
+ }
+
+ GrFakeRefObj *findObject(GrGLuint ID, GrObjTypes type);
+
+ GrGLuint getMaxTextureUnits() const { return kDefaultMaxTextureUnits; }
+
+ void setCurTextureUnit(GrGLuint curTextureUnit) { fCurTextureUnit = curTextureUnit; }
+ GrGLuint getCurTextureUnit() const { return fCurTextureUnit; }
+
+ GrTextureUnitObj *getTextureUnit(int iUnit) {
+ GrAlwaysAssert(0 <= iUnit && kDefaultMaxTextureUnits > iUnit);
+
+ return fTextureUnits[iUnit];
+ }
+
+ void setArrayBuffer(GrBufferObj *arrayBuffer);
+ GrBufferObj *getArrayBuffer() { return fArrayBuffer; }
+
+ void setElementArrayBuffer(GrBufferObj *elementArrayBuffer);
+ GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
+
+ void setTexture(GrTextureObj *texture);
+
+ void setFrameBuffer(GrFrameBufferObj *frameBuffer);
+ GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
+
+ void setRenderBuffer(GrRenderBufferObj *renderBuffer);
+ GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
+
+ void useProgram(GrProgramObj *program);
+
+ static GrDebugGL *getInstance() {
+// static GrDebugGL Obj;
+
+ return &Obj;
+ }
+
+ void report() const;
+
+protected:
+
+private:
+ // the OpenGLES 2.0 spec says this must be >= 2
+ static const GrGLint kDefaultMaxTextureUnits = 8;
+
+ GrGLuint fMaxTextureUnits;
+ GrGLuint fCurTextureUnit;
+ GrBufferObj * fArrayBuffer;
+ GrBufferObj * fElementArrayBuffer;
+ GrFrameBufferObj *fFrameBuffer;
+ GrRenderBufferObj *fRenderBuffer;
+ GrProgramObj * fProgram;
+ GrTextureObj * fTexture;
+ GrTextureUnitObj *fTextureUnits[kDefaultMaxTextureUnits];
+
+ typedef GrFakeRefObj *(*Create)();
+
+ static Create gFactoryFunc[kObjTypeCount];
+
+ static GrDebugGL Obj;
+
+ // global store of all objects
+ SkTArray<GrFakeRefObj *> fObjects;
+
+ GrDebugGL();
+ ~GrDebugGL();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper macro to make creating an object (where you need to get back a derived
+// type) easier
+#define GR_CREATE(className, classEnum) \
+ reinterpret_cast<className *>(GrDebugGL::getInstance()->createObj(classEnum))
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper macro to make finding objects less painful
+#define GR_FIND(id, className, classEnum) \
+ reinterpret_cast<className *>(GrDebugGL::getInstance()->findObject(id, classEnum))
+
+#endif // GrDebugGL_DEFINED
diff --git a/src/gpu/gl/debug/GrFBBindableObj.cpp b/src/gpu/gl/debug/GrFBBindableObj.cpp
new file mode 100644
index 0000000000..dbab2d7397
--- /dev/null
+++ b/src/gpu/gl/debug/GrFBBindableObj.cpp
@@ -0,0 +1,9 @@
+
+/*
+ * 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 "GrFBBindableObj.h" \ No newline at end of file
diff --git a/src/gpu/gl/debug/GrFBBindableObj.h b/src/gpu/gl/debug/GrFBBindableObj.h
new file mode 100644
index 0000000000..38c86380a2
--- /dev/null
+++ b/src/gpu/gl/debug/GrFBBindableObj.h
@@ -0,0 +1,88 @@
+
+/*
+ * 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 GrFBBindableObj_DEFINED
+#define GrFBBindableObj_DEFINED
+
+#include "SkTDArray.h"
+#include "GrFakeRefObj.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// A common base class for render buffers and textures
+class GrFBBindableObj : public GrFakeRefObj {
+
+public:
+ GrFBBindableObj()
+ : GrFakeRefObj() {
+ }
+
+ virtual ~GrFBBindableObj() {
+ GrAlwaysAssert(0 == fColorReferees.count());
+ GrAlwaysAssert(0 == fDepthReferees.count());
+ GrAlwaysAssert(0 == fStencilReferees.count());
+ }
+
+ void setColorBound(GrFakeRefObj *referee) {
+ fColorReferees.append(1, &referee);
+ }
+ void resetColorBound(GrFakeRefObj *referee) {
+ int index = fColorReferees.find(referee);
+ GrAlwaysAssert(0 <= index);
+ fColorReferees.removeShuffle(index);
+ }
+ bool getColorBound(GrFakeRefObj *referee) const {
+ int index = fColorReferees.find(referee);
+ return 0 <= index;
+ }
+ bool getColorBound() const {
+ return 0 != fColorReferees.count();
+ }
+
+ void setDepthBound(GrFakeRefObj *referee) {
+ fDepthReferees.append(1, &referee);
+ }
+ void resetDepthBound(GrFakeRefObj *referee) {
+ int index = fDepthReferees.find(referee);
+ GrAlwaysAssert(0 <= index);
+ fDepthReferees.removeShuffle(index);
+ }
+ bool getDepthBound(GrFakeRefObj *referee) const {
+ int index = fDepthReferees.find(referee);
+ return 0 <= index;
+ }
+ bool getDepthBound() const {
+ return 0 != fDepthReferees.count();
+ }
+
+ void setStencilBound(GrFakeRefObj *referee) {
+ fStencilReferees.append(1, &referee);
+ }
+ void resetStencilBound(GrFakeRefObj *referee) {
+ int index = fStencilReferees.find(referee);
+ GrAlwaysAssert(0 <= index);
+ fStencilReferees.removeShuffle(index);
+ }
+ bool getStencilBound(GrFakeRefObj *referee) const {
+ int index = fStencilReferees.find(referee);
+ return 0 <= index;
+ }
+ bool getStencilBound() const {
+ return 0 != fStencilReferees.count();
+ }
+
+
+protected:
+private:
+ SkTDArray<GrFakeRefObj *> fColorReferees; // frame buffers that use this as a color buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
+ SkTDArray<GrFakeRefObj *> fDepthReferees; // frame buffers that use this as a depth buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
+ SkTDArray<GrFakeRefObj *> fStencilReferees; // frame buffers that use this as a stencil buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
+
+ typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrFBBindableObj_DEFINED
diff --git a/src/gpu/gl/debug/GrFakeRefObj.cpp b/src/gpu/gl/debug/GrFakeRefObj.cpp
new file mode 100644
index 0000000000..508f5c34ae
--- /dev/null
+++ b/src/gpu/gl/debug/GrFakeRefObj.cpp
@@ -0,0 +1,9 @@
+
+/*
+ * 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 "GrFakeRefObj.h" \ No newline at end of file
diff --git a/src/gpu/gl/debug/GrFakeRefObj.h b/src/gpu/gl/debug/GrFakeRefObj.h
new file mode 100644
index 0000000000..8dbef9cb59
--- /dev/null
+++ b/src/gpu/gl/debug/GrFakeRefObj.h
@@ -0,0 +1,93 @@
+
+/*
+ * 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 GrFakeRefObj_DEFINED
+#define GrFakeRefObj_DEFINED
+
+#include "gl/GrGLInterface.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// 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()
+ : fRef(0)
+ , fHighRefCount(0)
+ , fMarkedForDeletion(false)
+ , fDeleted(false) {
+
+ static int fNextID = 0; // source for globally unique IDs - 0 is reserved!
+
+ fID = ++fNextID;
+ }
+ virtual ~GrFakeRefObj() {};
+
+ void ref() {
+ fRef++;
+ if (fHighRefCount < fRef) {
+ fHighRefCount = fRef;
+ }
+ }
+ void unref() {
+ fRef--;
+ GrAlwaysAssert(fRef >= 0);
+
+ // 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; }
+ int getHighRefCount() const { return fHighRefCount; }
+
+ GrGLuint getID() const { return fID; }
+
+ void setMarkedForDeletion() { fMarkedForDeletion = true; }
+ bool getMarkedForDeletion() const { return fMarkedForDeletion; }
+
+ 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() {
+ this->setDeleted();
+ }
+
+protected:
+private:
+ int fRef;
+ int fHighRefCount; // high water mark of the ref count
+ 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;
+
+ // setDeleted should only ever appear in the deleteAction method!
+ void setDeleted() { fDeleted = true; }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Each class derived from GrFakeRefObj should use this macro to add a
+// factory creation entry point. This entry point is used by the GrGLDebug
+// object to instantiate the various objects
+// all globally unique IDs
+#define GR_DEFINE_CREATOR(className) \
+ public: \
+ static GrFakeRefObj *create ## className() { \
+ return SkNEW(className); \
+ }
+
+#endif // GrFakeRefObj_DEFINED
diff --git a/src/gpu/gl/debug/GrFrameBufferObj.cpp b/src/gpu/gl/debug/GrFrameBufferObj.cpp
new file mode 100644
index 0000000000..331be8a702
--- /dev/null
+++ b/src/gpu/gl/debug/GrFrameBufferObj.cpp
@@ -0,0 +1,67 @@
+
+/*
+ * 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 "GrFrameBufferObj.h"
+#include "GrFBBindableObj.h"
+
+void GrFrameBufferObj::setColor(GrFBBindableObj *buffer) {
+ if (fColorBuffer) {
+ // automatically break the binding of the old buffer
+ GrAlwaysAssert(fColorBuffer->getColorBound(this));
+ fColorBuffer->resetColorBound(this);
+
+ GrAlwaysAssert(!fColorBuffer->getDeleted());
+ fColorBuffer->unref();
+ }
+ fColorBuffer = buffer;
+ if (fColorBuffer) {
+ GrAlwaysAssert(!fColorBuffer->getDeleted());
+ fColorBuffer->ref();
+
+ GrAlwaysAssert(!fColorBuffer->getColorBound(this));
+ fColorBuffer->setColorBound(this);
+ }
+}
+
+void GrFrameBufferObj::setDepth(GrFBBindableObj *buffer) {
+ if (fDepthBuffer) {
+ // automatically break the binding of the old buffer
+ GrAlwaysAssert(fDepthBuffer->getDepthBound(this));
+ fDepthBuffer->resetDepthBound(this);
+
+ GrAlwaysAssert(!fDepthBuffer->getDeleted());
+ fDepthBuffer->unref();
+ }
+ fDepthBuffer = buffer;
+ if (fDepthBuffer) {
+ GrAlwaysAssert(!fDepthBuffer->getDeleted());
+ fDepthBuffer->ref();
+
+ GrAlwaysAssert(!fDepthBuffer->getDepthBound(this));
+ fDepthBuffer->setDepthBound(this);
+ }
+}
+
+void GrFrameBufferObj::setStencil(GrFBBindableObj *buffer) {
+ if (fStencilBuffer) {
+ // automatically break the binding of the old buffer
+ GrAlwaysAssert(fStencilBuffer->getStencilBound(this));
+ fStencilBuffer->resetStencilBound(this);
+
+ GrAlwaysAssert(!fStencilBuffer->getDeleted());
+ fStencilBuffer->unref();
+ }
+ fStencilBuffer = buffer;
+ if (fStencilBuffer) {
+ GrAlwaysAssert(!fStencilBuffer->getDeleted());
+ fStencilBuffer->ref();
+
+ GrAlwaysAssert(!fStencilBuffer->getStencilBound(this));
+ fStencilBuffer->setStencilBound(this);
+ }
+} \ No newline at end of file
diff --git a/src/gpu/gl/debug/GrFrameBufferObj.h b/src/gpu/gl/debug/GrFrameBufferObj.h
new file mode 100644
index 0000000000..33af4f7a97
--- /dev/null
+++ b/src/gpu/gl/debug/GrFrameBufferObj.h
@@ -0,0 +1,68 @@
+
+/*
+ * 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 GrFrameBufferObj_DEFINED
+#define GrFrameBufferObj_DEFINED
+
+#include "GrFakeRefObj.h"
+class GrFBBindableObj;
+
+////////////////////////////////////////////////////////////////////////////////
+// TODO: when a framebuffer obj is bound the GL_SAMPLES query must return 0
+// TODO: GL_STENCIL_BITS must also be redirected to the framebuffer
+class GrFrameBufferObj : public GrFakeRefObj {
+ GR_DEFINE_CREATOR(GrFrameBufferObj);
+
+public:
+ GrFrameBufferObj()
+ : GrFakeRefObj()
+ , fBound(false)
+ , fColorBuffer(NULL)
+ , fDepthBuffer(NULL)
+ , fStencilBuffer(NULL) {
+ }
+
+ virtual ~GrFrameBufferObj() {
+ fColorBuffer = NULL;
+ fDepthBuffer = NULL;
+ fStencilBuffer = NULL;
+ }
+
+ void setBound() { fBound = true; }
+ void resetBound() { fBound = false; }
+ bool getBound() const { return fBound; }
+
+ void setColor(GrFBBindableObj *buffer);
+ GrFBBindableObj *getColor() { return fColorBuffer; }
+
+ void setDepth(GrFBBindableObj *buffer);
+ GrFBBindableObj *getDepth() { return fDepthBuffer; }
+
+ void setStencil(GrFBBindableObj *buffer);
+ GrFBBindableObj *getStencil() { return fStencilBuffer; }
+
+ virtual void deleteAction() SK_OVERRIDE {
+
+ setColor(NULL);
+ setDepth(NULL);
+ setStencil(NULL);
+
+ this->INHERITED::deleteAction();
+ }
+
+protected:
+private:
+ bool fBound; // is this frame buffer currently bound via "glBindFramebuffer"?
+ GrFBBindableObj * fColorBuffer;
+ GrFBBindableObj * fDepthBuffer;
+ GrFBBindableObj * fStencilBuffer;
+
+ typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrFrameBufferObj_DEFINED
diff --git a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
index 5b8c315414..a9adf7d017 100644
--- a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
+++ b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
@@ -8,9 +8,14 @@
#include "gl/GrGLInterface.h"
-
-#include "SkTArray.h"
-#include "SkTDArray.h"
+#include "GrDebugGL.h"
+#include "GrShaderObj.h"
+#include "GrProgramObj.h"
+#include "GrBufferObj.h"
+#include "GrTextureUnitObj.h"
+#include "GrTextureObj.h"
+#include "GrFrameBufferObj.h"
+#include "GrRenderBufferObj.h"
// the OpenGLES 2.0 spec says this must be >= 128
static const GrGLint kDefaultMaxVertexUniformVectors = 128;
@@ -25,785 +30,6 @@ static const GrGLint kDefaultMaxVertexAttribs = 8;
static const GrGLint kDefaultMaxVaryingVectors = 8;
////////////////////////////////////////////////////////////////////////////////
-// Each class derived from GrFakeRefObj should use this macro to add a
-// factory creation entry point. This entry point is used by the GrGLDebug
-// object to instantiate the various objects
-// all globally unique IDs
-#define GR_DEFINE_CREATOR(className) \
- public: \
- static GrFakeRefObj *create ## className() { \
- return SkNEW(className); \
- }
-
-////////////////////////////////////////////////////////////////////////////////
-// Helper macro to make creating an object (where you need to get back a derived
-// type) easier
-#define GR_CREATE(className, classEnum) \
- reinterpret_cast<className *>(GrDebugGL::getInstance()->createObj(classEnum))
-
-////////////////////////////////////////////////////////////////////////////////
-// Helper macro to make finding objects less painful
-#define GR_FIND(id, className, classEnum) \
- reinterpret_cast<className *>(GrDebugGL::getInstance()->findObject(id, classEnum))
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// 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()
- : fRef(0)
- , fHighRefCount(0)
- , fMarkedForDeletion(false)
- , fDeleted(false) {
-
- static int fNextID = 0; // source for globally unique IDs - 0 is reserved!
-
- fID = ++fNextID;
- }
- virtual ~GrFakeRefObj() {};
-
- void ref() {
- fRef++;
- if (fHighRefCount < fRef) {
- fHighRefCount = fRef;
- }
- }
- void unref() {
- fRef--;
- GrAlwaysAssert(fRef >= 0);
-
- // 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; }
- int getHighRefCount() const { return fHighRefCount; }
-
- GrGLuint getID() const { return fID; }
-
- void setMarkedForDeletion() { fMarkedForDeletion = true; }
- bool getMarkedForDeletion() const { return fMarkedForDeletion; }
-
- 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() {
- this->setDeleted();
- }
-
-protected:
-private:
- int fRef;
- int fHighRefCount; // high water mark of the ref count
- 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;
-
- // setDeleted should only ever appear in the deleteAction method!
- void setDeleted() { fDeleted = true; }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-class GrBufferObj : public GrFakeRefObj {
- GR_DEFINE_CREATOR(GrBufferObj);
-
-public:
- GrBufferObj()
- : GrFakeRefObj()
- , 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 GrGLchar *dataPtr) {
- GrAlwaysAssert(size >= 0);
-
- // delete pre-existing data
- delete[] fDataPtr;
-
- fSize = size;
- fDataPtr = new GrGLchar[size];
- if (dataPtr) {
- memcpy(fDataPtr, dataPtr, fSize);
- }
- // TODO: w/ no dataPtr the data is unitialized - this could be tracked
- }
- GrGLint getSize() const { return fSize; }
- GrGLchar *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->INHERITED::deleteAction();
- }
-
-
-protected:
-private:
-
- GrGLchar* 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;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// A common base class for render buffers and textures
-class GrFBBindable : public GrFakeRefObj {
-
-public:
- GrFBBindable()
- : GrFakeRefObj() {
- }
-
- virtual ~GrFBBindable() {
- GrAlwaysAssert(0 == fColorReferees.count());
- GrAlwaysAssert(0 == fDepthReferees.count());
- GrAlwaysAssert(0 == fStencilReferees.count());
- }
-
- void setColorBound(GrFakeRefObj *referee) {
- fColorReferees.append(1, &referee);
- }
- void resetColorBound(GrFakeRefObj *referee) {
- int index = fColorReferees.find(referee);
- GrAlwaysAssert(0 <= index);
- fColorReferees.removeShuffle(index);
- }
- bool getColorBound(GrFakeRefObj *referee) const {
- int index = fColorReferees.find(referee);
- return 0 <= index;
- }
- bool getColorBound() const {
- return 0 != fColorReferees.count();
- }
-
- void setDepthBound(GrFakeRefObj *referee) {
- fDepthReferees.append(1, &referee);
- }
- void resetDepthBound(GrFakeRefObj *referee) {
- int index = fDepthReferees.find(referee);
- GrAlwaysAssert(0 <= index);
- fDepthReferees.removeShuffle(index);
- }
- bool getDepthBound(GrFakeRefObj *referee) const {
- int index = fDepthReferees.find(referee);
- return 0 <= index;
- }
- bool getDepthBound() const {
- return 0 != fDepthReferees.count();
- }
-
- void setStencilBound(GrFakeRefObj *referee) {
- fStencilReferees.append(1, &referee);
- }
- void resetStencilBound(GrFakeRefObj *referee) {
- int index = fStencilReferees.find(referee);
- GrAlwaysAssert(0 <= index);
- fStencilReferees.removeShuffle(index);
- }
- bool getStencilBound(GrFakeRefObj *referee) const {
- int index = fStencilReferees.find(referee);
- return 0 <= index;
- }
- bool getStencilBound() const {
- return 0 != fStencilReferees.count();
- }
-
-
-protected:
-private:
- SkTDArray<GrFakeRefObj *> fColorReferees; // frame buffers that use this as a color buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
- SkTDArray<GrFakeRefObj *> fDepthReferees; // frame buffers that use this as a depth buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
- SkTDArray<GrFakeRefObj *> fStencilReferees; // frame buffers that use this as a stencil buffer (via "glFramebufferRenderbuffer" or "glFramebufferTexture2D")
-
- typedef GrFakeRefObj INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-class GrRenderBufferObj : public GrFBBindable {
- GR_DEFINE_CREATOR(GrRenderBufferObj);
-
-public:
- GrRenderBufferObj()
- : GrFBBindable()
- , fBound(false) {
- }
-
- void setBound() { fBound = true; }
- void resetBound() { fBound = false; }
- bool getBound() const { return fBound; }
-
- virtual void deleteAction() SK_OVERRIDE {
-
- this->INHERITED::deleteAction();
- }
-
-protected:
-private:
- bool fBound; // is this render buffer currently bound via "glBindRenderbuffer"?
-
- typedef GrFBBindable INHERITED;
-};
-
-class GrTextureUnitObj;
-
-////////////////////////////////////////////////////////////////////////////////
-class GrTextureObj : public GrFBBindable {
- GR_DEFINE_CREATOR(GrTextureObj);
-
-public:
- GrTextureObj()
- : GrFBBindable() {
- }
-
- virtual ~GrTextureObj() {
- GrAlwaysAssert(0 == fTextureUnitReferees.count());
- }
-
- void setBound(GrTextureUnitObj *referee) {
- fTextureUnitReferees.append(1, &referee);
- }
-
- void resetBound(GrTextureUnitObj *referee) {
- int index = fTextureUnitReferees.find(referee);
- GrAlwaysAssert(0 <= index);
- fTextureUnitReferees.removeShuffle(index);
- }
- bool getBound(GrTextureUnitObj *referee) const {
- int index = fTextureUnitReferees.find(referee);
- return 0 <= index;
- }
- bool getBound() const {
- return 0 != fTextureUnitReferees.count();
- }
-
- virtual void deleteAction() SK_OVERRIDE {
-
- this->INHERITED::deleteAction();
- }
-
-protected:
-
-private:
- SkTDArray<GrTextureUnitObj *> fTextureUnitReferees; // texture units that bind this texture (via "glBindTexture")
-
- typedef GrFBBindable INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// Although texture unit objects are allocated & deallocated like the other
-// GL emulation objects they are derived from GrFakeRefObj to provide some
-// uniformity in how the GrDebugGL class manages resources
-class GrTextureUnitObj : public GrFakeRefObj {
- GR_DEFINE_CREATOR(GrTextureUnitObj);
-
-public:
- GrTextureUnitObj()
- : GrFakeRefObj()
- , fNumber(0)
- , fTexture(NULL) {
- }
-
- void setNumber(GrGLenum number) {
- fNumber = number;
- }
- GrGLenum getNumber() const { return fNumber; }
-
- void setTexture(GrTextureObj *texture) {
-
- if (fTexture) {
- GrAlwaysAssert(fTexture->getBound(this));
- fTexture->resetBound(this);
-
- GrAlwaysAssert(!fTexture->getDeleted());
- fTexture->unref();
- }
-
- fTexture = texture;
-
- if (fTexture) {
- GrAlwaysAssert(!fTexture->getDeleted());
- fTexture->ref();
-
- GrAlwaysAssert(!fTexture->getBound(this));
- fTexture->setBound(this);
- }
- }
-
- GrTextureObj *getTexture() { return fTexture; }
-
-protected:
-private:
- GrGLenum fNumber;
- GrTextureObj *fTexture;
-
- typedef GrFakeRefObj INHERITED;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-// TODO: when a framebuffer obj is bound the GL_SAMPLES query must return 0
-// TODO: GL_STENCIL_BITS must also be redirected to the framebuffer
-class GrFrameBufferObj : public GrFakeRefObj {
- GR_DEFINE_CREATOR(GrFrameBufferObj);
-
-public:
- GrFrameBufferObj()
- : GrFakeRefObj()
- , fBound(false)
- , fColorBuffer(NULL)
- , fDepthBuffer(NULL)
- , fStencilBuffer(NULL) {
- }
-
- virtual ~GrFrameBufferObj() {
- fColorBuffer = NULL;
- fDepthBuffer = NULL;
- fStencilBuffer = NULL;
- }
-
- void setBound() { fBound = true; }
- void resetBound() { fBound = false; }
- bool getBound() const { return fBound; }
-
- void setColor(GrFBBindable *buffer) {
- if (fColorBuffer) {
- // automatically break the binding of the old buffer
- GrAlwaysAssert(fColorBuffer->getColorBound(this));
- fColorBuffer->resetColorBound(this);
-
- GrAlwaysAssert(!fColorBuffer->getDeleted());
- fColorBuffer->unref();
- }
- fColorBuffer = buffer;
- if (fColorBuffer) {
- GrAlwaysAssert(!fColorBuffer->getDeleted());
- fColorBuffer->ref();
-
- GrAlwaysAssert(!fColorBuffer->getColorBound(this));
- fColorBuffer->setColorBound(this);
- }
- }
- GrFBBindable *getColor() { return fColorBuffer; }
-
- void setDepth(GrFBBindable *buffer) {
- if (fDepthBuffer) {
- // automatically break the binding of the old buffer
- GrAlwaysAssert(fDepthBuffer->getDepthBound(this));
- fDepthBuffer->resetDepthBound(this);
-
- GrAlwaysAssert(!fDepthBuffer->getDeleted());
- fDepthBuffer->unref();
- }
- fDepthBuffer = buffer;
- if (fDepthBuffer) {
- GrAlwaysAssert(!fDepthBuffer->getDeleted());
- fDepthBuffer->ref();
-
- GrAlwaysAssert(!fDepthBuffer->getDepthBound(this));
- fDepthBuffer->setDepthBound(this);
- }
- }
- GrFBBindable *getDepth() { return fDepthBuffer; }
-
- void setStencil(GrFBBindable *buffer) {
- if (fStencilBuffer) {
- // automatically break the binding of the old buffer
- GrAlwaysAssert(fStencilBuffer->getStencilBound(this));
- fStencilBuffer->resetStencilBound(this);
-
- GrAlwaysAssert(!fStencilBuffer->getDeleted());
- fStencilBuffer->unref();
- }
- fStencilBuffer = buffer;
- if (fStencilBuffer) {
- GrAlwaysAssert(!fStencilBuffer->getDeleted());
- fStencilBuffer->ref();
-
- GrAlwaysAssert(!fStencilBuffer->getStencilBound(this));
- fStencilBuffer->setStencilBound(this);
- }
- }
- GrFBBindable *getStencil() { return fStencilBuffer; }
-
- virtual void deleteAction() SK_OVERRIDE {
-
- setColor(NULL);
- setDepth(NULL);
- setStencil(NULL);
-
- this->INHERITED::deleteAction();
- }
-
-protected:
-private:
- bool fBound; // is this frame buffer currently bound via "glBindFramebuffer"?
- GrFBBindable * fColorBuffer;
- GrFBBindable * fDepthBuffer;
- GrFBBindable * fStencilBuffer;
-
- typedef GrFakeRefObj INHERITED;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-class GrShaderObj : public GrFakeRefObj {
- GR_DEFINE_CREATOR(GrShaderObj);
-
-public:
- GrShaderObj()
- : GrFakeRefObj()
- , fType(GR_GL_VERTEX_SHADER) {}
-
- void setType(GrGLenum type) { fType = type; }
- GrGLenum getType() { return fType; }
-
- virtual void deleteAction() SK_OVERRIDE {
-
- this->INHERITED::deleteAction();
- }
-
-protected:
-private:
- GrGLenum fType; // either GR_GL_VERTEX_SHADER or GR_GL_FRAGMENT_SHADER
-
- typedef GrFakeRefObj INHERITED;
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-class GrProgramObj : public GrFakeRefObj {
- GR_DEFINE_CREATOR(GrProgramObj);
-
-public:
- GrProgramObj()
- : GrFakeRefObj()
- , 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->INHERITED::deleteAction();
- }
-
- // TODO: this flag system won't work w/ multiple contexts!
- void setInUse() { fInUse = true; }
- void resetInUse() { fInUse = false; }
- 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:
- enum GrObjTypes {
- kTexture_ObjTypes = 0,
- kBuffer_ObjTypes,
- kRenderBuffer_ObjTypes,
- kFrameBuffer_ObjTypes,
- kShader_ObjTypes,
- kProgram_ObjTypes,
- kTextureUnit_ObjTypes,
- kObjTypeCount
- };
-
- GrFakeRefObj *createObj(GrObjTypes type) {
- GrFakeRefObj *temp = (*gFactoryFunc[type])();
-
- fObjects.push_back(temp);
-
- return temp;
- }
-
- GrFakeRefObj *findObject(GrGLuint ID, GrObjTypes 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 NULL;
- }
-
- GrGLuint getMaxTextureUnits() const { return kDefaultMaxTextureUnits; }
-
- void setCurTextureUnit(GrGLuint curTextureUnit) { fCurTextureUnit = curTextureUnit; }
- GrGLuint getCurTextureUnit() const { return fCurTextureUnit; }
-
- GrTextureUnitObj *getTextureUnit(int iUnit) {
- GrAlwaysAssert(0 <= iUnit && kDefaultMaxTextureUnits > iUnit);
-
- return fTextureUnits[iUnit];
- }
-
- 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 setTexture(GrTextureObj *texture) {
- fTextureUnits[fCurTextureUnit]->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();
- }
- }
-
- static GrDebugGL *getInstance() {
-// static GrDebugGL Obj;
-
- return &Obj;
- }
-
- void report() const {
- for (int i = 0; i < fObjects.count(); ++i) {
- GrAlwaysAssert(0 == fObjects[i]->getRefCount());
- GrAlwaysAssert(0 < fObjects[i]->getHighRefCount());
- GrAlwaysAssert(fObjects[i]->getDeleted());
- }
- }
-
-protected:
-
-private:
- // the OpenGLES 2.0 spec says this must be >= 2
- static const GrGLint kDefaultMaxTextureUnits = 8;
-
- GrGLuint fMaxTextureUnits;
- GrGLuint fCurTextureUnit;
- GrBufferObj * fArrayBuffer;
- GrBufferObj * fElementArrayBuffer;
- GrFrameBufferObj *fFrameBuffer;
- GrRenderBufferObj *fRenderBuffer;
- GrProgramObj * fProgram;
- GrTextureObj * fTexture;
- GrTextureUnitObj *fTextureUnits[kDefaultMaxTextureUnits];
-
- typedef GrFakeRefObj *(*Create)();
-
- static Create gFactoryFunc[kObjTypeCount];
-
- static GrDebugGL Obj;
-
- // global store of all objects
- SkTArray<GrFakeRefObj *> fObjects;
-
- GrDebugGL()
- : fCurTextureUnit(0)
- , fArrayBuffer(NULL)
- , fElementArrayBuffer(NULL)
- , fFrameBuffer(NULL)
- , fRenderBuffer(NULL)
- , fProgram(NULL)
- , fTexture(NULL) {
-
- for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
- fTextureUnits[i] = GR_CREATE(GrTextureUnitObj, GrDebugGL::kTextureUnit_ObjTypes);
- fTextureUnits[i]->ref();
-
- fTextureUnits[i]->setNumber(i);
- }
- }
-
- ~GrDebugGL() {
- // 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();
- }
-
- this->report();
-
- for (int i = 0; i < fObjects.count(); ++i) {
- delete fObjects[i];
- }
- fObjects.reset();
-
- fArrayBuffer = NULL;
- fElementArrayBuffer = NULL;
- fFrameBuffer = NULL;
- fRenderBuffer = NULL;
- fProgram = NULL;
- fTexture = NULL;
- }
-};
-
-GrDebugGL GrDebugGL::Obj;
-GrDebugGL::Create GrDebugGL::gFactoryFunc[kObjTypeCount] = {
- GrTextureObj::createGrTextureObj,
- GrBufferObj::createGrBufferObj,
- GrRenderBufferObj::createGrRenderBufferObj,
- GrFrameBufferObj::createGrFrameBufferObj,
- GrShaderObj::createGrShaderObj,
- GrProgramObj::createGrProgramObj,
- GrTextureUnitObj::createGrTextureUnitObj,
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) {
// Ganesh offsets the texture unit indices
diff --git a/src/gpu/gl/debug/GrProgramObj.cpp b/src/gpu/gl/debug/GrProgramObj.cpp
new file mode 100644
index 0000000000..aecec258a8
--- /dev/null
+++ b/src/gpu/gl/debug/GrProgramObj.cpp
@@ -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.
+ */
+
+#include "GrProgramObj.h"
+#include "GrShaderObj.h"
+
+void GrProgramObj::AttachShader(GrShaderObj *shader) {
+ shader->ref();
+ fShaders.push_back(shader);
+}
+
+void GrProgramObj::deleteAction() {
+
+ // 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->INHERITED::deleteAction();
+}
diff --git a/src/gpu/gl/debug/GrProgramObj.h b/src/gpu/gl/debug/GrProgramObj.h
new file mode 100644
index 0000000000..d83eab8805
--- /dev/null
+++ b/src/gpu/gl/debug/GrProgramObj.h
@@ -0,0 +1,43 @@
+
+/*
+ * 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 GrProgramObj_DEFINED
+#define GrProgramObj_DEFINED
+
+#include "SkTArray.h"
+#include "GrFakeRefObj.h"
+class GrShaderObj;
+
+////////////////////////////////////////////////////////////////////////////////
+class GrProgramObj : public GrFakeRefObj {
+ GR_DEFINE_CREATOR(GrProgramObj);
+
+public:
+ GrProgramObj()
+ : GrFakeRefObj()
+ , fInUse(false) {}
+
+ void AttachShader(GrShaderObj *shader);
+
+ virtual void deleteAction() SK_OVERRIDE;
+
+ // TODO: this flag system won't work w/ multiple contexts!
+ void setInUse() { fInUse = true; }
+ void resetInUse() { fInUse = false; }
+ bool getInUse() const { return fInUse; }
+
+protected:
+
+private:
+ SkTArray<GrShaderObj *> fShaders;
+ bool fInUse; // has this program been activated by a glUseProgram call?
+
+ typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrProgramObj_DEFINED
diff --git a/src/gpu/gl/debug/GrRenderBufferObj.cpp b/src/gpu/gl/debug/GrRenderBufferObj.cpp
new file mode 100644
index 0000000000..b7641ca948
--- /dev/null
+++ b/src/gpu/gl/debug/GrRenderBufferObj.cpp
@@ -0,0 +1,9 @@
+
+/*
+ * 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 "GrRenderBufferObj.h"
diff --git a/src/gpu/gl/debug/GrRenderBufferObj.h b/src/gpu/gl/debug/GrRenderBufferObj.h
new file mode 100644
index 0000000000..344b90e5a9
--- /dev/null
+++ b/src/gpu/gl/debug/GrRenderBufferObj.h
@@ -0,0 +1,40 @@
+
+/*
+ * 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 GrRenderBufferObj_DEFINED
+#define GrRenderBufferObj_DEFINED
+
+#include "GrFBBindableObj.h"
+
+////////////////////////////////////////////////////////////////////////////////
+class GrRenderBufferObj : public GrFBBindableObj {
+ GR_DEFINE_CREATOR(GrRenderBufferObj);
+
+public:
+ GrRenderBufferObj()
+ : GrFBBindableObj()
+ , fBound(false) {
+ }
+
+ void setBound() { fBound = true; }
+ void resetBound() { fBound = false; }
+ bool getBound() const { return fBound; }
+
+ virtual void deleteAction() SK_OVERRIDE {
+
+ this->INHERITED::deleteAction();
+ }
+
+protected:
+private:
+ bool fBound; // is this render buffer currently bound via "glBindRenderbuffer"?
+
+ typedef GrFBBindableObj INHERITED;
+};
+
+#endif // GrRenderBufferObj_DEFINED
diff --git a/src/gpu/gl/debug/GrShaderObj.cpp b/src/gpu/gl/debug/GrShaderObj.cpp
new file mode 100644
index 0000000000..60c6903ecb
--- /dev/null
+++ b/src/gpu/gl/debug/GrShaderObj.cpp
@@ -0,0 +1,9 @@
+
+/*
+ * 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 "GrShaderObj.h"
diff --git a/src/gpu/gl/debug/GrShaderObj.h b/src/gpu/gl/debug/GrShaderObj.h
new file mode 100644
index 0000000000..ca6ccdc048
--- /dev/null
+++ b/src/gpu/gl/debug/GrShaderObj.h
@@ -0,0 +1,38 @@
+
+/*
+ * 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 GrShaderObj_DEFINED
+#define GrShaderObj_DEFINED
+
+#include "GrFakeRefObj.h"
+
+////////////////////////////////////////////////////////////////////////////////
+class GrShaderObj : public GrFakeRefObj {
+ GR_DEFINE_CREATOR(GrShaderObj);
+
+public:
+ GrShaderObj()
+ : GrFakeRefObj()
+ , fType(GR_GL_VERTEX_SHADER) {}
+
+ void setType(GrGLenum type) { fType = type; }
+ GrGLenum getType() { return fType; }
+
+ virtual void deleteAction() SK_OVERRIDE {
+
+ this->INHERITED::deleteAction();
+ }
+
+protected:
+private:
+ GrGLenum fType; // either GR_GL_VERTEX_SHADER or GR_GL_FRAGMENT_SHADER
+
+ typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrShaderObj_DEFINED
diff --git a/src/gpu/gl/debug/GrTextureObj.cpp b/src/gpu/gl/debug/GrTextureObj.cpp
new file mode 100644
index 0000000000..24284d43be
--- /dev/null
+++ b/src/gpu/gl/debug/GrTextureObj.cpp
@@ -0,0 +1,9 @@
+
+/*
+ * 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 "GrTextureObj.h" \ No newline at end of file
diff --git a/src/gpu/gl/debug/GrTextureObj.h b/src/gpu/gl/debug/GrTextureObj.h
new file mode 100644
index 0000000000..922c9853cb
--- /dev/null
+++ b/src/gpu/gl/debug/GrTextureObj.h
@@ -0,0 +1,60 @@
+
+/*
+ * 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 GrTextureObj_DEFINED
+#define GrTextureObj_DEFINED
+
+#include "GrFBBindableObj.h"
+
+class GrTextureUnitObj;
+
+////////////////////////////////////////////////////////////////////////////////
+class GrTextureObj : public GrFBBindableObj {
+ GR_DEFINE_CREATOR(GrTextureObj);
+
+public:
+ GrTextureObj()
+ : GrFBBindableObj() {
+ }
+
+ virtual ~GrTextureObj() {
+ GrAlwaysAssert(0 == fTextureUnitReferees.count());
+ }
+
+ void setBound(GrTextureUnitObj *referee) {
+ fTextureUnitReferees.append(1, &referee);
+ }
+
+ void resetBound(GrTextureUnitObj *referee) {
+ int index = fTextureUnitReferees.find(referee);
+ GrAlwaysAssert(0 <= index);
+ fTextureUnitReferees.removeShuffle(index);
+ }
+ bool getBound(GrTextureUnitObj *referee) const {
+ int index = fTextureUnitReferees.find(referee);
+ return 0 <= index;
+ }
+ bool getBound() const {
+ return 0 != fTextureUnitReferees.count();
+ }
+
+ virtual void deleteAction() SK_OVERRIDE {
+
+ this->INHERITED::deleteAction();
+ }
+
+protected:
+
+private:
+ // texture units that bind this texture (via "glBindTexture")
+ SkTDArray<GrTextureUnitObj *> fTextureUnitReferees;
+
+ typedef GrFBBindableObj INHERITED;
+};
+
+#endif // GrTextureObj_DEFINED
diff --git a/src/gpu/gl/debug/GrTextureUnitObj.cpp b/src/gpu/gl/debug/GrTextureUnitObj.cpp
new file mode 100644
index 0000000000..05c149a1c0
--- /dev/null
+++ b/src/gpu/gl/debug/GrTextureUnitObj.cpp
@@ -0,0 +1,32 @@
+
+/*
+ * 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 "GrTextureUnitObj.h"
+#include "GrTextureObj.h"
+
+void GrTextureUnitObj::setTexture(GrTextureObj *texture) {
+
+ if (fTexture) {
+ GrAlwaysAssert(fTexture->getBound(this));
+ fTexture->resetBound(this);
+
+ GrAlwaysAssert(!fTexture->getDeleted());
+ fTexture->unref();
+ }
+
+ fTexture = texture;
+
+ if (fTexture) {
+ GrAlwaysAssert(!fTexture->getDeleted());
+ fTexture->ref();
+
+ GrAlwaysAssert(!fTexture->getBound(this));
+ fTexture->setBound(this);
+ }
+}
+
diff --git a/src/gpu/gl/debug/GrTextureUnitObj.h b/src/gpu/gl/debug/GrTextureUnitObj.h
new file mode 100644
index 0000000000..a1dab11ddc
--- /dev/null
+++ b/src/gpu/gl/debug/GrTextureUnitObj.h
@@ -0,0 +1,45 @@
+
+/*
+ * 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 GrTextreUnitObj_DEFINED
+#define GrTextureUnitObj_DEFINED
+
+#include "GrFakeRefObj.h"
+class GrTextureObj;
+
+////////////////////////////////////////////////////////////////////////////////
+// Although texture unit objects are allocated & deallocated like the other
+// GL emulation objects they are derived from GrFakeRefObj to provide some
+// uniformity in how the GrDebugGL class manages resources
+class GrTextureUnitObj : public GrFakeRefObj {
+ GR_DEFINE_CREATOR(GrTextureUnitObj);
+
+public:
+ GrTextureUnitObj()
+ : GrFakeRefObj()
+ , fNumber(0)
+ , fTexture(NULL) {
+ }
+
+ void setNumber(GrGLenum number) {
+ fNumber = number;
+ }
+ GrGLenum getNumber() const { return fNumber; }
+
+ void setTexture(GrTextureObj *texture);
+ GrTextureObj *getTexture() { return fTexture; }
+
+protected:
+private:
+ GrGLenum fNumber;
+ GrTextureObj *fTexture;
+
+ typedef GrFakeRefObj INHERITED;
+};
+
+#endif // GrTextureUnitObj_DEFINED