Don't pass uniform arrays in GrGLNonlinearColorSpaceXformEffect
authorChristopher Cameron <ccameron@chromium.org>
Mon, 22 May 2017 23:46:36 +0000 (16:46 -0700)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 23 May 2017 17:34:32 +0000 (17:34 +0000)
This avoids a problem where passing a uniform array as a function
array sometimes gets lost.

Instead of passing the uniform array as an argument to the
transfer function evaluation function, create two separate
transfer function evaluation functions that read the uniforms
directly.

BUG=723133

Change-Id: Ib46b99efdbc04ce0201644ebbc1dfd4cb27e9276
Reviewed-on: https://skia-review.googlesource.com/17293
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp

index c6c0c26..ab03268 100644 (file)
@@ -44,27 +44,30 @@ public:
                                                         &gamutXformName);
         }
 
-        // Helper function to apply a transfer function to a single value
-        SkString tfFuncNameString;
-        static const GrShaderVar gTransferFnFuncArgs[] = {
-            GrShaderVar("x", kFloat_GrSLType),
-            GrShaderVar("coeffs", kFloat_GrSLType,
-                        GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs),
-        };
-        SkString transferFnBody;
-        // Temporaries to make evaluation line readable
-        transferFnBody.printf("float A = coeffs[0];");
-        transferFnBody.append("float B = coeffs[1];");
-        transferFnBody.append("float C = coeffs[2];");
-        transferFnBody.append("float D = coeffs[3];");
-        transferFnBody.append("float E = coeffs[4];");
-        transferFnBody.append("float F = coeffs[5];");
-        transferFnBody.append("float G = coeffs[6];");
-        transferFnBody.appendf("return (x < D) ? (C * x) + F : pow(A * x + B, G) + E;");
-        fragBuilder->emitFunction(kFloat_GrSLType, "transfer_fn",
-                                  SK_ARRAY_COUNT(gTransferFnFuncArgs), gTransferFnFuncArgs,
-                                  transferFnBody.c_str(), &tfFuncNameString);
-        const char* tfFuncName = tfFuncNameString.c_str();
+        // Helper function to apply the src or dst transfer function to a single value
+        SkString tfFuncNames[2];
+        for (size_t i = 0; i < 2; ++i) {
+            const char* coeffsName = i ? dstCoeffsName : srcCoeffsName;
+            if (!coeffsName) {
+                continue;
+            }
+            const char* fnName = i ? "dst_transfer_fn" : "src_transfer_fn";
+            static const GrShaderVar gTransferFnFuncArgs[] = {
+                    GrShaderVar("x", kFloat_GrSLType),
+            };
+            SkString transferFnBody;
+            // Temporaries to make evaluation line readable
+            transferFnBody.printf("float A = %s[0];", coeffsName);
+            transferFnBody.appendf("float B = %s[1];", coeffsName);
+            transferFnBody.appendf("float C = %s[2];", coeffsName);
+            transferFnBody.appendf("float D = %s[3];", coeffsName);
+            transferFnBody.appendf("float E = %s[4];", coeffsName);
+            transferFnBody.appendf("float F = %s[5];", coeffsName);
+            transferFnBody.appendf("float G = %s[6];", coeffsName);
+            transferFnBody.appendf("return (x < D) ? (C * x) + F : pow(A * x + B, G) + E;");
+            fragBuilder->emitFunction(kFloat_GrSLType, fnName, SK_ARRAY_COUNT(gTransferFnFuncArgs),
+                                      gTransferFnFuncArgs, transferFnBody.c_str(), &tfFuncNames[i]);
+        }
 
         if (nullptr == args.fInputColor) {
             args.fInputColor = "vec4(1)";
@@ -77,9 +80,9 @@ public:
 
         // 2: Apply src transfer function (to get to linear RGB)
         if (srcCoeffsName) {
-            fragBuilder->codeAppendf("color.r = %s(color.r, %s);", tfFuncName, srcCoeffsName);
-            fragBuilder->codeAppendf("color.g = %s(color.g, %s);", tfFuncName, srcCoeffsName);
-            fragBuilder->codeAppendf("color.b = %s(color.b, %s);", tfFuncName, srcCoeffsName);
+            fragBuilder->codeAppendf("color.r = %s(color.r);", tfFuncNames[0].c_str());
+            fragBuilder->codeAppendf("color.g = %s(color.g);", tfFuncNames[0].c_str());
+            fragBuilder->codeAppendf("color.b = %s(color.b);", tfFuncNames[0].c_str());
         }
 
         // 3: Apply gamut matrix
@@ -91,9 +94,9 @@ public:
 
         // 4: Apply dst transfer fn
         if (dstCoeffsName) {
-            fragBuilder->codeAppendf("color.r = %s(color.r, %s);", tfFuncName, dstCoeffsName);
-            fragBuilder->codeAppendf("color.g = %s(color.g, %s);", tfFuncName, dstCoeffsName);
-            fragBuilder->codeAppendf("color.b = %s(color.b, %s);", tfFuncName, dstCoeffsName);
+            fragBuilder->codeAppendf("color.r = %s(color.r);", tfFuncNames[1].c_str());
+            fragBuilder->codeAppendf("color.g = %s(color.g);", tfFuncNames[1].c_str());
+            fragBuilder->codeAppendf("color.b = %s(color.b);", tfFuncNames[1].c_str());
         }
 
         // 5: Premultiply again