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