OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "gl/GrGLInterface.h" | 10 #include "gl/GrGLInterface.h" |
11 #include "GrDebugGL.h" | 11 |
12 #include "GrBufferObj.h" | |
13 #include "GrFrameBufferObj.h" | |
14 #include "GrProgramObj.h" | |
15 #include "GrRenderBufferObj.h" | |
12 #include "GrShaderObj.h" | 16 #include "GrShaderObj.h" |
13 #include "GrProgramObj.h" | 17 #include "GrTextureObj.h" |
14 #include "GrBufferObj.h" | |
15 #include "GrTextureUnitObj.h" | 18 #include "GrTextureUnitObj.h" |
16 #include "GrTextureObj.h" | |
17 #include "GrFrameBufferObj.h" | |
18 #include "GrRenderBufferObj.h" | |
19 #include "GrVertexArrayObj.h" | 19 #include "GrVertexArrayObj.h" |
20 #include "SkFloatingPoint.h" | 20 #include "gl/GrGLTestInterface.h" |
21 #include "../GrGLNoOpInterface.h" | 21 |
22 #include "SkMutex.h" | |
22 | 23 |
23 namespace { // suppress no previous prototype warning | 24 namespace { // suppress no previous prototype warning |
24 | 25 |
25 //////////////////////////////////////////////////////////////////////////////// | 26 // Helper macro to make creating an object (where you need to get back a derived |
robertphillips
2016/03/21 14:52:40
Can this all go on one line ?
bsalomon
2016/03/21 15:42:49
Done.
| |
26 GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) { | 27 // type) easier |
27 | 28 #define CREATE(className, classEnum) \ |
28 // Ganesh offsets the texture unit indices | 29 reinterpret_cast<className *>(this->createObj(classEnum)) |
29 texture -= GR_GL_TEXTURE0; | 30 |
30 GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits()); | 31 // Helper macro to make creating an object (where you need to get back a derived |
robertphillips
2016/03/21 14:52:40
same here
bsalomon
2016/03/21 15:42:49
Done.
| |
31 | 32 // type) easier |
32 GrDebugGL::getInstance()->setCurTextureUnit(texture); | 33 #define FIND(id, className, classEnum) \ |
33 } | 34 reinterpret_cast<className *>(this->findObject(id, classEnum)) |
34 | 35 |
35 //////////////////////////////////////////////////////////////////////////////// | 36 class DebugInterface : public GrGLTestInterface { |
36 GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, | 37 public: |
37 GrGLuint shaderID) { | 38 DebugInterface() |
38 | 39 : fCurrGenericID(0) |
39 GrProgramObj *program = GR_FIND(programID, GrProgramObj, | 40 , fCurrTextureUnit(0) |
40 GrDebugGL::kProgram_ObjTypes); | 41 , fArrayBuffer(nullptr) |
41 GrAlwaysAssert(program); | 42 , fElementArrayBuffer(nullptr) |
42 | 43 , fVertexArray(nullptr) |
43 GrShaderObj *shader = GR_FIND(shaderID, | 44 , fPackRowLength(0) |
44 GrShaderObj, | 45 , fUnpackRowLength(0) |
45 GrDebugGL::kShader_ObjTypes); | 46 , fPackAlignment(4) |
46 GrAlwaysAssert(shader); | 47 , fFrameBuffer(nullptr) |
47 | 48 , fRenderBuffer(nullptr) |
48 program->AttachShader(shader); | 49 , fProgram(nullptr) |
49 } | 50 , fTexture(nullptr) |
50 | 51 , fAbandoned(false) { |
51 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) { | 52 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { |
52 } | 53 fTextureUnits[i] = |
53 | 54 reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit _ObjTypes)); |
54 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, | 55 fTextureUnits[i]->ref(); |
55 GrGLuint index, | 56 fTextureUnits[i]->setNumber(i); |
56 const char* name) { | 57 } |
57 } | 58 this->init(kGL_GrGLStandard); |
58 | 59 } |
59 //////////////////////////////////////////////////////////////////////////////// | 60 |
60 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, | 61 ~DebugInterface() override { |
61 GrGLuint textureID) { | 62 // unref & delete the texture units first so they don't show up on the l eak report |
62 | 63 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) { |
63 // we don't use cube maps | 64 fTextureUnits[i]->unref(); |
64 GrAlwaysAssert(target == GR_GL_TEXTURE_2D); | 65 fTextureUnits[i]->deleteAction(); |
65 // || target == GR_GL_TEXTURE_CUBE_MAP); | 66 } |
66 | 67 for (int i = 0; i < fObjects.count(); ++i) { |
67 // a textureID of 0 is acceptable - it binds to the default texture target | 68 delete fObjects[i]; |
68 GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, | 69 } |
69 GrDebugGL::kTexture_ObjTypes); | 70 fObjects.reset(); |
70 | 71 |
71 GrDebugGL::getInstance()->setTexture(texture); | 72 fArrayBuffer = nullptr; |
72 } | 73 fElementArrayBuffer = nullptr; |
73 | 74 fVertexArray = nullptr; |
74 | 75 |
75 //////////////////////////////////////////////////////////////////////////////// | 76 this->report(); |
76 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target, | 77 } |
77 GrGLsizeiptr size, | 78 |
78 const GrGLvoid* data, | 79 void abandon() const override { fAbandoned = true; } |
79 GrGLenum usage) { | 80 |
80 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | 81 GrGLvoid activeTexture(GrGLenum texture) override { |
81 GR_GL_ELEMENT_ARRAY_BUFFER == target); | 82 // Ganesh offsets the texture unit indices |
82 GrAlwaysAssert(size >= 0); | 83 texture -= GR_GL_TEXTURE0; |
83 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || | 84 GrAlwaysAssert(texture < kDefaultMaxTextureUnits); |
84 GR_GL_STATIC_DRAW == usage || | 85 fCurrTextureUnit = texture; |
85 GR_GL_DYNAMIC_DRAW == usage); | 86 } |
86 | 87 |
87 GrBufferObj *buffer = nullptr; | 88 GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override { |
88 switch (target) { | 89 |
89 case GR_GL_ARRAY_BUFFER: | 90 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes) ; |
90 buffer = GrDebugGL::getInstance()->getArrayBuffer(); | 91 GrAlwaysAssert(program); |
91 break; | 92 |
92 case GR_GL_ELEMENT_ARRAY_BUFFER: | 93 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); |
93 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); | 94 GrAlwaysAssert(shader); |
94 break; | 95 |
95 default: | 96 program->AttachShader(shader); |
96 SkFAIL("Unexpected target to glBufferData"); | 97 } |
97 break; | 98 |
98 } | 99 //////////////////////////////////////////////////////////////////////////// //// |
99 | 100 GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override { |
100 GrAlwaysAssert(buffer); | 101 GrAlwaysAssert(target == GR_GL_TEXTURE_2D || |
101 GrAlwaysAssert(buffer->getBound()); | 102 target == GR_GL_TEXTURE_RECTANGLE || |
102 | 103 target == GR_GL_TEXTURE_EXTERNAL); |
103 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); | 104 |
104 buffer->setUsage(usage); | 105 // a textureID of 0 is acceptable - it binds to the default texture targ et |
105 } | 106 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes) ; |
106 | 107 |
107 | 108 this->setTexture(texture); |
108 GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, | 109 } |
109 GrGLint param) { | 110 |
110 | 111 //////////////////////////////////////////////////////////////////////////// //// |
111 switch (pname) { | 112 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data , |
112 case GR_GL_UNPACK_ROW_LENGTH: | 113 GrGLenum usage) override { |
113 GrDebugGL::getInstance()->setUnPackRowLength(param); | 114 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || |
114 break; | 115 GR_GL_ELEMENT_ARRAY_BUFFER == target); |
115 case GR_GL_PACK_ROW_LENGTH: | 116 GrAlwaysAssert(size >= 0); |
116 GrDebugGL::getInstance()->setPackRowLength(param); | 117 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || |
117 break; | 118 GR_GL_STATIC_DRAW == usage || |
118 case GR_GL_UNPACK_ALIGNMENT: | 119 GR_GL_DYNAMIC_DRAW == usage); |
119 break; | 120 |
120 case GR_GL_PACK_ALIGNMENT: | 121 GrBufferObj *buffer = nullptr; |
121 GrAlwaysAssert(false); | 122 switch (target) { |
122 break; | 123 case GR_GL_ARRAY_BUFFER: |
123 default: | 124 buffer = this->getArrayBuffer(); |
124 GrAlwaysAssert(false); | 125 break; |
125 break; | 126 case GR_GL_ELEMENT_ARRAY_BUFFER: |
126 } | 127 buffer = this->getElementArrayBuffer(); |
127 } | 128 break; |
128 | 129 default: |
129 GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, | 130 SkFAIL("Unexpected target to glBufferData"); |
130 GrGLint y, | 131 break; |
131 GrGLsizei width, | 132 } |
132 GrGLsizei height, | 133 |
133 GrGLenum format, | 134 GrAlwaysAssert(buffer); |
134 GrGLenum type, | 135 GrAlwaysAssert(buffer->getBound()); |
135 GrGLvoid* pixels) { | 136 |
136 | 137 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data)); |
137 GrGLint pixelsInRow = width; | 138 buffer->setUsage(usage); |
138 if (0 < GrDebugGL::getInstance()->getPackRowLength()) { | 139 } |
139 pixelsInRow = GrDebugGL::getInstance()->getPackRowLength(); | 140 |
140 } | 141 |
141 | 142 GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override { |
142 GrGLint componentsPerPixel = 0; | 143 |
143 | 144 switch (pname) { |
144 switch (format) { | 145 case GR_GL_UNPACK_ROW_LENGTH: |
145 case GR_GL_RGBA: | 146 fUnpackRowLength = param; |
146 // fallthrough | 147 break; |
147 case GR_GL_BGRA: | 148 case GR_GL_PACK_ROW_LENGTH: |
148 componentsPerPixel = 4; | 149 fPackRowLength = param; |
149 break; | 150 break; |
150 case GR_GL_RGB: | 151 case GR_GL_UNPACK_ALIGNMENT: |
151 componentsPerPixel = 3; | 152 break; |
152 break; | 153 case GR_GL_PACK_ALIGNMENT: |
153 case GR_GL_RED: | 154 fPackAlignment = param; |
154 componentsPerPixel = 1; | 155 break; |
155 break; | 156 default: |
156 default: | 157 GrAlwaysAssert(false); |
157 GrAlwaysAssert(false); | 158 break; |
158 break; | 159 } |
159 } | 160 } |
160 | 161 |
161 GrGLint alignment = 4; // the pack alignment (one of 1, 2, 4 or 8) | 162 GrGLvoid readPixels(GrGLint x, |
162 // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT | 163 GrGLint y, |
163 | 164 GrGLsizei width, |
164 GrGLint componentSize = 0; // size (in bytes) of a single component | 165 GrGLsizei height, |
165 | 166 GrGLenum format, |
166 switch (type) { | 167 GrGLenum type, |
167 case GR_GL_UNSIGNED_BYTE: | 168 GrGLvoid* pixels) override { |
168 componentSize = 1; | 169 |
169 break; | 170 GrGLint pixelsInRow = width; |
170 default: | 171 if (fPackRowLength > 0) { |
171 GrAlwaysAssert(false); | 172 pixelsInRow = fPackRowLength; |
172 break; | 173 } |
173 } | 174 |
174 | 175 GrGLint componentsPerPixel = 0; |
175 GrGLint rowStride = 0; // number of components (not bytes) to skip | 176 |
176 if (componentSize >= alignment) { | 177 switch (format) { |
177 rowStride = componentsPerPixel * pixelsInRow; | 178 case GR_GL_RGBA: |
178 } else { | 179 // fallthrough |
179 float fTemp = | 180 case GR_GL_BGRA: |
180 sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / | 181 componentsPerPixel = 4; |
181 static_cast<float>(alignment)); | 182 break; |
182 rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); | 183 case GR_GL_RGB: |
183 } | 184 componentsPerPixel = 3; |
184 | 185 break; |
185 GrGLchar *scanline = static_cast<GrGLchar *>(pixels); | 186 case GR_GL_RED: |
186 for (int y = 0; y < height; ++y) { | 187 componentsPerPixel = 1; |
187 memset(scanline, 0, componentsPerPixel * componentSize * width); | 188 break; |
188 scanline += rowStride; | 189 default: |
189 } | 190 GrAlwaysAssert(false); |
190 } | 191 break; |
191 | 192 } |
192 GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) { | 193 |
193 | 194 GrGLint alignment = fPackAlignment; |
194 // A programID of 0 is legal | 195 |
195 GrProgramObj *program = GR_FIND(programID, | 196 GrGLint componentSize = 0; // size (in bytes) of a single component |
196 GrProgramObj, | 197 |
197 GrDebugGL::kProgram_ObjTypes); | 198 switch (type) { |
198 | 199 case GR_GL_UNSIGNED_BYTE: |
199 GrDebugGL::getInstance()->useProgram(program); | 200 componentSize = 1; |
200 } | 201 break; |
201 | 202 default: |
202 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, | 203 GrAlwaysAssert(false); |
203 GrGLuint frameBufferID) { | 204 break; |
204 | 205 } |
205 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || | 206 |
206 GR_GL_READ_FRAMEBUFFER == target || | 207 GrGLint rowStride = 0; // number of components (not bytes) to skip |
207 GR_GL_DRAW_FRAMEBUFFER); | 208 if (componentSize >= alignment) { |
208 | 209 rowStride = componentsPerPixel * pixelsInRow; |
209 // a frameBufferID of 0 is acceptable - it binds to the default | 210 } else { |
210 // frame buffer | 211 float fTemp = |
211 GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID, | 212 sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow / |
212 GrFrameBufferObj, | 213 static_cast<float>(alignment)); |
213 GrDebugGL::kFrameBuffer_ObjTypes); | 214 rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize); |
214 | 215 } |
215 GrDebugGL::getInstance()->setFrameBuffer(frameBuffer); | 216 |
216 } | 217 GrGLchar *scanline = static_cast<GrGLchar *>(pixels); |
217 | 218 for (int y = 0; y < height; ++y) { |
218 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) { | 219 memset(scanline, 0, componentsPerPixel * componentSize * width); |
219 | 220 scanline += rowStride; |
220 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); | 221 } |
221 | 222 } |
222 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer | 223 |
223 GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID, | 224 GrGLvoid useProgram(GrGLuint programID) override { |
224 GrRenderBufferObj, | 225 |
225 GrDebugGL::kRenderBuffer_ObjTypes ); | 226 // A programID of 0 is legal |
226 | 227 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes ); |
227 GrDebugGL::getInstance()->setRenderBuffer(renderBuffer); | 228 |
228 } | 229 this->useProgram(program); |
229 | 230 } |
230 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) { | 231 |
231 | 232 GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override { |
232 // first potentially unbind the texture | 233 |
233 // TODO: move this into GrDebugGL as unBindTexture? | 234 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target || |
234 for (unsigned int i = 0; | 235 GR_GL_READ_FRAMEBUFFER == target || |
235 i < GrDebugGL::getInstance()->getMaxTextureUnits(); | 236 GR_GL_DRAW_FRAMEBUFFER); |
236 ++i) { | 237 |
237 GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i); | 238 // a frameBufferID of 0 is acceptable - it binds to the default |
238 | 239 // frame buffer |
239 if (pTU->getTexture()) { | 240 GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj, |
240 for (int j = 0; j < n; ++j) { | 241 kFrameBuffer_ObjTypes); |
241 | 242 |
242 if (textures[j] == pTU->getTexture()->getID()) { | 243 this->setFrameBuffer(frameBuffer); |
243 // this ID is the current texture - revert the binding to 0 | 244 } |
244 pTU->setTexture(nullptr); | 245 |
246 GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) overrid e { | |
247 | |
248 GrAlwaysAssert(GR_GL_RENDERBUFFER == target); | |
249 | |
250 // a renderBufferID of 0 is acceptable - it unbinds the bound render bu ffer | |
251 GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferOb j, | |
252 kRenderBuffer_ObjTypes); | |
253 | |
254 this->setRenderBuffer(renderBuffer); | |
255 } | |
256 | |
257 GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override { | |
258 // first potentially unbind the texture | |
259 for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) { | |
260 GrTextureUnitObj *pTU = this->getTextureUnit(i); | |
261 | |
262 if (pTU->getTexture()) { | |
263 for (int j = 0; j < n; ++j) { | |
264 | |
265 if (textures[j] == pTU->getTexture()->getID()) { | |
266 // this ID is the current texture - revert the binding to 0 | |
267 pTU->setTexture(nullptr); | |
268 } | |
245 } | 269 } |
246 } | 270 } |
247 } | 271 } |
248 } | 272 |
249 | 273 // TODO: fuse the following block with DeleteRenderBuffers? |
250 // TODO: fuse the following block with DeleteRenderBuffers? | 274 // Open GL will remove a deleted render buffer from the active |
251 // Open GL will remove a deleted render buffer from the active | 275 // frame buffer but not from any other frame buffer |
252 // frame buffer but not from any other frame buffer | 276 if (this->getFrameBuffer()) { |
253 if (GrDebugGL::getInstance()->getFrameBuffer()) { | 277 |
254 | 278 GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); |
255 GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffe r(); | 279 |
256 | 280 for (int i = 0; i < n; ++i) { |
257 for (int i = 0; i < n; ++i) { | 281 |
258 | 282 if (frameBuffer->getColor() && |
259 if (frameBuffer->getColor() && | 283 textures[i] == frameBuffer->getColor()->getID()) { |
260 textures[i] == frameBuffer->getColor()->getID()) { | 284 frameBuffer->setColor(nullptr); |
261 frameBuffer->setColor(nullptr); | 285 } |
262 } | 286 if (frameBuffer->getDepth() && |
263 if (frameBuffer->getDepth() && | 287 textures[i] == frameBuffer->getDepth()->getID()) { |
264 textures[i] == frameBuffer->getDepth()->getID()) { | 288 frameBuffer->setDepth(nullptr); |
265 frameBuffer->setDepth(nullptr); | 289 } |
266 } | 290 if (frameBuffer->getStencil() && |
267 if (frameBuffer->getStencil() && | 291 textures[i] == frameBuffer->getStencil()->getID()) { |
268 textures[i] == frameBuffer->getStencil()->getID()) { | 292 frameBuffer->setStencil(nullptr); |
269 frameBuffer->setStencil(nullptr); | 293 } |
270 } | 294 } |
271 } | 295 } |
296 | |
297 // then actually "delete" the buffers | |
298 for (int i = 0; i < n; ++i) { | |
299 GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_Obj Types); | |
300 GrAlwaysAssert(buffer); | |
301 | |
302 // OpenGL gives no guarantees if a texture is deleted while attache d to | |
303 // something other than the currently bound frame buffer | |
304 GrAlwaysAssert(!buffer->getBound()); | |
305 | |
306 GrAlwaysAssert(!buffer->getDeleted()); | |
307 buffer->deleteAction(); | |
308 } | |
309 | |
272 } | 310 } |
273 | 311 |
274 // then actually "delete" the buffers | 312 GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) over ride { |
275 for (int i = 0; i < n; ++i) { | 313 |
276 GrTextureObj *buffer = GR_FIND(textures[i], | 314 // first potentially unbind the buffers |
277 GrTextureObj, | 315 if (this->getFrameBuffer()) { |
278 GrDebugGL::kTexture_ObjTypes); | 316 for (int i = 0; i < n; ++i) { |
279 GrAlwaysAssert(buffer); | 317 |
280 | 318 if (frameBuffers[i] == |
281 // OpenGL gives no guarantees if a texture is deleted while attached to | 319 this->getFrameBuffer()->getID()) { |
282 // something other than the currently bound frame buffer | 320 // this ID is the current frame buffer - rebind to the defa ult |
283 GrAlwaysAssert(!buffer->getBound()); | 321 this->setFrameBuffer(nullptr); |
284 | 322 } |
285 GrAlwaysAssert(!buffer->getDeleted()); | |
286 buffer->deleteAction(); | |
287 } | |
288 | |
289 } | |
290 | |
291 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, | |
292 const GrGLuint *frameBuf fers) { | |
293 | |
294 // first potentially unbind the buffers | |
295 if (GrDebugGL::getInstance()->getFrameBuffer()) { | |
296 for (int i = 0; i < n; ++i) { | |
297 | |
298 if (frameBuffers[i] == | |
299 GrDebugGL::getInstance()->getFrameBuffer()->getID()) { | |
300 // this ID is the current frame buffer - rebind to the default | |
301 GrDebugGL::getInstance()->setFrameBuffer(nullptr); | |
302 } | 323 } |
303 } | 324 } |
325 | |
326 // then actually "delete" the buffers | |
327 for (int i = 0; i < n; ++i) { | |
328 GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj, | |
329 kFrameBuffer_ObjTypes); | |
330 GrAlwaysAssert(buffer); | |
331 | |
332 GrAlwaysAssert(!buffer->getDeleted()); | |
333 buffer->deleteAction(); | |
334 } | |
304 } | 335 } |
305 | 336 |
306 // then actually "delete" the buffers | 337 GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) ove rride { |
307 for (int i = 0; i < n; ++i) { | 338 |
308 GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i], | 339 // first potentially unbind the buffers |
309 GrFrameBufferObj, | 340 if (this->getRenderBuffer()) { |
310 GrDebugGL::kFrameBuffer_ObjTypes); | 341 for (int i = 0; i < n; ++i) { |
311 GrAlwaysAssert(buffer); | 342 |
312 | 343 if (renderBuffers[i] == |
313 GrAlwaysAssert(!buffer->getDeleted()); | 344 this->getRenderBuffer()->getID()) { |
314 buffer->deleteAction(); | 345 // this ID is the current render buffer - make no |
315 } | 346 // render buffer be bound |
316 } | 347 this->setRenderBuffer(nullptr); |
317 | 348 } |
318 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, | |
319 const GrGLuint *renderB uffers) { | |
320 | |
321 // first potentially unbind the buffers | |
322 if (GrDebugGL::getInstance()->getRenderBuffer()) { | |
323 for (int i = 0; i < n; ++i) { | |
324 | |
325 if (renderBuffers[i] == | |
326 GrDebugGL::getInstance()->getRenderBuffer()->getID()) { | |
327 // this ID is the current render buffer - make no | |
328 // render buffer be bound | |
329 GrDebugGL::getInstance()->setRenderBuffer(nullptr); | |
330 } | 349 } |
331 } | 350 } |
332 } | 351 |
333 | 352 // TODO: fuse the following block with DeleteTextures? |
334 // TODO: fuse the following block with DeleteTextures? | 353 // Open GL will remove a deleted render buffer from the active frame |
335 // Open GL will remove a deleted render buffer from the active frame | 354 // buffer but not from any other frame buffer |
336 // buffer but not from any other frame buffer | 355 if (this->getFrameBuffer()) { |
337 if (GrDebugGL::getInstance()->getFrameBuffer()) { | 356 |
338 | 357 GrFrameBufferObj *frameBuffer = this->getFrameBuffer(); |
339 GrFrameBufferObj *frameBuffer = | 358 |
340 GrDebugGL::getInstance()->getFrameBuffer(); | 359 for (int i = 0; i < n; ++i) { |
341 | 360 |
342 for (int i = 0; i < n; ++i) { | 361 if (frameBuffer->getColor() && |
343 | 362 renderBuffers[i] == frameBuffer->getColor()->getID()) { |
344 if (frameBuffer->getColor() && | 363 frameBuffer->setColor(nullptr); |
345 renderBuffers[i] == frameBuffer->getColor()->getID()) { | 364 } |
346 frameBuffer->setColor(nullptr); | 365 if (frameBuffer->getDepth() && |
347 } | 366 renderBuffers[i] == frameBuffer->getDepth()->getID()) { |
348 if (frameBuffer->getDepth() && | 367 frameBuffer->setDepth(nullptr); |
349 renderBuffers[i] == frameBuffer->getDepth()->getID()) { | 368 } |
350 frameBuffer->setDepth(nullptr); | 369 if (frameBuffer->getStencil() && |
351 } | 370 renderBuffers[i] == frameBuffer->getStencil()->getID()) { |
352 if (frameBuffer->getStencil() && | 371 frameBuffer->setStencil(nullptr); |
353 renderBuffers[i] == frameBuffer->getStencil()->getID()) { | 372 } |
354 frameBuffer->setStencil(nullptr); | |
355 } | 373 } |
356 } | 374 } |
375 | |
376 // then actually "delete" the buffers | |
377 for (int i = 0; i < n; ++i) { | |
378 GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferOb j, | |
379 kRenderBuffer_ObjTypes); | |
380 GrAlwaysAssert(buffer); | |
381 | |
382 // OpenGL gives no guarantees if a render buffer is deleted | |
383 // while attached to something other than the currently | |
384 // bound frame buffer | |
385 GrAlwaysAssert(!buffer->getColorBound()); | |
386 GrAlwaysAssert(!buffer->getDepthBound()); | |
387 // However, at GrContext destroy time we release all GrRsources and so stencil buffers | |
388 // may get deleted before FBOs that refer to them. | |
389 //GrAlwaysAssert(!buffer->getStencilBound()); | |
390 | |
391 GrAlwaysAssert(!buffer->getDeleted()); | |
392 buffer->deleteAction(); | |
393 } | |
357 } | 394 } |
358 | 395 |
359 // then actually "delete" the buffers | 396 GrGLvoid framebufferRenderbuffer(GrGLenum target, |
360 for (int i = 0; i < n; ++i) { | 397 GrGLenum attachment, |
361 GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i], | 398 GrGLenum renderbuffertarget, |
362 GrRenderBufferObj, | 399 GrGLuint renderBufferID) override { |
363 GrDebugGL::kRenderBuffer_ObjTypes); | 400 |
364 GrAlwaysAssert(buffer); | 401 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); |
365 | 402 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || |
366 // OpenGL gives no guarantees if a render buffer is deleted | 403 GR_GL_DEPTH_ATTACHMENT == attachment || |
367 // while attached to something other than the currently | 404 GR_GL_STENCIL_ATTACHMENT == attachment); |
368 // bound frame buffer | 405 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); |
369 GrAlwaysAssert(!buffer->getColorBound()); | 406 |
370 GrAlwaysAssert(!buffer->getDepthBound()); | 407 GrFrameBufferObj *framebuffer = this->getFrameBuffer(); |
371 // However, at GrContext destroy time we release all GrRsources and so stencil buffers | 408 // A render buffer cannot be attached to the default framebuffer |
372 // may get deleted before FBOs that refer to them. | 409 GrAlwaysAssert(framebuffer); |
373 //GrAlwaysAssert(!buffer->getStencilBound()); | 410 |
374 | 411 // a renderBufferID of 0 is acceptable - it unbinds the current |
375 GrAlwaysAssert(!buffer->getDeleted()); | 412 // render buffer |
376 buffer->deleteAction(); | 413 GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferOb j, |
414 kRenderBuffer_ObjTypes); | |
415 | |
416 switch (attachment) { | |
417 case GR_GL_COLOR_ATTACHMENT0: | |
418 framebuffer->setColor(renderbuffer); | |
419 break; | |
420 case GR_GL_DEPTH_ATTACHMENT: | |
421 framebuffer->setDepth(renderbuffer); | |
422 break; | |
423 case GR_GL_STENCIL_ATTACHMENT: | |
424 framebuffer->setStencil(renderbuffer); | |
425 break; | |
426 default: | |
427 GrAlwaysAssert(false); | |
428 break; | |
429 }; | |
430 | |
377 } | 431 } |
378 } | 432 |
379 | 433 /////////////////////////////////////////////////////////////////////////// ///// |
380 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, | 434 GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenu m textarget, |
381 GrGLenum attachment , | 435 GrGLuint textureID, GrGLint level) override { |
382 GrGLenum renderbuff ertarget, | 436 |
383 GrGLuint renderBuff erID) { | 437 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); |
384 | 438 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || |
385 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); | 439 GR_GL_DEPTH_ATTACHMENT == attachment || |
386 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || | 440 GR_GL_STENCIL_ATTACHMENT == attachment); |
387 GR_GL_DEPTH_ATTACHMENT == attachment || | 441 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); |
388 GR_GL_STENCIL_ATTACHMENT == attachment); | 442 |
389 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget); | 443 GrFrameBufferObj *framebuffer = this->getFrameBuffer(); |
390 | 444 // A texture cannot be attached to the default framebuffer |
391 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); | 445 GrAlwaysAssert(framebuffer); |
392 // A render buffer cannot be attached to the default framebuffer | 446 |
393 GrAlwaysAssert(framebuffer); | 447 // A textureID of 0 is allowed - it unbinds the currently bound texture |
394 | 448 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes ); |
395 // a renderBufferID of 0 is acceptable - it unbinds the current | 449 if (texture) { |
396 // render buffer | 450 // The texture shouldn't be bound to a texture unit - this |
397 GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID, | 451 // could lead to a feedback loop |
398 GrRenderBufferObj, | 452 GrAlwaysAssert(!texture->getBound()); |
399 GrDebugGL::kRenderBuffer_ObjTypes ); | 453 } |
400 | 454 |
401 switch (attachment) { | 455 GrAlwaysAssert(0 == level); |
402 case GR_GL_COLOR_ATTACHMENT0: | 456 |
403 framebuffer->setColor(renderbuffer); | 457 switch (attachment) { |
404 break; | 458 case GR_GL_COLOR_ATTACHMENT0: |
405 case GR_GL_DEPTH_ATTACHMENT: | 459 framebuffer->setColor(texture); |
406 framebuffer->setDepth(renderbuffer); | 460 break; |
407 break; | 461 case GR_GL_DEPTH_ATTACHMENT: |
408 case GR_GL_STENCIL_ATTACHMENT: | 462 framebuffer->setDepth(texture); |
409 framebuffer->setStencil(renderbuffer); | 463 break; |
410 break; | 464 case GR_GL_STENCIL_ATTACHMENT: |
411 default: | 465 framebuffer->setStencil(texture); |
412 GrAlwaysAssert(false); | 466 break; |
413 break; | 467 default: |
414 }; | 468 GrAlwaysAssert(false); |
415 | 469 break; |
416 } | 470 }; |
417 | |
418 /////////////////////////////////////////////////////////////////////////////// / | |
419 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, | |
420 GrGLenum attachment, | |
421 GrGLenum textarget, | |
422 GrGLuint textureID, | |
423 GrGLint level) { | |
424 | |
425 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target); | |
426 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment || | |
427 GR_GL_DEPTH_ATTACHMENT == attachment || | |
428 GR_GL_STENCIL_ATTACHMENT == attachment); | |
429 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget); | |
430 | |
431 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer(); | |
432 // A texture cannot be attached to the default framebuffer | |
433 GrAlwaysAssert(framebuffer); | |
434 | |
435 // A textureID of 0 is allowed - it unbinds the currently bound texture | |
436 GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, | |
437 GrDebugGL::kTexture_ObjTypes); | |
438 if (texture) { | |
439 // The texture shouldn't be bound to a texture unit - this | |
440 // could lead to a feedback loop | |
441 GrAlwaysAssert(!texture->getBound()); | |
442 } | 471 } |
443 | 472 |
444 GrAlwaysAssert(0 == level); | 473 GrGLuint createProgram() override { |
445 | 474 |
446 switch (attachment) { | 475 GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes); |
447 case GR_GL_COLOR_ATTACHMENT0: | 476 |
448 framebuffer->setColor(texture); | 477 return program->getID(); |
449 break; | 478 } |
450 case GR_GL_DEPTH_ATTACHMENT: | 479 |
451 framebuffer->setDepth(texture); | 480 GrGLuint createShader(GrGLenum type) override { |
452 break; | 481 |
453 case GR_GL_STENCIL_ATTACHMENT: | 482 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || |
454 framebuffer->setStencil(texture); | 483 GR_GL_FRAGMENT_SHADER == type); |
455 break; | 484 |
456 default: | 485 GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes); |
457 GrAlwaysAssert(false); | 486 shader->setType(type); |
458 break; | 487 |
459 }; | 488 return shader->getID(); |
460 } | 489 } |
461 | 490 |
462 GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() { | 491 GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRA MEBUFFER_COMPLETE; } |
463 | 492 |
464 GrProgramObj *program = GR_CREATE(GrProgramObj, | 493 GrGLvoid deleteProgram(GrGLuint programID) override { |
465 GrDebugGL::kProgram_ObjTypes); | 494 |
466 | 495 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes) ; |
467 return program->getID(); | 496 GrAlwaysAssert(program); |
468 } | 497 |
469 | 498 if (program->getRefCount()) { |
470 GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) { | 499 // someone is still using this program so we can't delete it here |
471 | 500 program->setMarkedForDeletion(); |
472 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || | |
473 GR_GL_FRAGMENT_SHADER == type); | |
474 | |
475 GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes); | |
476 shader->setType(type); | |
477 | |
478 return shader->getID(); | |
479 } | |
480 | |
481 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) { | |
482 | |
483 GrProgramObj *program = GR_FIND(programID, | |
484 GrProgramObj, | |
485 GrDebugGL::kProgram_ObjTypes); | |
486 GrAlwaysAssert(program); | |
487 | |
488 if (program->getRefCount()) { | |
489 // someone is still using this program so we can't delete it here | |
490 program->setMarkedForDeletion(); | |
491 } else { | |
492 program->deleteAction(); | |
493 } | |
494 } | |
495 | |
496 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) { | |
497 | |
498 GrShaderObj *shader = GR_FIND(shaderID, | |
499 GrShaderObj, | |
500 GrDebugGL::kShader_ObjTypes); | |
501 GrAlwaysAssert(shader); | |
502 | |
503 if (shader->getRefCount()) { | |
504 // someone is still using this shader so we can't delete it here | |
505 shader->setMarkedForDeletion(); | |
506 } else { | |
507 shader->deleteAction(); | |
508 } | |
509 } | |
510 | |
511 GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type, | |
512 GrGLsizei n, | |
513 GrGLuint* ids) { | |
514 | |
515 for (int i = 0; i < n; ++i) { | |
516 GrAlwaysAssert(ids[i] == 0); | |
517 GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type); | |
518 GrAlwaysAssert(obj); | |
519 ids[i] = obj->getID(); | |
520 } | |
521 } | |
522 | |
523 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) { | |
524 debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids); | |
525 } | |
526 | |
527 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenerateMipmap(GrGLenum level) { | |
528 } | |
529 | |
530 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, | |
531 GrGLuint* ids) { | |
532 debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids); | |
533 } | |
534 | |
535 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, | |
536 GrGLuint* ids) { | |
537 debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids); | |
538 } | |
539 | |
540 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) { | |
541 debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids); | |
542 } | |
543 | |
544 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenVertexArrays(GrGLsizei n, GrGLuint* ids) { | |
545 debugGenObjs(GrDebugGL::kVertexArray_ObjTypes, n, ids); | |
546 } | |
547 | |
548 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteVertexArrays(GrGLsizei n, const GrGLui nt* ids) { | |
549 for (GrGLsizei i = 0; i < n; ++i) { | |
550 GrVertexArrayObj* array = | |
551 GR_FIND(ids[i], GrVertexArrayObj, GrDebugGL::kVertexArray_ObjTypes); | |
552 GrAlwaysAssert(array); | |
553 | |
554 // Deleting the current vertex array binds object 0 | |
555 if (GrDebugGL::getInstance()->getVertexArray() == array) { | |
556 GrDebugGL::getInstance()->setVertexArray(nullptr); | |
557 } | |
558 | |
559 if (array->getRefCount()) { | |
560 // someone is still using this vertex array so we can't delete it he re | |
561 array->setMarkedForDeletion(); | |
562 } else { | 501 } else { |
563 array->deleteAction(); | 502 program->deleteAction(); |
564 } | 503 } |
565 } | 504 } |
566 } | 505 |
567 | 506 GrGLvoid deleteShader(GrGLuint shaderID) override { |
568 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindVertexArray(GrGLuint id) { | 507 |
569 GrVertexArrayObj* array = GR_FIND(id, GrVertexArrayObj, GrDebugGL::kVertexAr ray_ObjTypes); | 508 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes); |
570 GrAlwaysAssert((0 == id) || array); | 509 GrAlwaysAssert(shader); |
571 GrDebugGL::getInstance()->setVertexArray(array); | 510 |
572 } | 511 if (shader->getRefCount()) { |
573 | 512 // someone is still using this shader so we can't delete it here |
574 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferI D) { | 513 shader->setMarkedForDeletion(); |
575 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target); | 514 } else { |
576 | 515 shader->deleteAction(); |
577 GrBufferObj *buffer = GR_FIND(bufferID, | 516 } |
578 GrBufferObj, | 517 } |
579 GrDebugGL::kBuffer_ObjTypes); | 518 |
580 // 0 is a permissible bufferID - it unbinds the current buffer | 519 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override { |
581 | 520 this->genObjs(kBuffer_ObjTypes, n, ids); |
582 switch (target) { | 521 } |
583 case GR_GL_ARRAY_BUFFER: | 522 |
584 GrDebugGL::getInstance()->setArrayBuffer(buffer); | 523 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override { |
585 break; | 524 this->genObjs(kFrameBuffer_ObjTypes, n, ids); |
586 case GR_GL_ELEMENT_ARRAY_BUFFER: | 525 } |
587 GrDebugGL::getInstance()->setElementArrayBuffer(buffer); | 526 |
588 break; | 527 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override { |
589 default: | 528 this->genObjs(kRenderBuffer_ObjTypes, n, ids); |
590 SkFAIL("Unexpected target to glBindBuffer"); | 529 } |
591 break; | 530 |
592 } | 531 GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override { |
593 } | 532 this->genObjs(kTexture_ObjTypes, n, ids); |
594 | 533 } |
595 // deleting a bound buffer has the side effect of binding 0 | 534 |
596 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* i ds) { | 535 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override { |
597 // first potentially unbind the buffers | 536 this->genObjs(kVertexArray_ObjTypes, n, ids); |
598 for (int i = 0; i < n; ++i) { | 537 } |
599 | 538 |
600 if (GrDebugGL::getInstance()->getArrayBuffer() && | 539 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericI ds(n, ids); } |
601 ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) { | 540 |
602 // this ID is the current array buffer | 541 GrGLenum getError() override { return GR_GL_NO_ERROR; } |
603 GrDebugGL::getInstance()->setArrayBuffer(nullptr); | 542 |
604 } | 543 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override { |
605 if (GrDebugGL::getInstance()->getElementArrayBuffer() && | 544 // TODO: remove from Ganesh the #defines for gets we don't use. |
606 ids[i] == | 545 // We would like to minimize gets overall due to performance issues |
607 GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) { | 546 switch (pname) { |
608 // this ID is the current element array buffer | 547 case GR_GL_CONTEXT_PROFILE_MASK: |
609 GrDebugGL::getInstance()->setElementArrayBuffer(nullptr); | 548 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; |
610 } | 549 break; |
611 } | 550 case GR_GL_STENCIL_BITS: |
612 | 551 *params = 8; |
613 // then actually "delete" the buffers | 552 break; |
614 for (int i = 0; i < n; ++i) { | 553 case GR_GL_SAMPLES: |
615 GrBufferObj *buffer = GR_FIND(ids[i], | 554 *params = 1; |
616 GrBufferObj, | 555 break; |
617 GrDebugGL::kBuffer_ObjTypes); | 556 case GR_GL_FRAMEBUFFER_BINDING: |
557 *params = 0; | |
558 break; | |
559 case GR_GL_VIEWPORT: | |
560 params[0] = 0; | |
561 params[1] = 0; | |
562 params[2] = 800; | |
563 params[3] = 600; | |
564 break; | |
565 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: | |
566 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: | |
567 case GR_GL_MAX_TEXTURE_IMAGE_UNITS: | |
568 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: | |
569 *params = 8; | |
570 break; | |
571 case GR_GL_MAX_TEXTURE_COORDS: | |
572 *params = 8; | |
573 break; | |
574 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS: | |
575 *params = kDefaultMaxVertexUniformVectors; | |
576 break; | |
577 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: | |
578 *params = kDefaultMaxFragmentUniformVectors; | |
579 break; | |
580 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: | |
581 *params = 16 * 4; | |
582 break; | |
583 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: | |
584 *params = 0; | |
585 break; | |
586 case GR_GL_COMPRESSED_TEXTURE_FORMATS: | |
587 break; | |
588 case GR_GL_MAX_TEXTURE_SIZE: | |
589 *params = 8192; | |
590 break; | |
591 case GR_GL_MAX_RENDERBUFFER_SIZE: | |
592 *params = 8192; | |
593 break; | |
594 case GR_GL_MAX_SAMPLES: | |
595 *params = 32; | |
596 break; | |
597 case GR_GL_MAX_VERTEX_ATTRIBS: | |
598 *params = kDefaultMaxVertexAttribs; | |
599 break; | |
600 case GR_GL_MAX_VARYING_VECTORS: | |
601 *params = kDefaultMaxVaryingVectors; | |
602 break; | |
603 case GR_GL_NUM_EXTENSIONS: { | |
604 GrGLint i = 0; | |
605 while (kExtensions[i++]); | |
606 *params = i; | |
607 break; | |
608 } | |
609 default: | |
610 SkFAIL("Unexpected pname to GetIntegerv"); | |
611 } | |
612 } | |
613 | |
614 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) ov erride { | |
615 val[0] = val[1] = 0.5f; | |
616 } | |
617 | |
618 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) ove rride { | |
619 this->getShaderOrProgramiv(program, pname, params); | |
620 } | |
621 | |
622 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* l ength, | |
623 char* infolog) override { | |
624 this->getInfoLog(program, bufsize, length, infolog); | |
625 } | |
626 | |
627 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) over ride { | |
628 switch (pname) { | |
629 case GR_GL_CURRENT_QUERY: | |
630 *params = 0; | |
631 break; | |
632 case GR_GL_QUERY_COUNTER_BITS: | |
633 *params = 32; | |
634 break; | |
635 default: | |
636 SkFAIL("Unexpected pname passed GetQueryiv."); | |
637 } | |
638 } | |
639 | |
640 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override { | |
641 this->queryResult(id, pname, params); | |
642 } | |
643 | |
644 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) over ride { | |
645 this->queryResult(id, pname, params); | |
646 } | |
647 | |
648 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params ) override { | |
649 this->queryResult(id, pname, params); | |
650 } | |
651 | |
652 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) ov erride { | |
653 this->queryResult(id, pname, params); | |
654 } | |
655 | |
656 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) overr ide { | |
657 this->getShaderOrProgramiv(shader, pname, params); | |
658 } | |
659 | |
660 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* len gth, | |
661 char* infolog) override { | |
662 this->getInfoLog(shader, bufsize, length, infolog); | |
663 } | |
664 | |
665 const GrGLubyte* getString(GrGLenum name) override { | |
666 switch (name) { | |
667 case GR_GL_EXTENSIONS: | |
668 return CombinedExtensionString(); | |
669 case GR_GL_VERSION: | |
670 return (const GrGLubyte*)"4.0 Debug GL"; | |
671 case GR_GL_SHADING_LANGUAGE_VERSION: | |
672 return (const GrGLubyte*)"4.20.8 Debug GLSL"; | |
673 case GR_GL_VENDOR: | |
674 return (const GrGLubyte*)"Debug Vendor"; | |
675 case GR_GL_RENDERER: | |
676 return (const GrGLubyte*)"The Debug (Non-)Renderer"; | |
677 default: | |
678 SkFAIL("Unexpected name passed to GetString"); | |
679 return nullptr; | |
680 } | |
681 } | |
682 | |
683 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override { | |
684 switch (name) { | |
685 case GR_GL_EXTENSIONS: { | |
686 GrGLint count; | |
687 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count); | |
688 if ((GrGLint)i <= count) { | |
689 return (const GrGLubyte*) kExtensions[i]; | |
690 } else { | |
691 return nullptr; | |
692 } | |
693 } | |
694 default: | |
695 SkFAIL("Unexpected name passed to GetStringi"); | |
696 return nullptr; | |
697 } | |
698 } | |
699 | |
700 GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pna me, | |
701 GrGLint* params) override { | |
702 // we used to use this to query stuff about externally created textures, | |
703 // now we just require clients to tell us everything about the texture. | |
704 SkFAIL("Should never query texture parameters."); | |
705 } | |
706 | |
707 GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override { | |
708 for (GrGLsizei i = 0; i < n; ++i) { | |
709 GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArra y_ObjTypes); | |
710 GrAlwaysAssert(array); | |
711 | |
712 // Deleting the current vertex array binds object 0 | |
713 if (this->getVertexArray() == array) { | |
714 this->setVertexArray(nullptr); | |
715 } | |
716 | |
717 if (array->getRefCount()) { | |
718 // someone is still using this vertex array so we can't delete i t here | |
719 array->setMarkedForDeletion(); | |
720 } else { | |
721 array->deleteAction(); | |
722 } | |
723 } | |
724 } | |
725 | |
726 GrGLvoid bindVertexArray(GrGLuint id) override { | |
727 GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTyp es); | |
728 GrAlwaysAssert((0 == id) || array); | |
729 this->setVertexArray(array); | |
730 } | |
731 | |
732 GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override { | |
733 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFE R == target); | |
734 | |
735 GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes); | |
736 // 0 is a permissible bufferID - it unbinds the current buffer | |
737 | |
738 switch (target) { | |
739 case GR_GL_ARRAY_BUFFER: | |
740 this->setArrayBuffer(buffer); | |
741 break; | |
742 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
743 this->setElementArrayBuffer(buffer); | |
744 break; | |
745 default: | |
746 SkFAIL("Unexpected target to glBindBuffer"); | |
747 break; | |
748 } | |
749 } | |
750 | |
751 // deleting a bound buffer has the side effect of binding 0 | |
752 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override { | |
753 // first potentially unbind the buffers | |
754 for (int i = 0; i < n; ++i) { | |
755 | |
756 if (this->getArrayBuffer() && | |
757 ids[i] == this->getArrayBuffer()->getID()) { | |
758 // this ID is the current array buffer | |
759 this->setArrayBuffer(nullptr); | |
760 } | |
761 if (this->getElementArrayBuffer() && | |
762 ids[i] == this->getElementArrayBuffer()->getID()) { | |
763 // this ID is the current element array buffer | |
764 this->setElementArrayBuffer(nullptr); | |
765 } | |
766 } | |
767 | |
768 // then actually "delete" the buffers | |
769 for (int i = 0; i < n; ++i) { | |
770 GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes); | |
771 GrAlwaysAssert(buffer); | |
772 | |
773 GrAlwaysAssert(!buffer->getDeleted()); | |
774 buffer->deleteAction(); | |
775 } | |
776 } | |
777 | |
778 // map a buffer to the caller's address space | |
779 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr le ngth, | |
780 GrGLbitfield access) override { | |
781 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
782 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
783 | |
784 // We only expect read access and we expect that the buffer or range is always invalidated. | |
785 GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access)); | |
786 GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_R ANGE_BIT) & access); | |
787 | |
788 GrBufferObj *buffer = nullptr; | |
789 switch (target) { | |
790 case GR_GL_ARRAY_BUFFER: | |
791 buffer = this->getArrayBuffer(); | |
792 break; | |
793 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
794 buffer = this->getElementArrayBuffer(); | |
795 break; | |
796 default: | |
797 SkFAIL("Unexpected target to glMapBufferRange"); | |
798 break; | |
799 } | |
800 | |
801 if (buffer) { | |
802 GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize()); | |
803 GrAlwaysAssert(!buffer->getMapped()); | |
804 buffer->setMapped(offset, length); | |
805 return buffer->getDataPtr() + offset; | |
806 } | |
807 | |
808 GrAlwaysAssert(false); | |
809 return nullptr; // no buffer bound to the target | |
810 } | |
811 | |
812 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override { | |
813 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); | |
814 | |
815 GrBufferObj *buffer = nullptr; | |
816 switch (target) { | |
817 case GR_GL_ARRAY_BUFFER: | |
818 buffer = this->getArrayBuffer(); | |
819 break; | |
820 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
821 buffer = this->getElementArrayBuffer(); | |
822 break; | |
823 default: | |
824 SkFAIL("Unexpected target to glMapBuffer"); | |
825 break; | |
826 } | |
827 | |
828 return this->mapBufferRange(target, 0, buffer->getSize(), | |
829 GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_B UFFER_BIT); | |
830 } | |
831 | |
832 // remove a buffer from the caller's address space | |
833 // TODO: check if the "access" method from "glMapBuffer" was honored | |
834 GrGLboolean unmapBuffer(GrGLenum target) override { | |
835 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
836 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
837 | |
838 GrBufferObj *buffer = nullptr; | |
839 switch (target) { | |
840 case GR_GL_ARRAY_BUFFER: | |
841 buffer = this->getArrayBuffer(); | |
842 break; | |
843 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
844 buffer = this->getElementArrayBuffer(); | |
845 break; | |
846 default: | |
847 SkFAIL("Unexpected target to glUnmapBuffer"); | |
848 break; | |
849 } | |
850 | |
851 if (buffer) { | |
852 GrAlwaysAssert(buffer->getMapped()); | |
853 buffer->resetMapped(); | |
854 return GR_GL_TRUE; | |
855 } | |
856 | |
857 GrAlwaysAssert(false); | |
858 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; | |
859 } | |
860 | |
861 GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset, | |
862 GrGLsizeiptr length) override { | |
863 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
864 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
865 | |
866 GrBufferObj *buffer = nullptr; | |
867 switch (target) { | |
868 case GR_GL_ARRAY_BUFFER: | |
869 buffer = this->getArrayBuffer(); | |
870 break; | |
871 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
872 buffer = this->getElementArrayBuffer(); | |
873 break; | |
874 default: | |
875 SkFAIL("Unexpected target to glUnmapBuffer"); | |
876 break; | |
877 } | |
878 | |
879 if (buffer) { | |
880 GrAlwaysAssert(buffer->getMapped()); | |
881 GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMapped Length()); | |
882 } else { | |
883 GrAlwaysAssert(false); | |
884 } | |
885 } | |
886 | |
887 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* para ms) override { | |
888 | |
889 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | |
890 GR_GL_ELEMENT_ARRAY_BUFFER == target); | |
891 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || | |
892 GR_GL_BUFFER_USAGE == value); | |
893 | |
894 GrBufferObj *buffer = nullptr; | |
895 switch (target) { | |
896 case GR_GL_ARRAY_BUFFER: | |
897 buffer = this->getArrayBuffer(); | |
898 break; | |
899 case GR_GL_ELEMENT_ARRAY_BUFFER: | |
900 buffer = this->getElementArrayBuffer(); | |
901 break; | |
902 } | |
903 | |
618 GrAlwaysAssert(buffer); | 904 GrAlwaysAssert(buffer); |
619 | 905 |
620 GrAlwaysAssert(!buffer->getDeleted()); | 906 switch (value) { |
621 buffer->deleteAction(); | 907 case GR_GL_BUFFER_MAPPED: |
622 } | 908 *params = GR_GL_FALSE; |
623 } | 909 if (buffer) |
624 | 910 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; |
625 // map a buffer to the caller's address space | 911 break; |
626 GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBufferRange(GrGLenum target, GrGLintptr offset, | 912 case GR_GL_BUFFER_SIZE: |
627 GrGLsizeiptr length, GrGLbit field access) { | 913 *params = 0; |
628 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | 914 if (buffer) |
629 GR_GL_ELEMENT_ARRAY_BUFFER == target); | 915 *params = SkToInt(buffer->getSize()); |
630 | 916 break; |
631 // We only expect read access and we expect that the buffer or range is alwa ys invalidated. | 917 case GR_GL_BUFFER_USAGE: |
632 GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access)); | 918 *params = GR_GL_STATIC_DRAW; |
633 GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE _BIT) & access); | 919 if (buffer) |
634 | 920 *params = buffer->getUsage(); |
635 GrBufferObj *buffer = nullptr; | 921 break; |
636 switch (target) { | 922 default: |
637 case GR_GL_ARRAY_BUFFER: | 923 SkFAIL("Unexpected value to glGetBufferParamateriv"); |
638 buffer = GrDebugGL::getInstance()->getArrayBuffer(); | 924 break; |
639 break; | 925 } |
640 case GR_GL_ELEMENT_ARRAY_BUFFER: | 926 } |
641 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); | 927 |
642 break; | 928 private: |
643 default: | 929 // the OpenGLES 2.0 spec says this must be >= 128 |
644 SkFAIL("Unexpected target to glMapBufferRange"); | 930 static const GrGLint kDefaultMaxVertexUniformVectors = 128; |
645 break; | 931 |
646 } | 932 // the OpenGLES 2.0 spec says this must be >=16 |
647 | 933 static const GrGLint kDefaultMaxFragmentUniformVectors = 16; |
648 if (buffer) { | 934 |
649 GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize()); | 935 // the OpenGLES 2.0 spec says this must be >= 8 |
650 GrAlwaysAssert(!buffer->getMapped()); | 936 static const GrGLint kDefaultMaxVertexAttribs = 8; |
651 buffer->setMapped(offset, length); | 937 |
652 return buffer->getDataPtr() + offset; | 938 // the OpenGLES 2.0 spec says this must be >= 8 |
653 } | 939 static const GrGLint kDefaultMaxVaryingVectors = 8; |
654 | 940 |
655 GrAlwaysAssert(false); | 941 // the OpenGLES 2.0 spec says this must be >= 2 |
656 return nullptr; // no buffer bound to the target | 942 static const GrGLint kDefaultMaxTextureUnits = 8; |
657 } | 943 |
658 | 944 static const char* kExtensions[]; |
659 GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) { | 945 |
660 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); | 946 GrGLuint fCurrGenericID; |
661 | 947 GrGLuint fCurrTextureUnit; |
662 GrBufferObj *buffer = nullptr; | 948 GrTextureUnitObj* fTextureUnits[kDefaultMaxTextureUnits]; |
663 switch (target) { | 949 GrBufferObj* fArrayBuffer; |
664 case GR_GL_ARRAY_BUFFER: | 950 GrBufferObj* fElementArrayBuffer; |
665 buffer = GrDebugGL::getInstance()->getArrayBuffer(); | 951 GrVertexArrayObj* fVertexArray; |
666 break; | 952 GrGLint fPackRowLength; |
667 case GR_GL_ELEMENT_ARRAY_BUFFER: | 953 GrGLint fUnpackRowLength; |
668 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); | 954 GrGLint fPackAlignment; |
669 break; | 955 GrFrameBufferObj* fFrameBuffer; |
670 default: | 956 GrRenderBufferObj* fRenderBuffer; |
671 SkFAIL("Unexpected target to glMapBuffer"); | 957 GrProgramObj* fProgram; |
672 break; | 958 GrTextureObj* fTexture; |
673 } | 959 mutable bool fAbandoned; |
674 | 960 // global store of all objects |
675 return debugGLMapBufferRange(target, 0, buffer->getSize(), | 961 SkTArray<GrFakeRefObj *> fObjects; |
676 GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFF ER_BIT); | 962 |
677 } | 963 static const GrGLubyte* CombinedExtensionString() { |
678 | 964 static SkString gExtString; |
679 // remove a buffer from the caller's address space | 965 static SkMutex gMutex; |
680 // TODO: check if the "access" method from "glMapBuffer" was honored | 966 gMutex.acquire(); |
681 GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) { | 967 if (0 == gExtString.size()) { |
682 | 968 int i = 0; |
683 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | 969 while (kExtensions[i]) { |
684 GR_GL_ELEMENT_ARRAY_BUFFER == target); | 970 if (i > 0) { |
685 | 971 gExtString.append(" "); |
686 GrBufferObj *buffer = nullptr; | 972 } |
687 switch (target) { | 973 gExtString.append(kExtensions[i]); |
688 case GR_GL_ARRAY_BUFFER: | 974 ++i; |
689 buffer = GrDebugGL::getInstance()->getArrayBuffer(); | 975 } |
690 break; | 976 } |
691 case GR_GL_ELEMENT_ARRAY_BUFFER: | 977 gMutex.release(); |
692 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); | 978 return (const GrGLubyte*) gExtString.c_str(); |
693 break; | 979 } |
694 default: | 980 |
695 SkFAIL("Unexpected target to glUnmapBuffer"); | 981 GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) { |
696 break; | 982 for (int i = 0; i < n; ++i) { |
697 } | 983 ids[i] = ++fCurrGenericID; |
698 | 984 } |
699 if (buffer) { | 985 } |
700 GrAlwaysAssert(buffer->getMapped()); | 986 |
701 buffer->resetMapped(); | 987 GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length, |
702 return GR_GL_TRUE; | 988 char* infolog) { |
703 } | 989 if (length) { |
704 | 990 *length = 0; |
705 GrAlwaysAssert(false); | 991 } |
706 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION; | 992 if (bufsize > 0) { |
707 } | 993 *infolog = 0; |
708 | 994 } |
709 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlushMappedBufferRange(GrGLenum target, | 995 } |
710 GrGLintptr offset, | 996 |
711 GrGLsizeiptr length) { | 997 GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* par ams) { |
712 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | 998 switch (pname) { |
713 GR_GL_ELEMENT_ARRAY_BUFFER == target); | 999 case GR_GL_LINK_STATUS: // fallthru |
714 | 1000 case GR_GL_COMPILE_STATUS: |
715 GrBufferObj *buffer = nullptr; | 1001 *params = GR_GL_TRUE; |
716 switch (target) { | 1002 break; |
717 case GR_GL_ARRAY_BUFFER: | 1003 case GR_GL_INFO_LOG_LENGTH: |
718 buffer = GrDebugGL::getInstance()->getArrayBuffer(); | 1004 *params = 0; |
719 break; | 1005 break; |
720 case GR_GL_ELEMENT_ARRAY_BUFFER: | 1006 // we don't expect any other pnames |
721 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); | 1007 default: |
722 break; | 1008 SkFAIL("Unexpected pname to GetProgramiv"); |
723 default: | 1009 break; |
724 SkFAIL("Unexpected target to glUnmapBuffer"); | 1010 } |
725 break; | 1011 } |
726 } | 1012 |
727 | 1013 template <typename T> |
728 if (buffer) { | 1014 void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) { |
729 GrAlwaysAssert(buffer->getMapped()); | 1015 switch (pname) { |
730 GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLeng th()); | 1016 case GR_GL_QUERY_RESULT_AVAILABLE: |
731 } else { | 1017 *params = GR_GL_TRUE; |
732 GrAlwaysAssert(false); | 1018 break; |
733 } | 1019 case GR_GL_QUERY_RESULT: |
734 } | 1020 *params = 0; |
735 | 1021 break; |
736 | 1022 default: |
737 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, | 1023 SkFAIL("Unexpected pname passed to GetQueryObject."); |
738 GrGLenum value, | 1024 break; |
739 GrGLint* params) { | 1025 } |
740 | 1026 } |
741 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || | 1027 |
742 GR_GL_ELEMENT_ARRAY_BUFFER == target); | 1028 enum ObjTypes { |
743 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || | 1029 kTexture_ObjTypes = 0, |
744 GR_GL_BUFFER_USAGE == value); | 1030 kBuffer_ObjTypes, |
745 | 1031 kRenderBuffer_ObjTypes, |
746 GrBufferObj *buffer = nullptr; | 1032 kFrameBuffer_ObjTypes, |
747 switch (target) { | 1033 kShader_ObjTypes, |
748 case GR_GL_ARRAY_BUFFER: | 1034 kProgram_ObjTypes, |
749 buffer = GrDebugGL::getInstance()->getArrayBuffer(); | 1035 kTextureUnit_ObjTypes, |
750 break; | 1036 kVertexArray_ObjTypes, |
751 case GR_GL_ELEMENT_ARRAY_BUFFER: | 1037 kObjTypeCount |
752 buffer = GrDebugGL::getInstance()->getElementArrayBuffer(); | 1038 }; |
753 break; | 1039 |
754 } | 1040 typedef GrFakeRefObj *(*Create)(); |
755 | 1041 |
756 GrAlwaysAssert(buffer); | 1042 static Create gFactoryFunc[kObjTypeCount]; |
757 | 1043 |
758 switch (value) { | 1044 GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) { |
759 case GR_GL_BUFFER_MAPPED: | 1045 for (int i = 0; i < n; ++i) { |
760 *params = GR_GL_FALSE; | 1046 GrAlwaysAssert(ids[i] == 0); |
761 if (buffer) | 1047 GrFakeRefObj *obj = this->createObj(type); |
762 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE; | 1048 GrAlwaysAssert(obj); |
763 break; | 1049 ids[i] = obj->getID(); |
764 case GR_GL_BUFFER_SIZE: | 1050 } |
765 *params = 0; | 1051 } |
766 if (buffer) | 1052 |
767 *params = SkToInt(buffer->getSize()); | 1053 GrFakeRefObj* createObj(ObjTypes type) { |
768 break; | 1054 GrFakeRefObj *temp = (*gFactoryFunc[type])(); |
769 case GR_GL_BUFFER_USAGE: | 1055 |
770 *params = GR_GL_STATIC_DRAW; | 1056 fObjects.push_back(temp); |
771 if (buffer) | 1057 |
772 *params = buffer->getUsage(); | 1058 return temp; |
773 break; | 1059 } |
774 default: | 1060 |
775 SkFAIL("Unexpected value to glGetBufferParamateriv"); | 1061 GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) { |
776 break; | 1062 for (int i = 0; i < fObjects.count(); ++i) { |
777 } | 1063 if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == ty pe) { |
1064 // The application shouldn't be accessing objects | |
1065 // that (as far as OpenGL knows) were already deleted | |
1066 GrAlwaysAssert(!fObjects[i]->getDeleted()); | |
1067 GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion()); | |
1068 return fObjects[i]; | |
1069 } | |
1070 } | |
1071 return nullptr; | |
1072 } | |
1073 | |
1074 GrTextureUnitObj* getTextureUnit(int unit) { | |
1075 GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit); | |
1076 | |
1077 return fTextureUnits[unit]; | |
1078 } | |
1079 | |
1080 void setArrayBuffer(GrBufferObj *arrayBuffer) { | |
1081 if (fArrayBuffer) { | |
1082 // automatically break the binding of the old buffer | |
1083 GrAlwaysAssert(fArrayBuffer->getBound()); | |
1084 fArrayBuffer->resetBound(); | |
1085 | |
1086 GrAlwaysAssert(!fArrayBuffer->getDeleted()); | |
1087 fArrayBuffer->unref(); | |
1088 } | |
1089 | |
1090 fArrayBuffer = arrayBuffer; | |
1091 | |
1092 if (fArrayBuffer) { | |
1093 GrAlwaysAssert(!fArrayBuffer->getDeleted()); | |
1094 fArrayBuffer->ref(); | |
1095 | |
1096 GrAlwaysAssert(!fArrayBuffer->getBound()); | |
1097 fArrayBuffer->setBound(); | |
1098 } | |
1099 } | |
1100 | |
1101 GrBufferObj* getArrayBuffer() { return fArrayBuffer; } | |
1102 void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) { | |
1103 if (fElementArrayBuffer) { | |
1104 // automatically break the binding of the old buffer | |
1105 GrAlwaysAssert(fElementArrayBuffer->getBound()); | |
1106 fElementArrayBuffer->resetBound(); | |
1107 | |
1108 GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); | |
1109 fElementArrayBuffer->unref(); | |
1110 } | |
1111 | |
1112 fElementArrayBuffer = elementArrayBuffer; | |
1113 | |
1114 if (fElementArrayBuffer) { | |
1115 GrAlwaysAssert(!fElementArrayBuffer->getDeleted()); | |
1116 fElementArrayBuffer->ref(); | |
1117 | |
1118 GrAlwaysAssert(!fElementArrayBuffer->getBound()); | |
1119 fElementArrayBuffer->setBound(); | |
1120 } | |
1121 } | |
1122 | |
1123 GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; } | |
1124 | |
1125 void setVertexArray(GrVertexArrayObj* vertexArray) { | |
1126 if (vertexArray) { | |
1127 SkASSERT(!vertexArray->getDeleted()); | |
1128 } | |
1129 SkRefCnt_SafeAssign(fVertexArray, vertexArray); | |
1130 } | |
1131 | |
1132 GrVertexArrayObj* getVertexArray() { return fVertexArray; } | |
1133 | |
1134 void setTexture(GrTextureObj *texture) { | |
1135 fTextureUnits[fCurrTextureUnit]->setTexture(texture); | |
1136 } | |
1137 | |
1138 void setFrameBuffer(GrFrameBufferObj *frameBuffer) { | |
1139 if (fFrameBuffer) { | |
1140 GrAlwaysAssert(fFrameBuffer->getBound()); | |
1141 fFrameBuffer->resetBound(); | |
1142 | |
1143 GrAlwaysAssert(!fFrameBuffer->getDeleted()); | |
1144 fFrameBuffer->unref(); | |
1145 } | |
1146 | |
1147 fFrameBuffer = frameBuffer; | |
1148 | |
1149 if (fFrameBuffer) { | |
1150 GrAlwaysAssert(!fFrameBuffer->getDeleted()); | |
1151 fFrameBuffer->ref(); | |
1152 | |
1153 GrAlwaysAssert(!fFrameBuffer->getBound()); | |
1154 fFrameBuffer->setBound(); | |
1155 } | |
1156 } | |
1157 | |
1158 GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; } | |
1159 | |
1160 void setRenderBuffer(GrRenderBufferObj *renderBuffer) { | |
1161 if (fRenderBuffer) { | |
1162 GrAlwaysAssert(fRenderBuffer->getBound()); | |
1163 fRenderBuffer->resetBound(); | |
1164 | |
1165 GrAlwaysAssert(!fRenderBuffer->getDeleted()); | |
1166 fRenderBuffer->unref(); | |
1167 } | |
1168 | |
1169 fRenderBuffer = renderBuffer; | |
1170 | |
1171 if (fRenderBuffer) { | |
1172 GrAlwaysAssert(!fRenderBuffer->getDeleted()); | |
1173 fRenderBuffer->ref(); | |
1174 | |
1175 GrAlwaysAssert(!fRenderBuffer->getBound()); | |
1176 fRenderBuffer->setBound(); | |
1177 } | |
1178 } | |
1179 GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; } | |
1180 | |
1181 void useProgram(GrProgramObj *program) { | |
1182 if (fProgram) { | |
1183 GrAlwaysAssert(fProgram->getInUse()); | |
1184 fProgram->resetInUse(); | |
1185 | |
1186 GrAlwaysAssert(!fProgram->getDeleted()); | |
1187 fProgram->unref(); | |
1188 } | |
1189 | |
1190 fProgram = program; | |
1191 | |
1192 if (fProgram) { | |
1193 GrAlwaysAssert(!fProgram->getDeleted()); | |
1194 fProgram->ref(); | |
1195 | |
1196 GrAlwaysAssert(!fProgram->getInUse()); | |
1197 fProgram->setInUse(); | |
1198 } | |
1199 } | |
1200 | |
1201 void report() const { | |
1202 for (int i = 0; i < fObjects.count(); ++i) { | |
1203 if (!fAbandoned) { | |
1204 GrAlwaysAssert(0 == fObjects[i]->getRefCount()); | |
1205 GrAlwaysAssert(fObjects[i]->getDeleted()); | |
1206 } | |
1207 } | |
1208 } | |
1209 | |
1210 typedef GrGLTestInterface INHERITED; | |
778 }; | 1211 }; |
779 } // end of namespace | 1212 |
1213 #undef CREATE | |
1214 #undef FIND | |
1215 | |
1216 DebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = { | |
1217 GrTextureObj::createGrTextureObj, | |
1218 GrBufferObj::createGrBufferObj, | |
1219 GrRenderBufferObj::createGrRenderBufferObj, | |
1220 GrFrameBufferObj::createGrFrameBufferObj, | |
1221 GrShaderObj::createGrShaderObj, | |
1222 GrProgramObj::createGrProgramObj, | |
1223 GrTextureUnitObj::createGrTextureUnitObj, | |
1224 GrVertexArrayObj::createGrVertexArrayObj, | |
1225 }; | |
1226 | |
1227 const char* DebugInterface::kExtensions[] = { | |
1228 "GL_ARB_framebuffer_object", | |
1229 "GL_ARB_blend_func_extended", | |
1230 "GL_ARB_timer_query", | |
1231 "GL_ARB_draw_buffers", | |
1232 "GL_ARB_occlusion_query", | |
1233 "GL_EXT_stencil_wrap", | |
1234 nullptr, // signifies the end of the array. | |
1235 }; | |
1236 | |
1237 } // anonymous namespace | |
780 | 1238 |
781 //////////////////////////////////////////////////////////////////////////////// | 1239 //////////////////////////////////////////////////////////////////////////////// |
782 struct GrDebugGLInterface : public GrGLInterface { | 1240 |
783 | 1241 const GrGLInterface* GrGLCreateDebugInterface() { return new DebugInterface; } |
784 public: | |
785 | |
786 | |
787 GrDebugGLInterface() | |
788 : fWrapped(nullptr) { | |
789 GrDebugGL::staticRef(); | |
790 } | |
791 | |
792 virtual ~GrDebugGLInterface() { | |
793 GrDebugGL::staticUnRef(); | |
794 } | |
795 | |
796 void setWrapped(GrGLInterface *interface) { | |
797 fWrapped.reset(interface); | |
798 } | |
799 | |
800 void abandon() const override { | |
801 GrDebugGL::abandon(); | |
802 } | |
803 | |
804 // TODO: there are some issues w/ wrapping another GL interface inside the | |
805 // debug interface: | |
806 // Since none of the "gl" methods are member functions they don't get | |
807 // a "this" pointer through which to access "fWrapped" | |
808 // This could be worked around by having all of them access the | |
809 // "glInterface" pointer - i.e., treating the debug interface as a | |
810 // true singleton | |
811 // | |
812 // The problem with this is that we also want to handle OpenGL | |
813 // contexts. The natural way to do this is to have multiple debug | |
814 // interfaces. Each of which represents a separate context. The | |
815 // static ID count would still uniquify IDs across all of them. | |
816 // The problem then is that we couldn't treat the debug GL | |
817 // interface as a singleton (since there would be one for each | |
818 // context). | |
819 // | |
820 // The solution to this is probably to alter SkDebugGlContext's | |
821 // "makeCurrent" method to make a call like "makeCurrent(this)" to | |
822 // the debug GL interface (assuming that the application will create | |
823 // multiple SkGLContext's) to let it switch between the active | |
824 // context. Everything in the GrDebugGL object would then need to be | |
825 // moved to a GrContextObj and the GrDebugGL object would just switch | |
826 // between them. Note that this approach would also require that | |
827 // SkDebugGLContext wrap an arbitrary other context | |
828 // and then pass the wrapped interface to the debug GL interface. | |
829 | |
830 protected: | |
831 private: | |
832 | |
833 SkAutoTUnref<GrGLInterface> fWrapped; | |
834 | |
835 typedef GrGLInterface INHERITED; | |
836 }; | |
837 | |
838 //////////////////////////////////////////////////////////////////////////////// | |
839 const GrGLInterface* GrGLCreateDebugInterface() { | |
840 GrGLInterface *interface = new GrDebugGLInterface; | |
841 | |
842 interface->fStandard = kGL_GrGLStandard; | |
843 | |
844 GrGLInterface::Functions* functions = &interface->fFunctions; | |
845 functions->fActiveTexture = debugGLActiveTexture; | |
846 functions->fAttachShader = debugGLAttachShader; | |
847 functions->fBeginQuery = debugGLBeginQuery; | |
848 functions->fBindAttribLocation = debugGLBindAttribLocation; | |
849 functions->fBindBuffer = debugGLBindBuffer; | |
850 functions->fBindFragDataLocation = noOpGLBindFragDataLocation; | |
851 functions->fBindTexture = debugGLBindTexture; | |
852 functions->fBindVertexArray = debugGLBindVertexArray; | |
853 functions->fBlendColor = noOpGLBlendColor; | |
854 functions->fBlendEquation = noOpGLBlendEquation; | |
855 functions->fBlendFunc = noOpGLBlendFunc; | |
856 functions->fBufferData = debugGLBufferData; | |
857 functions->fBufferSubData = noOpGLBufferSubData; | |
858 functions->fClear = noOpGLClear; | |
859 functions->fClearColor = noOpGLClearColor; | |
860 functions->fClearStencil = noOpGLClearStencil; | |
861 functions->fColorMask = noOpGLColorMask; | |
862 functions->fCompileShader = noOpGLCompileShader; | |
863 functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; | |
864 functions->fCompressedTexSubImage2D = noOpGLCompressedTexSubImage2D; | |
865 functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; | |
866 functions->fCreateProgram = debugGLCreateProgram; | |
867 functions->fCreateShader = debugGLCreateShader; | |
868 functions->fCullFace = noOpGLCullFace; | |
869 functions->fDeleteBuffers = debugGLDeleteBuffers; | |
870 functions->fDeleteProgram = debugGLDeleteProgram; | |
871 functions->fDeleteQueries = noOpGLDeleteIds; | |
872 functions->fDeleteShader = debugGLDeleteShader; | |
873 functions->fDeleteTextures = debugGLDeleteTextures; | |
874 functions->fDeleteVertexArrays = debugGLDeleteVertexArrays; | |
875 functions->fDepthMask = noOpGLDepthMask; | |
876 functions->fDisable = noOpGLDisable; | |
877 functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; | |
878 functions->fDrawArrays = noOpGLDrawArrays; | |
879 functions->fDrawArraysInstanced = noOpGLDrawArraysInstanced; | |
880 functions->fDrawBuffer = noOpGLDrawBuffer; | |
881 functions->fDrawBuffers = noOpGLDrawBuffers; | |
882 functions->fDrawElements = noOpGLDrawElements; | |
883 functions->fDrawElementsInstanced = noOpGLDrawElementsInstanced; | |
884 functions->fEnable = noOpGLEnable; | |
885 functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; | |
886 functions->fEndQuery = noOpGLEndQuery; | |
887 functions->fFinish = noOpGLFinish; | |
888 functions->fFlush = noOpGLFlush; | |
889 functions->fFlushMappedBufferRange = debugGLFlushMappedBufferRange; | |
890 functions->fFrontFace = noOpGLFrontFace; | |
891 functions->fGenerateMipmap = debugGLGenerateMipmap; | |
892 functions->fGenBuffers = debugGLGenBuffers; | |
893 functions->fGenQueries = noOpGLGenIds; | |
894 functions->fGenTextures = debugGLGenTextures; | |
895 functions->fGetBufferParameteriv = debugGLGetBufferParameteriv; | |
896 functions->fGetError = noOpGLGetError; | |
897 functions->fGetIntegerv = noOpGLGetIntegerv; | |
898 functions->fGetMultisamplefv = noOpGLGetMultisamplefv; | |
899 functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; | |
900 functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; | |
901 functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; | |
902 functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; | |
903 functions->fGetQueryiv = noOpGLGetQueryiv; | |
904 functions->fGetProgramInfoLog = noOpGLGetInfoLog; | |
905 functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; | |
906 functions->fGetShaderInfoLog = noOpGLGetInfoLog; | |
907 functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; | |
908 functions->fGetString = noOpGLGetString; | |
909 functions->fGetStringi = noOpGLGetStringi; | |
910 functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; | |
911 functions->fGetUniformLocation = noOpGLGetUniformLocation; | |
912 functions->fGenVertexArrays = debugGLGenVertexArrays; | |
913 functions->fLineWidth = noOpGLLineWidth; | |
914 functions->fLinkProgram = noOpGLLinkProgram; | |
915 functions->fMapBuffer = debugGLMapBuffer; | |
916 functions->fMapBufferRange = debugGLMapBufferRange; | |
917 functions->fPixelStorei = debugGLPixelStorei; | |
918 functions->fQueryCounter = noOpGLQueryCounter; | |
919 functions->fReadBuffer = noOpGLReadBuffer; | |
920 functions->fReadPixels = debugGLReadPixels; | |
921 functions->fScissor = noOpGLScissor; | |
922 functions->fShaderSource = noOpGLShaderSource; | |
923 functions->fStencilFunc = noOpGLStencilFunc; | |
924 functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; | |
925 functions->fStencilMask = noOpGLStencilMask; | |
926 functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; | |
927 functions->fStencilOp = noOpGLStencilOp; | |
928 functions->fStencilOpSeparate = noOpGLStencilOpSeparate; | |
929 functions->fTexBuffer = noOpGLTexBuffer; | |
930 functions->fTexImage2D = noOpGLTexImage2D; | |
931 functions->fTexParameteri = noOpGLTexParameteri; | |
932 functions->fTexParameteriv = noOpGLTexParameteriv; | |
933 functions->fTexSubImage2D = noOpGLTexSubImage2D; | |
934 functions->fTexStorage2D = noOpGLTexStorage2D; | |
935 functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; | |
936 functions->fUniform1f = noOpGLUniform1f; | |
937 functions->fUniform1i = noOpGLUniform1i; | |
938 functions->fUniform1fv = noOpGLUniform1fv; | |
939 functions->fUniform1iv = noOpGLUniform1iv; | |
940 functions->fUniform2f = noOpGLUniform2f; | |
941 functions->fUniform2i = noOpGLUniform2i; | |
942 functions->fUniform2fv = noOpGLUniform2fv; | |
943 functions->fUniform2iv = noOpGLUniform2iv; | |
944 functions->fUniform3f = noOpGLUniform3f; | |
945 functions->fUniform3i = noOpGLUniform3i; | |
946 functions->fUniform3fv = noOpGLUniform3fv; | |
947 functions->fUniform3iv = noOpGLUniform3iv; | |
948 functions->fUniform4f = noOpGLUniform4f; | |
949 functions->fUniform4i = noOpGLUniform4i; | |
950 functions->fUniform4fv = noOpGLUniform4fv; | |
951 functions->fUniform4iv = noOpGLUniform4iv; | |
952 functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; | |
953 functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; | |
954 functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; | |
955 functions->fUnmapBuffer = debugGLUnmapBuffer; | |
956 functions->fUseProgram = debugGLUseProgram; | |
957 functions->fVertexAttrib1f = noOpGLVertexAttrib1f; | |
958 functions->fVertexAttrib2fv = noOpGLVertexAttrib2fv; | |
959 functions->fVertexAttrib3fv = noOpGLVertexAttrib3fv; | |
960 functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; | |
961 functions->fVertexAttribDivisor = noOpGLVertexAttribDivisor; | |
962 functions->fVertexAttribIPointer = noOpGLVertexAttribIPointer; | |
963 functions->fVertexAttribPointer = noOpGLVertexAttribPointer; | |
964 functions->fViewport = noOpGLViewport; | |
965 functions->fBindFramebuffer = debugGLBindFramebuffer; | |
966 functions->fBindRenderbuffer = debugGLBindRenderbuffer; | |
967 functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; | |
968 functions->fDeleteFramebuffers = debugGLDeleteFramebuffers; | |
969 functions->fDeleteRenderbuffers = debugGLDeleteRenderbuffers; | |
970 functions->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer; | |
971 functions->fFramebufferTexture2D = debugGLFramebufferTexture2D; | |
972 functions->fGenFramebuffers = debugGLGenFramebuffers; | |
973 functions->fGenRenderbuffers = debugGLGenRenderbuffers; | |
974 functions->fGetFramebufferAttachmentParameteriv = | |
975 noOpGLGetFramebufferAttachmentParameteriv; | |
976 functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; | |
977 functions->fRenderbufferStorage = noOpGLRenderbufferStorage; | |
978 functions->fRenderbufferStorageMultisample = | |
979 noOpGLRenderbufferStorageMultisample; | |
980 functions->fBlitFramebuffer = noOpGLBlitFramebuffer; | |
981 functions->fResolveMultisampleFramebuffer = | |
982 noOpGLResolveMultisampleFramebuffer; | |
983 functions->fMatrixLoadf = noOpGLMatrixLoadf; | |
984 functions->fMatrixLoadIdentity = noOpGLMatrixLoadIdentity; | |
985 | |
986 functions->fBindFragDataLocationIndexed = | |
987 noOpGLBindFragDataLocationIndexed; | |
988 | |
989 interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functio ns->fGetStringi, | |
990 functions->fGetIntegerv, nullptr, GR_EGL_NO_DISP LAY); | |
991 | |
992 return interface; | |
993 } | |
OLD | NEW |