Always run color space math in full-float on the GPU (Part 2)
In https://reviews.skia.org/674396, we forced this code to run at full
precision in Ganesh (to fix Android HDR bugs). This CL applies the same
treatment to Graphite, and also cleans up an obsolete caps bit.
Change-Id: Iae1033f86ed8dda782bc32fc8ad994280a4ecac4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/674398
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/ganesh/GrShaderCaps.cpp b/src/gpu/ganesh/GrShaderCaps.cpp
index 58dee34..df95258 100644
--- a/src/gpu/ganesh/GrShaderCaps.cpp
+++ b/src/gpu/ganesh/GrShaderCaps.cpp
@@ -60,7 +60,6 @@
fNoDefaultPrecisionForExternalSamplers);
writer->appendBool("Rewrite matrix-vector multiply", fRewriteMatrixVectorMultiply);
writer->appendBool("Rewrite matrix equality comparisons", fRewriteMatrixComparisons);
- writer->appendBool("Color space math needs float", fColorSpaceMathNeedsFloat);
writer->appendBool("Rounding fix required for Perlin noise", fPerlinNoiseRoundingFix);
writer->appendBool("Flat interpolation support", fFlatInterpolationSupport);
writer->appendBool("Prefer flat interpolation", fPreferFlatInterpolation);
@@ -110,7 +109,6 @@
SkASSERT(!fNoDefaultPrecisionForExternalSamplers);
SkASSERT(!fRewriteMatrixVectorMultiply);
SkASSERT(!fRewriteMatrixComparisons);
- SkASSERT(!fColorSpaceMathNeedsFloat);
SkASSERT(!fPerlinNoiseRoundingFix);
}
if (options.fReducedShaderVariations) {
diff --git a/src/gpu/ganesh/gl/GrGLCaps.cpp b/src/gpu/ganesh/gl/GrGLCaps.cpp
index 8958815..7d11fac 100644
--- a/src/gpu/ganesh/gl/GrGLCaps.cpp
+++ b/src/gpu/ganesh/gl/GrGLCaps.cpp
@@ -4097,13 +4097,6 @@
shaderCaps->fMustObfuscateUniformColor = true;
}
- // On Mali G series GPUs, applying transfer functions in the fragment shader with half-floats
- // produces answers that are much less accurate than expected/required. This forces full floats
- // for some intermediate values to get acceptable results.
- if (ctxInfo.renderer() == GrGLRenderer::kMaliG) {
- fShaderCaps->fColorSpaceMathNeedsFloat = true;
- }
-
#if defined(SK_BUILD_FOR_ANDROID)
// On the following GPUs, the Perlin noise code needs to aggressively snap to multiples
// of 1/255 to avoid artifacts in the double table lookup:
diff --git a/src/gpu/ganesh/vk/GrVkCaps.cpp b/src/gpu/ganesh/vk/GrVkCaps.cpp
index 9cbd016..9e19ec1 100644
--- a/src/gpu/ganesh/vk/GrVkCaps.cpp
+++ b/src/gpu/ganesh/vk/GrVkCaps.cpp
@@ -546,13 +546,6 @@
fSupportsDiscardableMSAAForDMSAA = false;
}
- // On Mali G series GPUs, applying transfer functions in the fragment shader with half-floats
- // produces answers that are much less accurate than expected/required. This forces full floats
- // for some intermediate values to get acceptable results.
- if (kARM_VkVendor == properties.vendorID) {
- fShaderCaps->fColorSpaceMathNeedsFloat = true;
- }
-
// On the Mali G76 and T880, the Perlin noise code needs to aggressively snap to multiples
// of 1/255 to avoid artifacts in the double table lookup.
if (kARM_VkVendor == properties.vendorID) {
diff --git a/src/sksl/SkSLUtil.h b/src/sksl/SkSLUtil.h
index c45ae9d..2968f43 100644
--- a/src/sksl/SkSLUtil.h
+++ b/src/sksl/SkSLUtil.h
@@ -143,10 +143,6 @@
bool fRewriteMatrixComparisons = false;
// Strips const from function parameters in the GLSL code generator. (skia:13858)
bool fRemoveConstFromFunctionParameters = false;
- // On Mali G series GPUs, applying transfer functions in the fragment shader with half-floats
- // produces answers that are much less accurate than expected/required. This forces full floats
- // for some intermediate values to get acceptable results.
- bool fColorSpaceMathNeedsFloat = false;
// On some Android devices colors aren't accurate enough for the double lookup in the
// Perlin noise shader. This workaround aggressively snaps colors to multiples of 1/255.
bool fPerlinNoiseRoundingFix = false;
diff --git a/src/sksl/generated/sksl_graphite_frag.minified.sksl b/src/sksl/generated/sksl_graphite_frag.minified.sksl
index 55ba746..6f7b345 100644
--- a/src/sksl/generated/sksl_graphite_frag.minified.sksl
+++ b/src/sksl/generated/sksl_graphite_frag.minified.sksl
@@ -3,100 +3,93 @@
"(half4 a){return a;}$pure half4 sk_solid_shader(float4 a){return half4(a);}"
"$pure half4 $k(int a,half4 b){half4 c=b;switch(a){case 0:break;case 1:c=half4"
"(b.xyz,1.);break;case 2:c=b.xxxx;break;case 3:c=half4(b.xxx,1.);break;case 4"
-":c=b.zyxw;break;}return c;}$pure half $l(int a,half b,half[7]c){half d=c[0]"
-";half e=c[1];half f=c[2];half g=c[3];half h=c[4];half i=c[5];half j=c[6];half"
-" 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_float(float4 a"
-",int b,int c,half[7]d,half3x3 e,int f,half[7]g){if(bool(b&1)){a=unpremul(a)"
-";}if(bool(b&2)){a.x=float($l(c,half(a.x),d));a.y=float($l(c,half(a.y),d));a"
-".z=float($l(c,half(a.z),d));}if(bool(b&4)){a.xyz=float3x3(e)*a.xyz;}if(bool"
-"(b&8)){a.x=float($l(f,half(a.x),g));a.y=float($l(f,half(a.y),g));a.z=float("
-"$l(f,half(a.z),g));}if(bool(b&16)){a.xyz*=a.w;}return half4(a);}$pure half4"
-" sk_color_space_transform_half(half4 a,int b,int c,half[7]d,half3x3 e,int f"
-",half[7]g){if(bool(b&1)){a=unpremul(a);}if(bool(b&2)){a.x=$l(c,a.x,d);a.y=$l"
-"(c,a.y,d);a.z=$l(c,a.z,d);}if(bool(b&4)){a.xyz=e*a.xyz;}if(bool(b&8)){a.x=$l"
-"(f,a.x,g);a.y=$l(f,a.y,g);a.z=$l(f,a.z,g);}if(bool(b&16)){a.xyz*=a.w;}return"
-" a;}$pure half4 sk_color_space_transform(half4 a,int b,int c,half[7]d,half3x3"
-" e,int f,half[7]g){return sk_Caps.colorSpaceMathNeedsFloat?sk_color_space_transform_float"
-"(float4(a),b,c,d,e,f,g):sk_color_space_transform_half(a,b,c,d,e,f,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,float4x4 g,int h,sampler2D i){float2 j=fract(a-.5);a-=1.5;a=floor(a)"
-"+.5;float4 k=g*float4(1.,j.x,j.x*j.x,(j.x*j.x)*j.x);float4 l=g*float4(1.,j."
-"y,j.y*j.y,(j.y*j.y)*j.y);float4 m=float4(0.);for(int n=0;n<4;++n){float4 o="
-"float4(0.);for(int p=0;p<4;++p){o+=k[p]*float4($n(a+float2(float(p),float(n"
-")),b,c,d,e,0,h,i));}m+=l[n]*o;}return half4(m);}$pure half4 sk_image_shader"
-"(float2 a,float2 b,float4 c,int d,int e,int f,int g,float4x4 h,int i,int j,"
-"int k,half[7]l,half3x3 m,int n,half[7]o,sampler2D p){half4 q=g!=0?$o(a,b,c,"
-"d,e,h,i,p):$n(a,b,c,d,e,f,i,p);return sk_color_space_transform(q,j,k,l,m,n,"
-"o);}$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=clamp(b.x,0.,1.);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(sk_Caps"
-".mustDoOpBetweenFloorAndAbs){b.x=clamp(b.x,-1.,1.);}b.x=abs(b.x);break;}case"
-" 3:if(b.x<0.||b.x>1.){return float2(0.,-1.);}break;}return b;}$pure half4 $q"
-"(float4[4]a,float[4]b,float2 c){if(c.y<0.){return half4(0.);}else if(c.x<=b"
-"[0]){return half4(a[0]);}else if(c.x<b[1]){return half4(mix(a[0],a[1],(c.x-"
-"b[0])/(b[1]-b[0])));}else if(c.x<b[2]){return half4(mix(a[1],a[2],(c.x-b[1]"
-")/(b[2]-b[1])));}else if(c.x<b[3]){return half4(mix(a[2],a[3],(c.x-b[2])/(b"
-"[3]-b[2])));}else{return half4(a[3]);}}$pure half4 $r(float4[8]a,float[8]b,"
-"float2 c){if(c.y<0.){return half4(0.);}else if(c.x<b[4]){if(c.x<b[2]){if(c."
-"x<=b[0]){return half4(a[0]);}else if(c.x<b[1]){return half4(mix(a[0],a[1],("
-"c.x-b[0])/(b[1]-b[0])));}else{return half4(mix(a[1],a[2],(c.x-b[1])/(b[2]-b"
-"[1])));}}else{if(c.x<b[3]){return half4(mix(a[2],a[3],(c.x-b[2])/(b[3]-b[2]"
-")));}else{return half4(mix(a[3],a[4],(c.x-b[3])/(b[4]-b[3])));}}}else{if(c."
-"x<b[6]){if(c.x<b[5]){return half4(mix(a[4],a[5],(c.x-b[4])/(b[5]-b[4])));}else"
-"{return half4(mix(a[5],a[6],(c.x-b[5])/(b[6]-b[5])));}}else{if(c.x<b[7]){return"
-" half4(mix(a[6],a[7],(c.x-b[6])/(b[7]-b[6])));}else{return half4(a[7]);}}}}"
-"half4 $s(sampler2D a,int b,float2 c){if(c.y<0.){return half4(0.);}else if(c"
-".x==0.){return sampleLod(a,float2(0.,.25),0.);}else if(c.x==1.){return sampleLod"
-"(a,float2(1.,.25),0.);}else{int f=0;int g=b;for(int h=1;h<b;h<<=1){int i=(f"
-"+g)/2;float j=(float(i)+.5)/float(b);float2 k=float2(sampleLod(a,float2(j,.75"
-"),0.).xy);float l=ldexp(k.x,int(k.y));if(c.x<l){g=i;}else{f=i;}}float h=(float"
-"(f)+.5)/float(b);float i=(float(f+1)+.5)/float(b);half4 j=sampleLod(a,float2"
-"(h,.25),0.);half4 k=sampleLod(a,float2(i,.25),0.);float2 l=float2(sampleLod"
-"(a,float2(h,.75),0.).xy);float m=ldexp(l.x,int(l.y));l=float2(sampleLod(a,float2"
-"(i,.75),0.).xy);float n=ldexp(l.x,int(l.y));return half4(mix(float4(j),float4"
-"(k),(c.x-m)/(n-m)));}}$pure float2 $t(float2 a,float2 b,float2 c){c-=a;float2"
-" d=b-a;float e=dot(c,d)/dot(d,d);return float2(e,1.);}$pure float2 $u(float2"
-" a,float b,float2 c){float d=distance(c,a)/b;return float2(d,1.);}$pure float2"
-" $v(float2 a,float b,float c,float2 d){d-=a;float e=sk_Caps.atan2ImplementedAsAtanYOverX"
-"?2.*atan(-d.y,length(d)-d.x):atan(-d.y,-d.x);float f=((e*.159154937+.5)+b)*"
-"c;return float2(f,1.);}$pure float3x3 $w(float2 a,float2 b){return float3x3"
-"(0.,-1.,0.,1.,0.,0.,0.,0.,1.)*inverse(float3x3(b.y-a.y,a.x-b.x,0.,b.x-a.x,b"
-".y-a.y,0.,a.x,a.y,1.));}$pure float2 $x(float2 a,float2 b,float c,float d,float2"
-" e){const float f=.000244140625;float g=distance(a,b);float h=d-c;bool i=g<"
-"f;bool j=abs(h)<f;if(i){if(j){return float2(0.,-1.);}float k=1./h;float l=sign"
-"(h);float m=c/h;float2 n=(e-a)*k;float o=length(n)*l-m;return float2(o,1.);"
-"}else if(j){float3x3 k=$w(a,b);float l=c/g;float m=l*l;float2 n=(k*float3(e"
-",1.)).xy;float o=m-n.y*n.y;if(o<0.){return float2(0.,-1.);}o=n.x+sqrt(o);return"
-" float2(o,1.);}else{float k=c/(c-d);bool l=abs(k-1.)<f;if(l){float2 m=a;a=b"
-";b=m;k=0.;}float2 m=a*(1.-k)+b*k;float3x3 n=$w(m,b);float o=abs(1.-k);float"
-" p=o;float q=abs(d-c)/g;bool r=abs(q-1.)<f;if(r){o*=.5;p*=.5;}else{o*=q/(q*"
-"q-1.);p/=sqrt(abs(q*q-1.));}n=float3x3(o,0.,0.,0.,p,0.,0.,0.,1.)*n;float2 s"
-"=(n*float3(e,1.)).xy;float u=1./q;float v=sign(1.-k);bool w=!r&&q>1.;float x"
-"=-1.;if(r){x=dot(s,s)/s.x;}else if(w){x=length(s)-s.x*u;}else{float y=s.x*s"
-".x-s.y*s.y;if(y>=0.){if(l||v<0.){x=-sqrt(y)-s.x*u;}else{x=sqrt(y)-s.x*u;}}}"
-"if(!w&&x<0.){return float2(0.,-1.);}float y=k+v*x;if(l){y=1.-y;}return float2"
-"(y,1.);}}$pure half4 sk_linear_grad_4_shader(float2 a,float4[4]b,float[4]c,"
-"float2 d,float2 e,int f,int g,int h){float2 i=$t(d,e,a);i=$p(f,i);half4 j=$q"
-"(b,c,i);return $interpolated_to_rgb_unpremul(j,g,h);}$pure half4 sk_linear_grad_8_shader"
-"(float2 a,float4[8]b,float[8]c,float2 d,float2 e,int f,int g,int h){float2 i"
+":c=b.zyxw;break;}return c;}$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,float4x4 g,int h,"
+"sampler2D i){float2 j=fract(a-.5);a-=1.5;a=floor(a)+.5;float4 k=g*float4(1."
+",j.x,j.x*j.x,(j.x*j.x)*j.x);float4 l=g*float4(1.,j.y,j.y*j.y,(j.y*j.y)*j.y)"
+";float4 m=float4(0.);for(int n=0;n<4;++n){float4 o=float4(0.);for(int p=0;p"
+"<4;++p){o+=k[p]*float4($n(a+float2(float(p),float(n)),b,c,d,e,0,h,i));}m+=l"
+"[n]*o;}return half4(m);}$pure half4 sk_image_shader(float2 a,float2 b,float4"
+" c,int d,int e,int f,int g,float4x4 h,int i,int j,int k,half[7]l,half3x3 m,"
+"int n,half[7]o,sampler2D p){half4 q=g!=0?$o(a,b,c,d,e,h,i,p):$n(a,b,c,d,e,f"
+",i,p);return sk_color_space_transform(q,j,k,l,m,n,o);}$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=clamp(b.x,0.,1.);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(sk_Caps.mustDoOpBetweenFloorAndAbs){b.x="
+"clamp(b.x,-1.,1.);}b.x=abs(b.x);break;}case 3:if(b.x<0.||b.x>1.){return float2"
+"(0.,-1.);}break;}return b;}$pure half4 $q(float4[4]a,float[4]b,float2 c){if"
+"(c.y<0.){return half4(0.);}else if(c.x<=b[0]){return half4(a[0]);}else if(c"
+".x<b[1]){return half4(mix(a[0],a[1],(c.x-b[0])/(b[1]-b[0])));}else if(c.x<b"
+"[2]){return half4(mix(a[1],a[2],(c.x-b[1])/(b[2]-b[1])));}else if(c.x<b[3])"
+"{return half4(mix(a[2],a[3],(c.x-b[2])/(b[3]-b[2])));}else{return half4(a[3"
+"]);}}$pure half4 $r(float4[8]a,float[8]b,float2 c){if(c.y<0.){return half4("
+"0.);}else if(c.x<b[4]){if(c.x<b[2]){if(c.x<=b[0]){return half4(a[0]);}else if"
+"(c.x<b[1]){return half4(mix(a[0],a[1],(c.x-b[0])/(b[1]-b[0])));}else{return"
+" half4(mix(a[1],a[2],(c.x-b[1])/(b[2]-b[1])));}}else{if(c.x<b[3]){return half4"
+"(mix(a[2],a[3],(c.x-b[2])/(b[3]-b[2])));}else{return half4(mix(a[3],a[4],(c"
+".x-b[3])/(b[4]-b[3])));}}}else{if(c.x<b[6]){if(c.x<b[5]){return half4(mix(a"
+"[4],a[5],(c.x-b[4])/(b[5]-b[4])));}else{return half4(mix(a[5],a[6],(c.x-b[5"
+"])/(b[6]-b[5])));}}else{if(c.x<b[7]){return half4(mix(a[6],a[7],(c.x-b[6])/"
+"(b[7]-b[6])));}else{return half4(a[7]);}}}}half4 $s(sampler2D a,int b,float2"
+" c){if(c.y<0.){return half4(0.);}else if(c.x==0.){return sampleLod(a,float2"
+"(0.,.25),0.);}else if(c.x==1.){return sampleLod(a,float2(1.,.25),0.);}else{"
+"int f=0;int g=b;for(int h=1;h<b;h<<=1){int i=(f+g)/2;float j=(float(i)+.5)/"
+"float(b);float2 k=float2(sampleLod(a,float2(j,.75),0.).xy);float l=ldexp(k."
+"x,int(k.y));if(c.x<l){g=i;}else{f=i;}}float h=(float(f)+.5)/float(b);float i"
+"=(float(f+1)+.5)/float(b);half4 j=sampleLod(a,float2(h,.25),0.);half4 k=sampleLod"
+"(a,float2(i,.25),0.);float2 l=float2(sampleLod(a,float2(h,.75),0.).xy);float"
+" m=ldexp(l.x,int(l.y));l=float2(sampleLod(a,float2(i,.75),0.).xy);float n=ldexp"
+"(l.x,int(l.y));return half4(mix(float4(j),float4(k),(c.x-m)/(n-m)));}}$pure"
+" float2 $t(float2 a,float2 b,float2 c){c-=a;float2 d=b-a;float e=dot(c,d)/dot"
+"(d,d);return float2(e,1.);}$pure float2 $u(float2 a,float b,float2 c){float"
+" d=distance(c,a)/b;return float2(d,1.);}$pure float2 $v(float2 a,float b,float"
+" c,float2 d){d-=a;float e=sk_Caps.atan2ImplementedAsAtanYOverX?2.*atan(-d.y"
+",length(d)-d.x):atan(-d.y,-d.x);float f=((e*.159154937+.5)+b)*c;return float2"
+"(f,1.);}$pure float3x3 $w(float2 a,float2 b){return float3x3(0.,-1.,0.,1.,0."
+",0.,0.,0.,1.)*inverse(float3x3(b.y-a.y,a.x-b.x,0.,b.x-a.x,b.y-a.y,0.,a.x,a."
+"y,1.));}$pure float2 $x(float2 a,float2 b,float c,float d,float2 e){const float"
+" f=.000244140625;float g=distance(a,b);float h=d-c;bool i=g<f;bool j=abs(h)"
+"<f;if(i){if(j){return float2(0.,-1.);}float k=1./h;float l=sign(h);float m="
+"c/h;float2 n=(e-a)*k;float o=length(n)*l-m;return float2(o,1.);}else if(j){"
+"float3x3 k=$w(a,b);float l=c/g;float m=l*l;float2 n=(k*float3(e,1.)).xy;float"
+" o=m-n.y*n.y;if(o<0.){return float2(0.,-1.);}o=n.x+sqrt(o);return float2(o,"
+"1.);}else{float k=c/(c-d);bool l=abs(k-1.)<f;if(l){float2 m=a;a=b;b=m;k=0.;"
+"}float2 m=a*(1.-k)+b*k;float3x3 n=$w(m,b);float o=abs(1.-k);float p=o;float"
+" q=abs(d-c)/g;bool r=abs(q-1.)<f;if(r){o*=.5;p*=.5;}else{o*=q/(q*q-1.);p/=sqrt"
+"(abs(q*q-1.));}n=float3x3(o,0.,0.,0.,p,0.,0.,0.,1.)*n;float2 s=(n*float3(e,"
+"1.)).xy;float u=1./q;float v=sign(1.-k);bool w=!r&&q>1.;float x=-1.;if(r){x"
+"=dot(s,s)/s.x;}else if(w){x=length(s)-s.x*u;}else{float y=s.x*s.x-s.y*s.y;if"
+"(y>=0.){if(l||v<0.){x=-sqrt(y)-s.x*u;}else{x=sqrt(y)-s.x*u;}}}if(!w&&x<0.){"
+"return float2(0.,-1.);}float y=k+v*x;if(l){y=1.-y;}return float2(y,1.);}}$pure"
+" half4 sk_linear_grad_4_shader(float2 a,float4[4]b,float[4]c,float2 d,float2"
+" e,int f,int g,int h){float2 i=$t(d,e,a);i=$p(f,i);half4 j=$q(b,c,i);return"
+" $interpolated_to_rgb_unpremul(j,g,h);}$pure half4 sk_linear_grad_8_shader("
+"float2 a,float4[8]b,float[8]c,float2 d,float2 e,int f,int g,int h){float2 i"
"=$t(d,e,a);i=$p(f,i);half4 j=$r(b,c,i);return $interpolated_to_rgb_unpremul"
"(j,g,h);}$pure half4 sk_linear_grad_tex_shader(float2 a,float2 b,float2 c,int"
" d,int e,int f,int g,sampler2D h){float2 i=$t(b,c,a);i=$p(e,i);half4 j=$s(h"
diff --git a/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl b/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl
index 388c429..f0afab3 100644
--- a/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl
+++ b/src/sksl/generated/sksl_graphite_frag.unoptimized.sksl
@@ -13,74 +13,60 @@
"){half4 resultantColor=color;switch(swizzleType){case 0:break;case 1:resultantColor"
"=half4(color.xyz,1.);break;case 2:resultantColor=color.xxxx;break;case 3:resultantColor"
"=half4(color.xxx,1.);break;case 4:resultantColor=color.zyxw;break;}return resultantColor"
-";}$pure half $apply_xfer_fn(int kind,half x,half[7]cs){half G=cs[0];half A="
-"cs[1];half B=cs[2];half C=cs[3];half D=cs[4];half E=cs[5];half F=cs[6];half"
-" 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_float(float4"
-" color,int flags,int srcKind,half[7]srcCoeffs,half3x3 gamutTransform,int dstKind"
-",half[7]dstCoeffs){if(bool(flags&$kColorSpaceXformFlagUnpremul)){color=unpremul"
-"(color);}if(bool(flags&$kColorSpaceXformFlagLinearize)){color.x=float($apply_xfer_fn"
-"(srcKind,half(color.x),srcCoeffs));color.y=float($apply_xfer_fn(srcKind,half"
-"(color.y),srcCoeffs));color.z=float($apply_xfer_fn(srcKind,half(color.z),srcCoeffs"
-"));}if(bool(flags&$kColorSpaceXformFlagGamutTransform)){color.xyz=float3x3("
-"gamutTransform)*color.xyz;}if(bool(flags&$kColorSpaceXformFlagEncode)){color"
-".x=float($apply_xfer_fn(dstKind,half(color.x),dstCoeffs));color.y=float($apply_xfer_fn"
-"(dstKind,half(color.y),dstCoeffs));color.z=float($apply_xfer_fn(dstKind,half"
-"(color.z),dstCoeffs));}if(bool(flags&$kColorSpaceXformFlagPremul)){color.xyz"
-"*=color.w;}return half4(color);}$pure half4 sk_color_space_transform_half(half4"
-" color,int flags,int srcKind,half[7]srcCoeffs,half3x3 gamutTransform,int dstKind"
-",half[7]dstCoeffs){if(bool(flags&$kColorSpaceXformFlagUnpremul)){color=unpremul"
-"(color);}if(bool(flags&$kColorSpaceXformFlagLinearize)){color.x=$apply_xfer_fn"
+";}$pure float $apply_xfer_fn(int kind,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=gamutTransform*color.xyz;}if(bool(flags&$kColorSpaceXformFlagEncode"
+")){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 color"
-";}$pure half4 sk_color_space_transform(half4 color,int flags,int srcKind,half"
-"[7]srcCoeffs,half3x3 gamutTransform,int dstKind,half[7]dstCoeffs){return sk_Caps"
-".colorSpaceMathNeedsFloat?sk_color_space_transform_float(float4(color),flags"
-",srcKind,srcCoeffs,gamutTransform,dstKind,dstCoeffs):sk_color_space_transform_half"
-"(color,flags,srcKind,srcCoeffs,gamutTransform,dstKind,dstCoeffs);}$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){float extraCoordX;float extraCoordY;half4 extraColorX"
-";half4 extraColorY;if(sampleExtraX){extraCoordX=error.x>0.?insetClamp.x:insetClamp"
-".z;extraColorX=sample(s,float2(extraCoordX,clampedPos.y)/imgSize);extraColorX"
-"=$apply_swizzle(readSwizzle,extraColorX);}if(sampleExtraY){extraCoordY=error"
-".y>0.?insetClamp.y:insetClamp.w;extraColorY=sample(s,float2(clampedPos.x,extraCoordY"
-")/imgSize);extraColorY=$apply_swizzle(readSwizzle,extraColorY);}if(sampleExtraX"
-"&&sampleExtraY){half4 extraColorXY=sample(s,float2(extraCoordX,extraCoordY)"
-"/imgSize);extraColorXY=$apply_swizzle(readSwizzle,extraColorXY);color=mix(mix"
-"(color,extraColorX,absError.x),mix(extraColorY,extraColorXY,absError.x),absError"
-".y);}else if(sampleExtraX){color=mix(color,extraColorX,absError.x);}else if"
-"(sampleExtraY){color=mix(color,extraColorY,absError.y);}}if(tileModeX==$kTileModeDecal"
-"){color*=max(1.-absError.x,0.);}if(tileModeY==$kTileModeDecal){color*=max(1."
-"-absError.y,0.);}}return color;}$pure half4 $cubic_filter_image(float2 pos,"
-"float2 imgSize,float4 subset,int tileModeX,int tileModeY,float4x4 coeffs,int"
-" readSwizzle,sampler2D s){float2 f=fract(pos-.5);pos-=1.5;pos=floor(pos)+.5"
-";float4 wx=coeffs*float4(1.,f.x,f.x*f.x,(f.x*f.x)*f.x);float4 wy=coeffs*float4"
-"(1.,f.y,f.y*f.y,(f.y*f.y)*f.y);float4 color=float4(0.);for(int y=0;y<4;++y)"
-"{float4 rowColor=float4(0.);for(int x=0;x<4;++x){rowColor+=wx[x]*float4($sample_image"
-"(pos+float2(float(x),float(y)),imgSize,subset,tileModeX,tileModeY,$kFilterModeNearest"
-",readSwizzle,s));}color+=wy[y]*rowColor;}return half4(color);}$pure half4 sk_image_shader"
+");}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"
+"){float extraCoordX;float extraCoordY;half4 extraColorX;half4 extraColorY;if"
+"(sampleExtraX){extraCoordX=error.x>0.?insetClamp.x:insetClamp.z;extraColorX"
+"=sample(s,float2(extraCoordX,clampedPos.y)/imgSize);extraColorX=$apply_swizzle"
+"(readSwizzle,extraColorX);}if(sampleExtraY){extraCoordY=error.y>0.?insetClamp"
+".y:insetClamp.w;extraColorY=sample(s,float2(clampedPos.x,extraCoordY)/imgSize"
+");extraColorY=$apply_swizzle(readSwizzle,extraColorY);}if(sampleExtraX&&sampleExtraY"
+"){half4 extraColorXY=sample(s,float2(extraCoordX,extraCoordY)/imgSize);extraColorXY"
+"=$apply_swizzle(readSwizzle,extraColorXY);color=mix(mix(color,extraColorX,absError"
+".x),mix(extraColorY,extraColorXY,absError.x),absError.y);}else if(sampleExtraX"
+"){color=mix(color,extraColorX,absError.x);}else if(sampleExtraY){color=mix("
+"color,extraColorY,absError.y);}}if(tileModeX==$kTileModeDecal){color*=max(1."
+"-absError.x,0.);}if(tileModeY==$kTileModeDecal){color*=max(1.-absError.y,0."
+");}}return color;}$pure half4 $cubic_filter_image(float2 pos,float2 imgSize"
+",float4 subset,int tileModeX,int tileModeY,float4x4 coeffs,int readSwizzle,"
+"sampler2D s){float2 f=fract(pos-.5);pos-=1.5;pos=floor(pos)+.5;float4 wx=coeffs"
+"*float4(1.,f.x,f.x*f.x,(f.x*f.x)*f.x);float4 wy=coeffs*float4(1.,f.y,f.y*f."
+"y,(f.y*f.y)*f.y);float4 color=float4(0.);for(int y=0;y<4;++y){float4 rowColor"
+"=float4(0.);for(int x=0;x<4;++x){rowColor+=wx[x]*float4($sample_image(pos+float2"
+"(float(x),float(y)),imgSize,subset,tileModeX,tileModeY,$kFilterModeNearest,"
+"readSwizzle,s));}color+=wy[y]*rowColor;}return half4(color);}$pure half4 sk_image_shader"
"(float2 coords,float2 imgSize,float4 subset,int tileModeX,int tileModeY,int"
" filterMode,int useCubic,float4x4 cubicCoeffs,int readSwizzle,int csXformFlags"
",int csXformSrcKind,half[7]csXformSrcCoeffs,half3x3 csXformGamutTransform,int"
diff --git a/src/sksl/ir/SkSLSetting.cpp b/src/sksl/ir/SkSLSetting.cpp
index f3e7187..9b84969 100644
--- a/src/sksl/ir/SkSLSetting.cpp
+++ b/src/sksl/ir/SkSLSetting.cpp
@@ -42,8 +42,6 @@
&ShaderCaps::fBuiltinDeterminantSupport),
CapsLookupTable::Pair("rewriteMatrixVectorMultiply",
&ShaderCaps::fRewriteMatrixVectorMultiply),
- CapsLookupTable::Pair("colorSpaceMathNeedsFloat",
- &ShaderCaps::fColorSpaceMathNeedsFloat),
CapsLookupTable::Pair("PerlinNoiseRoundingFix",
&ShaderCaps::fPerlinNoiseRoundingFix),
});
diff --git a/src/sksl/sksl_graphite_frag.sksl b/src/sksl/sksl_graphite_frag.sksl
index 0c731af..930a747 100644
--- a/src/sksl/sksl_graphite_frag.sksl
+++ b/src/sksl/sksl_graphite_frag.sksl
@@ -58,9 +58,9 @@
return resultantColor;
}
-$pure half $apply_xfer_fn(int kind, half x, half cs[7]) {
- half G = cs[0], A = cs[1], B = cs[2], C = cs[3], D = cs[4], E = cs[5], F = cs[6];
- half s = sign(x);
+$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) {
case $kTFTypeSRGB:
@@ -84,48 +84,15 @@
return s * x;
}
-// Some GPUs require full float to get results that are as accurate as expected/required.
-// Most GPUs work just fine with half float. Strangely, the GPUs that have this bug
-// (Mali G series) only require us to promote the type of a few temporaries here --
-// the helper functions can always be written to use half.
-$pure half4 sk_color_space_transform_float(float4 color,
- int flags,
- int srcKind,
- half srcCoeffs[7],
- half3x3 gamutTransform,
- int dstKind,
- half dstCoeffs[7]) {
- if (bool(flags & $kColorSpaceXformFlagUnpremul)) {
- color = unpremul(color);
- }
+$pure half4 sk_color_space_transform(half4 halfColor,
+ int flags,
+ int srcKind,
+ half srcCoeffs[7],
+ half3x3 gamutTransform,
+ int dstKind,
+ half dstCoeffs[7]) {
+ float4 color = float4(halfColor);
- if (bool(flags & $kColorSpaceXformFlagLinearize)) {
- color.r = $apply_xfer_fn(srcKind, half(color.r), srcCoeffs);
- color.g = $apply_xfer_fn(srcKind, half(color.g), srcCoeffs);
- color.b = $apply_xfer_fn(srcKind, half(color.b), srcCoeffs);
- }
- if (bool(flags & $kColorSpaceXformFlagGamutTransform)) {
- color.rgb = gamutTransform * color.rgb;
- }
- if (bool(flags & $kColorSpaceXformFlagEncode)) {
- color.r = $apply_xfer_fn(dstKind, half(color.r), dstCoeffs);
- color.g = $apply_xfer_fn(dstKind, half(color.g), dstCoeffs);
- color.b = $apply_xfer_fn(dstKind, half(color.b), dstCoeffs);
- }
-
- if (bool(flags & $kColorSpaceXformFlagPremul)) {
- color.rgb *= color.a;
- }
- return half4(color);
-}
-
-$pure half4 sk_color_space_transform_half(half4 color,
- int flags,
- int srcKind,
- half srcCoeffs[7],
- half3x3 gamutTransform,
- int dstKind,
- half dstCoeffs[7]) {
if (bool(flags & $kColorSpaceXformFlagUnpremul)) {
color = unpremul(color);
}
@@ -147,21 +114,7 @@
if (bool(flags & $kColorSpaceXformFlagPremul)) {
color.rgb *= color.a;
}
- return color;
-}
-
-$pure half4 sk_color_space_transform(half4 color,
- int flags,
- int srcKind,
- half srcCoeffs[7],
- half3x3 gamutTransform,
- int dstKind,
- half dstCoeffs[7]) {
- return sk_Caps.colorSpaceMathNeedsFloat
- ? sk_color_space_transform_float(float4(color), flags, srcKind, srcCoeffs,
- gamutTransform, dstKind, dstCoeffs)
- : sk_color_space_transform_half(color, flags, srcKind, srcCoeffs,
- gamutTransform, dstKind, dstCoeffs);
+ return half4(color);
}
$pure float $tile(int tileMode, float f, float low, float high) {