1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar
2583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor/*
3583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor * Copyright 2012 Google Inc.
4583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor *
5583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor * Use of this source code is governed by a BSD-style license that can be
6583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor * found in the LICENSE file.
7583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor */
8583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor
9583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrDebugGL.h"
10583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrTextureObj.h"
11583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrBufferObj.h"
12583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrRenderBufferObj.h"
13583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrFrameBufferObj.h"
14583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrShaderObj.h"
15583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrProgramObj.h"
16583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor#include "GrTextureUnitObj.h"
17be0ee875d8a91c031a085cbbd73ad9e8dc1aa8ffDavid Blaikie#include "GrVertexArrayObj.h"
18583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor
19e31b8fb25b458f00e31dcd657c0840e5238e0f05David BlaikieGrDebugGL* GrDebugGL::gObj = nullptr;
20e31b8fb25b458f00e31dcd657c0840e5238e0f05David Blaikieint GrDebugGL::gStaticRefCount = 0;
21583f33b8a9227bace1a77a15404b4c64dc619d69Douglas GregorGrDebugGL::Create GrDebugGL::gFactoryFunc[kObjTypeCount] = {
22583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrTextureObj::createGrTextureObj,
23583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrBufferObj::createGrBufferObj,
24583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrRenderBufferObj::createGrRenderBufferObj,
25583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrFrameBufferObj::createGrFrameBufferObj,
26583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrShaderObj::createGrShaderObj,
27583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrProgramObj::createGrProgramObj,
28583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrTextureUnitObj::createGrTextureUnitObj,
29583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor    GrVertexArrayObj::createGrVertexArrayObj,
30583f33b8a9227bace1a77a15404b4c64dc619d69Douglas Gregor};
31a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor
32a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor
33a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas GregorGrDebugGL::GrDebugGL()
34a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    : fPackRowLength(0)
35a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fUnPackRowLength(0)
36a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fCurTextureUnit(0)
37a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fArrayBuffer(nullptr)
38a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fElementArrayBuffer(nullptr)
39a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fFrameBuffer(nullptr)
40a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fRenderBuffer(nullptr)
41a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fProgram(nullptr)
42a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fTexture(nullptr)
43a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fVertexArray(nullptr)
44a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    , fAbandoned(false) {
45a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor
46a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor    for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
47a77eaa9f4562dc611aa121a20ee8f2e2146765ceDouglas Gregor
48        fTextureUnits[i] = reinterpret_cast<GrTextureUnitObj *>(
49                            createObj(GrDebugGL::kTextureUnit_ObjTypes));
50        fTextureUnits[i]->ref();
51
52        fTextureUnits[i]->setNumber(i);
53    }
54}
55
56GrDebugGL::~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
79GrFakeRefObj *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
93void 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
114void GrDebugGL::setVertexArray(GrVertexArrayObj* vertexArray) {
115    if (vertexArray) {
116        SkASSERT(!vertexArray->getDeleted());
117    }
118    SkRefCnt_SafeAssign(fVertexArray, vertexArray);
119}
120
121void 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
142void GrDebugGL::setTexture(GrTextureObj *texture)  {
143    fTextureUnits[fCurTextureUnit]->setTexture(texture);
144}
145
146void 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
166void 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
186void 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
206void 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