Updated workaround for Intel 6xxx clear to 0/1 bug

The previous workaround only handled the glClearColor(0,0,0,1) case,
it turns out we need to work around any glClearColor made up of entirely
0s and 1s.

R=bsalomon@google.com
Bug: 710443
Change-Id: I78a75559fc11811ad9a218436231354d66d2ad51
Reviewed-on: https://skia-review.googlesource.com/17327
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Eric Karl <ericrk@chromium.org>

Workaround for Intel 6xxx clear to opaque black bug
NOTREECHECKS=true
NOTRY=true
NOPRESUBMIT=true
Bug: skia:
Change-Id: Id5e29b483c2b6f698219abfc5bbb2d858c4fc117
Reviewed-On: https://skia-review.googlesource.com/16427
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-By: Brian Osman <brianosman@google.com>
Reviewed-on: https://skia-review.googlesource.com/17790
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 41c3706..61f07d1 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -53,6 +53,7 @@
     fDoManualMipmapping = false;
     fSRGBDecodeDisableSupport = false;
     fSRGBDecodeDisableAffectsMipmaps = false;
+    fClearToBoundaryValuesIsBroken = false;
 
     fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
 
@@ -574,6 +575,13 @@
     fSRGBDecodeDisableAffectsMipmaps = fSRGBDecodeDisableSupport &&
         kChromium_GrGLDriver != ctxInfo.driver();
 
+    // See http://crbug.com/710443
+#ifdef SK_BUILD_FOR_MAC
+    if (kIntel6xxx_GrGLRenderer == ctxInfo.renderer()) {
+        fClearToBoundaryValuesIsBroken = true;
+    }
+#endif
+
     // Requires fTextureRedSupport, fTextureSwizzleSupport, msaa support, ES compatibility have
     // already been detected.
     this->initConfigTable(contextOptions, ctxInfo, gli, shaderCaps);
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index c32e419..98d5276 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -359,6 +359,9 @@
         return fRGBAToBGRAReadbackConversionsAreSlow;
     }
 
+    // Certain Intel GPUs on Mac fail to clear if the glClearColor is made up of only 1s and 0s.
+    bool clearToBoundaryValuesIsBroken() const { return fClearToBoundaryValuesIsBroken; }
+
     bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                             bool* rectsMustMatch, bool* disallowSubrect) const override;
 
@@ -430,6 +433,7 @@
     bool fDoManualMipmapping : 1;
     bool fSRGBDecodeDisableSupport : 1;
     bool fSRGBDecodeDisableAffectsMipmaps : 1;
+    bool fClearToBoundaryValuesIsBroken : 1;
 
     uint32_t fBlitFramebufferFlags;
 
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 714ded0..b9c1a05 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -7,6 +7,7 @@
 
 #include "GrGLGpu.h"
 
+#include <cmath>
 #include "../private/GrGLSL.h"
 #include "GrFixedClip.h"
 #include "GrGLBuffer.h"
@@ -2094,6 +2095,19 @@
 
     GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
     fHWWriteToColor = kYes_TriState;
+
+    if (this->glCaps().clearToBoundaryValuesIsBroken() &&
+        (1 == r || 0 == r) && (1 == g || 0 == g) && (1 == b || 0 == b) && (1 == a || 0 == a)) {
+#ifdef SK_BUILD_FOR_ANDROID
+        // Android doesn't have std::nextafter but has nextafter.
+        static const GrGLfloat safeAlpha1 = nextafter(1.f, 2.f);
+        static const GrGLfloat safeAlpha0 = nextafter(0.f, -1.f);
+#else
+        static const GrGLfloat safeAlpha1 = std::nextafter(1.f, 2.f);
+        static const GrGLfloat safeAlpha0 = std::nextafter(0.f, -1.f);
+#endif
+        a = (1 == a) ? safeAlpha1 : safeAlpha0;
+    }
     GL_CALL(ClearColor(r, g, b, a));
     GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
 }
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 443d77c..58b5860 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -313,6 +313,16 @@
                 }
             }
         }
+        int intelNumber;
+        n = sscanf(rendererString, "Intel(R) Iris(TM) Graphics %d", &intelNumber);
+        if (1 != n) {
+            n = sscanf(rendererString, "Intel(R) HD Graphics %d", &intelNumber);
+        }
+        if (1 == n) {
+            if (intelNumber >= 6000 && intelNumber < 7000) {
+                return kIntel6xxx_GrGLRenderer;
+            }
+        }
         if (0 == strcmp("Mesa Offscreen", rendererString)) {
             return kOSMesa_GrGLRenderer;
         }
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 7503371..25bd681 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -54,6 +54,8 @@
     kAdreno4xx_GrGLRenderer,
     kAdreno5xx_GrGLRenderer,
     kOSMesa_GrGLRenderer,
+    /** Either HD 6xxx or Iris 6xxx */
+    kIntel6xxx_GrGLRenderer,
     kOther_GrGLRenderer
 };