Initial split up of Debug Interface into separate files
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 5 Apr 2012 14:40:53 +0000 (14:40 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 5 Apr 2012 14:40:53 +0000 (14:40 +0000)
http://codereview.appspot.com/5979048/

git-svn-id: http://skia.googlecode.com/svn/trunk@3616 2bbb7eff-a529-9590-31e7-b0007b416f81

22 files changed:
gyp/gpu.gyp
src/gpu/gl/debug/GrBufferObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrBufferObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrDebugGL.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrDebugGL.h [new file with mode: 0644]
src/gpu/gl/debug/GrFBBindableObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrFBBindableObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrFakeRefObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrFakeRefObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrFrameBufferObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrFrameBufferObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
src/gpu/gl/debug/GrProgramObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrProgramObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrRenderBufferObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrRenderBufferObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrShaderObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrShaderObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrTextureObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrTextureObj.h [new file with mode: 0644]
src/gpu/gl/debug/GrTextureUnitObj.cpp [new file with mode: 0644]
src/gpu/gl/debug/GrTextureUnitObj.h [new file with mode: 0644]

index 7f7b566..df8fb7b 100644 (file)
         '../src/gpu/gl/GrGpuGLShaders.h',
 
         '../src/gpu/gl/debug/GrGLCreateDebugInterface.cpp',
+        '../src/gpu/gl/debug/GrFakeRefObj.h',
+        '../src/gpu/gl/debug/GrFakeRefObj.cpp',
+        '../src/gpu/gl/debug/GrBufferObj.h',
+        '../src/gpu/gl/debug/GrBufferObj.cpp',
+        '../src/gpu/gl/debug/GrFBBindableObj.h',
+        '../src/gpu/gl/debug/GrFBBindableObj.cpp',
+        '../src/gpu/gl/debug/GrRenderBufferObj.h',
+        '../src/gpu/gl/debug/GrRenderBufferObj.cpp',
+        '../src/gpu/gl/debug/GrTextureObj.h',
+        '../src/gpu/gl/debug/GrTextureObj.cpp',
+        '../src/gpu/gl/debug/GrTextureUnitObj.h',
+        '../src/gpu/gl/debug/GrTextureUnitObj.cpp',
+        '../src/gpu/gl/debug/GrFrameBufferObj.h',
+        '../src/gpu/gl/debug/GrFrameBufferObj.cpp',
+        '../src/gpu/gl/debug/GrShaderObj.h',
+        '../src/gpu/gl/debug/GrShaderObj.cpp',
+        '../src/gpu/gl/debug/GrProgramObj.h',
+        '../src/gpu/gl/debug/GrProgramObj.cpp',
+        '../src/gpu/gl/debug/GrDebugGL.h',
+        '../src/gpu/gl/debug/GrDebugGL.cpp',
 
         '../src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp',
 
diff --git a/src/gpu/gl/debug/GrBufferObj.cpp b/src/gpu/gl/debug/GrBufferObj.cpp
new file mode 100644 (file)
index 0000000..0cd4fc8
--- /dev/null
@@ -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 (file)
index 0000000..e4cfee2
--- /dev/null
@@ -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 (file)
index 0000000..60971eb
--- /dev/null
@@ -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 (file)
index 0000000..d6af98e
--- /dev/null
@@ -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 (file)
index 0000000..dbab2d7
--- /dev/null
@@ -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 (file)
index 0000000..38c8638
--- /dev/null
@@ -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 (file)
index 0000000..508f5c3
--- /dev/null
@@ -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.
+ */
+\r
+#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 (file)
index 0000000..8dbef9c
--- /dev/null
@@ -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 (file)
index 0000000..331be8a
--- /dev/null
@@ -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 (file)
index 0000000..33af4f7
--- /dev/null
@@ -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
index 5b8c315..a9adf7d 100644 (file)
@@ -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 (file)
index 0000000..aecec25
--- /dev/null
@@ -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) {\r
+    shader->ref();\r
+    fShaders.push_back(shader);\r
+}\r
+\r
+void GrProgramObj::deleteAction() {\r
+\r
+    // shaders are automatically detached from a deleted program. They will only be\r
+    // deleted if they were marked for deletion by a prior call to glDeleteShader\r
+    for (int i = 0; i < fShaders.count(); ++i) {\r
+        fShaders[i]->unref();\r
+    }\r
+    fShaders.reset();\r
+\r
+    this->INHERITED::deleteAction();\r
+}\r
diff --git a/src/gpu/gl/debug/GrProgramObj.h b/src/gpu/gl/debug/GrProgramObj.h
new file mode 100644 (file)
index 0000000..d83eab8
--- /dev/null
@@ -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;
+
+////////////////////////////////////////////////////////////////////////////////\r
+class GrProgramObj : public GrFakeRefObj {\r
+    GR_DEFINE_CREATOR(GrProgramObj);\r
+\r
+public:\r
+    GrProgramObj()\r
+        : GrFakeRefObj()\r
+        , fInUse(false) {}\r
+\r
+    void AttachShader(GrShaderObj *shader);\r
+\r
+    virtual void deleteAction() SK_OVERRIDE;\r
+\r
+    // TODO: this flag system won't work w/ multiple contexts!\r
+    void setInUse()         { fInUse = true; }\r
+    void resetInUse()       { fInUse = false; }\r
+    bool getInUse() const   { return fInUse; }\r
+\r
+protected:\r
+\r
+private:\r
+    SkTArray<GrShaderObj *> fShaders;\r
+    bool fInUse;            // has this program been activated by a glUseProgram call?\r
+\r
+    typedef GrFakeRefObj INHERITED;\r
+};\r
+\r
+#endif // GrProgramObj_DEFINED
diff --git a/src/gpu/gl/debug/GrRenderBufferObj.cpp b/src/gpu/gl/debug/GrRenderBufferObj.cpp
new file mode 100644 (file)
index 0000000..b7641ca
--- /dev/null
@@ -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 (file)
index 0000000..344b90e
--- /dev/null
@@ -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 (file)
index 0000000..60c6903
--- /dev/null
@@ -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 (file)
index 0000000..ca6ccdc
--- /dev/null
@@ -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 (file)
index 0000000..24284d4
--- /dev/null
@@ -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 (file)
index 0000000..922c985
--- /dev/null
@@ -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 (file)
index 0000000..05c149a
--- /dev/null
@@ -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 (file)
index 0000000..a1dab11
--- /dev/null
@@ -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