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