Add support for glDrawRangeElements
authorbsalomon <bsalomon@google.com>
Mon, 29 Aug 2016 16:18:39 +0000 (09:18 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 29 Aug 2016 16:18:39 +0000 (09:18 -0700)
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2287003002

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

include/gpu/gl/GrGLFunctions.h
include/gpu/gl/GrGLInterface.h
src/gpu/gl/GrGLAssembleInterface.cpp
src/gpu/gl/GrGLCaps.cpp
src/gpu/gl/GrGLCaps.h
src/gpu/gl/GrGLGpu.cpp
src/gpu/gl/GrGLInterface.cpp
src/gpu/gl/GrGLTestInterface.cpp
src/gpu/gl/GrGLTestInterface.h

index 4dff208..7e720cd 100644 (file)
@@ -66,6 +66,7 @@ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawBuffersProc)(GrGLsizei n, const G
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsInstancedProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid *indices, GrGLsizei primcount);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsIndirectProc)(GrGLenum mode, GrGLenum type, const GrGLvoid* indirect);
+typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawRangeElementsProc)(GrGLenum mode, GrGLuint start, GrGLuint end, GrGLsizei count, GrGLenum type, const GrGLvoid* indices);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableProc)(GrGLenum cap);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableVertexAttribArrayProc)(GrGLuint index);
 typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEndQueryProc)(GrGLenum target);
index 0603e9e..27184ad 100644 (file)
@@ -155,6 +155,7 @@ public:
         GrGLFunction<GrGLDrawElementsProc> fDrawElements;
         GrGLFunction<GrGLDrawElementsIndirectProc> fDrawElementsIndirect;
         GrGLFunction<GrGLDrawElementsInstancedProc> fDrawElementsInstanced;
+        GrGLFunction<GrGLDrawRangeElementsProc> fDrawRangeElements;
         GrGLFunction<GrGLEnableProc> fEnable;
         GrGLFunction<GrGLEnableVertexAttribArrayProc> fEnableVertexAttribArray;
         GrGLFunction<GrGLEndQueryProc> fEndQuery;
index 2233005..e804dd6 100644 (file)
@@ -148,7 +148,9 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
         GET_PROC(DrawArraysIndirect);
         GET_PROC(DrawElementsIndirect);
     }
-
+    if (glVer >= GR_GL_VER(2,0)) {
+        GET_PROC(DrawRangeElements);
+    }
     GET_PROC(Enable);
     GET_PROC(EnableVertexAttribArray);
     GET_PROC(EndQuery);
@@ -615,6 +617,9 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
     }
 
     GET_PROC(DrawElements);
+    if (version >= GR_GL_VER(3,0)) {
+        GET_PROC(DrawRangeElements);
+    }
     GET_PROC(Enable);
     GET_PROC(EnableVertexAttribArray);
     GET_PROC(Finish);
index 255d516..b6e9f22 100644 (file)
@@ -525,12 +525,14 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
                                     (fDrawIndirectSupport &&
                                      !fBaseInstanceSupport && // The ARB extension has no base inst.
                                      ctxInfo.hasExtension("GL_ARB_multi_draw_indirect"));
+        fDrawRangeElementsSupport = version >= GR_GL_VER(2,0);
     } else {
         fDrawIndirectSupport = version >= GR_GL_VER(3,1);
         fMultiDrawIndirectSupport = fDrawIndirectSupport &&
                                     ctxInfo.hasExtension("GL_EXT_multi_draw_indirect");
         fBaseInstanceSupport = fDrawIndirectSupport &&
                                ctxInfo.hasExtension("GL_EXT_base_instance");
+        fDrawRangeElementsSupport = version >= GR_GL_VER(3,0);
     }
 
     this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
index 3408ae0..f0b0940 100644 (file)
@@ -307,6 +307,9 @@ public:
     /// draw commands cannot be used unless we have base instance support.
     bool multiDrawIndirectSupport() const { return fMultiDrawIndirectSupport; }
 
+    /// Is there support for glDrawRangeElements?
+    bool drawRangeElementsSupport() const { return fDrawRangeElementsSupport; }
+
     /// Are the baseInstance fields supported in indirect draw commands?
     bool baseInstanceSupport() const { return fBaseInstanceSupport; }
 
@@ -400,6 +403,7 @@ private:
     bool fES2CompatibilitySupport : 1;
     bool fDrawInstancedSupport : 1;
     bool fDrawIndirectSupport : 1;
+    bool fDrawRangeElementsSupport : 1;
     bool fMultiDrawIndirectSupport : 1;
     bool fBaseInstanceSupport : 1;
     bool fUseNonVBOVertexAndIndexDynamicData : 1;
