1
2 /*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "DebugGLTestContext.h"
10
11 #include "GrBufferObj.h"
12 #include "GrFrameBufferObj.h"
13 #include "GrProgramObj.h"
14 #include "GrRenderBufferObj.h"
15 #include "GrShaderObj.h"
16 #include "GrTextureObj.h"
17 #include "GrTextureUnitObj.h"
18 #include "GrVertexArrayObj.h"
19 #include "gl/GrGLTestInterface.h"
20
21 #include "SkMutex.h"
22
23 namespace {
24
25 // Helper macro to make creating an object (where you need to get back a derived type) easier
26 #define CREATE(className, classEnum) \
27 reinterpret_cast<className *>(this->createObj(classEnum))
28
29 // Helper macro to make creating an object (where you need to get back a derived type) easier
30 #define FIND(id, className, classEnum) \
31 reinterpret_cast<className *>(this->findObject(id, classEnum))
32
33 class DebugInterface : public GrGLTestInterface {
34 public:
DebugInterface()35 DebugInterface()
36 : fCurrGenericID(0)
37 , fCurrTextureUnit(0)
38 , fVertexArray(nullptr)
39 , fPackRowLength(0)
40 , fUnpackRowLength(0)
41 , fPackAlignment(4)
42 , fFrameBuffer(nullptr)
43 , fRenderBuffer(nullptr)
44 , fProgram(nullptr)
45 , fAbandoned(false) {
46 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
47 fTextureUnits[i] =
48 reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit_ObjTypes));
49 fTextureUnits[i]->ref();
50 fTextureUnits[i]->setNumber(i);
51 }
52 memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
53 this->init(kGL_GrGLStandard);
54 }
55
~DebugInterface()56 ~DebugInterface() override {
57 // unref & delete the texture units first so they don't show up on the leak report
58 for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
59 fTextureUnits[i]->unref();
60 fTextureUnits[i]->deleteAction();
61 }
62 for (int i = 0; i < fObjects.count(); ++i) {
63 delete fObjects[i];
64 }
65 fObjects.reset();
66
67 memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
68 fVertexArray = nullptr;
69
70 this->report();
71 }
72
abandon() const73 void abandon() const override { fAbandoned = true; }
74
activeTexture(GrGLenum texture)75 GrGLvoid activeTexture(GrGLenum texture) override {
76 // Ganesh offsets the texture unit indices
77 texture -= GR_GL_TEXTURE0;
78 GrAlwaysAssert(texture < kDefaultMaxTextureUnits);
79 fCurrTextureUnit = texture;
80 }
81
attachShader(GrGLuint programID,GrGLuint shaderID)82 GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override {
83
84 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
85 GrAlwaysAssert(program);
86
87 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
88 GrAlwaysAssert(shader);
89
90 program->AttachShader(shader);
91 }
92
93 ////////////////////////////////////////////////////////////////////////////////
bindTexture(GrGLenum target,GrGLuint textureID)94 GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override {
95 GrAlwaysAssert(target == GR_GL_TEXTURE_2D ||
96 target == GR_GL_TEXTURE_RECTANGLE ||
97 target == GR_GL_TEXTURE_EXTERNAL);
98
99 // a textureID of 0 is acceptable - it binds to the default texture target
100 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
101
102 this->setTexture(texture);
103 }
104
105 ////////////////////////////////////////////////////////////////////////////////
bufferData(GrGLenum target,GrGLsizeiptr size,const GrGLvoid * data,GrGLenum usage)106 GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
107 GrGLenum usage) override {
108 GrAlwaysAssert(size >= 0);
109 GrAlwaysAssert(GR_GL_STREAM_DRAW == usage ||
110 GR_GL_STATIC_DRAW == usage ||
111 GR_GL_DYNAMIC_DRAW == usage);
112
113 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
114 GrAlwaysAssert(buffer);
115 GrAlwaysAssert(buffer->getBound());
116
117 buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
118 buffer->setUsage(usage);
119 }
120
121
pixelStorei(GrGLenum pname,GrGLint param)122 GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override {
123
124 switch (pname) {
125 case GR_GL_UNPACK_ROW_LENGTH:
126 fUnpackRowLength = param;
127 break;
128 case GR_GL_PACK_ROW_LENGTH:
129 fPackRowLength = param;
130 break;
131 case GR_GL_UNPACK_ALIGNMENT:
132 break;
133 case GR_GL_PACK_ALIGNMENT:
134 fPackAlignment = param;
135 break;
136 default:
137 GrAlwaysAssert(false);
138 break;
139 }
140 }
141
readPixels(GrGLint x,GrGLint y,GrGLsizei width,GrGLsizei height,GrGLenum format,GrGLenum type,GrGLvoid * pixels)142 GrGLvoid readPixels(GrGLint x,
143 GrGLint y,
144 GrGLsizei width,
145 GrGLsizei height,
146 GrGLenum format,
147 GrGLenum type,
148 GrGLvoid* pixels) override {
149
150 GrGLint pixelsInRow = width;
151 if (fPackRowLength > 0) {
152 pixelsInRow = fPackRowLength;
153 }
154
155 GrGLint componentsPerPixel = 0;
156
157 switch (format) {
158 case GR_GL_RGBA:
159 // fallthrough
160 case GR_GL_BGRA:
161 componentsPerPixel = 4;
162 break;
163 case GR_GL_RGB:
164 componentsPerPixel = 3;
165 break;
166 case GR_GL_RED:
167 componentsPerPixel = 1;
168 break;
169 default:
170 GrAlwaysAssert(false);
171 break;
172 }
173
174 GrGLint alignment = fPackAlignment;
175
176 GrGLint componentSize = 0; // size (in bytes) of a single component
177
178 switch (type) {
179 case GR_GL_UNSIGNED_BYTE:
180 componentSize = 1;
181 break;
182 default:
183 GrAlwaysAssert(false);
184 break;
185 }
186
187 GrGLint rowStride = 0; // number of components (not bytes) to skip
188 if (componentSize >= alignment) {
189 rowStride = componentsPerPixel * pixelsInRow;
190 } else {
191 float fTemp =
192 sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
193 static_cast<float>(alignment));
194 rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
195 }
196
197 GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
198 for (int y = 0; y < height; ++y) {
199 memset(scanline, 0, componentsPerPixel * componentSize * width);
200 scanline += rowStride;
201 }
202 }
203
useProgram(GrGLuint programID)204 GrGLvoid useProgram(GrGLuint programID) override {
205
206 // A programID of 0 is legal
207 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
208
209 this->useProgram(program);
210 }
211
bindFramebuffer(GrGLenum target,GrGLuint frameBufferID)212 GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override {
213
214 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target ||
215 GR_GL_READ_FRAMEBUFFER == target ||
216 GR_GL_DRAW_FRAMEBUFFER);
217
218 // a frameBufferID of 0 is acceptable - it binds to the default
219 // frame buffer
220 GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj,
221 kFrameBuffer_ObjTypes);
222
223 this->setFrameBuffer(frameBuffer);
224 }
225
bindRenderbuffer(GrGLenum target,GrGLuint renderBufferID)226 GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) override {
227
228 GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
229
230 // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
231 GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj,
232 kRenderBuffer_ObjTypes);
233
234 this->setRenderBuffer(renderBuffer);
235 }
236
deleteTextures(GrGLsizei n,const GrGLuint * textures)237 GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override {
238 // first potentially unbind the texture
239 for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) {
240 GrTextureUnitObj *pTU = this->getTextureUnit(i);
241
242 if (pTU->getTexture()) {
243 for (int j = 0; j < n; ++j) {
244
245 if (textures[j] == pTU->getTexture()->getID()) {
246 // this ID is the current texture - revert the binding to 0
247 pTU->setTexture(nullptr);
248 }
249 }
250 }
251 }
252
253 // TODO: fuse the following block with DeleteRenderBuffers?
254 // Open GL will remove a deleted render buffer from the active
255 // frame buffer but not from any other frame buffer
256 if (this->getFrameBuffer()) {
257
258 GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
259
260 for (int i = 0; i < n; ++i) {
261
262 if (frameBuffer->getColor() &&
263 textures[i] == frameBuffer->getColor()->getID()) {
264 frameBuffer->setColor(nullptr);
265 }
266 if (frameBuffer->getDepth() &&
267 textures[i] == frameBuffer->getDepth()->getID()) {
268 frameBuffer->setDepth(nullptr);
269 }
270 if (frameBuffer->getStencil() &&
271 textures[i] == frameBuffer->getStencil()->getID()) {
272 frameBuffer->setStencil(nullptr);
273 }
274 }
275 }
276
277 // then actually "delete" the buffers
278 for (int i = 0; i < n; ++i) {
279 GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_ObjTypes);
280 GrAlwaysAssert(buffer);
281
282 // OpenGL gives no guarantees if a texture is deleted while attached to
283 // something other than the currently bound frame buffer
284 GrAlwaysAssert(!buffer->getBound());
285
286 GrAlwaysAssert(!buffer->getDeleted());
287 buffer->deleteAction();
288 }
289
290 }
291
deleteFramebuffers(GrGLsizei n,const GrGLuint * frameBuffers)292 GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) override {
293
294 // first potentially unbind the buffers
295 if (this->getFrameBuffer()) {
296 for (int i = 0; i < n; ++i) {
297
298 if (frameBuffers[i] ==
299 this->getFrameBuffer()->getID()) {
300 // this ID is the current frame buffer - rebind to the default
301 this->setFrameBuffer(nullptr);
302 }
303 }
304 }
305
306 // then actually "delete" the buffers
307 for (int i = 0; i < n; ++i) {
308 GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj,
309 kFrameBuffer_ObjTypes);
310 GrAlwaysAssert(buffer);
311
312 GrAlwaysAssert(!buffer->getDeleted());
313 buffer->deleteAction();
314 }
315 }
316
deleteRenderbuffers(GrGLsizei n,const GrGLuint * renderBuffers)317 GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) override {
318
319 // first potentially unbind the buffers
320 if (this->getRenderBuffer()) {
321 for (int i = 0; i < n; ++i) {
322
323 if (renderBuffers[i] ==
324 this->getRenderBuffer()->getID()) {
325 // this ID is the current render buffer - make no
326 // render buffer be bound
327 this->setRenderBuffer(nullptr);
328 }
329 }
330 }
331
332 // TODO: fuse the following block with DeleteTextures?
333 // Open GL will remove a deleted render buffer from the active frame
334 // buffer but not from any other frame buffer
335 if (this->getFrameBuffer()) {
336
337 GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
338
339 for (int i = 0; i < n; ++i) {
340
341 if (frameBuffer->getColor() &&
342 renderBuffers[i] == frameBuffer->getColor()->getID()) {
343 frameBuffer->setColor(nullptr);
344 }
345 if (frameBuffer->getDepth() &&
346 renderBuffers[i] == frameBuffer->getDepth()->getID()) {
347 frameBuffer->setDepth(nullptr);
348 }
349 if (frameBuffer->getStencil() &&
350 renderBuffers[i] == frameBuffer->getStencil()->getID()) {
351 frameBuffer->setStencil(nullptr);
352 }
353 }
354 }
355
356 // then actually "delete" the buffers
357 for (int i = 0; i < n; ++i) {
358 GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferObj,
359 kRenderBuffer_ObjTypes);
360 GrAlwaysAssert(buffer);
361
362 // OpenGL gives no guarantees if a render buffer is deleted
363 // while attached to something other than the currently
364 // bound frame buffer
365 GrAlwaysAssert(!buffer->getColorBound());
366 GrAlwaysAssert(!buffer->getDepthBound());
367 // However, at GrContext destroy time we release all GrRsources and so stencil buffers
368 // may get deleted before FBOs that refer to them.
369 //GrAlwaysAssert(!buffer->getStencilBound());
370
371 GrAlwaysAssert(!buffer->getDeleted());
372 buffer->deleteAction();
373 }
374 }
375
renderbufferStorage(GrGLenum target,GrGLenum internalformat,GrGLsizei width,GrGLsizei height)376 GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width,
377 GrGLsizei height) override {
378 GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
379 GrRenderBufferObj* renderBuffer = this->getRenderBuffer();
380 GrAlwaysAssert(renderBuffer);
381 renderBuffer->setNumSamples(1);
382 }
383
renderbufferStorageMultisample(GrGLenum target,GrGLsizei samples,GrGLenum internalformat,GrGLsizei width,GrGLsizei height)384 GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples,
385 GrGLenum internalformat, GrGLsizei width,
386 GrGLsizei height) override {
387 GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
388 GrRenderBufferObj* renderBuffer = this->getRenderBuffer();
389 GrAlwaysAssert(renderBuffer);
390 renderBuffer->setNumSamples(samples);
391 }
392
namedRenderbufferStorage(GrGLuint renderbuffer,GrGLenum GrGLinternalformat,GrGLsizei width,GrGLsizei height)393 GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat,
394 GrGLsizei width, GrGLsizei height) override {
395 SK_ABORT("Not implemented");
396 }
397
namedRenderbufferStorageMultisample(GrGLuint renderbuffer,GrGLsizei samples,GrGLenum GrGLinternalformat,GrGLsizei width,GrGLsizei height)398 GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples,
399 GrGLenum GrGLinternalformat, GrGLsizei width,
400 GrGLsizei height) override {
401 SK_ABORT("Not implemented");
402 }
403
framebufferRenderbuffer(GrGLenum target,GrGLenum attachment,GrGLenum renderbuffertarget,GrGLuint renderBufferID)404 GrGLvoid framebufferRenderbuffer(GrGLenum target,
405 GrGLenum attachment,
406 GrGLenum renderbuffertarget,
407 GrGLuint renderBufferID) override {
408
409 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
410 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
411 GR_GL_DEPTH_ATTACHMENT == attachment ||
412 GR_GL_STENCIL_ATTACHMENT == attachment);
413 GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
414
415 GrFrameBufferObj *framebuffer = this->getFrameBuffer();
416 // A render buffer cannot be attached to the default framebuffer
417 GrAlwaysAssert(framebuffer);
418
419 // a renderBufferID of 0 is acceptable - it unbinds the current
420 // render buffer
421 GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferObj,
422 kRenderBuffer_ObjTypes);
423
424 switch (attachment) {
425 case GR_GL_COLOR_ATTACHMENT0:
426 framebuffer->setColor(renderbuffer);
427 break;
428 case GR_GL_DEPTH_ATTACHMENT:
429 framebuffer->setDepth(renderbuffer);
430 break;
431 case GR_GL_STENCIL_ATTACHMENT:
432 framebuffer->setStencil(renderbuffer);
433 break;
434 default:
435 GrAlwaysAssert(false);
436 break;
437 };
438
439 }
440
namedFramebufferRenderbuffer(GrGLuint framebuffer,GrGLenum attachment,GrGLenum renderbuffertarget,GrGLuint renderbuffer)441 GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment,
442 GrGLenum renderbuffertarget,
443 GrGLuint renderbuffer) override {
444 SK_ABORT("Not implemented");
445 }
446
447 ////////////////////////////////////////////////////////////////////////////////
framebufferTexture2D(GrGLenum target,GrGLenum attachment,GrGLenum textarget,GrGLuint textureID,GrGLint level)448 GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget,
449 GrGLuint textureID, GrGLint level) override {
450
451 GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
452 GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
453 GR_GL_DEPTH_ATTACHMENT == attachment ||
454 GR_GL_STENCIL_ATTACHMENT == attachment);
455 GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
456
457 GrFrameBufferObj *framebuffer = this->getFrameBuffer();
458 // A texture cannot be attached to the default framebuffer
459 GrAlwaysAssert(framebuffer);
460
461 // A textureID of 0 is allowed - it unbinds the currently bound texture
462 GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
463 if (texture) {
464 // The texture shouldn't be bound to a texture unit - this
465 // could lead to a feedback loop
466 GrAlwaysAssert(!texture->getBound());
467 }
468
469 GrAlwaysAssert(0 == level);
470
471 switch (attachment) {
472 case GR_GL_COLOR_ATTACHMENT0:
473 framebuffer->setColor(texture);
474 break;
475 case GR_GL_DEPTH_ATTACHMENT:
476 framebuffer->setDepth(texture);
477 break;
478 case GR_GL_STENCIL_ATTACHMENT:
479 framebuffer->setStencil(texture);
480 break;
481 default:
482 GrAlwaysAssert(false);
483 break;
484 };
485 }
486
framebufferTexture2DMultisample(GrGLenum target,GrGLenum attachment,GrGLenum textarget,GrGLuint texture,GrGLint level,GrGLsizei samples)487 GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachment,
488 GrGLenum textarget, GrGLuint texture, GrGLint level,
489 GrGLsizei samples) override {
490 SK_ABORT("Not implemented");
491 }
492
namedFramebufferTexture1D(GrGLuint framebuffer,GrGLenum attachment,GrGLenum textarget,GrGLuint texture,GrGLint level)493 GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment,
494 GrGLenum textarget, GrGLuint texture,
495 GrGLint level) override {
496 SK_ABORT("Not implemented");
497 }
498
namedFramebufferTexture2D(GrGLuint framebuffer,GrGLenum attachment,GrGLenum textarget,GrGLuint texture,GrGLint level)499 GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment,
500 GrGLenum textarget, GrGLuint texture,
501 GrGLint level) override {
502 SK_ABORT("Not implemented");
503 }
504
namedFramebufferTexture3D(GrGLuint framebuffer,GrGLenum attachment,GrGLenum textarget,GrGLuint texture,GrGLint level,GrGLint zoffset)505 GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment,
506 GrGLenum textarget, GrGLuint texture, GrGLint level,
507 GrGLint zoffset) override {
508 SK_ABORT("Not implemented");
509 }
510
createProgram()511 GrGLuint createProgram() override {
512
513 GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes);
514
515 return program->getID();
516 }
517
createShader(GrGLenum type)518 GrGLuint createShader(GrGLenum type) override {
519
520 GrAlwaysAssert(GR_GL_VERTEX_SHADER == type ||
521 GR_GL_FRAGMENT_SHADER == type);
522
523 GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes);
524 shader->setType(type);
525
526 return shader->getID();
527 }
528
checkFramebufferStatus(GrGLenum target)529 GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; }
530
deleteProgram(GrGLuint programID)531 GrGLvoid deleteProgram(GrGLuint programID) override {
532
533 GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
534 GrAlwaysAssert(program);
535
536 if (program->getRefCount()) {
537 // someone is still using this program so we can't delete it here
538 program->setMarkedForDeletion();
539 } else {
540 program->deleteAction();
541 }
542 }
543
deleteShader(GrGLuint shaderID)544 GrGLvoid deleteShader(GrGLuint shaderID) override {
545
546 GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
547 GrAlwaysAssert(shader);
548
549 if (shader->getRefCount()) {
550 // someone is still using this shader so we can't delete it here
551 shader->setMarkedForDeletion();
552 } else {
553 shader->deleteAction();
554 }
555 }
556
genBuffers(GrGLsizei n,GrGLuint * ids)557 GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
558 this->genObjs(kBuffer_ObjTypes, n, ids);
559 }
560
genFramebuffers(GrGLsizei n,GrGLuint * ids)561 GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override {
562 this->genObjs(kFrameBuffer_ObjTypes, n, ids);
563 }
564
genRenderbuffers(GrGLsizei n,GrGLuint * ids)565 GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override {
566 this->genObjs(kRenderBuffer_ObjTypes, n, ids);
567 }
568
genTextures(GrGLsizei n,GrGLuint * ids)569 GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override {
570 this->genObjs(kTexture_ObjTypes, n, ids);
571 }
572
genVertexArrays(GrGLsizei n,GrGLuint * ids)573 GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override {
574 this->genObjs(kVertexArray_ObjTypes, n, ids);
575 }
576
genQueries(GrGLsizei n,GrGLuint * ids)577 GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
578
getError()579 GrGLenum getError() override { return GR_GL_NO_ERROR; }
580
getIntegerv(GrGLenum pname,GrGLint * params)581 GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
582 // TODO: remove from Ganesh the #defines for gets we don't use.
583 // We would like to minimize gets overall due to performance issues
584 switch (pname) {
585 case GR_GL_CONTEXT_PROFILE_MASK:
586 *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
587 break;
588 case GR_GL_STENCIL_BITS:
589 *params = 8;
590 break;
591 case GR_GL_SAMPLES: {
592 GrFrameBufferObj* framebuffer = this->getFrameBuffer();
593 GrAlwaysAssert(framebuffer);
594 int numSamples = 0;
595
596 if (GrFBBindableObj* stencil = framebuffer->getStencil()) {
597 numSamples = stencil->numSamples();
598 }
599 if (GrFBBindableObj* depth = framebuffer->getDepth()) {
600 GrAlwaysAssert(!numSamples || numSamples == depth->numSamples());
601 numSamples = depth->numSamples();
602 }
603 if (GrFBBindableObj* color = framebuffer->getColor()) {
604 GrAlwaysAssert(!numSamples || numSamples == color->numSamples());
605 numSamples = color->numSamples();
606 }
607 GrAlwaysAssert(numSamples);
608 *params = numSamples;
609 break;
610 }
611 case GR_GL_FRAMEBUFFER_BINDING:
612 *params = 0;
613 break;
614 case GR_GL_VIEWPORT:
615 params[0] = 0;
616 params[1] = 0;
617 params[2] = 800;
618 params[3] = 600;
619 break;
620 case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
621 case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
622 case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
623 case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
624 *params = 8;
625 break;
626 case GR_GL_MAX_TEXTURE_COORDS:
627 *params = 8;
628 break;
629 case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
630 *params = kDefaultMaxVertexUniformVectors;
631 break;
632 case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
633 *params = kDefaultMaxFragmentUniformVectors;
634 break;
635 case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
636 *params = 16 * 4;
637 break;
638 case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
639 *params = 0;
640 break;
641 case GR_GL_COMPRESSED_TEXTURE_FORMATS:
642 break;
643 case GR_GL_MAX_TEXTURE_SIZE:
644 *params = 8192;
645 break;
646 case GR_GL_MAX_RENDERBUFFER_SIZE:
647 *params = 8192;
648 break;
649 case GR_GL_MAX_SAMPLES:
650 *params = 32;
651 break;
652 case GR_GL_MAX_VERTEX_ATTRIBS:
653 *params = kDefaultMaxVertexAttribs;
654 break;
655 case GR_GL_MAX_VARYING_VECTORS:
656 *params = kDefaultMaxVaryingVectors;
657 break;
658 case GR_GL_NUM_EXTENSIONS: {
659 GrGLint i = 0;
660 while (kExtensions[i++]);
661 *params = i;
662 break;
663 }
664 default:
665 SkFAIL("Unexpected pname to GetIntegerv");
666 }
667 }
668
getMultisamplefv(GrGLenum pname,GrGLuint index,GrGLfloat * val)669 GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
670 val[0] = val[1] = 0.5f;
671 }
672
getProgramiv(GrGLuint program,GrGLenum pname,GrGLint * params)673 GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
674 this->getShaderOrProgramiv(program, pname, params);
675 }
676
getProgramInfoLog(GrGLuint program,GrGLsizei bufsize,GrGLsizei * length,char * infolog)677 GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
678 char* infolog) override {
679 this->getInfoLog(program, bufsize, length, infolog);
680 }
681
getQueryiv(GrGLenum GLtarget,GrGLenum pname,GrGLint * params)682 GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
683 switch (pname) {
684 case GR_GL_CURRENT_QUERY:
685 *params = 0;
686 break;
687 case GR_GL_QUERY_COUNTER_BITS:
688 *params = 32;
689 break;
690 default:
691 SkFAIL("Unexpected pname passed GetQueryiv.");
692 }
693 }
694
getQueryObjecti64v(GrGLuint id,GrGLenum pname,GrGLint64 * params)695 GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
696 this->queryResult(id, pname, params);
697 }
698
getQueryObjectiv(GrGLuint id,GrGLenum pname,GrGLint * params)699 GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
700 this->queryResult(id, pname, params);
701 }
702
getQueryObjectui64v(GrGLuint id,GrGLenum pname,GrGLuint64 * params)703 GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
704 this->queryResult(id, pname, params);
705 }
706
getQueryObjectuiv(GrGLuint id,GrGLenum pname,GrGLuint * params)707 GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
708 this->queryResult(id, pname, params);
709 }
710
getShaderiv(GrGLuint shader,GrGLenum pname,GrGLint * params)711 GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
712 this->getShaderOrProgramiv(shader, pname, params);
713 }
714
getShaderInfoLog(GrGLuint shader,GrGLsizei bufsize,GrGLsizei * length,char * infolog)715 GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
716 char* infolog) override {
717 this->getInfoLog(shader, bufsize, length, infolog);
718 }
719
getString(GrGLenum name)720 const GrGLubyte* getString(GrGLenum name) override {
721 switch (name) {
722 case GR_GL_EXTENSIONS:
723 return CombinedExtensionString();
724 case GR_GL_VERSION:
725 return (const GrGLubyte*)"4.0 Debug GL";
726 case GR_GL_SHADING_LANGUAGE_VERSION:
727 return (const GrGLubyte*)"4.20.8 Debug GLSL";
728 case GR_GL_VENDOR:
729 return (const GrGLubyte*)"Debug Vendor";
730 case GR_GL_RENDERER:
731 return (const GrGLubyte*)"The Debug (Non-)Renderer";
732 default:
733 SkFAIL("Unexpected name passed to GetString");
734 return nullptr;
735 }
736 }
737
getStringi(GrGLenum name,GrGLuint i)738 const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override {
739 switch (name) {
740 case GR_GL_EXTENSIONS: {
741 GrGLint count;
742 this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count);
743 if ((GrGLint)i <= count) {
744 return (const GrGLubyte*) kExtensions[i];
745 } else {
746 return nullptr;
747 }
748 }
749 default:
750 SkFAIL("Unexpected name passed to GetStringi");
751 return nullptr;
752 }
753 }
754
getTexLevelParameteriv(GrGLenum target,GrGLint level,GrGLenum pname,GrGLint * params)755 GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname,
756 GrGLint* params) override {
757 // we used to use this to query stuff about externally created textures,
758 // now we just require clients to tell us everything about the texture.
759 SkFAIL("Should never query texture parameters.");
760 }
761
deleteVertexArrays(GrGLsizei n,const GrGLuint * ids)762 GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override {
763 for (GrGLsizei i = 0; i < n; ++i) {
764 GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArray_ObjTypes);
765 GrAlwaysAssert(array);
766
767 // Deleting the current vertex array binds object 0
768 if (this->getVertexArray() == array) {
769 this->setVertexArray(nullptr);
770 }
771
772 if (array->getRefCount()) {
773 // someone is still using this vertex array so we can't delete it here
774 array->setMarkedForDeletion();
775 } else {
776 array->deleteAction();
777 }
778 }
779 }
780
bindVertexArray(GrGLuint id)781 GrGLvoid bindVertexArray(GrGLuint id) override {
782 GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTypes);
783 GrAlwaysAssert((0 == id) || array);
784 this->setVertexArray(array);
785 }
786
bindBuffer(GrGLenum target,GrGLuint bufferID)787 GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override {
788 GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes);
789 // 0 is a permissible bufferID - it unbinds the current buffer
790
791 this->setBuffer(GetBufferIndex(target), buffer);
792 }
793
794 // deleting a bound buffer has the side effect of binding 0
deleteBuffers(GrGLsizei n,const GrGLuint * ids)795 GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
796 // first potentially unbind the buffers
797 for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) {
798 GrBufferObj* buffer = fBoundBuffers[buffIdx];
799 if (!buffer) {
800 continue;
801 }
802 for (int i = 0; i < n; ++i) {
803 if (ids[i] == buffer->getID()) {
804 this->setBuffer(buffIdx, nullptr);
805 break;
806 }
807 }
808 }
809
810 // then actually "delete" the buffers
811 for (int i = 0; i < n; ++i) {
812 GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes);
813 GrAlwaysAssert(buffer);
814
815 GrAlwaysAssert(!buffer->getDeleted());
816 buffer->deleteAction();
817 }
818 }
819
820 // map a buffer to the caller's address space
mapBufferRange(GrGLenum target,GrGLintptr offset,GrGLsizeiptr length,GrGLbitfield access)821 GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
822 GrGLbitfield access) override {
823 // We only expect read access and we expect that the buffer or range is always invalidated.
824 GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access));
825 GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access);
826
827 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
828 if (buffer) {
829 GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
830 GrAlwaysAssert(!buffer->getMapped());
831 buffer->setMapped(offset, length);
832 return buffer->getDataPtr() + offset;
833 }
834
835 GrAlwaysAssert(false);
836 return nullptr; // no buffer bound to the target
837 }
838
mapBuffer(GrGLenum target,GrGLenum access)839 GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
840 GrAlwaysAssert(GR_GL_WRITE_ONLY == access);
841 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
842 return this->mapBufferRange(target, 0, buffer->getSize(),
843 GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT);
844 }
845
846 // remove a buffer from the caller's address space
847 // TODO: check if the "access" method from "glMapBuffer" was honored
unmapBuffer(GrGLenum target)848 GrGLboolean unmapBuffer(GrGLenum target) override {
849 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
850 if (buffer) {
851 GrAlwaysAssert(buffer->getMapped());
852 buffer->resetMapped();
853 return GR_GL_TRUE;
854 }
855
856 GrAlwaysAssert(false);
857 return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
858 }
859
flushMappedBufferRange(GrGLenum target,GrGLintptr offset,GrGLsizeiptr length)860 GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset,
861 GrGLsizeiptr length) override {
862 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
863 if (buffer) {
864 GrAlwaysAssert(buffer->getMapped());
865 GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
866 } else {
867 GrAlwaysAssert(false);
868 }
869 }
870
getBufferParameteriv(GrGLenum target,GrGLenum value,GrGLint * params)871 GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) override {
872
873 GrAlwaysAssert(GR_GL_BUFFER_SIZE == value ||
874 GR_GL_BUFFER_USAGE == value);
875
876 GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
877 GrAlwaysAssert(buffer);
878
879 switch (value) {
880 case GR_GL_BUFFER_MAPPED:
881 *params = GR_GL_FALSE;
882 if (buffer)
883 *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
884 break;
885 case GR_GL_BUFFER_SIZE:
886 *params = 0;
887 if (buffer)
888 *params = SkToInt(buffer->getSize());
889 break;
890 case GR_GL_BUFFER_USAGE:
891 *params = GR_GL_STATIC_DRAW;
892 if (buffer)
893 *params = buffer->getUsage();
894 break;
895 default:
896 SkFAIL("Unexpected value to glGetBufferParamateriv");
897 break;
898 }
899 }
900
901 private:
GetBufferIndex(GrGLenum glTarget)902 inline int static GetBufferIndex(GrGLenum glTarget) {
903 switch (glTarget) {
904 default: SkFAIL("Unexpected GL target to GetBufferIndex");
905 case GR_GL_ARRAY_BUFFER: return 0;
906 case GR_GL_ELEMENT_ARRAY_BUFFER: return 1;
907 case GR_GL_TEXTURE_BUFFER: return 2;
908 case GR_GL_DRAW_INDIRECT_BUFFER: return 3;
909 }
910 }
911 constexpr int static kNumBufferTargets = 4;
912
913 // the OpenGLES 2.0 spec says this must be >= 128
914 static const GrGLint kDefaultMaxVertexUniformVectors = 128;
915
916 // the OpenGLES 2.0 spec says this must be >=16
917 static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
918
919 // the OpenGLES 2.0 spec says this must be >= 8
920 static const GrGLint kDefaultMaxVertexAttribs = 8;
921
922 // the OpenGLES 2.0 spec says this must be >= 8
923 static const GrGLint kDefaultMaxVaryingVectors = 8;
924
925 // the OpenGLES 2.0 spec says this must be >= 2
926 static const GrGLint kDefaultMaxTextureUnits = 8;
927
928 static const char* kExtensions[];
929
930 GrGLuint fCurrGenericID;
931 GrGLuint fCurrTextureUnit;
932 GrTextureUnitObj* fTextureUnits[kDefaultMaxTextureUnits];
933 GrBufferObj* fBoundBuffers[kNumBufferTargets];
934 GrVertexArrayObj* fVertexArray;
935 GrGLint fPackRowLength;
936 GrGLint fUnpackRowLength;
937 GrGLint fPackAlignment;
938 GrFrameBufferObj* fFrameBuffer;
939 GrRenderBufferObj* fRenderBuffer;
940 GrProgramObj* fProgram;
941 mutable bool fAbandoned;
942 // global store of all objects
943 SkTArray<GrFakeRefObj *> fObjects;
944
CombinedExtensionString()945 static const GrGLubyte* CombinedExtensionString() {
946 static SkString gExtString;
947 static SkMutex gMutex;
948 gMutex.acquire();
949 if (0 == gExtString.size()) {
950 int i = 0;
951 while (kExtensions[i]) {
952 if (i > 0) {
953 gExtString.append(" ");
954 }
955 gExtString.append(kExtensions[i]);
956 ++i;
957 }
958 }
959 gMutex.release();
960 return (const GrGLubyte*) gExtString.c_str();
961 }
962
genGenericIds(GrGLsizei n,GrGLuint * ids)963 GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
964 for (int i = 0; i < n; ++i) {
965 ids[i] = ++fCurrGenericID;
966 }
967 }
968
getInfoLog(GrGLuint object,GrGLsizei bufsize,GrGLsizei * length,char * infolog)969 GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length,
970 char* infolog) {
971 if (length) {
972 *length = 0;
973 }
974 if (bufsize > 0) {
975 *infolog = 0;
976 }
977 }
978
getShaderOrProgramiv(GrGLuint object,GrGLenum pname,GrGLint * params)979 GrGLvoid getShaderOrProgramiv(GrGLuint object, GrGLenum pname, GrGLint* params) {
980 switch (pname) {
981 case GR_GL_LINK_STATUS: // fallthru
982 case GR_GL_COMPILE_STATUS:
983 *params = GR_GL_TRUE;
984 break;
985 case GR_GL_INFO_LOG_LENGTH:
986 *params = 0;
987 break;
988 // we don't expect any other pnames
989 default:
990 SkFAIL("Unexpected pname to GetProgramiv");
991 break;
992 }
993 }
994
995 template <typename T>
queryResult(GrGLenum GLtarget,GrGLenum pname,T * params)996 void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) {
997 switch (pname) {
998 case GR_GL_QUERY_RESULT_AVAILABLE:
999 *params = GR_GL_TRUE;
1000 break;
1001 case GR_GL_QUERY_RESULT:
1002 *params = 0;
1003 break;
1004 default:
1005 SkFAIL("Unexpected pname passed to GetQueryObject.");
1006 break;
1007 }
1008 }
1009
1010 enum ObjTypes {
1011 kTexture_ObjTypes = 0,
1012 kBuffer_ObjTypes,
1013 kRenderBuffer_ObjTypes,
1014 kFrameBuffer_ObjTypes,
1015 kShader_ObjTypes,
1016 kProgram_ObjTypes,
1017 kTextureUnit_ObjTypes,
1018 kVertexArray_ObjTypes,
1019 kObjTypeCount
1020 };
1021
1022 typedef GrFakeRefObj *(*Create)();
1023
1024 static Create gFactoryFunc[kObjTypeCount];
1025
genObjs(ObjTypes type,GrGLsizei n,GrGLuint * ids)1026 GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) {
1027 for (int i = 0; i < n; ++i) {
1028 GrAlwaysAssert(ids[i] == 0);
1029 GrFakeRefObj *obj = this->createObj(type);
1030 GrAlwaysAssert(obj);
1031 ids[i] = obj->getID();
1032 }
1033 }
1034
createObj(ObjTypes type)1035 GrFakeRefObj* createObj(ObjTypes type) {
1036 GrFakeRefObj *temp = (*gFactoryFunc[type])();
1037
1038 fObjects.push_back(temp);
1039
1040 return temp;
1041 }
1042
findObject(GrGLuint ID,ObjTypes type)1043 GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) {
1044 for (int i = 0; i < fObjects.count(); ++i) {
1045 if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) {
1046 // The application shouldn't be accessing objects
1047 // that (as far as OpenGL knows) were already deleted
1048 GrAlwaysAssert(!fObjects[i]->getDeleted());
1049 GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion());
1050 return fObjects[i];
1051 }
1052 }
1053 return nullptr;
1054 }
1055
getTextureUnit(int unit)1056 GrTextureUnitObj* getTextureUnit(int unit) {
1057 GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit);
1058
1059 return fTextureUnits[unit];
1060 }
1061
setBuffer(int buffIdx,GrBufferObj * buffer)1062 GrGLvoid setBuffer(int buffIdx, GrBufferObj* buffer) {
1063 if (fBoundBuffers[buffIdx]) {
1064 // automatically break the binding of the old buffer
1065 GrAlwaysAssert(fBoundBuffers[buffIdx]->getBound());
1066 fBoundBuffers[buffIdx]->resetBound();
1067
1068 GrAlwaysAssert(!fBoundBuffers[buffIdx]->getDeleted());
1069 fBoundBuffers[buffIdx]->unref();
1070 }
1071
1072 if (buffer) {
1073 GrAlwaysAssert(!buffer->getDeleted());
1074 buffer->ref();
1075
1076 GrAlwaysAssert(!buffer->getBound());
1077 buffer->setBound();
1078 }
1079
1080 fBoundBuffers[buffIdx] = buffer;
1081 }
1082
setVertexArray(GrVertexArrayObj * vertexArray)1083 void setVertexArray(GrVertexArrayObj* vertexArray) {
1084 if (vertexArray) {
1085 SkASSERT(!vertexArray->getDeleted());
1086 }
1087 SkRefCnt_SafeAssign(fVertexArray, vertexArray);
1088 }
1089
getVertexArray()1090 GrVertexArrayObj* getVertexArray() { return fVertexArray; }
1091
setTexture(GrTextureObj * texture)1092 void setTexture(GrTextureObj *texture) {
1093 fTextureUnits[fCurrTextureUnit]->setTexture(texture);
1094 }
1095
setFrameBuffer(GrFrameBufferObj * frameBuffer)1096 void setFrameBuffer(GrFrameBufferObj *frameBuffer) {
1097 if (fFrameBuffer) {
1098 GrAlwaysAssert(fFrameBuffer->getBound());
1099 fFrameBuffer->resetBound();
1100
1101 GrAlwaysAssert(!fFrameBuffer->getDeleted());
1102 fFrameBuffer->unref();
1103 }
1104
1105 fFrameBuffer = frameBuffer;
1106
1107 if (fFrameBuffer) {
1108 GrAlwaysAssert(!fFrameBuffer->getDeleted());
1109 fFrameBuffer->ref();
1110
1111 GrAlwaysAssert(!fFrameBuffer->getBound());
1112 fFrameBuffer->setBound();
1113 }
1114 }
1115
getFrameBuffer()1116 GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
1117
setRenderBuffer(GrRenderBufferObj * renderBuffer)1118 void setRenderBuffer(GrRenderBufferObj *renderBuffer) {
1119 if (fRenderBuffer) {
1120 GrAlwaysAssert(fRenderBuffer->getBound());
1121 fRenderBuffer->resetBound();
1122
1123 GrAlwaysAssert(!fRenderBuffer->getDeleted());
1124 fRenderBuffer->unref();
1125 }
1126
1127 fRenderBuffer = renderBuffer;
1128
1129 if (fRenderBuffer) {
1130 GrAlwaysAssert(!fRenderBuffer->getDeleted());
1131 fRenderBuffer->ref();
1132
1133 GrAlwaysAssert(!fRenderBuffer->getBound());
1134 fRenderBuffer->setBound();
1135 }
1136 }
getRenderBuffer()1137 GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
1138
useProgram(GrProgramObj * program)1139 void useProgram(GrProgramObj *program) {
1140 if (fProgram) {
1141 GrAlwaysAssert(fProgram->getInUse());
1142 fProgram->resetInUse();
1143
1144 GrAlwaysAssert(!fProgram->getDeleted());
1145 fProgram->unref();
1146 }
1147
1148 fProgram = program;
1149
1150 if (fProgram) {
1151 GrAlwaysAssert(!fProgram->getDeleted());
1152 fProgram->ref();
1153
1154 GrAlwaysAssert(!fProgram->getInUse());
1155 fProgram->setInUse();
1156 }
1157 }
1158
report() const1159 void report() const {
1160 for (int i = 0; i < fObjects.count(); ++i) {
1161 if (!fAbandoned) {
1162 GrAlwaysAssert(0 == fObjects[i]->getRefCount());
1163 GrAlwaysAssert(fObjects[i]->getDeleted());
1164 }
1165 }
1166 }
1167
1168 typedef GrGLTestInterface INHERITED;
1169 };
1170
1171 #undef CREATE
1172 #undef FIND
1173
1174 DebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = {
1175 GrTextureObj::createGrTextureObj,
1176 GrBufferObj::createGrBufferObj,
1177 GrRenderBufferObj::createGrRenderBufferObj,
1178 GrFrameBufferObj::createGrFrameBufferObj,
1179 GrShaderObj::createGrShaderObj,
1180 GrProgramObj::createGrProgramObj,
1181 GrTextureUnitObj::createGrTextureUnitObj,
1182 GrVertexArrayObj::createGrVertexArrayObj,
1183 };
1184
1185 const char* DebugInterface::kExtensions[] = {
1186 "GL_ARB_framebuffer_object",
1187 "GL_ARB_blend_func_extended",
1188 "GL_ARB_timer_query",
1189 "GL_ARB_draw_buffers",
1190 "GL_ARB_occlusion_query",
1191 "GL_EXT_stencil_wrap",
1192 nullptr, // signifies the end of the array.
1193 };
1194
1195 class DebugGLContext : public sk_gpu_test::GLTestContext {
1196 public:
DebugGLContext()1197 DebugGLContext() {
1198 this->init(new DebugInterface());
1199 }
1200
~DebugGLContext()1201 ~DebugGLContext() override { this->teardown(); }
1202
1203 private:
onPlatformMakeCurrent() const1204 void onPlatformMakeCurrent() const override {}
onPlatformSwapBuffers() const1205 void onPlatformSwapBuffers() const override {}
onPlatformGetProcAddress(const char *) const1206 GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nullptr; }
1207 };
1208 } // anonymous namespace
1209
1210 namespace sk_gpu_test {
CreateDebugGLTestContext(GLTestContext * shareContext)1211 GLTestContext* CreateDebugGLTestContext(GLTestContext* shareContext) {
1212 if (shareContext) {
1213 return nullptr;
1214 }
1215 GLTestContext* ctx = new DebugGLContext();
1216 if (ctx->isValid()) {
1217 return ctx;
1218 }
1219 delete ctx;
1220 return nullptr;
1221 }
1222 }
1223