Make mixed samples contingent on auxiliary extensions

Moves the cap for mixed samples into GrShaderCaps and does not enable
it unless we have support for both dual source blending and
multisample disable.

Creates a dedicated cap for multisample disable.

Reconfigures the mixed samples cap to indicate the collective
capability of three different extensions:

  GL_NV_framebuffer_mixed_samples
  GL_NV_sample_mask_override_coverage
  GL_EXT_raster_multisample

Imports tokens and procedures for GL_EXT_raster_multisample.

BUG=skia:

Review URL: https://codereview.chromium.org/1151793002
diff --git a/include/gpu/gl/GrGLFunctions.h b/include/gpu/gl/GrGLFunctions.h
index 5c2cf7b..cbab026 100644
--- a/include/gpu/gl/GrGLFunctions.h
+++ b/include/gpu/gl/GrGLFunctions.h
@@ -164,6 +164,7 @@
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPopGroupMarkerProc)();
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPushGroupMarkerProc)(GrGLsizei length, const char* marker);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLQueryCounterProc)(GrGLuint id, GrGLenum target);
+    typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLRasterSamplesProc)(GrGLuint samples, GrGLboolean fixedsamplelocations);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLReadBufferProc)(GrGLenum src);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLReadPixelsProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels);
     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLRenderbufferStorageProc)(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height);
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index 2e9ef6f..27f1ecc 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -246,6 +246,7 @@
         GLPtr<GrGLPopGroupMarkerProc> fPopGroupMarker;
         GLPtr<GrGLPushGroupMarkerProc> fPushGroupMarker;
         GLPtr<GrGLQueryCounterProc> fQueryCounter;
+        GLPtr<GrGLRasterSamplesProc> fRasterSamples;
         GLPtr<GrGLReadBufferProc> fReadBuffer;
         GLPtr<GrGLReadPixelsProc> fReadPixels;
         GLPtr<GrGLRenderbufferStorageProc> fRenderbufferStorage;
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 847e497..35a19e4 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -538,6 +538,7 @@
     fPathRenderingSupport = false;
     fDstReadInShaderSupport = false;
     fDualSourceBlendingSupport = false;
+    fMixedSamplesSupport = false;
 
     fShaderPrecisionVaries = false;
 }
@@ -548,6 +549,7 @@
     fPathRenderingSupport = other.fPathRenderingSupport;
     fDstReadInShaderSupport = other.fDstReadInShaderSupport;
     fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
