blob: 120381e29edd82ef838db705101ac60c2b91e8dc [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;
166 default:
167 GrAlwaysAssert(false);
168 break;
169 }
170
171 GrGLint alignment = 4; // the pack alignment (one of 1, 2, 4 or 8)
172 // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT
173
174 GrGLint componentSize = 0; // size (in bytes) of a single component
175
176 switch (type) {
177 case GR_GL_UNSIGNED_BYTE:
178 componentSize = 1;
179 break;
180 default:
181 GrAlwaysAssert(false);
182 break;
183 }
184
185 GrGLint rowStride = 0; // number of components (not bytes) to skip
186 if (componentSize >= alignment) {
187 rowStride = componentsPerPixel * pixelsInRow;
188 } else {
189 float fTemp =
190 sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
191 static_cast<float>(alignment));
192 rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
193 }
194
195 GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
196 for (int y = 0; y < height; ++y) {
197 memset(scanline, 0, componentsPerPixel * componentSize * width);
198 scanline += rowStride;
199 }
200}
robertphillips@google.com0da37192012-03-19 14:42:13 +0000201GrGLvoid GR_GL_FUNCTION_TYPE debugGLScissor(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
202GrGLvoid GR_GL_FUNCTION_TYPE debugGLShaderSource(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length) {}
203GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {}
204GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFuncSeparate(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask) {}
205GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMask(GrGLuint mask) {}
206GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMaskSeparate(GrGLenum face, GrGLuint mask) {}
207GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOp(GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
208GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOpSeparate(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
209GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexImage2D(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
210GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexParameteri(GrGLenum target, GrGLenum pname, GrGLint param) {}
211GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexStorage2D(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
212GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
213GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1f(GrGLint location, GrGLfloat v0) {}
214GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1i(GrGLint location, GrGLint v0) {}
215GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
216GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
217GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2f(GrGLint location, GrGLfloat v0, GrGLfloat v1) {}
218GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2i(GrGLint location, GrGLint v0, GrGLint v1) {}
219GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
220GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
221GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) {}
222GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {}
223GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
224GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
225GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3) {}
226GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {}
227GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
228GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
229GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix2fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
230GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix3fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
231GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix4fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
232
233GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) {
234
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000235 // A programID of 0 is legal
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000236 GrProgramObj *program = GR_FIND(programID, GrProgramObj, GrDebugGL::kProgram_ObjTypes);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000237
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000238 GrDebugGL::getInstance()->useProgram(program);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000239}
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000240
robertphillips@google.com0da37192012-03-19 14:42:13 +0000241GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {}
242GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttribPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr) {}
243GrGLvoid GR_GL_FUNCTION_TYPE debugGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000244
245GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, GrGLuint frameBufferID) {
246
247 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
248
249 // a frameBufferID of 0 is acceptable - it binds to the default frame buffer
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000250 GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID, GrFrameBufferObj, GrDebugGL::kFrameBuffer_ObjTypes);
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000251
robertphillips@google.com7c959422012-03-22 20:43:56 +0000252 GrDebugGL::getInstance()->setFrameBuffer(frameBuffer);
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000253}
254
robertphillips@google.com7c959422012-03-22 20:43:56 +0000255GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000256
robertphillips@google.com7c959422012-03-22 20:43:56 +0000257 GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
258
259 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000260 GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID, GrRenderBufferObj, GrDebugGL::kRenderBuffer_ObjTypes);
robertphillips@google.com7c959422012-03-22 20:43:56 +0000261
262 GrDebugGL::getInstance()->setRenderBuffer(renderBuffer);
263}
264
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000265GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n, const GrGLuint* textures) {
266
267 // first potentially unbind the texture
268 // TODO: move this into GrDebugGL as unBindTexture?
269 for (unsigned int i = 0; i < GrDebugGL::getInstance()->getMaxTextureUnits(); ++i)
270 {
271 GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i);
272
273 if (pTU->getTexture()) {
274 for (int j = 0; j < n; ++j) {
275
276 if (textures[j] == pTU->getTexture()->getID()) {
277 // this ID is the current texture - revert the binding to 0
278 pTU->setTexture(NULL);
279 }
280 }
281 }
282 }
283
284 // TODO: fuse the following block with DeleteRenderBuffers?
285 // Open GL will remove a deleted render buffer from the active frame buffer but not
286 // from any other frame buffer
287 if (GrDebugGL::getInstance()->getFrameBuffer()) {
288
289 GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer();
290
291 for (int i = 0; i < n; ++i) {
292
293 if (NULL != frameBuffer->getColor() && textures[i] == frameBuffer->getColor()->getID()) {
294 frameBuffer->setColor(NULL);
295 }
296 if (NULL != frameBuffer->getDepth() && textures[i] == frameBuffer->getDepth()->getID()) {
297 frameBuffer->setDepth(NULL);
298 }
299 if (NULL != frameBuffer->getStencil() && textures[i] == frameBuffer->getStencil()->getID()) {
300 frameBuffer->setStencil(NULL);
301 }
302 }
303 }
304
305 // then actually "delete" the buffers
306 for (int i = 0; i < n; ++i) {
307 GrTextureObj *buffer = GR_FIND(textures[i], GrTextureObj, GrDebugGL::kTexture_ObjTypes);
308 GrAlwaysAssert(buffer);
309
310 // OpenGL gives no guarantees if a texture is deleted while attached to
311 // something other than the currently bound frame buffer
312 GrAlwaysAssert(!buffer->getBound());
313
314 GrAlwaysAssert(!buffer->getDeleted());
315 buffer->deleteAction();
316 }
317
318}
319
320
robertphillips@google.com7c959422012-03-22 20:43:56 +0000321GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000322
323 // first potentially unbind the buffers
324 if (GrDebugGL::getInstance()->getFrameBuffer()) {
325 for (int i = 0; i < n; ++i) {
326
robertphillips@google.com7c959422012-03-22 20:43:56 +0000327 if (frameBuffers[i] == GrDebugGL::getInstance()->getFrameBuffer()->getID()) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000328 // this ID is the current frame buffer - rebind to the default
329 GrDebugGL::getInstance()->setFrameBuffer(NULL);
330 }
331 }
332 }
333
334 // then actually "delete" the buffers
335 for (int i = 0; i < n; ++i) {
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000336 GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i], GrFrameBufferObj, GrDebugGL::kFrameBuffer_ObjTypes);
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000337 GrAlwaysAssert(buffer);
338
339 GrAlwaysAssert(!buffer->getDeleted());
340 buffer->deleteAction();
341 }
342}
343
robertphillips@google.com7c959422012-03-22 20:43:56 +0000344GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderBuffers) {
345
346 // first potentially unbind the buffers
347 if (GrDebugGL::getInstance()->getRenderBuffer()) {
348 for (int i = 0; i < n; ++i) {
349
350 if (renderBuffers[i] == GrDebugGL::getInstance()->getRenderBuffer()->getID()) {
351 // this ID is the current render buffer - make no render buffer be bound
352 GrDebugGL::getInstance()->setRenderBuffer(NULL);
353 }
354 }
355 }
356
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000357 // TODO: fuse the following block with DeleteTextures?
robertphillips@google.com7c959422012-03-22 20:43:56 +0000358 // Open GL will remove a deleted render buffer from the active frame buffer but not
359 // from any other frame buffer
360 if (GrDebugGL::getInstance()->getFrameBuffer()) {
361
362 GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer();
363
364 for (int i = 0; i < n; ++i) {
365
366 if (NULL != frameBuffer->getColor() && renderBuffers[i] == frameBuffer->getColor()->getID()) {
367 frameBuffer->setColor(NULL);
368 }
369 if (NULL != frameBuffer->getDepth() && renderBuffers[i] == frameBuffer->getDepth()->getID()) {
370 frameBuffer->setDepth(NULL);
371 }
372 if (NULL != frameBuffer->getStencil() && renderBuffers[i] == frameBuffer->getStencil()->getID()) {
373 frameBuffer->setStencil(NULL);
374 }
375 }
376 }
377
378 // then actually "delete" the buffers
379 for (int i = 0; i < n; ++i) {
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000380 GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i], GrRenderBufferObj, GrDebugGL::kRenderBuffer_ObjTypes);
robertphillips@google.com7c959422012-03-22 20:43:56 +0000381 GrAlwaysAssert(buffer);
382
383 // OpenGL gives no guarantees if a render buffer is deleted while attached to
384 // something other than the currently bound frame buffer
385 GrAlwaysAssert(!buffer->getColorBound());
386 GrAlwaysAssert(!buffer->getDepthBound());
387 GrAlwaysAssert(!buffer->getStencilBound());
388
389 GrAlwaysAssert(!buffer->getDeleted());
390 buffer->deleteAction();
391 }
392}
393
394GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderBufferID) {
395
396 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
397 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
398 GR_GL_DEPTH_ATTACHMENT == attachment ||
399 GR_GL_STENCIL_ATTACHMENT == attachment);
400 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
401
402 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
403 // A render buffer cannot be attached to the default framebuffer
404 GrAlwaysAssert(NULL != framebuffer);
405
406 // a renderBufferID of 0 is acceptable - it unbinds the current render buffer
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000407 GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID, GrRenderBufferObj, GrDebugGL::kRenderBuffer_ObjTypes);
robertphillips@google.com7c959422012-03-22 20:43:56 +0000408
409 switch (attachment) {
410 case GR_GL_COLOR_ATTACHMENT0:
411 framebuffer->setColor(renderbuffer);
412 break;
413 case GR_GL_DEPTH_ATTACHMENT:
414 framebuffer->setDepth(renderbuffer);
415 break;
416 case GR_GL_STENCIL_ATTACHMENT:
417 framebuffer->setStencil(renderbuffer);
418 break;
419 default:
420 GrAlwaysAssert(false);
421 break;
422 };
423
424}
425
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000426////////////////////////////////////////////////////////////////////////////////
427GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint textureID, GrGLint level) {
428
429 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
430 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
431 GR_GL_DEPTH_ATTACHMENT == attachment ||
432 GR_GL_STENCIL_ATTACHMENT == attachment);
433 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
434
435 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
436 // A texture cannot be attached to the default framebuffer
437 GrAlwaysAssert(NULL != framebuffer);
438
439 // A textureID of 0 is allowed - it unbinds the currently bound texture
440 GrTextureObj *texture = GR_FIND(textureID, GrTextureObj, GrDebugGL::kTexture_ObjTypes);
441 if (texture) {
442 // The texture shouldn't be bound to a texture unit - this could lead to a feedback loop
443 GrAlwaysAssert(!texture->getBound());
444 }
445
446 GrAlwaysAssert(0 == level);
447
448 switch (attachment) {
449 case GR_GL_COLOR_ATTACHMENT0:
450 framebuffer->setColor(texture);
451 break;
452 case GR_GL_DEPTH_ATTACHMENT:
453 framebuffer->setDepth(texture);
454 break;
455 case GR_GL_STENCIL_ATTACHMENT:
456 framebuffer->setStencil(texture);
457 break;
458 default:
459 GrAlwaysAssert(false);
460 break;
461 };
462}
463
robertphillips@google.com0da37192012-03-19 14:42:13 +0000464GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetFramebufferAttachmentParameteriv(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params) {}
465GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetRenderbufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {}
466GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
467GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
468GrGLvoid 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) {}
469GrGLvoid GR_GL_FUNCTION_TYPE debugGLResolveMultisampleFramebuffer() {}
470GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocationIndexed(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name) {}
471
472GrGLenum GR_GL_FUNCTION_TYPE debugGLCheckFramebufferStatus(GrGLenum target) {
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000473
474 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
475
robertphillips@google.com0da37192012-03-19 14:42:13 +0000476 return GR_GL_FRAMEBUFFER_COMPLETE;
477}
478
479GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() {
480
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000481 GrProgramObj *program = GR_CREATE(GrProgramObj, GrDebugGL::kProgram_ObjTypes);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000482
483 return program->getID();
484}
485
486GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) {
487
488 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || GR_GL_FRAGMENT_SHADER == type);
489
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000490 GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes);
491 shader->setType(type);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000492
493 return shader->getID();
494}
495
496GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) {
497
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000498 GrProgramObj *program = GR_FIND(programID, GrProgramObj, GrDebugGL::kProgram_ObjTypes);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000499 GrAlwaysAssert(program);
500
robertphillips@google.com0da37192012-03-19 14:42:13 +0000501 if (program->getRefCount()) {
502 // someone is still using this program so we can't delete it here
503 program->setMarkedForDeletion();
504 } else {
505 program->deleteAction();
506 }
507}
508
509GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) {
510
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000511 GrShaderObj *shader = GR_FIND(shaderID, GrShaderObj, GrDebugGL::kShader_ObjTypes);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000512 GrAlwaysAssert(shader);
513
robertphillips@google.com0da37192012-03-19 14:42:13 +0000514 if (shader->getRefCount()) {
515 // someone is still using this shader so we can't delete it here
516 shader->setMarkedForDeletion();
517 } else {
518 shader->deleteAction();
519 }
520}
521
522// same function used for all glGen*(GLsize i, GLuint*) functions
523GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenIds(GrGLsizei n, GrGLuint* ids) {
524 static int gCurrID = 1;
525 for (int i = 0; i < n; ++i) {
526 ids[i] = ++gCurrID;
527 }
528}
529
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000530GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type, GrGLsizei n, GrGLuint* ids) {
531
532 for (int i = 0; i < n; ++i) {
533 GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type);
534 GrAlwaysAssert(obj);
535 ids[i] = obj->getID();
536 }
537}
538
robertphillips@google.com0da37192012-03-19 14:42:13 +0000539GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
540
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000541 debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000542}
543
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000544GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, GrGLuint* ids) {
545
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000546 debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids);
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000547}
548
robertphillips@google.com7c959422012-03-22 20:43:56 +0000549GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, GrGLuint* ids) {
550
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000551 debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids);
552}
553
554GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) {
555
556 debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids);
robertphillips@google.com7c959422012-03-22 20:43:56 +0000557}
558
robertphillips@google.com0da37192012-03-19 14:42:13 +0000559// same delete function for all glDelete*(GLsize i, const GLuint*) except buffers
560GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteIds(GrGLsizei n, const GrGLuint* ids) {}
561
robertphillips@google.com0da37192012-03-19 14:42:13 +0000562GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) {
563
564 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
565
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000566 GrBufferObj *buffer = GR_FIND(bufferID, GrBufferObj, GrDebugGL::kBuffer_ObjTypes);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000567 // 0 is a permissable bufferID - it unbinds the current buffer
568
569 switch (target) {
570 case GR_GL_ARRAY_BUFFER:
robertphillips@google.com0da37192012-03-19 14:42:13 +0000571 GrDebugGL::getInstance()->setArrayBuffer(buffer);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000572 break;
573 case GR_GL_ELEMENT_ARRAY_BUFFER:
robertphillips@google.com0da37192012-03-19 14:42:13 +0000574 GrDebugGL::getInstance()->setElementArrayBuffer(buffer);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000575 break;
576 default:
577 GrCrash("Unexpected target to glBindBuffer");
578 break;
579 }
580}
581
582// deleting a bound buffer has the side effect of binding 0
583GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
584 // first potentially unbind the buffers
585 for (int i = 0; i < n; ++i) {
586
587 if (GrDebugGL::getInstance()->getArrayBuffer() &&
588 ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) {
589 // this ID is the current array buffer
robertphillips@google.com0da37192012-03-19 14:42:13 +0000590 GrDebugGL::getInstance()->setArrayBuffer(NULL);
591 }
592 if (GrDebugGL::getInstance()->getElementArrayBuffer() &&
593 ids[i] == GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) {
594 // this ID is the current element array buffer
robertphillips@google.com0da37192012-03-19 14:42:13 +0000595 GrDebugGL::getInstance()->setElementArrayBuffer(NULL);
596 }
597 }
598
599 // then actually "delete" the buffers
600 for (int i = 0; i < n; ++i) {
robertphillips@google.comba0cc3e2012-03-26 17:58:35 +0000601 GrBufferObj *buffer = GR_FIND(ids[i], GrBufferObj, GrDebugGL::kBuffer_ObjTypes);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000602 GrAlwaysAssert(buffer);
603
604 GrAlwaysAssert(!buffer->getDeleted());
605 buffer->deleteAction();
606 }
607}
608
609// map a buffer to the caller's address space
610GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) {
611
612 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
613 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); // GR_GL_READ_ONLY == access || || GR_GL_READ_WRIT == access);
614
615 GrBufferObj *buffer = NULL;
616 switch (target) {
617 case GR_GL_ARRAY_BUFFER:
618 buffer = GrDebugGL::getInstance()->getArrayBuffer();
619 break;
620 case GR_GL_ELEMENT_ARRAY_BUFFER:
621 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
622 break;
623 default:
624 GrCrash("Unexpected target to glMapBuffer");
625 break;
626 }
627
628 if (buffer) {
629 GrAlwaysAssert(!buffer->getMapped());
630 buffer->setMapped();
631 return buffer->getDataPtr();
632 }
633
634 GrAlwaysAssert(false);
635 return NULL; // no buffer bound to the target
636}
637
638// remove a buffer from the caller's address space
639// TODO: check if the "access" method from "glMapBuffer" was honored
640GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) {
641
642 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
643
644 GrBufferObj *buffer = NULL;
645 switch (target) {
646 case GR_GL_ARRAY_BUFFER:
647 buffer = GrDebugGL::getInstance()->getArrayBuffer();
648 break;
649 case GR_GL_ELEMENT_ARRAY_BUFFER:
650 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
651 break;
652 default:
653 GrCrash("Unexpected target to glUnmapBuffer");
654 break;
655 }
656
657 if (buffer) {
658 GrAlwaysAssert(buffer->getMapped());
659 buffer->resetMapped();
660 return GR_GL_TRUE;
661 }
662
663 GrAlwaysAssert(false);
664 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
665}
666
667GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) {
668
669 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
670 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || GR_GL_BUFFER_USAGE == value);
671
672 GrBufferObj *buffer = NULL;
673 switch (target) {
674 case GR_GL_ARRAY_BUFFER:
675 buffer = GrDebugGL::getInstance()->getArrayBuffer();
676 break;
677 case GR_GL_ELEMENT_ARRAY_BUFFER:
678 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
679 break;
680 }
681
682 GrAlwaysAssert(buffer);
683
684 switch (value) {
685 case GR_GL_BUFFER_MAPPED:
686 *params = GR_GL_FALSE;
687 if (buffer)
688 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
689 break;
690 case GR_GL_BUFFER_SIZE:
691 *params = 0;
692 if (buffer)
693 *params = buffer->getSize();
694 break;
695 case GR_GL_BUFFER_USAGE:
696 *params = GR_GL_STATIC_DRAW;
697 if (buffer)
698 *params = buffer->getUsage();
699 break;
700 default:
701 GrCrash("Unexpected value to glGetBufferParamateriv");
702 break;
703 }
704};
705
706GrGLenum GR_GL_FUNCTION_TYPE debugGLGetError() {
707 return GR_GL_NO_ERROR;
708}
709
710GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetIntegerv(GrGLenum pname, GrGLint* params) {
711 // TODO: remove from Ganesh the #defines for gets we don't use.
712 // We would like to minimize gets overall due to performance issues
713 switch (pname) {
714 case GR_GL_STENCIL_BITS:
715 *params = 8;
716 break;
717 case GR_GL_SAMPLES:
718 *params = 1;
719 break;
720 case GR_GL_FRAMEBUFFER_BINDING:
721 *params = 0;
722 break;
723 case GR_GL_VIEWPORT:
724 params[0] = 0;
725 params[1] = 0;
726 params[2] = 800;
727 params[3] = 600;
728 break;
729 case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
730 *params = 8;
731 break;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000732 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
733 *params = kDefaultMaxVertexUniformVectors;
734 break;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000735 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000736 *params = kDefaultMaxFragmentUniformVectors;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000737 break;
738 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
739 *params = 16 * 4;
740 break;
741 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
742 *params = 0;
743 break;
744 case GR_GL_COMPRESSED_TEXTURE_FORMATS:
745 break;
746 case GR_GL_MAX_TEXTURE_SIZE:
747 *params = 8192;
748 break;
749 case GR_GL_MAX_RENDERBUFFER_SIZE:
750 *params = 8192;
751 break;
752 case GR_GL_MAX_SAMPLES:
753 *params = 32;
754 break;
755 case GR_GL_MAX_VERTEX_ATTRIBS:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000756 *params = kDefaultMaxVertexAttribs;
757 break;
758 case GR_GL_MAX_VARYING_VECTORS:
759 *params = kDefaultMaxVaryingVectors;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000760 break;
761 case GR_GL_MAX_TEXTURE_UNITS:
762 *params = GrDebugGL::getInstance()->getMaxTextureUnits();
763 break;
764 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}