Begin tracking driver info in GrGLContextInfo

BUG=skia:

Review URL: https://codereview.chromium.org/1165463005
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 9489e21..dd4ba65 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -135,7 +135,7 @@
 
     // ARB_texture_rg is part of OpenGL 3.0, but mesa doesn't support GL_RED 
     // and GL_RG on FBO textures.
-    if (!ctxInfo.isMesa()) {
+    if (kMesa_GrGLDriver != ctxInfo.driver()) {
         if (kGL_GrGLStandard == standard) {
             fTextureRedSupport = version >= GR_GL_VER(3,0) ||
                                  ctxInfo.hasExtension("GL_ARB_texture_rg");
@@ -274,7 +274,7 @@
     // On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
     // threshold to the maximum unless the client gives us a hint that map memory is cheap.
     if (fGeometryBufferMapThreshold < 0) {
-        fGeometryBufferMapThreshold = ctxInfo.isChromium() ? 0 : SK_MaxS32;
+        fGeometryBufferMapThreshold = kChromium_GrGLDriver == ctxInfo.driver() ? 0 : SK_MaxS32;
     }
 
     if (kGL_GrGLStandard == standard) {
diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp
index 3359865..6f23eca 100644
--- a/src/gpu/gl/GrGLContext.cpp
+++ b/src/gpu/gl/GrGLContext.cpp
@@ -52,9 +52,8 @@
 
     args.fRenderer = GrGLGetRendererFromString(renderer);
 
-    args.fIsMesa = GrGLIsMesaFromVersionString(ver);
-
-    args.fIsChromium = GrGLIsChromiumFromRendererString(renderer);
+    GrGLGetDriverInfo(interface->fStandard, args.fVendor, renderer, ver,
+                      &args.fDriver, &args.fDriverVersion);
 
     args.fContextOptions = &options;
 
@@ -67,8 +66,8 @@
     fGLSLGeneration = args.fGLSLGeneration;
     fVendor = args.fVendor;
     fRenderer = args.fRenderer;
-    fIsMesa = args.fIsMesa;
-    fIsChromium = args.fIsChromium;
+    fDriver = args.fDriver;
+    fDriverVersion = args.fDriverVersion;
 
     fGLCaps.reset(SkNEW_ARGS(GrGLCaps, (*args.fContextOptions, *this, fInterface)));
 }
diff --git a/src/gpu/gl/GrGLContext.h b/src/gpu/gl/GrGLContext.h
index 50262cf..8a42894 100644
--- a/src/gpu/gl/GrGLContext.h
+++ b/src/gpu/gl/GrGLContext.h
@@ -28,12 +28,10 @@
     GrGLSLGeneration glslGeneration() const { return fGLSLGeneration; }
     GrGLVendor vendor() const { return fVendor; }
     GrGLRenderer renderer() const { return fRenderer; }
-    /** Is this a mesa-based driver. Does not mean it is the osmesa software rasterizer. */
-    bool isMesa() const { return fIsMesa; }
-    /** Are we running inside Chromium (using the command buffer)? We make some different tradeoffs
-        about what errors to check for because queries are synchronous. We should probably expose
-        this as an option for clients other than Chromium. */
-    bool isChromium() const { return fIsChromium; }
+    /** What driver is running our GL implementation? This is not necessarily related to the vendor.
+        (e.g. Intel GPU being driven by Mesa) */
+    GrGLDriver driver() const { return fDriver; }
+    GrGLDriverVersion driverVersion() const { return fDriverVersion; }
     const GrGLCaps* caps() const { return fGLCaps.get(); }
     GrGLCaps* caps() { return fGLCaps; }
     bool hasExtension(const char* ext) const {
@@ -49,8 +47,8 @@
         GrGLSLGeneration                    fGLSLGeneration;
         GrGLVendor                          fVendor;
         GrGLRenderer                        fRenderer;
-        bool                                fIsMesa;
-        bool                                fIsChromium;
+        GrGLDriver                          fDriver;
+        GrGLDriverVersion                   fDriverVersion;
         const  GrContextOptions*            fContextOptions;
     };
 
@@ -61,8 +59,8 @@
     GrGLSLGeneration                    fGLSLGeneration;
     GrGLVendor                          fVendor;
     GrGLRenderer                        fRenderer;
-    bool                                fIsMesa;
-    bool                                fIsChromium;
+    GrGLDriver                          fDriver;
+    GrGLDriverVersion                   fDriverVersion;
     SkAutoTUnref<GrGLCaps>              fGLCaps;
 };
 
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 6bcca81..7696334 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -270,7 +270,7 @@
                                                  GrPixelConfig surfaceConfig) const {
     if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig) {
         return kBGRA_8888_GrPixelConfig;
-    } else if (this->glContext().isMesa() &&
+    } else if (kMesa_GrGLDriver == this->glContext().driver() &&
                GrBytesPerPixel(readConfig) == 4 &&
                GrPixelConfigSwapRAndB(readConfig) == surfaceConfig) {
         // Mesa 3D takes a slow path on when reading back  BGRA from an RGBA surface and vice-versa.
@@ -1865,7 +1865,7 @@
         // lots of repeated command buffer flushes when the compositor is
         // rendering with Ganesh, which is really slow; even too slow for
         // Debug mode.
-        if (!this->glContext().isChromium()) {
+        if (kChromium_GrGLDriver != this->glContext().driver()) {
             GrGLenum status;
             GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER));
             if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 0a17c19..5db541c 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -92,24 +92,62 @@
     return kNone_GrGLStandard;
 }
 
-bool GrGLIsMesaFromVersionString(const char* versionString) {
-    int major, minor, mesaMajor, mesaMinor;
+void GrGLGetDriverInfo(GrGLStandard standard,
+                       GrGLVendor vendor,
+                       const char* rendererString,
+                       const char* versionString,
+                       GrGLDriver* outDriver,
+                       GrGLDriverVersion* outVersion) {
+    int major, minor, rev, driverMajor, driverMinor;
 
-    GrGLStandard standard = GrGLGetStandardInUseFromString(versionString);
+    *outDriver = kUnknown_GrGLDriver;
+    *outVersion = GR_GL_DRIVER_UNKNOWN_VER;
+
+    if (0 == strcmp(rendererString, "Chromium")) {
+        *outDriver = kChromium_GrGLDriver;
+        return;
+    }
 
     if (standard == kGL_GrGLStandard) {
-        int n = sscanf(versionString, "%d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
-        return 4 == n;
+        if (kNVIDIA_GrGLVendor == vendor) {
+            *outDriver = kNVIDIA_GrGLDriver;
+            int n = sscanf(versionString, "%d.%d.%d NVIDIA %d.%d",
+                           &major, &minor, &rev, &driverMajor, &driverMinor);
+            // Some older NVIDIA drivers don't report the driver version.
+            if (5 == n) {
+                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
+            }
+            return;
+        }
+
+        int n = sscanf(versionString, "%d.%d Mesa %d.%d",
+                       &major, &minor, &driverMajor, &driverMinor);
+        if (4 == n) {
+            *outDriver = kMesa_GrGLDriver;
+            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
+            return;
+        }
     }
     else {
-        int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d", &major, &minor, &mesaMajor, &mesaMinor);
-        return 4 == n;
-    }
-    return false;
-}
+        if (kNVIDIA_GrGLVendor == vendor) {
+            *outDriver = kNVIDIA_GrGLDriver;
+            int n = sscanf(versionString, "OpenGL ES %d.%d NVIDIA %d.%d",
+                           &major, &minor, &driverMajor, &driverMinor);
+            // Some older NVIDIA drivers don't report the driver version.
+            if (4 == n) {
+                *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
+            }
+            return;
+        }
 
-bool GrGLIsChromiumFromRendererString(const char* rendererString) {
-    return 0 == strcmp(rendererString, "Chromium");
+        int n = sscanf(versionString, "OpenGL ES %d.%d Mesa %d.%d",
+                       &major, &minor, &driverMajor, &driverMinor);
+        if (4 == n) {
+            *outDriver = kMesa_GrGLDriver;
+            *outVersion = GR_GL_DRIVER_VER(driverMajor, driverMinor);
+            return;
+        }
+    }
 }
 
 GrGLVersion GrGLGetVersionFromString(const char* versionString) {
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 3646de5..3a7f450 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -18,14 +18,18 @@
 
 typedef uint32_t GrGLVersion;
 typedef uint32_t GrGLSLVersion;
+typedef uint32_t GrGLDriverVersion;
 
 #define GR_GL_VER(major, minor) ((static_cast<int>(major) << 16) | \
                                  static_cast<int>(minor))
 #define GR_GLSL_VER(major, minor) ((static_cast<int>(major) << 16) | \
                                    static_cast<int>(minor))
+#define GR_GL_DRIVER_VER(major, minor) ((static_cast<int>(major) << 16) | \
+                                        static_cast<int>(minor))
 
 #define GR_GL_INVALID_VER GR_GL_VER(0, 0)
