1
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "gl/GrGLInterface.h"
11#include "GrDebugGL.h"
12#include "GrShaderObj.h"
13#include "GrProgramObj.h"
14#include "GrBufferObj.h"
15#include "GrTextureUnitObj.h"
16#include "GrTextureObj.h"
17#include "GrFrameBufferObj.h"
18#include "GrRenderBufferObj.h"
19#include "SkFloatingPoint.h"
20
21// the OpenGLES 2.0 spec says this must be >= 128
22static const GrGLint kDefaultMaxVertexUniformVectors = 128;
23
24// the OpenGLES 2.0 spec says this must be >=16
25static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
26
27// the OpenGLES 2.0 spec says this must be >= 8
28static const GrGLint kDefaultMaxVertexAttribs = 8;
29
30// the OpenGLES 2.0 spec says this must be >= 8
31static const GrGLint kDefaultMaxVaryingVectors = 8;
32
33namespace { // suppress no previsous prototype warning
34
35////////////////////////////////////////////////////////////////////////////////
36GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) {
37
38    // Ganesh offsets the texture unit indices
39    texture -= GR_GL_TEXTURE0;
40    GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits());
41
42    GrDebugGL::getInstance()->setCurTextureUnit(texture);
43}
44
45////////////////////////////////////////////////////////////////////////////////
46GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID,
47                                                 GrGLuint shaderID) {
48
49    GrProgramObj *program = GR_FIND(programID, GrProgramObj,
50                                    GrDebugGL::kProgram_ObjTypes);
51    GrAlwaysAssert(program);
52
53    GrShaderObj *shader = GR_FIND(shaderID,
54                                  GrShaderObj,
55                                  GrDebugGL::kShader_ObjTypes);
56    GrAlwaysAssert(shader);
57
58    program->AttachShader(shader);
59}
60
61GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) {
62}
63
64GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program,
65                                                       GrGLuint index,
66                                                       const char* name) {
67}
68
69////////////////////////////////////////////////////////////////////////////////
70GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target,
71                                                GrGLuint textureID) {
72
73    // we don't use cube maps
74    GrAlwaysAssert(target == GR_GL_TEXTURE_2D);
75                                    // || target == GR_GL_TEXTURE_CUBE_MAP);
76
77    // a textureID of 0 is acceptable - it binds to the default texture target
78    GrTextureObj *texture = GR_FIND(textureID, GrTextureObj,
79                                    GrDebugGL::kTexture_ObjTypes);
80
81    GrDebugGL::getInstance()->setTexture(texture);
82}
83
84GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendColor(GrGLclampf red,
85                                               GrGLclampf green,
86                                               GrGLclampf blue,
87                                               GrGLclampf alpha) {
88}
89
90GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocation(GrGLuint program,
91                                                         GrGLuint colorNumber,
92                                                         const GrGLchar* name) {
93}
94
95GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendFunc(GrGLenum sfactor,
96                                              GrGLenum dfactor) {
97}
98
99////////////////////////////////////////////////////////////////////////////////
100GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target,
101                                               GrGLsizeiptr size,
102                                               const GrGLvoid* data,
103                                               GrGLenum usage) {
104    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
105                   GR_GL_ELEMENT_ARRAY_BUFFER == target);
106    GrAlwaysAssert(size >= 0);
107    GrAlwaysAssert(GR_GL_STREAM_DRAW == usage ||
108                   GR_GL_STATIC_DRAW == usage ||
109                   GR_GL_DYNAMIC_DRAW == usage);
110
111    GrBufferObj *buffer = NULL;
112    switch (target) {
113        case GR_GL_ARRAY_BUFFER:
114            buffer = GrDebugGL::getInstance()->getArrayBuffer();
115            break;
116        case GR_GL_ELEMENT_ARRAY_BUFFER:
117            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
118            break;
119        default:
120            GrCrash("Unexpected target to glBufferData");
121            break;
122    }
123
124    GrAlwaysAssert(buffer);
125    GrAlwaysAssert(buffer->getBound());
126
127    buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
128    buffer->setUsage(usage);
129}
130
131GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferSubData(GrGLenum target,
132                                                  GrGLintptr offset,
133                                                  GrGLsizeiptr size,
134                                                  const GrGLvoid* data) {
135}
136
137GrGLvoid GR_GL_FUNCTION_TYPE debugGLClear(GrGLbitfield mask) {
138}
139
140GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearColor(GrGLclampf red,
141                                               GrGLclampf green,
142                                               GrGLclampf blue,
143                                               GrGLclampf alpha) {
144}
145
146GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearStencil(GrGLint s) {
147}
148
149GrGLvoid GR_GL_FUNCTION_TYPE debugGLColorMask(GrGLboolean red,
150                                              GrGLboolean green,
151                                              GrGLboolean blue,
152                                              GrGLboolean alpha) {
153}
154
155GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompileShader(GrGLuint shader) {
156}
157
158GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompressedTexImage2D(GrGLenum target,
159                                                         GrGLint level,
160                                                         GrGLenum internalformat,
161                                                         GrGLsizei width,
162                                                         GrGLsizei height,
163                                                         GrGLint border,
164                                                         GrGLsizei imageSize,
165                                                         const GrGLvoid* data) {
166}
167
168GrGLvoid GR_GL_FUNCTION_TYPE debugGLCullFace(GrGLenum mode) {
169}
170
171GrGLvoid GR_GL_FUNCTION_TYPE debugGLDepthMask(GrGLboolean flag) {
172}
173
174GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisable(GrGLenum cap) {
175}
176
177GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisableVertexAttribArray(GrGLuint index) {
178}
179
180GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawArrays(GrGLenum mode,
181                                               GrGLint first,
182                                               GrGLsizei count) {
183}
184
185GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffer(GrGLenum mode) {
186}
187
188GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffers(GrGLsizei n,
189                                                const GrGLenum* bufs) {
190}
191
192GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawElements(GrGLenum mode,
193                                                 GrGLsizei count,
194                                                 GrGLenum type,
195                                                 const GrGLvoid* indices) {
196}
197
198GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnable(GrGLenum cap) {
199}
200
201GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnableVertexAttribArray(GrGLuint index) {
202}
203
204GrGLvoid GR_GL_FUNCTION_TYPE debugGLEndQuery(GrGLenum target) {
205}
206
207GrGLvoid GR_GL_FUNCTION_TYPE debugGLFinish() {
208}
209
210GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlush() {
211}
212
213GrGLvoid GR_GL_FUNCTION_TYPE debugGLFrontFace(GrGLenum mode) {
214}
215
216GrGLvoid GR_GL_FUNCTION_TYPE debugGLLineWidth(GrGLfloat width) {
217}
218
219GrGLvoid GR_GL_FUNCTION_TYPE debugGLLinkProgram(GrGLuint program) {
220}
221
222GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname,
223                                                GrGLint param) {
224
225    switch (pname) {
226        case GR_GL_UNPACK_ROW_LENGTH:
227            GrDebugGL::getInstance()->setUnPackRowLength(param);
228            break;
229        case GR_GL_PACK_ROW_LENGTH:
230            GrDebugGL::getInstance()->setPackRowLength(param);
231            break;
232        case GR_GL_UNPACK_ALIGNMENT:
233            break;
234        case GR_GL_PACK_ALIGNMENT:
235            GrAlwaysAssert(false);
236            break;
237        default:
238            GrAlwaysAssert(false);
239            break;
240    }
241}
242
243GrGLvoid GR_GL_FUNCTION_TYPE debugGLQueryCounter(GrGLuint id,
244                                                 GrGLenum target) {
245}
246
247GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadBuffer(GrGLenum src) {
248}
249
250GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x,
251                                               GrGLint y,
252                                               GrGLsizei width,
253                                               GrGLsizei height,
254                                               GrGLenum format,
255                                               GrGLenum type,
256                                               GrGLvoid* pixels) {
257
258    GrGLint pixelsInRow = width;
259    if (0 < GrDebugGL::getInstance()->getPackRowLength()) {
260        pixelsInRow = GrDebugGL::getInstance()->getPackRowLength();
261    }
262
263    GrGLint componentsPerPixel = 0;
264
265    switch (format) {
266        case GR_GL_RGBA:
267            // fallthrough
268        case GR_GL_BGRA:
269            componentsPerPixel = 4;
270            break;
271        case GR_GL_RGB:
272            componentsPerPixel = 3;
273            break;
274        case GR_GL_RED:
275            componentsPerPixel = 1;
276            break;
277        default:
278            GrAlwaysAssert(false);
279            break;
280    }
281
282    GrGLint alignment = 4;  // the pack alignment (one of 1, 2, 4 or 8)
283    // Ganesh currently doesn't support setting GR_GL_PACK_ALIGNMENT
284
285    GrGLint componentSize = 0;  // size (in bytes) of a single component
286
287    switch (type) {
288        case GR_GL_UNSIGNED_BYTE:
289            componentSize = 1;
290            break;
291        default:
292            GrAlwaysAssert(false);
293            break;
294    }
295
296    GrGLint rowStride = 0;  // number of components (not bytes) to skip
297    if (componentSize >= alignment) {
298        rowStride = componentsPerPixel * pixelsInRow;
299    } else {
300        float fTemp =
301            sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
302                          static_cast<float>(alignment));
303        rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
304    }
305
306    GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
307    for (int y = 0; y < height; ++y) {
308        memset(scanline, 0, componentsPerPixel * componentSize * width);
309        scanline += rowStride;
310    }
311}
312
313GrGLvoid GR_GL_FUNCTION_TYPE debugGLScissor(GrGLint x,
314                                            GrGLint y,
315                                            GrGLsizei width,
316                                            GrGLsizei height) {
317}
318
319GrGLvoid GR_GL_FUNCTION_TYPE debugGLShaderSource(GrGLuint shader,
320                                                 GrGLsizei count,
321#if GR_USE_NEW_GL_SHADER_SOURCE_SIGNATURE
322                                                 const char* const * str,
323#else
324                                                 const char** str,
325#endif
326                                                 const GrGLint* length) {
327}
328
329GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFunc(GrGLenum func,
330                                                GrGLint ref,
331                                                GrGLuint mask) {
332}
333
334GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFuncSeparate(GrGLenum face,
335                                                        GrGLenum func,
336                                                        GrGLint ref,
337                                                        GrGLuint mask) {
338}
339
340GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMask(GrGLuint mask) {
341}
342
343GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMaskSeparate(GrGLenum face,
344                                                        GrGLuint mask) {
345}
346
347GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOp(GrGLenum fail,
348                                              GrGLenum zfail,
349                                              GrGLenum zpass) {
350}
351
352GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOpSeparate(GrGLenum face,
353                                                      GrGLenum fail,
354                                                      GrGLenum zfail,
355                                                      GrGLenum zpass) {
356}
357
358GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexImage2D(GrGLenum target,
359                                               GrGLint level,
360                                               GrGLint internalformat,
361                                               GrGLsizei width,
362                                               GrGLsizei height,
363                                               GrGLint border,
364                                               GrGLenum format,
365                                               GrGLenum type,
366                                               const GrGLvoid* pixels) {
367}
368
369GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexParameteri(GrGLenum target,
370                                                  GrGLenum pname,
371                                                  GrGLint param) {
372}
373
374GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexParameteriv(GrGLenum target,
375                                                   GrGLenum pname,
376                                                   const GrGLint* params) {
377}
378
379GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexStorage2D(GrGLenum target,
380                                                 GrGLsizei levels,
381                                                 GrGLenum internalformat,
382                                                 GrGLsizei width,
383                                                 GrGLsizei height) {
384}
385
386GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexSubImage2D(GrGLenum target,
387                                                  GrGLint level,
388                                                  GrGLint xoffset,
389                                                  GrGLint yoffset,
390                                                  GrGLsizei width,
391                                                  GrGLsizei height,
392                                                  GrGLenum format,
393                                                  GrGLenum type,
394                                                  const GrGLvoid* pixels) {
395}
396
397GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1f(GrGLint location,
398                                              GrGLfloat v0) {
399}
400
401GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1i(GrGLint location,
402                                              GrGLint v0) {
403}
404
405GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1fv(GrGLint location,
406                                               GrGLsizei count,
407                                               const GrGLfloat* v) {
408}
409
410GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1iv(GrGLint location,
411                                               GrGLsizei count,
412                                               const GrGLint* v) {
413}
414
415GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2f(GrGLint location,
416                                              GrGLfloat v0,
417                                              GrGLfloat v1) {
418}
419
420GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2i(GrGLint location,
421                                              GrGLint v0,
422                                              GrGLint v1) {
423}
424
425GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2fv(GrGLint location,
426                                               GrGLsizei count,
427                                               const GrGLfloat* v) {
428}
429
430GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2iv(GrGLint location,
431                                               GrGLsizei count,
432                                               const GrGLint* v) {
433}
434
435GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3f(GrGLint location,
436                                              GrGLfloat v0,
437                                              GrGLfloat v1,
438                                              GrGLfloat v2) {
439}
440
441GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3i(GrGLint location,
442                                              GrGLint v0,
443                                              GrGLint v1,
444                                              GrGLint v2) {
445}
446
447GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3fv(GrGLint location,
448                                               GrGLsizei count,
449                                               const GrGLfloat* v) {
450}
451
452GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3iv(GrGLint location,
453                                               GrGLsizei count,
454                                               const GrGLint* v) {
455}
456
457GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4f(GrGLint location,
458                                              GrGLfloat v0,
459                                              GrGLfloat v1,
460                                              GrGLfloat v2,
461                                              GrGLfloat v3) {
462}
463
464GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4i(GrGLint location,
465                                              GrGLint v0,
466                                              GrGLint v1,
467                                              GrGLint v2,
468                                              GrGLint v3) {
469}
470
471GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4fv(GrGLint location,
472                                               GrGLsizei count,
473                                               const GrGLfloat* v) {
474 }
475
476 GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4iv(GrGLint location,
477                                                GrGLsizei count,
478                                                const GrGLint* v) {
479 }
480
481 GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix2fv(GrGLint location,
482                                                      GrGLsizei count,
483                                                      GrGLboolean transpose,
484                                                      const GrGLfloat* value) {
485 }
486
487 GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix3fv(GrGLint location,
488                                                      GrGLsizei count,
489                                                      GrGLboolean transpose,
490                                                      const GrGLfloat* value) {
491 }
492
493 GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix4fv(GrGLint location,
494                                                      GrGLsizei count,
495                                                      GrGLboolean transpose,
496                                                      const GrGLfloat* value) {
497 }
498
499 GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) {
500
501     // A programID of 0 is legal
502     GrProgramObj *program = GR_FIND(programID,
503                                     GrProgramObj,
504                                     GrDebugGL::kProgram_ObjTypes);
505
506     GrDebugGL::getInstance()->useProgram(program);
507 }
508
509 GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttrib4fv(GrGLuint indx,
510                                                     const GrGLfloat* values) {
511 }
512
513 GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttribPointer(GrGLuint indx,
514                                                         GrGLint size,
515                                                         GrGLenum type,
516                                                         GrGLboolean normalized,
517                                                         GrGLsizei stride,
518                                                         const GrGLvoid* ptr) {
519 }
520
521 GrGLvoid GR_GL_FUNCTION_TYPE debugGLViewport(GrGLint x,
522                                              GrGLint y,
523                                              GrGLsizei width,
524                                              GrGLsizei height) {
525 }
526
527 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target,
528                                                     GrGLuint frameBufferID) {
529
530     GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
531
532     // a frameBufferID of 0 is acceptable - it binds to the default
533     // frame buffer
534     GrFrameBufferObj *frameBuffer = GR_FIND(frameBufferID,
535                                             GrFrameBufferObj,
536                                             GrDebugGL::kFrameBuffer_ObjTypes);
537
538     GrDebugGL::getInstance()->setFrameBuffer(frameBuffer);
539 }
540
541 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target,
542                                                      GrGLuint renderBufferID) {
543
544     GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
545
546     // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
547     GrRenderBufferObj *renderBuffer = GR_FIND(renderBufferID,
548                                               GrRenderBufferObj,
549                                               GrDebugGL::kRenderBuffer_ObjTypes);
550
551     GrDebugGL::getInstance()->setRenderBuffer(renderBuffer);
552 }
553
554 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteTextures(GrGLsizei n,
555                                                    const GrGLuint* textures) {
556
557     // first potentially unbind the texture
558     // TODO: move this into GrDebugGL as unBindTexture?
559     for (unsigned int i = 0;
560          i < GrDebugGL::getInstance()->getMaxTextureUnits();
561          ++i) {
562         GrTextureUnitObj *pTU = GrDebugGL::getInstance()->getTextureUnit(i);
563
564         if (pTU->getTexture()) {
565             for (int j = 0; j < n; ++j) {
566
567                 if (textures[j] == pTU->getTexture()->getID()) {
568                     // this ID is the current texture - revert the binding to 0
569                     pTU->setTexture(NULL);
570                 }
571             }
572         }
573     }
574
575     // TODO: fuse the following block with DeleteRenderBuffers?
576     // Open GL will remove a deleted render buffer from the active
577     // frame buffer but not from any other frame buffer
578     if (GrDebugGL::getInstance()->getFrameBuffer()) {
579
580         GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer();
581
582         for (int i = 0; i < n; ++i) {
583
584             if (NULL != frameBuffer->getColor() &&
585                 textures[i] == frameBuffer->getColor()->getID()) {
586                 frameBuffer->setColor(NULL);
587             }
588             if (NULL != frameBuffer->getDepth() &&
589                 textures[i] == frameBuffer->getDepth()->getID()) {
590                 frameBuffer->setDepth(NULL);
591             }
592             if (NULL != frameBuffer->getStencil() &&
593                 textures[i] == frameBuffer->getStencil()->getID()) {
594                 frameBuffer->setStencil(NULL);
595             }
596         }
597     }
598
599     // then actually "delete" the buffers
600     for (int i = 0; i < n; ++i) {
601         GrTextureObj *buffer = GR_FIND(textures[i],
602                                        GrTextureObj,
603                                        GrDebugGL::kTexture_ObjTypes);
604         GrAlwaysAssert(buffer);
605
606         // OpenGL gives no guarantees if a texture is deleted while attached to
607         // something other than the currently bound frame buffer
608         GrAlwaysAssert(!buffer->getBound());
609
610         GrAlwaysAssert(!buffer->getDeleted());
611         buffer->deleteAction();
612     }
613
614 }
615
616
617 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n,
618                                                        const GrGLuint *frameBuffers) {
619
620     // first potentially unbind the buffers
621     if (GrDebugGL::getInstance()->getFrameBuffer()) {
622         for (int i = 0; i < n; ++i) {
623
624             if (frameBuffers[i] ==
625                 GrDebugGL::getInstance()->getFrameBuffer()->getID()) {
626                 // this ID is the current frame buffer - rebind to the default
627                 GrDebugGL::getInstance()->setFrameBuffer(NULL);
628             }
629         }
630     }
631
632     // then actually "delete" the buffers
633     for (int i = 0; i < n; ++i) {
634         GrFrameBufferObj *buffer = GR_FIND(frameBuffers[i],
635                                            GrFrameBufferObj,
636                                            GrDebugGL::kFrameBuffer_ObjTypes);
637         GrAlwaysAssert(buffer);
638
639         GrAlwaysAssert(!buffer->getDeleted());
640         buffer->deleteAction();
641     }
642 }
643
644 GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n,
645                                                         const GrGLuint *renderBuffers) {
646
647     // first potentially unbind the buffers
648     if (GrDebugGL::getInstance()->getRenderBuffer()) {
649         for (int i = 0; i < n; ++i) {
650
651             if (renderBuffers[i] ==
652                 GrDebugGL::getInstance()->getRenderBuffer()->getID()) {
653                 // this ID is the current render buffer - make no
654                 // render buffer be bound
655                 GrDebugGL::getInstance()->setRenderBuffer(NULL);
656             }
657         }
658     }
659
660     // TODO: fuse the following block with DeleteTextures?
661     // Open GL will remove a deleted render buffer from the active frame
662     // buffer but not from any other frame buffer
663     if (GrDebugGL::getInstance()->getFrameBuffer()) {
664
665         GrFrameBufferObj *frameBuffer =
666                               GrDebugGL::getInstance()->getFrameBuffer();
667
668         for (int i = 0; i < n; ++i) {
669
670             if (NULL != frameBuffer->getColor() &&
671                 renderBuffers[i] == frameBuffer->getColor()->getID()) {
672                 frameBuffer->setColor(NULL);
673             }
674             if (NULL != frameBuffer->getDepth() &&
675                 renderBuffers[i] == frameBuffer->getDepth()->getID()) {
676                 frameBuffer->setDepth(NULL);
677             }
678             if (NULL != frameBuffer->getStencil() &&
679                 renderBuffers[i] == frameBuffer->getStencil()->getID()) {
680                 frameBuffer->setStencil(NULL);
681             }
682         }
683     }
684
685     // then actually "delete" the buffers
686     for (int i = 0; i < n; ++i) {
687         GrRenderBufferObj *buffer = GR_FIND(renderBuffers[i],
688                                             GrRenderBufferObj,
689                                             GrDebugGL::kRenderBuffer_ObjTypes);
690         GrAlwaysAssert(buffer);
691
692         // OpenGL gives no guarantees if a render buffer is deleted
693         // while attached to something other than the currently
694         // bound frame buffer
695         GrAlwaysAssert(!buffer->getColorBound());
696         GrAlwaysAssert(!buffer->getDepthBound());
697         GrAlwaysAssert(!buffer->getStencilBound());
698
699         GrAlwaysAssert(!buffer->getDeleted());
700         buffer->deleteAction();
701     }
702 }
703
704 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target,
705                                                             GrGLenum attachment,
706                                                             GrGLenum renderbuffertarget,
707                                                             GrGLuint renderBufferID) {
708
709     GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
710     GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
711                    GR_GL_DEPTH_ATTACHMENT == attachment ||
712                    GR_GL_STENCIL_ATTACHMENT == attachment);
713     GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
714
715     GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
716     // A render buffer cannot be attached to the default framebuffer
717     GrAlwaysAssert(NULL != framebuffer);
718
719     // a renderBufferID of 0 is acceptable - it unbinds the current
720     // render buffer
721     GrRenderBufferObj *renderbuffer = GR_FIND(renderBufferID,
722                                               GrRenderBufferObj,
723                                               GrDebugGL::kRenderBuffer_ObjTypes);
724
725     switch (attachment) {
726     case GR_GL_COLOR_ATTACHMENT0:
727         framebuffer->setColor(renderbuffer);
728         break;
729     case GR_GL_DEPTH_ATTACHMENT:
730         framebuffer->setDepth(renderbuffer);
731         break;
732     case GR_GL_STENCIL_ATTACHMENT:
733         framebuffer->setStencil(renderbuffer);
734         break;
735     default:
736         GrAlwaysAssert(false);
737         break;
738     };
739
740 }
741
742 ////////////////////////////////////////////////////////////////////////////////
743 GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target,
744                                                          GrGLenum attachment,
745                                                          GrGLenum textarget,
746                                                          GrGLuint textureID,
747                                                          GrGLint level) {
748
749     GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
750     GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
751                    GR_GL_DEPTH_ATTACHMENT == attachment ||
752                    GR_GL_STENCIL_ATTACHMENT == attachment);
753     GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
754
755     GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
756     // A texture cannot be attached to the default framebuffer
757     GrAlwaysAssert(NULL != framebuffer);
758
759     // A textureID of 0 is allowed - it unbinds the currently bound texture
760     GrTextureObj *texture = GR_FIND(textureID, GrTextureObj,
761                                     GrDebugGL::kTexture_ObjTypes);
762     if (texture) {
763         // The texture shouldn't be bound to a texture unit - this
764         // could lead to a feedback loop
765         GrAlwaysAssert(!texture->getBound());
766     }
767
768     GrAlwaysAssert(0 == level);
769
770     switch (attachment) {
771     case GR_GL_COLOR_ATTACHMENT0:
772         framebuffer->setColor(texture);
773         break;
774     case GR_GL_DEPTH_ATTACHMENT:
775         framebuffer->setDepth(texture);
776         break;
777     case GR_GL_STENCIL_ATTACHMENT:
778         framebuffer->setStencil(texture);
779         break;
780     default:
781         GrAlwaysAssert(false);
782         break;
783     };
784 }
785
786 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetFramebufferAttachmentParameteriv(GrGLenum target,
787                                                                         GrGLenum attachment,
788                                                                         GrGLenum pname,
789                                                                         GrGLint* params) {
790 }
791
792 GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetRenderbufferParameteriv(GrGLenum target,
793                                                                GrGLenum pname,
794                                                                GrGLint* params) {
795 }
796
797 GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorage(GrGLenum target,
798                                                         GrGLenum internalformat,
799                                                         GrGLsizei width,
800                                                         GrGLsizei height) {
801 }
802
803 GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorageMultisample(GrGLenum target,
804                                                                    GrGLsizei samples,
805                                                                    GrGLenum internalformat,
806                                                                    GrGLsizei width,
807                                                                    GrGLsizei height) {
808 }
809
810 GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlitFramebuffer(GrGLint srcX0,
811                                                     GrGLint srcY0,
812                                                     GrGLint srcX1,
813                                                     GrGLint srcY1,
814                                                     GrGLint dstX0,
815                                                    GrGLint dstY0,
816                                                    GrGLint dstX1,
817                                                    GrGLint dstY1,
818                                                    GrGLbitfield mask,
819                                                    GrGLenum filter) {
820}
821
822GrGLvoid GR_GL_FUNCTION_TYPE debugGLResolveMultisampleFramebuffer() {
823}
824
825GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocationIndexed(GrGLuint program,
826                                                                GrGLuint colorNumber,
827                                                                GrGLuint index,
828                                                                const GrGLchar * name) {
829}
830
831GrGLenum GR_GL_FUNCTION_TYPE debugGLCheckFramebufferStatus(GrGLenum target) {
832
833    GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
834
835    return GR_GL_FRAMEBUFFER_COMPLETE;
836}
837
838GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() {
839
840    GrProgramObj *program = GR_CREATE(GrProgramObj,
841                                      GrDebugGL::kProgram_ObjTypes);
842
843    return program->getID();
844}
845
846GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) {
847
848    GrAlwaysAssert(GR_GL_VERTEX_SHADER == type ||
849                   GR_GL_FRAGMENT_SHADER == type);
850
851    GrShaderObj *shader = GR_CREATE(GrShaderObj, GrDebugGL::kShader_ObjTypes);
852    shader->setType(type);
853
854    return shader->getID();
855}
856
857GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) {
858
859    GrProgramObj *program = GR_FIND(programID,
860                                    GrProgramObj,
861                                    GrDebugGL::kProgram_ObjTypes);
862    GrAlwaysAssert(program);
863
864    if (program->getRefCount()) {
865        // someone is still using this program so we can't delete it here
866        program->setMarkedForDeletion();
867    } else {
868        program->deleteAction();
869    }
870}
871
872GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) {
873
874    GrShaderObj *shader = GR_FIND(shaderID,
875                                  GrShaderObj,
876                                  GrDebugGL::kShader_ObjTypes);
877    GrAlwaysAssert(shader);
878
879    if (shader->getRefCount()) {
880        // someone is still using this shader so we can't delete it here
881        shader->setMarkedForDeletion();
882    } else {
883        shader->deleteAction();
884    }
885}
886
887// same function used for all glGen*(GLsize i, GLuint*) functions
888GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenIds(GrGLsizei n, GrGLuint* ids) {
889    static int gCurrID = 1;
890    for (int i = 0; i < n; ++i) {
891        ids[i] = ++gCurrID;
892    }
893}
894
895GrGLvoid debugGenObjs(GrDebugGL::GrObjTypes type,
896                      GrGLsizei n,
897                      GrGLuint* ids) {
898
899   for (int i = 0; i < n; ++i) {
900        GrFakeRefObj *obj = GrDebugGL::getInstance()->createObj(type);
901        GrAlwaysAssert(obj);
902        ids[i] = obj->getID();
903    }
904}
905
906GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
907
908    debugGenObjs(GrDebugGL::kBuffer_ObjTypes, n, ids);
909}
910
911GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n,
912                                                    GrGLuint* ids) {
913
914    debugGenObjs(GrDebugGL::kFrameBuffer_ObjTypes, n, ids);
915}
916
917GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n,
918                                                     GrGLuint* ids) {
919
920    debugGenObjs(GrDebugGL::kRenderBuffer_ObjTypes, n, ids);
921}
922
923GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenTextures(GrGLsizei n, GrGLuint* ids) {
924
925    debugGenObjs(GrDebugGL::kTexture_ObjTypes, n, ids);
926}
927
928// same delete function for all glDelete*(GLsize i, const GLuint*) except
929// buffers
930GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteIds(GrGLsizei n,
931                                              const GrGLuint* ids) {
932}
933
934GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target,
935                                               GrGLuint bufferID) {
936
937    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
938                   GR_GL_ELEMENT_ARRAY_BUFFER == target);
939
940    GrBufferObj *buffer = GR_FIND(bufferID,
941                                  GrBufferObj,
942                                  GrDebugGL::kBuffer_ObjTypes);
943    // 0 is a permissable bufferID - it unbinds the current buffer
944
945    switch (target) {
946        case GR_GL_ARRAY_BUFFER:
947            GrDebugGL::getInstance()->setArrayBuffer(buffer);
948            break;
949        case GR_GL_ELEMENT_ARRAY_BUFFER:
950            GrDebugGL::getInstance()->setElementArrayBuffer(buffer);
951            break;
952        default:
953            GrCrash("Unexpected target to glBindBuffer");
954            break;
955    }
956}
957
958// deleting a bound buffer has the side effect of binding 0
959GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n,
960                                                  const GrGLuint* ids) {
961    // first potentially unbind the buffers
962    for (int i = 0; i < n; ++i) {
963
964        if (GrDebugGL::getInstance()->getArrayBuffer() &&
965            ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) {
966            // this ID is the current array buffer
967            GrDebugGL::getInstance()->setArrayBuffer(NULL);
968        }
969        if (GrDebugGL::getInstance()->getElementArrayBuffer() &&
970            ids[i] ==
971                GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) {
972            // this ID is the current element array buffer
973            GrDebugGL::getInstance()->setElementArrayBuffer(NULL);
974        }
975    }
976
977    // then actually "delete" the buffers
978    for (int i = 0; i < n; ++i) {
979        GrBufferObj *buffer = GR_FIND(ids[i],
980                                      GrBufferObj,
981                                      GrDebugGL::kBuffer_ObjTypes);
982        GrAlwaysAssert(buffer);
983
984        GrAlwaysAssert(!buffer->getDeleted());
985        buffer->deleteAction();
986    }
987}
988
989// map a buffer to the caller's address space
990GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target,
991                                               GrGLenum access) {
992
993    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
994                   GR_GL_ELEMENT_ARRAY_BUFFER == target);
995    // GR_GL_READ_ONLY == access ||  || GR_GL_READ_WRIT == access);
996    GrAlwaysAssert(GR_GL_WRITE_ONLY == access);
997
998    GrBufferObj *buffer = NULL;
999    switch (target) {
1000        case GR_GL_ARRAY_BUFFER:
1001            buffer = GrDebugGL::getInstance()->getArrayBuffer();
1002            break;
1003        case GR_GL_ELEMENT_ARRAY_BUFFER:
1004            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
1005            break;
1006        default:
1007            GrCrash("Unexpected target to glMapBuffer");
1008            break;
1009    }
1010
1011    if (buffer) {
1012        GrAlwaysAssert(!buffer->getMapped());
1013        buffer->setMapped();
1014        return buffer->getDataPtr();
1015    }
1016
1017    GrAlwaysAssert(false);
1018    return NULL;        // no buffer bound to the target
1019}
1020
1021// remove a buffer from the caller's address space
1022// TODO: check if the "access" method from "glMapBuffer" was honored
1023GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) {
1024
1025    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
1026                   GR_GL_ELEMENT_ARRAY_BUFFER == target);
1027
1028    GrBufferObj *buffer = NULL;
1029    switch (target) {
1030        case GR_GL_ARRAY_BUFFER:
1031            buffer = GrDebugGL::getInstance()->getArrayBuffer();
1032            break;
1033        case GR_GL_ELEMENT_ARRAY_BUFFER:
1034            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
1035            break;
1036        default:
1037            GrCrash("Unexpected target to glUnmapBuffer");
1038            break;
1039    }
1040
1041    if (buffer) {
1042        GrAlwaysAssert(buffer->getMapped());
1043        buffer->resetMapped();
1044        return GR_GL_TRUE;
1045    }
1046
1047    GrAlwaysAssert(false);
1048    return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
1049}
1050
1051GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target,
1052                                                         GrGLenum value,
1053                                                         GrGLint* params) {
1054
1055    GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
1056                   GR_GL_ELEMENT_ARRAY_BUFFER == target);
1057    GrAlwaysAssert(GR_GL_BUFFER_SIZE == value ||
1058                   GR_GL_BUFFER_USAGE == value);
1059
1060    GrBufferObj *buffer = NULL;
1061    switch (target) {
1062        case GR_GL_ARRAY_BUFFER:
1063            buffer = GrDebugGL::getInstance()->getArrayBuffer();
1064            break;
1065        case GR_GL_ELEMENT_ARRAY_BUFFER:
1066            buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
1067            break;
1068    }
1069
1070    GrAlwaysAssert(buffer);
1071
1072    switch (value) {
1073        case GR_GL_BUFFER_MAPPED:
1074            *params = GR_GL_FALSE;
1075            if (buffer)
1076                *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
1077            break;
1078        case GR_GL_BUFFER_SIZE:
1079            *params = 0;
1080            if (buffer)
1081                *params = buffer->getSize();
1082            break;
1083        case GR_GL_BUFFER_USAGE:
1084            *params = GR_GL_STATIC_DRAW;
1085            if (buffer)
1086                *params = buffer->getUsage();
1087            break;
1088        default:
1089            GrCrash("Unexpected value to glGetBufferParamateriv");
1090            break;
1091    }
1092};
1093
1094GrGLenum GR_GL_FUNCTION_TYPE debugGLGetError() {
1095    return GR_GL_NO_ERROR;
1096}
1097
1098GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetIntegerv(GrGLenum pname,
1099                                                GrGLint* params) {
1100    // TODO: remove from Ganesh the #defines for gets we don't use.
1101    // We would like to minimize gets overall due to performance issues
1102    switch (pname) {
1103        case GR_GL_STENCIL_BITS:
1104            *params = 8;
1105            break;
1106        case GR_GL_SAMPLES:
1107            *params = 1;
1108            break;
1109        case GR_GL_FRAMEBUFFER_BINDING:
1110            *params = 0;
1111            break;
1112        case GR_GL_VIEWPORT:
1113            params[0] = 0;
1114            params[1] = 0;
1115            params[2] = 800;
1116            params[3] = 600;
1117            break;
1118        case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
1119            *params = 8;
1120            break;
1121        case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
1122            *params = kDefaultMaxVertexUniformVectors;
1123            break;
1124        case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1125            *params = kDefaultMaxFragmentUniformVectors;
1126            break;
1127        case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1128            *params = 16 * 4;
1129            break;
1130        case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1131            *params = 0;
1132            break;
1133        case GR_GL_COMPRESSED_TEXTURE_FORMATS:
1134            break;
1135        case GR_GL_MAX_TEXTURE_SIZE:
1136            *params = 8192;
1137            break;
1138        case GR_GL_MAX_RENDERBUFFER_SIZE:
1139            *params = 8192;
1140            break;
1141        case GR_GL_MAX_SAMPLES:
1142            *params = 32;
1143            break;
1144        case GR_GL_MAX_VERTEX_ATTRIBS:
1145            *params = kDefaultMaxVertexAttribs;
1146            break;
1147        case GR_GL_MAX_VARYING_VECTORS:
1148            *params = kDefaultMaxVaryingVectors;
1149            break;
1150        default:
1151            GrCrash("Unexpected pname to GetIntegerv");
1152    }
1153}
1154// used for both the program and shader info logs
1155GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetInfoLog(GrGLuint program,
1156                                               GrGLsizei bufsize,
1157                                               GrGLsizei* length,
1158                                               char* infolog) {
1159    if (length) {
1160        *length = 0;
1161    }
1162    if (bufsize > 0) {
1163        *infolog = 0;
1164    }
1165}
1166
1167// used for both the program and shader params
1168GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetShaderOrProgramiv(GrGLuint program,
1169                                                         GrGLenum pname,
1170                                                         GrGLint* params) {
1171    switch (pname) {
1172        case GR_GL_LINK_STATUS:  // fallthru
1173        case GR_GL_COMPILE_STATUS:
1174            *params = GR_GL_TRUE;
1175            break;
1176        case GR_GL_INFO_LOG_LENGTH:
1177            *params = 0;
1178            break;
1179        // we don't expect any other pnames
1180        default:
1181            GrCrash("Unexpected pname to GetProgramiv");
1182            break;
1183    }
1184}
1185
1186namespace {
1187template <typename T>
1188void query_result(GrGLenum GLtarget, GrGLenum pname, T *params) {
1189    switch (pname) {
1190        case GR_GL_QUERY_RESULT_AVAILABLE:
1191            *params = GR_GL_TRUE;
1192            break;
1193        case GR_GL_QUERY_RESULT:
1194            *params = 0;
1195            break;
1196        default:
1197            GrCrash("Unexpected pname passed to GetQueryObject.");
1198            break;
1199    }
1200}
1201}
1202
1203// Queries on the null GL just don't do anything at all. We could potentially
1204// make the timers work.
1205GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryiv(GrGLenum GLtarget,
1206                                               GrGLenum pname,
1207                                               GrGLint *params) {
1208    switch (pname) {
1209        case GR_GL_CURRENT_QUERY:
1210            *params = 0;
1211            break;
1212        case GR_GL_QUERY_COUNTER_BITS:
1213            *params = 32;
1214            break;
1215        default:
1216            GrCrash("Unexpected pname passed GetQueryiv.");
1217    }
1218}
1219
1220GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjecti64v(GrGLuint id,
1221                                                       GrGLenum pname,
1222                                                       GrGLint64 *params) {
1223    query_result(id, pname, params);
1224}
1225
1226GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectiv(GrGLuint id,
1227                                                     GrGLenum pname,
1228                                                     GrGLint *params) {
1229    query_result(id, pname, params);
1230}
1231
1232GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectui64v(GrGLuint id,
1233                                                        GrGLenum pname,
1234                                                        GrGLuint64 *params) {
1235    query_result(id, pname, params);
1236}
1237
1238GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectuiv(GrGLuint id,
1239                                                      GrGLenum pname,
1240                                                      GrGLuint *params) {
1241    query_result(id, pname, params);
1242}
1243
1244const GrGLubyte* GR_GL_FUNCTION_TYPE debugGLGetString(GrGLenum name) {
1245    switch (name) {
1246        case GR_GL_EXTENSIONS:
1247            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";
1248        case GR_GL_VERSION:
1249            return (const GrGLubyte*)"4.0 Debug GL";
1250        case GR_GL_SHADING_LANGUAGE_VERSION:
1251            return (const GrGLubyte*)"4.20.8 Debug GLSL";
1252        case GR_GL_VENDOR:
1253            return (const GrGLubyte*)"Debug Vendor";
1254        case GR_GL_RENDERER:
1255            return (const GrGLubyte*)"The Debug (Non-)Renderer";
1256        default:
1257            GrCrash("Unexpected name to GetString");
1258            return NULL;
1259    }
1260}
1261
1262// we used to use this to query stuff about externally created textures,
1263// now we just require clients to tell us everything about the texture.
1264GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetTexLevelParameteriv(GrGLenum target,
1265                                                           GrGLint level,
1266                                                           GrGLenum pname,
1267                                                           GrGLint* params) {
1268    GrCrash("Should never query texture parameters.");
1269}
1270
1271GrGLint GR_GL_FUNCTION_TYPE debugGLGetUniformLocation(GrGLuint program,
1272                                                      const char* name) {
1273    static int gUniLocation = 0;
1274    return ++gUniLocation;
1275}
1276
1277} // end of namespace
1278
1279////////////////////////////////////////////////////////////////////////////////
1280struct GrDebugGLInterface : public GrGLInterface {
1281
1282public:
1283    SK_DECLARE_INST_COUNT(GrDebugGLInterface)
1284
1285    GrDebugGLInterface()
1286        : fWrapped(NULL) {
1287        GrDebugGL::staticRef();
1288    }
1289
1290    virtual ~GrDebugGLInterface() {
1291        GrDebugGL::staticUnRef();
1292    }
1293
1294    void setWrapped(GrGLInterface *interface) {
1295        fWrapped.reset(interface);
1296    }
1297
1298    // TODO: there are some issues w/ wrapping another GL interface inside the
1299    // debug interface:
1300    //      Since none of the "gl" methods are member functions they don't get
1301    //      a "this" pointer through which to access "fWrapped"
1302    //      This could be worked around by having all of them access the
1303    //      "glInterface" pointer - i.e., treating the debug interface as a
1304    //      true singleton
1305    //
1306    //      The problem with this is that we also want to handle OpenGL
1307    //      contexts. The natural way to do this is to have multiple debug
1308    //      interfaces. Each of which represents a separate context. The
1309    //      static ID count would still uniquify IDs across all of them.
1310    //      The problem then is that we couldn't treat the debug GL
1311    //      interface as a singleton (since there would be one for each
1312    //      context).
1313    //
1314    //      The solution to this is probably to alter SkDebugGlContext's
1315    //      "makeCurrent" method to make a call like "makeCurrent(this)" to
1316    //      the debug GL interface (assuming that the application will create
1317    //      multiple SkGLContext's) to let it switch between the active
1318    //      context. Everything in the GrDebugGL object would then need to be
1319    //      moved to a GrContextObj and the GrDebugGL object would just switch
1320    //      between them. Note that this approach would also require that
1321    //      SkDebugGLContext wrap an arbitrary other context
1322    //      and then pass the wrapped interface to the debug GL interface.
1323
1324protected:
1325private:
1326
1327    SkAutoTUnref<GrGLInterface> fWrapped;
1328
1329    typedef GrGLInterface INHERITED;
1330};
1331
1332SK_DEFINE_INST_COUNT(GrDebugGLInterface)
1333
1334////////////////////////////////////////////////////////////////////////////////
1335const GrGLInterface* GrGLCreateDebugInterface() {
1336    GrGLInterface* interface = SkNEW(GrDebugGLInterface);
1337
1338    interface->fBindingsExported = kDesktop_GrGLBinding;
1339    interface->fActiveTexture = debugGLActiveTexture;
1340    interface->fAttachShader = debugGLAttachShader;
1341    interface->fBeginQuery = debugGLBeginQuery;
1342    interface->fBindAttribLocation = debugGLBindAttribLocation;
1343    interface->fBindBuffer = debugGLBindBuffer;
1344    interface->fBindFragDataLocation = debugGLBindFragDataLocation;
1345    interface->fBindTexture = debugGLBindTexture;
1346    interface->fBlendColor = debugGLBlendColor;
1347    interface->fBlendFunc = debugGLBlendFunc;
1348    interface->fBufferData = debugGLBufferData;
1349    interface->fBufferSubData = debugGLBufferSubData;
1350    interface->fClear = debugGLClear;
1351    interface->fClearColor = debugGLClearColor;
1352    interface->fClearStencil = debugGLClearStencil;
1353    interface->fColorMask = debugGLColorMask;
1354    interface->fCompileShader = debugGLCompileShader;
1355    interface->fCompressedTexImage2D = debugGLCompressedTexImage2D;
1356    interface->fCreateProgram = debugGLCreateProgram;
1357    interface->fCreateShader = debugGLCreateShader;
1358    interface->fCullFace = debugGLCullFace;
1359    interface->fDeleteBuffers = debugGLDeleteBuffers;
1360    interface->fDeleteProgram = debugGLDeleteProgram;
1361    interface->fDeleteQueries = debugGLDeleteIds;
1362    interface->fDeleteShader = debugGLDeleteShader;
1363    interface->fDeleteTextures = debugGLDeleteTextures;
1364    interface->fDepthMask = debugGLDepthMask;
1365    interface->fDisable = debugGLDisable;
1366    interface->fDisableVertexAttribArray = debugGLDisableVertexAttribArray;
1367    interface->fDrawArrays = debugGLDrawArrays;
1368    interface->fDrawBuffer = debugGLDrawBuffer;
1369    interface->fDrawBuffers = debugGLDrawBuffers;
1370    interface->fDrawElements = debugGLDrawElements;
1371    interface->fEnable = debugGLEnable;
1372    interface->fEnableVertexAttribArray = debugGLEnableVertexAttribArray;
1373    interface->fEndQuery = debugGLEndQuery;
1374    interface->fFinish = debugGLFinish;
1375    interface->fFlush = debugGLFlush;
1376    interface->fFrontFace = debugGLFrontFace;
1377    interface->fGenBuffers = debugGLGenBuffers;
1378    interface->fGenQueries = debugGLGenIds;
1379    interface->fGenTextures = debugGLGenTextures;
1380    interface->fGetBufferParameteriv = debugGLGetBufferParameteriv;
1381    interface->fGetError = debugGLGetError;
1382    interface->fGetIntegerv = debugGLGetIntegerv;
1383    interface->fGetQueryObjecti64v = debugGLGetQueryObjecti64v;
1384    interface->fGetQueryObjectiv = debugGLGetQueryObjectiv;
1385    interface->fGetQueryObjectui64v = debugGLGetQueryObjectui64v;
1386    interface->fGetQueryObjectuiv = debugGLGetQueryObjectuiv;
1387    interface->fGetQueryiv = debugGLGetQueryiv;
1388    interface->fGetProgramInfoLog = debugGLGetInfoLog;
1389    interface->fGetProgramiv = debugGLGetShaderOrProgramiv;
1390    interface->fGetShaderInfoLog = debugGLGetInfoLog;
1391    interface->fGetShaderiv = debugGLGetShaderOrProgramiv;
1392    interface->fGetString = debugGLGetString;
1393    interface->fGetTexLevelParameteriv = debugGLGetTexLevelParameteriv;
1394    interface->fGetUniformLocation = debugGLGetUniformLocation;
1395    interface->fLineWidth = debugGLLineWidth;
1396    interface->fLinkProgram = debugGLLinkProgram;
1397    interface->fPixelStorei = debugGLPixelStorei;
1398    interface->fQueryCounter = debugGLQueryCounter;
1399    interface->fReadBuffer = debugGLReadBuffer;
1400    interface->fReadPixels = debugGLReadPixels;
1401    interface->fScissor = debugGLScissor;
1402    interface->fShaderSource = debugGLShaderSource;
1403    interface->fStencilFunc = debugGLStencilFunc;
1404    interface->fStencilFuncSeparate = debugGLStencilFuncSeparate;
1405    interface->fStencilMask = debugGLStencilMask;
1406    interface->fStencilMaskSeparate = debugGLStencilMaskSeparate;
1407    interface->fStencilOp = debugGLStencilOp;
1408    interface->fStencilOpSeparate = debugGLStencilOpSeparate;
1409    interface->fTexImage2D = debugGLTexImage2D;
1410    interface->fTexParameteri = debugGLTexParameteri;
1411    interface->fTexParameteriv = debugGLTexParameteriv;
1412    interface->fTexSubImage2D = debugGLTexSubImage2D;
1413    interface->fTexStorage2D = debugGLTexStorage2D;
1414    interface->fUniform1f = debugGLUniform1f;
1415    interface->fUniform1i = debugGLUniform1i;
1416    interface->fUniform1fv = debugGLUniform1fv;
1417    interface->fUniform1iv = debugGLUniform1iv;
1418    interface->fUniform2f = debugGLUniform2f;
1419    interface->fUniform2i = debugGLUniform2i;
1420    interface->fUniform2fv = debugGLUniform2fv;
1421    interface->fUniform2iv = debugGLUniform2iv;
1422    interface->fUniform3f = debugGLUniform3f;
1423    interface->fUniform3i = debugGLUniform3i;
1424    interface->fUniform3fv = debugGLUniform3fv;
1425    interface->fUniform3iv = debugGLUniform3iv;
1426    interface->fUniform4f = debugGLUniform4f;
1427    interface->fUniform4i = debugGLUniform4i;
1428    interface->fUniform4fv = debugGLUniform4fv;
1429    interface->fUniform4iv = debugGLUniform4iv;
1430    interface->fUniformMatrix2fv = debugGLUniformMatrix2fv;
1431    interface->fUniformMatrix3fv = debugGLUniformMatrix3fv;
1432    interface->fUniformMatrix4fv = debugGLUniformMatrix4fv;
1433    interface->fUseProgram = debugGLUseProgram;
1434    interface->fVertexAttrib4fv = debugGLVertexAttrib4fv;
1435    interface->fVertexAttribPointer = debugGLVertexAttribPointer;
1436    interface->fViewport = debugGLViewport;
1437    interface->fBindFramebuffer = debugGLBindFramebuffer;
1438    interface->fBindRenderbuffer = debugGLBindRenderbuffer;
1439    interface->fCheckFramebufferStatus = debugGLCheckFramebufferStatus;
1440    interface->fDeleteFramebuffers = debugGLDeleteFramebuffers;
1441    interface->fDeleteRenderbuffers = debugGLDeleteRenderbuffers;
1442    interface->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer;
1443    interface->fFramebufferTexture2D = debugGLFramebufferTexture2D;
1444    interface->fGenFramebuffers = debugGLGenFramebuffers;
1445    interface->fGenRenderbuffers = debugGLGenRenderbuffers;
1446    interface->fGetFramebufferAttachmentParameteriv =
1447                                    debugGLGetFramebufferAttachmentParameteriv;
1448    interface->fGetRenderbufferParameteriv = debugGLGetRenderbufferParameteriv;
1449    interface->fRenderbufferStorage = debugGLRenderbufferStorage;
1450    interface->fRenderbufferStorageMultisample =
1451                                    debugGLRenderbufferStorageMultisample;
1452    interface->fBlitFramebuffer = debugGLBlitFramebuffer;
1453    interface->fResolveMultisampleFramebuffer =
1454                                    debugGLResolveMultisampleFramebuffer;
1455    interface->fMapBuffer = debugGLMapBuffer;
1456    interface->fUnmapBuffer = debugGLUnmapBuffer;
1457    interface->fBindFragDataLocationIndexed =
1458                                    debugGLBindFragDataLocationIndexed;
1459
1460    return interface;
1461}
1462