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