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
23namespace {
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
33class DebugInterface : public GrGLTestInterface {
34public:
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
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
73    void abandon() const override { fAbandoned = true; }
74
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
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    ////////////////////////////////////////////////////////////////////////////////
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    ////////////////////////////////////////////////////////////////////////////////
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
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
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
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
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
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
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
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
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
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
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
393    GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat,
394                                      GrGLsizei width, GrGLsizei height) override {
395        SK_ABORT("Not implemented");
396    }
397
398    GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples,
399                                                 GrGLenum GrGLinternalformat, GrGLsizei width,
400                                                 GrGLsizei height) override {
401        SK_ABORT("Not implemented");
402    }
403
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
441    GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment,
442                                          GrGLenum renderbuffertarget,
443                                          GrGLuint renderbuffer) override {
444        SK_ABORT("Not implemented");
445    }
446
447    ////////////////////////////////////////////////////////////////////////////////
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
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
493    GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment,
494                                       GrGLenum textarget, GrGLuint texture,
495                                       GrGLint level) override {
496        SK_ABORT("Not implemented");
497    }
498
499    GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment,
500                                       GrGLenum textarget, GrGLuint texture,
501                                       GrGLint level) override {
502        SK_ABORT("Not implemented");
503    }
504
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
511    GrGLuint createProgram() override {
512
513        GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes);
514
515        return program->getID();
516    }
517
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
529    GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; }
530
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
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
557    GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
558        this->genObjs(kBuffer_ObjTypes, n, ids);
559    }
560
561    GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override {
562        this->genObjs(kFrameBuffer_ObjTypes, n, ids);
563    }
564
565    GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override {
566        this->genObjs(kRenderBuffer_ObjTypes, n, ids);
567    }
568
569    GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override {
570        this->genObjs(kTexture_ObjTypes, n, ids);
571    }
572
573    GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override {
574        this->genObjs(kVertexArray_ObjTypes, n, ids);
575    }
576
577    GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
578
579    GrGLenum getError() override { return GR_GL_NO_ERROR; }
580
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
669    GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
670        val[0] = val[1] = 0.5f;
671    }
672
673    GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
674        this->getShaderOrProgramiv(program, pname, params);
675    }
676
677    GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
678                               char* infolog) override {
679        this->getInfoLog(program, bufsize, length, infolog);
680    }
681
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
695    GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
696        this->queryResult(id, pname, params);
697    }
698
699    GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
700        this->queryResult(id, pname, params);
701    }
702
703    GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
704        this->queryResult(id, pname, params);
705    }
706
707    GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
708        this->queryResult(id, pname, params);
709    }
710
711    GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
712        this->getShaderOrProgramiv(shader, pname, params);
713    }
714
715    GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
716                              char* infolog) override {
717        this->getInfoLog(shader, bufsize, length, infolog);
718    }
719
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
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
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
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
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
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
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
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
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
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
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
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
901private:
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
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
963    GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
964        for (int i = 0; i < n; ++i) {
965            ids[i] = ++fCurrGenericID;
966        }
967    }
968
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
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>
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
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
1035    GrFakeRefObj* createObj(ObjTypes type) {
1036        GrFakeRefObj *temp = (*gFactoryFunc[type])();
1037
1038        fObjects.push_back(temp);
1039
1040        return temp;
1041    }
1042
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
1056    GrTextureUnitObj* getTextureUnit(int unit) {
1057        GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit);
1058
1059        return fTextureUnits[unit];
1060    }
1061
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
1083    void setVertexArray(GrVertexArrayObj* vertexArray) {
1084        if (vertexArray) {
1085            SkASSERT(!vertexArray->getDeleted());
1086        }
1087        SkRefCnt_SafeAssign(fVertexArray, vertexArray);
1088    }
1089
1090    GrVertexArrayObj* getVertexArray() { return fVertexArray; }
1091
1092    void setTexture(GrTextureObj *texture) {
1093        fTextureUnits[fCurrTextureUnit]->setTexture(texture);
1094    }
1095
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
1116    GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
1117
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    }
1137    GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
1138
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
1159    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
1174DebugInterface::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
1185const 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
1195class DebugGLContext : public sk_gpu_test::GLTestContext {
1196public:
1197   DebugGLContext() {
1198       this->init(new DebugInterface());
1199   }
1200
1201   ~DebugGLContext() override { this->teardown(); }
1202
1203private:
1204    void onPlatformMakeCurrent() const override {}
1205    void onPlatformSwapBuffers() const override {}
1206    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nullptr; }
1207};
1208}  // anonymous namespace
1209
1210namespace sk_gpu_test {
1211GLTestContext* 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