+    fMixedSamplesSupport = other.fMixedSamplesSupport;
 
     fShaderPrecisionVaries = other.fShaderPrecisionVaries;
     for (int s = 0; s < kGrShaderTypeCount; ++s) {
@@ -590,6 +592,7 @@
     r.appendf("Path Rendering Support             : %s\n", gNY[fPathRenderingSupport]);
     r.appendf("Dst Read In Shader Support         : %s\n", gNY[fDstReadInShaderSupport]);
     r.appendf("Dual Source Blending Support       : %s\n", gNY[fDualSourceBlendingSupport]);
+    r.appendf("Mixed Samples Support              : %s\n", gNY[fMixedSamplesSupport]);
 
     r.appendf("Shader Float Precisions (varies: %s):\n", gNY[fShaderPrecisionVaries]);
 
diff --git a/src/gpu/GrDrawTargetCaps.h b/src/gpu/GrDrawTargetCaps.h
index c1b7381..3381bd3 100644
--- a/src/gpu/GrDrawTargetCaps.h
+++ b/src/gpu/GrDrawTargetCaps.h
@@ -69,6 +69,7 @@
     bool pathRenderingSupport() const { return fPathRenderingSupport; }
     bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
     bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
+    bool mixedSamplesSupport() const { return fMixedSamplesSupport; }
 
     /**
     * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
@@ -94,6 +95,7 @@
     bool fPathRenderingSupport : 1;
     bool fDstReadInShaderSupport : 1;
     bool fDualSourceBlendingSupport : 1;
+    bool fMixedSamplesSupport : 1;
 
     bool fShaderPrecisionVaries;
     PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index 89b21fd..af5b336 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -158,6 +158,9 @@
         GET_PROC_SUFFIX(MatrixLoadIdentity, EXT);
     }
     GET_PROC(PixelStorei);
+    if (extensions.has("GL_EXT_raster_multisample")) {
+        GET_PROC_SUFFIX(RasterSamples, EXT);
+    }
     GET_PROC(ReadBuffer);
     GET_PROC(ReadPixels);
     GET_PROC(Scissor);
@@ -411,6 +414,11 @@
     GET_PROC(LineWidth);
     GET_PROC(LinkProgram);
     GET_PROC(PixelStorei);
+
+    if (extensions.has("GL_EXT_raster_multisample")) {
+        GET_PROC_SUFFIX(RasterSamples, EXT);
+    }
+
     GET_PROC(ReadPixels);
     GET_PROC(Scissor);
     GET_PROC(ShaderSource);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index ea6b83f..85a7260 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -44,10 +44,10 @@
     fFragCoordsConventionSupport = false;
     fVertexArrayObjectSupport = false;
     fES2CompatibilitySupport = false;
+    fMultisampleDisableSupport = false;
     fUseNonVBOVertexAndIndexDynamicData = false;
     fIsCoreProfile = false;
     fFullClearIsFree = false;
-    fFBMixedSamplesSupport = false;
 
     fReadPixelsSupportedCache.reset();
 
@@ -86,10 +86,10 @@
     fFragCoordsConventionSupport = caps.fFragCoordsConventionSupport;
     fVertexArrayObjectSupport = caps.fVertexArrayObjectSupport;
     fES2CompatibilitySupport = caps.fES2CompatibilitySupport;
+    fMultisampleDisableSupport = caps.fMultisampleDisableSupport;
     fUseNonVBOVertexAndIndexDynamicData = caps.fUseNonVBOVertexAndIndexDynamicData;
     fIsCoreProfile = caps.fIsCoreProfile;
     fFullClearIsFree = caps.fFullClearIsFree;
-    fFBMixedSamplesSupport = caps.fFBMixedSamplesSupport;
 
     *(reinterpret_cast<GrGLSLCaps*>(fShaderCaps.get())) = 
                                           *(reinterpret_cast<GrGLSLCaps*>(caps.fShaderCaps.get()));
@@ -252,6 +252,12 @@
         fES2CompatibilitySupport = true;
     }
 
+    if (kGL_GrGLStandard == standard) {
+        fMultisampleDisableSupport = true;
+    } else {
+        fMultisampleDisableSupport = false;
+    }
+
     this->initFSAASupport(ctxInfo, gli);
     this->initStencilFormats(ctxInfo);
 
@@ -336,8 +342,6 @@
     // attachment, hence this min:
     fMaxRenderTargetSize = SkTMin(fMaxTextureSize, fMaxRenderTargetSize);
 
-    fFBMixedSamplesSupport = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples");
-
     fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
 
     // Disable scratch texture reuse on Mali and Adreno devices
@@ -935,6 +939,7 @@
     r.appendf("Fragment coord conventions support: %s\n",
              (fFragCoordsConventionSupport ? "YES": "NO"));
     r.appendf("Vertex array object support: %s\n", (fVertexArrayObjectSupport ? "YES": "NO"));
+    r.appendf("Multisample disable support: %s\n", (fMultisampleDisableSupport ? "YES" : "NO"));
     r.appendf("Use non-VBO for dynamic data: %s\n",
              (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO"));
     r.appendf("Full screen clear is free: %s\n", (fFullClearIsFree ? "YES" : "NO"));
@@ -1054,6 +1059,15 @@
             ctxInfo.hasExtension("GL_OES_standard_derivatives");
     }
 
+    // We need dual source blending and the ability to disable multisample in order to support mixed
+    // samples in every corner case.
+    if (fDualSourceBlendingSupport && glCaps.multisampleDisableSupport()) {
+        // We understand "mixed samples" to mean the collective capability of 3 different extensions
+        fMixedSamplesSupport = ctxInfo.hasExtension("GL_NV_framebuffer_mixed_samples") &&
+                               ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage") &&
+                               ctxInfo.hasExtension("GL_EXT_raster_multisample");
+    }
+
     if (glCaps.advancedBlendEquationSupport()) {
         bool coherent = glCaps.advancedCoherentBlendEquationSupport();
         if (ctxInfo.hasExtension(coherent ? "GL_NV_blend_equation_advanced_coherent"
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 663cd4b..5503576 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -237,6 +237,9 @@
     /// Is there support for ES2 compatability?
     bool ES2CompatibilitySupport() const { return fES2CompatibilitySupport; }
 
+    /// Can we call glDisable(GL_MULTISAMPLE)?
+    bool multisampleDisableSupport() const { return fMultisampleDisableSupport; }
+
     /// Use indices or vertices in CPU arrays rather than VBOs for dynamic content.
     bool useNonVBOVertexAndIndexDynamicData() const {
         return fUseNonVBOVertexAndIndexDynamicData;
@@ -353,6 +356,7 @@
     bool fFragCoordsConventionSupport : 1;
     bool fVertexArrayObjectSupport : 1;
     bool fES2CompatibilitySupport : 1;
+    bool fMultisampleDisableSupport : 1;
     bool fUseNonVBOVertexAndIndexDynamicData : 1;
     bool fIsCoreProfile : 1;
     bool fFullClearIsFree : 1;
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index 4c479ed..61c5588 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -880,4 +880,12 @@
 /*  ARM specific define for MSAA support on framebuffer fetch */
 #define GR_GL_FETCH_PER_SAMPLE_ARM                          0x8F65
 
+/* GL_EXT_raster_multisample */
+#define GR_GL_RASTER_MULTISAMPLE                            0x9327
+#define GR_GL_RASTER_SAMPLES                                0x9328
+#define GR_GL_MAX_RASTER_SAMPLES                            0x9329
+#define GR_GL_RASTER_FIXED_SAMPLE_LOCATIONS                 0x932A
+#define GR_GL_MULTISAMPLE_RASTERIZATION_ALLOWED             0x932B
+#define GR_GL_EFFECTIVE_RASTER_SAMPLES                      0x932C
+
 #endif
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 6a8d83b..1b94a1e 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -2101,7 +2101,7 @@
 void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA) {
     SkASSERT(!useHWAA || rt->isMultisampled());
 
-    if (kGL_GrGLStandard == this->glStandard()) {
+    if (this->glCaps().multisampleDisableSupport()) {
         if (useHWAA) {
             if (kYes_TriState != fMSAAEnabled) {
                 GL_CALL(Enable(GR_GL_MULTISAMPLE));
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index 89f1f9b..8bbd2f3 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -528,6 +528,12 @@
         }
     }
 
+    if (fExtensions.has("GL_EXT_raster_multisample")) {
+        if (NULL == fFunctions.fRasterSamples) {
+            RETURN_FALSE_INTERFACE
+        }
+    }
+
     if (fExtensions.has("GL_NV_framebuffer_mixed_samples")) {
         if (NULL == fFunctions.fCoverageModulation) {
             RETURN_FALSE_INTERFACE