Detect chrome command buffer separately from GL driver.

When we're on top of the command buffer which in turn is on top
of ANGLE's GL backend we detect the underlying driver as GrGLDriver.
However, we still need to know if we're on the command buffer. Separate
that out from GrGLDriver.

Bug: chromium:1210334
Change-Id: I87d7d7d6d22f9629e1abe817668a33e3204300e1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410016
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 3afaa95..00ce402 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -294,14 +294,9 @@
         }
     } // no WebGL support
 
-    // Chrome's command buffer will zero out a buffer if null is passed to glBufferData to
-    // avoid letting an application see uninitialized memory.
-    if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
-        fUseBufferDataNullHint = (ctxInfo.driver() != GrGLDriver::kChromium);
-    } else if (GR_IS_GR_WEBGL(standard)) {
-        // WebGL spec explicitly disallows null values.
-        fUseBufferDataNullHint = false;
-    }
+    // Chrome's command buffer will zero out a buffer if null is passed to glBufferData to avoid
+    // letting an application see uninitialized memory. WebGL spec explicitly disallows null values.
+    fUseBufferDataNullHint = !GR_IS_GR_WEBGL(standard) && !ctxInfo.isOverCommandBuffer();
 
     if (GR_IS_GR_GL(standard)) {
         fClearTextureSupport = (version >= GR_GL_VER(4,4) ||
@@ -324,7 +319,7 @@
         fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
     }  // No WebGL support
 
-    fSkipErrorChecks = ctxInfo.driver() == GrGLDriver::kChromium;
+    fSkipErrorChecks = ctxInfo.isOverCommandBuffer();
     if (GR_IS_GR_WEBGL(standard)) {
         // Error checks are quite costly in webgl, especially in Chrome.
         fSkipErrorChecks = true;
@@ -420,7 +415,7 @@
     // The Chrome command buffer blocks the use of client side buffers (but may emulate VBOs with
     // them). Client side buffers are not allowed in core profiles.
     if (GR_IS_GR_GL(standard) || GR_IS_GR_GL_ES(standard)) {
-        if (ctxInfo.driver() != GrGLDriver::kChromium && !fIsCoreProfile &&
+        if (!ctxInfo.isOverCommandBuffer() && !fIsCoreProfile &&
             (ctxInfo.vendor() == GrGLVendor::kARM         ||
              ctxInfo.vendor() == GrGLVendor::kImagination ||
              ctxInfo.vendor() == GrGLVendor::kQualcomm)) {
@@ -521,7 +516,7 @@
         // We think mapping on Chromium will be cheaper once we know ahead of time how much space
         // we will use for all GrMeshDrawOps. Right now we might wind up mapping a large buffer and
         // using a small subset.
-        fBufferMapThreshold = ctxInfo.driver() == GrGLDriver::kChromium ? 0 : SK_MaxS32;
+        fBufferMapThreshold = ctxInfo.isOverCommandBuffer() ? 0 : SK_MaxS32;
 #else
         fBufferMapThreshold = SK_MaxS32;
 #endif
@@ -579,12 +574,12 @@
 #ifdef SK_BUILD_FOR_WIN
     // We're assuming that on Windows Chromium we're using ANGLE.
     bool isANGLE = ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown ||
-                   ctxInfo.driver()       == GrGLDriver::kChromium;
+                   ctxInfo.isOverCommandBuffer();
     // On ANGLE deferring flushes can lead to GPU starvation
     fPreferVRAMUseOverFlushes = !isANGLE;
 #endif
 
-    if (ctxInfo.driver() == GrGLDriver::kChromium) {
+    if (ctxInfo.isOverCommandBuffer()) {
         fMustClearUploadedBufferData = true;
     }
 
@@ -3553,8 +3548,7 @@
 #ifndef SK_BUILD_FOR_IOS
     if (ctxInfo.renderer() == GrGLRenderer::kPowerVR54x   ||
         ctxInfo.renderer() == GrGLRenderer::kPowerVRRogue ||
-        (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx &&
-         ctxInfo.driver()   != GrGLDriver::kChromium)) {
+        (ctxInfo.renderer() == GrGLRenderer::kAdreno3xx && !ctxInfo.isOverCommandBuffer())) {
         fPerformColorClearsAsDraws = true;
     }
 #endif
@@ -3805,8 +3799,7 @@
     // we've explicitly guarded the division with a check against zero. This manifests in much
     // more complex ways in some of our shaders, so we use this caps bit to add an epsilon value
     // to the denominator of divisions, even when we've added checks that the denominator isn't 0.
-    if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown ||
-        ctxInfo.driver()       == GrGLDriver::kChromium) {
+    if (ctxInfo.angleBackend() != GrGLANGLEBackend::kUnknown || ctxInfo.isOverCommandBuffer()) {
         shaderCaps->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
     }
 #endif
@@ -3866,13 +3859,13 @@
     }
 
     // Disabling advanced blend on various platforms with major known issues. We also block Chrome
-    // for now until its own denylists can be updated.
+    // command buffer for now until its own denylists can be updated.
     if (ctxInfo.renderer() == GrGLRenderer::kAdreno430       ||
         ctxInfo.renderer() == GrGLRenderer::kAdreno4xx_other ||
         ctxInfo.renderer() == GrGLRenderer::kAdreno530       ||
         ctxInfo.renderer() == GrGLRenderer::kAdreno5xx_other ||
         ctxInfo.driver()   == GrGLDriver::kIntel             ||
-        ctxInfo.driver()   == GrGLDriver::kChromium          ||
+        ctxInfo.isOverCommandBuffer()                        ||
         ctxInfo.vendor()   == GrGLVendor::kARM /* http://skbug.com/11906 */) {
         fBlendEquationSupport = kBasic_BlendEquationSupport;
         shaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kNotSupported_AdvBlendEqInteraction;
@@ -4003,7 +3996,7 @@
     // Command buffer fails glTexSubImage2D with type == GL_HALF_FLOAT_OES if a GL_RGBA16F texture
     // is created with glTexStorage2D. See crbug.com/1008003.
     formatWorkarounds->fDisableRGBA16FTexStorageForCrBug1008003 =
-            ctxInfo.driver() == GrGLDriver::kChromium && ctxInfo.version() < GR_GL_VER(3, 0);
+            ctxInfo.isOverCommandBuffer() && ctxInfo.version() < GR_GL_VER(3, 0);
 
 #if defined(SK_BUILD_FOR_WIN)
     // On Intel Windows ES contexts it seems that using texture storage with BGRA causes
diff --git a/src/gpu/gl/GrGLContext.h b/src/gpu/gl/GrGLContext.h
index 798fe1a..93bd57c 100644
--- a/src/gpu/gl/GrGLContext.h
+++ b/src/gpu/gl/GrGLContext.h
@@ -40,8 +40,11 @@
         (e.g. Intel GPU being driven by Mesa) */
     GrGLDriver driver() const { return fDriverInfo.fDriver; }
     GrGLDriverVersion driverVersion() const { return fDriverInfo.fDriverVersion; }
+    bool isOverCommandBuffer() const { return fDriverInfo.fIsOverCommandBuffer; }
+
     const GrGLCaps* caps() const { return fGLCaps.get(); }
     GrGLCaps* caps() { return fGLCaps.get(); }
+
     bool hasExtension(const char* ext) const {
         return fInterface->hasExtension(ext);
     }
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 4bedee4..6a2fdbf 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -352,10 +352,22 @@
     return GrGLRenderer::kOther;
 }
 
-std::tuple<GrGLDriver, GrGLDriverVersion> get_driver_and_version(GrGLStandard standard,
-                                                                 GrGLVendor vendor,
-                                                                 const char* rendererString,
-                                                                 const char* versionString) {
+static bool is_commamd_buffer(const char* rendererString, const char* versionString) {
+    SkASSERT(rendererString);
+    SkASSERT(versionString);
+
+    int major, minor;
+    static const char kChromium[] = "Chromium";
+    char suffix[SK_ARRAY_COUNT(kChromium)] = {0};
+    return (0 == strcmp(rendererString, kChromium) ||
+           (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
+            0 == strcmp(kChromium, suffix)));
+}
+
+static std::tuple<GrGLDriver, GrGLDriverVersion> get_driver_and_version(GrGLStandard standard,
+                                                                        GrGLVendor vendor,
+                                                                        const char* rendererString,
+                                                                        const char* versionString) {
     SkASSERT(rendererString);
     SkASSERT(versionString);
 
@@ -363,13 +375,7 @@
     GrGLDriverVersion driverVersion = GR_GL_DRIVER_UNKNOWN_VER;
 
     int major, minor, rev, driverMajor, driverMinor, driverPoint;
-    static const char kChromium[] = "Chromium";
-    char suffix[SK_ARRAY_COUNT(kChromium)] = {0};
-    if (0 == strcmp(rendererString, kChromium) ||
-        (3 == sscanf(versionString, "OpenGL ES %d.%d %8s", &major, &minor, suffix) &&
-         0 == strcmp(kChromium, suffix))) {
-        driver = GrGLDriver::kChromium;
-    } else if (GR_IS_GR_GL(standard)) {
+    if (GR_IS_GR_GL(standard)) {
         if (vendor == GrGLVendor::kNVIDIA) {
             driver = GrGLDriver::kNVIDIA;
             int n = sscanf(versionString,
@@ -403,7 +409,7 @@
                 driverVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor, 0);
             }
         }
-    } else if (standard) {
+    } else if (standard == kGLES_GrGLStandard) {
         if (vendor == GrGLVendor::kNVIDIA) {
             driver = GrGLDriver::kNVIDIA;
             int n = sscanf(versionString,
@@ -523,7 +529,7 @@
     return {GrGLANGLEBackend::kUnknown, {}};
 }
 
-std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
+static std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
 get_angle_gl_vendor_and_renderer(
         const char* innerString,
         const GrGLExtensions& extensions) {
@@ -553,7 +559,7 @@
     return {angleVendor, angleRenderer, angleDriver, angleDriverVersion};
 }
 
-std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
+static std::tuple<GrGLVendor, GrGLRenderer, GrGLDriver, GrGLDriverVersion>
 get_angle_d3d_vendor_and_renderer(const char* innerString) {
     auto vendor   = GrGLVendor::kOther;
     auto renderer = GrGLRenderer::kOther;
@@ -654,6 +660,8 @@
                                                  interface->fExtensions);
     }
 
+    info.fIsOverCommandBuffer = is_commamd_buffer(renderer, version);
+
     return info;
 }
 
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 8777794..5f7b2f4 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -147,7 +147,6 @@
 
 enum class GrGLDriver {
     kMesa,
-    kChromium,
     kNVIDIA,
     kIntel,
     kSwiftShader,
@@ -233,6 +232,9 @@
     GrGLRenderer      fANGLERenderer      = GrGLRenderer::kOther;
     GrGLDriver        fANGLEDriver        = GrGLDriver::kUnknown;
     GrGLDriverVersion fANGLEDriverVersion = GR_GL_DRIVER_UNKNOWN_VER;
+
+    // Are we running over the Chrome interprocess command buffer?
+    bool fIsOverCommandBuffer = false;
 };
 
 GrGLDriverInfo GrGLGetDriverInfo(const GrGLInterface*);