blob: b6e2e58ebfa20920c368d0b7c7e68a23ec2ac5ef [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"
13
14// the OpenGLES 2.0 spec says this must be >= 2
15static const GrGLint kDefaultMaxTextureUnits = 8;
16
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000017// the OpenGLES 2.0 spec says this must be >= 128
18static const GrGLint kDefaultMaxVertexUniformVectors = 128;
19
20// the OpenGLES 2.0 spec says this must be >=16
21static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
22
23// the OpenGLES 2.0 spec says this must be >= 8
24static const GrGLint kDefaultMaxVertexAttribs = 8;
25
26// the OpenGLES 2.0 spec says this must be >= 8
27static const GrGLint kDefaultMaxVaryingVectors = 8;
28
robertphillips@google.com0da37192012-03-19 14:42:13 +000029////////////////////////////////////////////////////////////////////////////////
30// This object is used to track the OpenGL objects. We don't use real
31// reference counting (i.e., we don't free the objects when their ref count
32// goes to 0) so that we can detect invalid memory accesses. The refs we
33// are tracking in this class are actually OpenGL's references to the objects
34// not "ours"
35// Each object also gets a unique globally identifying ID
36class GrFakeRefObj
37{
38public:
39 GrFakeRefObj(GrGLuint ID)
40 : fRef(0)
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000041 , fHighRefCount(0)
robertphillips@google.com0da37192012-03-19 14:42:13 +000042 , fID(ID)
43 , fMarkedForDeletion(false)
44 , fDeleted(false) {
45 }
46 virtual ~GrFakeRefObj() {};
47
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000048 void ref() {
49 fRef++;
50 if (fHighRefCount < fRef) {
51 fHighRefCount = fRef;
52 }
53 }
robertphillips@google.com0da37192012-03-19 14:42:13 +000054 void unref() {
55 fRef--;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000056 GrAlwaysAssert(fRef >= 0);
57
robertphillips@google.com0da37192012-03-19 14:42:13 +000058 // often in OpenGL a given object may still be in use when the
59 // delete call is made. In these cases the object is marked
60 // for deletion and then freed when it is no longer in use
61 if (0 == fRef && fMarkedForDeletion) {
62 this->deleteAction();
63 }
64 }
65 int getRefCount() const { return fRef; }
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000066 int getHighRefCount() const { return fHighRefCount; }
robertphillips@google.com0da37192012-03-19 14:42:13 +000067
68 GrGLuint getID() const { return fID; }
69
70 void setMarkedForDeletion() { fMarkedForDeletion = true; }
71 bool getMarkedForDeletion() const { return fMarkedForDeletion; }
72
73 // setDeleted should only ever appear in deleteAction methods!
74 void setDeleted() { fDeleted = true; }
75 bool getDeleted() const { return fDeleted; }
76
77 // The deleteAction fires if the object has been marked for deletion but
78 // couldn't be deleted earlier due to refs
79 virtual void deleteAction() = 0;
80
81protected:
82private:
83 int fRef;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +000084 int fHighRefCount; // high water mark of the ref count
robertphillips@google.com0da37192012-03-19 14:42:13 +000085 GrGLuint fID;
86 bool fMarkedForDeletion;
87 // The deleted flag is only set when OpenGL thinks the object is deleted
88 // It is obviously still allocated w/in this framework
89 bool fDeleted;
90};
91
92////////////////////////////////////////////////////////////////////////////////
93class GrBufferObj : public GrFakeRefObj
94{
95public:
96 GrBufferObj(GrGLuint ID)
97 : GrFakeRefObj(ID)
98 , fDataPtr(NULL)
99 , fMapped(false)
100 , fBound(false)
101 , fSize(0)
102 , fUsage(GR_GL_STATIC_DRAW) {
103 }
104 virtual ~GrBufferObj() {
105 delete[] fDataPtr;
106 }
107
108 void access() {
109 // cannot access the buffer if it is currently mapped
110 GrAlwaysAssert(!fMapped);
111 }
112
113 void setMapped() { fMapped = true; }
114 void resetMapped() { fMapped = false; }
115 bool getMapped() const { return fMapped; }
116
117 void setBound() { fBound = true; }
118 void resetBound() { fBound = false; }
119 bool getBound() const { return fBound; }
120
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000121 void allocate(GrGLint size, const GrGLchar *dataPtr) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000122 GrAlwaysAssert(size >= 0);
123
124 // delete pre-existing data
robertphillips@google.com0ffc56f2012-03-21 13:05:04 +0000125 delete fDataPtr;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000126
127 fSize = size;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000128 fDataPtr = new GrGLchar[size];
robertphillips@google.com0da37192012-03-19 14:42:13 +0000129 if (dataPtr) {
130 memcpy(fDataPtr, dataPtr, fSize);
131 }
132 // TODO: w/ no dataPtr the data is unitialized - this could be tracked
133 }
134 GrGLint getSize() const { return fSize; }
robertphillips@google.comd41a1dc2012-03-19 17:33:58 +0000135 GrGLvoid *getDataPtr() { return fDataPtr; }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000136
137 GrGLint getUsage() const { return fUsage; }
138 void setUsage(GrGLint usage) { fUsage = usage; }
139
140 virtual void deleteAction() SK_OVERRIDE {
141
142 // buffers are automatically unmapped when deleted
143 this->resetMapped();
144 this->setDeleted();
145 }
146
147
148protected:
149private:
150
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000151 GrGLchar* fDataPtr;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000152 bool fMapped; // is the buffer object mapped via "glMapBuffer"?
153 bool fBound; // is the buffer object bound via "glBindBuffer"?
154 GrGLint fSize; // size in bytes
155 GrGLint fUsage; // one of: GL_STREAM_DRAW, GL_STATIC_DRAW, GL_DYNAMIC_DRAW
156
157 typedef GrFakeRefObj INHERITED;
158};
159
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000160////////////////////////////////////////////////////////////////////////////////
161// TODO: when a framebuffer obj is bound the GL_SAMPLES query must return 0
162// TODO: GL_STENCIL_BITS must also be redirected to the framebuffer
163class GrFrameBufferObj : public GrFakeRefObj
164{
165public:
166 GrFrameBufferObj(GrGLuint ID)
167 : GrFakeRefObj(ID)
168 , fBound(false) {
169 }
170
171 void setBound() { fBound = true; }
172 void resetBound() { fBound = false; }
173 bool getBound() const { return fBound; }
174
175 virtual void deleteAction() SK_OVERRIDE {
176
177 this->setDeleted();
178 }
179
180protected:
181private:
182 bool fBound; // is this frame buffer currently bound via "glBindFramebuffer"?
183
184 typedef GrFakeRefObj INHERITED;
185};
robertphillips@google.com0da37192012-03-19 14:42:13 +0000186
187////////////////////////////////////////////////////////////////////////////////
188class GrShaderObj : public GrFakeRefObj
189{
190public:
191 GrShaderObj(GrGLuint ID, GrGLenum type)
192 : GrFakeRefObj(ID)
193 , fType(type) {}
194
195 GrGLenum getType() { return fType; }
196
197 virtual void deleteAction() SK_OVERRIDE {
198
199 this->setDeleted();
200 }
201
202protected:
203private:
204 GrGLenum fType; // either GR_GL_VERTEX_SHADER or GR_GL_FRAGMENT_SHADER
205
206 typedef GrFakeRefObj INHERITED;
207};
208
209
210////////////////////////////////////////////////////////////////////////////////
211class GrProgramObj : public GrFakeRefObj
212{
213public:
214 GrProgramObj(GrGLuint ID)
215 : GrFakeRefObj(ID)
216 , fInUse(false) {}
217
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000218 void AttachShader(GrShaderObj *shader) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000219 shader->ref();
220 fShaders.push_back(shader);
221 }
222
223 virtual void deleteAction() SK_OVERRIDE {
224
225 // shaders are automatically detached from a deleted program. They will only be
226 // deleted if they were marked for deletion by a prior call to glDeleteShader
227 for (int i = 0; i < fShaders.count(); ++i) {
228 fShaders[i]->unref();
229 }
230 fShaders.reset();
231
232 this->setDeleted();
233 }
234
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000235 // TODO: this flag system won't work w/ multiple contexts!
robertphillips@google.com0da37192012-03-19 14:42:13 +0000236 void setInUse() { fInUse = true; }
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000237 void resetInUse() { fInUse = false; }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000238 bool getInUse() const { return fInUse; }
239
240protected:
241
242private:
243 SkTArray<GrShaderObj *> fShaders;
244 bool fInUse; // has this program been activated by a glUseProgram call?
245
246 typedef GrFakeRefObj INHERITED;
247};
248
249////////////////////////////////////////////////////////////////////////////////
250// This is the main debugging object. It is a singleton and keeps track of
251// all the other debug objects.
252class GrDebugGL
253{
254public:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000255 // TODO: merge findBuffer, findFrameBuffer, findShader & findProgram??
256 GrBufferObj *findBuffer(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000257 GrFakeRefObj *obj = this->findObject(ID);
258 if (NULL == obj) {
259 return NULL;
260 }
261
262 return reinterpret_cast<GrBufferObj *>(obj);
263 }
264
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000265 GrFrameBufferObj *findFrameBuffer(GrGLuint ID) {
266 GrFakeRefObj *obj = this->findObject(ID);
267 if (NULL == obj) {
268 return NULL;
269 }
270
271 return reinterpret_cast<GrFrameBufferObj *>(obj);
272 }
273
274 GrShaderObj *findShader(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000275 GrFakeRefObj *obj = this->findObject(ID);
276 if (NULL == obj) {
277 return NULL;
278 }
279
280 return reinterpret_cast<GrShaderObj *>(obj);
281 }
282
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000283 GrProgramObj *findProgram(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000284 GrFakeRefObj *obj = this->findObject(ID);
285 if (NULL == obj) {
286 return NULL;
287 }
288
289 return reinterpret_cast<GrProgramObj *>(obj);
290 }
291
292 // TODO: merge createBuffer, createShader, createProgram??
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000293 GrBufferObj *createBuffer() {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000294 GrBufferObj *buffer = new GrBufferObj(++fNextID);
295
296 fObjects.push_back(buffer);
297
298 return buffer;
299 }
300
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000301 GrFrameBufferObj *createFrameBuffer() {
302 GrFrameBufferObj *buffer = new GrFrameBufferObj(++fNextID);
303
304 fObjects.push_back(buffer);
305
306 return buffer;
307 }
308
309 GrShaderObj *createShader(GrGLenum type) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000310 GrShaderObj *shader = new GrShaderObj(++fNextID, type);
311
312 fObjects.push_back(shader);
313
314 return shader;
315 }
316
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000317 GrProgramObj *createProgram() {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000318 GrProgramObj *program = new GrProgramObj(++fNextID);
319
320 fObjects.push_back(program);
321
322 return program;
323 }
324
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000325 GrFakeRefObj *findObject(GrGLuint ID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000326 for (int i = 0; i < fObjects.count(); ++i) {
327 if (fObjects[i]->getID() == ID) {
328 // The application shouldn't be accessing objects
329 // that (as far as OpenGL knows) were already deleted
330 GrAlwaysAssert(!fObjects[i]->getDeleted());
331 GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion());
332 return fObjects[i];
333 }
334 }
335
336 return NULL;
337 }
338
339
340 void setMaxTextureUnits(GrGLuint maxTextureUnits) { fMaxTextureUnits = maxTextureUnits; }
341 GrGLuint getMaxTextureUnits() const { return fMaxTextureUnits; }
342
343 void setCurTextureUnit(GrGLuint curTextureUnit) { fCurTextureUnit = curTextureUnit; }
344 GrGLuint getCurTextureUnit() const { return fCurTextureUnit; }
345
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000346 void setArrayBuffer(GrBufferObj *arrayBuffer) {
347 if (fArrayBuffer) {
348 // automatically break the binding of the old buffer
349 GrAlwaysAssert(fArrayBuffer->getBound());
350 fArrayBuffer->resetBound();
351
352 GrAlwaysAssert(!fArrayBuffer->getDeleted());
353 fArrayBuffer->unref();
354 }
355
356 fArrayBuffer = arrayBuffer;
357
358 if (fArrayBuffer) {
359 GrAlwaysAssert(!fArrayBuffer->getDeleted());
360 fArrayBuffer->ref();
361
362 GrAlwaysAssert(!fArrayBuffer->getBound());
363 fArrayBuffer->setBound();
364 }
365 }
robertphillips@google.com0da37192012-03-19 14:42:13 +0000366 GrBufferObj *getArrayBuffer() { return fArrayBuffer; }
367
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000368 void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
369 if (fElementArrayBuffer) {
370 // automatically break the binding of the old buffer
371 GrAlwaysAssert(fElementArrayBuffer->getBound());
372 fElementArrayBuffer->resetBound();
373
374 GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
375 fElementArrayBuffer->unref();
376 }
377
378 fElementArrayBuffer = elementArrayBuffer;
379
380 if (fElementArrayBuffer) {
381 GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
382 fElementArrayBuffer->ref();
383
384 GrAlwaysAssert(!fElementArrayBuffer->getBound());
385 fElementArrayBuffer->setBound();
386 }
387 }
388
robertphillips@google.com0da37192012-03-19 14:42:13 +0000389 GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
390
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000391 void setFrameBuffer(GrFrameBufferObj *frameBuffer) {
392 if (fFrameBuffer)
393 {
394 GrAlwaysAssert(fFrameBuffer->getBound());
395 fFrameBuffer->resetBound();
396
397 GrAlwaysAssert(!fFrameBuffer->getDeleted());
398 fFrameBuffer->unref();
399 }
400
401 fFrameBuffer = frameBuffer;
402
403 if (fFrameBuffer)
404 {
405 GrAlwaysAssert(!fFrameBuffer->getDeleted());
406 fFrameBuffer->ref();
407
408 GrAlwaysAssert(!fFrameBuffer->getBound());
409 fFrameBuffer->setBound();
410 }
411 }
412
413 GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
414
415 void useProgram(GrProgramObj *program) {
416 if (fProgram) {
417 GrAlwaysAssert(fProgram->getInUse());
418 fProgram->resetInUse();
419
420 GrAlwaysAssert(!fProgram->getDeleted());
421 fProgram->unref();
422 }
423
424 fProgram = program;
425
426 if (fProgram)
427 {
428 GrAlwaysAssert(!fProgram->getDeleted());
429 fProgram->ref();
430
431 GrAlwaysAssert(!fProgram->getInUse());
432 fProgram->setInUse();
433 }
434 }
435
436 static GrDebugGL *getInstance() {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000437// static GrDebugGL Obj;
438
439 return &Obj;
440 }
441
442 void report() const {
443 for (int i = 0; i < fObjects.count(); ++i) {
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000444 GrAlwaysAssert(0 == fObjects[i]->getRefCount());
445 GrAlwaysAssert(0 < fObjects[i]->getHighRefCount());
robertphillips@google.com0da37192012-03-19 14:42:13 +0000446 GrAlwaysAssert(fObjects[i]->getDeleted());
447 }
448 }
449
450protected:
451
452private:
453 GrGLuint fMaxTextureUnits;
454 GrGLuint fCurTextureUnit;
455 GrBufferObj * fArrayBuffer;
456 GrBufferObj * fElementArrayBuffer;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000457 GrFrameBufferObj *fFrameBuffer;
458 GrProgramObj * fProgram;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000459
460 static int fNextID; // source for globally unique IDs
461
462 static GrDebugGL Obj;
463
464 // global store of all objects
465 SkTArray<GrFakeRefObj *> fObjects;
466
467 GrDebugGL()
468 : fMaxTextureUnits(kDefaultMaxTextureUnits)
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000469 , fCurTextureUnit(0)
470 , fArrayBuffer(NULL)
471 , fElementArrayBuffer(NULL)
472 , fFrameBuffer(NULL)
473 , fProgram(NULL) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000474 }
475
476 ~GrDebugGL() {
477 this->report();
478
479 for (int i = 0; i < fObjects.count(); ++i) {
480 delete fObjects[i];
481 }
482 fObjects.reset();
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000483
robertphillips@google.com0da37192012-03-19 14:42:13 +0000484 fArrayBuffer = NULL;
485 fElementArrayBuffer = NULL;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000486 fFrameBuffer = NULL;
487 fProgram = NULL;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000488 }
489};
490
491int GrDebugGL::fNextID = 0;
492GrDebugGL GrDebugGL::Obj;
493
494////////////////////////////////////////////////////////////////////////////////
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000495GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) {
robertphillips@google.comd41a1dc2012-03-19 17:33:58 +0000496
robertphillips@google.com0ffc56f2012-03-21 13:05:04 +0000497 GrAlwaysAssert(0 <= texture);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000498// GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits());
499
500 GrDebugGL::getInstance()->setCurTextureUnit(texture);
501}
502
503////////////////////////////////////////////////////////////////////////////////
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000504GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, GrGLuint shaderID) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000505 GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID);
506 GrAlwaysAssert(program);
507
508 GrShaderObj *shader = GrDebugGL::getInstance()->findShader(shaderID);
509 GrAlwaysAssert(shader);
510
511 program->AttachShader(shader);
512}
513
514GrGLvoid GR_GL_FUNCTION_TYPE debugGLBeginQuery(GrGLenum target, GrGLuint id) {}
515GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
516GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindTexture(GrGLenum target, GrGLuint texture) {}
517GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
518GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocation(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name) {}
519GrGLvoid GR_GL_FUNCTION_TYPE debugGLBlendFunc(GrGLenum sfactor, GrGLenum dfactor) {}
520
521////////////////////////////////////////////////////////////////////////////////
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000522GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, GrGLenum usage) {
robertphillips@google.com0da37192012-03-19 14:42:13 +0000523 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
524 GrAlwaysAssert(size >= 0);
525 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage || GR_GL_STATIC_DRAW == usage || GR_GL_DYNAMIC_DRAW == usage);
526
527 GrBufferObj *buffer = NULL;
528 switch (target) {
529 case GR_GL_ARRAY_BUFFER:
530 buffer = GrDebugGL::getInstance()->getArrayBuffer();
531 break;
532 case GR_GL_ELEMENT_ARRAY_BUFFER:
533 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
534 break;
535 default:
536 GrCrash("Unexpected target to glBufferData");
537 break;
538 }
539
540 GrAlwaysAssert(buffer);
541 GrAlwaysAssert(buffer->getBound());
542
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000543 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
robertphillips@google.com0da37192012-03-19 14:42:13 +0000544 buffer->setUsage(usage);
545}
546
547GrGLvoid GR_GL_FUNCTION_TYPE debugGLBufferSubData(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data) {}
548GrGLvoid GR_GL_FUNCTION_TYPE debugGLClear(GrGLbitfield mask) {}
549GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
550GrGLvoid GR_GL_FUNCTION_TYPE debugGLClearStencil(GrGLint s) {}
551GrGLvoid GR_GL_FUNCTION_TYPE debugGLColorMask(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha) {}
552GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompileShader(GrGLuint shader) {}
553GrGLvoid GR_GL_FUNCTION_TYPE debugGLCompressedTexImage2D(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data) {}
554GrGLvoid GR_GL_FUNCTION_TYPE debugGLCullFace(GrGLenum mode) {}
555GrGLvoid GR_GL_FUNCTION_TYPE debugGLDepthMask(GrGLboolean flag) {}
556GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisable(GrGLenum cap) {}
557GrGLvoid GR_GL_FUNCTION_TYPE debugGLDisableVertexAttribArray(GrGLuint index) {}
558GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawArrays(GrGLenum mode, GrGLint first, GrGLsizei count) {}
559GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffer(GrGLenum mode) {}
560GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawBuffers(GrGLsizei n, const GrGLenum* bufs) {}
561GrGLvoid GR_GL_FUNCTION_TYPE debugGLDrawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
562GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnable(GrGLenum cap) {}
563GrGLvoid GR_GL_FUNCTION_TYPE debugGLEnableVertexAttribArray(GrGLuint index) {}
564GrGLvoid GR_GL_FUNCTION_TYPE debugGLEndQuery(GrGLenum target) {}
565GrGLvoid GR_GL_FUNCTION_TYPE debugGLFinish() {}
566GrGLvoid GR_GL_FUNCTION_TYPE debugGLFlush() {}
567GrGLvoid GR_GL_FUNCTION_TYPE debugGLFrontFace(GrGLenum mode) {}
568GrGLvoid GR_GL_FUNCTION_TYPE debugGLLineWidth(GrGLfloat width) {}
569GrGLvoid GR_GL_FUNCTION_TYPE debugGLLinkProgram(GrGLuint program) {}
570GrGLvoid GR_GL_FUNCTION_TYPE debugGLPixelStorei(GrGLenum pname, GrGLint param) {}
571GrGLvoid GR_GL_FUNCTION_TYPE debugGLQueryCounter(GrGLuint id, GrGLenum target) {}
572GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadBuffer(GrGLenum src) {}
573GrGLvoid GR_GL_FUNCTION_TYPE debugGLReadPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
574GrGLvoid GR_GL_FUNCTION_TYPE debugGLScissor(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
575GrGLvoid GR_GL_FUNCTION_TYPE debugGLShaderSource(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length) {}
576GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {}
577GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilFuncSeparate(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask) {}
578GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMask(GrGLuint mask) {}
579GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilMaskSeparate(GrGLenum face, GrGLuint mask) {}
580GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOp(GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
581GrGLvoid GR_GL_FUNCTION_TYPE debugGLStencilOpSeparate(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
582GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexImage2D(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
583GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexParameteri(GrGLenum target, GrGLenum pname, GrGLint param) {}
584GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexStorage2D(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
585GrGLvoid GR_GL_FUNCTION_TYPE debugGLTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
586GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1f(GrGLint location, GrGLfloat v0) {}
587GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1i(GrGLint location, GrGLint v0) {}
588GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
589GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform1iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
590GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2f(GrGLint location, GrGLfloat v0, GrGLfloat v1) {}
591GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2i(GrGLint location, GrGLint v0, GrGLint v1) {}
592GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
593GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform2iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
594GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) {}
595GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {}
596GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
597GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform3iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
598GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3) {}
599GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {}
600GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
601GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniform4iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
602GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix2fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
603GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix3fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
604GrGLvoid GR_GL_FUNCTION_TYPE debugGLUniformMatrix4fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
605
606GrGLvoid GR_GL_FUNCTION_TYPE debugGLUseProgram(GrGLuint programID) {
607
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000608 // A programID of 0 is legal
robertphillips@google.com0da37192012-03-19 14:42:13 +0000609 GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000610
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000611 GrDebugGL::getInstance()->useProgram(program);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000612}
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000613
robertphillips@google.com0da37192012-03-19 14:42:13 +0000614GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {}
615GrGLvoid GR_GL_FUNCTION_TYPE debugGLVertexAttribPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr) {}
616GrGLvoid GR_GL_FUNCTION_TYPE debugGLViewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000617
618GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFramebuffer(GrGLenum target, GrGLuint frameBufferID) {
619
620 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
621
622 // a frameBufferID of 0 is acceptable - it binds to the default frame buffer
623 GrFrameBufferObj *framebuffer = GrDebugGL::getInstance()->findFrameBuffer(frameBufferID);
624
625 GrDebugGL::getInstance()->setFrameBuffer(framebuffer);
626}
627
robertphillips@google.com0da37192012-03-19 14:42:13 +0000628GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {}
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000629
630GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {
631
632 // first potentially unbind the buffers
633 if (GrDebugGL::getInstance()->getFrameBuffer()) {
634 for (int i = 0; i < n; ++i) {
635
636 if (framebuffers[i] == GrDebugGL::getInstance()->getFrameBuffer()->getID()) {
637 // this ID is the current frame buffer - rebind to the default
638 GrDebugGL::getInstance()->setFrameBuffer(NULL);
639 }
640 }
641 }
642
643 // then actually "delete" the buffers
644 for (int i = 0; i < n; ++i) {
645 GrFrameBufferObj *buffer = GrDebugGL::getInstance()->findFrameBuffer(framebuffers[i]);
646 GrAlwaysAssert(buffer);
647
648 GrAlwaysAssert(!buffer->getDeleted());
649 buffer->deleteAction();
650 }
651}
652
robertphillips@google.com0da37192012-03-19 14:42:13 +0000653GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {}
654GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
655GrGLvoid GR_GL_FUNCTION_TYPE debugGLFramebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
656GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetFramebufferAttachmentParameteriv(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params) {}
657GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetRenderbufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {}
658GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
659GrGLvoid GR_GL_FUNCTION_TYPE debugGLRenderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
660GrGLvoid 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) {}
661GrGLvoid GR_GL_FUNCTION_TYPE debugGLResolveMultisampleFramebuffer() {}
662GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindFragDataLocationIndexed(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name) {}
663
664GrGLenum GR_GL_FUNCTION_TYPE debugGLCheckFramebufferStatus(GrGLenum target) {
665 return GR_GL_FRAMEBUFFER_COMPLETE;
666}
667
668GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateProgram() {
669
670 GrProgramObj *program = GrDebugGL::getInstance()->createProgram();
671
672 return program->getID();
673}
674
675GrGLuint GR_GL_FUNCTION_TYPE debugGLCreateShader(GrGLenum type) {
676
677 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type || GR_GL_FRAGMENT_SHADER == type);
678
679 GrShaderObj *shader = GrDebugGL::getInstance()->createShader(type);
680
681 return shader->getID();
682}
683
684GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteProgram(GrGLuint programID) {
685
686 GrProgramObj *program = GrDebugGL::getInstance()->findProgram(programID);
687 GrAlwaysAssert(program);
688
robertphillips@google.com0da37192012-03-19 14:42:13 +0000689 if (program->getRefCount()) {
690 // someone is still using this program so we can't delete it here
691 program->setMarkedForDeletion();
692 } else {
693 program->deleteAction();
694 }
695}
696
697GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteShader(GrGLuint shaderID) {
698
699 GrShaderObj *shader = GrDebugGL::getInstance()->findShader(shaderID);
700 GrAlwaysAssert(shader);
701
robertphillips@google.com0da37192012-03-19 14:42:13 +0000702 if (shader->getRefCount()) {
703 // someone is still using this shader so we can't delete it here
704 shader->setMarkedForDeletion();
705 } else {
706 shader->deleteAction();
707 }
708}
709
710// same function used for all glGen*(GLsize i, GLuint*) functions
711GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenIds(GrGLsizei n, GrGLuint* ids) {
712 static int gCurrID = 1;
713 for (int i = 0; i < n; ++i) {
714 ids[i] = ++gCurrID;
715 }
716}
717
718GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenBuffers(GrGLsizei n, GrGLuint* ids) {
719
720 for (int i = 0; i < n; ++i) {
721 GrBufferObj *buffer = GrDebugGL::getInstance()->createBuffer();
722 GrAlwaysAssert(buffer);
723 ids[i] = buffer->getID();
724 }
725}
726
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000727GrGLvoid GR_GL_FUNCTION_TYPE debugGLGenFramebuffers(GrGLsizei n, GrGLuint* ids) {
728
729 for (int i = 0; i < n; ++i) {
730 GrFrameBufferObj *buffer = GrDebugGL::getInstance()->createFrameBuffer();
731 GrAlwaysAssert(buffer);
732 ids[i] = buffer->getID();
733 }
734}
735
robertphillips@google.com0da37192012-03-19 14:42:13 +0000736// same delete function for all glDelete*(GLsize i, const GLuint*) except buffers
737GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteIds(GrGLsizei n, const GrGLuint* ids) {}
738
739
740GrGLvoid GR_GL_FUNCTION_TYPE debugGLBindBuffer(GrGLenum target, GrGLuint bufferID) {
741
742 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
743
744 GrBufferObj *buffer = GrDebugGL::getInstance()->findBuffer(bufferID);
745 // 0 is a permissable bufferID - it unbinds the current buffer
746
747 switch (target) {
748 case GR_GL_ARRAY_BUFFER:
robertphillips@google.com0da37192012-03-19 14:42:13 +0000749 GrDebugGL::getInstance()->setArrayBuffer(buffer);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000750 break;
751 case GR_GL_ELEMENT_ARRAY_BUFFER:
robertphillips@google.com0da37192012-03-19 14:42:13 +0000752 GrDebugGL::getInstance()->setElementArrayBuffer(buffer);
robertphillips@google.com0da37192012-03-19 14:42:13 +0000753 break;
754 default:
755 GrCrash("Unexpected target to glBindBuffer");
756 break;
757 }
758}
759
760// deleting a bound buffer has the side effect of binding 0
761GrGLvoid GR_GL_FUNCTION_TYPE debugGLDeleteBuffers(GrGLsizei n, const GrGLuint* ids) {
762 // first potentially unbind the buffers
763 for (int i = 0; i < n; ++i) {
764
765 if (GrDebugGL::getInstance()->getArrayBuffer() &&
766 ids[i] == GrDebugGL::getInstance()->getArrayBuffer()->getID()) {
767 // this ID is the current array buffer
robertphillips@google.com0da37192012-03-19 14:42:13 +0000768 GrDebugGL::getInstance()->setArrayBuffer(NULL);
769 }
770 if (GrDebugGL::getInstance()->getElementArrayBuffer() &&
771 ids[i] == GrDebugGL::getInstance()->getElementArrayBuffer()->getID()) {
772 // this ID is the current element array buffer
robertphillips@google.com0da37192012-03-19 14:42:13 +0000773 GrDebugGL::getInstance()->setElementArrayBuffer(NULL);
774 }
775 }
776
777 // then actually "delete" the buffers
778 for (int i = 0; i < n; ++i) {
779 GrBufferObj *buffer = GrDebugGL::getInstance()->findBuffer(ids[i]);
780 GrAlwaysAssert(buffer);
781
782 GrAlwaysAssert(!buffer->getDeleted());
783 buffer->deleteAction();
784 }
785}
786
787// map a buffer to the caller's address space
788GrGLvoid* GR_GL_FUNCTION_TYPE debugGLMapBuffer(GrGLenum target, GrGLenum access) {
789
790 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
791 GrAlwaysAssert(GR_GL_WRITE_ONLY == access); // GR_GL_READ_ONLY == access || || GR_GL_READ_WRIT == access);
792
793 GrBufferObj *buffer = NULL;
794 switch (target) {
795 case GR_GL_ARRAY_BUFFER:
796 buffer = GrDebugGL::getInstance()->getArrayBuffer();
797 break;
798 case GR_GL_ELEMENT_ARRAY_BUFFER:
799 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
800 break;
801 default:
802 GrCrash("Unexpected target to glMapBuffer");
803 break;
804 }
805
806 if (buffer) {
807 GrAlwaysAssert(!buffer->getMapped());
808 buffer->setMapped();
809 return buffer->getDataPtr();
810 }
811
812 GrAlwaysAssert(false);
813 return NULL; // no buffer bound to the target
814}
815
816// remove a buffer from the caller's address space
817// TODO: check if the "access" method from "glMapBuffer" was honored
818GrGLboolean GR_GL_FUNCTION_TYPE debugGLUnmapBuffer(GrGLenum target) {
819
820 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
821
822 GrBufferObj *buffer = NULL;
823 switch (target) {
824 case GR_GL_ARRAY_BUFFER:
825 buffer = GrDebugGL::getInstance()->getArrayBuffer();
826 break;
827 case GR_GL_ELEMENT_ARRAY_BUFFER:
828 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
829 break;
830 default:
831 GrCrash("Unexpected target to glUnmapBuffer");
832 break;
833 }
834
835 if (buffer) {
836 GrAlwaysAssert(buffer->getMapped());
837 buffer->resetMapped();
838 return GR_GL_TRUE;
839 }
840
841 GrAlwaysAssert(false);
842 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
843}
844
845GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) {
846
847 GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
848 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value || GR_GL_BUFFER_USAGE == value);
849
850 GrBufferObj *buffer = NULL;
851 switch (target) {
852 case GR_GL_ARRAY_BUFFER:
853 buffer = GrDebugGL::getInstance()->getArrayBuffer();
854 break;
855 case GR_GL_ELEMENT_ARRAY_BUFFER:
856 buffer = GrDebugGL::getInstance()->getElementArrayBuffer();
857 break;
858 }
859
860 GrAlwaysAssert(buffer);
861
862 switch (value) {
863 case GR_GL_BUFFER_MAPPED:
864 *params = GR_GL_FALSE;
865 if (buffer)
866 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
867 break;
868 case GR_GL_BUFFER_SIZE:
869 *params = 0;
870 if (buffer)
871 *params = buffer->getSize();
872 break;
873 case GR_GL_BUFFER_USAGE:
874 *params = GR_GL_STATIC_DRAW;
875 if (buffer)
876 *params = buffer->getUsage();
877 break;
878 default:
879 GrCrash("Unexpected value to glGetBufferParamateriv");
880 break;
881 }
882};
883
884GrGLenum GR_GL_FUNCTION_TYPE debugGLGetError() {
885 return GR_GL_NO_ERROR;
886}
887
888GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetIntegerv(GrGLenum pname, GrGLint* params) {
889 // TODO: remove from Ganesh the #defines for gets we don't use.
890 // We would like to minimize gets overall due to performance issues
891 switch (pname) {
892 case GR_GL_STENCIL_BITS:
893 *params = 8;
894 break;
895 case GR_GL_SAMPLES:
896 *params = 1;
897 break;
898 case GR_GL_FRAMEBUFFER_BINDING:
899 *params = 0;
900 break;
901 case GR_GL_VIEWPORT:
902 params[0] = 0;
903 params[1] = 0;
904 params[2] = 800;
905 params[3] = 600;
906 break;
907 case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
908 *params = 8;
909 break;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000910 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
911 *params = kDefaultMaxVertexUniformVectors;
912 break;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000913 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000914 *params = kDefaultMaxFragmentUniformVectors;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000915 break;
916 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
917 *params = 16 * 4;
918 break;
919 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
920 *params = 0;
921 break;
922 case GR_GL_COMPRESSED_TEXTURE_FORMATS:
923 break;
924 case GR_GL_MAX_TEXTURE_SIZE:
925 *params = 8192;
926 break;
927 case GR_GL_MAX_RENDERBUFFER_SIZE:
928 *params = 8192;
929 break;
930 case GR_GL_MAX_SAMPLES:
931 *params = 32;
932 break;
933 case GR_GL_MAX_VERTEX_ATTRIBS:
robertphillips@google.comf6f123d2012-03-21 17:57:55 +0000934 *params = kDefaultMaxVertexAttribs;
935 break;
936 case GR_GL_MAX_VARYING_VECTORS:
937 *params = kDefaultMaxVaryingVectors;
robertphillips@google.com0da37192012-03-19 14:42:13 +0000938 break;
939 case GR_GL_MAX_TEXTURE_UNITS:
940 *params = GrDebugGL::getInstance()->getMaxTextureUnits();
941 break;
942 default:
943 GrCrash("Unexpected pname to GetIntegerv");
944 }
945}
946// used for both the program and shader info logs
947GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog) {
948 if (length) {
949 *length = 0;
950 }
951 if (bufsize > 0) {
952 *infolog = 0;
953 }
954}
955
956// used for both the program and shader params
957GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetShaderOrProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) {
958 switch (pname) {
959 case GR_GL_LINK_STATUS: // fallthru
960 case GR_GL_COMPILE_STATUS:
961 *params = GR_GL_TRUE;
962 break;
963 case GR_GL_INFO_LOG_LENGTH:
964 *params = 0;
965 break;
966 // we don't expect any other pnames
967 default:
968 GrCrash("Unexpected pname to GetProgramiv");
969 break;
970 }
971}
972
973namespace {
974template <typename T>
975void query_result(GrGLenum GLtarget, GrGLenum pname, T *params) {
976 switch (pname) {
977 case GR_GL_QUERY_RESULT_AVAILABLE:
978 *params = GR_GL_TRUE;
979 break;
980 case GR_GL_QUERY_RESULT:
981 *params = 0;
982 break;
983 default:
984 GrCrash("Unexpected pname passed to GetQueryObject.");
985 break;
986 }
987}
988}
989
990// Queries on the null GL just don't do anything at all. We could potentially make
991// the timers work.
992GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) {
993 switch (pname) {
994 case GR_GL_CURRENT_QUERY:
995 *params = 0;
996 break;
997 case GR_GL_QUERY_COUNTER_BITS:
998 *params = 32;
999 break;
1000 default:
1001 GrCrash("Unexpected pname passed GetQueryiv.");
1002 }
1003}
1004GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) {
1005 query_result(id, pname, params);
1006}
1007GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) {
1008 query_result(id, pname, params);
1009}
1010GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) {
1011 query_result(id, pname, params);
1012}
1013GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) {
1014 query_result(id, pname, params);
1015}
1016
1017const GrGLubyte* GR_GL_FUNCTION_TYPE debugGLGetString(GrGLenum name) {
1018 switch (name) {
1019 case GR_GL_EXTENSIONS:
1020 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";
1021 case GR_GL_VERSION:
1022 return (const GrGLubyte*)"4.0 Null GL";
1023 case GR_GL_SHADING_LANGUAGE_VERSION:
1024 return (const GrGLubyte*)"4.20.8 Null GLSL";
1025 default:
1026 GrCrash("Unexpected name to GetString");
1027 return NULL;
1028 }
1029}
1030
1031// we used to use this to query stuff about externally created textures, now we just
1032// require clients to tell us everything about the texture.
1033GrGLvoid GR_GL_FUNCTION_TYPE debugGLGetTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params) {
1034 GrCrash("Should never query texture parameters.");
1035}
1036
1037GrGLint GR_GL_FUNCTION_TYPE debugGLGetUniformLocation(GrGLuint program, const char* name) {
1038 static int gUniLocation = 0;
1039 return ++gUniLocation;
1040}
1041
1042const GrGLInterface* GrGLCreateDebugInterface() {
1043 // The gl functions are not context-specific so we create one global
1044 // interface
1045 static SkAutoTUnref<GrGLInterface> glInterface;
1046 if (!glInterface.get()) {
1047 GrGLInterface* interface = new GrGLInterface;
1048 glInterface.reset(interface);
1049 interface->fBindingsExported = kDesktop_GrGLBinding;
1050 interface->fActiveTexture = debugGLActiveTexture;
1051 interface->fAttachShader = debugGLAttachShader;
1052 interface->fBeginQuery = debugGLBeginQuery;
1053 interface->fBindAttribLocation = debugGLBindAttribLocation;
1054 interface->fBindBuffer = debugGLBindBuffer;
1055 interface->fBindFragDataLocation = debugGLBindFragDataLocation;
1056 interface->fBindTexture = debugGLBindTexture;
1057 interface->fBlendColor = debugGLBlendColor;
1058 interface->fBlendFunc = debugGLBlendFunc;
1059 interface->fBufferData = debugGLBufferData;
1060 interface->fBufferSubData = debugGLBufferSubData;
1061 interface->fClear = debugGLClear;
1062 interface->fClearColor = debugGLClearColor;
1063 interface->fClearStencil = debugGLClearStencil;
1064 interface->fColorMask = debugGLColorMask;
1065 interface->fCompileShader = debugGLCompileShader;
1066 interface->fCompressedTexImage2D = debugGLCompressedTexImage2D;
1067 interface->fCreateProgram = debugGLCreateProgram;
1068 interface->fCreateShader = debugGLCreateShader;
1069 interface->fCullFace = debugGLCullFace;
1070 interface->fDeleteBuffers = debugGLDeleteBuffers;
1071 interface->fDeleteProgram = debugGLDeleteProgram;
1072 interface->fDeleteQueries = debugGLDeleteIds;
1073 interface->fDeleteShader = debugGLDeleteShader;
1074 interface->fDeleteTextures = debugGLDeleteIds;
1075 interface->fDepthMask = debugGLDepthMask;
1076 interface->fDisable = debugGLDisable;
1077 interface->fDisableVertexAttribArray = debugGLDisableVertexAttribArray;
1078 interface->fDrawArrays = debugGLDrawArrays;
1079 interface->fDrawBuffer = debugGLDrawBuffer;
1080 interface->fDrawBuffers = debugGLDrawBuffers;
1081 interface->fDrawElements = debugGLDrawElements;
1082 interface->fEnable = debugGLEnable;
1083 interface->fEnableVertexAttribArray = debugGLEnableVertexAttribArray;
1084 interface->fEndQuery = debugGLEndQuery;
1085 interface->fFinish = debugGLFinish;
1086 interface->fFlush = debugGLFlush;
1087 interface->fFrontFace = debugGLFrontFace;
1088 interface->fGenBuffers = debugGLGenBuffers;
1089 interface->fGenQueries = debugGLGenIds;
1090 interface->fGenTextures = debugGLGenIds;
1091 interface->fGetBufferParameteriv = debugGLGetBufferParameteriv;
1092 interface->fGetError = debugGLGetError;
1093 interface->fGetIntegerv = debugGLGetIntegerv;
1094 interface->fGetQueryObjecti64v = debugGLGetQueryObjecti64v;
1095 interface->fGetQueryObjectiv = debugGLGetQueryObjectiv;
1096 interface->fGetQueryObjectui64v = debugGLGetQueryObjectui64v;
1097 interface->fGetQueryObjectuiv = debugGLGetQueryObjectuiv;
1098 interface->fGetQueryiv = debugGLGetQueryiv;
1099 interface->fGetProgramInfoLog = debugGLGetInfoLog;
1100 interface->fGetProgramiv = debugGLGetShaderOrProgramiv;
1101 interface->fGetShaderInfoLog = debugGLGetInfoLog;
1102 interface->fGetShaderiv = debugGLGetShaderOrProgramiv;
1103 interface->fGetString = debugGLGetString;
1104 interface->fGetTexLevelParameteriv = debugGLGetTexLevelParameteriv;
1105 interface->fGetUniformLocation = debugGLGetUniformLocation;
1106 interface->fLineWidth = debugGLLineWidth;
1107 interface->fLinkProgram = debugGLLinkProgram;
1108 interface->fPixelStorei = debugGLPixelStorei;
1109 interface->fQueryCounter = debugGLQueryCounter;
1110 interface->fReadBuffer = debugGLReadBuffer;
1111 interface->fReadPixels = debugGLReadPixels;
1112 interface->fScissor = debugGLScissor;
1113 interface->fShaderSource = debugGLShaderSource;
1114 interface->fStencilFunc = debugGLStencilFunc;
1115 interface->fStencilFuncSeparate = debugGLStencilFuncSeparate;
1116 interface->fStencilMask = debugGLStencilMask;
1117 interface->fStencilMaskSeparate = debugGLStencilMaskSeparate;
1118 interface->fStencilOp = debugGLStencilOp;
1119 interface->fStencilOpSeparate = debugGLStencilOpSeparate;
1120 interface->fTexImage2D = debugGLTexImage2D;
1121 interface->fTexParameteri = debugGLTexParameteri;
1122 interface->fTexSubImage2D = debugGLTexSubImage2D;
1123 interface->fTexStorage2D = debugGLTexStorage2D;
1124 interface->fUniform1f = debugGLUniform1f;
1125 interface->fUniform1i = debugGLUniform1i;
1126 interface->fUniform1fv = debugGLUniform1fv;
1127 interface->fUniform1iv = debugGLUniform1iv;
1128 interface->fUniform2f = debugGLUniform2f;
1129 interface->fUniform2i = debugGLUniform2i;
1130 interface->fUniform2fv = debugGLUniform2fv;
1131 interface->fUniform2iv = debugGLUniform2iv;
1132 interface->fUniform3f = debugGLUniform3f;
1133 interface->fUniform3i = debugGLUniform3i;
1134 interface->fUniform3fv = debugGLUniform3fv;
1135 interface->fUniform3iv = debugGLUniform3iv;
1136 interface->fUniform4f = debugGLUniform4f;
1137 interface->fUniform4i = debugGLUniform4i;
1138 interface->fUniform4fv = debugGLUniform4fv;
1139 interface->fUniform4iv = debugGLUniform4iv;
1140 interface->fUniformMatrix2fv = debugGLUniformMatrix2fv;
1141 interface->fUniformMatrix3fv = debugGLUniformMatrix3fv;
1142 interface->fUniformMatrix4fv = debugGLUniformMatrix4fv;
1143 interface->fUseProgram = debugGLUseProgram;
1144 interface->fVertexAttrib4fv = debugGLVertexAttrib4fv;
1145 interface->fVertexAttribPointer = debugGLVertexAttribPointer;
1146 interface->fViewport = debugGLViewport;
1147 interface->fBindFramebuffer = debugGLBindFramebuffer;
1148 interface->fBindRenderbuffer = debugGLBindRenderbuffer;
1149 interface->fCheckFramebufferStatus = debugGLCheckFramebufferStatus;
1150 interface->fDeleteFramebuffers = debugGLDeleteFramebuffers;
1151 interface->fDeleteRenderbuffers = debugGLDeleteRenderbuffers;
1152 interface->fFramebufferRenderbuffer = debugGLFramebufferRenderbuffer;
1153 interface->fFramebufferTexture2D = debugGLFramebufferTexture2D;
robertphillips@google.comf6f123d2012-03-21 17:57:55 +00001154 interface->fGenFramebuffers = debugGLGenFramebuffers;
robertphillips@google.com0da37192012-03-19 14:42:13 +00001155 interface->fGenRenderbuffers = debugGLGenIds;
1156 interface->fGetFramebufferAttachmentParameteriv = debugGLGetFramebufferAttachmentParameteriv;
1157 interface->fGetRenderbufferParameteriv = debugGLGetRenderbufferParameteriv;
1158 interface->fRenderbufferStorage = debugGLRenderbufferStorage;
1159 interface->fRenderbufferStorageMultisample = debugGLRenderbufferStorageMultisample;
1160 interface->fBlitFramebuffer = debugGLBlitFramebuffer;
1161 interface->fResolveMultisampleFramebuffer = debugGLResolveMultisampleFramebuffer;
1162 interface->fMapBuffer = debugGLMapBuffer;
1163 interface->fUnmapBuffer = debugGLUnmapBuffer;
1164 interface->fBindFragDataLocationIndexed = debugGLBindFragDataLocationIndexed;
1165 }
1166 glInterface.get()->ref();
1167 return glInterface.get();
1168}