| /* | |
| * 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" | |
| #include "GrVertexArrayObj.h" | |
| GrDebugGL* GrDebugGL::gObj = nullptr; | |
| int GrDebugGL::gStaticRefCount = 0; | |
| GrDebugGL::Create GrDebugGL::gFactoryFunc[kObjTypeCount] = { | |
| GrTextureObj::createGrTextureObj, | |
| GrBufferObj::createGrBufferObj, | |
| GrRenderBufferObj::createGrRenderBufferObj, | |
| GrFrameBufferObj::createGrFrameBufferObj, | |
| GrShaderObj::createGrShaderObj, | |
| GrProgramObj::createGrProgramObj, | |
| GrTextureUnitObj::createGrTextureUnitObj, | |
| GrVertexArrayObj::createGrVertexArrayObj, | |
| }; | |
| GrDebugGL::GrDebugGL() | |
| : fPackRowLength(0) | |
| , fUnPackRowLength(0) | |
| , fCurTextureUnit(0) | |
| , fArrayBuffer(nullptr) | |
| , fElementArrayBuffer(nullptr) | |
| , fFrameBuffer(nullptr) | |
| , fRenderBuffer(nullptr) | |
| , fProgram(nullptr) | |
| , fTexture(nullptr) | |
| , fVertexArray(nullptr) | |
| , fAbandoned(false) { | |
| for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { | |
| fTextureUnits[i] = reinterpret_cast<GrTextureUnitObj *>( | |
| createObj(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 = nullptr; | |
| fElementArrayBuffer = nullptr; | |
| fFrameBuffer = nullptr; | |
| fRenderBuffer = nullptr; | |
| fProgram = nullptr; | |
| fTexture = nullptr; | |
| fVertexArray = nullptr; | |
| } | |
| 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 nullptr; | |
| } | |
| 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::setVertexArray(GrVertexArrayObj* vertexArray) { | |
| if (vertexArray) { | |
| SkASSERT(!vertexArray->getDeleted()); | |
| } | |
| SkRefCnt_SafeAssign(fVertexArray, vertexArray); | |
| } | |
| 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) { | |
| if (!fAbandoned) { | |
| GrAlwaysAssert(0 == fObjects[i]->getRefCount()); | |
| GrAlwaysAssert(fObjects[i]->getDeleted()); | |
| } | |
| } | |
| } |