Support texel and draw-indirect buffers in null GL contexts
authorcsmartdalton <csmartdalton@google.com>
Tue, 21 Jun 2016 14:55:17 +0000 (07:55 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 21 Jun 2016 14:55:17 +0000 (07:55 -0700)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2081183002

Review-Url: https://codereview.chromium.org/2081183002

src/gpu/gl/GrGLCreateNullInterface.cpp
tools/gpu/gl/debug/DebugGLTestContext.cpp

index 7282667..efdea2b 100644 (file)
@@ -113,15 +113,12 @@ private:
 class NullInterface : public GrGLTestInterface {
 public:
     NullInterface(bool enableNVPR)
-        : fCurrArrayBuffer(0)
-        , fCurrElementArrayBuffer(0)
-        , fCurrPixelPackBuffer(0)
-        , fCurrPixelUnpackBuffer(0)
-        , fCurrProgramID(0)
+        : fCurrProgramID(0)
         , fCurrShaderID(0)
         , fCurrGenericID(0)
         , fCurrUniformLocation(0)
         , fCurrPathID(0) {
+        memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
         fExtensions.push_back("GL_ARB_framebuffer_object");
         fExtensions.push_back("GL_ARB_blend_func_extended");
         fExtensions.push_back("GL_ARB_timer_query");
@@ -150,26 +147,7 @@ public:
 
     GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
                         GrGLenum usage) override {
-        GrGLuint id = 0;
-
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                id = fCurrArrayBuffer;
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                id = fCurrElementArrayBuffer;
-                break;
-            case GR_GL_PIXEL_PACK_BUFFER:
-                id = fCurrPixelPackBuffer;
-                break;
-            case GR_GL_PIXEL_UNPACK_BUFFER:
-                id = fCurrPixelUnpackBuffer;
-                break;
-            default:
-                SkFAIL("Unexpected target to nullGLBufferData");
-                break;
-        }
-
+        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
         if (id > 0) {
             BufferObj* buffer = fBufferManager.lookUp(id);
             buffer->allocate(size, (const GrGLchar*) data);
@@ -185,38 +163,26 @@ public:
     }
 
     GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override {
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                fCurrArrayBuffer = buffer;
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                fCurrElementArrayBuffer = buffer;
-                break;
-            case GR_GL_PIXEL_PACK_BUFFER:
-                fCurrPixelPackBuffer = buffer;
-                break;
-            case GR_GL_PIXEL_UNPACK_BUFFER:
-                fCurrPixelUnpackBuffer = buffer;
-                break;
-        }
+        fBoundBuffers[GetBufferIndex(target)] = buffer;
     }
 
    // deleting a bound buffer has the side effect of binding 0
-    GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
-        for (int i = 0; i < n; ++i) {
-            if (ids[i] == fCurrArrayBuffer) {
-                fCurrArrayBuffer = 0;
-            }
-            if (ids[i] == fCurrElementArrayBuffer) {
-                fCurrElementArrayBuffer = 0;
+   GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
+        // First potentially unbind the buffers.
+        for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) {
+            if (!fBoundBuffers[buffIdx]) {
+                continue;
             }
-            if (ids[i] == fCurrPixelPackBuffer) {
-                fCurrPixelPackBuffer = 0;
-            }
-            if (ids[i] == fCurrPixelUnpackBuffer) {
-                fCurrPixelUnpackBuffer = 0;
+            for (int i = 0; i < n; ++i) {
+                if (ids[i] == fBoundBuffers[buffIdx]) {
+                    fBoundBuffers[buffIdx] = 0;
+                    break;
+                }
             }
+        }
 
+        // Then actually "delete" the buffers.
+        for (int i = 0; i < n; ++i) {
             if (ids[i] > 0) {
                 BufferObj* buffer = fBufferManager.lookUp(ids[i]);
                 fBufferManager.free(buffer);
@@ -407,22 +373,7 @@ public:
 
     GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
                              GrGLbitfield access) override {
-        GrGLuint id = 0;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                id = fCurrArrayBuffer;
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                id = fCurrElementArrayBuffer;
-                break;
-            case GR_GL_PIXEL_PACK_BUFFER:
-                id = fCurrPixelPackBuffer;
-                break;
-            case GR_GL_PIXEL_UNPACK_BUFFER:
-                id = fCurrPixelUnpackBuffer;
-                break;
-        }
-
+        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
         if (id > 0) {
             // We just ignore the offset and length here.
             BufferObj* buffer = fBufferManager.lookUp(id);
@@ -434,22 +385,7 @@ public:
     }
 
     GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
-        GrGLuint id = 0;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                id = fCurrArrayBuffer;
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                id = fCurrElementArrayBuffer;
-                break;
-            case GR_GL_PIXEL_PACK_BUFFER:
-                id = fCurrPixelPackBuffer;
-                break;
-            case GR_GL_PIXEL_UNPACK_BUFFER:
-                id = fCurrPixelUnpackBuffer;
-                break;
-        }
-
+        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
         if (id > 0) {
             BufferObj* buffer = fBufferManager.lookUp(id);
             SkASSERT(!buffer->mapped());
@@ -462,21 +398,7 @@ public:
     }
 
     GrGLboolean unmapBuffer(GrGLenum target) override {
-        GrGLuint id = 0;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                id = fCurrArrayBuffer;
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                id = fCurrElementArrayBuffer;
-                break;
-            case GR_GL_PIXEL_PACK_BUFFER:
-                id = fCurrPixelPackBuffer;
-                break;
-            case GR_GL_PIXEL_UNPACK_BUFFER:
-                id = fCurrPixelUnpackBuffer;
-                break;
-        }
+        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
         if (id > 0) {
             BufferObj* buffer = fBufferManager.lookUp(id);
             SkASSERT(buffer->mapped());
@@ -492,21 +414,7 @@ public:
         switch (pname) {
             case GR_GL_BUFFER_MAPPED: {
                 *params = GR_GL_FALSE;
-                GrGLuint id = 0;
-                switch (target) {
-                    case GR_GL_ARRAY_BUFFER:
-                        id = fCurrArrayBuffer;
-                        break;
-                    case GR_GL_ELEMENT_ARRAY_BUFFER:
-                        id = fCurrElementArrayBuffer;
-                        break;
-                    case GR_GL_PIXEL_PACK_BUFFER:
-                        id = fCurrPixelPackBuffer;
-                        break;
-                    case GR_GL_PIXEL_UNPACK_BUFFER:
-                        id = fCurrPixelUnpackBuffer;
-                        break;
-                }
+                GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
                 if (id > 0) {
                     BufferObj* buffer = fBufferManager.lookUp(id);
                     if (buffer->mapped()) {
@@ -527,11 +435,21 @@ public:
 
 
 private:
+    inline int static GetBufferIndex(GrGLenum glTarget) {
+        switch (glTarget) {
+            default:                           SkFAIL("Unexpected GL target to GetBufferIndex");
+            case GR_GL_ARRAY_BUFFER:           return 0;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:   return 1;
+            case GR_GL_TEXTURE_BUFFER:         return 2;
+            case GR_GL_DRAW_INDIRECT_BUFFER:   return 3;
+            case GR_GL_PIXEL_PACK_BUFFER:      return 4;
+            case GR_GL_PIXEL_UNPACK_BUFFER:    return 5;
+        }
+    }
+    constexpr int static kNumBufferTargets = 6;
+
     BufferManager          fBufferManager;
-    GrGLuint               fCurrArrayBuffer;
-    GrGLuint               fCurrElementArrayBuffer;
-    GrGLuint               fCurrPixelPackBuffer;
-    GrGLuint               fCurrPixelUnpackBuffer;
+    GrGLuint               fBoundBuffers[kNumBufferTargets];
     GrGLuint               fCurrProgramID;
     GrGLuint               fCurrShaderID;
     GrGLuint               fCurrGenericID;
index 96640c5..022d56a 100644 (file)
@@ -35,8 +35,6 @@ public:
     DebugInterface()
         : fCurrGenericID(0)
         , fCurrTextureUnit(0)
-        , fArrayBuffer(nullptr)
-        , fElementArrayBuffer(nullptr)
         , fVertexArray(nullptr)
         , fPackRowLength(0)
         , fUnpackRowLength(0)
@@ -51,6 +49,7 @@ public:
             fTextureUnits[i]->ref();
             fTextureUnits[i]->setNumber(i);
         }
+        memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
         this->init(kGL_GrGLStandard);
     }
 
@@ -65,8 +64,7 @@ public:
         }
         fObjects.reset();
 
-        fArrayBuffer = nullptr;
-        fElementArrayBuffer = nullptr;
+        memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
         fVertexArray = nullptr;
 
         this->report();
@@ -107,26 +105,12 @@ public:
     ////////////////////////////////////////////////////////////////////////////////
     GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
                         GrGLenum usage) override {
-        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
-                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
         GrAlwaysAssert(size >= 0);
         GrAlwaysAssert(GR_GL_STREAM_DRAW == usage ||
                        GR_GL_STATIC_DRAW == usage ||
                        GR_GL_DYNAMIC_DRAW == usage);
 
-        GrBufferObj *buffer = nullptr;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                buffer = this->getArrayBuffer();
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                buffer = this->getElementArrayBuffer();
-                break;
-            default:
-                SkFAIL("Unexpected target to glBufferData");
-                break;
-        }
-
+        GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
         GrAlwaysAssert(buffer);
         GrAlwaysAssert(buffer->getBound());
 
@@ -726,38 +710,25 @@ public:
     }
 
     GrGLvoid bindBuffer(GrGLenum target, GrGLuint bufferID) override {
-        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target || GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
         GrBufferObj *buffer = FIND(bufferID, GrBufferObj, kBuffer_ObjTypes);
         // 0 is a permissible bufferID - it unbinds the current buffer
 
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                this->setArrayBuffer(buffer);
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                this->setElementArrayBuffer(buffer);
-                break;
-            default:
-                SkFAIL("Unexpected target to glBindBuffer");
-                break;
-        }
+        this->setBuffer(GetBufferIndex(target), buffer);
     }
 
     // deleting a bound buffer has the side effect of binding 0
     GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
         // first potentially unbind the buffers
-        for (int i = 0; i < n; ++i) {
-
-            if (this->getArrayBuffer() &&
-                ids[i] == this->getArrayBuffer()->getID()) {
-                // this ID is the current array buffer
-                this->setArrayBuffer(nullptr);
+        for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) {
+            GrBufferObj* buffer = fBoundBuffers[buffIdx];
+            if (!buffer) {
+                continue;
             }
-            if (this->getElementArrayBuffer() &&
-                ids[i] == this->getElementArrayBuffer()->getID()) {
-                // this ID is the current element array buffer
-                this->setElementArrayBuffer(nullptr);
+            for (int i = 0; i < n; ++i) {
+                if (ids[i] == buffer->getID()) {
+                    this->setBuffer(buffIdx, nullptr);
+                    break;
+                }
             }
         }
 
@@ -774,26 +745,11 @@ public:
     // map a buffer to the caller's address space
     GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
                              GrGLbitfield access) override {
-        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
-                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
         // We only expect read access and we expect that the buffer or range is always invalidated.
         GrAlwaysAssert(!SkToBool(GR_GL_MAP_READ_BIT & access));
         GrAlwaysAssert((GR_GL_MAP_INVALIDATE_BUFFER_BIT | GR_GL_MAP_INVALIDATE_RANGE_BIT) & access);
 
-        GrBufferObj *buffer = nullptr;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                buffer = this->getArrayBuffer();
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                buffer = this->getElementArrayBuffer();
-                break;
-            default:
-                SkFAIL("Unexpected target to glMapBufferRange");
-                break;
-        }
-
+        GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
         if (buffer) {
             GrAlwaysAssert(offset >= 0 && offset + length <= buffer->getSize());
             GrAlwaysAssert(!buffer->getMapped());
@@ -807,20 +763,7 @@ public:
 
     GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
         GrAlwaysAssert(GR_GL_WRITE_ONLY == access);
-
-        GrBufferObj *buffer = nullptr;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                buffer = this->getArrayBuffer();
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                buffer = this->getElementArrayBuffer();
-                break;
-            default:
-                SkFAIL("Unexpected target to glMapBuffer");
-                break;
-        }
-
+        GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
         return this->mapBufferRange(target, 0, buffer->getSize(),
                                     GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT);
     }
@@ -828,22 +771,7 @@ public:
     // remove a buffer from the caller's address space
     // TODO: check if the "access" method from "glMapBuffer" was honored
     GrGLboolean unmapBuffer(GrGLenum target) override {
-        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
-                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
-        GrBufferObj *buffer = nullptr;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                buffer = this->getArrayBuffer();
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                buffer = this->getElementArrayBuffer();
-                break;
-            default:
-                SkFAIL("Unexpected target to glUnmapBuffer");
-                break;
-        }
-
+        GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
         if (buffer) {
             GrAlwaysAssert(buffer->getMapped());
             buffer->resetMapped();
@@ -856,22 +784,7 @@ public:
 
     GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset,
                                     GrGLsizeiptr length) override {
-        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
-                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
-
-        GrBufferObj *buffer = nullptr;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                buffer = this->getArrayBuffer();
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                buffer = this->getElementArrayBuffer();
-                break;
-            default:
-                SkFAIL("Unexpected target to glUnmapBuffer");
-                break;
-        }
-
+        GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
         if (buffer) {
             GrAlwaysAssert(buffer->getMapped());
             GrAlwaysAssert(offset >= 0 && (offset + length) <= buffer->getMappedLength());
@@ -882,21 +795,10 @@ public:
 
     GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum value, GrGLint* params) override {
 
-        GrAlwaysAssert(GR_GL_ARRAY_BUFFER == target ||
-                       GR_GL_ELEMENT_ARRAY_BUFFER == target);
         GrAlwaysAssert(GR_GL_BUFFER_SIZE == value ||
                        GR_GL_BUFFER_USAGE == value);
 
-        GrBufferObj *buffer = nullptr;
-        switch (target) {
-            case GR_GL_ARRAY_BUFFER:
-                buffer = this->getArrayBuffer();
-                break;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:
-                buffer = this->getElementArrayBuffer();
-                break;
-        }
-
+        GrBufferObj *buffer = fBoundBuffers[GetBufferIndex(target)];
         GrAlwaysAssert(buffer);
 
         switch (value) {
@@ -922,6 +824,17 @@ public:
     }
 
 private:
+    inline int static GetBufferIndex(GrGLenum glTarget) {
+        switch (glTarget) {
+            default:                           SkFAIL("Unexpected GL target to GetBufferIndex");
+            case GR_GL_ARRAY_BUFFER:           return 0;
+            case GR_GL_ELEMENT_ARRAY_BUFFER:   return 1;
+            case GR_GL_TEXTURE_BUFFER:         return 2;
+            case GR_GL_DRAW_INDIRECT_BUFFER:   return 3;
+        }
+    }
+    constexpr int static kNumBufferTargets = 4;
+
     // the OpenGLES 2.0 spec says this must be >= 128
     static const GrGLint kDefaultMaxVertexUniformVectors = 128;
 
@@ -942,8 +855,7 @@ private:
     GrGLuint                    fCurrGenericID;
     GrGLuint                    fCurrTextureUnit;
     GrTextureUnitObj*           fTextureUnits[kDefaultMaxTextureUnits];
-    GrBufferObj*                fArrayBuffer;
-    GrBufferObj*                fElementArrayBuffer;
+    GrBufferObj*                fBoundBuffers[kNumBufferTargets];
     GrVertexArrayObj*           fVertexArray;
     GrGLint                     fPackRowLength;
     GrGLint                     fUnpackRowLength;
@@ -1072,51 +984,27 @@ private:
         return fTextureUnits[unit];
     }
 
-    void setArrayBuffer(GrBufferObj *arrayBuffer) {
-        if (fArrayBuffer) {
+    GrGLvoid setBuffer(int buffIdx, GrBufferObj* buffer) {
+        if (fBoundBuffers[buffIdx]) {
             // automatically break the binding of the old buffer
-            GrAlwaysAssert(fArrayBuffer->getBound());
-            fArrayBuffer->resetBound();
-
-            GrAlwaysAssert(!fArrayBuffer->getDeleted());
-            fArrayBuffer->unref();
-        }
-
-        fArrayBuffer = arrayBuffer;
+            GrAlwaysAssert(fBoundBuffers[buffIdx]->getBound());
+            fBoundBuffers[buffIdx]->resetBound();
 
-        if (fArrayBuffer) {
-            GrAlwaysAssert(!fArrayBuffer->getDeleted());
-            fArrayBuffer->ref();
-
-            GrAlwaysAssert(!fArrayBuffer->getBound());
-            fArrayBuffer->setBound();
+            GrAlwaysAssert(!fBoundBuffers[buffIdx]->getDeleted());
+            fBoundBuffers[buffIdx]->unref();
         }
-    }
 
-    GrBufferObj* getArrayBuffer() { return fArrayBuffer; }
-    void setElementArrayBuffer(GrBufferObj *elementArrayBuffer) {
-        if (fElementArrayBuffer) {
-            // automatically break the binding of the old buffer
-            GrAlwaysAssert(fElementArrayBuffer->getBound());
-            fElementArrayBuffer->resetBound();
+        if (buffer) {
+            GrAlwaysAssert(!buffer->getDeleted());
+            buffer->ref();
 
-            GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
-            fElementArrayBuffer->unref();
+            GrAlwaysAssert(!buffer->getBound());
+            buffer->setBound();
         }
 
-        fElementArrayBuffer = elementArrayBuffer;
-
-        if (fElementArrayBuffer) {
-            GrAlwaysAssert(!fElementArrayBuffer->getDeleted());
-            fElementArrayBuffer->ref();
-
-            GrAlwaysAssert(!fElementArrayBuffer->getBound());
-            fElementArrayBuffer->setBound();
-        }
+        fBoundBuffers[buffIdx] = buffer;
     }
 
-    GrBufferObj *getElementArrayBuffer() { return fElementArrayBuffer; }
-
     void setVertexArray(GrVertexArrayObj* vertexArray) {
         if (vertexArray) {
             SkASSERT(!vertexArray->getDeleted());