1 
2 /*
3  * Copyright 2012 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #include "GrDebugGL.h"
10 #include "GrTextureObj.h"
11 #include "GrBufferObj.h"
12 #include "GrRenderBufferObj.h"
13 #include "GrFrameBufferObj.h"
14 #include "GrShaderObj.h"
15 #include "GrProgramObj.h"
16 #include "GrTextureUnitObj.h"
17 #include "GrVertexArrayObj.h"
18 
19 GrDebugGL* GrDebugGL::gObj = nullptr;
20 int GrDebugGL::gStaticRefCount = 0;
21 GrDebugGL::Create GrDebugGL::gFactoryFunc[kObjTypeCount] = {
22     GrTextureObj::createGrTextureObj,
23     GrBufferObj::createGrBufferObj,
24     GrRenderBufferObj::createGrRenderBufferObj,
25     GrFrameBufferObj::createGrFrameBufferObj,
26     GrShaderObj::createGrShaderObj,
27     GrProgramObj::createGrProgramObj,
28     GrTextureUnitObj::createGrTextureUnitObj,
29     GrVertexArrayObj::createGrVertexArrayObj,
30 };
31 
32 
GrDebugGL()33 GrDebugGL::GrDebugGL()
34     : fPackRowLength(0)
35     , fUnPackRowLength(0)
36     , fCurTextureUnit(0)
37     , fArrayBuffer(nullptr)
38     , fElementArrayBuffer(nullptr)
39     , fFrameBuffer(nullptr)
40     , fRenderBuffer(nullptr)
41     , fProgram(nullptr)
42     , fTexture(nullptr)
43     , fVertexArray(nullptr)
44     , fAbandoned(false) {
45 
46     for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
47 
48         fTextureUnits[i] = reinterpret_cast<GrTextureUnitObj *>(
49                             createObj(GrDebugGL::kTextureUnit_ObjTypes));
50         fTextureUnits[i]->ref();
51 
52         fTextureUnits[i]->setNumber(i);
53     }
54 }
55 
~GrDebugGL()56 GrDebugGL::~GrDebugGL() {
57     // unref & delete the texture units first so they don't show up on the leak report
58     for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
59         fTextureUnits[i]->unref();
60         fTextureUnits[i]->deleteAction();
61     }
62 
63     this->report();
64 
65     for (int i = 0; i < fObjects.count(); ++i) {
66         delete fObjects[i];
67     }
68     fObjects.reset();
69 
70     fArrayBuffer = nullptr;
71     fElementArrayBuffer = nullptr;
72     fFrameBuffer = nullptr;
73     fRenderBuffer = nullptr;
74     fProgram = nullptr;
75     fTexture = nullptr;
76     fVertexArray = nullptr;
77 }
78 
findObject(GrGLuint ID,GrObjTypes type)79 GrFakeRefObj *GrDebugGL::findObject(GrGLuint ID, GrObjTypes type) {
80     for (int i = 0; i < fObjects.count(); ++i) {
81         if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) {
82             // The application shouldn't be accessing objects
83             // that (as far as OpenGL knows) were already deleted
84             GrAlwaysAssert(!fObjects[i]->getDeleted());
85             GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion());
86             return fObjects[i];
87         }
88     }
89 
90     return nullptr;
91 }
92 
setArrayBuffer(GrBufferObj * arrayBuffer)93 void GrDebugGL::setArrayBuffer(GrBufferObj *arrayBuffer) {
94     if (fArrayBuffer) {
95         // automatically break the binding of the old buffer
96         GrAlwaysAssert(fArrayBuffer->getBound());
97         fArrayBuffer->resetBound();
98 
99         GrAlwaysAssert(!fArrayBuffer->getDeleted());
100         fArrayBuffer->unref();
101     }
102 
103     fArrayBuffer = arrayBuffer;
104 
105     if (fArrayBuffer) {
106         GrAlwaysAssert(!fArrayBuffer->getDeleted());
107         fArrayBuffer->ref();
108 
109         GrAlwaysAssert(!fArrayBuffer->getBound());
110         fArrayBuffer->setBound();
111     }
112 }
113 
setVertexArray(GrVertexArrayObj * vertexArray)114 void GrDebugGL::setVertexArray(GrVertexArrayObj* vertexArray) {
115     if (vertexArray) {
116         SkASSERT(!vertexArray->getDeleted());
117     }
118     SkRefCnt_SafeAssign(fVertexArray, vertexArray);
119 }
120 
setElementArrayBuffer(GrBufferObj * elementArrayBuffer)121 void GrDebugGL::setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
122     if (fElementArrayBuffer) {
123         // automatically break the binding of the old buffer
124         GrAlwaysAssert(fElementArrayBuffer->getBound());
125         fElementArrayBuffer->resetBound();
126 
127         GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
128         fElementArrayBuffer->unref();
129     }
130 
131     fElementArrayBuffer = elementArrayBuffer;
132 
133     if (fElementArrayBuffer) {
134         GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
135         fElementArrayBuffer->ref();
136 
137         GrAlwaysAssert(!fElementArrayBuffer->getBound());
138         fElementArrayBuffer->setBound();
139     }
140 }
141 
setTexture(GrTextureObj * texture)142 void GrDebugGL::setTexture(GrTextureObj *texture)  {
143     fTextureUnits[fCurTextureUnit]->setTexture(texture);
144 }
145 
setFrameBuffer(GrFrameBufferObj * frameBuffer)146 void GrDebugGL::setFrameBuffer(GrFrameBufferObj *frameBuffer)  {
147     if (fFrameBuffer) {
148         GrAlwaysAssert(fFrameBuffer->getBound());
149         fFrameBuffer->resetBound();
150 
151         GrAlwaysAssert(!fFrameBuffer->getDeleted());
152         fFrameBuffer->unref();
153     }
154 
155     fFrameBuffer = frameBuffer;
156 
157     if (fFrameBuffer) {
158         GrAlwaysAssert(!fFrameBuffer->getDeleted());
159         fFrameBuffer->ref();
160 
161         GrAlwaysAssert(!fFrameBuffer->getBound());
162         fFrameBuffer->setBound();
163     }
164 }
165 
setRenderBuffer(GrRenderBufferObj * renderBuffer)166 void GrDebugGL::setRenderBuffer(GrRenderBufferObj *renderBuffer)  {
167     if (fRenderBuffer) {
168         GrAlwaysAssert(fRenderBuffer->getBound());
169         fRenderBuffer->resetBound();
170 
171         GrAlwaysAssert(!fRenderBuffer->getDeleted());
172         fRenderBuffer->unref();
173     }
174 
175     fRenderBuffer = renderBuffer;
176 
177     if (fRenderBuffer) {
178         GrAlwaysAssert(!fRenderBuffer->getDeleted());
179         fRenderBuffer->ref();
180 
181         GrAlwaysAssert(!fRenderBuffer->getBound());
182         fRenderBuffer->setBound();
183     }
184 }
185 
useProgram(GrProgramObj * program)186 void GrDebugGL::useProgram(GrProgramObj *program) {
187     if (fProgram) {
188         GrAlwaysAssert(fProgram->getInUse());
189         fProgram->resetInUse();
190 
191         GrAlwaysAssert(!fProgram->getDeleted());
192         fProgram->unref();
193     }
194 
195     fProgram = program;
196 
197     if (fProgram) {
198         GrAlwaysAssert(!fProgram->getDeleted());
199         fProgram->ref();
200 
201         GrAlwaysAssert(!fProgram->getInUse());
202         fProgram->setInUse();
203     }
204 }
205 
report() const206 void GrDebugGL::report() const {
207     for (int i = 0; i < fObjects.count(); ++i) {
208         if (!fAbandoned) {
209             GrAlwaysAssert(0 == fObjects[i]->getRefCount());
210             GrAlwaysAssert(fObjects[i]->getDeleted());
211         }
212     }
213 }
214