-#define GR_GLSL_INVALID_VER GR_GL_VER(0, 0)
+#define GR_GLSL_INVALID_VER GR_GLSL_VER(0, 0)
+#define GR_GL_DRIVER_UNKNOWN_VER GR_GL_DRIVER_VER(0, 0)
 
 /**
  * The Vendor and Renderer enum values are lazily updated as required.
@@ -50,6 +54,13 @@
     kOther_GrGLRenderer
 };
 
+enum GrGLDriver {
+    kMesa_GrGLDriver,
+    kChromium_GrGLDriver,
+    kNVIDIA_GrGLDriver,
+    kUnknown_GrGLDriver
+};
+
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -98,10 +109,15 @@
 GrGLVersion GrGLGetVersionFromString(const char* versionString);
 GrGLStandard GrGLGetStandardInUseFromString(const char* versionString);
 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString);
-bool GrGLIsMesaFromVersionString(const char* versionString);
 GrGLVendor GrGLGetVendorFromString(const char* vendorString);
 GrGLRenderer GrGLGetRendererFromString(const char* rendererString);
-bool GrGLIsChromiumFromRendererString(const char* rendererString);
+
+void GrGLGetDriverInfo(GrGLStandard standard,
+                       GrGLVendor vendor,
+                       const char* rendererString,
+                       const char* versionString,
+                       GrGLDriver* outDriver,
+                       GrGLDriverVersion* outVersion);
 
 // these variants call glGetString()
 GrGLVersion GrGLGetVersion(const GrGLInterface*);
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 1478279..1e6251b 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -429,7 +429,7 @@
     GL_CALL(LinkProgram(programID));
 
     // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
-    bool checkLinked = !fGpu->ctxInfo().isChromium();
+    bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver();
 #ifdef SK_DEBUG
     checkLinked = true;
 #endif
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
index b123c03..52915b6 100644
--- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
@@ -54,7 +54,7 @@
     GR_GL_CALL(gli, CompileShader(shaderId));
 
     // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
-    bool checkCompiled = !glCtx.isChromium();
+    bool checkCompiled = kChromium_GrGLDriver != glCtx.driver();
 #ifdef SK_DEBUG
     checkCompiled = true;
 #endif