Support GL_EXT_draw_buffers

Change-Id: I078aa7c42de4368602b0ef43bd7e18efbfd1e049
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/212182
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp b/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp
index 73aacc1..53b50e1 100644
--- a/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp
+++ b/src/gpu/gl/GrGLAssembleGLESInterfaceAutogen.cpp
@@ -187,6 +187,11 @@
 
     if (glVer >= GR_GL_VER(3,0)) {
         GET_PROC(DrawBuffers);
+    } else if (extensions.has("GL_EXT_draw_buffers")) {
+        GET_PROC_SUFFIX(DrawBuffers, EXT);
+    }
+
+    if (glVer >= GR_GL_VER(3,0)) {
         GET_PROC(ReadBuffer);
     }
 
diff --git a/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp b/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp
index b39d9d9..a808937 100644
--- a/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp
+++ b/src/gpu/gl/GrGLAssembleGLInterfaceAutogen.cpp
@@ -194,6 +194,7 @@
     }
 
     GET_PROC(DrawBuffers);
+
     GET_PROC(ReadBuffer);
 
     if (glVer >= GR_GL_VER(4,0)) {
diff --git a/src/gpu/gl/GrGLAssembleWebGLInterfaceAutogen.cpp b/src/gpu/gl/GrGLAssembleWebGLInterfaceAutogen.cpp
index 1516368..1a32bf6 100644
--- a/src/gpu/gl/GrGLAssembleWebGLInterfaceAutogen.cpp
+++ b/src/gpu/gl/GrGLAssembleWebGLInterfaceAutogen.cpp
@@ -169,6 +169,9 @@
 
     if (glVer >= GR_GL_VER(2,0)) {
         GET_PROC(DrawBuffers);
+    }
+
+    if (glVer >= GR_GL_VER(2,0)) {
         GET_PROC(ReadBuffer);
     }
 
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index c22daa1..460365c 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -323,6 +323,15 @@
     fSupportsAHardwareBufferImages = true;
 #endif
 
+    if (GR_IS_GR_GL(standard)) {
+        fDrawBuffersSupport = true;
+    } else if (GR_IS_GR_GL_ES(standard)) {
+        fDrawBuffersSupport = (version >= GR_GL_VER(3, 0)) ||
+                              ctxInfo.hasExtension("GL_EXT_draw_buffers");
+    } else if (GR_IS_GR_WEBGL(standard)) {
+        fDrawBuffersSupport = version >= GR_GL_VER(2, 0);
+    }
+
     /**************************************************************************
     * GrShaderCaps fields
     **************************************************************************/
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index e845c32..8dd09a6 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -419,6 +419,8 @@
 
     bool fbFetchRequiresEnablePerSample() const { return fFBFetchRequiresEnablePerSample; }
 
+    bool drawBuffersSupport() const { return fDrawBuffersSupport; }
+
     GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&,
                                               SkColorType) const override;
 
@@ -507,6 +509,7 @@
     bool fProgramBinarySupport : 1;
     bool fSamplerObjectSupport : 1;
     bool fFBFetchRequiresEnablePerSample : 1;
+    bool fDrawBuffersSupport : 1;
 
     // Driver workarounds
     bool fDoManualMipmapping : 1;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 0a044b6..fe05fd3 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3124,13 +3124,22 @@
 void GrGLGpu::flushColorWrite(bool writeColor) {
     if (!writeColor) {
         if (kNo_TriState != fHWWriteToColor) {
-            GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
-                              GR_GL_FALSE, GR_GL_FALSE));
+            if (this->glCaps().drawBuffersSupport()) {
+                const GrGLenum drawBuffer = GR_GL_NONE;
+                GL_CALL(DrawBuffers(1, &drawBuffer));
+            } else {
+                GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE, GR_GL_FALSE, GR_GL_FALSE));
+            }
             fHWWriteToColor = kNo_TriState;
         }
     } else {
         if (kYes_TriState != fHWWriteToColor) {
-            GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
+            if (this->glCaps().drawBuffersSupport()) {
+                const GrGLenum drawBuffer = GR_GL_COLOR_ATTACHMENT0;
+                GL_CALL(DrawBuffers(1, &drawBuffer));
+            } else {
+                GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
+            }
             fHWWriteToColor = kYes_TriState;
         }
     }
diff --git a/src/gpu/gl/GrGLInterfaceAutogen.cpp b/src/gpu/gl/GrGLInterfaceAutogen.cpp
index c2c8a5e..a404ee6 100644
--- a/src/gpu/gl/GrGLInterfaceAutogen.cpp
+++ b/src/gpu/gl/GrGLInterfaceAutogen.cpp
@@ -220,11 +220,21 @@
 
     if (GR_IS_GR_GL(fStandard) ||
        (GR_IS_GR_GL_ES(fStandard) && (
+          (glVer >= GR_GL_VER(3,0)) ||
+          fExtensions.has("GL_EXT_draw_buffers"))) ||
+       (GR_IS_GR_WEBGL(fStandard) && (
+          (glVer >= GR_GL_VER(2,0))))) {
+        if (!fFunctions.fDrawBuffers) {
+            RETURN_FALSE_INTERFACE;
+        }
+    }
+
+    if (GR_IS_GR_GL(fStandard) ||
+       (GR_IS_GR_GL_ES(fStandard) && (
           (glVer >= GR_GL_VER(3,0)))) ||
        (GR_IS_GR_WEBGL(fStandard) && (
           (glVer >= GR_GL_VER(2,0))))) {
-        if (!fFunctions.fDrawBuffers ||
-            !fFunctions.fReadBuffer) {
+        if (!fFunctions.fReadBuffer) {
             RETURN_FALSE_INTERFACE;
         }
     }