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