Transform verts using nonsquare matrices when available.

We were previously doing a square-matrix multiply then discarding one
third of the result; now, when available, we just get the result we need
via a non-square multiply.

Change-Id: Ie13ae6f2c7f23e3a4c1f2c4eeb6361a97cdccf67
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/403079
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 6bdda09..86f06ad 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -114,6 +114,10 @@
         if (childProc->sampleUsage().fHasPerspective) {
             return SkStringPrintf("%s(%s, proj((%s) * %s.xy1))", fFunctionNames[childIndex].c_str(),
                                   inputColor, matrixExpr.c_str(), args.fSampleCoord);
+        } else if (args.fShaderCaps->nonsquareMatrixSupport()) {
+            return SkStringPrintf("%s(%s, float3x2(%s) * %s.xy1)",
+                                  fFunctionNames[childIndex].c_str(), inputColor,
+                                  matrixExpr.c_str(), args.fSampleCoord);
         } else {
             return SkStringPrintf("%s(%s, ((%s) * %s.xy1).xy)", fFunctionNames[childIndex].c_str(),
                                   inputColor, matrixExpr.c_str(), args.fSampleCoord);
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index 4ae691c..c4dce3c 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -226,9 +226,15 @@
 
         vb->codeAppend("{\n");
         if (tr.fOutputCoords.getType() == kFloat2_GrSLType) {
-            vb->codeAppendf("%s = ((%s) * %s).xy", tr.fOutputCoords.getName().c_str(),
-                                                   transformExpression.c_str(),
-                                                   localCoords.c_str());
+            if (vb->getProgramBuilder()->shaderCaps()->nonsquareMatrixSupport()) {
+                vb->codeAppendf("%s = float3x2(%s) * %s", tr.fOutputCoords.getName().c_str(),
+                                                          transformExpression.c_str(),
+                                                          localCoords.c_str());
+            } else {
+                vb->codeAppendf("%s = ((%s) * %s).xy", tr.fOutputCoords.getName().c_str(),
+                                                       transformExpression.c_str(),
+                                                       localCoords.c_str());
+            }
         } else {
             SkASSERT(tr.fOutputCoords.getType() == kFloat3_GrSLType);
             vb->codeAppendf("%s = (%s) * %s", tr.fOutputCoords.getName().c_str(),
@@ -353,6 +359,11 @@
                                  mangledMatrixName,
                                  inPos.getName().c_str(),
                                  mangledMatrixName);
+    } else if (shaderCaps.nonsquareMatrixSupport()) {
+        vertBuilder->codeAppendf("float2 %s = float3x2(%s) * %s.xy1;\n",
+                                 outName.c_str(),
+                                 mangledMatrixName,
+                                 inPos.getName().c_str());
     } else {
         vertBuilder->codeAppendf("float2 %s = (%s * %s.xy1).xy;\n",
                                  outName.c_str(),
diff --git a/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp b/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
index 6fe394d..0c28e52 100644
--- a/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLVertexGeoBuilder.cpp
@@ -16,20 +16,18 @@
     if (this->getProgramBuilder()->snapVerticesToPixelCenters()) {
         if (kFloat3_GrSLType == devPosType) {
             const char* p = devPos;
-            out->appendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p);
+            out->appendf("{float2 _posTmp = %s.xy / %s.z;", p, p);
         } else {
             SkASSERT(kFloat2_GrSLType == devPosType);
             out->appendf("{float2 _posTmp = %s;", devPos);
         }
-        out->appendf("_posTmp = floor(_posTmp) + half2(0.5, 0.5);"
-                     "sk_Position = float4(_posTmp, 0, 1);}");
+        out->appendf("_posTmp = floor(_posTmp) + float2(0.5);"
+                     "sk_Position = _posTmp.xy01;}");
     } else if (kFloat3_GrSLType == devPosType) {
-        out->appendf("sk_Position = float4(%s.x , %s.y, 0, %s.z);",
-                     devPos, devPos, devPos);
+        out->appendf("sk_Position = %s.xy0z;", devPos);
     } else {
         SkASSERT(kFloat2_GrSLType == devPosType);
-        out->appendf("sk_Position = float4(%s.x , %s.y, 0, 1);",
-                     devPos, devPos);
+        out->appendf("sk_Position = %s.xy01;", devPos);
     }
 }