• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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