DebugGLTestContext.cpp revision 273c0f5e87397c40d22bb7e3ee078bb46a3f6860
13724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
20da3719050473344b6013fd7b614611984f20effrobertphillips@google.com/*
30da3719050473344b6013fd7b614611984f20effrobertphillips@google.com * Copyright 2012 Google Inc.
40da3719050473344b6013fd7b614611984f20effrobertphillips@google.com *
50da3719050473344b6013fd7b614611984f20effrobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
60da3719050473344b6013fd7b614611984f20effrobertphillips@google.com * found in the LICENSE file.
70da3719050473344b6013fd7b614611984f20effrobertphillips@google.com */
80da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
9273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon#include "DebugGLTestContext.h"
103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#include "GrBufferObj.h"
12dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#include "GrFrameBufferObj.h"
133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#include "GrProgramObj.h"
14dd743fefad9764ad86d7f69deec32e9a3b5de47frobertphillips@google.com#include "GrRenderBufferObj.h"
153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#include "GrShaderObj.h"
163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#include "GrTextureObj.h"
173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#include "GrTextureUnitObj.h"
18ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com#include "GrVertexArrayObj.h"
193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#include "gl/GrGLTestInterface.h"
200da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#include "SkMutex.h"
22cf6285b89b8820641ffb6871d4b3275bfe783f51caryclark@google.com
233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomonnamespace {
24fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon// Helper macro to make creating an object (where you need to get back a derived type) easier
263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#define CREATE(className, classEnum)                     \
273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    reinterpret_cast<className *>(this->createObj(classEnum))
280da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon// Helper macro to make creating an object (where you need to get back a derived type) easier
303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#define FIND(id, className, classEnum)                   \
313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    reinterpret_cast<className *>(this->findObject(id, classEnum))
320da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomonclass DebugInterface : public GrGLTestInterface {
343c481001b16288f604a5279bcb4bf46c5dd2b703bsalomonpublic:
353c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    DebugInterface()
363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        : fCurrGenericID(0)
373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fCurrTextureUnit(0)
383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fArrayBuffer(nullptr)
393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fElementArrayBuffer(nullptr)
403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fVertexArray(nullptr)
413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fPackRowLength(0)
423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fUnpackRowLength(0)
433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fPackAlignment(4)
443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fFrameBuffer(nullptr)
453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fRenderBuffer(nullptr)
463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fProgram(nullptr)
473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        , fAbandoned(false) {
483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fTextureUnits[i] =
503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                reinterpret_cast<GrTextureUnitObj*>(this->createObj(kTextureUnit_ObjTypes));
513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fTextureUnits[i]->ref();
523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fTextureUnits[i]->setNumber(i);
533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->init(kGL_GrGLStandard);
553c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
56ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    ~DebugInterface() override {
583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // unref & delete the texture units first so they don't show up on the leak report
593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < kDefaultMaxTextureUnits; ++i) {
603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fTextureUnits[i]->unref();
613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fTextureUnits[i]->deleteAction();
623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < fObjects.count(); ++i) {
643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            delete fObjects[i];
653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fObjects.reset();
670da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fArrayBuffer = nullptr;
693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fElementArrayBuffer = nullptr;
703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fVertexArray = nullptr;
710da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->report();
733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
740da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void abandon() const override { fAbandoned = true; }
76ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid activeTexture(GrGLenum texture) override {
783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // Ganesh offsets the texture unit indices
793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        texture -= GR_GL_TEXTURE0;
803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(texture < kDefaultMaxTextureUnits);
813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fCurrTextureUnit = texture;
823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
83ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid attachShader(GrGLuint programID, GrGLuint shaderID) override {
85ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(program);
88ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(shader);
91ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        program->AttachShader(shader);
933c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
94ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    ////////////////////////////////////////////////////////////////////////////////
963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid bindTexture(GrGLenum target, GrGLuint textureID) override {
973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(target == GR_GL_TEXTURE_2D ||
983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       target == GR_GL_TEXTURE_RECTANGLE ||
993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       target == GR_GL_TEXTURE_EXTERNAL);
1000da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
1013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // a textureID of 0 is acceptable - it binds to the default texture target
1023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
1033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
1043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->setTexture(texture);
105670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com    }
106670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com
1073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    ////////////////////////////////////////////////////////////////////////////////
1083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
1093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        GrGLenum usage) override {
1103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
1113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
1123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(size >= 0);
1133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_STREAM_DRAW == usage ||
1143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_STATIC_DRAW == usage ||
1153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_DYNAMIC_DRAW == usage);
1163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
1173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrBufferObj *buffer = nullptr;
1183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (target) {
1193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ARRAY_BUFFER:
1203c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getArrayBuffer();
1213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1223c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ELEMENT_ARRAY_BUFFER:
1233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getElementArrayBuffer();
1243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
1263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected target to glBufferData");
1273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
129670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com
1303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(buffer);
1313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(buffer->getBound());
132670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com
1333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        buffer->allocate(size, reinterpret_cast<const GrGLchar *>(data));
1343c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        buffer->setUsage(usage);
135670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com    }
136670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com
137670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com
1383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) override {
1393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
1403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (pname) {
1413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_UNPACK_ROW_LENGTH:
1423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                fUnpackRowLength = param;
1433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_PACK_ROW_LENGTH:
1453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                fPackRowLength = param;
1463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_UNPACK_ALIGNMENT:
1483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_PACK_ALIGNMENT:
1503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                fPackAlignment = param;
1513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
1533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrAlwaysAssert(false);
1543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1553c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
156670ff9ae7f37356bff08b30a356bb0c52dc8d62erobertphillips@google.com    }
157f6f123d23608a4a5fe9c812d2452039a18da7e0brobertphillips@google.com
1583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid readPixels(GrGLint x,
1593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        GrGLint y,
1603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        GrGLsizei width,
1613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        GrGLsizei height,
1623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        GrGLenum format,
1633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        GrGLenum type,
1643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        GrGLvoid* pixels) override {
1653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
1663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrGLint pixelsInRow = width;
1673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fPackRowLength > 0) {
1683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            pixelsInRow = fPackRowLength;
1693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
170ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
1713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrGLint componentsPerPixel = 0;
1723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
1733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (format) {
1743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_RGBA:
1753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                // fallthrough
1763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_BGRA:
1773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                componentsPerPixel = 4;
1783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_RGB:
1803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                componentsPerPixel = 3;
1813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_RED:
1833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                componentsPerPixel = 1;
1843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
1863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrAlwaysAssert(false);
1873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
189ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
1903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrGLint alignment = fPackAlignment;
191ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
1923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrGLint componentSize = 0;  // size (in bytes) of a single component
193ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
1943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (type) {
1953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_UNSIGNED_BYTE:
1963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                componentSize = 1;
1973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
1983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
1993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrAlwaysAssert(false);
2003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
2013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
202ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrGLint rowStride = 0;  // number of components (not bytes) to skip
2043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (componentSize >= alignment) {
2053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            rowStride = componentsPerPixel * pixelsInRow;
2063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        } else {
2073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            float fTemp =
2083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                sk_float_ceil(componentSize * componentsPerPixel * pixelsInRow /
2093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                              static_cast<float>(alignment));
2103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            rowStride = static_cast<GrGLint>(alignment * fTemp / componentSize);
2113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
212ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrGLchar *scanline = static_cast<GrGLchar *>(pixels);
2143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int y = 0; y < height; ++y) {
2153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            memset(scanline, 0, componentsPerPixel * componentSize * width);
2163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            scanline += rowStride;
2173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
2183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
219ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2203724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid useProgram(GrGLuint programID) override {
221ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2223724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // A programID of 0 is legal
2233724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
224ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2253724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        this->useProgram(program);
2263724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
2273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
2283724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint frameBufferID) override {
229ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2303724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_FRAMEBUFFER == target ||
2313724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                       GR_GL_READ_FRAMEBUFFER == target ||
2323724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                       GR_GL_DRAW_FRAMEBUFFER);
233ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2343724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // a frameBufferID of 0 is acceptable - it binds to the default
2353724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // frame buffer
2363724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrFrameBufferObj *frameBuffer = FIND(frameBufferID, GrFrameBufferObj,
2373724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                             kFrameBuffer_ObjTypes);
2383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
2393724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        this->setFrameBuffer(frameBuffer);
2403724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
241ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2423724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderBufferID) override {
243ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2443724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
2453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
2463724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // a renderBufferID of 0 is acceptable - it unbinds the bound render buffer
2473724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrRenderBufferObj *renderBuffer = FIND(renderBufferID, GrRenderBufferObj,
2483724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                               kRenderBuffer_ObjTypes);
2493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
2503724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        this->setRenderBuffer(renderBuffer);
2513724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
252ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2533724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) override {
2543724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // first potentially unbind the texture
2553724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        for (unsigned int i = 0; i < kDefaultMaxTextureUnits; ++i) {
2563724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrTextureUnitObj *pTU = this->getTextureUnit(i);
2573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
2583724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            if (pTU->getTexture()) {
2593724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                for (int j = 0; j < n; ++j) {
2603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
2613724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    if (textures[j] == pTU->getTexture()->getID()) {
2623724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                        // this ID is the current texture - revert the binding to 0
2633724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                        pTU->setTexture(nullptr);
2643724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    }
2653724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
2663724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            }
2673724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
268ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2693724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // TODO: fuse the following block with DeleteRenderBuffers?
2703724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // Open GL will remove a deleted render buffer from the active
2713724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // frame buffer but not from any other frame buffer
2723724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        if (this->getFrameBuffer()) {
273ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2743724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
275ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2763724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            for (int i = 0; i < n; ++i) {
277ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2783724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (frameBuffer->getColor() &&
2793724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    textures[i] == frameBuffer->getColor()->getID()) {
2803724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    frameBuffer->setColor(nullptr);
2813724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
2823724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (frameBuffer->getDepth() &&
2833724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    textures[i] == frameBuffer->getDepth()->getID()) {
2843724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    frameBuffer->setDepth(nullptr);
2853724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
2863724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (frameBuffer->getStencil() &&
2873724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    textures[i] == frameBuffer->getStencil()->getID()) {
2883724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    frameBuffer->setStencil(nullptr);
2893724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
2903724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            }
2913724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
292ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2933724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // then actually "delete" the buffers
2943724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        for (int i = 0; i < n; ++i) {
2953724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrTextureObj *buffer = FIND(textures[i], GrTextureObj, kTexture_ObjTypes);
2963724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(buffer);
297ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
2983724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // OpenGL gives no guarantees if a texture is deleted while attached to
2993724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // something other than the currently bound frame buffer
3003724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(!buffer->getBound());
3013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
3023724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(!buffer->getDeleted());
3033724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            buffer->deleteAction();
3043724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
305ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
3063724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
307ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
3083724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *frameBuffers) override {
309ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
3103724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // first potentially unbind the buffers
3113724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        if (this->getFrameBuffer()) {
3123724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            for (int i = 0; i < n; ++i) {
313ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
3143724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (frameBuffers[i] ==
3153724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    this->getFrameBuffer()->getID()) {
3163724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    // this ID is the current frame buffer - rebind to the default
3173724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    this->setFrameBuffer(nullptr);
3183724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
3193724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            }
3203724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
3213724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3223724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // then actually "delete" the buffers
3233724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        for (int i = 0; i < n; ++i) {
3243724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrFrameBufferObj *buffer = FIND(frameBuffers[i], GrFrameBufferObj,
3253724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                            kFrameBuffer_ObjTypes);
3263724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(buffer);
3273724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3283724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(!buffer->getDeleted());
3293724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            buffer->deleteAction();
3303724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
3313724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
3323724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3333724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid deleteRenderbuffers(GrGLsizei n,const GrGLuint *renderBuffers) override {
3343724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3353724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // first potentially unbind the buffers
3363724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        if (this->getRenderBuffer()) {
3373724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            for (int i = 0; i < n; ++i) {
3383724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3393724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (renderBuffers[i] ==
3403724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    this->getRenderBuffer()->getID()) {
3413724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    // this ID is the current render buffer - make no
3423724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    // render buffer be bound
3433724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    this->setRenderBuffer(nullptr);
3443724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
3453724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            }
3463724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
3473724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3483724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // TODO: fuse the following block with DeleteTextures?
3493724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // Open GL will remove a deleted render buffer from the active frame
3503724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // buffer but not from any other frame buffer
3513724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        if (this->getFrameBuffer()) {
3523724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3533724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrFrameBufferObj *frameBuffer = this->getFrameBuffer();
3543724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3553724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            for (int i = 0; i < n; ++i) {
3563724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3573724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (frameBuffer->getColor() &&
3583724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    renderBuffers[i] == frameBuffer->getColor()->getID()) {
3593724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    frameBuffer->setColor(nullptr);
3603724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
3613724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (frameBuffer->getDepth() &&
3623724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    renderBuffers[i] == frameBuffer->getDepth()->getID()) {
3633724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    frameBuffer->setDepth(nullptr);
3643724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
3653724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                if (frameBuffer->getStencil() &&
3663724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    renderBuffers[i] == frameBuffer->getStencil()->getID()) {
3673724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                    frameBuffer->setStencil(nullptr);
3683724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                }
3693724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            }
3703724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
3713724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3723724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // then actually "delete" the buffers
3733724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        for (int i = 0; i < n; ++i) {
3743724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrRenderBufferObj *buffer = FIND(renderBuffers[i], GrRenderBufferObj,
3753724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                             kRenderBuffer_ObjTypes);
3763724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(buffer);
3773724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3783724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // OpenGL gives no guarantees if a render buffer is deleted
3793724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // while attached to something other than the currently
3803724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // bound frame buffer
3813724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(!buffer->getColorBound());
3823724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(!buffer->getDepthBound());
3833724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // However, at GrContext destroy time we release all GrRsources and so stencil buffers
3843724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // may get deleted before FBOs that refer to them.
3853724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            //GrAlwaysAssert(!buffer->getStencilBound());
3863724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3873724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(!buffer->getDeleted());
3883724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            buffer->deleteAction();
3893724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
3903724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
3913724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3923724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid framebufferRenderbuffer(GrGLenum target,
3933724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                     GrGLenum attachment,
3943724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                     GrGLenum renderbuffertarget,
3953724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                     GrGLuint renderBufferID) override {
3963724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
3973724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
3983724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
3993724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                       GR_GL_DEPTH_ATTACHMENT == attachment ||
4003724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                       GR_GL_STENCIL_ATTACHMENT == attachment);
4013724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
4023724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4033724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrFrameBufferObj *framebuffer = this->getFrameBuffer();
4043724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // A render buffer cannot be attached to the default framebuffer
4053724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(framebuffer);
4063724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4073724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // a renderBufferID of 0 is acceptable - it unbinds the current
4083724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // render buffer
4093724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrRenderBufferObj *renderbuffer = FIND(renderBufferID, GrRenderBufferObj,
4103724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                               kRenderBuffer_ObjTypes);
4113724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4123724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        switch (attachment) {
4133724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            case GR_GL_COLOR_ATTACHMENT0:
4143724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                framebuffer->setColor(renderbuffer);
4153724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4163724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            case GR_GL_DEPTH_ATTACHMENT:
4173724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                framebuffer->setDepth(renderbuffer);
4183724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4193724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            case GR_GL_STENCIL_ATTACHMENT:
4203724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                framebuffer->setStencil(renderbuffer);
4213724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4223724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            default:
4233724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                GrAlwaysAssert(false);
4243724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4253724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        };
4263724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4273724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
4283724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4293724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    ////////////////////////////////////////////////////////////////////////////////
4303724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget,
4313724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                                  GrGLuint textureID, GrGLint level) override {
4323724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4333724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_FRAMEBUFFER == target);
4343724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_COLOR_ATTACHMENT0 == attachment ||
4353724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                       GR_GL_DEPTH_ATTACHMENT == attachment ||
4363724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                       GR_GL_STENCIL_ATTACHMENT == attachment);
4373724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(GR_GL_TEXTURE_2D == textarget);
4383724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4393724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrFrameBufferObj *framebuffer = this->getFrameBuffer();
4403724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // A texture cannot be attached to the default framebuffer
4413724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(framebuffer);
4423724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4433724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        // A textureID of 0 is allowed - it unbinds the currently bound texture
4443724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrTextureObj *texture = FIND(textureID, GrTextureObj, kTexture_ObjTypes);
4453724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        if (texture) {
4463724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // The texture shouldn't be bound to a texture unit - this
4473724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            // could lead to a feedback loop
4483724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            GrAlwaysAssert(!texture->getBound());
4493724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        }
4503724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4513724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        GrAlwaysAssert(0 == level);
4523724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
4533724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        switch (attachment) {
4543724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            case GR_GL_COLOR_ATTACHMENT0:
4553724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                framebuffer->setColor(texture);
4563724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4573724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            case GR_GL_DEPTH_ATTACHMENT:
4583724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                framebuffer->setDepth(texture);
4593724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4603724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            case GR_GL_STENCIL_ATTACHMENT:
4613724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                framebuffer->setStencil(texture);
4623724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4633724e574a744491b7cfb8187ac865a70ef3d4528bsalomon            default:
4643724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                GrAlwaysAssert(false);
4653724e574a744491b7cfb8187ac865a70ef3d4528bsalomon                break;
4663724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        };
4673724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
468ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
4693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLuint createProgram() override {
4703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
4713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrProgramObj *program = CREATE(GrProgramObj, kProgram_ObjTypes);
472ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
4733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return program->getID();
4743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
475ebde3e0e74ccb82042b742dddb9b3cf877c82f6frobertphillips@google.com
4763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLuint createShader(GrGLenum type) override {
4770da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
4783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_VERTEX_SHADER == type ||
4793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_FRAGMENT_SHADER == type);
4800da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
4813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrShaderObj *shader = CREATE(GrShaderObj, kShader_ObjTypes);
4823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        shader->setType(type);
4830da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
4843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return shader->getID();
4853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
486fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLenum checkFramebufferStatus(GrGLenum target) override { return GR_GL_FRAMEBUFFER_COMPLETE; }
4880da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
4893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid deleteProgram(GrGLuint programID) override {
4900da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
4913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrProgramObj *program = FIND(programID, GrProgramObj, kProgram_ObjTypes);
4923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(program);
4930da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
4943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (program->getRefCount()) {
4953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            // someone is still using this program so we can't delete it here
4963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            program->setMarkedForDeletion();
4973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        } else {
4983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            program->deleteAction();
4993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
5003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
5013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
5023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid deleteShader(GrGLuint shaderID) override {
5030da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
5043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrShaderObj *shader = FIND(shaderID, GrShaderObj, kShader_ObjTypes);
5053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(shader);
5060da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
5073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (shader->getRefCount()) {
5083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            // someone is still using this shader so we can't delete it here
5093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            shader->setMarkedForDeletion();
5103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        } else {
5113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            shader->deleteAction();
5123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
5133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
5143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
5153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
5163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->genObjs(kBuffer_ObjTypes, n, ids);
5173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
5183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
5193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint* ids) override {
5203c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->genObjs(kFrameBuffer_ObjTypes, n, ids);
5213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
5223c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
5233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint* ids) override {
5243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->genObjs(kRenderBuffer_ObjTypes, n, ids);
5250da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
5260da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
5273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genTextures(GrGLsizei n, GrGLuint* ids) override {
5283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->genObjs(kTexture_ObjTypes, n, ids);
5293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
5303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
5313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint* ids) override {
5323c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->genObjs(kVertexArray_ObjTypes, n, ids);
5333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
5340da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
5353c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
5363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
5373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLenum getError() override { return GR_GL_NO_ERROR; }
5383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
5393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
5403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // TODO: remove from Ganesh the #defines for gets we don't use.
5413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // We would like to minimize gets overall due to performance issues
5423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (pname) {
5433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_CONTEXT_PROFILE_MASK:
5443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
5453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_STENCIL_BITS:
5473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 8;
5483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_SAMPLES:
5503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 1;
5513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_FRAMEBUFFER_BINDING:
5533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 0;
5543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5553c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_VIEWPORT:
5563c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                params[0] = 0;
5573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                params[1] = 0;
5583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                params[2] = 800;
5593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                params[3] = 600;
5603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
5623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
5633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
5643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
5653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 8;
5663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_TEXTURE_COORDS:
5683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 8;
5693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
5713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = kDefaultMaxVertexUniformVectors;
5723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
5743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = kDefaultMaxFragmentUniformVectors;
5753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
5773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 16 * 4;
5783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
5803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 0;
5813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_COMPRESSED_TEXTURE_FORMATS:
5833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_TEXTURE_SIZE:
5853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 8192;
5863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_RENDERBUFFER_SIZE:
5883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 8192;
5893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_SAMPLES:
5913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 32;
5923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5933c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_VERTEX_ATTRIBS:
5943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = kDefaultMaxVertexAttribs;
5953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_MAX_VARYING_VECTORS:
5973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = kDefaultMaxVaryingVectors;
5983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
5993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_NUM_EXTENSIONS: {
6003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrGLint i = 0;
6013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                while (kExtensions[i++]);
6023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = i;
6033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
6043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
6053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
6063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected pname to GetIntegerv");
6073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
6083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
6093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
6103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
6113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        val[0] = val[1] = 0.5f;
6123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
6130da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
6143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
6153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->getShaderOrProgramiv(program, pname, params);
6160da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
6170da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
6183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
6193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                               char* infolog) override {
6203c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->getInfoLog(program, bufsize, length, infolog);
6213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
6220da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
6233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
6243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (pname) {
6253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_CURRENT_QUERY:
6263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 0;
6273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
6283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_QUERY_COUNTER_BITS:
6293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 32;
6303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
6313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
6323c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected pname passed GetQueryiv.");
6333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
6340da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
6350da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
6363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
6373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->queryResult(id, pname, params);
6383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
639ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
6403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
6413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->queryResult(id, pname, params);
6423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
643cffff79a40bd7672e13b31b9801a3f3cda64875ecommit-bot@chromium.org
6443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
6453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->queryResult(id, pname, params);
6463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
647f6f123d23608a4a5fe9c812d2452039a18da7e0brobertphillips@google.com
6483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
6493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->queryResult(id, pname, params);
6503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
651ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
6523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
6533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->getShaderOrProgramiv(shader, pname, params);
6543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
65587c6d7a99ee7fee2dcc537a1ccad95fc5a9bd26bbsalomon@google.com
6563c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
6573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                              char* infolog) override {
6583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->getInfoLog(shader, bufsize, length, infolog);
6593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
66087c6d7a99ee7fee2dcc537a1ccad95fc5a9bd26bbsalomon@google.com
6613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    const GrGLubyte* getString(GrGLenum name) override {
6623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (name) {
6633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_EXTENSIONS:
6643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return CombinedExtensionString();
6653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_VERSION:
6663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return (const GrGLubyte*)"4.0 Debug GL";
6673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_SHADING_LANGUAGE_VERSION:
6683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return (const GrGLubyte*)"4.20.8 Debug GLSL";
6693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_VENDOR:
6703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return (const GrGLubyte*)"Debug Vendor";
6713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_RENDERER:
6723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return (const GrGLubyte*)"The Debug (Non-)Renderer";
6733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
6743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected name passed to GetString");
6753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return nullptr;
6763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
6773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
678ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com
6793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override {
6803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (name) {
6813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_EXTENSIONS: {
6823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrGLint count;
6833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count);
6843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                if ((GrGLint)i <= count) {
6853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                    return (const GrGLubyte*) kExtensions[i];
6863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                } else {
6873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                    return nullptr;
6883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                }
6893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
6903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
6913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected name passed to GetStringi");
6923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return nullptr;
693ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com        }
6943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
695ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com
6963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname,
6973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                                    GrGLint* params) override {
6983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // we used to use this to query stuff about externally created textures,
6993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // now we just require clients to tell us everything about the texture.
7003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        SkFAIL("Should never query texture parameters.");
7013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
7023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint* ids) override {
7043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (GrGLsizei i = 0; i < n; ++i) {
7053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrVertexArrayObj* array = FIND(ids[i], GrVertexArrayObj, kVertexArray_ObjTypes);
7063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(array);
7073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            // Deleting the current vertex array binds object 0
7093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            if (this->getVertexArray() == array) {
7103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                this->setVertexArray(nullptr);
7113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
7123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            if (array->getRefCount()) {
7143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                // someone is still using this vertex array so we can't delete it here
7153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                array->setMarkedForDeletion();
7163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            } else {
7173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                array->deleteAction();
7183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
719ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com        }
720ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com    }
721ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com
7223c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid bindVertexArray(GrGLuint id) override {
7233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrVertexArrayObj* array = FIND(id, GrVertexArrayObj, kVertexArray_ObjTypes);
7243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert((0 == id) || array);
7253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        this->setVertexArray(array);
7263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
7273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override {
7293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
7303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes);
7323c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // 0 is a permissible bufferID - it unbinds the current buffer
7333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7343c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (target) {
7353c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ARRAY_BUFFER:
7363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                this->setArrayBuffer(buffer);
7373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
7383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ELEMENT_ARRAY_BUFFER:
7393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                this->setElementArrayBuffer(buffer);
7403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
7413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
7423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected target to glBindBuffer");
7433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
7443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
7453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
746ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com
7473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // deleting a bound buffer has the side effect of binding 0
7483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
7493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // first potentially unbind the buffers
7503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < n; ++i) {
7513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            if (this->getArrayBuffer() &&
7533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                ids[i] == this->getArrayBuffer()->getID()) {
7543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                // this ID is the current array buffer
7553c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                this->setArrayBuffer(nullptr);
7563c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
7573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            if (this->getElementArrayBuffer() &&
7583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                ids[i] == this->getElementArrayBuffer()->getID()) {
7593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                // this ID is the current element array buffer
7603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                this->setElementArrayBuffer(nullptr);
7613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
7623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
7630da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
7643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // then actually "delete" the buffers
7653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < n; ++i) {
7663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrBufferObj *buffer = FIND(ids[i], GrBufferObj, kBuffer_ObjTypes);
7673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(buffer);
7680da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
7693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!buffer->getDeleted());
7703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            buffer->deleteAction();
7713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
7720da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
7730da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
7743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // map a buffer to the caller's address space
7753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
7763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                             GrGLbitfield access) override {
7773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
7783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
7793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        // We only expect read access and we expect that the buffer or range is always invalidated.
7813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access));
7823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access);
7833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
7843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrBufferObj *buffer = nullptr;
7853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (target) {
7863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ARRAY_BUFFER:
7873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getArrayBuffer();
7883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
7893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ELEMENT_ARRAY_BUFFER:
7903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getElementArrayBuffer();
7913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
7923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
7933c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected target to glMapBufferRange");
7943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
7953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
7960da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
7973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (buffer) {
7983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
7993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!buffer->getMapped());
8003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            buffer->setMapped(offset, length);
8013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            return buffer->getDataPtr() + offset;
8020da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        }
8033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(false);
8053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return nullptr;        // no buffer bound to the target
8063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
8073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
8093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_WRITE_ONLY == access);
8103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrBufferObj *buffer = nullptr;
8123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (target) {
8133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ARRAY_BUFFER:
8143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getArrayBuffer();
8153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ELEMENT_ARRAY_BUFFER:
8173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getElementArrayBuffer();
8183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
8203c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected target to glMapBuffer");
8213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8220da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        }
8233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return this->mapBufferRange(target, 0, buffer->getSize(),
8253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                                    GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT);
8260da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
8270da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
8283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // remove a buffer from the caller's address space
8293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // TODO: check if the "access" method from "glMapBuffer" was honored
8303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLboolean unmapBuffer(GrGLenum target) override {
8313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
8323c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
8333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8343c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrBufferObj *buffer = nullptr;
8353c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (target) {
8363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ARRAY_BUFFER:
8373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getArrayBuffer();
8383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ELEMENT_ARRAY_BUFFER:
8403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getElementArrayBuffer();
8413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
8433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected target to glUnmapBuffer");
8443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
8463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (buffer) {
8483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(buffer->getMapped());
8493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            buffer->resetMapped();
8503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            return GR_GL_TRUE;
8513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
8520da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
853160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org        GrAlwaysAssert(false);
8543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
855160b478eed1dd4924a86a87fd60c91139e08ff71commit-bot@chromium.org    }
8563c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset,
8583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                                    GrGLsizeiptr length) override {
8593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
8603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
8613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrBufferObj *buffer = nullptr;
8633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (target) {
8643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ARRAY_BUFFER:
8653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getArrayBuffer();
8663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ELEMENT_ARRAY_BUFFER:
8683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getElementArrayBuffer();
8693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
8713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected target to glUnmapBuffer");
8723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
8743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (buffer) {
8763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(buffer->getMapped());
8773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
8783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        } else {
8793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(false);
8803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
8810da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
882cf6285b89b8820641ffb6871d4b3275bfe783f51caryclark@google.com
8833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) override {
8843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
8863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
8873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(GR_GL_BUFFER_SIZE == value ||
8883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                       GR_GL_BUFFER_USAGE == value);
8893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
8903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrBufferObj *buffer = nullptr;
8913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (target) {
8923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ARRAY_BUFFER:
8933c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getArrayBuffer();
8943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_ELEMENT_ARRAY_BUFFER:
8963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                buffer = this->getElementArrayBuffer();
8973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
8983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
8993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(buffer);
9013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (value) {
9033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_BUFFER_MAPPED:
9043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = GR_GL_FALSE;
9053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                if (buffer)
9063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                    *params = buffer->getMapped() ? GR_GL_TRUE : GR_GL_FALSE;
9073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
9083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_BUFFER_SIZE:
9093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 0;
9103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                if (buffer)
9113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                    *params = SkToInt(buffer->getSize());
9123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
9133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_BUFFER_USAGE:
9143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = GR_GL_STATIC_DRAW;
9153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                if (buffer)
9163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                    *params = buffer->getUsage();
9173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
9183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
9193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected value to glGetBufferParamateriv");
9203c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
9213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
9223c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
923ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
924ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.comprivate:
9253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // the OpenGLES 2.0 spec says this must be >= 128
9263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static const GrGLint kDefaultMaxVertexUniformVectors = 128;
9273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // the OpenGLES 2.0 spec says this must be >=16
9293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
9303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // the OpenGLES 2.0 spec says this must be >= 8
9323c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static const GrGLint kDefaultMaxVertexAttribs = 8;
9333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9343c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // the OpenGLES 2.0 spec says this must be >= 8
9353c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static const GrGLint kDefaultMaxVaryingVectors = 8;
9363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // the OpenGLES 2.0 spec says this must be >= 2
9383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static const GrGLint kDefaultMaxTextureUnits = 8;
9393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static const char* kExtensions[];
9413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLuint                    fCurrGenericID;
9433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLuint                    fCurrTextureUnit;
9443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrTextureUnitObj*           fTextureUnits[kDefaultMaxTextureUnits];
9453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrBufferObj*                fArrayBuffer;
9463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrBufferObj*                fElementArrayBuffer;
9473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrVertexArrayObj*           fVertexArray;
9483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLint                     fPackRowLength;
9493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLint                     fUnpackRowLength;
9503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLint                     fPackAlignment;
9513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrFrameBufferObj*           fFrameBuffer;
9523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrRenderBufferObj*          fRenderBuffer;
9533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrProgramObj*               fProgram;
9543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    mutable bool                fAbandoned;
9553c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    // global store of all objects
9563c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    SkTArray<GrFakeRefObj *>    fObjects;
9573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static const GrGLubyte* CombinedExtensionString() {
9593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        static SkString gExtString;
9603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        static SkMutex gMutex;
9613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        gMutex.acquire();
9623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (0 == gExtString.size()) {
9633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            int i = 0;
9643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            while (kExtensions[i]) {
9653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                if (i > 0) {
9663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                    gExtString.append(" ");
9673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                }
9683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                gExtString.append(kExtensions[i]);
9693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                ++i;
9703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
9713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
9723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        gMutex.release();
9733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return (const GrGLubyte*) gExtString.c_str();
9743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
975ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
9763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
9773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < n; ++i) {
9783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            ids[i] = ++fCurrGenericID;
9793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
9803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
9813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length,
9833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                        char* infolog) {
9843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (length) {
9853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            *length = 0;
9863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
9873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (bufsize > 0) {
9883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            *infolog = 0;
9893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
9903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
9913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
9923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid getShaderOrProgramiv(GrGLuint object,  GrGLenum pname, GrGLint* params) {
9933c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (pname) {
9943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_LINK_STATUS:  // fallthru
9953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_COMPILE_STATUS:
9963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = GR_GL_TRUE;
9973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
9983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_INFO_LOG_LENGTH:
9993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 0;
10003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
10013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                // we don't expect any other pnames
10023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
10033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected pname to GetProgramiv");
10043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
10053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
10063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
10073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    template <typename T>
10093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) {
10103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        switch (pname) {
10113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_QUERY_RESULT_AVAILABLE:
10123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = GR_GL_TRUE;
10133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
10143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            case GR_GL_QUERY_RESULT:
10153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                *params = 0;
10163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
10173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            default:
10183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                SkFAIL("Unexpected pname passed to GetQueryObject.");
10193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                break;
10203c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
10213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
10223c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    enum ObjTypes {
10243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kTexture_ObjTypes = 0,
10253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kBuffer_ObjTypes,
10263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kRenderBuffer_ObjTypes,
10273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kFrameBuffer_ObjTypes,
10283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kShader_ObjTypes,
10293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kProgram_ObjTypes,
10303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kTextureUnit_ObjTypes,
10313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kVertexArray_ObjTypes,
10323c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        kObjTypeCount
10333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    };
10343c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10353c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    typedef GrFakeRefObj *(*Create)();
10363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    static Create gFactoryFunc[kObjTypeCount];
10383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrGLvoid genObjs(ObjTypes type, GrGLsizei n, GrGLuint* ids) {
10403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < n; ++i) {
10413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(ids[i] == 0);
10423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrFakeRefObj *obj = this->createObj(type);
10433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(obj);
10443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            ids[i] = obj->getID();
10453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
10463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
10473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrFakeRefObj* createObj(ObjTypes type) {
10493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrFakeRefObj *temp = (*gFactoryFunc[type])();
10503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fObjects.push_back(temp);
10523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return temp;
10543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
10553c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10563c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrFakeRefObj* findObject(GrGLuint ID, ObjTypes type) {
10573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < fObjects.count(); ++i) {
10583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            if (fObjects[i]->getID() == ID) { // && fObjects[i]->getType() == type) {
10593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                // The application shouldn't be accessing objects
10603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                // that (as far as OpenGL knows) were already deleted
10613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrAlwaysAssert(!fObjects[i]->getDeleted());
10623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrAlwaysAssert(!fObjects[i]->getMarkedForDeletion());
10633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                return fObjects[i];
10643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
10653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
10663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return nullptr;
10673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
10683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrTextureUnitObj* getTextureUnit(int unit) {
10703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        GrAlwaysAssert(0 <= unit && kDefaultMaxTextureUnits > unit);
10713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        return fTextureUnits[unit];
10733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
1074ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
10753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void setArrayBuffer(GrBufferObj *arrayBuffer) {
10763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fArrayBuffer) {
10773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            // automatically break the binding of the old buffer
10783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(fArrayBuffer->getBound());
10793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fArrayBuffer->resetBound();
10803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fArrayBuffer->getDeleted());
10823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fArrayBuffer->unref();
10833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
10843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fArrayBuffer = arrayBuffer;
10863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fArrayBuffer) {
10883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fArrayBuffer->getDeleted());
10893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fArrayBuffer->ref();
10903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fArrayBuffer->getBound());
10923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fArrayBuffer->setBound();
10933c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
10943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
10953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
10963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrBufferObj* getArrayBuffer() { return fArrayBuffer; }
10973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
10983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fElementArrayBuffer) {
10993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            // automatically break the binding of the old buffer
11003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(fElementArrayBuffer->getBound());
11013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fElementArrayBuffer->resetBound();
11023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
11043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fElementArrayBuffer->unref();
11053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fElementArrayBuffer = elementArrayBuffer;
11083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fElementArrayBuffer) {
11103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
11113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fElementArrayBuffer->ref();
11123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fElementArrayBuffer->getBound());
11143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fElementArrayBuffer->setBound();
11153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
11173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
11193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11203c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void setVertexArray(GrVertexArrayObj* vertexArray) {
11213c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (vertexArray) {
11223c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            SkASSERT(!vertexArray->getDeleted());
11233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        SkRefCnt_SafeAssign(fVertexArray, vertexArray);
11253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
11263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrVertexArrayObj* getVertexArray() { return fVertexArray; }
11283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void setTexture(GrTextureObj *texture) {
11303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fTextureUnits[fCurrTextureUnit]->setTexture(texture);
11313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
11323c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11333c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void setFrameBuffer(GrFrameBufferObj *frameBuffer) {
11343c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fFrameBuffer) {
11353c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(fFrameBuffer->getBound());
11363c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fFrameBuffer->resetBound();
11373c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11383c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fFrameBuffer->getDeleted());
11393c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fFrameBuffer->unref();
11403c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11413c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11423c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fFrameBuffer = frameBuffer;
11433c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11443c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fFrameBuffer) {
11453c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fFrameBuffer->getDeleted());
11463c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fFrameBuffer->ref();
11473c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11483c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fFrameBuffer->getBound());
11493c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fFrameBuffer->setBound();
11503c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11513c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
11523c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11533c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrFrameBufferObj *getFrameBuffer() { return fFrameBuffer; }
11543c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11553c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void setRenderBuffer(GrRenderBufferObj *renderBuffer) {
11563c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fRenderBuffer) {
11573c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(fRenderBuffer->getBound());
11583c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fRenderBuffer->resetBound();
11593c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11603c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fRenderBuffer->getDeleted());
11613c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fRenderBuffer->unref();
11623c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11633c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11643c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fRenderBuffer = renderBuffer;
11653c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11663c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fRenderBuffer) {
11673c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fRenderBuffer->getDeleted());
11683c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fRenderBuffer->ref();
11693c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11703c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fRenderBuffer->getBound());
11713c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fRenderBuffer->setBound();
11723c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11733c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
11743c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrRenderBufferObj *getRenderBuffer() { return fRenderBuffer; }
11753c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11763c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void useProgram(GrProgramObj *program) {
11773c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fProgram) {
11783c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(fProgram->getInUse());
11793c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fProgram->resetInUse();
11803c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11813c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fProgram->getDeleted());
11823c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fProgram->unref();
11833c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11843c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11853c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        fProgram = program;
11863c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11873c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        if (fProgram) {
11883c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fProgram->getDeleted());
11893c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fProgram->ref();
11903c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11913c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            GrAlwaysAssert(!fProgram->getInUse());
11923c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            fProgram->setInUse();
11933c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
11943c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
11953c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
11963c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    void report() const {
11973c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        for (int i = 0; i < fObjects.count(); ++i) {
11983c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            if (!fAbandoned) {
11993c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrAlwaysAssert(0 == fObjects[i]->getRefCount());
12003c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon                GrAlwaysAssert(fObjects[i]->getDeleted());
12013c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon            }
12023c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon        }
12033c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    }
12043c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
12053c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    typedef GrGLTestInterface INHERITED;
12063c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon};
12073c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
12083c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#undef CREATE
12093c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon#undef FIND
12103c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
12113c481001b16288f604a5279bcb4bf46c5dd2b703bsalomonDebugInterface::Create DebugInterface::gFactoryFunc[kObjTypeCount] = {
12123c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrTextureObj::createGrTextureObj,
12133c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrBufferObj::createGrBufferObj,
12143c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrRenderBufferObj::createGrRenderBufferObj,
12153c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrFrameBufferObj::createGrFrameBufferObj,
12163c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrShaderObj::createGrShaderObj,
12173c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrProgramObj::createGrProgramObj,
12183c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrTextureUnitObj::createGrTextureUnitObj,
12193c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    GrVertexArrayObj::createGrVertexArrayObj,
1220ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com};
1221ba0cc3ef1109c5ebba7e3fffda5408ce6120eb9drobertphillips@google.com
12223c481001b16288f604a5279bcb4bf46c5dd2b703bsalomonconst char* DebugInterface::kExtensions[] = {
12233c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    "GL_ARB_framebuffer_object",
12243c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    "GL_ARB_blend_func_extended",
12253c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    "GL_ARB_timer_query",
12263c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    "GL_ARB_draw_buffers",
12273c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    "GL_ARB_occlusion_query",
12283c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    "GL_EXT_stencil_wrap",
12293c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon    nullptr, // signifies the end of the array.
12303c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon};
12313c481001b16288f604a5279bcb4bf46c5dd2b703bsalomon
1232273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonclass DebugGLContext : public sk_gpu_test::GLTestContext {
12333724e574a744491b7cfb8187ac865a70ef3d4528bsalomonpublic:
12343724e574a744491b7cfb8187ac865a70ef3d4528bsalomon   DebugGLContext() {
12353724e574a744491b7cfb8187ac865a70ef3d4528bsalomon       this->init(new DebugInterface());
12363724e574a744491b7cfb8187ac865a70ef3d4528bsalomon   }
1237fe3456cb006110d045b26ff3f8681b893a757b58bsalomon
12383724e574a744491b7cfb8187ac865a70ef3d4528bsalomon   ~DebugGLContext() override { this->teardown(); }
12396f70d43719d0583d486a000f66e915c10a6b83a2robertphillips
12403724e574a744491b7cfb8187ac865a70ef3d4528bsalomonprivate:
12413724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    void onPlatformMakeCurrent() const override {}
12423724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    void onPlatformSwapBuffers() const override {}
12433724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override { return nullptr; }
12443724e574a744491b7cfb8187ac865a70ef3d4528bsalomon};
12453724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}  // anonymous namespace
12463724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
12473724e574a744491b7cfb8187ac865a70ef3d4528bsalomonnamespace sk_gpu_test {
1248273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonGLTestContext* CreateDebugGLTestContext() {
1249273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon    GLTestContext* ctx = new DebugGLContext();
12503724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    if (ctx->isValid()) {
12513724e574a744491b7cfb8187ac865a70ef3d4528bsalomon        return ctx;
12523724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    }
12533724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    delete ctx;
12543724e574a744491b7cfb8187ac865a70ef3d4528bsalomon    return nullptr;
12553724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}
12563724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}
1257