Add MESA detection to GrContextInfo and use to decide whether to use GL_ALPHA or GL_RED.

Based on yunchao.he@intel.com's original change here: https://codereview.chromium.org/15994006/

R=yunchao.he@intel.com, robertphillips@google.com

Author: bsalomon@google.com

Review URL: https://chromiumcodereview.appspot.com/16955005

git-svn-id: http://skia.googlecode.com/svn/trunk@9608 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index fd74d50..1770d05 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -164,10 +164,15 @@
                          ctxInfo.hasExtension("GL_ARB_texture_storage") ||
                          ctxInfo.hasExtension("GL_EXT_texture_storage");
 
-    // ARB_texture_rg is part of OpenGL 3.0
+    // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support it if
+    // it doesn't have ARB_texture_rg extension.
     if (kDesktop_GrGLBinding == binding) {
-        fTextureRedSupport = version >= GR_GL_VER(3,0) ||
-                             ctxInfo.hasExtension("GL_ARB_texture_rg");
+        if (ctxInfo.isMesa()) {
+            fTextureRedSupport = ctxInfo.hasExtension("GL_ARB_texture_rg");
+        } else {
+            fTextureRedSupport = version >= GR_GL_VER(3,0) ||
+                                 ctxInfo.hasExtension("GL_ARB_texture_rg");
+        }
     } else {
         fTextureRedSupport = ctxInfo.hasExtension("GL_EXT_texture_rg");
     }
diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp
index d384b4e..1d0a01f 100644
--- a/src/gpu/gl/GrGLContext.cpp
+++ b/src/gpu/gl/GrGLContext.cpp
@@ -14,6 +14,7 @@
     fGLSLGeneration = ctxInfo.fGLSLGeneration;
     fVendor = ctxInfo.fVendor;
     fExtensions = ctxInfo.fExtensions;
+    fIsMesa = ctxInfo.fIsMesa;
     *fGLCaps = *ctxInfo.fGLCaps.get();
     return *this;
 }
@@ -36,6 +37,9 @@
             fGLSLGeneration = GrGetGLSLGeneration(fBindingInUse, interface);
 
             fVendor = GrGLGetVendor(interface);
+
+            fIsMesa = GrGLIsMesaFromVersionString(ver);
+
             fGLCaps->init(*this, interface);
             return true;
         }
@@ -52,6 +56,7 @@
     fGLVersion = GR_GL_VER(0, 0);
     fGLSLGeneration = static_cast<GrGLSLGeneration>(0);
     fVendor = kOther_GrGLVendor;
+    fIsMesa = false;
     fExtensions.reset();
     fGLCaps->reset();
 }
diff --git a/src/gpu/gl/GrGLContext.h b/src/gpu/gl/GrGLContext.h
index 172cd8b..34f2190 100644
--- a/src/gpu/gl/GrGLContext.h
+++ b/src/gpu/gl/GrGLContext.h
@@ -47,6 +47,8 @@
     GrGLVersion version() const { return fGLVersion; }
     GrGLSLGeneration glslGeneration() const { return fGLSLGeneration; }
     GrGLVendor vendor() const { return fVendor; }
+    /** Is this a mesa-based driver. Does not mean it is the osmesa software rasterizer. */
+    bool isMesa() const { return fIsMesa; }
     const GrGLCaps* caps() const { return fGLCaps.get(); }
     GrGLCaps* caps() { return fGLCaps; }
     const GrGLExtensions& extensions() const { return fExtensions; }
@@ -73,6 +75,7 @@
     GrGLSLGeneration        fGLSLGeneration;
     GrGLVendor              fVendor;
     GrGLExtensions          fExtensions;
+    bool                    fIsMesa;
     SkAutoTUnref<GrGLCaps>  fGLCaps;
 };
 
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 08bbebc..a13b03d 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -121,6 +121,12 @@
     return kNone_GrGLBinding;
 }
 
+bool GrGLIsMesaFromVersionString(const char* versionString) {
+    int major, minor, mesaMajor, mesaMinor;
+    int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
+    return 4 == n;
+}
+
 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
     if (NULL == versionString) {
         GrAssert(!"NULL GL version string.");
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index ea84480..b8a96e5 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -71,6 +71,7 @@
 GrGLVersion GrGLGetVersionFromString(const char* versionString);
 GrGLBinding GrGLGetBindingInUseFromString(const char* versionString);
 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString);
+bool GrGLIsMesaFromVersionString(const char* versionString);
 GrGLVendor GrGLGetVendorFromString(const char* vendorString);
 
 // these variants call glGetString()