GrGLCreateDebugInterface.cpp revision 670ff9ae7f37356bff08b30a356bb0c52dc8d62e
1
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "gl/GrGLInterface.h"
11#include "GrDebugGL.h"
12#include "GrShaderObj.h"
13#include "GrProgramObj.h"
14#include "GrBufferObj.h"
15#include "GrTextureUnitObj.h"
16#include "GrTextureObj.h"
17#include "GrFrameBufferObj.h"
18#include "GrRenderBufferObj.h"
19#include "SkFloatingPoint.h"
20
21// the OpenGLES 2.0 spec says this must be >= 128
22static const GrGLint kDefaultMaxVertexUniformVectors = 128;
23
24// the OpenGLES 2.0 spec says this must be >=16
25static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
26
27// the OpenGLES 2.0 spec says this must be >= 8
28static const GrGLint kDefaultMaxVertexAttribs = 8;
29
30// the OpenGLES 2.0 spec says this must be >= 8
31static const GrGLint kDefaultMaxVaryingVectors = 8;
32
33////////////////////////////////////////////////////////////////////////////////
34GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) {
35
36    // Ganesh offsets the texture unit indices
37    texture -= GR_GL_TEXTURE0;
38    GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits());
39
40    GrDebugGL::getInstance()->setCurTextureUnit(texture);
41}
42
43////////////////////////////////////////////////////////////////////////////////
44GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, GrGLuint shaderID) {
45
46    GrProgramObj *program = GR_FIND(programID, GrProgramObj, GrDebugGL::kProgram_ObjTypes);
47    GrAlwaysAssert(program);
48
49    GrShaderObj *shader = GR_FIND(shaderID, GrShaderObj, GrDebugGL::kShader_ObjTypes);
50    GrAlwaysAssert(shader);
51
52    program->AttachShader(shader);
53}
54
55GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) {}
56GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
57
58////////////////////////////////////////////////////////////////////////////////
59GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, GrGLuint textureID) {
60
61    // we don't use cube maps
62    GrAlwaysAssert(target == GR_GL_TEXTURE_2D); // || target == GR_GL_TEXTURE_CUBE_MAP);
63
64    // a textureID of 0 is acceptable - it binds to the default texture target
65    GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, GrDebugGL::kTexture_ObjTypes);
66
67    GrDebugGL::getInstance()->setTexture(texture);
68}
69
70GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
71GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocation(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name) {}
72GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendFunc(GrGLenum sfactor, GrGLenum dfactor) {}
73
74////////////////////////////////////////////////////////////////////////////////
75GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, GrGLenum usage) {
76    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
77    GrAlwaysAssert(size >= 0);
78    GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || GR_GL_STATIC_DRAW == usage || GR_GL_DYNAMIC_DRAW == usage);
79
80    GrBufferObj *buffer = NULL;
81    switch (target) {
82        case GR_GL_ARRAY_BUFFER:
83            buffer = GrDebugGL::getInstance()->getArrayBuffer();
84            break;
85        case GR_GL_ELEMENT_ARRAY_BUFFER:
86            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
87            break;
88        default:
89            GrCrash("Unexpected target to glBufferData");
90            break;
91    }
92
93    GrAlwaysAssert(buffer);
94    GrAlwaysAssert(buffer->getBound());
95
96    buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
97    buffer->setUsage(usage);
98}
99
100GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferSubData(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data) {}
101GrGLvoid GR_GL_FUNCTION_TYPE debugGLClear(GrGLbitfield mask) {}
102GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
103GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearStencil(GrGLint s) {}
104GrGLvoid GR_GL_FUNCTION_TYPE debugGLColorMask(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha) {}
105GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompileShader(GrGLuint shader) {}
106GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompressedTexImage2D(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data) {}
107GrGLvoid GR_GL_FUNCTION_TYPE debugGLCullFace(GrGLenum mode) {}
108GrGLvoid GR_GL_FUNCTION_TYPE debugGLDepthMask(GrGLboolean flag) {}
109GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisable(GrGLenum cap) {}
110GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisableVertexAttribArray(GrGLuint index) {}
111GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawArrays(GrGLenum mode, GrGLint first, GrGLsizei count) {}
112GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffer(GrGLenum mode) {}
113GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffers(GrGLsizei n, const GrGLenum* bufs) {}
114GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
115GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnable(GrGLenum cap) {}
116GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnableVertexAttribArray(GrGLuint index) {}
117GrGLvoid GR_GL_FUNCTION_TYPE debugGLEndQuery(GrGLenum target) {}
118GrGLvoid GR_GL_FUNCTION_TYPE debugGLFinish() {}
119GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlush() {}
120GrGLvoid GR_GL_FUNCTION_TYPE debugGLFrontFace(GrGLenum mode) {}
121GrGLvoid GR_GL_FUNCTION_TYPE debugGLLineWidth(GrGLfloat width) {}
122GrGLvoid GR_GL_FUNCTION_TYPE debugGLLinkProgram(GrGLuint program) {}
123GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, GrGLint param) {
124
125    switch (pname) {
126        case GR_GL_UNPACK_ROW_LENGTH:
127            GrDebugGL::getInstance()->setUnPackRowLength(param);
128            break;
129        case GR_GL_PACK_ROW_LENGTH:
130            GrDebugGL::getInstance()->setPackRowLength(param);
131            break;
132        case GR_GL_UNPACK_ALIGNMENT:
133            break;
134        case GR_GL_PACK_ALIGNMENT:
135            GrAlwaysAssert(false);
136            break;
137        default:
138            GrAlwaysAssert(false);
139            break;
140    }
141}
142GrGLvoid GR_GL_FUNCTION_TYPE debugGLQueryCounter(GrGLuint id, GrGLenum target) {}
143GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadBuffer(GrGLenum src) {}
144GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, GrGLint y,
145                                               GrGLsizei width, GrGLsizei height,
146                                               GrGLenum format, GrGLenum type,
147                                               GrGLvoid* pixels) {
148
149    GrGLint pixelsInRow = width;
150    if (0 < GrDebugGL::getInstance()->getPackRowLength()) {
151        pixelsInRow = GrDebugGL::getInstance()->getPackRowLength();
152    }
153
154    GrGLint componentsPerPixel = 0;
155
156    switch (format) {
157        case GR_GL_RGBA:
158            // fallthrough
159        case GR_GL_BGRA:
160            componentsPerPixel = 4;
161            break;
162        case GR_GL_RGB:
163            componentsPerPixel = 3;
164            break;
165        default:
166            GrAlwaysAssert(false);
167            break;
168    }
169
170    GrGLint alignment = 4;  // the pack alignment (one of 1, 2, 4 or 8)
171    // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT
172
173    GrGLint componentSize = 0;  // size (in bytes) of a single component
174
175    switch (type) {
176        case GR_GL_UNSIGNED_BYTE:
177            componentSize = 1;
178            break;
179        default:
180            GrAlwaysAssert(false);
181            break;
182    }
183
184    GrGLint rowStride = 0;  // number of components (not bytes) to skip
185    if (componentSize >= alignment) {
186        rowStride = componentsPerPixel * pixelsInRow;
187    } else {
188        float fTemp =
189            sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
190                          static_cast<float>(alignment));
191        rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
192    }
193
194    GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
195    for (int y = 0; y < height; ++y) {
196        memset(scanline, 0, componentsPerPixel * componentSize * width);
197        scanline += rowStride;
198    }
199}
200GrGLvoid GR_GL_FUNCTION_TYPE debugGLScissor(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
201GrGLvoid GR_GL_FUNCTION_TYPE debugGLShaderSource(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length) {}
202GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {}
203GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFuncSeparate(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask) {}
204GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMask(GrGLuint mask) {}
205GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMaskSeparate(GrGLenum face, GrGLuint mask) {}
206GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOp(GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
207GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOpSeparate(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
208GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexImage2D(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
209GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexParameteri(GrGLenum target, GrGLenum pname, GrGLint param) {}
210GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexStorage2D(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
211GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
212GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1f(GrGLint location, GrGLfloat v0) {}
213GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1i(GrGLint location, GrGLint v0) {}
214GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
215GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
216GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2f(GrGLint location, GrGLfloat v0, GrGLfloat v1) {}
217GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2i(GrGLint location, GrGLint v0, GrGLint v1) {}
218GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
219GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
220GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) {}
221GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {}
222GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
223GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
224GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3) {}
225GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {}
226GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
227GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
228GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix2fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
229GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix3fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
230GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix4fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
231
232GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) {
233
234    // A programID of 0 is legal
235    GrProgramObj *program = GR_FIND(programID, GrProgramObj, GrDebugGL::kProgram_ObjTypes);
236
237    GrDebugGL::getInstance()->useProgram(program);
238}
239
240GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {}
241GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttribPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr) {}
242GrGLvoid GR_GL_FUNCTION_TYPE debugGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
243
244GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, GrGLuint frameBufferID) {
245
246    GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
247
248    // a frameBufferID of 0 is acceptable - it binds to the default frame buffer
249    GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID, GrFrameBufferObj, GrDebugGL::kFrameBuffer_ObjTypes);
250
251    GrDebugGL::getInstance()->setFrameBuffer(frameBuffer);
252}
253
254GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) {
255
256    GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
257
258    // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
259    GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID, GrRenderBufferObj, GrDebugGL::kRenderBuffer_ObjTypes);
260
261    GrDebugGL::getInstance()->setRenderBuffer(renderBuffer);
262}
263
264GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) {
265
266    // first potentially unbind the texture
267    // TODO: move this into GrDebugGL as unBindTexture?
268    for (unsigned int i = 0; i < GrDebugGL::getInstance()->getMaxTextureUnits(); ++i)
269    {
270        GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i);
271
272        if (pTU->getTexture()) {
273            for (int j = 0; j < n; ++j) {
274
275                if (textures[j] == pTU->getTexture()->getID()) {
276                    // this ID is the current texture - revert the binding to 0
277                    pTU->setTexture(NULL);
278                }
279            }
280        }
281    }
282
283    // TODO: fuse the following block with DeleteRenderBuffers?
284    // Open GL will remove a deleted render buffer from the active frame buffer but not
285    // from any other frame buffer
286    if (GrDebugGL::getInstance()->getFrameBuffer()) {
287
288        GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer();
289
290        for (int i = 0; i < n; ++i) {
291
292            if (NULL != frameBuffer->getColor() && textures[i] == frameBuffer->getColor()->getID()) {
293                frameBuffer->setColor(NULL);
294            }
295            if (NULL != frameBuffer->getDepth() && textures[i] == frameBuffer->getDepth()->getID()) {
296                frameBuffer->setDepth(NULL);
297            }
298            if (NULL != frameBuffer->getStencil() && textures[i] == frameBuffer->getStencil()->getID()) {
299                frameBuffer->setStencil(NULL);
300            }
301        }
302    }
303
304    // then actually "delete" the buffers
305    for (int i = 0; i < n; ++i) {
306        GrTextureObj *buffer = GR_FIND(textures[i], GrTextureObj, GrDebugGL::kTexture_ObjTypes);
307        GrAlwaysAssert(buffer);
308
309        // OpenGL gives no guarantees if a texture is deleted while attached to
310        // something other than the currently bound frame buffer
311        GrAlwaysAssert(!buffer->getBound());
312
313        GrAlwaysAssert(!buffer->getDeleted());
314        buffer->deleteAction();
315    }
316
317}
318
319
320GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) {
321
322    // first potentially unbind the buffers
323    if (GrDebugGL::getInstance()->getFrameBuffer()) {
324        for (int i = 0; i < n; ++i) {
325
326            if (frameBuffers[i] == GrDebugGL::getInstance()->getFrameBuffer()->getID()) {
327                // this ID is the current frame buffer - rebind to the default
328                GrDebugGL::getInstance()->setFrameBuffer(NULL);
329            }
330        }
331    }
332
333    // then actually "delete" the buffers
334    for (int i = 0; i < n; ++i) {
335        GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i], GrFrameBufferObj, GrDebugGL::kFrameBuffer_ObjTypes);
336        GrAlwaysAssert(buffer);
337
338        GrAlwaysAssert(!buffer->getDeleted());
339        buffer->deleteAction();
340    }
341}
342
343GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderBuffers) {
344
345    // first potentially unbind the buffers
346    if (GrDebugGL::getInstance()->getRenderBuffer()) {
347        for (int i = 0; i < n; ++i) {
348
349            if (renderBuffers[i] == GrDebugGL::getInstance()->getRenderBuffer()->getID()) {
350                // this ID is the current render buffer - make no render buffer be bound
351                GrDebugGL::getInstance()->setRenderBuffer(NULL);
352            }
353        }
354    }
355
356    // TODO: fuse the following block with DeleteTextures?
357    // Open GL will remove a deleted render buffer from the active frame buffer but not
358    // from any other frame buffer
359    if (GrDebugGL::getInstance()->getFrameBuffer()) {
360
361        GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer();
362
363        for (int i = 0; i < n; ++i) {
364
365            if (NULL != frameBuffer->getColor() && renderBuffers[i] == frameBuffer->getColor()->getID()) {
366                frameBuffer->setColor(NULL);
367            }
368            if (NULL != frameBuffer->getDepth() && renderBuffers[i] == frameBuffer->getDepth()->getID()) {
369                frameBuffer->setDepth(NULL);
370            }
371            if (NULL != frameBuffer->getStencil() && renderBuffers[i] == frameBuffer->getStencil()->getID()) {
372                frameBuffer->setStencil(NULL);
373            }
374        }
375    }
376
377    // then actually "delete" the buffers
378    for (int i = 0; i < n; ++i) {
379        GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i], GrRenderBufferObj, GrDebugGL::kRenderBuffer_ObjTypes);
380        GrAlwaysAssert(buffer);
381
382        // OpenGL gives no guarantees if a render buffer is deleted while attached to
383        // something other than the currently bound frame buffer
384        GrAlwaysAssert(!buffer->getColorBound());
385        GrAlwaysAssert(!buffer->getDepthBound());
386        GrAlwaysAssert(!buffer->getStencilBound());
387
388        GrAlwaysAssert(!buffer->getDeleted());
389        buffer->deleteAction();
390    }
391}
392
393GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderBufferID) {
394
395    GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
396    GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
397                   GR_GL_DEPTH_ATTACHMENT == attachment ||
398                   GR_GL_STENCIL_ATTACHMENT == attachment);
399    GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
400
401    GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
402    // A render buffer cannot be attached to the default framebuffer
403    GrAlwaysAssert(NULL != framebuffer);
404
405    // a renderBufferID of 0 is acceptable - it unbinds the current render buffer
406    GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID, GrRenderBufferObj, GrDebugGL::kRenderBuffer_ObjTypes);
407
408    switch (attachment) {
409    case GR_GL_COLOR_ATTACHMENT0:
410        framebuffer->setColor(renderbuffer);
411        break;
412    case GR_GL_DEPTH_ATTACHMENT:
413        framebuffer->setDepth(renderbuffer);
414        break;
415    case GR_GL_STENCIL_ATTACHMENT:
416        framebuffer->setStencil(renderbuffer);
417        break;
418    default:
419        GrAlwaysAssert(false);
420        break;
421    };
422
423}
424
425////////////////////////////////////////////////////////////////////////////////
426GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint textureID, GrGLint level) {
427
428    GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
429    GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
430                   GR_GL_DEPTH_ATTACHMENT == attachment ||
431                   GR_GL_STENCIL_ATTACHMENT == attachment);
432    GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
433
434    GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
435    // A texture cannot be attached to the default framebuffer
436    GrAlwaysAssert(NULL != framebuffer);
437
438    // A textureID of 0 is allowed - it unbinds the currently bound texture
439    GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, GrDebugGL::kTexture_ObjTypes);
440    if (texture) {
441        // The texture shouldn't be bound to a texture unit - this could lead to a feedback loop
442        GrAlwaysAssert(!texture->getBound());
443    }
444
445    GrAlwaysAssert(0 == level);
446
447    switch (attachment) {
448    case GR_GL_COLOR_ATTACHMENT0:
449        framebuffer->setColor(texture);
450        break;
451    case GR_GL_DEPTH_ATTACHMENT:
452        framebuffer->setDepth(texture);
453        break;
454    case GR_GL_STENCIL_ATTACHMENT:
455        framebuffer->setStencil(texture);
456        break;
457    default:
458        GrAlwaysAssert(false);
459        break;
460    };
461}
462
463GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetFramebufferAttachmentParameteriv(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params) {}
464GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetRenderbufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {}
465GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
466GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
467GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlitFramebuffer(GrGLint srcX0, GrGLint srcY0, GrGLint srcX1, GrGLint srcY1, GrGLint dstX0, GrGLint dstY0, GrGLint dstX1, GrGLint dstY1, GrGLbitfield mask, GrGLenum filter) {}
468GrGLvoid GR_GL_FUNCTION_TYPE debugGLResolveMultisampleFramebuffer() {}
469GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocationIndexed(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name) {}
470
471GrGLenum GR_GL_FUNCTION_TYPE debugGLCheckFramebufferStatus(GrGLenum target) {
472
473    GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
474
475    return GR_GL_FRAMEBUFFER_COMPLETE;
476}
477
478GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() {
479
480    GrProgramObj *program = GR_CREATE(GrProgramObj, GrDebugGL::kProgram_ObjTypes);
481
482    return program->getID();
483}
484
485GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) {
486
487    GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || GR_GL_FRAGMENT_SHADER == type);
488
489    GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes);
490    shader->setType(type);
491
492    return shader->getID();
493}
494
495GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) {
496
497    GrProgramObj *program = GR_FIND(programID, GrProgramObj, GrDebugGL::kProgram_ObjTypes);
498    GrAlwaysAssert(program);
499
500    if (program->getRefCount()) {
501        // someone is still using this program so we can't delete it here
502        program->setMarkedForDeletion();
503    } else {
504        program->deleteAction();
505    }
506}
507
508GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) {
509
510    GrShaderObj *shader = GR_FIND(shaderID, GrShaderObj, GrDebugGL::kShader_ObjTypes);
511    GrAlwaysAssert(shader);
512
513    if (shader->getRefCount()) {
514        // someone is still using this shader so we can't delete it here
515        shader->setMarkedForDeletion();
516    } else {
517        shader->deleteAction();
518    }
519}
520
521// same function used for all glGen*(GLsize i, GLuint*) functions
522GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenIds(GrGLsizei n, GrGLuint* ids) {
523    static int gCurrID = 1;
524    for (int i = 0; i < n; ++i) {
525        ids[i] = ++gCurrID;
526    }
527}
528
529GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type, GrGLsizei n, GrGLuint* ids) {
530
531   for (int i = 0; i < n; ++i) {
532        GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type);
533        GrAlwaysAssert(obj);
534        ids[i] = obj->getID();
535    }
536}
537
538GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
539
540    debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids);
541}
542
543GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, GrGLuint* ids) {
544
545    debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids);
546}
547
548GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, GrGLuint* ids) {
549
550    debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids);
551}
552
553GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) {
554
555    debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids);
556}
557
558// same delete function for all glDelete*(GLsize i, const GLuint*) except buffers
559GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteIds(GrGLsizei n, const GrGLuint* ids) {}
560
561GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) {
562
563    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
564
565    GrBufferObj *buffer = GR_FIND(bufferID, GrBufferObj, GrDebugGL::kBuffer_ObjTypes);
566    // 0 is a permissable bufferID - it unbinds the current buffer
567
568    switch (target) {
569        case GR_GL_ARRAY_BUFFER:
570            GrDebugGL::getInstance()->setArrayBuffer(buffer);
571            break;
572        case GR_GL_ELEMENT_ARRAY_BUFFER:
573            GrDebugGL::getInstance()->setElementArrayBuffer(buffer);
574            break;
575        default:
576            GrCrash("Unexpected target to glBindBuffer");
577            break;
578    }
579}
580
581// deleting a bound buffer has the side effect of binding 0
582GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
583    // first potentially unbind the buffers
584    for (int i = 0; i < n; ++i) {
585
586        if (GrDebugGL::getInstance()->getArrayBuffer() &&
587            ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) {
588            // this ID is the current array buffer
589            GrDebugGL::getInstance()->setArrayBuffer(NULL);
590        }
591        if (GrDebugGL::getInstance()->getElementArrayBuffer() &&
592            ids[i] == GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) {
593            // this ID is the current element array buffer
594            GrDebugGL::getInstance()->setElementArrayBuffer(NULL);
595        }
596    }
597
598    // then actually "delete" the buffers
599    for (int i = 0; i < n; ++i) {
600        GrBufferObj *buffer = GR_FIND(ids[i], GrBufferObj, GrDebugGL::kBuffer_ObjTypes);
601        GrAlwaysAssert(buffer);
602
603        GrAlwaysAssert(!buffer->getDeleted());
604        buffer->deleteAction();
605    }
606}
607
608// map a buffer to the caller's address space
609GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) {
610
611    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
612    GrAlwaysAssert(GR_GL_WRITE_ONLY == access); // GR_GL_READ_ONLY == access ||  || GR_GL_READ_WRIT == access);
613
614    GrBufferObj *buffer = NULL;
615    switch (target) {
616        case GR_GL_ARRAY_BUFFER:
617            buffer = GrDebugGL::getInstance()->getArrayBuffer();
618            break;
619        case GR_GL_ELEMENT_ARRAY_BUFFER:
620            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
621            break;
622        default:
623            GrCrash("Unexpected target to glMapBuffer");
624            break;
625    }
626
627    if (buffer) {
628        GrAlwaysAssert(!buffer->getMapped());
629        buffer->setMapped();
630        return buffer->getDataPtr();
631    }
632
633    GrAlwaysAssert(false);
634    return NULL;        // no buffer bound to the target
635}
636
637// remove a buffer from the caller's address space
638// TODO: check if the "access" method from "glMapBuffer" was honored
639GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) {
640
641    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
642
643    GrBufferObj *buffer = NULL;
644    switch (target) {
645        case GR_GL_ARRAY_BUFFER:
646            buffer = GrDebugGL::getInstance()->getArrayBuffer();
647            break;
648        case GR_GL_ELEMENT_ARRAY_BUFFER:
649            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
650            break;
651        default:
652            GrCrash("Unexpected target to glUnmapBuffer");
653            break;
654    }
655
656    if (buffer) {
657        GrAlwaysAssert(buffer->getMapped());
658        buffer->resetMapped();
659        return GR_GL_TRUE;
660    }
661
662    GrAlwaysAssert(false);
663    return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
664}
665
666GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) {
667
668    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
669    GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || GR_GL_BUFFER_USAGE == value);
670
671    GrBufferObj *buffer = NULL;
672    switch (target) {
673        case GR_GL_ARRAY_BUFFER:
674            buffer = GrDebugGL::getInstance()->getArrayBuffer();
675            break;
676        case GR_GL_ELEMENT_ARRAY_BUFFER:
677            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
678            break;
679    }
680
681    GrAlwaysAssert(buffer);
682
683    switch (value) {
684        case GR_GL_BUFFER_MAPPED:
685            *params = GR_GL_FALSE;
686            if (buffer)
687                *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
688            break;
689        case GR_GL_BUFFER_SIZE:
690            *params = 0;
691            if (buffer)
692                *params = buffer->getSize();
693            break;
694        case GR_GL_BUFFER_USAGE:
695            *params = GR_GL_STATIC_DRAW;
696            if (buffer)
697                *params = buffer->getUsage();
698            break;
699        default:
700            GrCrash("Unexpected value to glGetBufferParamateriv");
701            break;
702    }
703};
704
705GrGLenum GR_GL_FUNCTION_TYPE debugGLGetError() {
706    return GR_GL_NO_ERROR;
707}
708
709GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetIntegerv(GrGLenum pname, GrGLint* params) {
710    // TODO: remove from Ganesh the #defines for gets we don't use.
711    // We would like to minimize gets overall due to performance issues
712    switch (pname) {
713        case GR_GL_STENCIL_BITS:
714            *params = 8;
715            break;
716        case GR_GL_SAMPLES:
717            *params = 1;
718            break;
719        case GR_GL_FRAMEBUFFER_BINDING:
720            *params = 0;
721            break;
722        case GR_GL_VIEWPORT:
723            params[0] = 0;
724            params[1] = 0;
725            params[2] = 800;
726            params[3] = 600;
727            break;
728        case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
729            *params = 8;
730            break;
731        case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
732            *params = kDefaultMaxVertexUniformVectors;
733            break;
734        case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
735            *params = kDefaultMaxFragmentUniformVectors;
736            break;
737        case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
738            *params = 16 * 4;
739            break;
740        case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
741            *params = 0;
742            break;
743        case GR_GL_COMPRESSED_TEXTURE_FORMATS:
744            break;
745        case GR_GL_MAX_TEXTURE_SIZE:
746            *params = 8192;
747            break;
748        case GR_GL_MAX_RENDERBUFFER_SIZE:
749            *params = 8192;
750            break;
751        case GR_GL_MAX_SAMPLES:
752            *params = 32;
753            break;
754        case GR_GL_MAX_VERTEX_ATTRIBS:
755            *params = kDefaultMaxVertexAttribs;
756            break;
757        case GR_GL_MAX_VARYING_VECTORS:
758            *params = kDefaultMaxVaryingVectors;
759            break;
760        case GR_GL_MAX_TEXTURE_UNITS:
761            *params = GrDebugGL::getInstance()->getMaxTextureUnits();
762            break;
763        default:
764            GrCrash("Unexpected pname to GetIntegerv");
765    }
766}
767// used for both the program and shader info logs
768GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog) {
769    if (length) {
770        *length = 0;
771    }
772    if (bufsize > 0) {
773        *infolog = 0;
774    }
775}
776
777// used for both the program and shader params
778GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetShaderOrProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) {
779    switch (pname) {
780        case GR_GL_LINK_STATUS:  // fallthru
781        case GR_GL_COMPILE_STATUS:
782            *params = GR_GL_TRUE;
783            break;
784        case GR_GL_INFO_LOG_LENGTH:
785            *params = 0;
786            break;
787        // we don't expect any other pnames
788        default:
789            GrCrash("Unexpected pname to GetProgramiv");
790            break;
791    }
792}
793
794namespace {
795template <typename T>
796void query_result(GrGLenum GLtarget, GrGLenum pname, T *params) {
797    switch (pname) {
798        case GR_GL_QUERY_RESULT_AVAILABLE:
799            *params = GR_GL_TRUE;
800            break;
801        case GR_GL_QUERY_RESULT:
802            *params = 0;
803            break;
804        default:
805            GrCrash("Unexpected pname passed to GetQueryObject.");
806            break;
807    }
808}
809}
810
811// Queries on the null GL just don't do anything at all. We could potentially make
812// the timers work.
813GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) {
814    switch (pname) {
815        case GR_GL_CURRENT_QUERY:
816            *params = 0;
817            break;
818        case GR_GL_QUERY_COUNTER_BITS:
819            *params = 32;
820            break;
821        default:
822            GrCrash("Unexpected pname passed GetQueryiv.");
823    }
824}
825GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) {
826    query_result(id, pname, params);
827}
828GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) {
829    query_result(id, pname, params);
830}
831GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) {
832    query_result(id, pname, params);
833}
834GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) {
835    query_result(id, pname, params);
836}
837
838const GrGLubyte* GR_GL_FUNCTION_TYPE debugGLGetString(GrGLenum name) {
839    switch (name) {
840        case GR_GL_EXTENSIONS:
841            return (const GrGLubyte*)"GL_ARB_framebuffer_object GL_ARB_blend_func_extended GL_ARB_timer_query GL_ARB_draw_buffers GL_ARB_occlusion_query GL_EXT_blend_color GL_EXT_stencil_wrap";
842        case GR_GL_VERSION:
843            return (const GrGLubyte*)"4.0 Null GL";
844        case GR_GL_SHADING_LANGUAGE_VERSION:
845            return (const GrGLubyte*)"4.20.8 Null GLSL";
846        default:
847            GrCrash("Unexpected name to GetString");
848            return NULL;
849    }
850}
851
852// we used to use this to query stuff about externally created textures, now we just
853// require clients to tell us everything about the texture.
854GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params) {
855    GrCrash("Should never query texture parameters.");
856}
857
858GrGLint GR_GL_FUNCTION_TYPE debugGLGetUniformLocation(GrGLuint program, const char* name) {
859    static int gUniLocation = 0;
860    return ++gUniLocation;
861}
862
863////////////////////////////////////////////////////////////////////////////////
864struct GrDebugGLInterface : public GrGLInterface {
865
866public:
867    GrDebugGLInterface()
868        : fWrapped(NULL) {
869    }
870
871    void setWrapped(GrGLInterface *interface) {
872        fWrapped.reset(interface);
873    }
874
875    // TODO: there are some issues w/ wrapping another GL interface inside the
876    // debug interface:
877    //      Since none of the "gl" methods are member functions they don't get
878    //      a "this" pointer through which to access "fWrapped"
879    //      This could be worked around by having all of them access the
880    //      "glInterface" pointer - i.e., treating the debug interface as a
881    //      true singleton
882    //
883    //      The problem with this is that we also want to handle OpenGL
884    //      contexts. The natural way to do this is to have multiple debug
885    //      interfaces. Each of which represents a separate context. The
886    //      static ID count would still uniquify IDs across all of them.
887    //      The problem then is that we couldn't treat the debug GL
888    //      interface as a singleton (since there would be one for each
889    //      context).
890    //
891    //      The solution to this is probably to alter SkDebugGlContext's
892    //      "makeCurrent" method to make a call like "makeCurrent(this)" to
893    //      the debug GL interface (assuming that the application will create
894    //      multiple SkGLContext's) to let it switch between the active
895    //      context. Everything in the GrDebugGL object would then need to be
896    //      moved to a GrContextObj and the GrDebugGL object would just switch
897    //      between them. Note that this approach would also require that
898    //      SkDebugGLContext wrap an arbitrary other context
899    //      and then pass the wrapped interface to the debug GL interface.
900
901protected:
902private:
903
904    SkAutoTUnref<GrGLInterface> fWrapped;
905
906    typedef GrGLInterface INHERITED;
907};
908
909////////////////////////////////////////////////////////////////////////////////
910const GrGLInterface* GrGLCreateDebugInterface() {
911    // The gl functions are not context-specific so we create one global
912    // interface
913    static SkAutoTUnref<GrGLInterface> glInterface;
914    if (!glInterface.get()) {
915        GrGLInterface* interface = new GrDebugGLInterface;
916        glInterface.reset(interface);
917        interface->fBindingsExported = kDesktop_GrGLBinding;
918        interface->fActiveTexture = debugGLActiveTexture;
919        interface->fAttachShader = debugGLAttachShader;
920        interface->fBeginQuery = debugGLBeginQuery;
921        interface->fBindAttribLocation = debugGLBindAttribLocation;
922        interface->fBindBuffer = debugGLBindBuffer;
923        interface->fBindFragDataLocation = debugGLBindFragDataLocation;
924        interface->fBindTexture = debugGLBindTexture;
925        interface->fBlendColor = debugGLBlendColor;
926        interface->fBlendFunc = debugGLBlendFunc;
927        interface->fBufferData = debugGLBufferData;
928        interface->fBufferSubData = debugGLBufferSubData;
929        interface->fClear = debugGLClear;
930        interface->fClearColor = debugGLClearColor;
931        interface->fClearStencil = debugGLClearStencil;
932        interface->fColorMask = debugGLColorMask;
933        interface->fCompileShader = debugGLCompileShader;
934        interface->fCompressedTexImage2D = debugGLCompressedTexImage2D;
935        interface->fCreateProgram = debugGLCreateProgram;
936        interface->fCreateShader = debugGLCreateShader;
937        interface->fCullFace = debugGLCullFace;
938        interface->fDeleteBuffers = debugGLDeleteBuffers;
939        interface->fDeleteProgram = debugGLDeleteProgram;
940        interface->fDeleteQueries = debugGLDeleteIds;
941        interface->fDeleteShader = debugGLDeleteShader;
942        interface->fDeleteTextures = debugGLDeleteTextures;
943        interface->fDepthMask = debugGLDepthMask;
944        interface->fDisable = debugGLDisable;
945        interface->fDisableVertexAttribArray = debugGLDisableVertexAttribArray;
946        interface->fDrawArrays = debugGLDrawArrays;
947        interface->fDrawBuffer = debugGLDrawBuffer;
948        interface->fDrawBuffers = debugGLDrawBuffers;
949        interface->fDrawElements = debugGLDrawElements;
950        interface->fEnable = debugGLEnable;
951        interface->fEnableVertexAttribArray = debugGLEnableVertexAttribArray;
952        interface->fEndQuery = debugGLEndQuery;
953        interface->fFinish = debugGLFinish;
954        interface->fFlush = debugGLFlush;
955        interface->fFrontFace = debugGLFrontFace;
956        interface->fGenBuffers = debugGLGenBuffers;
957        interface->fGenQueries = debugGLGenIds;
958        interface->fGenTextures = debugGLGenTextures;
959        interface->fGetBufferParameteriv = debugGLGetBufferParameteriv;
960        interface->fGetError = debugGLGetError;
961        interface->fGetIntegerv = debugGLGetIntegerv;
962        interface->fGetQueryObjecti64v = debugGLGetQueryObjecti64v;
963        interface->fGetQueryObjectiv = debugGLGetQueryObjectiv;
964        interface->fGetQueryObjectui64v = debugGLGetQueryObjectui64v;
965        interface->fGetQueryObjectuiv = debugGLGetQueryObjectuiv;
966        interface->fGetQueryiv = debugGLGetQueryiv;
967        interface->fGetProgramInfoLog = debugGLGetInfoLog;
968        interface->fGetProgramiv = debugGLGetShaderOrProgramiv;
969        interface->fGetShaderInfoLog = debugGLGetInfoLog;
970        interface->fGetShaderiv = debugGLGetShaderOrProgramiv;
971        interface->fGetString = debugGLGetString;
972        interface->fGetTexLevelParameteriv = debugGLGetTexLevelParameteriv;
973        interface->fGetUniformLocation = debugGLGetUniformLocation;
974        interface->fLineWidth = debugGLLineWidth;
975        interface->fLinkProgram = debugGLLinkProgram;
976        interface->fPixelStorei = debugGLPixelStorei;
977        interface->fQueryCounter = debugGLQueryCounter;
978        interface->fReadBuffer = debugGLReadBuffer;
979        interface->fReadPixels = debugGLReadPixels;
980        interface->fScissor = debugGLScissor;
981        interface->fShaderSource = debugGLShaderSource;
982        interface->fStencilFunc = debugGLStencilFunc;
983        interface->fStencilFuncSeparate = debugGLStencilFuncSeparate;
984        interface->fStencilMask = debugGLStencilMask;
985        interface->fStencilMaskSeparate = debugGLStencilMaskSeparate;
986        interface->fStencilOp = debugGLStencilOp;
987        interface->fStencilOpSeparate = debugGLStencilOpSeparate;
988        interface->fTexImage2D = debugGLTexImage2D;
989        interface->fTexParameteri = debugGLTexParameteri;
990        interface->fTexSubImage2D = debugGLTexSubImage2D;
991        interface->fTexStorage2D = debugGLTexStorage2D;
992        interface->fUniform1f = debugGLUniform1f;
993        interface->fUniform1i = debugGLUniform1i;
994        interface->fUniform1fv = debugGLUniform1fv;
995        interface->fUniform1iv = debugGLUniform1iv;
996        interface->fUniform2f = debugGLUniform2f;
997        interface->fUniform2i = debugGLUniform2i;
998        interface->fUniform2fv = debugGLUniform2fv;
999        interface->fUniform2iv = debugGLUniform2iv;
1000        interface->fUniform3f = debugGLUniform3f;
1001        interface->fUniform3i = debugGLUniform3i;
1002        interface->fUniform3fv = debugGLUniform3fv;
1003        interface->fUniform3iv = debugGLUniform3iv;
1004        interface->fUniform4f = debugGLUniform4f;
1005        interface->fUniform4i = debugGLUniform4i;
1006        interface->fUniform4fv = debugGLUniform4fv;
1007        interface->fUniform4iv = debugGLUniform4iv;
1008        interface->fUniformMatrix2fv = debugGLUniformMatrix2fv;
1009        interface->fUniformMatrix3fv = debugGLUniformMatrix3fv;
1010        interface->fUniformMatrix4fv = debugGLUniformMatrix4fv;
1011        interface->fUseProgram = debugGLUseProgram;
1012        interface->fVertexAttrib4fv = debugGLVertexAttrib4fv;
1013        interface->fVertexAttribPointer = debugGLVertexAttribPointer;
1014        interface->fViewport = debugGLViewport;
1015        interface->fBindFramebuffer = debugGLBindFramebuffer;
1016        interface->fBindRenderbuffer = debugGLBindRenderbuffer;
1017        interface->fCheckFramebufferStatus = debugGLCheckFramebufferStatus;
1018        interface->fDeleteFramebuffers = debugGLDeleteFramebuffers;
1019        interface->fDeleteRenderbuffers = debugGLDeleteRenderbuffers;
1020        interface->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer;
1021        interface->fFramebufferTexture2D = debugGLFramebufferTexture2D;
1022        interface->fGenFramebuffers = debugGLGenFramebuffers;
1023        interface->fGenRenderbuffers = debugGLGenRenderbuffers;
1024        interface->fGetFramebufferAttachmentParameteriv = debugGLGetFramebufferAttachmentParameteriv;
1025        interface->fGetRenderbufferParameteriv = debugGLGetRenderbufferParameteriv;
1026        interface->fRenderbufferStorage = debugGLRenderbufferStorage;
1027        interface->fRenderbufferStorageMultisample = debugGLRenderbufferStorageMultisample;
1028        interface->fBlitFramebuffer = debugGLBlitFramebuffer;
1029        interface->fResolveMultisampleFramebuffer = debugGLResolveMultisampleFramebuffer;
1030        interface->fMapBuffer = debugGLMapBuffer;
1031        interface->fUnmapBuffer = debugGLUnmapBuffer;
1032        interface->fBindFragDataLocationIndexed = debugGLBindFragDataLocationIndexed;
1033    }
1034    glInterface.get()->ref();
1035    return glInterface.get();
1036}
1037