michael@0: michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #include "GrDebugGL.h" michael@0: #include "GrTextureObj.h" michael@0: #include "GrBufferObj.h" michael@0: #include "GrRenderBufferObj.h" michael@0: #include "GrFrameBufferObj.h" michael@0: #include "GrShaderObj.h" michael@0: #include "GrProgramObj.h" michael@0: #include "GrTextureUnitObj.h" michael@0: #include "GrVertexArrayObj.h" michael@0: michael@0: GrDebugGL* GrDebugGL::gObj = NULL; michael@0: int GrDebugGL::gStaticRefCount = 0; michael@0: GrDebugGL::Create GrDebugGL::gFactoryFunc[kObjTypeCount] = { michael@0: GrTextureObj::createGrTextureObj, michael@0: GrBufferObj::createGrBufferObj, michael@0: GrRenderBufferObj::createGrRenderBufferObj, michael@0: GrFrameBufferObj::createGrFrameBufferObj, michael@0: GrShaderObj::createGrShaderObj, michael@0: GrProgramObj::createGrProgramObj, michael@0: GrTextureUnitObj::createGrTextureUnitObj, michael@0: GrVertexArrayObj::createGrVertexArrayObj, michael@0: }; michael@0: michael@0: michael@0: GrDebugGL::GrDebugGL() michael@0: : fPackRowLength(0) michael@0: , fUnPackRowLength(0) michael@0: , fCurTextureUnit(0) michael@0: , fArrayBuffer(NULL) michael@0: , fElementArrayBuffer(NULL) michael@0: , fFrameBuffer(NULL) michael@0: , fRenderBuffer(NULL) michael@0: , fProgram(NULL) michael@0: , fTexture(NULL) michael@0: , fVertexArray(NULL) { michael@0: michael@0: for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { michael@0: michael@0: fTextureUnits[i] = reinterpret_cast( michael@0: createObj(GrDebugGL::kTextureUnit_ObjTypes)); michael@0: fTextureUnits[i]->ref(); michael@0: michael@0: fTextureUnits[i]->setNumber(i); michael@0: } michael@0: } michael@0: michael@0: GrDebugGL::~GrDebugGL() { michael@0: // unref & delete the texture units first so they don't show up on the leak report michael@0: for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { michael@0: fTextureUnits[i]->unref(); michael@0: fTextureUnits[i]->deleteAction(); michael@0: } michael@0: michael@0: this->report(); michael@0: michael@0: for (int i = 0; i < fObjects.count(); ++i) { michael@0: delete fObjects[i]; michael@0: } michael@0: fObjects.reset(); michael@0: michael@0: fArrayBuffer = NULL; michael@0: fElementArrayBuffer = NULL; michael@0: fFrameBuffer = NULL; michael@0: fRenderBuffer = NULL; michael@0: fProgram = NULL; michael@0: fTexture = NULL; michael@0: fVertexArray = NULL; michael@0: } michael@0: michael@0: GrFakeRefObj *GrDebugGL::findObject(GrGLuint ID, GrObjTypes type) { michael@0: for (int i = 0; i < fObjects.count(); ++i) { michael@0: if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) { michael@0: // The application shouldn't be accessing objects michael@0: // that (as far as OpenGL knows) were already deleted michael@0: GrAlwaysAssert(!fObjects[i]->getDeleted()); michael@0: GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion()); michael@0: return fObjects[i]; michael@0: } michael@0: } michael@0: michael@0: return NULL; michael@0: } michael@0: michael@0: void GrDebugGL::setArrayBuffer(GrBufferObj *arrayBuffer) { michael@0: if (fArrayBuffer) { michael@0: // automatically break the binding of the old buffer michael@0: GrAlwaysAssert(fArrayBuffer->getBound()); michael@0: fArrayBuffer->resetBound(); michael@0: michael@0: GrAlwaysAssert(!fArrayBuffer->getDeleted()); michael@0: fArrayBuffer->unref(); michael@0: } michael@0: michael@0: fArrayBuffer = arrayBuffer; michael@0: michael@0: if (fArrayBuffer) { michael@0: GrAlwaysAssert(!fArrayBuffer->getDeleted()); michael@0: fArrayBuffer->ref(); michael@0: michael@0: GrAlwaysAssert(!fArrayBuffer->getBound()); michael@0: fArrayBuffer->setBound(); michael@0: } michael@0: } michael@0: michael@0: void GrDebugGL::setVertexArray(GrVertexArrayObj* vertexArray) { michael@0: if (NULL != vertexArray) { michael@0: SkASSERT(!vertexArray->getDeleted()); michael@0: } michael@0: SkRefCnt_SafeAssign(fVertexArray, vertexArray); michael@0: } michael@0: michael@0: void GrDebugGL::setElementArrayBuffer(GrBufferObj *elementArrayBuffer) { michael@0: if (fElementArrayBuffer) { michael@0: // automatically break the binding of the old buffer michael@0: GrAlwaysAssert(fElementArrayBuffer->getBound()); michael@0: fElementArrayBuffer->resetBound(); michael@0: michael@0: GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); michael@0: fElementArrayBuffer->unref(); michael@0: } michael@0: michael@0: fElementArrayBuffer = elementArrayBuffer; michael@0: michael@0: if (fElementArrayBuffer) { michael@0: GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); michael@0: fElementArrayBuffer->ref(); michael@0: michael@0: GrAlwaysAssert(!fElementArrayBuffer->getBound()); michael@0: fElementArrayBuffer->setBound(); michael@0: } michael@0: } michael@0: michael@0: void GrDebugGL::setTexture(GrTextureObj *texture) { michael@0: fTextureUnits[fCurTextureUnit]->setTexture(texture); michael@0: } michael@0: michael@0: void GrDebugGL::setFrameBuffer(GrFrameBufferObj *frameBuffer) { michael@0: if (fFrameBuffer) { michael@0: GrAlwaysAssert(fFrameBuffer->getBound()); michael@0: fFrameBuffer->resetBound(); michael@0: michael@0: GrAlwaysAssert(!fFrameBuffer->getDeleted()); michael@0: fFrameBuffer->unref(); michael@0: } michael@0: michael@0: fFrameBuffer = frameBuffer; michael@0: michael@0: if (fFrameBuffer) { michael@0: GrAlwaysAssert(!fFrameBuffer->getDeleted()); michael@0: fFrameBuffer->ref(); michael@0: michael@0: GrAlwaysAssert(!fFrameBuffer->getBound()); michael@0: fFrameBuffer->setBound(); michael@0: } michael@0: } michael@0: michael@0: void GrDebugGL::setRenderBuffer(GrRenderBufferObj *renderBuffer) { michael@0: if (fRenderBuffer) { michael@0: GrAlwaysAssert(fRenderBuffer->getBound()); michael@0: fRenderBuffer->resetBound(); michael@0: michael@0: GrAlwaysAssert(!fRenderBuffer->getDeleted()); michael@0: fRenderBuffer->unref(); michael@0: } michael@0: michael@0: fRenderBuffer = renderBuffer; michael@0: michael@0: if (fRenderBuffer) { michael@0: GrAlwaysAssert(!fRenderBuffer->getDeleted()); michael@0: fRenderBuffer->ref(); michael@0: michael@0: GrAlwaysAssert(!fRenderBuffer->getBound()); michael@0: fRenderBuffer->setBound(); michael@0: } michael@0: } michael@0: michael@0: void GrDebugGL::useProgram(GrProgramObj *program) { michael@0: if (fProgram) { michael@0: GrAlwaysAssert(fProgram->getInUse()); michael@0: fProgram->resetInUse(); michael@0: michael@0: GrAlwaysAssert(!fProgram->getDeleted()); michael@0: fProgram->unref(); michael@0: } michael@0: michael@0: fProgram = program; michael@0: michael@0: if (fProgram) { michael@0: GrAlwaysAssert(!fProgram->getDeleted()); michael@0: fProgram->ref(); michael@0: michael@0: GrAlwaysAssert(!fProgram->getInUse()); michael@0: fProgram->setInUse(); michael@0: } michael@0: } michael@0: michael@0: void GrDebugGL::report() const { michael@0: for (int i = 0; i < fObjects.count(); ++i) { michael@0: GrAlwaysAssert(0 == fObjects[i]->getRefCount()); michael@0: GrAlwaysAssert(0 < fObjects[i]->getHighRefCount()); michael@0: GrAlwaysAssert(fObjects[i]->getDeleted()); michael@0: } michael@0: }