index 83d2df2..9981b66 100644 (file)
@@ -2762,28 +2762,40 @@ void GrGLGpu::draw(const GrPipeline& pipeline,
 
         const GrMesh& mesh = meshes[i];
         GrMesh::Iterator iter;
-        const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
+        const GrNonInstancedMesh* nonInstMesh = iter.init(mesh);
         do {
             size_t indexOffsetInBytes = 0;
-            this->setupGeometry(primProc, *nonIdxMesh, &indexOffsetInBytes);
-            if (nonIdxMesh->isIndexed()) {
+            this->setupGeometry(primProc, *nonInstMesh, &indexOffsetInBytes);
+            if (nonInstMesh->isIndexed()) {
                 GrGLvoid* indices =
-                    reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) *
-                    nonIdxMesh->startIndex());
+                    reinterpret_cast<GrGLvoid*>(indexOffsetInBytes +
+                                                sizeof(uint16_t) * nonInstMesh->startIndex());
                 // info.startVertex() was accounted for by setupGeometry.
-                GL_CALL(DrawElements(gPrimitiveType2GLMode[nonIdxMesh->primitiveType()],
-                                     nonIdxMesh->indexCount(),
-                                     GR_GL_UNSIGNED_SHORT,
-                                     indices));
+                if (this->glCaps().drawRangeElementsSupport()) {
+                    // We assume here that the batch that generated the mesh used the full
+                    // 0..vertexCount()-1 range.
+                    int start = 0;
+                    int end = nonInstMesh->vertexCount() - 1;
+                    GL_CALL(DrawRangeElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
+                                              start, end,
+                                              nonInstMesh->indexCount(),
+                                              GR_GL_UNSIGNED_SHORT,
+                                              indices));
+                } else {
+                    GL_CALL(DrawElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
+                                         nonInstMesh->indexCount(),
+                                         GR_GL_UNSIGNED_SHORT,
+                                         indices));
+                }
             } else {
                 // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account
                 // for startVertex in the DrawElements case. So we always rely on setupGeometry to
                 // have accounted for startVertex.
-                GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonIdxMesh->primitiveType()], 0,
-                                   nonIdxMesh->vertexCount()));
+                GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonInstMesh->primitiveType()], 0,
+                                   nonInstMesh->vertexCount()));
             }
             fStats.incNumDraws();
-        } while ((nonIdxMesh = iter.next()));
+        } while ((nonInstMesh = iter.next()));
     }
 
     if (fHWPLSEnabled && plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState) {
index ada6d8b..c3fc8a8 100644 (file)
@@ -793,5 +793,15 @@ bool GrGLInterface::validate() const {
         }
     }
 
+    if (kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(2,0)) {
+        if (nullptr == fFunctions.fDrawRangeElements) {
+            RETURN_FALSE_INTERFACE;
+        }
+    } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) {
+        if (nullptr == fFunctions.fDrawRangeElements) {
+            RETURN_FALSE_INTERFACE;
+        }
+    }
+
     return true;
 }
index c992587..10968a7 100644 (file)
@@ -65,6 +65,7 @@ GrGLTestInterface::GrGLTestInterface() {
     fFunctions.fDrawElements = bind_to_member(this, &GrGLTestInterface::drawElements);
     fFunctions.fDrawElementsInstanced = bind_to_member(this, &GrGLTestInterface::drawElementsInstanced);
     fFunctions.fDrawElementsIndirect = bind_to_member(this, &GrGLTestInterface::drawElementsIndirect);
+    fFunctions.fDrawRangeElements = bind_to_member(this, &GrGLTestInterface::drawRangeElements);
     fFunctions.fEnable = bind_to_member(this, &GrGLTestInterface::enable);
     fFunctions.fEnableVertexAttribArray = bind_to_member(this, &GrGLTestInterface::enableVertexAttribArray);
     fFunctions.fEndQuery = bind_to_member(this, &GrGLTestInterface::endQuery);
index 8f8a8bc..fc837bf 100644 (file)
@@ -66,6 +66,7 @@ public:
     virtual GrGLvoid drawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
     virtual GrGLvoid drawElementsInstanced(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid *indices, GrGLsizei primcount) {}
     virtual GrGLvoid drawElementsIndirect(GrGLenum mode, GrGLenum type, const GrGLvoid* indirect) {}
+    virtual GrGLvoid drawRangeElements(GrGLenum mode, GrGLuint start, GrGLuint end, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
     virtual GrGLvoid enable(GrGLenum cap) {}
     virtual GrGLvoid enableVertexAttribArray(GrGLuint index) {}
     virtual GrGLvoid endQuery(GrGLenum target) {}