Revert "Pass colorspace-transform coefficients in a 4x4 matrix."

This reverts commit b16b8d4d487b6d7b82848180b05496c1115f389f.

Reason for revert: breakage on tree

Original change's description:
> Pass colorspace-transform coefficients in a 4x4 matrix.
>
> Previously, these were passed as arrays of 7 scalars. In std140
> layout, this wastes a lot of uniform space, as we burn 12 padding
> bytes between each array element. Passing as a 4x4 matrix is
> convenient and only wastes two matrix elements total (since we need
> fourteen elements, and actually get sixteen).
>
> Change-Id: Ibc204519628f59145f013f1c6fa038c92088969d
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/748301
> Commit-Queue: Robert Phillips <robertphillips@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>
> Auto-Submit: John Stiles <johnstiles@google.com>

Change-Id: I228b80aa9422e56b760b0f57d211cb38044b0e23
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/748305
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
diff --git a/src/gpu/graphite/KeyHelpers.cpp b/src/gpu/graphite/KeyHelpers.cpp
index 58057c8..b3f7a00 100644
--- a/src/gpu/graphite/KeyHelpers.cpp
+++ b/src/gpu/graphite/KeyHelpers.cpp
@@ -422,20 +422,17 @@
 namespace {
 
 void add_color_space_uniforms(const SkColorSpaceXformSteps& steps, PipelineDataGatherer* gatherer) {
-    // We have 7 source coefficients and 7 destination coefficients. We pass them via a 4x4 matrix;
-    // the first two columns hold the source values, and the second two hold the destination.
-    // (The final value of each 8-element group is ignored.)
-    // In std140, this arrangement is much more efficient than a simple array of scalars.
-    SkM44 coeffs;
+    static constexpr int kNumXferFnCoeffs = 7;
+    static constexpr float kEmptyXferFn[kNumXferFnCoeffs] = {};
 
     gatherer->write(SkTo<int>(steps.flags.mask()));
 
     if (steps.flags.linearize) {
         gatherer->write(SkTo<int>(skcms_TransferFunction_getType(&steps.srcTF)));
-        coeffs.setCol(0, {steps.srcTF.g, steps.srcTF.a, steps.srcTF.b, steps.srcTF.c});
-        coeffs.setCol(1, {steps.srcTF.d, steps.srcTF.e, steps.srcTF.f, 0.0f});
+        gatherer->writeHalfArray({&steps.srcTF.g, kNumXferFnCoeffs});
     } else {
         gatherer->write(SkTo<int>(skcms_TFType::skcms_TFType_Invalid));
+        gatherer->writeHalfArray({kEmptyXferFn, kNumXferFnCoeffs});
     }
 
     SkMatrix gamutTransform;
@@ -447,13 +444,11 @@
 
     if (steps.flags.encode) {
         gatherer->write(SkTo<int>(skcms_TransferFunction_getType(&steps.dstTFInv)));
-        coeffs.setCol(2, {steps.dstTFInv.g, steps.dstTFInv.a, steps.dstTFInv.b, steps.dstTFInv.c});
-        coeffs.setCol(3, {steps.dstTFInv.d, steps.dstTFInv.e, steps.dstTFInv.f, 0.0f});
+        gatherer->writeHalfArray({&steps.dstTFInv.g, kNumXferFnCoeffs});
     } else {
         gatherer->write(SkTo<int>(skcms_TFType::skcms_TFType_Invalid));
+        gatherer->writeHalfArray({kEmptyXferFn, kNumXferFnCoeffs});
     }
-
-    gatherer->writeHalf(coeffs);
 }
 
 void add_image_uniform_data(const ShaderCodeDictionary* dict,
diff --git a/src/gpu/graphite/ShaderCodeDictionary.cpp b/src/gpu/graphite/ShaderCodeDictionary.cpp
index 586a82b..7b5aa7f 100644
--- a/src/gpu/graphite/ShaderCodeDictionary.cpp
+++ b/src/gpu/graphite/ShaderCodeDictionary.cpp
@@ -805,6 +805,8 @@
 }
 
 //--------------------------------------------------------------------------------------------------
+static constexpr int kNumXferFnCoeffs = 7;
+
 static constexpr Uniform kImageShaderUniforms[] = {
         { "imgSize",               SkSLType::kFloat2 },
         { "subset",                SkSLType::kFloat4 },
@@ -812,12 +814,13 @@
         { "tilemodeY",             SkSLType::kInt },
         { "filterMode",            SkSLType::kInt },
         { "readSwizzle",           SkSLType::kInt },
-        // The next 5 uniforms are for the color space transformation
+        // The next 6 uniforms are for the color space transformation
         { "csXformFlags",          SkSLType::kInt },
         { "csXformSrcKind",        SkSLType::kInt },
+        { "csXformSrcCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
         { "csXformGamutTransform", SkSLType::kHalf3x3 },
         { "csXformDstKind",        SkSLType::kInt },
-        { "csXformCoeffs",         SkSLType::kHalf4x4 },
+        { "csXformDstCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
 };
 
 static constexpr Uniform kCubicImageShaderUniforms[] = {
@@ -827,12 +830,13 @@
         { "tilemodeY",             SkSLType::kInt },
         { "cubicCoeffs",           SkSLType::kHalf4x4 },
         { "readSwizzle",           SkSLType::kInt },
-        // The next 5 uniforms are for the color space transformation
+        // The next 6 uniforms are for the color space transformation
         { "csXformFlags",          SkSLType::kInt },
         { "csXformSrcKind",        SkSLType::kInt },
+        { "csXformSrcCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
         { "csXformGamutTransform", SkSLType::kHalf3x3 },
         { "csXformDstKind",        SkSLType::kInt },
-        { "csXformCoeffs",         SkSLType::kHalf4x4 },
+        { "csXformDstCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
 };
 
 static constexpr TextureAndSampler kISTexturesAndSamplers[] = {
@@ -882,9 +886,10 @@
         // The next 6 uniforms are for the color space transformation
         { "csXformFlags",          SkSLType::kInt },
         { "csXformSrcKind",        SkSLType::kInt },
+        { "csXformSrcCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
         { "csXformGamutTransform", SkSLType::kHalf3x3 },
         { "csXformDstKind",        SkSLType::kInt },
-        { "csXformCoeffs",         SkSLType::kHalf4x4 },
+        { "csXformDstCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
 };
 
 static constexpr TextureAndSampler kYUVISTexturesAndSamplers[] = {
@@ -1174,9 +1179,10 @@
 static constexpr Uniform kColorSpaceTransformUniforms[] = {
         { "flags",          SkSLType::kInt },
         { "srcKind",        SkSLType::kInt },
+        { "srcCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
         { "gamutTransform", SkSLType::kHalf3x3 },
         { "dstKind",        SkSLType::kInt },
-        { "csXformCoeffs",  SkSLType::kHalf4x4 },
+        { "dstCoeffs",      SkSLType::kHalf, kNumXferFnCoeffs },
 };
 
 static_assert(0 == static_cast<int>(skcms_TFType_Invalid),
diff --git a/src/sksl/generated/sksl_graphite_frag.minified.sksl b/src/sksl/generated/sksl_graphite_frag.minified.sksl
index 62e2872..4e7aa02 100644
--- a/src/sksl/generated/sksl_graphite_frag.minified.sksl
+++ b/src/sksl/generated/sksl_graphite_frag.minified.sksl
@@ -3,53 +3,52 @@
 "(half4 a){return a;}$pure half4 sk_solid_shader(float4 a){return half4(a);}"
 "$pure half4 $k(int a,half4 b){switch(a){case 1:return half4(b.xyz,1.);case 2"
 ":return b.xxxx;case 3:return half4(b.xxx,1.);case 4:return b.zyxw;default:return"
-" b;}}$pure float $l(int a,float b,half4[2]c){float d=float(c[0].x);float e="
-"float(c[0].y);float f=float(c[0].z);float g=float(c[0].w);float h=float(c[1"
-"].x);float i=float(c[1].y);float j=float(c[1].z);float k=sign(b);b=abs(b);switch"
-"(a){case 1:b=b<h?g*b+j:pow(e*b+f,d)+i;break;case 2:b=pow(max(e+f*pow(b,g),0."
-")/(h+i*pow(b,g)),j);break;case 3:b=b*e<=1.?pow(b*e,f):exp((b-i)*g)+h;b*=j+1."
-";break;case 4:b/=j+1.;b=b<=1.?e*pow(b,f):g*log(b-h)+i;break;}return k*b;}$pure"
-" half4 sk_color_space_transform(half4 a,int b,int c,half3x3 d,int e,half4x4"
-" f){float4 g=float4(a);if(bool(b&1)){g=unpremul(g);}if(bool(b&2)){half4 h[2"
-"];h[0]=f[0];h[1]=f[1];g.x=$l(c,g.x,h);g.y=$l(c,g.y,h);g.z=$l(c,g.z,h);}if(bool"
-"(b&4)){g.xyz=float3x3(d)*g.xyz;}if(bool(b&8)){half4 h[2];h[0]=f[2];h[1]=f[3"
-"];g.x=$l(e,g.x,h);g.y=$l(e,g.y,h);g.z=$l(e,g.z,h);}if(bool(b&16)){g.xyz*=g."
-"w;}return half4(g);}$pure float $m(int a,float b,float c,float d){switch(a)"
-"{case 0:return clamp(b,c,d);case 1:{float e=d-c;return mod(b-c,e)+c;}case 2"
-":{float e=d-c;float g=2.*e;float h=mod(b-c,g);return mix(h,g-h,step(e,h))+c"
-";}default:return b;}}$pure half4 $n(float2 a,float2 b,float4 c,int d,int e,"
-"int f,int g,sampler2D h){if(d==3&&f==0){float i=floor(a.x)+.5;if(i<c.x||i>c"
-".z){return half4(0.);}}if(e==3&&f==0){float i=floor(a.y)+.5;if(i<c.y||i>c.w"
-"){return half4(0.);}}a.x=$m(d,a.x,c.x,c.z);a.y=$m(e,a.y,c.y,c.w);float4 i;if"
-"(f==0){i=float4(floor(c.xy)+.5,ceil(c.zw)-.5);}else{i=float4(c.xy+.5,c.zw-.5"
-");}float2 j=clamp(a,i.xy,i.zw);half4 k=sample(h,j/b);k=$k(g,k);if(f==1){half2"
-" l=half2(a-j);half2 m=abs(l);bool n=d==1;bool o=e==1;if(n||o){float p;float"
-" q;half4 r;half4 t;if(n){p=l.x>0.?i.x:i.z;r=sample(h,float2(p,j.y)/b);r=$k("
-"g,r);}if(o){q=l.y>0.?i.y:i.w;t=sample(h,float2(j.x,q)/b);t=$k(g,t);}if(n&&o"
-"){half4 u=sample(h,float2(p,q)/b);u=$k(g,u);k=mix(mix(k,r,m.x),mix(t,u,m.x)"
-",m.y);}else if(n){k=mix(k,r,m.x);}else if(o){k=mix(k,t,m.y);}}if(d==3){k*=max"
-"(1.-m.x,0.);}if(e==3){k*=max(1.-m.y,0.);}}return k;}$pure half4 $o(float2 a"
-",float2 b,float4 c,int d,int e,half4x4 g,int h,sampler2D i){float2 j=fract("
-"a-.5);a-=1.5;a=floor(a)+.5;half4 k=g*half4(1.,half(j.x),half(j.x*j.x),half("
-"(j.x*j.x)*j.x));half4 l=g*half4(1.,half(j.y),half(j.y*j.y),half((j.y*j.y)*j"
-".y));half4 m=half4(0.);for(int n=0;n<4;++n){half4 o=half4(0.);for(int p=0;p"
-"<4;++p){o+=k[p]*$n(a+float2(float(p),float(n)),b,c,d,e,0,h,i);}m+=l[n]*o;}m"
-".w=saturate(m.w);m.xyz=clamp(m.xyz,half3(0.),m.www);return m;}$pure half4 sk_image_shader"
-"(float2 a,float2 b,float4 c,int d,int e,int f,int g,int h,int i,half3x3 j,int"
-" k,half4x4 l,sampler2D m){half4 n=$n(a,b,c,d,e,f,g,m);return sk_color_space_transform"
-"(n,h,i,j,k,l);}$pure half4 sk_cubic_image_shader(float2 a,float2 b,float4 c"
-",int d,int e,half4x4 f,int g,int h,int i,half3x3 j,int k,half4x4 l,sampler2D"
-" m){half4 n=$o(a,b,c,d,e,f,g,m);return sk_color_space_transform(n,h,i,j,k,l"
-");}$pure half4 sk_yuv_image_shader(float2 a,float2 b,float4 c,int d,int e,int"
-" f,int g,half4x4 h,half4 i,half4 j,half4 k,half4 l,half3x3 m,float3 n,int o"
-",int p,half3x3 q,int r,half4x4 s,sampler2D t,sampler2D u,sampler2D v,sampler2D"
-" w){half4 x=g!=0?$o(a,b,c,d,e,h,0,t):$n(a,b,c,d,e,f,0,t);half4 y=g!=0?$o(a,"
-"b,c,d,e,h,0,u):$n(a,b,c,d,e,f,0,u);half4 z=g!=0?$o(a,b,c,d,e,h,0,t):$n(a,b,"
-"c,d,e,f,0,v);float A=float(dot(i,x));float B=float(dot(j,y));float C=float("
-"dot(k,z));half3 D=half3(half(A),half(B),half(C));half4 E;E.xyz=saturate(D*m"
-"+half3(n));if(l==half4(0.)){E.w=1.;}else{half4 F=g!=0?$o(a,b,c,d,e,h,0,w):$n"
-"(a,b,c,d,e,f,0,w);E.w=dot(l,F);E.xyz*=E.w;}return sk_color_space_transform("
-"E,o,p,q,r,s);}$pure half4 sk_dither_shader(half4 a,float2 b,half c,sampler2D"
+" b;}}$pure float $l(int a,float b,half[7]c){float d=float(c[0]);float e=float"
+"(c[1]);float f=float(c[2]);float g=float(c[3]);float h=float(c[4]);float i="
+"float(c[5]);float j=float(c[6]);float k=sign(b);b=abs(b);switch(a){case 1:b"
+"=b<h?g*b+j:pow(e*b+f,d)+i;break;case 2:b=pow(max(e+f*pow(b,g),0.)/(h+i*pow("
+"b,g)),j);break;case 3:b=b*e<=1.?pow(b*e,f):exp((b-i)*g)+h;b*=j+1.;break;case"
+" 4:b/=j+1.;b=b<=1.?e*pow(b,f):g*log(b-h)+i;break;}return k*b;}$pure half4 sk_color_space_transform"
+"(half4 a,int b,int c,half[7]d,half3x3 e,int f,half[7]g){float4 h=float4(a);"
+"if(bool(b&1)){h=unpremul(h);}if(bool(b&2)){h.x=$l(c,h.x,d);h.y=$l(c,h.y,d);"
+"h.z=$l(c,h.z,d);}if(bool(b&4)){h.xyz=float3x3(e)*h.xyz;}if(bool(b&8)){h.x=$l"
+"(f,h.x,g);h.y=$l(f,h.y,g);h.z=$l(f,h.z,g);}if(bool(b&16)){h.xyz*=h.w;}return"
+" half4(h);}$pure float $m(int a,float b,float c,float d){switch(a){case 0:return"
+" clamp(b,c,d);case 1:{float e=d-c;return mod(b-c,e)+c;}case 2:{float e=d-c;"
+"float g=2.*e;float h=mod(b-c,g);return mix(h,g-h,step(e,h))+c;}default:return"
+" b;}}$pure half4 $n(float2 a,float2 b,float4 c,int d,int e,int f,int g,sampler2D"
+" h){if(d==3&&f==0){float i=floor(a.x)+.5;if(i<c.x||i>c.z){return half4(0.);"
+"}}if(e==3&&f==0){float i=floor(a.y)+.5;if(i<c.y||i>c.w){return half4(0.);}}"
+"a.x=$m(d,a.x,c.x,c.z);a.y=$m(e,a.y,c.y,c.w);float4 i;if(f==0){i=float4(floor"
+"(c.xy)+.5,ceil(c.zw)-.5);}else{i=float4(c.xy+.5,c.zw-.5);}float2 j=clamp(a,"
+"i.xy,i.zw);half4 k=sample(h,j/b);k=$k(g,k);if(f==1){half2 l=half2(a-j);half2"
+" m=abs(l);bool n=d==1;bool o=e==1;if(n||o){float p;float q;half4 r;half4 t;"
+"if(n){p=l.x>0.?i.x:i.z;r=sample(h,float2(p,j.y)/b);r=$k(g,r);}if(o){q=l.y>0."
+"?i.y:i.w;t=sample(h,float2(j.x,q)/b);t=$k(g,t);}if(n&&o){half4 u=sample(h,float2"
+"(p,q)/b);u=$k(g,u);k=mix(mix(k,r,m.x),mix(t,u,m.x),m.y);}else if(n){k=mix(k"
+",r,m.x);}else if(o){k=mix(k,t,m.y);}}if(d==3){k*=max(1.-m.x,0.);}if(e==3){k"
+"*=max(1.-m.y,0.);}}return k;}$pure half4 $o(float2 a,float2 b,float4 c,int d"
+",int e,half4x4 g,int h,sampler2D i){float2 j=fract(a-.5);a-=1.5;a=floor(a)+"
+".5;half4 k=g*half4(1.,half(j.x),half(j.x*j.x),half((j.x*j.x)*j.x));half4 l="
+"g*half4(1.,half(j.y),half(j.y*j.y),half((j.y*j.y)*j.y));half4 m=half4(0.);for"
+"(int n=0;n<4;++n){half4 o=half4(0.);for(int p=0;p<4;++p){o+=k[p]*$n(a+float2"
+"(float(p),float(n)),b,c,d,e,0,h,i);}m+=l[n]*o;}m.w=saturate(m.w);m.xyz=clamp"
+"(m.xyz,half3(0.),m.www);return m;}$pure half4 sk_image_shader(float2 a,float2"
+" b,float4 c,int d,int e,int f,int g,int h,int i,half[7]j,half3x3 k,int l,half"
+"[7]m,sampler2D n){half4 o=$n(a,b,c,d,e,f,g,n);return sk_color_space_transform"
+"(o,h,i,j,k,l,m);}$pure half4 sk_cubic_image_shader(float2 a,float2 b,float4"
+" c,int d,int e,half4x4 f,int g,int h,int i,half[7]j,half3x3 k,int l,half[7]"
+"m,sampler2D n){half4 o=$o(a,b,c,d,e,f,g,n);return sk_color_space_transform("
+"o,h,i,j,k,l,m);}$pure half4 sk_yuv_image_shader(float2 a,float2 b,float4 c,"
+"int d,int e,int f,int g,half4x4 h,half4 i,half4 j,half4 k,half4 l,half3x3 m"
+",float3 n,int o,int p,half[7]q,half3x3 r,int s,half[7]t,sampler2D u,sampler2D"
+" v,sampler2D w,sampler2D x){half4 y=g!=0?$o(a,b,c,d,e,h,0,u):$n(a,b,c,d,e,f"
+",0,u);half4 z=g!=0?$o(a,b,c,d,e,h,0,v):$n(a,b,c,d,e,f,0,v);half4 A=g!=0?$o("
+"a,b,c,d,e,h,0,u):$n(a,b,c,d,e,f,0,w);float B=float(dot(i,y));float C=float("
+"dot(j,z));float D=float(dot(k,A));half3 E=half3(half(B),half(C),half(D));half4"
+" F;F.xyz=saturate(E*m+half3(n));if(l==half4(0.)){F.w=1.;}else{half4 G=g!=0?"
+"$o(a,b,c,d,e,h,0,x):$n(a,b,c,d,e,f,0,x);F.w=dot(l,G);F.xyz*=F.w;}return sk_color_space_transform"
+"(F,o,p,q,r,s,t);}$pure half4 sk_dither_shader(half4 a,float2 b,half c,sampler2D"
 " d){half f=sample(d,b*.125).x-.5;return half4(clamp(a.xyz+f*c,0.,a.w),a.w);"
 "}$pure float2 $p(int a,float2 b){switch(a){case 0:b.x=saturate(b.x);break;case"
 " 1:b.x=fract(b.x);break;case 2:{float c=b.x-1.;b.x=(c-2.*floor(c*.5))-1.;if"
diff --git a/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl b/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl
index 65da866..f520807 100644
--- a/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl
+++ b/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl
@@ -9,38 +9,36 @@
 "(int swizzleType,half4 color){switch(swizzleType){case 1:return half4(color"
 ".xyz,1.);case 2:return color.xxxx;case 3:return half4(color.xxx,1.);case 4:"
 "return color.zyxw;default:return color;}}$pure float $apply_xfer_fn(int kind"
-",float x,half4[2]cs){float G=float(cs[0].x);float A=float(cs[0].y);float B="
-"float(cs[0].z);float C=float(cs[0].w);float D=float(cs[1].x);float E=float("
-"cs[1].y);float F=float(cs[1].z);float s=sign(x);x=abs(x);switch(kind){case 1"
-":x=x<D?C*x+F:pow(A*x+B,G)+E;break;case 2:x=pow(max(A+B*pow(x,C),0.)/(D+E*pow"
-"(x,C)),F);break;case 3:x=x*A<=1.?pow(x*A,B):exp((x-E)*C)+D;x*=F+1.;break;case"
-" 4:x/=F+1.;x=x<=1.?A*pow(x,B):C*log(x-D)+E;break;}return s*x;}$pure half4 sk_color_space_transform"
-"(half4 halfColor,int flags,int srcKind,half3x3 gamutTransform,int dstKind,half4x4"
-" coeffs){float4 color=float4(halfColor);if(bool(flags&$kColorSpaceXformFlagUnpremul"
-")){color=unpremul(color);}if(bool(flags&$kColorSpaceXformFlagLinearize)){half4"
-" srcCoeffs[2];srcCoeffs[0]=coeffs[0];srcCoeffs[1]=coeffs[1];color.x=$apply_xfer_fn"
-"(srcKind,color.x,srcCoeffs);color.y=$apply_xfer_fn(srcKind,color.y,srcCoeffs"
-");color.z=$apply_xfer_fn(srcKind,color.z,srcCoeffs);}if(bool(flags&$kColorSpaceXformFlagGamutTransform"
-")){color.xyz=float3x3(gamutTransform)*color.xyz;}if(bool(flags&$kColorSpaceXformFlagEncode"
-")){half4 dstCoeffs[2];dstCoeffs[0]=coeffs[2];dstCoeffs[1]=coeffs[3];color.x"
-"=$apply_xfer_fn(dstKind,color.x,dstCoeffs);color.y=$apply_xfer_fn(dstKind,color"
-".y,dstCoeffs);color.z=$apply_xfer_fn(dstKind,color.z,dstCoeffs);}if(bool(flags"
-"&$kColorSpaceXformFlagPremul)){color.xyz*=color.w;}return half4(color);}$pure"
-" float $tile(int tileMode,float f,float low,float high){switch(tileMode){case"
-" 0:return clamp(f,low,high);case 1:{float length=high-low;return mod(f-low,"
-"length)+low;}case 2:{float length=high-low;float length2=2.*length;float tmp"
-"=mod(f-low,length2);return mix(tmp,length2-tmp,step(length,tmp))+low;}default"
-":return f;}}$pure half4 $sample_image(float2 pos,float2 imgSize,float4 subset"
-",int tileModeX,int tileModeY,int filterMode,int readSwizzle,sampler2D s){if"
-"(tileModeX==$kTileModeDecal&&filterMode==$kFilterModeNearest){float snappedX"
-"=floor(pos.x)+.5;if(snappedX<subset.x||snappedX>subset.z){return half4(0.);"
-"}}if(tileModeY==$kTileModeDecal&&filterMode==$kFilterModeNearest){float snappedY"
-"=floor(pos.y)+.5;if(snappedY<subset.y||snappedY>subset.w){return half4(0.);"
-"}}pos.x=$tile(tileModeX,pos.x,subset.x,subset.z);pos.y=$tile(tileModeY,pos."
-"y,subset.y,subset.w);float4 insetClamp;if(filterMode==$kFilterModeNearest){"
-"insetClamp=float4(floor(subset.xy)+.5,ceil(subset.zw)-.5);}else{insetClamp="
-"float4(subset.xy+.5,subset.zw-.5);}float2 clampedPos=clamp(pos,insetClamp.xy"
-",insetClamp.zw);half4 color=sample(s,clampedPos/imgSize);color=$apply_swizzle"
+",float x,half[7]cs){float G=float(cs[0]);float A=float(cs[1]);float B=float"
+"(cs[2]);float C=float(cs[3]);float D=float(cs[4]);float E=float(cs[5]);float"
+" F=float(cs[6]);float s=sign(x);x=abs(x);switch(kind){case 1:x=x<D?C*x+F:pow"
+"(A*x+B,G)+E;break;case 2:x=pow(max(A+B*pow(x,C),0.)/(D+E*pow(x,C)),F);break"
+";case 3:x=x*A<=1.?pow(x*A,B):exp((x-E)*C)+D;x*=F+1.;break;case 4:x/=F+1.;x="
+"x<=1.?A*pow(x,B):C*log(x-D)+E;break;}return s*x;}$pure half4 sk_color_space_transform"
+"(half4 halfColor,int flags,int srcKind,half[7]srcCoeffs,half3x3 gamutTransform"
+",int dstKind,half[7]dstCoeffs){float4 color=float4(halfColor);if(bool(flags"
+"&$kColorSpaceXformFlagUnpremul)){color=unpremul(color);}if(bool(flags&$kColorSpaceXformFlagLinearize"
+")){color.x=$apply_xfer_fn(srcKind,color.x,srcCoeffs);color.y=$apply_xfer_fn"
+"(srcKind,color.y,srcCoeffs);color.z=$apply_xfer_fn(srcKind,color.z,srcCoeffs"
+");}if(bool(flags&$kColorSpaceXformFlagGamutTransform)){color.xyz=float3x3(gamutTransform"
+")*color.xyz;}if(bool(flags&$kColorSpaceXformFlagEncode)){color.x=$apply_xfer_fn"
+"(dstKind,color.x,dstCoeffs);color.y=$apply_xfer_fn(dstKind,color.y,dstCoeffs"
+");color.z=$apply_xfer_fn(dstKind,color.z,dstCoeffs);}if(bool(flags&$kColorSpaceXformFlagPremul"
+")){color.xyz*=color.w;}return half4(color);}$pure float $tile(int tileMode,"
+"float f,float low,float high){switch(tileMode){case 0:return clamp(f,low,high"
+");case 1:{float length=high-low;return mod(f-low,length)+low;}case 2:{float"
+" length=high-low;float length2=2.*length;float tmp=mod(f-low,length2);return"
+" mix(tmp,length2-tmp,step(length,tmp))+low;}default:return f;}}$pure half4 $sample_image"
+"(float2 pos,float2 imgSize,float4 subset,int tileModeX,int tileModeY,int filterMode"
+",int readSwizzle,sampler2D s){if(tileModeX==$kTileModeDecal&&filterMode==$kFilterModeNearest"
+"){float snappedX=floor(pos.x)+.5;if(snappedX<subset.x||snappedX>subset.z){return"
+" half4(0.);}}if(tileModeY==$kTileModeDecal&&filterMode==$kFilterModeNearest"
+"){float snappedY=floor(pos.y)+.5;if(snappedY<subset.y||snappedY>subset.w){return"
+" half4(0.);}}pos.x=$tile(tileModeX,pos.x,subset.x,subset.z);pos.y=$tile(tileModeY"
+",pos.y,subset.y,subset.w);float4 insetClamp;if(filterMode==$kFilterModeNearest"
+"){insetClamp=float4(floor(subset.xy)+.5,ceil(subset.zw)-.5);}else{insetClamp"
+"=float4(subset.xy+.5,subset.zw-.5);}float2 clampedPos=clamp(pos,insetClamp."
+"xy,insetClamp.zw);half4 color=sample(s,clampedPos/imgSize);color=$apply_swizzle"
 "(readSwizzle,color);if(filterMode==$kFilterModeLinear){half2 error=half2(pos"
 "-clampedPos);half2 absError=abs(error);bool sampleExtraX=tileModeX==$kTileModeRepeat"
 ";bool sampleExtraY=tileModeY==$kTileModeRepeat;if(sampleExtraX||sampleExtraY"
@@ -66,46 +64,47 @@
 ",readSwizzle,s);}color+=wy[y]*rowColor;}color.w=saturate(color.w);color.xyz"
 "=clamp(color.xyz,half3(0.),color.www);return color;}$pure half4 sk_image_shader"
 "(float2 coords,float2 imgSize,float4 subset,int tileModeX,int tileModeY,int"
-" filterMode,int readSwizzle,int csXformFlags,int csXformSrcKind,half3x3 csXformGamutTransform"
-",int csXformDstKind,half4x4 csXformCoeffs,sampler2D s){half4 sampleColor=$sample_image"
-"(coords,imgSize,subset,tileModeX,tileModeY,filterMode,readSwizzle,s);return"
-" sk_color_space_transform(sampleColor,csXformFlags,csXformSrcKind,csXformGamutTransform"
-",csXformDstKind,csXformCoeffs);}$pure half4 sk_cubic_image_shader(float2 coords"
-",float2 imgSize,float4 subset,int tileModeX,int tileModeY,half4x4 cubicCoeffs"
-",int readSwizzle,int csXformFlags,int csXformSrcKind,half3x3 csXformGamutTransform"
-",int csXformDstKind,half4x4 csXformCoeffs,sampler2D s){half4 sampleColor=$cubic_filter_image"
+" filterMode,int readSwizzle,int csXformFlags,int csXformSrcKind,half[7]csXformSrcCoeffs"
+",half3x3 csXformGamutTransform,int csXformDstKind,half[7]csXformDstCoeffs,sampler2D"
+" s){half4 sampleColor=$sample_image(coords,imgSize,subset,tileModeX,tileModeY"
+",filterMode,readSwizzle,s);return sk_color_space_transform(sampleColor,csXformFlags"
+",csXformSrcKind,csXformSrcCoeffs,csXformGamutTransform,csXformDstKind,csXformDstCoeffs"
+");}$pure half4 sk_cubic_image_shader(float2 coords,float2 imgSize,float4 subset"
+",int tileModeX,int tileModeY,half4x4 cubicCoeffs,int readSwizzle,int csXformFlags"
+",int csXformSrcKind,half[7]csXformSrcCoeffs,half3x3 csXformGamutTransform,int"
+" csXformDstKind,half[7]csXformDstCoeffs,sampler2D s){half4 sampleColor=$cubic_filter_image"
 "(coords,imgSize,subset,tileModeX,tileModeY,cubicCoeffs,readSwizzle,s);return"
-" sk_color_space_transform(sampleColor,csXformFlags,csXformSrcKind,csXformGamutTransform"
-",csXformDstKind,csXformCoeffs);}$pure half4 sk_yuv_image_shader(float2 coords"
-",float2 imgSize,float4 subset,int tileModeX,int tileModeY,int filterMode,int"
-" useCubic,half4x4 cubicCoeffs,half4 channelSelectY,half4 channelSelectU,half4"
-" channelSelectV,half4 channelSelectA,half3x3 yuvToRGBMatrix,float3 yuvToRGBTranslate"
-",int csXformFlags,int csXformSrcKind,half3x3 csXformGamutTransform,int csXformDstKind"
-",half4x4 csXformCoeffs,sampler2D sY,sampler2D sU,sampler2D sV,sampler2D sA)"
-"{half4 sampleColorY=useCubic!=0?$cubic_filter_image(coords,imgSize,subset,tileModeX"
-",tileModeY,cubicCoeffs,$kReadSwizzleNormalRGBA,sY):$sample_image(coords,imgSize"
-",subset,tileModeX,tileModeY,filterMode,$kReadSwizzleNormalRGBA,sY);half4 sampleColorU"
-"=useCubic!=0?$cubic_filter_image(coords,imgSize,subset,tileModeX,tileModeY,"
-"cubicCoeffs,$kReadSwizzleNormalRGBA,sU):$sample_image(coords,imgSize,subset"
-",tileModeX,tileModeY,filterMode,$kReadSwizzleNormalRGBA,sU);half4 sampleColorV"
-"=useCubic!=0?$cubic_filter_image(coords,imgSize,subset,tileModeX,tileModeY,"
-"cubicCoeffs,$kReadSwizzleNormalRGBA,sY):$sample_image(coords,imgSize,subset"
-",tileModeX,tileModeY,filterMode,$kReadSwizzleNormalRGBA,sV);float Y=float(dot"
-"(channelSelectY,sampleColorY));float U=float(dot(channelSelectU,sampleColorU"
-"));float V=float(dot(channelSelectV,sampleColorV));half3 preColor=half3(half"
-"(Y),half(U),half(V));half4 sampleColor;sampleColor.xyz=saturate(preColor*yuvToRGBMatrix"
-"+half3(yuvToRGBTranslate));if(channelSelectA==half4(0.)){sampleColor.w=1.;}"
-"else{half4 sampleColorA=useCubic!=0?$cubic_filter_image(coords,imgSize,subset"
-",tileModeX,tileModeY,cubicCoeffs,$kReadSwizzleNormalRGBA,sA):$sample_image("
+" sk_color_space_transform(sampleColor,csXformFlags,csXformSrcKind,csXformSrcCoeffs"
+",csXformGamutTransform,csXformDstKind,csXformDstCoeffs);}$pure half4 sk_yuv_image_shader"
+"(float2 coords,float2 imgSize,float4 subset,int tileModeX,int tileModeY,int"
+" filterMode,int useCubic,half4x4 cubicCoeffs,half4 channelSelectY,half4 channelSelectU"
+",half4 channelSelectV,half4 channelSelectA,half3x3 yuvToRGBMatrix,float3 yuvToRGBTranslate"
+",int csXformFlags,int csXformSrcKind,half[7]csXformSrcCoeffs,half3x3 csXformGamutTransform"
+",int csXformDstKind,half[7]csXformDstCoeffs,sampler2D sY,sampler2D sU,sampler2D"
+" sV,sampler2D sA){half4 sampleColorY=useCubic!=0?$cubic_filter_image(coords"
+",imgSize,subset,tileModeX,tileModeY,cubicCoeffs,$kReadSwizzleNormalRGBA,sY)"
+":$sample_image(coords,imgSize,subset,tileModeX,tileModeY,filterMode,$kReadSwizzleNormalRGBA"
+",sY);half4 sampleColorU=useCubic!=0?$cubic_filter_image(coords,imgSize,subset"
+",tileModeX,tileModeY,cubicCoeffs,$kReadSwizzleNormalRGBA,sU):$sample_image("
 "coords,imgSize,subset,tileModeX,tileModeY,filterMode,$kReadSwizzleNormalRGBA"
+",sU);half4 sampleColorV=useCubic!=0?$cubic_filter_image(coords,imgSize,subset"
+",tileModeX,tileModeY,cubicCoeffs,$kReadSwizzleNormalRGBA,sY):$sample_image("
+"coords,imgSize,subset,tileModeX,tileModeY,filterMode,$kReadSwizzleNormalRGBA"
+",sV);float Y=float(dot(channelSelectY,sampleColorY));float U=float(dot(channelSelectU"
+",sampleColorU));float V=float(dot(channelSelectV,sampleColorV));half3 preColor"
+"=half3(half(Y),half(U),half(V));half4 sampleColor;sampleColor.xyz=saturate("
+"preColor*yuvToRGBMatrix+half3(yuvToRGBTranslate));if(channelSelectA==half4("
+"0.)){sampleColor.w=1.;}else{half4 sampleColorA=useCubic!=0?$cubic_filter_image"
+"(coords,imgSize,subset,tileModeX,tileModeY,cubicCoeffs,$kReadSwizzleNormalRGBA"
+",sA):$sample_image(coords,imgSize,subset,tileModeX,tileModeY,filterMode,$kReadSwizzleNormalRGBA"
 ",sA);sampleColor.w=dot(channelSelectA,sampleColorA);sampleColor.xyz*=sampleColor"
 ".w;}return sk_color_space_transform(sampleColor,csXformFlags,csXformSrcKind"
-",csXformGamutTransform,csXformDstKind,csXformCoeffs);}$pure half4 sk_dither_shader"
-"(half4 colorIn,float2 coords,half range,sampler2D lut){half value=sample(lut"
-",coords*.125).x-.5;return half4(clamp(colorIn.xyz+value*range,0.,colorIn.w)"
-",colorIn.w);}$pure float2 $tile_grad(int tileMode,float2 t){switch(tileMode"
-"){case 0:t.x=saturate(t.x);break;case 1:t.x=fract(t.x);break;case 2:{float t_1"
-"=t.x-1.;t.x=(t_1-2.*floor(t_1*.5))-1.;if(sk_Caps.mustDoOpBetweenFloorAndAbs"
+",csXformSrcCoeffs,csXformGamutTransform,csXformDstKind,csXformDstCoeffs);}$pure"
+" half4 sk_dither_shader(half4 colorIn,float2 coords,half range,sampler2D lut"
+"){half value=sample(lut,coords*.125).x-.5;return half4(clamp(colorIn.xyz+value"
+"*range,0.,colorIn.w),colorIn.w);}$pure float2 $tile_grad(int tileMode,float2"
+" t){switch(tileMode){case 0:t.x=saturate(t.x);break;case 1:t.x=fract(t.x);break"
+";case 2:{float t_1=t.x-1.;t.x=(t_1-2.*floor(t_1*.5))-1.;if(sk_Caps.mustDoOpBetweenFloorAndAbs"
 "){t.x=clamp(t.x,-1.,1.);}t.x=abs(t.x);break;}case 3:if(t.x<0.||t.x>1.){return"
 " float2(0.,-1.);}break;}return t;}$pure half4 $colorize_grad_4(float4[4]colorsParam"
 ",float4 offsetsParam,float2 t){if(t.y<0.){return half4(0.);}else if(t.x<=offsetsParam"
diff --git a/src/sksl/sksl_graphite_frag.sksl b/src/sksl/sksl_graphite_frag.sksl
index 94fd327..cae7bdb 100644
--- a/src/sksl/sksl_graphite_frag.sksl
+++ b/src/sksl/sksl_graphite_frag.sksl
@@ -52,9 +52,8 @@
     }
 }
 
-$pure float $apply_xfer_fn(int kind, float x, half4 cs[2]) {
-    float G = cs[0][0], A = cs[0][1], B = cs[0][2], C = cs[0][3],
-          D = cs[1][0], E = cs[1][1], F = cs[1][2];
+$pure float $apply_xfer_fn(int kind, float x, half cs[7]) {
+    float G = cs[0], A = cs[1], B = cs[2], C = cs[3], D = cs[4], E = cs[5], F = cs[6];
     float s = sign(x);
     x = abs(x);
     switch (kind) {
@@ -82,9 +81,10 @@
 $pure half4 sk_color_space_transform(half4 halfColor,
                                      int flags,
                                      int srcKind,
+                                     half srcCoeffs[7],
                                      half3x3 gamutTransform,
                                      int dstKind,
-                                     half4x4 coeffs) {
+                                     half dstCoeffs[7]) {
     float4 color = float4(halfColor);
 
     if (bool(flags & $kColorSpaceXformFlagUnpremul)) {
@@ -92,9 +92,6 @@
     }
 
     if (bool(flags & $kColorSpaceXformFlagLinearize)) {
-        half4 srcCoeffs[2];
-        srcCoeffs[0] = coeffs[0];
-        srcCoeffs[1] = coeffs[1];
         color.r = $apply_xfer_fn(srcKind, color.r, srcCoeffs);
         color.g = $apply_xfer_fn(srcKind, color.g, srcCoeffs);
         color.b = $apply_xfer_fn(srcKind, color.b, srcCoeffs);
@@ -103,9 +100,6 @@
         color.rgb = gamutTransform * color.rgb;
     }
     if (bool(flags & $kColorSpaceXformFlagEncode)) {
-        half4 dstCoeffs[2];
-        dstCoeffs[0] = coeffs[2];
-        dstCoeffs[1] = coeffs[3];
         color.r = $apply_xfer_fn(dstKind, color.r, dstCoeffs);
         color.g = $apply_xfer_fn(dstKind, color.g, dstCoeffs);
         color.b = $apply_xfer_fn(dstKind, color.b, dstCoeffs);
@@ -271,14 +265,15 @@
                             int readSwizzle,
                             int csXformFlags,
                             int csXformSrcKind,
+                            half csXformSrcCoeffs[7],
                             half3x3 csXformGamutTransform,
                             int csXformDstKind,
-                            half4x4 csXformCoeffs,
+                            half csXformDstCoeffs[7],
                             sampler2D s) {
     half4 sampleColor =
         $sample_image(coords, imgSize, subset, tileModeX, tileModeY, filterMode, readSwizzle, s);
-    return sk_color_space_transform(sampleColor, csXformFlags, csXformSrcKind,
-                                    csXformGamutTransform, csXformDstKind, csXformCoeffs);
+    return sk_color_space_transform(sampleColor, csXformFlags, csXformSrcKind, csXformSrcCoeffs,
+                                    csXformGamutTransform, csXformDstKind, csXformDstCoeffs);
 }
 
 $pure half4 sk_cubic_image_shader(float2 coords,
@@ -290,14 +285,15 @@
                                   int readSwizzle,
                                   int csXformFlags,
                                   int csXformSrcKind,
+                                  half csXformSrcCoeffs[7],
                                   half3x3 csXformGamutTransform,
                                   int csXformDstKind,
-                                  half4x4 csXformCoeffs,
+                                  half csXformDstCoeffs[7],
                                   sampler2D s) {
     half4 sampleColor = $cubic_filter_image(coords, imgSize, subset, tileModeX, tileModeY,
                                             cubicCoeffs, readSwizzle, s);
-    return sk_color_space_transform(sampleColor, csXformFlags, csXformSrcKind,
-                                    csXformGamutTransform, csXformDstKind, csXformCoeffs);
+    return sk_color_space_transform(sampleColor, csXformFlags, csXformSrcKind, csXformSrcCoeffs,
+                                    csXformGamutTransform, csXformDstKind, csXformDstCoeffs);
 }
 
 $pure half4 sk_yuv_image_shader(float2 coords,
@@ -316,9 +312,10 @@
                                 float3 yuvToRGBTranslate,
                                 int csXformFlags,
                                 int csXformSrcKind,
+                                half csXformSrcCoeffs[7],
                                 half3x3 csXformGamutTransform,
                                 int csXformDstKind,
-                                half4x4 csXformCoeffs,
+                                half csXformDstCoeffs[7],
                                 sampler2D sY,
                                 sampler2D sU,
                                 sampler2D sV,
@@ -357,8 +354,8 @@
         sampleColor.rgb *= sampleColor.a;
     }
 
-    return sk_color_space_transform(sampleColor, csXformFlags, csXformSrcKind,
-                                    csXformGamutTransform, csXformDstKind, csXformCoeffs);
+    return sk_color_space_transform(sampleColor, csXformFlags, csXformSrcKind, csXformSrcCoeffs,
+                                    csXformGamutTransform, csXformDstKind, csXformDstCoeffs);
 }
 
 $pure half4 sk_dither_shader(half4 colorIn,