Don't use gl_FragCoord on legacy Tegra hardware

Bug: skia:7413
Bug: skia:7757
Change-Id: I588c49409fd630f4c15546d8be64fb46c87db3c3
Reviewed-on: https://skia-review.googlesource.com/117007
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 9af54b1..e22133c 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2271,7 +2271,7 @@
     }
 
     // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
-    if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
+    if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
         fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true;
         fUseDrawInsteadOfAllRenderTargetWrites = true;
     }
@@ -2342,7 +2342,7 @@
         shaderCaps->fFragCoordConventionsExtensionString = nullptr;
     }
 
-    if (kTegra3_GrGLRenderer == ctxInfo.renderer()) {
+    if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
         // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0),
         // so we must do the abs first in a separate expression.
         shaderCaps->fCanUseMinAndAbsTogether = false;
@@ -2407,6 +2407,11 @@
         shaderCaps->fInterpolantsAreInaccurate = true;
     }
 
+    // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware.
+    if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) {
+        shaderCaps->fCanUseFragCoord = false;
+    }
+
     // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048.
     // (Are they implemented with fp16?)
     if (kARM_GrGLVendor == ctxInfo.vendor()) {
diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp
index dd774cd..2ae4710 100644
--- a/src/gpu/gl/GrGLContext.cpp
+++ b/src/gpu/gl/GrGLContext.cpp
@@ -25,6 +25,10 @@
     GR_GL_CALL_RET(interface.get(), rendererUByte, GetString(GR_GL_RENDERER));
     const char* renderer = reinterpret_cast<const char*>(rendererUByte);
 
+    const GrGLubyte* extensionsUByte;
+    GR_GL_CALL_RET(interface.get(), extensionsUByte, GetString(GR_GL_EXTENSIONS));
+    const char* extensions = reinterpret_cast<const char*>(extensionsUByte);
+
     ConstructorArgs args;
     args.fGLVersion = GrGLGetVersionFromString(ver);
     if (GR_GL_INVALID_VER == args.fGLVersion) {
@@ -37,7 +41,7 @@
 
     args.fVendor = GrGLGetVendor(interface.get());
 
-    args.fRenderer = GrGLGetRendererFromString(renderer);
+    args.fRenderer = GrGLGetRendererFromStrings(renderer, extensions);
 
     GrGLGetANGLEInfoFromString(renderer, &args.fANGLEBackend, &args.fANGLEVendor,
                                &args.fANGLERenderer);
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 3de894d..985bd4e 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -284,12 +284,15 @@
     return 0 == strncmp(rendererString, kHeader, kHeaderLength);
 }
 
-GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
+GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString, const char* extensionString) {
     if (rendererString) {
-        if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) {
-            return kTegra3_GrGLRenderer;
-        } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
-            return kTegra2_GrGLRenderer;
+        static const char kTegraStr[] = "NVIDIA Tegra";
+        if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) {
+            // Tegra strings are not very descriptive. We distinguish between the modern and legacy
+            // architectures by the presence of NV_path_rendering.
+            return (extensionString && strstr(extensionString, "GL_NV_path_rendering"))
+                           ? kTegra_GrGLRenderer
+                           : kTegra_PreK1_GrGLRenderer;
         }
         int lastDigit;
         int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit);
@@ -462,9 +465,13 @@
 }
 
 GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) {
-    const GrGLubyte* v;
-    GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER));
-    return GrGLGetRendererFromString((const char*) v);
+    const GrGLubyte* rendererString;
+    GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER));
+
+    const GrGLubyte* extensionString;
+    GR_GL_CALL_RET(gl, extensionString, GetString(GR_GL_EXTENSIONS));
+
+    return GrGLGetRendererFromStrings((const char*) rendererString, (const char*) extensionString);
 }
 
 GrGLenum GrToGLStencilFunc(GrStencilTest test) {
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 8062a0d..8b98854 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -47,8 +47,8 @@
 };
 
 enum GrGLRenderer {
-    kTegra2_GrGLRenderer,
-    kTegra3_GrGLRenderer,
+    kTegra_PreK1_GrGLRenderer,  // Legacy Tegra architecture (pre-K1).
+    kTegra_GrGLRenderer,  // Tegra with the same architecture as NVIDIA desktop GPUs (K1+).
     kPowerVR54x_GrGLRenderer,
     kPowerVRRogue_GrGLRenderer,
     kAdreno3xx_GrGLRenderer,
@@ -161,7 +161,7 @@
 GrGLStandard GrGLGetStandardInUseFromString(const char* versionString);
 GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString);
 GrGLVendor GrGLGetVendorFromString(const char* vendorString);
-GrGLRenderer GrGLGetRendererFromString(const char* rendererString);
+GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString, const char* extensionString);
 void GrGLGetANGLEInfoFromString(const char* rendererString, GrGLANGLEBackend*,
                                 GrGLANGLEVendor*, GrGLANGLERenderer*);