/* * 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()); } } }