Add glDraw*BaseInstance functions to GrGLInterface

Change-Id: I3f36fc0bdbc1d25e3da0e29be215a19acba6ed0e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/279407
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/include/gpu/gl/GrGLFunctions.h b/include/gpu/gl/GrGLFunctions.h
index 83f5255..52580c2 100644
--- a/include/gpu/gl/GrGLFunctions.h
+++ b/include/gpu/gl/GrGLFunctions.h
@@ -233,6 +233,11 @@
 /* GL_NV_framebuffer_mixed_samples */
 using GrGLCoverageModulationFn = GrGLvoid GR_GL_FUNCTION_TYPE(GrGLenum components);
 
+/* EXT_base_instance */
+using GrGLDrawArraysInstancedBaseInstanceFn = GrGLvoid GR_GL_FUNCTION_TYPE(GrGLenum mode, GrGLint first, GrGLsizei count, GrGLsizei instancecount, GrGLuint baseinstance);
+using GrGLDrawElementsInstancedBaseInstanceFn = GrGLvoid GR_GL_FUNCTION_TYPE(GrGLenum GrGLmode, GrGLsizei count, GrGLenum type, const void *indices, GrGLsizei instancecount, GrGLuint baseinstance);
+using GrGLDrawElementsInstancedBaseVertexBaseInstanceFn = GrGLvoid GR_GL_FUNCTION_TYPE(GrGLenum mode, GrGLsizei count, GrGLenum type, const void *indices, GrGLsizei instancecount, GrGLint basevertex, GrGLuint baseinstance);
+
 /* EXT_multi_draw_indirect */
 using GrGLMultiDrawArraysIndirectFn = GrGLvoid GR_GL_FUNCTION_TYPE(GrGLenum mode, const GrGLvoid* indirect, GrGLsizei drawcount, GrGLsizei stride);
 using GrGLMultiDrawElementsIndirectFn = GrGLvoid GR_GL_FUNCTION_TYPE(GrGLenum mode, GrGLenum type, const GrGLvoid* indirect, GrGLsizei drawcount, GrGLsizei stride);
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index 6d32370..31ca9d1 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -185,6 +185,9 @@
         GrGLFunction<GrGLMapBufferSubDataFn> fMapBufferSubData;
         GrGLFunction<GrGLMapTexSubImage2DFn> fMapTexSubImage2D;
         GrGLFunction<GrGLMemoryBarrierFn> fMemoryBarrier;
+        GrGLFunction<GrGLDrawArraysInstancedBaseInstanceFn> fDrawArraysInstancedBaseInstance;
+        GrGLFunction<GrGLDrawElementsInstancedBaseInstanceFn> fDrawElementsInstancedBaseInstance;
+        GrGLFunction<GrGLDrawElementsInstancedBaseVertexBaseInstanceFn> fDrawElementsInstancedBaseVertexBaseInstance;
         GrGLFunction<GrGLMultiDrawArraysIndirectFn> fMultiDrawArraysIndirect;
         GrGLFunction<GrGLMultiDrawElementsIndirectFn> fMultiDrawElementsIndirect;
         GrGLFunction<GrGLPatchParameteriFn> fPatchParameteri;
diff --git a/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp b/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp
index f9361a6..edbfdc2 100644
--- a/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp
+++ b/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp
@@ -195,6 +195,12 @@
         GET_PROC_SUFFIX(DrawElementsInstanced, EXT);
     }
 
+    if (extensions.has("GL_EXT_base_instance")) {
+        GET_PROC_SUFFIX(DrawArraysInstancedBaseInstance, EXT);
+        GET_PROC_SUFFIX(DrawElementsInstancedBaseInstance, EXT);
+        GET_PROC_SUFFIX(DrawElementsInstancedBaseVertexBaseInstance, EXT);
+    }
+
     if (glVer >= GR_GL_VER(3,0)) {
         GET_PROC(DrawBuffers);
         GET_PROC(ReadBuffer);
diff --git a/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp b/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp
index e100f78..5af82a0 100644
--- a/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp
+++ b/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp
@@ -203,6 +203,16 @@
         GET_PROC_SUFFIX(DrawElementsInstanced, EXT);
     }
 
+    if (glVer >= GR_GL_VER(4,2)) {
+        GET_PROC(DrawArraysInstancedBaseInstance);
+        GET_PROC(DrawElementsInstancedBaseInstance);
+        GET_PROC(DrawElementsInstancedBaseVertexBaseInstance);
+    } else if (extensions.has("GL_ARB_base_instance")) {
+        GET_PROC(DrawArraysInstancedBaseInstance);
+        GET_PROC(DrawElementsInstancedBaseInstance);
+        GET_PROC(DrawElementsInstancedBaseVertexBaseInstance);
+    }
+
     GET_PROC(DrawBuffers);
     GET_PROC(ReadBuffer);
 
diff --git a/src/gpu/gl/GrGLInterfaceAutogen.cpp b/src/gpu/gl/GrGLInterfaceAutogen.cpp
index dcc337c..c3e7af3 100644
--- a/src/gpu/gl/GrGLInterfaceAutogen.cpp
+++ b/src/gpu/gl/GrGLInterfaceAutogen.cpp
@@ -234,6 +234,14 @@
         }
     }
 
+    if ((GR_IS_GR_GL(fStandard) && (
+          (glVer >= GR_GL_VER(4,2)) ||
+          fExtensions.has("GL_ARB_base_instance"))) ||
+       (GR_IS_GR_GL_ES(fStandard) && (
+          fExtensions.has("GL_EXT_base_instance")))) {
+        // all functions were marked optional or test_only
+    }
+
     if (GR_IS_GR_GL(fStandard) ||
        (GR_IS_GR_GL_ES(fStandard) && (
           (glVer >= GR_GL_VER(3,0)))) ||
diff --git a/tools/gpu/gl/interface/interface.json5 b/tools/gpu/gl/interface/interface.json5
index 8ba26ae..6199cb8 100644
--- a/tools/gpu/gl/interface/interface.json5
+++ b/tools/gpu/gl/interface/interface.json5
@@ -168,6 +168,23 @@
       "DrawArraysInstanced", "DrawElementsInstanced",
     ]
   },
+
+  {
+    "GL":    [{"min_version": [4, 2], "ext": "<core>"},
+              {/*    else if      */  "ext": "GL_ARB_base_instance"}],
+    "GLES":  [{"ext": "GL_EXT_base_instance"}],
+    "WebGL": null,
+
+    "functions": [
+      "DrawArraysInstancedBaseInstance", "DrawElementsInstancedBaseInstance",
+      "DrawElementsInstancedBaseVertexBaseInstance"
+    ],
+    "optional": [
+      "DrawArraysInstancedBaseInstance", "DrawElementsInstancedBaseInstance",
+      "DrawElementsInstancedBaseVertexBaseInstance"
+    ]
+  },
+
   { // ES 3.0 has glDrawBuffers but not glDrawBuffer
     "GL":    [{"ext": "<core>"}],
     "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],