/*
* 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 GrBufferObj;
class GrFakeRefObj;
class GrFrameBufferObj;
class GrProgramObj;
class GrRenderBufferObj;
class GrTextureObj;
class GrTextureUnitObj;
class GrVertexArrayObj;
////////////////////////////////////////////////////////////////////////////////
// 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,
kVertexArray_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 setVertexArray(GrVertexArrayObj* vertexArray);
GrVertexArrayObj* getVertexArray() { return fVertexArray; }
void setTexture(GrTextureObj *texture);
void setFrameBuffer(GrFrameBufferObj *frameBuffer);
GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
void setRenderBuffer(GrRenderBufferObj *renderBuffer);
GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
void useProgram(GrProgramObj *program);
void setPackRowLength(GrGLint packRowLength) {
fPackRowLength = packRowLength;
}
GrGLint getPackRowLength() const { return fPackRowLength; }
void setUnPackRowLength(GrGLint unPackRowLength) {
fUnPackRowLength = unPackRowLength;
}
GrGLint getUnPackRowLength() const { return fUnPackRowLength; }
static GrDebugGL *getInstance() {
// someone should admit to actually using this class
SkASSERT(0 < gStaticRefCount);
if (nullptr == gObj) {
gObj = new GrDebugGL;
}
return gObj;
}
void report() const;
static void staticRef() {
gStaticRefCount++;
}
static void staticUnRef() {
SkASSERT(gStaticRefCount > 0);
gStaticRefCount--;
if (0 == gStaticRefCount) {
delete gObj;
gObj = nullptr;
}
}
static void abandon() {
SkASSERT(gStaticRefCount > 0);
gObj->fAbandoned = true;
}
protected:
private:
// the OpenGLES 2.0 spec says this must be >= 2
static const GrGLint kDefaultMaxTextureUnits = 8;
GrGLint fPackRowLength;
GrGLint fUnPackRowLength;
GrGLuint fCurTextureUnit;
GrBufferObj* fArrayBuffer;
GrBufferObj* fElementArrayBuffer;
GrFrameBufferObj* fFrameBuffer;
GrRenderBufferObj* fRenderBuffer;
GrProgramObj* fProgram;
GrTextureObj* fTexture;
GrTextureUnitObj *fTextureUnits[kDefaultMaxTextureUnits];
GrVertexArrayObj *fVertexArray;
bool fAbandoned;
typedef GrFakeRefObj *(*Create)();
static Create gFactoryFunc[kObjTypeCount];
static GrDebugGL* gObj;
static int gStaticRefCount;
// 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