From ccb46aaef838e1bd9d2feb249fb65aa935d7dc2c Mon Sep 17 00:00:00 2001 From: Christopher Cameron Date: Mon, 22 May 2017 16:46:36 -0700 Subject: [PATCH] Don't pass uniform arrays in GrGLNonlinearColorSpaceXformEffect 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 Reviewed-by: Brian Osman --- .../effects/GrNonlinearColorSpaceXformEffect.cpp | 57 ++++++++++++---------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp index c6c0c26..ab03268 100644 --- a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp +++ b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp @@ -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 -- 2.7.4