blob: 022cc56fb8e79ab25199f0895bbb540305222676 [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"
11
12#include "SkTArray.h"
robertphillips@google.com7c959422012-03-22 20:43:56 +000013#include "SkTDArray.h"
robertphillips@google.com0da37192012-03-19 14:42:13 +000014
15// the OpenGLES 2.0 spec says this must be >= 2
16static const GrGLint kDefaultMaxTextureUnits = 8;
17
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000018// the OpenGLES 2.0 spec says this must be >= 128
19static const GrGLint kDefaultMaxVertexUniformVectors = 128;
20
21// the OpenGLES 2.0 spec says this must be >=16
22static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
23
24// the OpenGLES 2.0 spec says this must be >= 8
25static const GrGLint kDefaultMaxVertexAttribs = 8;
26
27// the OpenGLES 2.0 spec says this must be >= 8
28static const GrGLint kDefaultMaxVaryingVectors = 8;
29
robertphillips@google.com0da37192012-03-19 14:42:13 +000030////////////////////////////////////////////////////////////////////////////////
31// This object is used to track the OpenGL objects. We don't use real
32// reference counting (i.e., we don't free the objects when their ref count
33// goes to 0) so that we can detect invalid memory accesses. The refs we
34// are tracking in this class are actually OpenGL's references to the objects
35// not "ours"
36// Each object also gets a unique globally identifying ID
37class GrFakeRefObj
38{
39public:
40 GrFakeRefObj(GrGLuint ID)
41 : fRef(0)
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000042 , fHighRefCount(0)
robertphillips@google.com0da37192012-03-19 14:42:13 +000043 , fID(ID)
44 , fMarkedForDeletion(false)
45 , fDeleted(false) {
46 }
47 virtual ~GrFakeRefObj() {};
48
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000049 void ref() {
50 fRef++;
51 if (fHighRefCount < fRef) {
52 fHighRefCount = fRef;
53 }
54 }
robertphillips@google.com0da37192012-03-19 14:42:13 +000055 void unref() {
56 fRef--;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000057 GrAlwaysAssert(fRef >= 0);
58
robertphillips@google.com0da37192012-03-19 14:42:13 +000059 // often in OpenGL a given object may still be in use when the
60 // delete call is made. In these cases the object is marked
61 // for deletion and then freed when it is no longer in use
62 if (0 == fRef && fMarkedForDeletion) {
63 this->deleteAction();
64 }
65 }
66 int getRefCount() const { return fRef; }
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000067 int getHighRefCount() const { return fHighRefCount; }
robertphillips@google.com0da37192012-03-19 14:42:13 +000068
69 GrGLuint getID() const { return fID; }
70
71 void setMarkedForDeletion() { fMarkedForDeletion = true; }
72 bool getMarkedForDeletion() const { return fMarkedForDeletion; }
73
74 // setDeleted should only ever appear in deleteAction methods!
75 void setDeleted() { fDeleted = true; }
76 bool getDeleted() const { return fDeleted; }
77
78 // The deleteAction fires if the object has been marked for deletion but
79 // couldn't be deleted earlier due to refs
80 virtual void deleteAction() = 0;
81
82protected:
83private:
84 int fRef;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000085 int fHighRefCount; // high water mark of the ref count
robertphillips@google.com0da37192012-03-19 14:42:13 +000086 GrGLuint fID;
87 bool fMarkedForDeletion;
88 // The deleted flag is only set when OpenGL thinks the object is deleted
89 // It is obviously still allocated w/in this framework
90 bool fDeleted;
91};
92
93////////////////////////////////////////////////////////////////////////////////
94class GrBufferObj : public GrFakeRefObj
95{
96public:
97 GrBufferObj(GrGLuint ID)
98 : GrFakeRefObj(ID)
99 , fDataPtr(NULL)
100 , fMapped(false)
101 , fBound(false)
102 , fSize(0)
103 , fUsage(GR_GL_STATIC_DRAW) {
104 }
105 virtual ~GrBufferObj() {
106 delete[] fDataPtr;
107 }
108
109 void access() {
110 // cannot access the buffer if it is currently mapped
111 GrAlwaysAssert(!fMapped);
112 }
113
114 void setMapped() { fMapped = true; }
115 void resetMapped() { fMapped = false; }
116 bool getMapped() const { return fMapped; }
117
118 void setBound() { fBound = true; }
119 void resetBound() { fBound = false; }
120 bool getBound() const { return fBound; }
121
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000122 void allocate(GrGLint size, const GrGLchar *dataPtr) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000123 GrAlwaysAssert(size >= 0);
124
125 // delete pre-existing data
robertphillips@google.com69705572012-03-21 19:46:50 +0000126 delete[] fDataPtr;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000127
128 fSize = size;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000129 fDataPtr = new GrGLchar[size];
robertphillips@google.com0da37192012-03-19 14:42:13 +0000130 if (dataPtr) {
131 memcpy(fDataPtr, dataPtr, fSize);
132 }
133 // TODO: w/ no dataPtr the data is unitialized - this could be tracked
134 }
135 GrGLint getSize() const { return fSize; }
robertphillips@google.com69705572012-03-21 19:46:50 +0000136 GrGLchar *getDataPtr() { return fDataPtr; }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000137
138 GrGLint getUsage() const { return fUsage; }
139 void setUsage(GrGLint usage) { fUsage = usage; }
140
141 virtual void deleteAction() SK_OVERRIDE {
142
143 // buffers are automatically unmapped when deleted
144 this->resetMapped();
145 this->setDeleted();
146 }
147
148
149protected:
150private:
151
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000152 GrGLchar* fDataPtr;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000153 bool fMapped; // is the buffer object mapped via "glMapBuffer"?
154 bool fBound; // is the buffer object bound via "glBindBuffer"?
155 GrGLint fSize; // size in bytes
156 GrGLint fUsage; // one of: GL_STREAM_DRAW, GL_STATIC_DRAW, GL_DYNAMIC_DRAW
157
158 typedef GrFakeRefObj INHERITED;
159};
160
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000161////////////////////////////////////////////////////////////////////////////////
robertphillips@google.com7c959422012-03-22 20:43:56 +0000162class GrRenderBufferObj : public GrFakeRefObj
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000163{
164public:
robertphillips@google.com7c959422012-03-22 20:43:56 +0000165 GrRenderBufferObj(GrGLuint ID)
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000166 : GrFakeRefObj(ID)
167 , fBound(false) {
168 }
169
robertphillips@google.com7c959422012-03-22 20:43:56 +0000170 virtual ~GrRenderBufferObj() {
171 GrAlwaysAssert(0 == fColorReferees.count());
172 GrAlwaysAssert(0 == fDepthReferees.count());
173 GrAlwaysAssert(0 == fStencilReferees.count());
174 }
175
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000176 void setBound() { fBound = true; }
177 void resetBound() { fBound = false; }
178 bool getBound() const { return fBound; }
179
robertphillips@google.com7c959422012-03-22 20:43:56 +0000180 void setColorBound(GrFakeRefObj *referee) {
181 fColorReferees.append(1, &referee);
182 }
183 void resetColorBound(GrFakeRefObj *referee) {
184 int index = fColorReferees.find(referee);
185 GrAlwaysAssert(0 <= index);
186 fColorReferees.removeShuffle(index);
187 }
188 bool getColorBound(GrFakeRefObj *referee) const {
189 int index = fColorReferees.find(referee);
190 return 0 <= index;
191 }
192 bool getColorBound() const {
193 return 0 != fColorReferees.count();
194 }
195
196 void setDepthBound(GrFakeRefObj *referee) {
197 fDepthReferees.append(1, &referee);
198 }
199 void resetDepthBound(GrFakeRefObj *referee) {
200 int index = fDepthReferees.find(referee);
201 GrAlwaysAssert(0 <= index);
202 fDepthReferees.removeShuffle(index);
203 }
204 bool getDepthBound(GrFakeRefObj *referee) const {
205 int index = fDepthReferees.find(referee);
206 return 0 <= index;
207 }
208 bool getDepthBound() const {
209 return 0 != fDepthReferees.count();
210 }
211
212 void setStencilBound(GrFakeRefObj *referee) {
213 fStencilReferees.append(1, &referee);
214 }
215 void resetStencilBound(GrFakeRefObj *referee) {
216 int index = fStencilReferees.find(referee);
217 GrAlwaysAssert(0 <= index);
218 fStencilReferees.removeShuffle(index);
219 }
220 bool getStencilBound(GrFakeRefObj *referee) const {
221 int index = fStencilReferees.find(referee);
222 return 0 <= index;
223 }
224 bool getStencilBound() const {
225 return 0 != fStencilReferees.count();
226 }
227
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000228 virtual void deleteAction() SK_OVERRIDE {
229
230 this->setDeleted();
231 }
232
233protected:
234private:
robertphillips@google.com7c959422012-03-22 20:43:56 +0000235 bool fBound; // is this render buffer currently bound via "glBindRenderbuffer"?
236
237 SkTDArray<GrFakeRefObj *> fColorReferees; // frame buffers that use this as a color buffer (via "glFramebufferRenderbuffer")
238 SkTDArray<GrFakeRefObj *> fDepthReferees; // frame buffers that use this as a depth buffer (via "glFramebufferRenderbuffer")
239 SkTDArray<GrFakeRefObj *> fStencilReferees; // frame buffers that use this as a stencil buffer (via "glFramebufferRenderbuffer")
240
241 typedef GrFakeRefObj INHERITED;
242};
243
244////////////////////////////////////////////////////////////////////////////////
245// TODO: when a framebuffer obj is bound the GL_SAMPLES query must return 0
246// TODO: GL_STENCIL_BITS must also be redirected to the framebuffer
247class GrFrameBufferObj : public GrFakeRefObj
248{
249public:
250 GrFrameBufferObj(GrGLuint ID)
251 : GrFakeRefObj(ID)
252 , fBound(false)
253 , fColorBuffer(NULL)
254 , fDepthBuffer(NULL)
255 , fStencilBuffer(NULL) {
256 }
257
258 virtual ~GrFrameBufferObj() {
259 fColorBuffer = NULL;
260 fDepthBuffer = NULL;
261 fStencilBuffer = NULL;
262 }
263
264 void setBound() { fBound = true; }
265 void resetBound() { fBound = false; }
266 bool getBound() const { return fBound; }
267
268 void setColor(GrRenderBufferObj *buffer) {
269 if (fColorBuffer) {
270 // automatically break the binding of the old buffer
271 GrAlwaysAssert(fColorBuffer->getColorBound(this));
272 fColorBuffer->resetColorBound(this);
273
274 GrAlwaysAssert(!fColorBuffer->getDeleted());
275 fColorBuffer->unref();
276 }
277 fColorBuffer = buffer;
278 if (fColorBuffer) {
279 GrAlwaysAssert(!fColorBuffer->getDeleted());
280 fColorBuffer->ref();
281
282 GrAlwaysAssert(!fColorBuffer->getColorBound(this));
283 fColorBuffer->setColorBound(this);
284 }
285 }
286 GrRenderBufferObj *getColor() { return fColorBuffer; }
287
288 void setDepth(GrRenderBufferObj *buffer) {
289 if (fDepthBuffer) {
290 // automatically break the binding of the old buffer
291 GrAlwaysAssert(fDepthBuffer->getDepthBound(this));
292 fDepthBuffer->resetDepthBound(this);
293
294 GrAlwaysAssert(!fDepthBuffer->getDeleted());
295 fDepthBuffer->unref();
296 }
297 fDepthBuffer = buffer;
298 if (fDepthBuffer) {
299 GrAlwaysAssert(!fDepthBuffer->getDeleted());
300 fDepthBuffer->ref();
301
302 GrAlwaysAssert(!fDepthBuffer->getDepthBound(this));
303 fDepthBuffer->setDepthBound(this);
304 }
305 }
306 GrRenderBufferObj *getDepth() { return fDepthBuffer; }
307
308 void setStencil(GrRenderBufferObj *buffer) {
309 if (fStencilBuffer) {
310 // automatically break the binding of the old buffer
311 GrAlwaysAssert(fStencilBuffer->getStencilBound(this));
312 fStencilBuffer->resetStencilBound(this);
313
314 GrAlwaysAssert(!fStencilBuffer->getDeleted());
315 fStencilBuffer->unref();
316 }
317 fStencilBuffer = buffer;
318 if (fStencilBuffer) {
319 GrAlwaysAssert(!fStencilBuffer->getDeleted());
320 fStencilBuffer->ref();
321
322 GrAlwaysAssert(!fStencilBuffer->getStencilBound(this));
323 fStencilBuffer->setStencilBound(this);
324 }
325 }
326 GrRenderBufferObj *getStencil() { return fStencilBuffer; }
327
328 virtual void deleteAction() SK_OVERRIDE {
329
330 setColor(NULL);
331 setDepth(NULL);
332 setStencil(NULL);
333 this->setDeleted();
334 }
335
336protected:
337private:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000338 bool fBound; // is this frame buffer currently bound via "glBindFramebuffer"?
robertphillips@google.com7c959422012-03-22 20:43:56 +0000339 GrRenderBufferObj * fColorBuffer;
340 GrRenderBufferObj * fDepthBuffer;
341 GrRenderBufferObj * fStencilBuffer;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000342
343 typedef GrFakeRefObj INHERITED;
344};
robertphillips@google.com0da37192012-03-19 14:42:13 +0000345
346////////////////////////////////////////////////////////////////////////////////
347class GrShaderObj : public GrFakeRefObj
348{
349public:
350 GrShaderObj(GrGLuint ID, GrGLenum type)
351 : GrFakeRefObj(ID)
352 , fType(type) {}
353
354 GrGLenum getType() { return fType; }
355
356 virtual void deleteAction() SK_OVERRIDE {
357
358 this->setDeleted();
359 }
360
361protected:
362private:
363 GrGLenum fType; // either GR_GL_VERTEX_SHADER or GR_GL_FRAGMENT_SHADER
364
365 typedef GrFakeRefObj INHERITED;
366};
367
368
369////////////////////////////////////////////////////////////////////////////////
370class GrProgramObj : public GrFakeRefObj
371{
372public:
373 GrProgramObj(GrGLuint ID)
374 : GrFakeRefObj(ID)
375 , fInUse(false) {}
376
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000377 void AttachShader(GrShaderObj *shader) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000378 shader->ref();
379 fShaders.push_back(shader);
380 }
381
382 virtual void deleteAction() SK_OVERRIDE {
383
384 // shaders are automatically detached from a deleted program. They will only be
385 // deleted if they were marked for deletion by a prior call to glDeleteShader
386 for (int i = 0; i < fShaders.count(); ++i) {
387 fShaders[i]->unref();
388 }
389 fShaders.reset();
390
391 this->setDeleted();
392 }
393
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000394 // TODO: this flag system won't work w/ multiple contexts!
robertphillips@google.com0da37192012-03-19 14:42:13 +0000395 void setInUse() { fInUse = true; }
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000396 void resetInUse() { fInUse = false; }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000397 bool getInUse() const { return fInUse; }
398
399protected:
400
401private:
402 SkTArray<GrShaderObj *> fShaders;
403 bool fInUse; // has this program been activated by a glUseProgram call?
404
405 typedef GrFakeRefObj INHERITED;
406};
407
408////////////////////////////////////////////////////////////////////////////////
409// This is the main debugging object. It is a singleton and keeps track of
410// all the other debug objects.
411class GrDebugGL
412{
413public:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000414 // TODO: merge findBuffer, findFrameBuffer, findShader & findProgram??
415 GrBufferObj *findBuffer(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000416 GrFakeRefObj *obj = this->findObject(ID);
417 if (NULL == obj) {
418 return NULL;
419 }
420
421 return reinterpret_cast<GrBufferObj *>(obj);
422 }
423
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000424 GrFrameBufferObj *findFrameBuffer(GrGLuint ID) {
425 GrFakeRefObj *obj = this->findObject(ID);
426 if (NULL == obj) {
427 return NULL;
428 }
429
430 return reinterpret_cast<GrFrameBufferObj *>(obj);
431 }
432
robertphillips@google.com7c959422012-03-22 20:43:56 +0000433 GrRenderBufferObj *findRenderBuffer(GrGLuint ID) {
434 GrFakeRefObj *obj = this->findObject(ID);
435 if (NULL == obj) {
436 return NULL;
437 }
438
439 return reinterpret_cast<GrRenderBufferObj *>(obj);
440 }
441
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000442 GrShaderObj *findShader(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000443 GrFakeRefObj *obj = this->findObject(ID);
444 if (NULL == obj) {
445 return NULL;
446 }
447
448 return reinterpret_cast<GrShaderObj *>(obj);
449 }
450
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000451 GrProgramObj *findProgram(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000452 GrFakeRefObj *obj = this->findObject(ID);
453 if (NULL == obj) {
454 return NULL;
455 }
456
457 return reinterpret_cast<GrProgramObj *>(obj);
458 }
459
460 // TODO: merge createBuffer, createShader, createProgram??
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000461 GrBufferObj *createBuffer() {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000462 GrBufferObj *buffer = new GrBufferObj(++fNextID);
463
464 fObjects.push_back(buffer);
465
466 return buffer;
467 }
468
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000469 GrFrameBufferObj *createFrameBuffer() {
470 GrFrameBufferObj *buffer = new GrFrameBufferObj(++fNextID);
471
472 fObjects.push_back(buffer);
473
474 return buffer;
475 }
476
robertphillips@google.com7c959422012-03-22 20:43:56 +0000477 GrRenderBufferObj *createRenderBuffer() {
478 GrRenderBufferObj *buffer = new GrRenderBufferObj(++fNextID);
479
480 fObjects.push_back(buffer);
481
482 return buffer;
483 }
484
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000485 GrShaderObj *createShader(GrGLenum type) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000486 GrShaderObj *shader = new GrShaderObj(++fNextID, type);
487
488 fObjects.push_back(shader);
489
490 return shader;
491 }
492
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000493 GrProgramObj *createProgram() {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000494 GrProgramObj *program = new GrProgramObj(++fNextID);
495
496 fObjects.push_back(program);
497
498 return program;
499 }
500
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000501 GrFakeRefObj *findObject(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000502 for (int i = 0; i < fObjects.count(); ++i) {
503 if (fObjects[i]->getID() == ID) {
504 // The application shouldn't be accessing objects
505 // that (as far as OpenGL knows) were already deleted
506 GrAlwaysAssert(!fObjects[i]->getDeleted());
507 GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion());
508 return fObjects[i];
509 }
510 }
511
512 return NULL;
513 }
514
515
516 void setMaxTextureUnits(GrGLuint maxTextureUnits) { fMaxTextureUnits = maxTextureUnits; }
517 GrGLuint getMaxTextureUnits() const { return fMaxTextureUnits; }
518
519 void setCurTextureUnit(GrGLuint curTextureUnit) { fCurTextureUnit = curTextureUnit; }
520 GrGLuint getCurTextureUnit() const { return fCurTextureUnit; }
521
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000522 void setArrayBuffer(GrBufferObj *arrayBuffer) {
523 if (fArrayBuffer) {
524 // automatically break the binding of the old buffer
525 GrAlwaysAssert(fArrayBuffer->getBound());
526 fArrayBuffer->resetBound();
527
528 GrAlwaysAssert(!fArrayBuffer->getDeleted());
529 fArrayBuffer->unref();
530 }
531
532 fArrayBuffer = arrayBuffer;
533
534 if (fArrayBuffer) {
535 GrAlwaysAssert(!fArrayBuffer->getDeleted());
536 fArrayBuffer->ref();
537
538 GrAlwaysAssert(!fArrayBuffer->getBound());
539 fArrayBuffer->setBound();
540 }
541 }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000542 GrBufferObj *getArrayBuffer() { return fArrayBuffer; }
543
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000544 void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
545 if (fElementArrayBuffer) {
546 // automatically break the binding of the old buffer
547 GrAlwaysAssert(fElementArrayBuffer->getBound());
548 fElementArrayBuffer->resetBound();
549
550 GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
551 fElementArrayBuffer->unref();
552 }
553
554 fElementArrayBuffer = elementArrayBuffer;
555
556 if (fElementArrayBuffer) {
557 GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
558 fElementArrayBuffer->ref();
559
560 GrAlwaysAssert(!fElementArrayBuffer->getBound());
561 fElementArrayBuffer->setBound();
562 }
563 }
564
robertphillips@google.com0da37192012-03-19 14:42:13 +0000565 GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
566
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000567 void setFrameBuffer(GrFrameBufferObj *frameBuffer) {
robertphillips@google.com7c959422012-03-22 20:43:56 +0000568 if (fFrameBuffer) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000569 GrAlwaysAssert(fFrameBuffer->getBound());
570 fFrameBuffer->resetBound();
571
572 GrAlwaysAssert(!fFrameBuffer->getDeleted());
573 fFrameBuffer->unref();
574 }
575
576 fFrameBuffer = frameBuffer;
577
robertphillips@google.com7c959422012-03-22 20:43:56 +0000578 if (fFrameBuffer) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000579 GrAlwaysAssert(!fFrameBuffer->getDeleted());
580 fFrameBuffer->ref();
581
582 GrAlwaysAssert(!fFrameBuffer->getBound());
583 fFrameBuffer->setBound();
584 }
585 }
586
587 GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
588
robertphillips@google.com7c959422012-03-22 20:43:56 +0000589 void setRenderBuffer(GrRenderBufferObj *renderBuffer) {
590 if (fRenderBuffer) {
591 GrAlwaysAssert(fRenderBuffer->getBound());
592 fRenderBuffer->resetBound();
593
594 GrAlwaysAssert(!fRenderBuffer->getDeleted());
595 fRenderBuffer->unref();
596 }
597
598 fRenderBuffer = renderBuffer;
599
600 if (fRenderBuffer) {
601 GrAlwaysAssert(!fRenderBuffer->getDeleted());
602 fRenderBuffer->ref();
603
604 GrAlwaysAssert(!fRenderBuffer->getBound());
605 fRenderBuffer->setBound();
606 }
607 }
608
609 GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
610
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000611 void useProgram(GrProgramObj *program) {
612 if (fProgram) {
613 GrAlwaysAssert(fProgram->getInUse());
614 fProgram->resetInUse();
615
616 GrAlwaysAssert(!fProgram->getDeleted());
617 fProgram->unref();
618 }
619
620 fProgram = program;
621
robertphillips@google.com7c959422012-03-22 20:43:56 +0000622 if (fProgram) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000623 GrAlwaysAssert(!fProgram->getDeleted());
624 fProgram->ref();
625
626 GrAlwaysAssert(!fProgram->getInUse());
627 fProgram->setInUse();
628 }
629 }
630
631 static GrDebugGL *getInstance() {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000632// static GrDebugGL Obj;
633
634 return &Obj;
635 }
636
637 void report() const {
638 for (int i = 0; i < fObjects.count(); ++i) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000639 GrAlwaysAssert(0 == fObjects[i]->getRefCount());
640 GrAlwaysAssert(0 < fObjects[i]->getHighRefCount());
robertphillips@google.com0da37192012-03-19 14:42:13 +0000641 GrAlwaysAssert(fObjects[i]->getDeleted());
642 }
643 }
644
645protected:
646
647private:
648 GrGLuint fMaxTextureUnits;
649 GrGLuint fCurTextureUnit;
650 GrBufferObj * fArrayBuffer;
651 GrBufferObj * fElementArrayBuffer;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000652 GrFrameBufferObj *fFrameBuffer;
robertphillips@google.com7c959422012-03-22 20:43:56 +0000653 GrRenderBufferObj *fRenderBuffer;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000654 GrProgramObj * fProgram;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000655
656 static int fNextID; // source for globally unique IDs
657
658 static GrDebugGL Obj;
659
660 // global store of all objects
661 SkTArray<GrFakeRefObj *> fObjects;
662
663 GrDebugGL()
664 : fMaxTextureUnits(kDefaultMaxTextureUnits)
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000665 , fCurTextureUnit(0)
666 , fArrayBuffer(NULL)
667 , fElementArrayBuffer(NULL)
668 , fFrameBuffer(NULL)
robertphillips@google.com7c959422012-03-22 20:43:56 +0000669 , fRenderBuffer(NULL)
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000670 , fProgram(NULL) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000671 }
672
673 ~GrDebugGL() {
674 this->report();
675
676 for (int i = 0; i < fObjects.count(); ++i) {
677 delete fObjects[i];
678 }
679 fObjects.reset();
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000680
robertphillips@google.com0da37192012-03-19 14:42:13 +0000681 fArrayBuffer = NULL;
682 fElementArrayBuffer = NULL;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000683 fFrameBuffer = NULL;
robertphillips@google.com7c959422012-03-22 20:43:56 +0000684 fRenderBuffer = NULL;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000685 fProgram = NULL;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000686 }
687};
688
689int GrDebugGL::fNextID = 0;
690GrDebugGL GrDebugGL::Obj;
691
692////////////////////////////////////////////////////////////////////////////////
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000693GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) {
robertphillips@google.comd41a1dc2012-03-19 17:33:58 +0000694
robertphillips@google.com69705572012-03-21 19:46:50 +0000695// GrAlwaysAssert(0 <= texture);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000696// GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits());
697
698 GrDebugGL::getInstance()->setCurTextureUnit(texture);
699}
700
701////////////////////////////////////////////////////////////////////////////////
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000702GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, GrGLuint shaderID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000703 GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID);
704 GrAlwaysAssert(program);
705
706 GrShaderObj *shader = GrDebugGL::getInstance()->findShader(shaderID);
707 GrAlwaysAssert(shader);
708
709 program->AttachShader(shader);
710}
711
712GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) {}
713GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
714GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, GrGLuint texture) {}
715GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
716GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocation(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name) {}
717GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendFunc(GrGLenum sfactor, GrGLenum dfactor) {}
718
719////////////////////////////////////////////////////////////////////////////////
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000720GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, GrGLenum usage) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000721 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
722 GrAlwaysAssert(size >= 0);
723 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || GR_GL_STATIC_DRAW == usage || GR_GL_DYNAMIC_DRAW == usage);
724
725 GrBufferObj *buffer = NULL;
726 switch (target) {
727 case GR_GL_ARRAY_BUFFER:
728 buffer = GrDebugGL::getInstance()->getArrayBuffer();
729 break;
730 case GR_GL_ELEMENT_ARRAY_BUFFER:
731 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
732 break;
733 default:
734 GrCrash("Unexpected target to glBufferData");
735 break;
736 }
737
738 GrAlwaysAssert(buffer);
739 GrAlwaysAssert(buffer->getBound());
740
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000741 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
robertphillips@google.com0da37192012-03-19 14:42:13 +0000742 buffer->setUsage(usage);
743}
744
745GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferSubData(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data) {}
746GrGLvoid GR_GL_FUNCTION_TYPE debugGLClear(GrGLbitfield mask) {}
747GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
748GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearStencil(GrGLint s) {}
749GrGLvoid GR_GL_FUNCTION_TYPE debugGLColorMask(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha) {}
750GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompileShader(GrGLuint shader) {}
751GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompressedTexImage2D(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data) {}
752GrGLvoid GR_GL_FUNCTION_TYPE debugGLCullFace(GrGLenum mode) {}
753GrGLvoid GR_GL_FUNCTION_TYPE debugGLDepthMask(GrGLboolean flag) {}
754GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisable(GrGLenum cap) {}
755GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisableVertexAttribArray(GrGLuint index) {}
756GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawArrays(GrGLenum mode, GrGLint first, GrGLsizei count) {}
757GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffer(GrGLenum mode) {}
758GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffers(GrGLsizei n, const GrGLenum* bufs) {}
759GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
760GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnable(GrGLenum cap) {}
761GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnableVertexAttribArray(GrGLuint index) {}
762GrGLvoid GR_GL_FUNCTION_TYPE debugGLEndQuery(GrGLenum target) {}
763GrGLvoid GR_GL_FUNCTION_TYPE debugGLFinish() {}
764GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlush() {}
765GrGLvoid GR_GL_FUNCTION_TYPE debugGLFrontFace(GrGLenum mode) {}
766GrGLvoid GR_GL_FUNCTION_TYPE debugGLLineWidth(GrGLfloat width) {}
767GrGLvoid GR_GL_FUNCTION_TYPE debugGLLinkProgram(GrGLuint program) {}
768GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, GrGLint param) {}
769GrGLvoid GR_GL_FUNCTION_TYPE debugGLQueryCounter(GrGLuint id, GrGLenum target) {}
770GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadBuffer(GrGLenum src) {}
771GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
772GrGLvoid GR_GL_FUNCTION_TYPE debugGLScissor(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
773GrGLvoid GR_GL_FUNCTION_TYPE debugGLShaderSource(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length) {}
774GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {}
775GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFuncSeparate(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask) {}
776GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMask(GrGLuint mask) {}
777GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMaskSeparate(GrGLenum face, GrGLuint mask) {}
778GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOp(GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
779GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOpSeparate(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
780GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexImage2D(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
781GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexParameteri(GrGLenum target, GrGLenum pname, GrGLint param) {}
782GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexStorage2D(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
783GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
784GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1f(GrGLint location, GrGLfloat v0) {}
785GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1i(GrGLint location, GrGLint v0) {}
786GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
787GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
788GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2f(GrGLint location, GrGLfloat v0, GrGLfloat v1) {}
789GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2i(GrGLint location, GrGLint v0, GrGLint v1) {}
790GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
791GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
792GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) {}
793GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {}
794GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
795GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
796GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3) {}
797GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {}
798GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
799GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
800GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix2fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
801GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix3fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
802GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix4fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
803
804GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) {
805
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000806 // A programID of 0 is legal
robertphillips@google.com0da37192012-03-19 14:42:13 +0000807 GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000808
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000809 GrDebugGL::getInstance()->useProgram(program);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000810}
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000811
robertphillips@google.com0da37192012-03-19 14:42:13 +0000812GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {}
813GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttribPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr) {}
814GrGLvoid GR_GL_FUNCTION_TYPE debugGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000815
816GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, GrGLuint frameBufferID) {
817
818 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
819
820 // a frameBufferID of 0 is acceptable - it binds to the default frame buffer
robertphillips@google.com7c959422012-03-22 20:43:56 +0000821 GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->findFrameBuffer(frameBufferID);
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000822
robertphillips@google.com7c959422012-03-22 20:43:56 +0000823 GrDebugGL::getInstance()->setFrameBuffer(frameBuffer);
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000824}
825
robertphillips@google.com7c959422012-03-22 20:43:56 +0000826GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000827
robertphillips@google.com7c959422012-03-22 20:43:56 +0000828 GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
829
830 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
831 GrRenderBufferObj *renderBuffer = GrDebugGL::getInstance()->findRenderBuffer(renderBufferID);
832
833 GrDebugGL::getInstance()->setRenderBuffer(renderBuffer);
834}
835
836GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000837
838 // first potentially unbind the buffers
839 if (GrDebugGL::getInstance()->getFrameBuffer()) {
840 for (int i = 0; i < n; ++i) {
841
robertphillips@google.com7c959422012-03-22 20:43:56 +0000842 if (frameBuffers[i] == GrDebugGL::getInstance()->getFrameBuffer()->getID()) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000843 // this ID is the current frame buffer - rebind to the default
844 GrDebugGL::getInstance()->setFrameBuffer(NULL);
845 }
846 }
847 }
848
849 // then actually "delete" the buffers
850 for (int i = 0; i < n; ++i) {
robertphillips@google.com7c959422012-03-22 20:43:56 +0000851 GrFrameBufferObj *buffer = GrDebugGL::getInstance()->findFrameBuffer(frameBuffers[i]);
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000852 GrAlwaysAssert(buffer);
853
854 GrAlwaysAssert(!buffer->getDeleted());
855 buffer->deleteAction();
856 }
857}
858
robertphillips@google.com7c959422012-03-22 20:43:56 +0000859GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderBuffers) {
860
861 // first potentially unbind the buffers
862 if (GrDebugGL::getInstance()->getRenderBuffer()) {
863 for (int i = 0; i < n; ++i) {
864
865 if (renderBuffers[i] == GrDebugGL::getInstance()->getRenderBuffer()->getID()) {
866 // this ID is the current render buffer - make no render buffer be bound
867 GrDebugGL::getInstance()->setRenderBuffer(NULL);
868 }
869 }
870 }
871
872 // Open GL will remove a deleted render buffer from the active frame buffer but not
873 // from any other frame buffer
874 if (GrDebugGL::getInstance()->getFrameBuffer()) {
875
876 GrFrameBufferObj *frameBuffer = GrDebugGL::getInstance()->getFrameBuffer();
877
878 for (int i = 0; i < n; ++i) {
879
880 if (NULL != frameBuffer->getColor() && renderBuffers[i] == frameBuffer->getColor()->getID()) {
881 frameBuffer->setColor(NULL);
882 }
883 if (NULL != frameBuffer->getDepth() && renderBuffers[i] == frameBuffer->getDepth()->getID()) {
884 frameBuffer->setDepth(NULL);
885 }
886 if (NULL != frameBuffer->getStencil() && renderBuffers[i] == frameBuffer->getStencil()->getID()) {
887 frameBuffer->setStencil(NULL);
888 }
889 }
890 }
891
892 // then actually "delete" the buffers
893 for (int i = 0; i < n; ++i) {
894 GrRenderBufferObj *buffer = GrDebugGL::getInstance()->findRenderBuffer(renderBuffers[i]);
895 GrAlwaysAssert(buffer);
896
897 // OpenGL gives no guarantees if a render buffer is deleted while attached to
898 // something other than the currently bound frame buffer
899 GrAlwaysAssert(!buffer->getColorBound());
900 GrAlwaysAssert(!buffer->getDepthBound());
901 GrAlwaysAssert(!buffer->getStencilBound());
902
903 GrAlwaysAssert(!buffer->getDeleted());
904 buffer->deleteAction();
905 }
906}
907
908GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderBufferID) {
909
910 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
911 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
912 GR_GL_DEPTH_ATTACHMENT == attachment ||
913 GR_GL_STENCIL_ATTACHMENT == attachment);
914 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
915
916 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->getFrameBuffer();
917 // A render buffer cannot be attached to the default framebuffer
918 GrAlwaysAssert(NULL != framebuffer);
919
920 // a renderBufferID of 0 is acceptable - it unbinds the current render buffer
921 GrRenderBufferObj *renderbuffer = GrDebugGL::getInstance()->findRenderBuffer(renderBufferID);
922
923 switch (attachment) {
924 case GR_GL_COLOR_ATTACHMENT0:
925 framebuffer->setColor(renderbuffer);
926 break;
927 case GR_GL_DEPTH_ATTACHMENT:
928 framebuffer->setDepth(renderbuffer);
929 break;
930 case GR_GL_STENCIL_ATTACHMENT:
931 framebuffer->setStencil(renderbuffer);
932 break;
933 default:
934 GrAlwaysAssert(false);
935 break;
936 };
937
938}
939
robertphillips@google.com0da37192012-03-19 14:42:13 +0000940GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
941GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetFramebufferAttachmentParameteriv(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params) {}
942GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetRenderbufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {}
943GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
944GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
945GrGLvoid 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) {}
946GrGLvoid GR_GL_FUNCTION_TYPE debugGLResolveMultisampleFramebuffer() {}
947GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocationIndexed(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name) {}
948
949GrGLenum GR_GL_FUNCTION_TYPE debugGLCheckFramebufferStatus(GrGLenum target) {
950 return GR_GL_FRAMEBUFFER_COMPLETE;
951}
952
953GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() {
954
955 GrProgramObj *program = GrDebugGL::getInstance()->createProgram();
956
957 return program->getID();
958}
959
960GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) {
961
962 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || GR_GL_FRAGMENT_SHADER == type);
963
964 GrShaderObj *shader = GrDebugGL::getInstance()->createShader(type);
965
966 return shader->getID();
967}
968
969GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) {
970
971 GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID);
972 GrAlwaysAssert(program);
973
robertphillips@google.com0da37192012-03-19 14:42:13 +0000974 if (program->getRefCount()) {
975 // someone is still using this program so we can't delete it here
976 program->setMarkedForDeletion();
977 } else {
978 program->deleteAction();
979 }
980}
981
982GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) {
983
984 GrShaderObj *shader = GrDebugGL::getInstance()->findShader(shaderID);
985 GrAlwaysAssert(shader);
986
robertphillips@google.com0da37192012-03-19 14:42:13 +0000987 if (shader->getRefCount()) {
988 // someone is still using this shader so we can't delete it here
989 shader->setMarkedForDeletion();
990 } else {
991 shader->deleteAction();
992 }
993}
994
995// same function used for all glGen*(GLsize i, GLuint*) functions
996GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenIds(GrGLsizei n, GrGLuint* ids) {
997 static int gCurrID = 1;
998 for (int i = 0; i < n; ++i) {
999 ids[i] = ++gCurrID;
1000 }
1001}
1002
1003GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
1004
1005 for (int i = 0; i < n; ++i) {
1006 GrBufferObj *buffer = GrDebugGL::getInstance()->createBuffer();
1007 GrAlwaysAssert(buffer);
1008 ids[i] = buffer->getID();
1009 }
1010}
1011
robertphillips@google.comf6f123d2012-03-21 17:57:55 +00001012GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, GrGLuint* ids) {
1013
1014 for (int i = 0; i < n; ++i) {
1015 GrFrameBufferObj *buffer = GrDebugGL::getInstance()->createFrameBuffer();
1016 GrAlwaysAssert(buffer);
1017 ids[i] = buffer->getID();
1018 }
1019}
1020
robertphillips@google.com7c959422012-03-22 20:43:56 +00001021GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenRenderbuffers(GrGLsizei n, GrGLuint* ids) {
1022
1023 for (int i = 0; i < n; ++i) {
1024 GrRenderBufferObj *buffer = GrDebugGL::getInstance()->createRenderBuffer();
1025 GrAlwaysAssert(buffer);
1026 ids[i] = buffer->getID();
1027 }
1028}
1029
robertphillips@google.com0da37192012-03-19 14:42:13 +00001030// same delete function for all glDelete*(GLsize i, const GLuint*) except buffers
1031GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteIds(GrGLsizei n, const GrGLuint* ids) {}
1032
1033
1034GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) {
1035
1036 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
1037
1038 GrBufferObj *buffer = GrDebugGL::getInstance()->findBuffer(bufferID);
1039 // 0 is a permissable bufferID - it unbinds the current buffer
1040
1041 switch (target) {
1042 case GR_GL_ARRAY_BUFFER:
robertphillips@google.com0da37192012-03-19 14:42:13 +00001043 GrDebugGL::getInstance()->setArrayBuffer(buffer);
robertphillips@google.com0da37192012-03-19 14:42:13 +00001044 break;
1045 case GR_GL_ELEMENT_ARRAY_BUFFER:
robertphillips@google.com0da37192012-03-19 14:42:13 +00001046 GrDebugGL::getInstance()->setElementArrayBuffer(buffer);
robertphillips@google.com0da37192012-03-19 14:42:13 +00001047 break;
1048 default:
1049 GrCrash("Unexpected target to glBindBuffer");
1050 break;
1051 }
1052}
1053
1054// deleting a bound buffer has the side effect of binding 0
1055GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
1056 // first potentially unbind the buffers
1057 for (int i = 0; i < n; ++i) {
1058
1059 if (GrDebugGL::getInstance()->getArrayBuffer() &&
1060 ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) {
1061 // this ID is the current array buffer
robertphillips@google.com0da37192012-03-19 14:42:13 +00001062 GrDebugGL::getInstance()->setArrayBuffer(NULL);
1063 }
1064 if (GrDebugGL::getInstance()->getElementArrayBuffer() &&
1065 ids[i] == GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) {
1066 // this ID is the current element array buffer
robertphillips@google.com0da37192012-03-19 14:42:13 +00001067 GrDebugGL::getInstance()->setElementArrayBuffer(NULL);
1068 }
1069 }
1070
1071 // then actually "delete" the buffers
1072 for (int i = 0; i < n; ++i) {
1073 GrBufferObj *buffer = GrDebugGL::getInstance()->findBuffer(ids[i]);
1074 GrAlwaysAssert(buffer);
1075
1076 GrAlwaysAssert(!buffer->getDeleted());
1077 buffer->deleteAction();
1078 }
1079}
1080
1081// map a buffer to the caller's address space
1082GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) {
1083
1084 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
1085 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); // GR_GL_READ_ONLY == access || || GR_GL_READ_WRIT == access);
1086
1087 GrBufferObj *buffer = NULL;
1088 switch (target) {
1089 case GR_GL_ARRAY_BUFFER:
1090 buffer = GrDebugGL::getInstance()->getArrayBuffer();
1091 break;
1092 case GR_GL_ELEMENT_ARRAY_BUFFER:
1093 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
1094 break;
1095 default:
1096 GrCrash("Unexpected target to glMapBuffer");
1097 break;
1098 }
1099
1100 if (buffer) {
1101 GrAlwaysAssert(!buffer->getMapped());
1102 buffer->setMapped();
1103 return buffer->getDataPtr();
1104 }
1105
1106 GrAlwaysAssert(false);
1107 return NULL; // no buffer bound to the target
1108}
1109
1110// remove a buffer from the caller's address space
1111// TODO: check if the "access" method from "glMapBuffer" was honored
1112GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) {
1113
1114 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
1115
1116 GrBufferObj *buffer = NULL;
1117 switch (target) {
1118 case GR_GL_ARRAY_BUFFER:
1119 buffer = GrDebugGL::getInstance()->getArrayBuffer();
1120 break;
1121 case GR_GL_ELEMENT_ARRAY_BUFFER:
1122 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
1123 break;
1124 default:
1125 GrCrash("Unexpected target to glUnmapBuffer");
1126 break;
1127 }
1128
1129 if (buffer) {
1130 GrAlwaysAssert(buffer->getMapped());
1131 buffer->resetMapped();
1132 return GR_GL_TRUE;
1133 }
1134
1135 GrAlwaysAssert(false);
1136 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
1137}
1138
1139GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) {
1140
1141 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
1142 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || GR_GL_BUFFER_USAGE == value);
1143
1144 GrBufferObj *buffer = NULL;
1145 switch (target) {
1146 case GR_GL_ARRAY_BUFFER:
1147 buffer = GrDebugGL::getInstance()->getArrayBuffer();
1148 break;
1149 case GR_GL_ELEMENT_ARRAY_BUFFER:
1150 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
1151 break;
1152 }
1153
1154 GrAlwaysAssert(buffer);
1155
1156 switch (value) {
1157 case GR_GL_BUFFER_MAPPED:
1158 *params = GR_GL_FALSE;
1159 if (buffer)
1160 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
1161 break;
1162 case GR_GL_BUFFER_SIZE:
1163 *params = 0;
1164 if (buffer)
1165 *params = buffer->getSize();
1166 break;
1167 case GR_GL_BUFFER_USAGE:
1168 *params = GR_GL_STATIC_DRAW;
1169 if (buffer)
1170 *params = buffer->getUsage();
1171 break;
1172 default:
1173 GrCrash("Unexpected value to glGetBufferParamateriv");
1174 break;
1175 }
1176};
1177
1178GrGLenum GR_GL_FUNCTION_TYPE debugGLGetError() {
1179 return GR_GL_NO_ERROR;
1180}
1181
1182GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetIntegerv(GrGLenum pname, GrGLint* params) {
1183 // TODO: remove from Ganesh the #defines for gets we don't use.
1184 // We would like to minimize gets overall due to performance issues
1185 switch (pname) {
1186 case GR_GL_STENCIL_BITS:
1187 *params = 8;
1188 break;
1189 case GR_GL_SAMPLES:
1190 *params = 1;
1191 break;
1192 case GR_GL_FRAMEBUFFER_BINDING:
1193 *params = 0;
1194 break;
1195 case GR_GL_VIEWPORT:
1196 params[0] = 0;
1197 params[1] = 0;
1198 params[2] = 800;
1199 params[3] = 600;
1200 break;
1201 case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
1202 *params = 8;
1203 break;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +00001204 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
1205 *params = kDefaultMaxVertexUniformVectors;
1206 break;
robertphillips@google.com0da37192012-03-19 14:42:13 +00001207 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +00001208 *params = kDefaultMaxFragmentUniformVectors;
robertphillips@google.com0da37192012-03-19 14:42:13 +00001209 break;
1210 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1211 *params = 16 * 4;
1212 break;
1213 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1214 *params = 0;
1215 break;
1216 case GR_GL_COMPRESSED_TEXTURE_FORMATS:
1217 break;
1218 case GR_GL_MAX_TEXTURE_SIZE:
1219 *params = 8192;
1220 break;
1221 case GR_GL_MAX_RENDERBUFFER_SIZE:
1222 *params = 8192;
1223 break;
1224 case GR_GL_MAX_SAMPLES:
1225 *params = 32;
1226 break;
1227 case GR_GL_MAX_VERTEX_ATTRIBS:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +00001228 *params = kDefaultMaxVertexAttribs;
1229 break;
1230 case GR_GL_MAX_VARYING_VECTORS:
1231 *params = kDefaultMaxVaryingVectors;
robertphillips@google.com0da37192012-03-19 14:42:13 +00001232 break;
1233 case GR_GL_MAX_TEXTURE_UNITS:
1234 *params = GrDebugGL::getInstance()->getMaxTextureUnits();
1235 break;
1236 default:
1237 GrCrash("Unexpected pname to GetIntegerv");
1238 }
1239}
1240// used for both the program and shader info logs
1241GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog) {
1242 if (length) {
1243 *length = 0;
1244 }
1245 if (bufsize > 0) {
1246 *infolog = 0;
1247 }
1248}
1249
1250// used for both the program and shader params
1251GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetShaderOrProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) {
1252 switch (pname) {
1253 case GR_GL_LINK_STATUS: // fallthru
1254 case GR_GL_COMPILE_STATUS:
1255 *params = GR_GL_TRUE;
1256 break;
1257 case GR_GL_INFO_LOG_LENGTH:
1258 *params = 0;
1259 break;
1260 // we don't expect any other pnames
1261 default:
1262 GrCrash("Unexpected pname to GetProgramiv");
1263 break;
1264 }
1265}
1266
1267namespace {
1268template <typename T>
1269void query_result(GrGLenum GLtarget, GrGLenum pname, T *params) {
1270 switch (pname) {
1271 case GR_GL_QUERY_RESULT_AVAILABLE:
1272 *params = GR_GL_TRUE;
1273 break;
1274 case GR_GL_QUERY_RESULT:
1275 *params = 0;
1276 break;
1277 default:
1278 GrCrash("Unexpected pname passed to GetQueryObject.");
1279 break;
1280 }
1281}
1282}
1283
1284// Queries on the null GL just don't do anything at all. We could potentially make
1285// the timers work.
1286GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) {
1287 switch (pname) {
1288 case GR_GL_CURRENT_QUERY:
1289 *params = 0;
1290 break;
1291 case GR_GL_QUERY_COUNTER_BITS:
1292 *params = 32;
1293 break;
1294 default:
1295 GrCrash("Unexpected pname passed GetQueryiv.");
1296 }
1297}
1298GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) {
1299 query_result(id, pname, params);
1300}
1301GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) {
1302 query_result(id, pname, params);
1303}
1304GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) {
1305 query_result(id, pname, params);
1306}
1307GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) {
1308 query_result(id, pname, params);
1309}
1310
1311const GrGLubyte* GR_GL_FUNCTION_TYPE debugGLGetString(GrGLenum name) {
1312 switch (name) {
1313 case GR_GL_EXTENSIONS:
1314 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";
1315 case GR_GL_VERSION:
1316 return (const GrGLubyte*)"4.0 Null GL";
1317 case GR_GL_SHADING_LANGUAGE_VERSION:
1318 return (const GrGLubyte*)"4.20.8 Null GLSL";
1319 default:
1320 GrCrash("Unexpected name to GetString");
1321 return NULL;
1322 }
1323}
1324
1325// we used to use this to query stuff about externally created textures, now we just
1326// require clients to tell us everything about the texture.
1327GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params) {
1328 GrCrash("Should never query texture parameters.");
1329}
1330
1331GrGLint GR_GL_FUNCTION_TYPE debugGLGetUniformLocation(GrGLuint program, const char* name) {
1332 static int gUniLocation = 0;
1333 return ++gUniLocation;
1334}
1335
1336const GrGLInterface* GrGLCreateDebugInterface() {
1337 // The gl functions are not context-specific so we create one global
1338 // interface
1339 static SkAutoTUnref<GrGLInterface> glInterface;
1340 if (!glInterface.get()) {
1341 GrGLInterface* interface = new GrGLInterface;
1342 glInterface.reset(interface);
1343 interface->fBindingsExported = kDesktop_GrGLBinding;
1344 interface->fActiveTexture = debugGLActiveTexture;
1345 interface->fAttachShader = debugGLAttachShader;
1346 interface->fBeginQuery = debugGLBeginQuery;
1347 interface->fBindAttribLocation = debugGLBindAttribLocation;
1348 interface->fBindBuffer = debugGLBindBuffer;
1349 interface->fBindFragDataLocation = debugGLBindFragDataLocation;
1350 interface->fBindTexture = debugGLBindTexture;
1351 interface->fBlendColor = debugGLBlendColor;
1352 interface->fBlendFunc = debugGLBlendFunc;
1353 interface->fBufferData = debugGLBufferData;
1354 interface->fBufferSubData = debugGLBufferSubData;
1355 interface->fClear = debugGLClear;
1356 interface->fClearColor = debugGLClearColor;
1357 interface->fClearStencil = debugGLClearStencil;
1358 interface->fColorMask = debugGLColorMask;
1359 interface->fCompileShader = debugGLCompileShader;
1360 interface->fCompressedTexImage2D = debugGLCompressedTexImage2D;
1361 interface->fCreateProgram = debugGLCreateProgram;
1362 interface->fCreateShader = debugGLCreateShader;
1363 interface->fCullFace = debugGLCullFace;
1364 interface->fDeleteBuffers = debugGLDeleteBuffers;
1365 interface->fDeleteProgram = debugGLDeleteProgram;
1366 interface->fDeleteQueries = debugGLDeleteIds;
1367 interface->fDeleteShader = debugGLDeleteShader;
1368 interface->fDeleteTextures = debugGLDeleteIds;
1369 interface->fDepthMask = debugGLDepthMask;
1370 interface->fDisable = debugGLDisable;
1371 interface->fDisableVertexAttribArray = debugGLDisableVertexAttribArray;
1372 interface->fDrawArrays = debugGLDrawArrays;
1373 interface->fDrawBuffer = debugGLDrawBuffer;
1374 interface->fDrawBuffers = debugGLDrawBuffers;
1375 interface->fDrawElements = debugGLDrawElements;
1376 interface->fEnable = debugGLEnable;
1377 interface->fEnableVertexAttribArray = debugGLEnableVertexAttribArray;
1378 interface->fEndQuery = debugGLEndQuery;
1379 interface->fFinish = debugGLFinish;
1380 interface->fFlush = debugGLFlush;
1381 interface->fFrontFace = debugGLFrontFace;
1382 interface->fGenBuffers = debugGLGenBuffers;
1383 interface->fGenQueries = debugGLGenIds;
1384 interface->fGenTextures = debugGLGenIds;
1385 interface->fGetBufferParameteriv = debugGLGetBufferParameteriv;
1386 interface->fGetError = debugGLGetError;
1387 interface->fGetIntegerv = debugGLGetIntegerv;
1388 interface->fGetQueryObjecti64v = debugGLGetQueryObjecti64v;
1389 interface->fGetQueryObjectiv = debugGLGetQueryObjectiv;
1390 interface->fGetQueryObjectui64v = debugGLGetQueryObjectui64v;
1391 interface->fGetQueryObjectuiv = debugGLGetQueryObjectuiv;
1392 interface->fGetQueryiv = debugGLGetQueryiv;
1393 interface->fGetProgramInfoLog = debugGLGetInfoLog;
1394 interface->fGetProgramiv = debugGLGetShaderOrProgramiv;
1395 interface->fGetShaderInfoLog = debugGLGetInfoLog;
1396 interface->fGetShaderiv = debugGLGetShaderOrProgramiv;
1397 interface->fGetString = debugGLGetString;
1398 interface->fGetTexLevelParameteriv = debugGLGetTexLevelParameteriv;
1399 interface->fGetUniformLocation = debugGLGetUniformLocation;
1400 interface->fLineWidth = debugGLLineWidth;
1401 interface->fLinkProgram = debugGLLinkProgram;
1402 interface->fPixelStorei = debugGLPixelStorei;
1403 interface->fQueryCounter = debugGLQueryCounter;
1404 interface->fReadBuffer = debugGLReadBuffer;
1405 interface->fReadPixels = debugGLReadPixels;
1406 interface->fScissor = debugGLScissor;
1407 interface->fShaderSource = debugGLShaderSource;
1408 interface->fStencilFunc = debugGLStencilFunc;
1409 interface->fStencilFuncSeparate = debugGLStencilFuncSeparate;
1410 interface->fStencilMask = debugGLStencilMask;
1411 interface->fStencilMaskSeparate = debugGLStencilMaskSeparate;
1412 interface->fStencilOp = debugGLStencilOp;
1413 interface->fStencilOpSeparate = debugGLStencilOpSeparate;
1414 interface->fTexImage2D = debugGLTexImage2D;
1415 interface->fTexParameteri = debugGLTexParameteri;
1416 interface->fTexSubImage2D = debugGLTexSubImage2D;
1417 interface->fTexStorage2D = debugGLTexStorage2D;
1418 interface->fUniform1f = debugGLUniform1f;
1419 interface->fUniform1i = debugGLUniform1i;
1420 interface->fUniform1fv = debugGLUniform1fv;
1421 interface->fUniform1iv = debugGLUniform1iv;
1422 interface->fUniform2f = debugGLUniform2f;
1423 interface->fUniform2i = debugGLUniform2i;
1424 interface->fUniform2fv = debugGLUniform2fv;
1425 interface->fUniform2iv = debugGLUniform2iv;
1426 interface->fUniform3f = debugGLUniform3f;
1427 interface->fUniform3i = debugGLUniform3i;
1428 interface->fUniform3fv = debugGLUniform3fv;
1429 interface->fUniform3iv = debugGLUniform3iv;
1430 interface->fUniform4f = debugGLUniform4f;
1431 interface->fUniform4i = debugGLUniform4i;
1432 interface->fUniform4fv = debugGLUniform4fv;
1433 interface->fUniform4iv = debugGLUniform4iv;
1434 interface->fUniformMatrix2fv = debugGLUniformMatrix2fv;
1435 interface->fUniformMatrix3fv = debugGLUniformMatrix3fv;
1436 interface->fUniformMatrix4fv = debugGLUniformMatrix4fv;
1437 interface->fUseProgram = debugGLUseProgram;
1438 interface->fVertexAttrib4fv = debugGLVertexAttrib4fv;
1439 interface->fVertexAttribPointer = debugGLVertexAttribPointer;
1440 interface->fViewport = debugGLViewport;
1441 interface->fBindFramebuffer = debugGLBindFramebuffer;
1442 interface->fBindRenderbuffer = debugGLBindRenderbuffer;
1443 interface->fCheckFramebufferStatus = debugGLCheckFramebufferStatus;
1444 interface->fDeleteFramebuffers = debugGLDeleteFramebuffers;
1445 interface->fDeleteRenderbuffers = debugGLDeleteRenderbuffers;
1446 interface->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer;
1447 interface->fFramebufferTexture2D = debugGLFramebufferTexture2D;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +00001448 interface->fGenFramebuffers = debugGLGenFramebuffers;
robertphillips@google.com7c959422012-03-22 20:43:56 +00001449 interface->fGenRenderbuffers = debugGLGenRenderbuffers;
robertphillips@google.com0da37192012-03-19 14:42:13 +00001450 interface->fGetFramebufferAttachmentParameteriv = debugGLGetFramebufferAttachmentParameteriv;
1451 interface->fGetRenderbufferParameteriv = debugGLGetRenderbufferParameteriv;
1452 interface->fRenderbufferStorage = debugGLRenderbufferStorage;
1453 interface->fRenderbufferStorageMultisample = debugGLRenderbufferStorageMultisample;
1454 interface->fBlitFramebuffer = debugGLBlitFramebuffer;
1455 interface->fResolveMultisampleFramebuffer = debugGLResolveMultisampleFramebuffer;
1456 interface->fMapBuffer = debugGLMapBuffer;
1457 interface->fUnmapBuffer = debugGLUnmapBuffer;
1458 interface->fBindFragDataLocationIndexed = debugGLBindFragDataLocationIndexed;
1459 }
1460 glInterface.get()->ref();
1461 return glInterface.get();
1462}