Reland "SkSL is now pickier about type conversions"

This is a reland of 91c1d08bc3

Original change's description:
> SkSL is now pickier about type conversions
> 
> Bug: skia:
> Change-Id: I4e8b8f229f4e4344f160b0dbb41832764d0b75bd
> Reviewed-on: https://skia-review.googlesource.com/c/188311
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>

Bug: skia:
Change-Id: I727cad061afc0a5ee6f4d2df789330d809dd110a
Reviewed-on: https://skia-review.googlesource.com/c/189643
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2019-02-05 17:17:40 -05:00 committed by Skia Commit-Bot
parent 70df231b74
commit e1f5502969
81 changed files with 646 additions and 546 deletions

View File

@ -73,7 +73,7 @@ class GLSLClockwiseTestProcessor : public GrGLSLGeometryProcessor {
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
} else {
// Verify layout(origin_upper_left) on gl_FragCoord does not affect gl_FrontFacing.
args.fFragBuilder->codeAppendf("%s = half4(min(sk_FragCoord.y, 1));",
args.fFragBuilder->codeAppendf("%s = half4(min(half(sk_FragCoord.y), 1));",
args.fOutputCoverage);
}
}

View File

@ -85,10 +85,10 @@ class FwidthSquircleTestProcessor::Impl : public GrGLSLGeometryProcessor {
squircleCoord.fsIn(), squircleCoord.fsIn());
// Squircle function!
f->codeAppendf("float fn = pow(x, golden_ratio*pi) + pow(y, golden_ratio*pi) - 1;");
f->codeAppendf("float fn = half(pow(x, golden_ratio*pi) + pow(y, golden_ratio*pi) - 1);");
f->codeAppendf("float fnwidth = fwidth(fn);");
f->codeAppendf("fnwidth += 1e-10;"); // Guard against divide-by-zero.
f->codeAppendf("half coverage = clamp(.5 - fn/fnwidth, 0, 1);");
f->codeAppendf("half coverage = clamp(half(.5 - fn/fnwidth), 0, 1);");
f->codeAppendf("%s = half4(.51, .42, .71, 1) * .89;", args.fOutputColor);
f->codeAppendf("%s = half4(coverage);", args.fOutputCoverage);

View File

@ -35,7 +35,7 @@ private:
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("%s = float4(0, 0, 1, 0);", args.fOutputColor);
fragBuilder->codeAppendf("%s = half4(0, 0, 1, 0);", args.fOutputColor);
}
private:

View File

@ -56,7 +56,7 @@ private:
// If there's no x & y components, return (0, 0, +/- 1) instead to avoid division by 0
fragBuilder->codeAppend( "if (abs(normal.z) > 0.999) {");
fragBuilder->codeAppendf(" %s = normalize(float4(0.0, 0.0, normal.z, 0.0));",
fragBuilder->codeAppendf(" %s = normalize(half4(0.0, 0.0, half(normal.z), 0.0));",
args.fOutputColor);
// Else, Normalizing the transformed X and Y, while keeping constant both Z and the
// vector's angle in the XY plane. This maintains the "slope" for the surface while
@ -70,8 +70,9 @@ private:
"( (transformed.x * transformed.x) "
"+ (transformed.y * transformed.y) )"
"/(1.0 - (normal.z * normal.z));");
fragBuilder->codeAppendf(" %s = float4(transformed*inversesqrt(scalingFactorSquared),"
"normal.z, 0.0);",
fragBuilder->codeAppendf(" %s = half4(half2(transformed * "
"inversesqrt(scalingFactorSquared)),"
"half(normal.z), 0.0);",
args.fOutputColor);
fragBuilder->codeAppend( "}");
}

View File

@ -31,7 +31,7 @@
#include "glsl/GrGLSLUniformHandler.h"
GR_FP_SRC_STRING SKSL_ARITHMETIC_SRC = R"(
in uniform float4 k;
in uniform half4 k;
layout(key) const in bool enforcePMColor;
in fragmentProcessor child;

View File

@ -2043,7 +2043,7 @@ void GrGLSpecularLightingEffect::emitLightFunc(GrGLSLUniformHandler* uniformHand
};
SkString lightBody;
lightBody.appendf("\thalf3 halfDir = half3(normalize(surfaceToLight + half3(0, 0, 1)));\n");
lightBody.appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n",
lightBody.appendf("\thalf colorScale = half(%s * pow(dot(normal, halfDir), %s));\n",
ks, shininess);
lightBody.appendf("\thalf3 color = lightColor * saturate(colorScale);\n");
lightBody.appendf("\treturn half4(color, max(max(color.r, color.g), color.b));\n");

View File

@ -71,7 +71,7 @@ void main(int x, int y, inout half4 color) {
} else {
// Simulate the integer effect used above using step/mod. For speed, simulates a 4x4
// dither pattern rather than an 8x8 one.
half4 modValues = mod(float4(x, y, x, y), half4(2.0, 2.0, 4.0, 4.0));
half4 modValues = mod(half4(x, y, x, y), half4(2.0, 2.0, 4.0, 4.0));
half4 stepValues = step(modValues, half4(1.0, 1.0, 2.0, 2.0));
value = dot(stepValues, half4(8.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0)) - 15.0 / 32.0;
}

View File

@ -74,10 +74,10 @@ void GrCCConicShader::onEmitFragmentCode(GrGLSLFPFragmentBuilder* f,
const char* outputCoverage) const {
this->calcHullCoverage(&AccessCodeString(f), fKLM_fWind.fsIn(), fGrad_fCorner.fsIn(),
outputCoverage);
f->codeAppendf("%s *= %s.w;", outputCoverage, fKLM_fWind.fsIn()); // Wind.
f->codeAppendf("%s *= half(%s.w);", outputCoverage, fKLM_fWind.fsIn()); // Wind.
if (kFloat4_GrSLType == fGrad_fCorner.type()) {
f->codeAppendf("%s = %s.z * %s.w + %s;", // Attenuated corner coverage.
f->codeAppendf("%s = fma(half(%s.z), half(%s.w), %s);", // Attenuated corner coverage.
outputCoverage, fGrad_fCorner.fsIn(), fGrad_fCorner.fsIn(),
outputCoverage);
}
@ -88,7 +88,9 @@ void GrCCConicShader::calcHullCoverage(SkString* code, const char* klm, const ch
code->appendf("float k = %s.x, l = %s.y, m = %s.z;", klm, klm, klm);
code->append ("float f = k*k - l*m;");
code->appendf("float fwidth = abs(%s.x) + abs(%s.y);", grad, grad);
code->appendf("%s = min(0.5 - f/fwidth, 1);", outputCoverage); // Curve coverage.
code->append ("half d = min(k - 0.5, 0);"); // K doubles as the flat opposite edge's AA.
code->appendf("%s = max(%s + d, 0);", outputCoverage, outputCoverage); // Total hull coverage.
code->appendf("float curve_coverage = min(0.5 - f/fwidth, 1);");
// K doubles as the flat opposite edge's AA.
code->append ("float edge_coverage = min(k - 0.5, 0);");
// Total hull coverage.
code->appendf("%s = max(half(curve_coverage + edge_coverage), 0);", outputCoverage);
}

View File

@ -66,11 +66,12 @@ void GrCCCoverageProcessor::Shader::CalcWind(const GrCCCoverageProcessor& proc,
// if the max effect it can have on any single pixel is <~ 1/1024, or 1/4 of a bit in 8888.
s->codeAppend ("float2 bbox_size = max(abs(a), abs(b));");
s->codeAppend ("float basewidth = max(bbox_size.x + bbox_size.y, 1);");
s->codeAppendf("%s = (abs(area_x2 * 1024) > basewidth) ? sign(area_x2) : 0;", outputWind);
s->codeAppendf("%s = (abs(area_x2 * 1024) > basewidth) ? sign(half(area_x2)) : 0;",
outputWind);
} else {
// We already converted nearly-flat curves to lines on the CPU, so no need to worry about
// thin curve hulls at this point.
s->codeAppendf("%s = sign(area_x2);", outputWind);
s->codeAppendf("%s = sign(half(area_x2));", outputWind);
}
}
@ -119,7 +120,8 @@ void GrCCCoverageProcessor::Shader::CalcEdgeCoverageAtBloatVertex(GrGLSLVertexGe
s->codeAppendf("float t = dot(%s, n);", rasterVertexDir);
// The below conditional guarantees we get exactly 1 on the divide when nwidth=t (in case the
// GPU divides by multiplying by the reciprocal?) It also guards against NaN when nwidth=0.
s->codeAppendf("%s = (abs(t) != nwidth ? t / nwidth : sign(t)) * -.5 - .5;", outputCoverage);
s->codeAppendf("%s = half(abs(t) != nwidth ? t / nwidth : sign(t)) * -.5 - .5;",
outputCoverage);
}
void GrCCCoverageProcessor::Shader::CalcEdgeCoveragesAtBloatVertices(GrGLSLVertexGeoBuilder* s,
@ -134,7 +136,7 @@ void GrCCCoverageProcessor::Shader::CalcEdgeCoveragesAtBloatVertices(GrGLSLVerte
s->codeAppend ("float nwidth = abs(n.x) + abs(n.y);");
s->codeAppendf("float2 t = n * float2x2(%s, %s);", bloatDir1, bloatDir2);
s->codeAppendf("for (int i = 0; i < 2; ++i) {");
s->codeAppendf( "%s[i] = (abs(t[i]) != nwidth ? t[i] / nwidth : sign(t[i])) * -.5 - .5;",
s->codeAppendf( "%s[i] = half(abs(t[i]) != nwidth ? t[i] / nwidth : sign(t[i])) * -.5 - .5;",
outputCoverages);
s->codeAppendf("}");
}
@ -147,13 +149,14 @@ void GrCCCoverageProcessor::Shader::CalcCornerAttenuation(GrGLSLVertexGeoBuilder
//
// NOTE: leftDir and rightDir are normalized and point in the same direction the path was
// defined with, i.e., leftDir points into the corner and rightDir points away from the corner.
s->codeAppendf("half obtuseness = max(dot(%s, %s), 0);", leftDir, rightDir);
s->codeAppendf("half obtuseness = max(half(dot(%s, %s)), 0);", leftDir, rightDir);
// axis_alignedness = 1 - tan(angle_to_nearest_axis_from_corner_bisector)
// (i.e., 1 when the corner bisector is aligned with the x- or y-axis
// 0 when the corner bisector falls on a 45 degree angle
// 0..1 when the corner bisector falls somewhere in between
s->codeAppendf("half2 abs_bisect_maybe_transpose = abs((0 == obtuseness) ? %s - %s : %s + %s);",
s->codeAppendf("half2 abs_bisect_maybe_transpose = abs((0 == obtuseness) ? half2(%s - %s) : "
"half2(%s + %s));",
leftDir, rightDir, leftDir, rightDir);
s->codeAppend ("half axis_alignedness = "
"1 - min(abs_bisect_maybe_transpose.y, abs_bisect_maybe_transpose.x) / "

View File

@ -62,7 +62,7 @@ protected:
if (PrimitiveType::kWeightedTriangles == proc.fPrimitiveType) {
SkASSERT(3 == numInputPoints);
SkASSERT(kFloat4_GrVertexAttribType == proc.fVertexAttribute.cpuType());
g->codeAppendf("%s *= sk_in[0].sk_Position.w;", wind.c_str());
g->codeAppendf("%s *= half(sk_in[0].sk_Position.w);", wind.c_str());
}
SkString emitVertexFn;

View File

@ -268,7 +268,8 @@ void GrCCCoverageProcessor::VSImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs)
SkASSERT(3 == numInputPoints);
SkASSERT(kFloat4_GrVertexAttribType ==
proc.fInstanceAttributes[kInstanceAttribIdx_X].cpuType());
v->codeAppendf("wind *= %s.w;", proc.fInstanceAttributes[kInstanceAttribIdx_X].name());
v->codeAppendf("wind *= half(%s.w);",
proc.fInstanceAttributes[kInstanceAttribIdx_X].name());
}
float bloat = kAABloatRadius;

View File

@ -128,7 +128,7 @@ void GrCCCubicShader::onEmitFragmentCode(GrGLSLFPFragmentBuilder* f,
// Wind is the sign of both L and/or M. Take the sign of whichever has the larger magnitude.
// (In reality, either would be fine because we chop cubics with more than a half pixel of
// padding around the L & M lines, so neither should approach zero.)
f->codeAppend ("half wind = sign(l + m);");
f->codeAppend ("half wind = sign(half(l + m));");
f->codeAppendf("%s *= wind;", outputCoverage);
if (fCornerCoverage.fsIn()) {
@ -144,7 +144,9 @@ void GrCCCubicShader::calcHullCoverage(SkString* code, const char* klmAndEdge,
code->append ("float f = k*k*k - l*m;");
code->appendf("float2 grad = %s.xy * k + %s.zw;", gradMatrix, gradMatrix);
code->append ("float fwidth = abs(grad.x) + abs(grad.y);");
code->appendf("%s = min(0.5 - f/fwidth, 1);", outputCoverage); // Curve coverage.
code->appendf("half d = min(%s.w, 0);", klmAndEdge); // Flat edge opposite the curve.
code->appendf("%s = max(%s + d, 0);", outputCoverage, outputCoverage); // Total hull coverage.
code->appendf("float curve_coverage = min(0.5 - f/fwidth, 1);");
// Flat edge opposite the curve.
code->appendf("float edge_coverage = min(%s.w, 0);", klmAndEdge);
// Total hull coverage.
code->appendf("%s = max(half(curve_coverage + edge_coverage), 0);", outputCoverage);
}

View File

@ -198,8 +198,9 @@ void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// NOTE: If we were just drawing a rect, ceil/floor would be enough. But since there are also
// diagonals in the octagon that cross through pixel centers, we need to outset by another
// quarter px to ensure those pixels get rasterized.
v->codeAppend ("float2 bloatdir = (0 != N[0].x) "
"? half2(N[0].x, N[1].y) : half2(N[1].x, N[0].y);");
v->codeAppend ("half2 bloatdir = (0 != N[0].x) "
"? half2(half(N[0].x), half(N[1].y))"
": half2(half(N[1].x), half(N[0].y));");
v->codeAppend ("octocoord = (ceil(octocoord * bloatdir - 1e-4) + 0.25) * bloatdir;");
gpArgs->fPositionVar.set(kFloat2_GrSLType, "octocoord");
@ -232,7 +233,7 @@ void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// Scale coverage count by .5. Make it negative for even-odd paths and positive for winding
// ones. Clamp winding coverage counts at 1.0 (i.e. min(coverage/2, .5)).
f->codeAppendf("coverage = min(abs(coverage) * %s.z, .5);", texcoord.fsIn());
f->codeAppendf("coverage = min(abs(coverage) * half(%s.z), .5);", texcoord.fsIn());
// For negative values, this finishes the even-odd sawtooth function. Since positive (winding)
// values were clamped at "coverage/2 = .5", this only undoes the previous multiply by .5.

View File

@ -69,10 +69,10 @@ void GrCCQuadraticShader::onEmitFragmentCode(GrGLSLFPFragmentBuilder* f,
this->calcHullCoverage(&AccessCodeString(f), fCoord_fGrad.fsIn(),
SkStringPrintf("%s.x", fEdge_fWind_fCorner.fsIn()).c_str(),
outputCoverage);
f->codeAppendf("%s *= %s.y;", outputCoverage, fEdge_fWind_fCorner.fsIn()); // Wind.
f->codeAppendf("%s *= half(%s.y);", outputCoverage, fEdge_fWind_fCorner.fsIn()); // Wind.
if (kFloat4_GrSLType == fEdge_fWind_fCorner.type()) {
f->codeAppendf("%s = %s.z * %s.w + %s;",// Attenuated corner coverage.
f->codeAppendf("%s = half(%s.z * %s.w) + %s;",// Attenuated corner coverage.
outputCoverage, fEdge_fWind_fCorner.fsIn(), fEdge_fWind_fCorner.fsIn(),
outputCoverage);
}
@ -84,7 +84,9 @@ void GrCCQuadraticShader::calcHullCoverage(SkString* code, const char* coordAndG
code->appendf("float2 grad = %s.zw;", coordAndGrad);
code->append ("float f = x*x - y;");
code->append ("float fwidth = abs(grad.x) + abs(grad.y);");
code->appendf("%s = min(0.5 - f/fwidth, 1);", outputCoverage); // Curve coverage.
code->appendf("half d = min(%s, 0);", edge); // Flat edge opposite the curve.
code->appendf("%s = max(%s + d, 0);", outputCoverage, outputCoverage); // Total hull coverage.
code->appendf("float curve_coverage = min(0.5 - f/fwidth, 1);");
// Flat edge opposite the curve.
code->appendf("float edge_coverage = min(%s, 0);", edge);
// Total hull coverage.
code->appendf("%s = max(half(curve_coverage + edge_coverage), 0);", outputCoverage);
}

View File

@ -138,7 +138,7 @@ void LinearStrokeProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// Use the 4 edge distances to calculate coverage in the fragment shader.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
f->codeAppendf("half2 coverages = min(%s.xy, .5) + min(%s.zw, .5);",
f->codeAppendf("half2 coverages = half2(min(%s.xy, .5) + min(%s.zw, .5));",
edgeDistances.fsIn(), edgeDistances.fsIn());
f->codeAppendf("%s = half4(coverages.x * coverages.y);", args.fOutputColor);
@ -260,9 +260,9 @@ void CubicStrokeProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// Use the 2 edge distances and interpolated butt cap AA to calculate fragment coverage.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
f->codeAppendf("half2 edge_coverages = min(%s.xy, .5);", coverages.fsIn());
f->codeAppendf("half2 edge_coverages = min(half2(%s.xy), .5);", coverages.fsIn());
f->codeAppend ("half coverage = edge_coverages.x + edge_coverages.y;");
f->codeAppendf("coverage *= %s.z;", coverages.fsIn()); // Butt cap AA.
f->codeAppendf("coverage *= half(%s.z);", coverages.fsIn()); // Butt cap AA.
// As is common for CCPR, clockwise-winding triangles from the strip emit positive coverage, and
// counter-clockwise triangles emit negative.

View File

@ -33,10 +33,10 @@ public:
"float4 prevRect = float4(%f, %f, %f, %f);\nhalf alpha;\n@switch (%d) {\n case "
"0:\n case 2:\n alpha = half(all(greaterThan(float4(sk_FragCoord.xy, "
"%s.zw), float4(%s.xy, sk_FragCoord.xy))) ? 1 : 0);\n break;\n "
"default:\n half xSub, ySub;\n xSub = half(min(sk_FragCoord.x - "
"%s.x, 0.0));\n xSub += half(min(%s.z - sk_FragCoord.x, 0.0));\n "
"ySub = half(min(sk_FragCoord.y - %s.y, 0.0));\n ySub += half(min(%s.w - "
"sk_FragCoord.y, 0.0));\n alpha = half((1",
"default:\n half xSub, ySub;\n xSub = min(half(sk_FragCoord.x - "
"%s.x), 0.0);\n xSub += min(half(%s.z - sk_FragCoord.x), 0.0);\n "
"ySub = min(half(sk_FragCoord.y - %s.y), 0.0);\n ySub += min(half(%s.w - "
"sk_FragCoord.y), 0.0);\n alpha = (1.0 + ",
prevRect.left(),
prevRect.top(),
prevRect.right(),
@ -49,8 +49,8 @@ public:
args.fUniformHandler->getUniformCStr(fRectUniformVar),
args.fUniformHandler->getUniformCStr(fRectUniformVar));
fragBuilder->codeAppendf(
".0 + max(float(xSub), -1.0)) * (1.0 + max(float(ySub), -1.0)));\n}\n@if (%d == 2 "
"|| %d == 3) {\n alpha = half(1.0 - float(alpha));\n}\n%s = %s * alpha;\n",
"max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n}\n@if (%d == 2 || %d == 3) {\n "
"alpha = 1.0 - alpha;\n}\n%s = %s * alpha;\n",
(int)_outer.edgeType(),
(int)_outer.edgeType(),
args.fOutputColor,

View File

@ -25,10 +25,10 @@ void main() {
// The amount of coverage removed in x and y by the edges is computed as a pair of
// negative numbers, xSub and ySub.
half xSub, ySub;
xSub = min(sk_FragCoord.x - rectUniform.x, 0.0);
xSub += min(rectUniform.z - sk_FragCoord.x, 0.0);
ySub = min(sk_FragCoord.y - rectUniform.y, 0.0);
ySub += min(rectUniform.w - sk_FragCoord.y, 0.0);
xSub = min(half(sk_FragCoord.x - rectUniform.x), 0.0);
xSub += min(half(rectUniform.z - sk_FragCoord.x), 0.0);
ySub = min(half(sk_FragCoord.y - rectUniform.y), 0.0);
ySub += min(half(rectUniform.w - sk_FragCoord.y), 0.0);
// Now compute coverage in x and y and multiply them to get the fraction of the pixel
// covered.
alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));

View File

@ -43,11 +43,11 @@ public:
kFragment_GrShaderFlag, kHalf_GrSLType, kDefault_GrSLPrecision, "outerThreshold");
SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf(
"half4 color = %s;\nhalf4 mask_color = texture(%s, %s).%s;\nif "
"(float(mask_color.w) < 0.5) {\n if (color.w > %s) {\n half scale = %s / "
"color.w;\n color.xyz *= scale;\n color.w = %s;\n }\n} else if "
"(color.w < %s) {\n half scale = float(%s) / max(0.001, float(color.w));\n "
"color.xyz *= scale;\n color.w = %s;\n}\n%s = color;\n",
"half4 color = %s;\nhalf4 mask_color = texture(%s, %s).%s;\nif (mask_color.w < "
"0.5) {\n if (color.w > %s) {\n half scale = %s / color.w;\n "
"color.xyz *= scale;\n color.w = %s;\n }\n} else if (color.w < %s) {\n "
" half scale = %s / max(0.001, color.w);\n color.xyz *= scale;\n color.w = "
"%s;\n}\n%s = color;\n",
args.fInputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
sk_TransformedCoords2D_0.c_str(),

View File

@ -103,7 +103,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// that suffices. Additionally we should assert that the upstream code only lets us get here if
// either float or half provides the required number of bits.
GrShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0);
GrShaderVar edgeAlpha("edgeAlpha", kHalf_GrSLType, 0);
GrShaderVar dklmdx("dklmdx", kFloat3_GrSLType, 0);
GrShaderVar dklmdy("dklmdy", kFloat3_GrSLType, 0);
GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0);
@ -142,7 +142,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;",
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
fragBuilder->codeAppendf("%s = %s / %s;",
fragBuilder->codeAppendf("%s = half(%s / %s);",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
@ -171,7 +171,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
gFM.c_str(), gF.c_str(), gF.c_str());
fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = %s / %s;",
fragBuilder->codeAppendf("%s = half(%s / %s);",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
fragBuilder->codeAppendf("%s = saturate(0.5 - %s);",
edgeAlpha.c_str(), edgeAlpha.c_str());
@ -180,9 +180,9 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
break;
}
case GrClipEdgeType::kFillBW: {
fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
fragBuilder->codeAppendf("%s = half(%s.x * %s.x - %s.y * %s.z);",
edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = float(%s < 0.0);",
fragBuilder->codeAppendf("%s = half(%s < 0.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
break;
}
@ -197,7 +197,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
kFloat_GrSLType,
"Coverage",
&coverageScale);
fragBuilder->codeAppendf("%s = half4(%s * %s);",
fragBuilder->codeAppendf("%s = half4(half(%s) * %s);",
args.fOutputCoverage, coverageScale, edgeAlpha.c_str());
} else {
fragBuilder->codeAppendf("%s = half4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
@ -354,12 +354,12 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
switch (fEdgeType) {
case GrClipEdgeType::kHairlineAA: {
fragBuilder->codeAppendf("half2 duvdx = dFdx(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = dFdy(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
@ -368,12 +368,12 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
break;
}
case GrClipEdgeType::kFillAA: {
fragBuilder->codeAppendf("half2 duvdx = dFdx(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = dFdy(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 gF = half2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
fragBuilder->codeAppend("edgeAlpha = saturate(0.5 - edgeAlpha);");
@ -382,7 +382,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
break;
}
case GrClipEdgeType::kFillBW: {
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
fragBuilder->codeAppendf("edgeAlpha = half(%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = half(edgeAlpha < 0.0);");
break;

View File

@ -75,8 +75,8 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) {
// starting coords are near a texel boundary and accumulations of imgInc would cause us to skip/
// double hit a texel.
fragBuilder->codeAppendf("coord /= %s;", imgInc);
fragBuilder->codeAppend("float2 f = fract(coord);");
fragBuilder->codeAppendf("coord = (coord - f + float2(0.5)) * %s;", imgInc);
fragBuilder->codeAppend("half2 f = half2(fract(coord));");
fragBuilder->codeAppendf("coord = (coord - f + half2(0.5)) * %s;", imgInc);
fragBuilder->codeAppend("half4 wx = kMitchellCoefficients * half4(1.0, f.x, f.x * f.x, f.x * f.x * f.x);");
fragBuilder->codeAppend("half4 wy = kMitchellCoefficients * half4(1.0, f.y, f.y * f.y, f.y * f.y * f.y);");
fragBuilder->codeAppend("half4 rowColors[4];");

View File

@ -26,10 +26,9 @@ public:
auto mode = _outer.mode();
(void)mode;
fragBuilder->codeAppendf(
"half factor = half(1.0 - float(%s.w));\n@switch (%d) {\n case 0:\n "
"factor = half(exp(float(float(-factor * factor) * 4.0)) - "
"0.017999999999999999);\n break;\n case 1:\n factor = "
"half(smoothstep(1.0, 0.0, float(factor)));\n break;\n}\n%s = "
"half factor = 1.0 - %s.w;\n@switch (%d) {\n case 0:\n factor = "
"exp((-factor * factor) * 4.0) - 0.017999999999999999;\n break;\n case "
"1:\n factor = smoothstep(1.0, 0.0, factor);\n break;\n}\n%s = "
"half4(factor);\n",
args.fInputColor, (int)_outer.mode(), args.fOutputColor);
}

View File

@ -16,7 +16,7 @@ void main() {
half factor = 1.0 - sk_InColor.a;
@switch (mode) {
case Mode::kGaussian:
factor = exp(-factor * factor * 4.0) - 0.018;
factor = half(exp(-factor * factor * 4.0) - 0.018);
break;
case Mode::kSmoothStep:
factor = smoothstep(1.0, 0.0, factor);

View File

@ -274,9 +274,8 @@ public:
kDefault_GrSLPrecision, "circleData");
fragBuilder->codeAppendf(
"half2 vec = half2(half((sk_FragCoord.x - float(%s.x)) * float(%s.w)), "
"half((sk_FragCoord.y - float(%s.y)) * float(%s.w)));\nhalf dist = "
"float(length(vec)) + (0.5 - float(%s.z)) * float(%s.w);\n%s = %s * texture(%s, "
"float2(half2(dist, 0.5))).%s.w;\n",
"half((sk_FragCoord.y - float(%s.y)) * float(%s.w)));\nhalf dist = length(vec) + "
"(0.5 - %s.z) * %s.w;\n%s = %s * texture(%s, float2(half2(dist, 0.5))).%s.w;\n",
args.fUniformHandler->getUniformCStr(fCircleDataVar),
args.fUniformHandler->getUniformCStr(fCircleDataVar),
args.fUniformHandler->getUniformCStr(fCircleDataVar),

View File

@ -278,8 +278,8 @@ uniform half4 circleData;
void main() {
// We just want to compute "(length(vec) - circleData.z + 0.5) * circleData.w" but need to
// rearrange for precision.
half2 vec = half2((sk_FragCoord.x - circleData.x) * circleData.w,
(sk_FragCoord.y - circleData.y) * circleData.w);
half2 vec = half2(half((sk_FragCoord.x - circleData.x) * circleData.w),
half((sk_FragCoord.y - circleData.y) * circleData.w));
half dist = length(vec) + (0.5 - circleData.z) * circleData.w;
sk_OutColor = sk_InColor * texture(blurProfileSampler, half2(dist, 0.5)).a;
}

View File

@ -33,11 +33,11 @@ public:
kDefault_GrSLPrecision, "circle");
fragBuilder->codeAppendf(
"half2 prevCenter;\nhalf prevRadius = %f;\nhalf d;\n@if (%d == 2 || %d == 3) {\n "
" d = (float(length((%s.xy - half2(sk_FragCoord.xy)) * %s.w)) - 1.0) * %s.z;\n} "
"else {\n d = half((1.0 - float(length((%s.xy - half2(sk_FragCoord.xy)) * "
"%s.w))) * float(%s.z));\n}\n@if ((%d == 1 || %d == 3) || %d == 4) {\n d = "
"half(clamp(float(d), 0.0, 1.0));\n} else {\n d = half(float(d) > 0.5 ? 1.0 : "
"0.0);\n}\n%s = %s * d;\n",
" d = half((length((float2(%s.xy) - sk_FragCoord.xy) * float(%s.w)) - 1.0) * "
"float(%s.z));\n} else {\n d = half((1.0 - length((float2(%s.xy) - "
"sk_FragCoord.xy) * float(%s.w))) * float(%s.z));\n}\n@if ((%d == 1 || %d == 3) || "
"%d == 4) {\n d = clamp(d, 0.0, 1.0);\n} else {\n d = d > 0.5 ? 1.0 : "
"0.0;\n}\n%s = %s * d;\n",
prevRadius, (int)_outer.edgeType(), (int)_outer.edgeType(),
args.fUniformHandler->getUniformCStr(fCircleVar),
args.fUniformHandler->getUniformCStr(fCircleVar),

View File

@ -53,9 +53,9 @@ void main() {
half d;
@if (edgeType == GrClipEdgeType::kInverseFillBW ||
edgeType == GrClipEdgeType::kInverseFillAA) {
d = (length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z;
d = half((length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z);
} else {
d = (1.0 - length((circle.xy - sk_FragCoord.xy) * circle.w)) * circle.z;
d = half((1.0 - length((circle.xy - sk_FragCoord.xy) * circle.w)) * circle.z);
}
@if (edgeType == GrClipEdgeType::kFillAA ||
edgeType == GrClipEdgeType::kInverseFillAA ||

View File

@ -27,11 +27,10 @@ public:
fragBuilder->forceHighPrecision();
fragBuilder->codeAppendf(
"%s = half4(floor(float4(float4(%s * 255.0) + 0.5)) / 255.0);\n@switch (%d) {\n "
"case 0:\n %s.xyz = half3(floor(float3(float3((%s.xyz * %s.w) * 255.0) + "
"0.5)) / 255.0);\n break;\n case 1:\n %s.xyz = float(%s.w) <= 0.0 "
"? half3(0.0) : half3(floor(float3(float3((%s.xyz / %s.w) * 255.0) + 0.5)) / "
"255.0);\n break;\n}\n",
"%s = floor(%s * 255.0 + 0.5) / 255.0;\n@switch (%d) {\n case 0:\n "
"%s.xyz = floor((%s.xyz * %s.w) * 255.0 + 0.5) / 255.0;\n break;\n case "
"1:\n %s.xyz = %s.w <= 0.0 ? half3(0.0) : floor((%s.xyz / %s.w) * 255.0 + "
"0.5) / 255.0;\n break;\n}\n",
args.fOutputColor, args.fInputColor, (int)_outer.pmConversion(), args.fOutputColor,
args.fOutputColor, args.fOutputColor, args.fOutputColor, args.fOutputColor,
args.fOutputColor, args.fOutputColor);

View File

@ -50,7 +50,8 @@ void GrGLConvexPolyEffect::emitCode(EmitArgs& args) {
fragBuilder->codeAppend("\t\thalf alpha = 1.0;\n");
fragBuilder->codeAppend("\t\thalf edge;\n");
for (int i = 0; i < cpe.getEdgeCount(); ++i) {
fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], half3(sk_FragCoord.x, sk_FragCoord.y, "
fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], half3(half(sk_FragCoord.x), "
"half(sk_FragCoord.y), "
"1));\n",
edgeArrayName, i);
if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {

View File

@ -103,12 +103,12 @@ public:
// this gives us a smooth step across approximately one fragment
#ifdef SK_VULKAN
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));",
st.fsIn());
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor
"*half(dFdx(%s.x)));", st.fsIn());
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
st.fsIn());
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor
"*half(dFdy(%s.y)));", st.fsIn());
#endif
} else if (isSimilarity) {
// For similarity transform, we adjust the effect of the transformation on the distance
@ -118,28 +118,29 @@ public:
// this gives us a smooth step across approximately one fragment
#ifdef SK_VULKAN
fragBuilder->codeAppendf("half st_grad_len = length(dFdx(%s));", st.fsIn());
fragBuilder->codeAppendf("half st_grad_len = length(half2(dFdx(%s)));", st.fsIn());
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppendf("half st_grad_len = length(dFdy(%s));", st.fsIn());
fragBuilder->codeAppendf("half st_grad_len = length(half2(dFdy(%s)));", st.fsIn());
#endif
fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
} else {
// For general transforms, to determine the amount of correction we multiply a unit
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
// (which is the inverse transform for this fragment) and take the length of the result.
fragBuilder->codeAppend("half2 dist_grad = half2(dFdx(distance), dFdy(distance));");
fragBuilder->codeAppend("half2 dist_grad = half2(float2(dFdx(distance), "
"dFdy(distance)));");
// the length of the gradient may be 0, so we need to check for this
// this also compensates for the Adreno, which likes to drop tiles on division by 0
fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);");
fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);");
fragBuilder->codeAppend("} else {");
fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
fragBuilder->codeAppend("dist_grad = dist_grad*half(inversesqrt(dg_len2));");
fragBuilder->codeAppend("}");
fragBuilder->codeAppendf("half2 Jdx = dFdx(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 Jdy = dFdy(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 Jdx = half2(dFdx(%s));", st.fsIn());
fragBuilder->codeAppendf("half2 Jdy = half2(dFdy(%s));", st.fsIn());
fragBuilder->codeAppend("half2 grad = half2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
@ -404,12 +405,12 @@ public:
// this gives us a smooth step across approximately one fragment
#ifdef SK_VULKAN
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));",
st.fsIn());
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor
"*half(dFdx(%s.x)));", st.fsIn());
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
st.fsIn());
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor
"*half(dFdy(%s.y)));", st.fsIn());
#endif
} else if (isSimilarity) {
// For similarity transform, we adjust the effect of the transformation on the distance
@ -418,28 +419,29 @@ public:
// this gives us a smooth step across approximately one fragment
#ifdef SK_VULKAN
fragBuilder->codeAppendf("half st_grad_len = length(dFdx(%s));", st.fsIn());
fragBuilder->codeAppendf("half st_grad_len = half(length(dFdx(%s)));", st.fsIn());
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppendf("half st_grad_len = length(dFdy(%s));", st.fsIn());
fragBuilder->codeAppendf("half st_grad_len = half(length(dFdy(%s)));", st.fsIn());
#endif
fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
} else {
// For general transforms, to determine the amount of correction we multiply a unit
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
// (which is the inverse transform for this fragment) and take the length of the result.
fragBuilder->codeAppend("half2 dist_grad = half2(dFdx(distance), dFdy(distance));");
fragBuilder->codeAppend("half2 dist_grad = half2(dFdx(distance), "
"dFdy(distance));");
// the length of the gradient may be 0, so we need to check for this
// this also compensates for the Adreno, which likes to drop tiles on division by 0
fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);");
fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);");
fragBuilder->codeAppend("} else {");
fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
fragBuilder->codeAppend("dist_grad = dist_grad*half(inversesqrt(dg_len2));");
fragBuilder->codeAppend("}");
fragBuilder->codeAppendf("half2 Jdx = dFdx(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 Jdy = dFdy(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 Jdx = half2(dFdx(%s));", st.fsIn());
fragBuilder->codeAppendf("half2 Jdy = half2(dFdy(%s));", st.fsIn());
fragBuilder->codeAppend("half2 grad = half2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
@ -677,32 +679,33 @@ public:
if (isUniformScale) {
#ifdef SK_VULKAN
fragBuilder->codeAppendf("half st_grad_len = abs(dFdx(%s.x));", st.fsIn());
fragBuilder->codeAppendf("half st_grad_len = half(abs(dFdx(%s.x)));", st.fsIn());
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppendf("half st_grad_len = abs(dFdy(%s.y));", st.fsIn());
fragBuilder->codeAppendf("half st_grad_len = half(abs(dFdy(%s.y)));", st.fsIn());
#endif
fragBuilder->codeAppendf("half2 offset = half2(st_grad_len*%s, 0.0);", delta.fsIn());
fragBuilder->codeAppendf("half2 offset = half2(half(st_grad_len*%s), 0.0);",
delta.fsIn());
} else if (isSimilarity) {
// For a similarity matrix with rotation, the gradient will not be aligned
// with the texel coordinate axes, so we need to calculate it.
#ifdef SK_VULKAN
fragBuilder->codeAppendf("half2 st_grad = dFdx(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 offset = %s*st_grad;", delta.fsIn());
fragBuilder->codeAppendf("half2 st_grad = half2(dFdx(%s));", st.fsIn());
fragBuilder->codeAppendf("half2 offset = half(%s)*st_grad;", delta.fsIn());
#else
// We use dFdy because of a Mali 400 bug, and rotate -90 degrees to
// get the gradient in the x direction.
fragBuilder->codeAppendf("half2 st_grad = dFdy(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 offset = %s*half2(st_grad.y, -st_grad.x);",
fragBuilder->codeAppendf("half2 st_grad = half2(dFdy(%s));", st.fsIn());
fragBuilder->codeAppendf("half2 offset = half2(%s*float2(st_grad.y, -st_grad.x));",
delta.fsIn());
#endif
fragBuilder->codeAppend("half st_grad_len = length(st_grad);");
} else {
fragBuilder->codeAppendf("half2 st = %s;\n", st.fsIn());
fragBuilder->codeAppendf("half2 st = half2(%s);\n", st.fsIn());
fragBuilder->codeAppend("half2 Jdx = dFdx(st);");
fragBuilder->codeAppend("half2 Jdy = dFdy(st);");
fragBuilder->codeAppendf("half2 offset = %s*Jdx;", delta.fsIn());
fragBuilder->codeAppend("half2 Jdx = half2(dFdx(st));");
fragBuilder->codeAppend("half2 Jdy = half2(dFdy(st));");
fragBuilder->codeAppendf("half2 offset = half2(half(%s))*Jdx;", delta.fsIn());
}
// sample the texture by index
@ -714,12 +717,12 @@ public:
fragBuilder->codeAppend("half3 distance;");
fragBuilder->codeAppend("distance.y = texColor.r;");
// red is distance to left offset
fragBuilder->codeAppend("half2 uv_adjusted = uv - offset;");
fragBuilder->codeAppend("half2 uv_adjusted = half2(uv) - offset;");
append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(),
texIdx, "uv_adjusted", "texColor");
fragBuilder->codeAppend("distance.x = texColor.r;");
// blue is distance to right offset
fragBuilder->codeAppend("uv_adjusted = uv + offset;");
fragBuilder->codeAppend("uv_adjusted = half2(uv) + offset;");
append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(),
texIdx, "uv_adjusted", "texColor");
fragBuilder->codeAppend("distance.z = texColor.r;");
@ -750,14 +753,15 @@ public:
// For general transforms, to determine the amount of correction we multiply a unit
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
// (which is the inverse transform for this fragment) and take the length of the result.
fragBuilder->codeAppend("half2 dist_grad = half2(dFdx(distance.r), dFdy(distance.r));");
fragBuilder->codeAppend("half2 dist_grad = half2(half(dFdx(distance.r)), "
"half(dFdy(distance.r)));");
// the length of the gradient may be 0, so we need to check for this
// this also compensates for the Adreno, which likes to drop tiles on division by 0
fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);");
fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);");
fragBuilder->codeAppend("} else {");
fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
fragBuilder->codeAppend("dist_grad = dist_grad*half(inversesqrt(dg_len2));");
fragBuilder->codeAppend("}");
fragBuilder->codeAppend("half2 grad = half2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");

View File

@ -42,8 +42,8 @@ public:
"%s.y;\n}\nfloat2 Z = d * %s.zw;\nfloat implicit = dot(Z, d) - 1.0;\nfloat "
"grad_dot = 4.0 * dot(Z, Z);\ngrad_dot = max(grad_dot, 0.0001);\nfloat approx_dist "
"= implicit * inversesqrt(grad_dot);\n@if (useScale) {\n approx_dist *= "
"%s.x;\n}\nhalf alpha;\n@switch (%d) {\n case 0:\n alpha = "
"half(approx_dist > 0.0 ? 0.0 : 1.0);\n break;\n case 1:\n ",
"%s.x;\n}\nhalf alpha;\n@switch (%d) {\n case 0:\n alpha = approx_dist > "
"0.0 ? 0.0 : 1.0;\n break;\n case 1:\n alph",
prevRadii.fX, prevRadii.fY, (useScale ? "true" : "false"),
args.fUniformHandler->getUniformCStr(fEllipseVar),
fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)",
@ -51,10 +51,10 @@ public:
fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)",
(int)_outer.edgeType());
fragBuilder->codeAppendf(
" alpha = half(clamp(0.5 - approx_dist, 0.0, 1.0));\n break;\n case "
"2:\n alpha = half(approx_dist > 0.0 ? 1.0 : 0.0);\n break;\n "
"case 3:\n alpha = half(clamp(0.5 + approx_dist, 0.0, 1.0));\n "
"break;\n default:\n discard;\n}\n%s = %s * alpha;\n",
"a = clamp(0.5 - half(approx_dist), 0.0, 1.0);\n break;\n case 2:\n "
" alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n break;\n case 3:\n "
"alpha = clamp(0.5 + half(approx_dist), 0.0, 1.0);\n break;\n default:\n "
" discard;\n}\n%s = %s * alpha;\n",
args.fOutputColor, args.fInputColor);
}

View File

@ -91,13 +91,13 @@ void main() {
alpha = approx_dist > 0.0 ? 0.0 : 1.0;
break;
case GrClipEdgeType::kFillAA:
alpha = saturate(0.5 - approx_dist);
alpha = saturate(0.5 - half(approx_dist));
break;
case GrClipEdgeType::kInverseFillBW:
alpha = approx_dist > 0.0 ? 1.0 : 0.0;
break;
case GrClipEdgeType::kInverseFillAA:
alpha = saturate(0.5 + approx_dist);
alpha = saturate(0.5 + half(approx_dist));
break;
default:
// hairline not supported

View File

@ -48,13 +48,13 @@ public:
kFragment_GrShaderFlag, kHalf2_GrSLType, kDefault_GrSLPrecision, "offset");
SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf(
"float2 coord = %s;\nfloat2 zoom_coord = float2(%s + half2(coord * "
"float2(half2(half(%s), half(%s)))));\nfloat2 delta = (coord - %s.xy) * "
"%s.zw;\ndelta = min(delta, float2(half2(1.0, 1.0) - half2(delta)));\ndelta *= "
"float2(half2(half(%s), half(%s)));\nhalf weight = 0.0;\nif (delta.x < 2.0 && "
"delta.y < 2.0) {\n delta = float2(half2(2.0, 2.0) - half2(delta));\n half "
"dist = half(length(delta));\n dist = half(max(2.0 - float(dist), 0.0));\n "
"weight = half(min(float(dist * dist), 1.0));\n} else {\n ",
"float2 coord = %s;\nfloat2 zoom_coord = float2(%s) + coord * float2(%s, "
"%s);\nfloat2 delta = (coord - %s.xy) * %s.zw;\ndelta = min(delta, "
"float2(half2(1.0, 1.0)) - delta);\ndelta *= float2(%s, %s);\nfloat weight = "
"0.0;\nif (delta.x < 2.0 && delta.y < 2.0) {\n delta = float2(half2(2.0, 2.0)) "
"- delta;\n float dist = length(delta);\n dist = max(2.0 - dist, 0.0);\n "
"weight = min(dist * dist, 1.0);\n} else {\n float2 delta_squared = delta * "
"delta;\n weight = min(min(delta_squared.x, delta_square",
sk_TransformedCoords2D_0.c_str(),
args.fUniformHandler->getUniformCStr(fOffsetVar),
args.fUniformHandler->getUniformCStr(fXInvZoomVar),
@ -64,9 +64,7 @@ public:
args.fUniformHandler->getUniformCStr(fXInvInsetVar),
args.fUniformHandler->getUniformCStr(fYInvInsetVar));
fragBuilder->codeAppendf(
"float2 delta_squared = delta * delta;\n weight = half(min(min(delta_squared.x, "
"delta_squared.y), 1.0));\n}\n%s = texture(%s, mix(coord, zoom_coord, "
"float(weight))).%s;\n",
"d.y), 1.0);\n}\n%s = texture(%s, mix(coord, zoom_coord, weight)).%s;\n",
args.fOutputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());

View File

@ -22,15 +22,15 @@ uniform half2 offset;
void main() {
float2 coord = sk_TransformedCoords2D[0];
float2 zoom_coord = offset + coord * half2(xInvZoom, yInvZoom);
float2 zoom_coord = offset + coord * float2(xInvZoom, yInvZoom);
float2 delta = (coord - boundsUniform.xy) * boundsUniform.zw;
delta = min(delta, half2(1.0, 1.0) - delta);
delta *= half2(xInvInset, yInvInset);
delta *= float2(xInvInset, yInvInset);
half weight = 0.0;
float weight = 0.0;
if (delta.s < 2.0 && delta.t < 2.0) {
delta = half2(2.0, 2.0) - delta;
half dist = length(delta);
float dist = length(delta);
dist = max(2.0 - dist, 0.0);
weight = min(dist * dist, 1.0);
} else {

View File

@ -67,30 +67,30 @@ public:
(void)rect;
auto cornerRadius = _outer.cornerRadius();
(void)cornerRadius;
fCornerRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType,
fCornerRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
kDefault_GrSLPrecision, "cornerRadius");
fProxyRectVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
kDefault_GrSLPrecision, "proxyRect");
fBlurRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
kDefault_GrSLPrecision, "blurRadius");
fragBuilder->codeAppendf(
"\nhalf2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);\nhalf threshold = "
"half(%s + 2.0 * float(%s));\nhalf2 middle = half2((%s.zw - %s.xy) - 2.0 * "
"float(threshold));\nif (translatedFragPos.x >= threshold && translatedFragPos.x < "
"middle.x + threshold) {\n translatedFragPos.x = threshold;\n} else if "
"(translatedFragPos.x >= middle.x + threshold) {\n translatedFragPos.x -= "
"float(middle.x) - 1.0;\n}\nif (translatedFragPos.y > threshold && "
"translatedFragPos.y < middle.y + threshold) {\n translatedFr",
"\nhalf2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);\nhalf threshold = %s "
"+ 2.0 * %s;\nhalf2 middle = half2((%s.zw - %s.xy) - float(2.0 * threshold));\nif "
"(translatedFragPos.x >= threshold && translatedFragPos.x < middle.x + threshold) "
"{\n translatedFragPos.x = threshold;\n} else if (translatedFragPos.x >= "
"middle.x + threshold) {\n translatedFragPos.x -= middle.x - 1.0;\n}\nif "
"(translatedFragPos.y > threshold && translatedFragPos.y < middle.y + threshold) "
"{\n translatedFragPos.y = threshold;",
args.fUniformHandler->getUniformCStr(fProxyRectVar),
args.fUniformHandler->getUniformCStr(fCornerRadiusVar),
args.fUniformHandler->getUniformCStr(fBlurRadiusVar),
args.fUniformHandler->getUniformCStr(fProxyRectVar),
args.fUniformHandler->getUniformCStr(fProxyRectVar));
fragBuilder->codeAppendf(
"agPos.y = threshold;\n} else if (translatedFragPos.y >= middle.y + threshold) {\n "
" translatedFragPos.y -= float(middle.y) - 1.0;\n}\nhalf2 proxyDims = "
"half2(half(2.0 * float(threshold) + 1.0));\nhalf2 texCoord = translatedFragPos / "
"proxyDims;\n%s = %s * texture(%s, float2(texCoord)).%s;\n",
"\n} else if (translatedFragPos.y >= middle.y + threshold) {\n "
"translatedFragPos.y -= middle.y - 1.0;\n}\nhalf2 proxyDims = half2(2.0 * "
"threshold + 1.0);\nhalf2 texCoord = translatedFragPos / proxyDims;\n%s = %s * "
"texture(%s, float2(texCoord)).%s;\n",
args.fOutputColor, args.fInputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());

View File

@ -7,7 +7,7 @@
in float sigma;
layout(ctype=SkRect) in float4 rect;
in uniform float cornerRadius;
in uniform half cornerRadius;
in uniform sampler2D ninePatchSampler;
layout(ctype=SkRect) uniform float4 proxyRect;
uniform half blurRadius;
@ -169,10 +169,10 @@ uniform half blurRadius;
void main() {
// warp the fragment position to the appropriate part of the 9patch blur texture
half2 rectCenter = (proxyRect.xy + proxyRect.zw) / 2.0;
half2 translatedFragPos = sk_FragCoord.xy - proxyRect.xy;
half2 rectCenter = half2((proxyRect.xy + proxyRect.zw) / 2.0);
half2 translatedFragPos = half2(sk_FragCoord.xy - proxyRect.xy);
half threshold = cornerRadius + 2.0 * blurRadius;
half2 middle = proxyRect.zw - proxyRect.xy - 2.0 * threshold;
half2 middle = half2(proxyRect.zw - proxyRect.xy - 2.0 * threshold);
if (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x + threshold)) {
translatedFragPos.x = threshold;

View File

@ -166,10 +166,10 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
// If we're on a device where float != fp32 then the length calculation could overflow.
SkString clampedCircleDistance;
if (!args.fShaderCaps->floatIs32Bits()) {
clampedCircleDistance.printf("saturate(%s.x * (1.0 - length(dxy * %s.y)));",
clampedCircleDistance.printf("saturate(%s.x * (1.0 - length(dxy * %s.y)))",
radiusPlusHalfName, radiusPlusHalfName);
} else {
clampedCircleDistance.printf("saturate(%s.x - length(dxy));", radiusPlusHalfName);
clampedCircleDistance.printf("saturate(%s.x - length(dxy))", radiusPlusHalfName);
}
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
@ -193,84 +193,84 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
fragBuilder->codeAppendf("half alpha = %s;", clampedCircleDistance.c_str());
fragBuilder->codeAppendf("half alpha = half(%s);", clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);",
rectName);
fragBuilder->codeAppendf("half rightAlpha = saturate(%s.z - sk_FragCoord.x);",
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));",
rectName);
fragBuilder->codeAppendf("half bottomAlpha = saturate(%s.w - sk_FragCoord.y);",
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * rightAlpha * %s;",
fragBuilder->codeAppendf("half alpha = bottomAlpha * rightAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopRight_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(float2(sk_FragCoord.x - %s.z, "
"%s.y - sk_FragCoord.y), 0.0);",
rectName, rectName);
fragBuilder->codeAppendf("half leftAlpha = saturate(sk_FragCoord.x - %s.x);",
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.x));",
rectName);
fragBuilder->codeAppendf("half bottomAlpha = saturate(%s.w - sk_FragCoord.y);",
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * leftAlpha * %s;",
fragBuilder->codeAppendf("half alpha = bottomAlpha * leftAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);",
rectName);
fragBuilder->codeAppendf("half leftAlpha = saturate(sk_FragCoord.x - %s.x);",
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.x));",
rectName);
fragBuilder->codeAppendf("half topAlpha = saturate(sk_FragCoord.y - %s.y);",
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.y));",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * leftAlpha * %s;",
fragBuilder->codeAppendf("half alpha = topAlpha * leftAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(float2(%s.x - sk_FragCoord.x, "
"sk_FragCoord.y - %s.w), 0.0);",
rectName, rectName);
fragBuilder->codeAppendf("half rightAlpha = saturate(%s.z - sk_FragCoord.x);",
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));",
rectName);
fragBuilder->codeAppendf("half topAlpha = saturate(sk_FragCoord.y - %s.y);",
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.y));",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * rightAlpha * %s;",
fragBuilder->codeAppendf("half alpha = topAlpha * rightAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kLeft_CornerFlags:
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float dy1 = sk_FragCoord.y - %s.w;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(dxy0.x, max(dxy0.y, dy1)), 0.0);");
fragBuilder->codeAppendf("half rightAlpha = saturate(%s.z - sk_FragCoord.x);",
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));",
rectName);
fragBuilder->codeAppendf("half alpha = rightAlpha * %s;",
fragBuilder->codeAppendf("half alpha = rightAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTop_CornerFlags:
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float dx1 = sk_FragCoord.x - %s.z;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(max(dxy0.x, dx1), dxy0.y), 0.0);");
fragBuilder->codeAppendf("half bottomAlpha = saturate(%s.w - sk_FragCoord.y);",
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * %s;",
fragBuilder->codeAppendf("half alpha = bottomAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kRight_CornerFlags:
fragBuilder->codeAppendf("float dy0 = %s.y - sk_FragCoord.y;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(dxy1.x, max(dy0, dxy1.y)), 0.0);");
fragBuilder->codeAppendf("half leftAlpha = saturate(sk_FragCoord.x - %s.x);",
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.x));",
rectName);
fragBuilder->codeAppendf("half alpha = leftAlpha * %s;",
fragBuilder->codeAppendf("half alpha = leftAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottom_CornerFlags:
fragBuilder->codeAppendf("float dx0 = %s.x - sk_FragCoord.x;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(max(dx0, dxy1.x), dxy1.y), 0.0);");
fragBuilder->codeAppendf("half topAlpha = saturate(sk_FragCoord.y - %s.y);",
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.y));",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * %s;",
fragBuilder->codeAppendf("half alpha = topAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
}
@ -570,12 +570,12 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
SK_ABORT("RRect should always be simple or nine-patch.");
}
// implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
fragBuilder->codeAppend("float implicit = dot(Z, dxy) - 1.0;");
fragBuilder->codeAppend("half implicit = half(dot(Z, dxy) - 1.0);");
// grad_dot is the squared length of the gradient of the implicit.
fragBuilder->codeAppend("float grad_dot = 4.0 * dot(Z, Z);");
fragBuilder->codeAppend("half grad_dot = half(4.0 * dot(Z, Z));");
// avoid calling inversesqrt on zero.
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
fragBuilder->codeAppend("float approx_dist = implicit * inversesqrt(grad_dot);");
fragBuilder->codeAppend("half approx_dist = implicit * half(inversesqrt(grad_dot));");
if (scaleName) {
fragBuilder->codeAppendf("approx_dist *= %s.x;", scaleName);
}

View File

@ -49,10 +49,10 @@ public:
"/* key */ bool highPrecision = %s;\n@if (highPrecision) {\n float2 "
"translatedPos = sk_FragCoord.xy - %s.xy;\n float width = %s.z - %s.x;\n "
"float height = %s.w - %s.y;\n float2 smallDims = float2(width - float(%s), "
"height - float(%s));\n float center = 2.0 * floor(float(float(%s / 2.0) + "
"0.25)) - 1.0;\n float2 wh = smallDims - float2(center, center);\n half "
"hcoord = half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n "
" half hlookup = texture(%s, float2(float(hcoord), ",
"height - float(%s));\n float center = float(2.0 * floor(%s / 2.0 + 0.25) - "
"1.0);\n float2 wh = smallDims - float2(center, center);\n half hcoord = "
"half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n half "
"hlookup = texture(%s, float2(float(hcoord), 0.5)).",
(highPrecision ? "true" : "false"), args.fUniformHandler->getUniformCStr(fRectVar),
args.fUniformHandler->getUniformCStr(fRectVar),
args.fUniformHandler->getUniformCStr(fRectVar),
@ -64,13 +64,13 @@ public:
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str());
fragBuilder->codeAppendf(
"0.5)).%s.w;\n half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * "
"wh.y) / float(%s));\n half vlookup = texture(%s, float2(float(vcoord), "
"0.5)).%s.w;\n %s = (%s * hlookup) * vlookup;\n} else {\n half2 "
"translatedPos = half2(sk_FragCoord.xy - %s.xy);\n half width = half(%s.z - "
"%s.x);\n half height = half(%s.w - %s.y);\n half2 smallDims = half2(width - "
"%s, height - %s);\n half center = half(2.0 * floor(float(float(%s / 2.0) + "
"0.25)) - 1.0);\n half2 wh = smallDims - half2(f",
"%s.w;\n half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) "
"/ float(%s));\n half vlookup = texture(%s, float2(float(vcoord), 0.5)).%s.w;\n "
" %s = (%s * hlookup) * vlookup;\n} else {\n half2 translatedPos = "
"half2(sk_FragCoord.xy - %s.xy);\n half width = half(%s.z - %s.x);\n half "
"height = half(%s.w - %s.y);\n half2 smallDims = half2(width - %s, height - "
"%s);\n half center = 2.0 * floor(%s / 2.0 + 0.25) - 1.0;\n half2 wh = "
"smallDims - half2(center, center);\n half ",
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
@ -84,11 +84,9 @@ public:
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
args.fUniformHandler->getUniformCStr(fProfileSizeVar));
fragBuilder->codeAppendf(
"loat2(float(center), float(center)));\n half hcoord = "
"half((abs(float(float(translatedPos.x) - 0.5 * float(width))) - 0.5 * "
"float(wh.x)) / float(%s));\n half hlookup = texture(%s, float2(float(hcoord), "
"0.5)).%s.w;\n half vcoord = half((abs(float(float(translatedPos.y) - 0.5 * "
"float(height))) - 0.5 * float(wh.y)) / float(%s));\n half vlookup = "
"hcoord = (abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / %s;\n half "
"hlookup = texture(%s, float2(float(hcoord), 0.5)).%s.w;\n half vcoord = "
"(abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) / %s;\n half vlookup = "
"texture(%s, float2(float(vcoord), 0.5)).%s.w;\n %s = (%s * hlookup) * "
"vlookup;\n}\n",
args.fUniformHandler->getUniformCStr(fProfileSizeVar),

View File

@ -123,21 +123,21 @@ void main() {
float2 smallDims = float2(width - profileSize, height - profileSize);
float center = 2 * floor(profileSize / 2 + 0.25) - 1;
float2 wh = smallDims - float2(center, center);
half hcoord = ((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x)) / profileSize;
half hcoord = half(((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x)) / profileSize);
half hlookup = texture(blurProfile, float2(hcoord, 0.5)).a;
half vcoord = ((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y)) / profileSize;
half vcoord = half(((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y)) / profileSize);
half vlookup = texture(blurProfile, float2(vcoord, 0.5)).a;
sk_OutColor = sk_InColor * hlookup * vlookup;
} else {
half2 translatedPos = sk_FragCoord.xy - rect.xy;
half width = rect.z - rect.x;
half height = rect.w - rect.y;
half2 translatedPos = half2(sk_FragCoord.xy - rect.xy);
half width = half(rect.z - rect.x);
half height = half(rect.w - rect.y);
half2 smallDims = half2(width - profileSize, height - profileSize);
half center = 2 * floor(profileSize / 2 + 0.25) - 1;
half2 wh = smallDims - float2(center, center);
half hcoord = ((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x)) / profileSize;
half2 wh = smallDims - half2(center, center);
half hcoord = ((half(abs(translatedPos.x - 0.5 * width)) - 0.5 * wh.x)) / profileSize;
half hlookup = texture(blurProfile, float2(hcoord, 0.5)).a;
half vcoord = ((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y)) / profileSize;
half vcoord = ((half(abs(translatedPos.y - 0.5 * height)) - 0.5 * wh.y)) / profileSize;
half vlookup = texture(blurProfile, float2(vcoord, 0.5)).a;
sk_OutColor = sk_InColor * hlookup * vlookup;
}

View File

@ -45,7 +45,7 @@ public:
// Mali Bifrost uses fp16 for mediump. Making the intermediate color variable highp causes
// calculations to be performed with sufficient precision.
fragBuilder->codeAppendf("float4 color = %s;", args.fInputColor);
fragBuilder->codeAppendf("half4 color = %s;", args.fInputColor);
if (srgbe.alpha() == GrSRGBEffect::Alpha::kPremul) {
fragBuilder->codeAppendf("half nonZeroAlpha = max(color.a, 0.00001);");
fragBuilder->codeAppendf("color = half4(color.rgb / nonZeroAlpha, color.a);");

View File

@ -151,15 +151,15 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder,
// pixel coordinate. This will then be clamped to 1.f if it's greater than the control
// parameter, which simulates kNearest and kBilerp behavior depending on if it's 0 or 1.
if (decalX && decalY) {
builder->codeAppendf("half err = max(abs(clampedCoord.x - origCoord.x) * %s.x, "
"abs(clampedCoord.y - origCoord.y) * %s.y);",
builder->codeAppendf("half err = max(half(abs(clampedCoord.x - origCoord.x) * %s.x), "
"half(abs(clampedCoord.y - origCoord.y) * %s.y));",
fDecalName.c_str(), fDecalName.c_str());
} else if (decalX) {
builder->codeAppendf("half err = abs(clampedCoord.x - origCoord.x) * %s.x;",
builder->codeAppendf("half err = half(abs(clampedCoord.x - origCoord.x) * %s.x);",
fDecalName.c_str());
} else {
SkASSERT(decalY);
builder->codeAppendf("half err = abs(clampedCoord.y - origCoord.y) * %s.y;",
builder->codeAppendf("half err = half(abs(clampedCoord.y - origCoord.y) * %s.y);",
fDecalName.c_str());
}
@ -427,7 +427,7 @@ GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLS
kHalf4_GrSLType,
"scaleAndTranslate",
&scaleAndTranslateName);
args.fFragBuilder->codeAppendf("half2 coords = sk_FragCoord.xy * %s.xy + %s.zw;",
args.fFragBuilder->codeAppendf("half2 coords = half2(sk_FragCoord.xy * %s.xy + %s.zw);",
scaleAndTranslateName, scaleAndTranslateName);
fGLDomain.sampleTexture(args.fFragBuilder,
args.fUniformHandler,

View File

@ -119,7 +119,7 @@ public:
static const char kChannelToChar[4] = { 'x', 'y', 'z', 'w' };
fragBuilder->codeAppendf(
"half4 yuvOne = half4(tmp%d.%c, tmp%d.%c, tmp%d.%c, 1.0) * %s;",
"half4 yuvOne = half4(half(tmp%d.%c), half(tmp%d.%c), half(tmp%d.%c), 1.0) * %s;",
_outer.yuvaIndex(0).fIndex, kChannelToChar[(int)_outer.yuvaIndex(0).fChannel],
_outer.yuvaIndex(1).fIndex, kChannelToChar[(int)_outer.yuvaIndex(1).fChannel],
_outer.yuvaIndex(2).fIndex, kChannelToChar[(int)_outer.yuvaIndex(2).fChannel],
@ -128,12 +128,12 @@ public:
if (_outer.yuvaIndex(3).fIndex >= 0) {
fragBuilder->codeAppendf(
"float a = tmp%d.%c;", _outer.yuvaIndex(3).fIndex,
"half a = tmp%d.%c;", _outer.yuvaIndex(3).fIndex,
kChannelToChar[(int)_outer.yuvaIndex(3).fChannel]);
// premultiply alpha
fragBuilder->codeAppend("yuvOne *= a;");
} else {
fragBuilder->codeAppendf("float a = 1.0;");
fragBuilder->codeAppendf("half a = 1.0;");
}
fragBuilder->codeAppendf("%s = half4(yuvOne.xyz, a);", args.fOutputColor);

View File

@ -3358,7 +3358,7 @@ bool GrGLGpu::createCopyProgram(GrTexture* srcTex) {
vshaderTxt.append(
"// Copy Program VS\n"
"void main() {"
" v_texCoord = a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw;"
" v_texCoord = half2(a_vertex.xy * u_texCoordXform.xy + u_texCoordXform.zw);"
" sk_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
" sk_Position.zw = half2(0, 1);"
"}"

View File

@ -146,7 +146,7 @@ static void add_lum_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setLumF
GrShaderVar getLumArgs[] = {
GrShaderVar("color", kHalf3_GrSLType),
};
SkString getLumBody("return dot(float3(0.3, 0.59, 0.11), color);");
SkString getLumBody("return dot(half3(0.3, 0.59, 0.11), color);");
fsBuilder->emitFunction(kHalf_GrSLType,
"luminance",
SK_ARRAY_COUNT(getLumArgs), getLumArgs,

View File

@ -70,7 +70,7 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
&dstCoordScaleName);
fragBuilder->codeAppend("// Read color from copy of the destination.\n");
fragBuilder->codeAppendf("half2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;",
fragBuilder->codeAppendf("half2 _dstTexCoord = (half2(sk_FragCoord.xy) - %s) * %s;",
dstTopLeftName, dstCoordScaleName);
if (flipY) {

View File

@ -39,7 +39,7 @@ public:
this->emitChild(1, &_child1, args);
fragBuilder->codeAppendf(
"half4 t = %s;\nif (!%s && t.y < 0.0) {\n %s = half4(0.0);\n} else if (t.x < "
"0.0) {\n %s = %s;\n} else if (float(t.x) > 1.0) {\n %s = %s;\n} else {",
"0.0) {\n %s = %s;\n} else if (t.x > 1.0) {\n %s = %s;\n} else {",
_child1.c_str(),
(_outer.childProcessor(1).preservesOpaqueInput() ? "true" : "false"),
args.fOutputColor, args.fOutputColor,

View File

@ -29,7 +29,7 @@ void main() {
bias = bias23;
}
sk_OutColor = t * scale + bias;
sk_OutColor = half4(t * scale + bias);
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -12,7 +12,7 @@ in half4x4 gradientMatrix;
}
void main() {
half t = sk_TransformedCoords2D[0].x;
half t = half(sk_TransformedCoords2D[0].x);
sk_OutColor = half4(t, 1, 0, 0); // y = 1 for always valid
}

View File

@ -12,7 +12,7 @@ in half4x4 gradientMatrix;
}
void main() {
half t = length(sk_TransformedCoords2D[0]);
half t = half(length(sk_TransformedCoords2D[0]));
sk_OutColor = half4(t, 1, 0, 0); // y = 1 for always valid
}

View File

@ -36,8 +36,8 @@ public:
fragBuilder->codeAppendf(
"half angle;\nif (sk_Caps.atan2ImplementedAsAtanYOverX) {\n angle = half(2.0 * "
"atan(-%s.y, length(%s) - %s.x));\n} else {\n angle = half(atan(-%s.y, "
"-%s.x));\n}\nhalf t = ((float(float(angle) * 0.15915494309180001) + 0.5) + %s) * "
"%s;\n%s = half4(t, 1.0, 0.0, 0.0);\n",
"-%s.x));\n}\nhalf t = ((angle * 0.15915494309180001 + 0.5) + %s) * %s;\n%s = "
"half4(t, 1.0, 0.0, 0.0);\n",
sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str(),
sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str(),
sk_TransformedCoords2D_0.c_str(), args.fUniformHandler->getUniformCStr(fBiasVar),

View File

@ -22,10 +22,10 @@ void main() {
// using atan instead.
half angle;
if (sk_Caps.atan2ImplementedAsAtanYOverX) {
angle = 2 * atan(-sk_TransformedCoords2D[0].y,
length(sk_TransformedCoords2D[0]) - sk_TransformedCoords2D[0].x);
angle = half(2 * atan(-sk_TransformedCoords2D[0].y,
length(sk_TransformedCoords2D[0]) - sk_TransformedCoords2D[0].x));
} else {
angle = atan(-sk_TransformedCoords2D[0].y, -sk_TransformedCoords2D[0].x);
angle = half(atan(-sk_TransformedCoords2D[0].y, -sk_TransformedCoords2D[0].x));
}
// 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]

View File

@ -32,12 +32,10 @@ public:
this->emitChild(1, &_child1, args);
fragBuilder->codeAppendf(
"half4 t = %s;\nif (!%s && t.y < 0.0) {\n %s = half4(0.0);\n} else {\n @if "
"(%s) {\n half t_1 = t.x - 1.0;\n half tiled_t = (float(t_1) - 2.0 * "
"floor(float(float(t_1) * 0.5))) - 1.0;\n if "
"(sk_Caps.mustDoOpBetweenFloorAndAbs) {\n tiled_t = "
"half(clamp(float(tiled_t), -1.0, 1.0));\n }\n t.x = "
"half(abs(float(tiled_t)));\n } else {\n t.x = "
"half(fract(float(t.x)));\n }",
"(%s) {\n half t_1 = t.x - 1.0;\n half tiled_t = (t_1 - 2.0 * "
"floor(t_1 * 0.5)) - 1.0;\n if (sk_Caps.mustDoOpBetweenFloorAndAbs) {\n "
" tiled_t = clamp(tiled_t, -1.0, 1.0);\n }\n t.x = "
"abs(tiled_t);\n } else {\n t.x = fract(t.x);\n }",
_child1.c_str(),
(_outer.childProcessor(1).preservesOpaqueInput() ? "true" : "false"),
args.fOutputColor, (_outer.mirror() ? "true" : "false"));

View File

@ -44,10 +44,10 @@ public:
SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf(
"float2 p = %s;\nfloat t = -1.0;\nhalf v = 1.0;\n@switch (%d) {\n case 1:\n "
" {\n half r0_2 = %s.y;\n t = float(float(r0_2) - p.y * "
"p.y);\n if (t >= 0.0) {\n t = p.x + sqrt(t);\n "
" } else {\n v = -1.0;\n }\n }\n break;\n "
" case 0:\n {\n half r0 = %s.x;\n @if (%s) {\n "
" {\n half r0_2 = %s.y;\n t = float(r0_2) - p.y * p.y;\n "
" if (t >= 0.0) {\n t = p.x + sqrt(t);\n } else "
"{\n v = -1.0;\n }\n }\n break;\n case "
"0:\n {\n half r0 = %s.x;\n @if (%s) {\n "
" t = length(p) - float(r0);\n } else {\n t = "
"-length(p) - float(r0);\n ",
sk_TransformedCoords2D_0.c_str(), (int)_outer.type(),
@ -55,13 +55,13 @@ public:
args.fUniformHandler->getUniformCStr(fFocalParamsVar),
(_outer.isRadiusIncreasing() ? "true" : "false"));
fragBuilder->codeAppendf(
" }\n }\n break;\n case 2:\n {\n "
"half invR1 = %s.x;\n half fx = %s.y;\n float x_t = -1.0;\n "
" @if (%s) {\n x_t = dot(p, p) / p.x;\n } else "
"if (%s) {\n x_t = length(p) - p.x * float(invR1);\n } "
"else {\n float temp = p.x * p.x - p.y * p.y;\n if "
"(temp >= 0.0) {\n @if (%s || !%s) {\n "
"x_t = -sqrt(temp) - p.x * float",
" }\n }\n break;\n case 2:\n {\n half invR1 "
"= %s.x;\n half fx = %s.y;\n float x_t = -1.0;\n "
"@if (%s) {\n x_t = dot(p, p) / p.x;\n } else if (%s) "
"{\n x_t = length(p) - p.x * float(invR1);\n } else {\n "
" float temp = p.x * p.x - p.y * p.y;\n if (temp >= "
"0.0) {\n @if (%s || !%s) {\n x_t = "
"-sqrt(temp) - p.x * float(invR1)",
args.fUniformHandler->getUniformCStr(fFocalParamsVar),
args.fUniformHandler->getUniformCStr(fFocalParamsVar),
(_outer.isFocalOnCircle() ? "true" : "false"),
@ -69,13 +69,13 @@ public:
(_outer.isSwapped() ? "true" : "false"),
(_outer.isRadiusIncreasing() ? "true" : "false"));
fragBuilder->codeAppendf(
"(invR1);\n } else {\n x_t = sqrt(temp) "
"- p.x * float(invR1);\n }\n }\n }\n "
" @if (!%s) {\n if (x_t <= 0.0) {\n v = "
"-1.0;\n }\n }\n @if (%s) {\n "
"@if (%s) {\n t = x_t;\n } else {\n "
" t = x_t + float(fx);\n }\n } else {\n "
" @if (%s) {\n ",
";\n } else {\n x_t = sqrt(temp) - p.x * "
"float(invR1);\n }\n }\n }\n "
" @if (!%s) {\n if (x_t <= 0.0) {\n v = -1.0;\n "
" }\n }\n @if (%s) {\n @if (%s) "
"{\n t = x_t;\n } else {\n t "
"= x_t + float(fx);\n }\n } else {\n @if "
"(%s) {\n ",
(_outer.isWellBehaved() ? "true" : "false"),
(_outer.isRadiusIncreasing() ? "true" : "false"),
(_outer.isNativelyFocal() ? "true" : "false"),

View File

@ -119,7 +119,7 @@ void main() {
break;
}
sk_OutColor = half4(t, v, 0, 0);
sk_OutColor = half4(half(t), v, 0, 0);
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -104,7 +104,7 @@ void main() {
}
}
sk_OutColor = t * scale + bias;
sk_OutColor = half4(t * scale + bias);
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -571,8 +571,8 @@ public:
fragBuilder->codeAppendf("half edgeAlpha;");
// keep the derivative instructions outside the conditional
fragBuilder->codeAppendf("half2 duvdx = dFdx(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = dFdy(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s.xy));", v.fsIn());
fragBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn());
// today we know z and w are in device space. We could use derivatives
fragBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(),

View File

@ -405,7 +405,7 @@ public:
f->codeAppendf("float x_plus_1=%s.x, y=%s.y;", arcCoord.fsIn(), arcCoord.fsIn());
f->codeAppendf("half coverage;");
f->codeAppendf("if (0 == x_plus_1) {");
f->codeAppendf( "coverage = y;"); // We are a non-arc pixel (i.e., linear coverage).
f->codeAppendf( "coverage = half(y);"); // We are a non-arc pixel (i.e., linear coverage).
f->codeAppendf("} else {");
f->codeAppendf( "float fn = x_plus_1 * (x_plus_1 - 2);"); // fn = (x+1)*(x-1) = x^2-1
f->codeAppendf( "fn = fma(y,y, fn);"); // fn = x^2 + y^2 - 1
@ -416,7 +416,7 @@ public:
f->codeAppendf("float gx=%s.z, gy=%s.w;", arcCoord.fsIn(), arcCoord.fsIn());
f->codeAppendf("float fnwidth = abs(gx) + abs(gy);");
}
f->codeAppendf( "half d = fn/fnwidth;");
f->codeAppendf( "half d = half(fn/fnwidth);");
f->codeAppendf( "coverage = clamp(.5 - d, 0, 1);");
f->codeAppendf("}");
f->codeAppendf("%s = half4(coverage);", args.fOutputCoverage);

View File

@ -860,10 +860,11 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
args.fFPCoordTransformHandler);
// transforms all points so that we can compare them to our test circle
fragBuilder->codeAppendf("half xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
fragBuilder->codeAppendf("half xShifted = half(%s.x - floor(%s.x / %s.z) * %s.z);",
dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn(),
dashParams.fsIn());
fragBuilder->codeAppendf("half2 fragPosShifted = half2(xShifted, %s.y);", dashParams.fsIn());
fragBuilder->codeAppendf("half2 fragPosShifted = half2(xShifted, half(%s.y));",
dashParams.fsIn());
fragBuilder->codeAppendf("half2 center = half2(%s.y, 0.0);", circleParams.fsIn());
fragBuilder->codeAppend("half dist = length(center - fragPosShifted);");
if (dce.aaMode() != AAMode::kNone) {
@ -1059,18 +1060,23 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
args.fFPCoordTransformHandler);
// transforms all points so that we can compare them to our test rect
fragBuilder->codeAppendf("half xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
fragBuilder->codeAppendf("half xShifted = half(%s.x - floor(%s.x / %s.z) * %s.z);",
inDashParams.fsIn(), inDashParams.fsIn(), inDashParams.fsIn(),
inDashParams.fsIn());
fragBuilder->codeAppendf("half2 fragPosShifted = half2(xShifted, %s.y);", inDashParams.fsIn());
fragBuilder->codeAppendf("half2 fragPosShifted = half2(xShifted, half(%s.y));",
inDashParams.fsIn());
if (de.aaMode() == AAMode::kCoverage) {
// The amount of coverage removed in x and y by the edges is computed as a pair of negative
// numbers, xSub and ySub.
fragBuilder->codeAppend("half xSub, ySub;");
fragBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRectParams.fsIn());
fragBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inRectParams.fsIn());
fragBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRectParams.fsIn());
fragBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inRectParams.fsIn());
fragBuilder->codeAppendf("xSub = half(min(fragPosShifted.x - %s.x, 0.0));",
inRectParams.fsIn());
fragBuilder->codeAppendf("xSub += half(min(%s.z - fragPosShifted.x, 0.0));",
inRectParams.fsIn());
fragBuilder->codeAppendf("ySub = half(min(fragPosShifted.y - %s.y, 0.0));",
inRectParams.fsIn());
fragBuilder->codeAppendf("ySub += half(min(%s.w - fragPosShifted.y, 0.0));",
inRectParams.fsIn());
// Now compute coverage in x and y and multiply them to get the fraction of the pixel
// covered.
fragBuilder->codeAppendf(
@ -1079,8 +1085,10 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// For MSAA, we don't modulate the alpha by the Y distance, since MSAA coverage will handle
// AA on the the top and bottom edges. The shader is only responsible for intra-dash alpha.
fragBuilder->codeAppend("half xSub;");
fragBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRectParams.fsIn());
fragBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inRectParams.fsIn());
fragBuilder->codeAppendf("xSub = half(min(fragPosShifted.x - %s.x, 0.0));",
inRectParams.fsIn());
fragBuilder->codeAppendf("xSub += half(min(%s.z - fragPosShifted.x, 0.0));",
inRectParams.fsIn());
// Now compute coverage in x to get the fraction of the pixel covered.
fragBuilder->codeAppendf("half alpha = (1.0 + max(xSub, -1.0));");
} else {

View File

@ -157,28 +157,28 @@ private:
args.fFPCoordTransformHandler);
fragBuilder->codeAppend("float d = length(circleEdge.xy);");
fragBuilder->codeAppend("half distanceToOuterEdge = circleEdge.z * (1.0 - d);");
fragBuilder->codeAppend("half distanceToOuterEdge = half(circleEdge.z * (1.0 - d));");
fragBuilder->codeAppend("half edgeAlpha = saturate(distanceToOuterEdge);");
if (cgp.fStroke) {
fragBuilder->codeAppend(
"half distanceToInnerEdge = circleEdge.z * (d - circleEdge.w);");
"half distanceToInnerEdge = half(circleEdge.z * (d - circleEdge.w));");
fragBuilder->codeAppend("half innerAlpha = saturate(distanceToInnerEdge);");
fragBuilder->codeAppend("edgeAlpha *= innerAlpha;");
}
if (cgp.fInClipPlane.isInitialized()) {
fragBuilder->codeAppend(
"half clip = saturate(circleEdge.z * dot(circleEdge.xy, clipPlane.xy) + "
"clipPlane.z);");
"half clip = half(saturate(circleEdge.z * dot(circleEdge.xy, "
"clipPlane.xy) + clipPlane.z));");
if (cgp.fInIsectPlane.isInitialized()) {
fragBuilder->codeAppend(
"clip *= saturate(circleEdge.z * dot(circleEdge.xy, isectPlane.xy) + "
"isectPlane.z);");
"clip *= half(saturate(circleEdge.z * dot(circleEdge.xy, "
"isectPlane.xy) + isectPlane.z));");
}
if (cgp.fInUnionPlane.isInitialized()) {
fragBuilder->codeAppend(
"clip = saturate(clip + saturate(circleEdge.z * dot(circleEdge.xy, "
"unionPlane.xy) + unionPlane.z));");
"clip = saturate(clip + half(saturate(circleEdge.z * dot(circleEdge.xy,"
" unionPlane.xy) + unionPlane.z)));");
}
fragBuilder->codeAppend("edgeAlpha *= clip;");
if (cgp.fInRoundCapCenters.isInitialized()) {
@ -186,10 +186,10 @@ private:
// by the clip planes. The inverse of the clip planes is applied so that there
// is no double counting.
fragBuilder->codeAppendf(
"half dcap1 = circleEdge.z * (%s - length(circleEdge.xy - "
" roundCapCenters.xy));"
"half dcap2 = circleEdge.z * (%s - length(circleEdge.xy - "
" roundCapCenters.zw));"
"half dcap1 = half(circleEdge.z * (%s - length(circleEdge.xy - "
" roundCapCenters.xy)));"
"half dcap2 = half(circleEdge.z * (%s - length(circleEdge.xy - "
" roundCapCenters.zw)));"
"half capAlpha = (1 - clip) * (max(dcap1, 0) + max(dcap2, 0));"
"edgeAlpha = min(edgeAlpha + capAlpha, 1.0);",
capRadius.fsIn(), capRadius.fsIn());
@ -327,10 +327,10 @@ private:
// The two boundary dash intervals are stored in wrapDashes.xy and .zw and fed
// to the fragment shader as a varying.
float4 wrapDashes;
half lastIntervalLength = mod(6.28318530718, dashParams.y);
half lastIntervalLength = mod(6.28318530718, half(dashParams.y));
// We can happen to be perfectly divisible.
if (0 == lastIntervalLength) {
lastIntervalLength = dashParams.y;
lastIntervalLength = half(dashParams.y);
}
// Let 'l' be the last interval before reaching 2 pi.
// Based on the phase determine whether (l-1)th, l-th, or (l+1)th interval's
@ -338,9 +338,9 @@ private:
// interval.
half offset = 0;
if (-dashParams.w >= lastIntervalLength) {
offset = -dashParams.y;
offset = half(-dashParams.y);
} else if (dashParams.w > dashParams.y - lastIntervalLength) {
offset = dashParams.y;
offset = half(dashParams.y);
}
wrapDashes.x = -lastIntervalLength + offset - dashParams.w;
// The end of this dash may be beyond the 2 pi and therefore clipped. Hence the
@ -351,9 +351,9 @@ private:
// "corresponding" dash appears in the 0th interval and is closest to l.
offset = 0;
if (dashParams.w >= dashParams.x) {
offset = dashParams.y;
offset = half(dashParams.y);
} else if (-dashParams.w > dashParams.y - dashParams.x) {
offset = -dashParams.y;
offset = half(-dashParams.y);
}
wrapDashes.z = lastIntervalLength + offset - dashParams.w;
wrapDashes.w = wrapDashes.z + dashParams.x;
@ -361,7 +361,7 @@ private:
// circle.
wrapDashes.z = max(wrapDashes.z, lastIntervalLength);
)");
vertBuilder->codeAppendf("%s = wrapDashes;", wrapDashes.vsOut());
vertBuilder->codeAppendf("%s = half4(wrapDashes);", wrapDashes.vsOut());
vertBuilder->codeAppendf("%s = lastIntervalLength;", lastIntervalLength.vsOut());
fragBuilder->codeAppendf("half4 wrapDashes = %s;", wrapDashes.fsIn());
fragBuilder->codeAppendf("half lastIntervalLength = %s;", lastIntervalLength.fsIn());
@ -398,27 +398,30 @@ private:
float d = length(circleEdge.xy) * circleEdge.z;
// Compute coverage from outer/inner edges of the stroke.
half distanceToOuterEdge = circleEdge.z - d;
half distanceToOuterEdge = half(circleEdge.z - d);
half edgeAlpha = saturate(distanceToOuterEdge);
half distanceToInnerEdge = d - circleEdge.z * circleEdge.w;
half distanceToInnerEdge = half(d - circleEdge.z * circleEdge.w);
half innerAlpha = saturate(distanceToInnerEdge);
edgeAlpha *= innerAlpha;
half angleFromStart = atan(circleEdge.y, circleEdge.x) - dashParams.z;
half angleFromStart = half(atan(circleEdge.y, circleEdge.x) - dashParams.z);
angleFromStart = mod(angleFromStart, 6.28318530718);
float x = mod(angleFromStart, dashParams.y);
// Convert the radial distance from center to pixel into a diameter.
d *= 2;
half2 currDash = half2(-dashParams.w, dashParams.x - dashParams.w);
half2 nextDash = half2(dashParams.y - dashParams.w,
dashParams.y + dashParams.x - dashParams.w);
half2 prevDash = half2(-dashParams.y - dashParams.w,
-dashParams.y + dashParams.x - dashParams.w);
half2 currDash = half2(half(-dashParams.w), half(dashParams.x) -
half(dashParams.w));
half2 nextDash = half2(half(dashParams.y) - half(dashParams.w),
half(dashParams.y) + half(dashParams.x) -
half(dashParams.w));
half2 prevDash = half2(half(-dashParams.y) - half(dashParams.w),
half(-dashParams.y) + half(dashParams.x) -
half(dashParams.w));
half dashAlpha = 0;
)");
fragBuilder->codeAppendf(R"(
if (angleFromStart - x + dashParams.y >= 6.28318530718) {
dashAlpha += %s(x - wrapDashes.z, d) * %s(wrapDashes.w - x, d);
dashAlpha += half(%s(x - wrapDashes.z, d) * %s(wrapDashes.w - x, d));
currDash.y = min(currDash.y, lastIntervalLength);
if (nextDash.x >= lastIntervalLength) {
// The next dash is outside the 0..2pi range, throw it away
@ -431,7 +434,7 @@ private:
)", fnName.c_str(), fnName.c_str());
fragBuilder->codeAppendf(R"(
if (angleFromStart - x - dashParams.y < -0.01) {
dashAlpha += %s(x - wrapDashes.x, d) * %s(wrapDashes.y - x, d);
dashAlpha += half(%s(x - wrapDashes.x, d) * %s(wrapDashes.y - x, d));
currDash.x = max(currDash.x, 0);
if (prevDash.y <= 0) {
// The previous dash is outside the 0..2pi range, throw it away
@ -443,9 +446,9 @@ private:
}
)", fnName.c_str(), fnName.c_str());
fragBuilder->codeAppendf(R"(
dashAlpha += %s(x - currDash.x, d) * %s(currDash.y - x, d);
dashAlpha += %s(x - nextDash.x, d) * %s(nextDash.y - x, d);
dashAlpha += %s(x - prevDash.x, d) * %s(prevDash.y - x, d);
dashAlpha += half(%s(x - currDash.x, d) * %s(currDash.y - x, d));
dashAlpha += half(%s(x - nextDash.x, d) * %s(nextDash.y - x, d));
dashAlpha += half(%s(x - prevDash.x, d) * %s(prevDash.y - x, d));
dashAlpha = min(dashAlpha, 1);
edgeAlpha *= dashAlpha;
)", fnName.c_str(), fnName.c_str(), fnName.c_str(), fnName.c_str(), fnName.c_str(),
@ -581,7 +584,7 @@ private:
// avoid calling inversesqrt on zero.
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
fragBuilder->codeAppend("half invlen = inversesqrt(grad_dot);");
fragBuilder->codeAppend("half invlen = half(inversesqrt(grad_dot));");
fragBuilder->codeAppend("half edgeAlpha = saturate(0.5-test*invlen);");
// for inner curve
@ -590,7 +593,7 @@ private:
ellipseRadii.fsIn());
fragBuilder->codeAppend("test = dot(offset, offset) - 1.0;");
fragBuilder->codeAppendf("grad = 2.0*offset*%s.zw;", ellipseRadii.fsIn());
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
fragBuilder->codeAppend("invlen = half(inversesqrt(dot(grad, grad)));");
fragBuilder->codeAppend("edgeAlpha *= saturate(0.5+test*invlen);");
}
@ -720,8 +723,8 @@ private:
// for outer curve
fragBuilder->codeAppendf("half2 scaledOffset = %s.xy;", offsets0.fsIn());
fragBuilder->codeAppend("half test = dot(scaledOffset, scaledOffset) - 1.0;");
fragBuilder->codeAppendf("half2 duvdx = dFdx(%s);", offsets0.fsIn());
fragBuilder->codeAppendf("half2 duvdy = dFdy(%s);", offsets0.fsIn());
fragBuilder->codeAppendf("half2 duvdx = half2(dFdx(%s));", offsets0.fsIn());
fragBuilder->codeAppendf("half2 duvdy = half2(dFdy(%s));", offsets0.fsIn());
fragBuilder->codeAppendf(
"half2 grad = half2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
@ -730,7 +733,7 @@ private:
fragBuilder->codeAppend("half grad_dot = dot(grad, grad);");
// avoid calling inversesqrt on zero.
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
fragBuilder->codeAppend("half invlen = inversesqrt(grad_dot);");
fragBuilder->codeAppend("half invlen = half(inversesqrt(grad_dot));");
if (DIEllipseStyle::kHairline == diegp.fStyle) {
// can probably do this with one step
fragBuilder->codeAppend("half edgeAlpha = saturate(1.0-test*invlen);");
@ -743,13 +746,13 @@ private:
if (DIEllipseStyle::kStroke == diegp.fStyle) {
fragBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
fragBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
fragBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
fragBuilder->codeAppendf("duvdx = half2(dFdx(%s));", offsets1.fsIn());
fragBuilder->codeAppendf("duvdy = half2(dFdy(%s));", offsets1.fsIn());
fragBuilder->codeAppendf(
"grad = half2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn());
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
fragBuilder->codeAppend("invlen = half(inversesqrt(dot(grad, grad)));");
fragBuilder->codeAppend("edgeAlpha *= saturate(0.5+test*invlen);");
}

View File

@ -659,12 +659,12 @@ public:
coverage.vsOut(), gp.fPosition.name());
}
args.fFragBuilder->codeAppendf("%s = float4(%s);",
args.fFragBuilder->codeAppendf("%s = half4(half(%s));",
args.fOutputCoverage, coverage.fsIn());
} else {
// Set coverage to 1, since it's either non-AA or the coverage was already
// folded into the output color
args.fFragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage);
args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
}
}
GrGLSLColorSpaceXformHelper fTextureColorSpaceXformHelper;

View File

@ -55,7 +55,7 @@ bool GrVkCopyManager::createCopyProgram(GrVkGpu* gpu) {
"// Copy Program VS\n"
"void main() {"
"vTexCoord = inPosition * uTexCoordXform.xy + uTexCoordXform.zw;"
"vTexCoord = half2(inPosition * uTexCoordXform.xy + uTexCoordXform.zw);"
"sk_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;"
"sk_Position.zw = half2(0, 1);"
"}"

View File

@ -204,6 +204,7 @@ bool GrCompileVkShaderModule(const GrVkGpu* gpu,
SkSL::String(shaderString),
settings);
if (!program) {
printf("%s\n", shaderString);
SkDebugf("SkSL error:\n%s\n", gpu->shaderCompiler()->errorText().c_str());
SkASSERT(false);
}

View File

@ -168,32 +168,33 @@ private:
kFloat3_GrSLType, kDefault_GrSLPrecision,
"AmbientColor", &ambientColorUniName);
fragBuilder->codeAppendf("float4 diffuseColor = %s;", args.fInputColor);
fragBuilder->codeAppendf("half4 diffuseColor = %s;", args.fInputColor);
SkString dstNormalName("dstNormal");
this->emitChild(0, &dstNormalName, args);
fragBuilder->codeAppendf("float3 normal = %s.xyz;", dstNormalName.c_str());
fragBuilder->codeAppend( "float3 result = float3(0.0);");
fragBuilder->codeAppend( "half3 result = half3(0.0);");
// diffuse light
if (lightingFP.fDirectionalLights.count() != 0) {
fragBuilder->codeAppendf("for (int i = 0; i < %d; i++) {",
lightingFP.fDirectionalLights.count());
// TODO: modulate the contribution from each light based on the shadow map
fragBuilder->codeAppendf(" float NdotL = saturate(dot(normal, %s[i]));",
fragBuilder->codeAppendf(" half NdotL = saturate(half(dot(normal, %s[i])));",
lightDirsUniName);
fragBuilder->codeAppendf(" result += %s[i]*diffuseColor.rgb*NdotL;",
fragBuilder->codeAppendf(" result += half3(%s[i])*diffuseColor.rgb*NdotL;",
lightColorsUniName);
fragBuilder->codeAppend("}");
}
// ambient light
fragBuilder->codeAppendf("result += %s * diffuseColor.rgb;", ambientColorUniName);
fragBuilder->codeAppendf("result += half3(%s) * diffuseColor.rgb;",
ambientColorUniName);
// Clamping to alpha (equivalent to an unpremul'd clamp to 1.0)
fragBuilder->codeAppendf("%s = float4(clamp(result.rgb, 0.0, diffuseColor.a), "
fragBuilder->codeAppendf("%s = half4(clamp(result.rgb, 0.0, diffuseColor.a), "
"diffuseColor.a);", args.fOutputColor);
}

View File

@ -1015,7 +1015,7 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
}
// There are rounding errors if the floor operation is not performed here
fragBuilder->codeAppendf("\n\t\thalf2 %s = floor(%s.xy) * %s;",
fragBuilder->codeAppendf("\n\t\thalf2 %s = half2(floor(%s.xy) * %s);",
noiseVec, vCoords.c_str(), baseFrequencyUni);
// Clear the color accumulator
@ -1292,10 +1292,10 @@ void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) {
GrShaderVar("p", kHalf3_GrSLType)
};
SkString gradFuncName;
SkString gradCode("return dot(");
SkString gradCode("return half(dot(");
fragBuilder->appendTextureLookup(&gradCode, args.fTexSamplers[1], "float2(fract(x / 16.0), 0.0)",
kHalf2_GrSLType);
gradCode.append(".rgb * 255.0 - float3(1.0), p);");
gradCode.append(".rgb * 255.0 - float3(1.0), p));");
fragBuilder->emitFunction(kHalf_GrSLType, "grad", SK_ARRAY_COUNT(gradArgs), gradArgs,
gradCode.c_str(), &gradFuncName);
@ -1363,7 +1363,7 @@ void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) {
fragBuilder->emitFunction(kHalf_GrSLType, "noiseOctaves", SK_ARRAY_COUNT(noiseOctavesArgs),
noiseOctavesArgs, noiseOctavesCode.c_str(), &noiseOctavesFuncName);
fragBuilder->codeAppendf("half2 coords = %s * %s;", vCoords.c_str(), baseFrequencyUni);
fragBuilder->codeAppendf("half2 coords = half2(%s * %s);", vCoords.c_str(), baseFrequencyUni);
fragBuilder->codeAppendf("half r = %s(half3(coords, %s));", noiseOctavesFuncName.c_str(),
zUni);
fragBuilder->codeAppendf("half g = %s(half3(coords, %s + 0000.0));",

View File

@ -21,23 +21,25 @@ public:
Context()
: fInvalid_Type(new Type("<INVALID>"))
, fVoid_Type(new Type("void"))
, fDouble_Type(new Type("double", Type::kFloat_NumberKind, 4))
, fFloatLiteral_Type(new Type("$floatLiteral", Type::kFloat_NumberKind, 3))
, fIntLiteral_Type(new Type("$intLiteral", Type::kSigned_NumberKind, 1))
, fDouble_Type(new Type("double", Type::kFloat_NumberKind, 6))
, fDouble2_Type(new Type("double2", *fDouble_Type, 2))
, fDouble3_Type(new Type("double3", *fDouble_Type, 3))
, fDouble4_Type(new Type("double4", *fDouble_Type, 4))
, fFloat_Type(new Type("float", Type::kFloat_NumberKind, 3))
, fFloat_Type(new Type("float", Type::kFloat_NumberKind, 5))
, fFloat2_Type(new Type("float2", *fFloat_Type, 2))
, fFloat3_Type(new Type("float3", *fFloat_Type, 3))
, fFloat4_Type(new Type("float4", *fFloat_Type, 4))
, fHalf_Type(new Type("half", Type::kFloat_NumberKind, 2))
, fHalf_Type(new Type("half", Type::kFloat_NumberKind, 4))
, fHalf2_Type(new Type("half2", *fHalf_Type, 2))
, fHalf3_Type(new Type("half3", *fHalf_Type, 3))
, fHalf4_Type(new Type("half4", *fHalf_Type, 4))
, fUInt_Type(new Type("uint", Type::kUnsigned_NumberKind, 1))
, fUInt_Type(new Type("uint", Type::kUnsigned_NumberKind, 2))
, fUInt2_Type(new Type("uint2", *fUInt_Type, 2))
, fUInt3_Type(new Type("uint3", *fUInt_Type, 3))
, fUInt4_Type(new Type("uint4", *fUInt_Type, 4))
, fInt_Type(new Type("int", Type::kSigned_NumberKind, 1))
, fInt_Type(new Type("int", Type::kSigned_NumberKind, 2))
, fInt2_Type(new Type("int2", *fInt_Type, 2))
, fInt3_Type(new Type("int3", *fInt_Type, 3))
, fInt4_Type(new Type("int4", *fInt_Type, 4))
@ -206,6 +208,8 @@ public:
const std::unique_ptr<Type> fInvalid_Type;
const std::unique_ptr<Type> fVoid_Type;
const std::unique_ptr<Type> fFloatLiteral_Type;
const std::unique_ptr<Type> fIntLiteral_Type;
const std::unique_ptr<Type> fDouble_Type;
const std::unique_ptr<Type> fDouble2_Type;

View File

@ -90,14 +90,10 @@ String GLSLCodeGenerator::getTypeName(const Type& type) {
else if (component == *fContext.fDouble_Type) {
result = "dvec";
}
else if (component == *fContext.fInt_Type ||
component == *fContext.fShort_Type ||
component == *fContext.fByte_Type) {
else if (component.isSigned()) {
result = "ivec";
}
else if (component == *fContext.fUInt_Type ||
component == *fContext.fUShort_Type ||
component == *fContext.fUByte_Type) {
else if (component.isUnsigned()) {
result = "uvec";
}
else if (component == *fContext.fBool_Type) {
@ -703,7 +699,9 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
void GLSLCodeGenerator::writeConstructor(const Constructor& c, Precedence parentPrecedence) {
if (c.fArguments.size() == 1 &&
this->getTypeName(c.fType) == this->getTypeName(c.fArguments[0]->fType)) {
(this->getTypeName(c.fType) == this->getTypeName(c.fArguments[0]->fType) ||
(c.fType.kind() == Type::kScalar_Kind &&
c.fArguments[0]->fType == *fContext.fFloatLiteral_Type))) {
// in cases like half(float), they're different types as far as SkSL is concerned but the
// same type as far as GLSL is concerned. We avoid a redundant float(float) by just writing
// out the inner expression here.

View File

@ -188,6 +188,9 @@ std::unique_ptr<Statement> IRGenerator::convertStatement(const ASTStatement& sta
case ASTStatement::kExpression_Kind: {
std::unique_ptr<Statement> result =
this->convertExpressionStatement((ASTExpressionStatement&) statement);
if (!result) {
return nullptr;
}
if (fRTAdjust && Program::kGeometry_Kind == fKind) {
SkASSERT(result->fKind == Statement::kExpression_Kind);
Expression& expr = *((ExpressionStatement&) *result).fExpression;
@ -1101,8 +1104,17 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr
if (type.kind() == Type::kScalar_Kind) {
std::vector<std::unique_ptr<Expression>> args;
args.push_back(std::move(expr));
ASTIdentifier id(-1, type.fName);
std::unique_ptr<Expression> ctor = this->convertIdentifier(id);
std::unique_ptr<Expression> ctor;
if (type == *fContext.fFloatLiteral_Type) {
ctor = this->convertIdentifier(ASTIdentifier(-1, "float"));
} else if (type == *fContext.fIntLiteral_Type) {
ctor = this->convertIdentifier(ASTIdentifier(-1, "int"));
} else {
ctor = this->convertIdentifier(ASTIdentifier(-1, type.fName));
}
if (!ctor) {
printf("error, null identifier: %s\n", String(type.fName).c_str());
}
SkASSERT(ctor);
return this->call(-1, std::move(ctor), std::move(args));
}
@ -1405,8 +1417,7 @@ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
default: return nullptr;
}
}
if (left.fType.kind() == Type::kVector_Kind &&
left.fType.componentType() == *fContext.fFloat_Type &&
if (left.fType.kind() == Type::kVector_Kind && left.fType.componentType().isFloat() &&
left.fType == right.fType) {
SkASSERT(left.fKind == Expression::kConstructor_Kind);
SkASSERT(right.fKind == Expression::kConstructor_Kind);
@ -1481,8 +1492,8 @@ std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(
!Compiler::IsAssignment(expression.fOperator))) {
fErrors.error(expression.fOffset, String("type mismatch: '") +
Compiler::OperatorName(expression.fOperator) +
"' cannot operate on '" + left->fType.fName +
"', '" + right->fType.fName + "'");
"' cannot operate on '" + left->fType.description() +
"', '" + right->fType.description() + "'");
return nullptr;
}
if (Compiler::IsAssignment(expression.fOperator)) {
@ -1528,8 +1539,8 @@ std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(
if (!determine_binary_type(fContext, Token::EQEQ, ifTrue->fType, ifFalse->fType, &trueType,
&falseType, &resultType, true) || trueType != falseType) {
fErrors.error(expression.fOffset, "ternary operator result mismatch: '" +
ifTrue->fType.fName + "', '" +
ifFalse->fType.fName + "'");
ifTrue->fType.description() + "', '" +
ifFalse->fType.description() + "'");
return nullptr;
}
ifTrue = this->coerce(std::move(ifTrue), *trueType);
@ -1807,18 +1818,14 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(
}
switch (expression.fOperator) {
case Token::PLUS:
if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind) {
if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind &&
base->fType != *fContext.fFloatLiteral_Type) {
fErrors.error(expression.fOffset,
"'+' cannot operate on '" + base->fType.description() + "'");
return nullptr;
}
return base;
case Token::MINUS:
if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind) {
fErrors.error(expression.fOffset,
"'-' cannot operate on '" + base->fType.description() + "'");
return nullptr;
}
if (base->fKind == Expression::kIntLiteral_Kind) {
return std::unique_ptr<Expression>(new IntLiteral(fContext, base->fOffset,
-((IntLiteral&) *base).fValue));
@ -1828,6 +1835,11 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(
return std::unique_ptr<Expression>(new FloatLiteral(fContext, base->fOffset,
value));
}
if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind) {
fErrors.error(expression.fOffset,
"'-' cannot operate on '" + base->fType.description() + "'");
return nullptr;
}
return std::unique_ptr<Expression>(new PrefixExpression(Token::MINUS, std::move(base)));
case Token::PLUSPLUS:
if (!base->fType.isNumber()) {

View File

@ -357,8 +357,7 @@ bool MetalCodeGenerator::canCoerce(const Type& t1, const Type& t2) {
if (t1.columns() > 1) {
return this->canCoerce(t1.componentType(), t2.componentType());
}
return ((t1 == *fContext.fFloat_Type || t1 == *fContext.fHalf_Type) &&
(t2 == *fContext.fFloat_Type || t2 == *fContext.fHalf_Type));
return t1.isFloat() && t2.isFloat();
}
void MetalCodeGenerator::writeConstructor(const Constructor& c, Precedence parentPrecedence) {

View File

@ -433,13 +433,13 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
}
Type SPIRVCodeGenerator::getActualType(const Type& type) {
if (type == *fContext.fHalf_Type) {
if (type.isFloat()) {
return *fContext.fFloat_Type;
}
if (type == *fContext.fShort_Type || type == *fContext.fByte_Type) {
if (type.isSigned()) {
return *fContext.fInt_Type;
}
if (type == *fContext.fUShort_Type || type == *fContext.fUByte_Type) {
if (type.isUnsigned()) {
return *fContext.fUInt_Type;
}
if (type.kind() == Type::kMatrix_Kind || type.kind() == Type::kVector_Kind) {
@ -472,11 +472,13 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou
case Type::kScalar_Kind:
if (type == *fContext.fBool_Type) {
this->writeInstruction(SpvOpTypeBool, result, fConstantBuffer);
} else if (type == *fContext.fInt_Type) {
} else if (type == *fContext.fInt_Type || type == *fContext.fShort_Type ||
type == *fContext.fIntLiteral_Type) {
this->writeInstruction(SpvOpTypeInt, result, 32, 1, fConstantBuffer);
} else if (type == *fContext.fUInt_Type) {
} else if (type == *fContext.fUInt_Type || type == *fContext.fUShort_Type) {
this->writeInstruction(SpvOpTypeInt, result, 32, 0, fConstantBuffer);
} else if (type == *fContext.fFloat_Type) {
} else if (type == *fContext.fFloat_Type || type == *fContext.fHalf_Type ||
type == *fContext.fFloatLiteral_Type) {
this->writeInstruction(SpvOpTypeFloat, result, 32, fConstantBuffer);
} else if (type == *fContext.fDouble_Type) {
this->writeInstruction(SpvOpTypeFloat, result, 64, fConstantBuffer);
@ -2043,7 +2045,8 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu
}
return result;
} else {
ABORT("unsupported binary expression: %s", b.description().c_str());
ABORT("unsupported binary expression: %s (%s, %s)", b.description().c_str(),
b.fLeft->fType.description().c_str(), b.fRight->fType.description().c_str());
}
} else {
tmp = this->getActualType(b.fLeft->fType);
@ -2473,7 +2476,7 @@ SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) {
}
SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
if (f.fType == *fContext.fFloat_Type || f.fType == *fContext.fHalf_Type) {
if (f.fType != *fContext.fDouble_Type) {
float value = (float) f.fValue;
auto entry = fFloatConstants.find(value);
if (entry == fFloatConstants.end()) {
@ -2488,7 +2491,6 @@ SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
}
return entry->second;
} else {
SkASSERT(f.fType == *fContext.fDouble_Type);
auto entry = fDoubleConstants.find(f.fValue);
if (entry == fDoubleConstants.end()) {
SpvId result = this->nextId();

View File

@ -32,15 +32,13 @@ struct Constructor : public Expression {
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override {
if (fArguments.size() == 1 && fArguments[0]->fKind == Expression::kIntLiteral_Kind) {
if (fType == *irGenerator.fContext.fFloat_Type ||
fType == *irGenerator.fContext.fHalf_Type) {
if (fType.isFloat()) {
// promote float(1) to 1.0
int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
return std::unique_ptr<Expression>(new FloatLiteral(irGenerator.fContext,
fOffset,
intValue));
} else if (fType == *irGenerator.fContext.fUInt_Type ||
fType == *irGenerator.fContext.fUShort_Type) {
} else if (fType.isInteger()) {
// promote uint(1) to 1u
int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
return std::unique_ptr<Expression>(new IntLiteral(fOffset,
@ -107,10 +105,10 @@ struct Constructor : public Expression {
const FloatLiteral fzero(context, -1, 0);
const IntLiteral izero(context, -1, 0);
const Expression* zero;
if (fType.componentType() == *context.fFloat_Type) {
if (fType.componentType().isFloat()) {
zero = &fzero;
} else {
SkASSERT(fType.componentType() == *context.fInt_Type);
SkASSERT(fType.componentType().isInteger());
zero = &izero;
}
for (int col = 0; col < fType.columns(); col++) {

View File

@ -18,7 +18,7 @@ namespace SkSL {
*/
struct FloatLiteral : public Expression {
FloatLiteral(const Context& context, int offset, double value)
: INHERITED(offset, kFloatLiteral_Kind, *context.fFloat_Type)
: INHERITED(offset, kFloatLiteral_Kind, *context.fFloatLiteral_Type)
, fValue(value) {}
FloatLiteral(int offset, double value, const Type* type)
@ -37,6 +37,13 @@ struct FloatLiteral : public Expression {
return true;
}
int coercionCost(const Type& target) const override {
if (target.isFloat()) {
return 0;
}
return INHERITED::coercionCost(target);
}
bool compareConstant(const Context& context, const Expression& other) const override {
FloatLiteral& f = (FloatLiteral&) other;
return fValue == f.fValue;

View File

@ -45,7 +45,7 @@ struct IntLiteral : public Expression {
}
int coercionCost(const Type& target) const override {
if (target.isUnsigned()) {
if (target.isSigned() || target.isUnsigned() || target.isFloat()) {
return 0;
}
return INHERITED::coercionCost(target);

View File

@ -106,13 +106,13 @@ struct Swizzle : public Expression {
if (fBase->fKind == Expression::kConstructor_Kind && fBase->isConstant()) {
// we're swizzling a constant vector, e.g. float4(1).x. Simplify it.
SkASSERT(fBase->fKind == Expression::kConstructor_Kind);
if (fType == *irGenerator.fContext.fInt_Type) {
if (fType.isInteger()) {
SkASSERT(fComponents.size() == 1);
int64_t value = ((Constructor&) *fBase).getIVecComponent(fComponents[0]);
return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
-1,
value));
} else if (fType == *irGenerator.fContext.fFloat_Type) {
} else if (fType.isFloat()) {
SkASSERT(fComponents.size() == 1);
double value = ((Constructor&) *fBase).getFVecComponent(fComponents[0]);
return std::unique_ptr<Expression>(new FloatLiteral(irGenerator.fContext,

View File

@ -26,17 +26,8 @@ int Type::coercionCost(const Type& other) const {
}
return INT_MAX;
}
if (this->isNumber() && other.isFloat()) {
return 1;
}
if (this->isSigned() && other.isSigned()) {
return 1;
}
if (this->isUnsigned() && other.isUnsigned()) {
return 1;
}
if (this->isUnsigned() && other.isSigned() && other.priority() > priority()) {
return 1;
if (this->isNumber() && other.isNumber() && other.priority() > this->priority()) {
return other.priority() - this->priority();
}
for (size_t i = 0; i < fCoercibleTypes.size(); i++) {
if (*fCoercibleTypes[i] == other) {
@ -51,7 +42,7 @@ const Type& Type::toCompound(const Context& context, int columns, int rows) cons
if (columns == 1 && rows == 1) {
return *this;
}
if (*this == *context.fFloat_Type) {
if (*this == *context.fFloat_Type || *this == *context.fFloatLiteral_Type) {
switch (rows) {
case 1:
switch (columns) {
@ -147,7 +138,7 @@ const Type& Type::toCompound(const Context& context, int columns, int rows) cons
}
default: ABORT("unsupported row count (%d)", rows);
}
} else if (*this == *context.fInt_Type) {
} else if (*this == *context.fInt_Type || *this == *context.fIntLiteral_Type) {
switch (rows) {
case 1:
switch (columns) {

View File

@ -197,6 +197,12 @@ public:
}
String description() const override {
if (fNameString == "$floatLiteral") {
return "float";
}
if (fNameString == "$intLiteral") {
return "int";
}
return fNameString;
}

View File

@ -22,35 +22,68 @@ $genType log($genType x);
$genType exp2($genType x);
$genType log2($genType x);
$genType sqrt($genType x);
$genHType radians($genHType degrees);
$genHType sin($genHType angle);
$genHType cos($genHType angle);
$genHType tan($genHType angle);
$genHType asin($genHType x);
$genHType acos($genHType x);
$genHType atan($genHType y, $genHType x);
$genHType atan($genHType y_over_x);
$genHType sinh($genHType x);
$genHType cosh($genHType x);
$genHType tanh($genHType x);
$genHType asinh($genHType x);
$genHType acosh($genHType x);
$genHType atanh($genHType x);
$genHType pow($genHType x, $genHType y);
$genHType exp($genHType x);
$genHType log($genHType x);
$genHType exp2($genHType x);
$genHType log2($genHType x);
$genHType sqrt($genHType x);
//$genDType sqrt($genDType x);
$genType inversesqrt($genType x);
//$genDType inversesqrt($genDType x);
$genType abs($genType x);
$genHType abs($genHType x);
$genIType abs($genIType x);
//$genDType abs($genDType x);
$genType sign($genType x);
$genHType sign($genHType x);
$genIType sign($genIType x);
//$genDType sign($genDType x);
$genType floor($genType x);
$genHType floor($genHType x);
//$genDType floor($genDType x);
$genType trunc($genType x);
$genHType trunc($genHType x);
//$genDType trunc($genDType x);
$genType round($genType x);
$genHType round($genHType x);
//$genDType round($genDType x);
$genType roundEven($genType x);
$genHType roundEven($genHType x);
//$genDType roundEven($genDType x);
$genType ceil($genType x);
$genHType ceil($genHType x);
//$genDType ceil($genDType x);
$genType fract($genType x);
$genHType fract($genHType x);
//$genDType fract($genDType x);
$genType mod($genType x, float y);
$genType mod($genType x, $genType y);
$genHType mod($genHType x, half y);
$genHType mod($genHType x, $genType y);
//$genDType mod($genDType x, double y);
//$genDType mod($genDType x, $genDType y);
$genType modf($genType x, out $genType i);
$genHType modf($genHType x, out $genHType i);
//$genDType modf($genDType x, out $genDType i);
$genType min($genType x, $genType y);
$genType min($genType x, float y);
$genHType min($genHType x, $genHType y);
$genHType min($genHType x, half y);
//$genDType min($genDType x, $genDType y);
//$genDType min($genDType x, double y);
$genIType min($genIType x, $genIType y);
@ -59,6 +92,8 @@ $genIType min($genIType x, int y);
//$genUType min($genUType x, uint y);
$genType max($genType x, $genType y);
$genType max($genType x, float y);
$genHType max($genHType x, $genHType y);
$genHType max($genHType x, half y);
//$genDType max($genDType x, $genDType y);
//$genDType max($genDType x, double y);
$genIType max($genIType x, $genIType y);
@ -67,6 +102,8 @@ $genIType max($genIType x, int y);
//$genUType max($genUType x, uint y);
$genType clamp($genType x, $genType minVal, $genType maxVal);
$genType clamp($genType x, float minVal, float maxVal);
$genHType clamp($genHType x, $genHType minVal, $genHType maxVal);
$genHType clamp($genHType x, half minVal, half maxVal);
//$genDType clamp($genDType x, $genDType minVal, $genDType maxVal);
//$genDType clamp($genDType x, double minVal, double maxVal);
$genIType clamp($genIType x, $genIType minVal, $genIType maxVal);
@ -74,8 +111,11 @@ $genIType clamp($genIType x, int minVal, int maxVal);
//$genUType clamp($genUType x, $genUType minVal, $genUType maxVal);
//$genUType clamp($genUType x, uint minVal, uint maxVal);
$genType saturate($genType x);
$genHType saturate($genHType x);
$genType mix($genType x, $genType y, $genType a);
$genType mix($genType x, $genType y, float a);
$genHType mix($genHType x, $genHType y, $genHType a);
$genHType mix($genHType x, $genHType y, half a);
//$genDType mix($genDType x, $genDType y, $genDType a);
//$genDType mix($genDType x, $genDType y, double a);
$genType mix($genType x, $genType y, $genBType a);
@ -85,10 +125,14 @@ $genIType mix($genIType x, $genIType y, $genBType a);
$genBType mix($genBType x, $genBType y, $genBType a);
$genType step($genType edge, $genType x);
$genType step(float edge, $genType x);
$genHType step($genHType edge, $genHType x);
$genHType step(half edge, $genHType x);
//$genDType step($genDType edge, $genDType x);
//$genDType step(double edge, $genDType x);
$genType smoothstep($genType edge0, $genType edge1, $genType x);
$genType smoothstep(float edge0, float edge1, $genType x);
$genHType smoothstep($genHType edge0, $genHType edge1, $genHType x);
$genHType smoothstep(half edge0, half edge1, $genHType x);
//$genDType smoothstep($genDType edge0, $genDType edge1, $genDType x);
//$genDType smoothstep(double edge0, double edge1, $genDType x);
$genBType isnan($genType x);
@ -154,6 +198,15 @@ float2x4 outerProduct(float4 c, float2 r);
float4x2 outerProduct(float2 c, float4 r);
float3x4 outerProduct(float4 c, float3 r);
float4x3 outerProduct(float3 c, float4 r);
half2x2 outerProduct(half2 c, half2 r);
half3x3 outerProduct(half3 c, half3 r);
half4x3 outerProduct(half4 c, half4 r);
half2x3 outerProduct(half3 c, half2 r);
half3x2 outerProduct(half2 c, half3 r);
half2x4 outerProduct(half4 c, half2 r);
half4x2 outerProduct(half2 c, half4 r);
half3x4 outerProduct(half4 c, half3 r);
half4x3 outerProduct(half3 c, half4 r);
float2x2 transpose(float2x2 m);
float3x3 transpose(float3x3 m);
float4x4 transpose(float4x4 m);
@ -163,12 +216,27 @@ float2x4 transpose(float4x2 m);
float4x2 transpose(float2x4 m);
float3x4 transpose(float4x3 m);
float4x3 transpose(float3x4 m);
half2x2 transpose(half2x2 m);
half3x3 transpose(half3x3 m);
half4x4 transpose(half4x4 m);
half2x3 transpose(half3x2 m);
half3x2 transpose(half2x3 m);
half2x4 transpose(half4x2 m);
half4x2 transpose(half2x4 m);
half3x4 transpose(half4x3 m);
half4x3 transpose(half3x4 m);
float determinant(float2x2 m);
float determinant(float3x3 m);
float determinant(float4x4 m);
half determinant(half2x2 m);
half determinant(half3x3 m);
half determinant(half4x4 m);
float2x2 inverse(float2x2 m);
float3x3 inverse(float3x3 m);
float4x4 inverse(float4x4 m);
half2x2 inverse(half2x2 m);
half3x3 inverse(half3x3 m);
half4x4 inverse(half4x4 m);
$bvec lessThan($vec x, $vec y);
$bvec lessThan($hvec x, $hvec y);
$bvec lessThan($dvec x, $dvec y);
@ -536,7 +604,10 @@ float4 imageLoad(image2D image, int2 P);
int4 imageLoad(iimage2D image, int2 P);
$genType dFdx($genType p);
$genType dFdy($genType p);
$genHType dFdx($genHType p);
$genHType dFdy($genHType p);
$genType fwidth($genType p);
$genHType fwidth($genHType p);
float interpolateAtSample(float interpolant, int sample);
float2 interpolateAtSample(float2 interpolant, int sample);
float3 interpolateAtSample(float3 interpolant, int sample);

View File

@ -52,7 +52,7 @@ DEF_TEST(SkSLUndefinedFunction, r) {
DEF_TEST(SkSLGenericArgumentMismatch, r) {
test_failure(r,
"void main() { float x = sin(1, 2); }",
"error: 1: call to 'sin' expected 1 argument, but found 2\n1 error\n");
"error: 1: no match for sin(int, int)\n1 error\n");
test_failure(r,
"void main() { float x = sin(true); }",
"error: 1: no match for sin(bool)\n1 error\n");
@ -341,7 +341,7 @@ DEF_TEST(SkSLUseWithoutInitialize, r) {
"error: 1: 'x' has not been assigned\n1 error\n");
test_failure(r,
"void main() { int x; switch (3) { case 0: x = 0; case 1: x = 1; }"
"sk_FragColor = float4(x); }",
"sk_FragColor = half4(x); }",
"error: 1: 'x' has not been assigned\n1 error\n");
}
@ -461,10 +461,10 @@ DEF_TEST(SkSLFieldAfterRuntimeArray, r) {
DEF_TEST(SkSLStaticIf, r) {
test_success(r,
"void main() { float x = 5; float y = 10;"
"@if (x < y) { sk_FragColor = float4(1); } }");
"@if (x < y) { sk_FragColor = half4(1); } }");
test_failure(r,
"void main() { float x = sqrt(25); float y = 10;"
"@if (x < y) { sk_FragColor = float4(1); } }",
"@if (x < y) { sk_FragColor = half4(1); } }",
"error: 1: static if has non-static test\n1 error\n");
}
@ -473,16 +473,16 @@ DEF_TEST(SkSLStaticSwitch, r) {
"void main() {"
"int x = 1;"
"@switch (x) {"
"case 1: sk_FragColor = float4(1); break;"
"default: sk_FragColor = float4(0);"
"case 1: sk_FragColor = half4(1); break;"
"default: sk_FragColor = half4(0);"
"}"
"}");
test_failure(r,
"void main() {"
"int x = int(sqrt(1));"
"@switch (x) {"
"case 1: sk_FragColor = float4(1); break;"
"default: sk_FragColor = float4(0);"
"case 1: sk_FragColor = half4(1); break;"
"default: sk_FragColor = half4(0);"
"}"
"}",
"error: 1: static switch has non-static test\n1 error\n");
@ -490,8 +490,8 @@ DEF_TEST(SkSLStaticSwitch, r) {
"void main() {"
"int x = 1;"
"@switch (x) {"
"case 1: sk_FragColor = float4(1); if (sqrt(0) < sqrt(1)) break;"
"default: sk_FragColor = float4(0);"
"case 1: sk_FragColor = half4(1); if (sqrt(0) < sqrt(1)) break;"
"default: sk_FragColor = half4(0);"
"}"
"}",
"error: 1: static switch contains non-static conditional break\n1 error\n");

View File

@ -329,7 +329,7 @@ DEF_TEST(SkSLFPSections, r) {
"@constructorParams { int x, float y, std::vector<float> z }"
"in float w;"
"void main() {"
"sk_OutColor = float4(1);"
"sk_OutColor = half4(1);"
"}",
*SkSL::ShaderCapsFactory::Default(),
{

View File

@ -49,7 +49,7 @@ static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& cap
DEF_TEST(SkSLHelloWorld, r) {
test(r,
"void main() { sk_FragColor = float4(0.75); }",
"void main() { sk_FragColor = half4(0.75); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -61,7 +61,7 @@ DEF_TEST(SkSLHelloWorld, r) {
DEF_TEST(SkSLControl, r) {
test(r,
"void main() {"
"if (sqrt(2) > 5) { sk_FragColor = float4(0.75); } else { discard; }"
"if (sqrt(2) > 5) { sk_FragColor = half4(0.75); } else { discard; }"
"int i = 0;"
"while (i < 10) { sk_FragColor *= 0.5; i++; }"
"do { sk_FragColor += 0.01; } while (sk_FragColor.x < 0.75);"
@ -98,7 +98,7 @@ DEF_TEST(SkSLFunctions, r) {
test(r,
"float foo(float v[2]) { return v[0] * v[1]; }"
"void bar(inout float x) { float y[2], z; y[0] = x; y[1] = x * 2; z = foo(y); x = z; }"
"void main() { float x = 10; bar(x); sk_FragColor = float4(x); }",
"void main() { float x = 10; bar(x); sk_FragColor = half4(half(x)); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -177,7 +177,7 @@ DEF_TEST(SkSLMatrices, r) {
"float3x4 z = x * y;"
"float3 v1 = float3x3(1) * float3(2);"
"float3 v2 = float3(2) * float3x3(1);"
"sk_FragColor = float4(z[0].x, v1 + v2);"
"sk_FragColor = half4(half(z[0].x), half3(v1 + v2));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -218,7 +218,7 @@ DEF_TEST(SkSLInterfaceBlock, r) {
"float x;"
"} test;"
"void main() {"
" sk_FragColor = half4(test.x);"
" sk_FragColor = half4(half(test.x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -234,7 +234,7 @@ DEF_TEST(SkSLInterfaceBlock, r) {
"float x;"
"} test[2];"
"void main() {"
" sk_FragColor = half4(test[1].x);"
" sk_FragColor = half4(half(test[1].x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -280,7 +280,7 @@ DEF_TEST(SkSLStructs, r) {
DEF_TEST(SkSLVersion, r) {
test(r,
"in float test; void main() { sk_FragColor = float4(0.75); }",
"in float test; void main() { sk_FragColor = half4(0.75); }",
*SkSL::ShaderCapsFactory::Version450Core(),
"#version 450 core\n"
"out vec4 sk_FragColor;\n"
@ -289,7 +289,7 @@ DEF_TEST(SkSLVersion, r) {
" sk_FragColor = vec4(0.75);\n"
"}\n");
test(r,
"in float test; void main() { sk_FragColor = float4(0.75); }",
"in float test; void main() { sk_FragColor = half4(0.75); }",
*SkSL::ShaderCapsFactory::Version110(),
"#version 110\n"
"varying float test;\n"
@ -301,7 +301,7 @@ DEF_TEST(SkSLVersion, r) {
DEF_TEST(SkSLUsesPrecisionModifiers, r) {
test(r,
"void main() { half x = 0.75; float y = 1; x++; y++;"
"sk_FragColor.rg = half2(x, y); }",
"sk_FragColor.rg = half2(x, half(y)); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -314,7 +314,7 @@ DEF_TEST(SkSLUsesPrecisionModifiers, r) {
"}\n");
test(r,
"void main() { half x = 0.75; float y = 1; x++; y++;"
"sk_FragColor.rg = half2(x, y); }",
"sk_FragColor.rg = half2(x, half(y)); }",
*SkSL::ShaderCapsFactory::UsesPrecisionModifiers(),
"#version 400\n"
"precision mediump float;\n"
@ -331,7 +331,7 @@ DEF_TEST(SkSLUsesPrecisionModifiers, r) {
DEF_TEST(SkSLMinAbs, r) {
test(r,
"void main() {"
"float x = -5;"
"half x = -5;"
"sk_FragColor.r = min(abs(x), 6);"
"}",
*SkSL::ShaderCapsFactory::Default(),
@ -343,7 +343,7 @@ DEF_TEST(SkSLMinAbs, r) {
test(r,
"void main() {"
"float x = -5.0;"
"half x = -5.0;"
"sk_FragColor.r = min(abs(x), 6.0);"
"}",
*SkSL::ShaderCapsFactory::CannotUseMinAndAbsTogether(),
@ -361,7 +361,7 @@ DEF_TEST(SkSLFractNegative, r) {
static constexpr char input[] =
"void main() {"
"float x = -42.0;"
"sk_FragColor.r = fract(x);"
"sk_FragColor.r = half(fract(x));"
"}";
static constexpr char output_default[] =
"#version 400\n"
@ -382,7 +382,7 @@ DEF_TEST(SkSLFractNegative, r) {
DEF_TEST(SkSLNegatedAtan, r) {
test(r,
"void main() { float2 x = float2(sqrt(2)); sk_FragColor.r = atan(x.x, -x.y); }",
"void main() { float2 x = float2(sqrt(2)); sk_FragColor.r = half(atan(x.x, -x.y)); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -391,7 +391,7 @@ DEF_TEST(SkSLNegatedAtan, r) {
" sk_FragColor.x = atan(x.x, -x.y);\n"
"}\n");
test(r,
"void main() { float2 x = float2(sqrt(2)); sk_FragColor.r = atan(x.x, -x.y); }",
"void main() { float2 x = float2(sqrt(2)); sk_FragColor.r = half(atan(x.x, -x.y)); }",
*SkSL::ShaderCapsFactory::MustForceNegatedAtanParamToFloat(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -528,7 +528,7 @@ DEF_TEST(SkSLArrayConstructors, r) {
DEF_TEST(SkSLDerivatives, r) {
test(r,
"void main() { sk_FragColor.r = dFdx(1); }",
"void main() { sk_FragColor.r = half(dFdx(1)); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -545,7 +545,7 @@ DEF_TEST(SkSLDerivatives, r) {
" sk_FragColor.x = 1.0;\n"
"}\n");
test(r,
"void main() { sk_FragColor.r = dFdx(1); }",
"void main() { sk_FragColor.r = half(dFdx(1)); }",
*SkSL::ShaderCapsFactory::ShaderDerivativeExtensionString(),
"#version 400\n"
"#extension GL_OES_standard_derivatives : require\n"
@ -664,15 +664,15 @@ DEF_TEST(SkSLFloatFolding, r) {
"sk_FragColor.r = 6.0 < 6.0 ? 10 : -10;"
"sk_FragColor.r = 6.0 <= 6.0 ? 11 : -11;"
"sk_FragColor.r = 6.0 <= 5.0 ? 12 : -12;"
"sk_FragColor.r = sqrt(1) + 0;"
"sk_FragColor.r = 0 + sqrt(2);"
"sk_FragColor.r = sqrt(3) - 0;"
"sk_FragColor.r = sqrt(4) * 0;"
"sk_FragColor.r = sqrt(5) * 1;"
"sk_FragColor.r = 1 * sqrt(6);"
"sk_FragColor.r = 0 * sqrt(7);"
"sk_FragColor.r = sqrt(8) / 1;"
"sk_FragColor.r = 0 / sqrt(9);"
"sk_FragColor.r = half(sqrt(1) + 0);"
"sk_FragColor.r = half(0 + sqrt(2));"
"sk_FragColor.r = half(sqrt(3) - 0);"
"sk_FragColor.r = half(sqrt(4) * 0);"
"sk_FragColor.r = half(sqrt(5) * 1);"
"sk_FragColor.r = half(1 * sqrt(6));"
"sk_FragColor.r = half(0 * sqrt(7));"
"sk_FragColor.r = half(sqrt(8) / 1);"
"sk_FragColor.r = half(0 / sqrt(9));"
"sk_FragColor.r += 1;"
"sk_FragColor.r += 0;"
"sk_FragColor.r -= 1;"
@ -796,56 +796,56 @@ DEF_TEST(SkSLShortCircuitBoolFolding, r) {
DEF_TEST(SkSLVecFolding, r) {
test(r,
"void main() {"
"sk_FragColor.r = float4(0.5, 1, 1, 1).x;"
"sk_FragColor = float4(float2(1), float2(2, 3)) + float4(5, 6, 7, 8);"
"sk_FragColor = float4(8, float3(10)) - float4(1);"
"sk_FragColor = float4(2) * float4(1, 2, 3, 4);"
"sk_FragColor = float4(12) / float4(1, 2, 3, 4);"
"sk_FragColor.r = (float4(12) / float4(1, 2, 3, 4)).y;"
"sk_FragColor.x = float4(1) == float4(1) ? 1.0 : -1.0;"
"sk_FragColor.x = float4(1) == float4(2) ? 2.0 : -2.0;"
"sk_FragColor.x = float2(1) == float2(1, 1) ? 3.0 : -3.0;"
"sk_FragColor.x = float2(1, 1) == float2(1, 1) ? 4.0 : -4.0;"
"sk_FragColor.x = float2(1) == float2(1, 0) ? 5.0 : -5.0;"
"sk_FragColor.x = float4(1) == float4(float2(1), float2(1)) ? 6.0 : -6.0;"
"sk_FragColor.x = float4(float3(1), 1) == float4(float2(1), float2(1)) ? 7.0 : -7.0;"
"sk_FragColor.x = float4(float3(1), 1) == float4(float2(1), 1, 0) ? 8.0 : -8.0;"
"sk_FragColor.x = float2(1) != float2(1, 0) ? 9.0 : -9.0;"
"sk_FragColor.x = float4(1) != float4(float2(1), float2(1)) ? 10.0 : -10.0;"
"sk_FragColor = float4(sqrt(1)) * float4(1);"
"sk_FragColor = float4(1) * float4(sqrt(2));"
"sk_FragColor = float4(0) * float4(sqrt(3));"
"sk_FragColor = float4(sqrt(4)) * float4(0);"
"sk_FragColor = float4(0) / float4(sqrt(5));"
"sk_FragColor = float4(0) + float4(sqrt(6));"
"sk_FragColor = float4(sqrt(7)) + float4(0);"
"sk_FragColor = float4(sqrt(8)) - float4(0);"
"sk_FragColor = float4(0) + sqrt(9);"
"sk_FragColor = float4(0) * sqrt(10);"
"sk_FragColor = float4(0) / sqrt(11);"
"sk_FragColor = float4(1) * sqrt(12);"
"sk_FragColor = 0 + float4(sqrt(13));"
"sk_FragColor = 0 * float4(sqrt(14));"
"sk_FragColor = 0 / float4(sqrt(15));"
"sk_FragColor = 1 * float4(sqrt(16));"
"sk_FragColor = float4(sqrt(17)) + 0;"
"sk_FragColor = float4(sqrt(18)) * 0;"
"sk_FragColor = float4(sqrt(19)) * 1;"
"sk_FragColor = float4(sqrt(19.5)) - 0;"
"sk_FragColor = sqrt(20) * float4(1);"
"sk_FragColor = sqrt(21) + float4(0);"
"sk_FragColor = sqrt(22) - float4(0);"
"sk_FragColor = sqrt(23) / float4(1);"
"sk_FragColor = float4(sqrt(24)) / 1;"
"sk_FragColor += float4(1);"
"sk_FragColor += float4(0);"
"sk_FragColor -= float4(1);"
"sk_FragColor -= float4(0);"
"sk_FragColor *= float4(1);"
"sk_FragColor *= float4(2);"
"sk_FragColor /= float4(1);"
"sk_FragColor /= float4(2);"
"void main() {\n"
"sk_FragColor.r = half4(0.5, 1, 1, 1).x;\n"
"sk_FragColor = half4(half2(1), half2(2, 3)) + half4(5, 6, 7, 8);\n"
"sk_FragColor = half4(8, half3(10)) - half4(1);\n"
"sk_FragColor = half4(2) * half4(1, 2, 3, 4);\n"
"sk_FragColor = half4(12) / half4(1, 2, 3, 4);\n"
"sk_FragColor.r = (half4(12) / half4(1, 2, 3, 4)).y;\n"
"sk_FragColor.x = half4(1) == half4(1) ? 1.0 : -1.0;\n"
"sk_FragColor.x = half4(1) == half4(2) ? 2.0 : -2.0;\n"
"sk_FragColor.x = half2(1) == half2(1, 1) ? 3.0 : -3.0;\n"
"sk_FragColor.x = half2(1, 1) == half2(1, 1) ? 4.0 : -4.0;\n"
"sk_FragColor.x = half2(1) == half2(1, 0) ? 5.0 : -5.0;\n"
"sk_FragColor.x = half4(1) == half4(half2(1), half2(1)) ? 6.0 : -6.0;\n"
"sk_FragColor.x = half4(half3(1), 1) == half4(half2(1), half2(1)) ? 7.0 : -7.0;\n"
"sk_FragColor.x = half4(half3(1), 1) == half4(half2(1), 1, 0) ? 8.0 : -8.0;\n"
"sk_FragColor.x = half2(1) != half2(1, 0) ? 9.0 : -9.0;\n"
"sk_FragColor.x = half4(1) != half4(half2(1), half2(1)) ? 10.0 : -10.0;\n"
"sk_FragColor = half4(half(sqrt(1))) * half4(1);\n"
"sk_FragColor = half4(1) * half4(half(sqrt(2)));\n"
"sk_FragColor = half4(0) * half4(half(sqrt(3)));\n"
"sk_FragColor = half4(half(sqrt(4))) * half4(0);\n"
"sk_FragColor = half4(0) / half4(half(sqrt(5)));\n"
"sk_FragColor = half4(0) + half4(half(sqrt(6)));\n"
"sk_FragColor = half4(half(sqrt(7))) + half4(0);\n"
"sk_FragColor = half4(half(sqrt(8))) - half4(0);\n"
"sk_FragColor = half4(0) + half(half(sqrt(9)));\n"
"sk_FragColor = half4(0) * half(sqrt(10));\n"
"sk_FragColor = half4(0) / half(sqrt(11));\n"
"sk_FragColor = half4(1) * half(sqrt(12));\n"
"sk_FragColor = 0 + half4(half(sqrt(13)));\n"
"sk_FragColor = 0 * half4(half(sqrt(14)));\n"
"sk_FragColor = 0 / half4(half(sqrt(15)));\n"
"sk_FragColor = 1 * half4(half(sqrt(16)));\n"
"sk_FragColor = half4(half(sqrt(17))) + 0;\n"
"sk_FragColor = half4(half(sqrt(18))) * 0;\n"
"sk_FragColor = half4(half(sqrt(19))) * 1;\n"
"sk_FragColor = half4(half(sqrt(19.5))) - 0;\n"
"sk_FragColor = half(half(sqrt(20))) * half4(1);\n"
"sk_FragColor = half(half(sqrt(21))) + half4(0);\n"
"sk_FragColor = half(half(sqrt(22))) - half4(0);\n"
"sk_FragColor = half(half(sqrt(23))) / half4(1);\n"
"sk_FragColor = half4(half(sqrt(24))) / 1;\n"
"sk_FragColor += half4(1);\n"
"sk_FragColor += half4(0);\n"
"sk_FragColor -= half4(1);\n"
"sk_FragColor -= half4(0);\n"
"sk_FragColor *= half4(1);\n"
"sk_FragColor *= half4(2);\n"
"sk_FragColor /= half4(1);\n"
"sk_FragColor /= half4(2);\n"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -990,7 +990,7 @@ DEF_TEST(SkSLTexture, r) {
"float4 b = texture(two, float2(0));"
"float4 c = texture(one, float2(0));"
"float4 d = texture(two, float3(0));"
"sk_FragColor = half4(a.x, b.x, c.x, d.x);"
"sk_FragColor = half4(half(a.x), half(b.x), half(c.x), half(d.x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1012,7 +1012,7 @@ DEF_TEST(SkSLTexture, r) {
"float4 b = texture(two, float2(0));"
"float4 c = texture(one, float2(0));"
"float4 d = texture(two, float3(0));"
"sk_FragColor = half4(a.x, b.x, c.x, d.x);"
"sk_FragColor = half4(half(a.x), half(b.x), half(c.x), half(d.x));"
"}",
*SkSL::ShaderCapsFactory::Version110(),
"#version 110\n"
@ -1041,7 +1041,7 @@ DEF_TEST(SkSLSharpen, r) {
"float4 b = texture(two, float2(0));"
"float4 c = texture(one, float2(0));"
"float4 d = texture(two, float3(0));"
"sk_FragColor = half4(a.x, b.x, c.x, d.x);"
"sk_FragColor = half4(half(a.x), half(b.x), half(c.x), half(d.x));"
"}",
settings,
"#version 400\n"
@ -1067,7 +1067,7 @@ DEF_TEST(SkSLSharpen, r) {
"float4 b = texture(two, float2(0));"
"float4 c = texture(one, float2(0));"
"float4 d = texture(two, float3(0));"
"sk_FragColor = half4(a.x, b.x, c.x, d.x);"
"sk_FragColor = half4(half(a.x), half(b.x), half(c.x), half(d.x));"
"}",
settings,
"#version 110\n"
@ -1106,7 +1106,7 @@ DEF_TEST(SkSLFragCoord, r) {
settings.fCaps = caps.get();
SkSL::Program::Inputs inputs;
test(r,
"void main() { sk_FragColor.xy = sk_FragCoord.xy; }",
"void main() { sk_FragColor.xy = half2(sk_FragCoord.xy); }",
settings,
"#version 110\n"
"#extension GL_ARB_fragment_coord_conventions : require\n"
@ -1120,7 +1120,7 @@ DEF_TEST(SkSLFragCoord, r) {
caps = SkSL::ShaderCapsFactory::FragCoordsNew();
settings.fCaps = caps.get();
test(r,
"void main() { sk_FragColor.xy = sk_FragCoord.xy; }",
"void main() { sk_FragColor.xy = half2(sk_FragCoord.xy); }",
settings,
"#version 400\n"
"layout(origin_upper_left) in vec4 gl_FragCoord;\n"
@ -1134,7 +1134,7 @@ DEF_TEST(SkSLFragCoord, r) {
caps = SkSL::ShaderCapsFactory::Default();
settings.fCaps = caps.get();
test(r,
"void main() { sk_FragColor.xy = sk_FragCoord.xy; }",
"void main() { sk_FragColor.xy = half2(sk_FragCoord.xy); }",
settings,
"#version 400\n"
"uniform float u_skRTHeight;\n"
@ -1149,7 +1149,7 @@ DEF_TEST(SkSLFragCoord, r) {
settings.fFlipY = false;
test(r,
"void main() { sk_FragColor.xy = sk_FragCoord.xy; }",
"void main() { sk_FragColor.xy = half2(sk_FragCoord.xy); }",
settings,
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -1185,7 +1185,7 @@ DEF_TEST(SkSLFragCoord, r) {
SkSL::Program::kVertex_Kind);
test(r,
"void main() { sk_FragColor.xy = sk_FragCoord.xy; }",
"void main() { sk_FragColor.xy = half2(sk_FragCoord.xy); }",
*SkSL::ShaderCapsFactory::CannotUseFragCoord(),
"#version 400\n"
"in vec4 sk_FragCoord_Workaround;\n"
@ -1205,7 +1205,7 @@ DEF_TEST(SkSLWidthAndHeight, r) {
settings.fCaps = caps.get();
SkSL::Program::Inputs inputs;
test(r,
"void main() { sk_FragColor.r = sk_FragCoord.x / sk_Width; }",
"void main() { sk_FragColor.r = half(sk_FragCoord.x / sk_Width); }",
settings,
"#version 400\n"
"uniform float u_skRTWidth;\n"
@ -1218,7 +1218,7 @@ DEF_TEST(SkSLWidthAndHeight, r) {
REPORTER_ASSERT(r, !inputs.fRTHeight);
test(r,
"void main() { sk_FragColor.r = sk_FragCoord.y / sk_Height; }",
"void main() { sk_FragColor.r = half(sk_FragCoord.y / sk_Height); }",
settings,
"#version 400\n"
"uniform float u_skRTHeight;\n"
@ -1276,7 +1276,7 @@ DEF_TEST(SkSLClipDistance, r) {
"}\n",
SkSL::Program::kVertex_Kind);
test(r,
"void main() { sk_FragColor = half4(sk_ClipDistance[0]); }",
"void main() { sk_FragColor = half4(half(sk_ClipDistance[0])); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -1289,7 +1289,7 @@ DEF_TEST(SkSLArrayTypes, r) {
test(r,
"void main() { float2 x[2] = float2[2](float2(1), float2(2));"
"float2[2] y = float2[2](float2(3), float2(4));"
"sk_FragColor = float4(x[0], y[1]); }",
"sk_FragColor = half4(half2(x[0]), half2(y[1])); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -1301,9 +1301,9 @@ DEF_TEST(SkSLArrayTypes, r) {
DEF_TEST(SkSLArrayIndexTypes, r) {
test(r,
"void main() { float array[4] = float[4](1, 2, 3, 4);"
"short x = 0; ushort y = 1; int z = 2; uint w = 3;"
"sk_FragColor = float4(array[x], array[y], array[z], array[w]); }",
"void main() { float array[4] = float[4](1, 2, 3, 4);\n"
"short x = 0;\n ushort y = 1;\n int z = 2;\n uint w = 3;\n"
"sk_FragColor = half4(half(array[x]), half(array[y]), half(array[z]), half(array[w])); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
"out vec4 sk_FragColor;\n"
@ -1357,7 +1357,7 @@ DEF_TEST(SkSLSwitch, r) {
" default:"
" x = 2.0;"
" }"
" sk_FragColor = float4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1388,7 +1388,7 @@ DEF_TEST(SkSLSwitch, r) {
" default:"
" x = 2.0;"
" }"
" sk_FragColor = half4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1414,7 +1414,7 @@ DEF_TEST(SkSLSwitch, r) {
" case 1:"
" x = 1.0;"
" }"
" sk_FragColor = half4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1439,7 +1439,7 @@ DEF_TEST(SkSLSwitch, r) {
" case 1:"
" x = 1.0;"
" }"
" sk_FragColor = half4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1457,7 +1457,7 @@ DEF_TEST(SkSLSwitch, r) {
" case 1:"
" x = 1.0;"
" }"
" sk_FragColor = half4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1476,7 +1476,7 @@ DEF_TEST(SkSLSwitch, r) {
" case 1:"
" x = 1.0;"
" }"
" sk_FragColor = half4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1495,7 +1495,7 @@ DEF_TEST(SkSLSwitch, r) {
" case 1:"
" x = 1.0;"
" }"
" sk_FragColor = half4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1514,7 +1514,7 @@ DEF_TEST(SkSLSwitch, r) {
" case 1:"
" x = 1.0;"
" }"
" sk_FragColor = half4(x);"
" sk_FragColor = half4(half(x));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1579,7 +1579,7 @@ DEF_TEST(SkSLUnusedVars, r) {
"float e = d;"
"b++;"
"d++;"
"sk_FragColor = float4(b, b, d, d);"
"sk_FragColor = half4(half(b), half(b), half(d), half(d));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1600,7 +1600,7 @@ DEF_TEST(SkSLMultipleAssignments, r) {
"float y;"
"int z;"
"x = y = z = 1;"
"sk_FragColor = float4(z);"
"sk_FragColor = half4(z);"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1616,10 +1616,10 @@ DEF_TEST(SkSLComplexDelete, r) {
"uniform sampler2D sampler;"
"void main() {"
"float4 tmpColor;"
"sk_FragColor = float4(1.0) * (tmpColor = texture(sampler, float2(1)) , "
"colorXform != float4x4(1.0) ? float4(clamp((float4x4(colorXform) * "
"sk_FragColor = half4(1.0) * (tmpColor = texture(sampler, float2(1)) , "
"half4(colorXform != float4x4(1.0) ? float4(clamp((float4x4(colorXform) * "
"float4(tmpColor.xyz, 1.0)).xyz, "
"0.0, tmpColor.w), tmpColor.w) : tmpColor);"
"0.0, tmpColor.w), tmpColor.w) : tmpColor));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1638,7 +1638,7 @@ DEF_TEST(SkSLDependentInitializers, r) {
test(r,
"void main() {"
"float x = 0.5, y = x * 2;"
"sk_FragColor = float4(y);"
"sk_FragColor = half4(half(y));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1788,10 +1788,10 @@ DEF_TEST(SkSLNumberConversions, r) {
"int i = int(sqrt(1));"
"ushort us = ushort(sqrt(1));"
"uint ui = uint(sqrt(1));"
"half h = sqrt(1);"
"half h = half(sqrt(1));"
"float f = sqrt(1);"
"short s2s = s;"
"short i2s = i;"
"short i2s = short(i);"
"short us2s = short(us);"
"short ui2s = short(ui);"
"short h2s = short(h);"
@ -1805,7 +1805,7 @@ DEF_TEST(SkSLNumberConversions, r) {
"ushort s2us = ushort(s);"
"ushort i2us = ushort(i);"
"ushort us2us = us;"
"ushort ui2us = ui;"
"ushort ui2us = ushort(ui);"
"ushort h2us = ushort(h);"
"ushort f2us = ushort(f);"
"uint s2ui = uint(s);"
@ -1862,7 +1862,7 @@ DEF_TEST(SkSLNumberConversions, r) {
DEF_TEST(SkSLForceHighPrecision, r) {
test(r,
"void main() { half x = sqrt(1); half4 y = half4(x); sk_FragColor = y; }",
"void main() {\n half x = half(sqrt(1));\n half4 y = half4(x);\n sk_FragColor = y;\n }",
*SkSL::ShaderCapsFactory::UsesPrecisionModifiers(),
"#version 400\n"
"precision mediump float;\n"
@ -1878,7 +1878,7 @@ DEF_TEST(SkSLForceHighPrecision, r) {
settings.fCaps = caps.get();
SkSL::Program::Inputs inputs;
test(r,
"void main() { half x = sqrt(1); half4 y = half4(x); sk_FragColor = y; }",
"void main() { half x = half(sqrt(1)); half4 y = half4(x); sk_FragColor = y; }",
settings,
"#version 400\n"
"precision mediump float;\n"
@ -1941,7 +1941,7 @@ DEF_TEST(SkSLNormalization, r) {
DEF_TEST(SkSLTernaryLValue, r) {
test(r,
"void main() { half r, g; (true ? r : g) = 1; (false ? r : g) = 0; "
"void main() { int r, g; (true ? r : g) = 1; (false ? r : g) = 0; "
"sk_FragColor = half4(r, g, 1, 1); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1950,7 +1950,7 @@ DEF_TEST(SkSLTernaryLValue, r) {
" sk_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\n"
"}\n");
test(r,
"void main() { half r, g; (true ? r : g) = sqrt(1); (false ? r : g) = sqrt(0); "
"void main() { half r, g; (true ? r : g) = half(sqrt(1)); (false ? r : g) = half(sqrt(0));"
"sk_FragColor = half4(r, g, 1, 1); }",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -1964,8 +1964,8 @@ DEF_TEST(SkSLTernaryLValue, r) {
test(r,
"void main() {"
"half r, g;"
"(sqrt(1) > 0 ? r : g) = sqrt(1);"
"(sqrt(0) > 0 ? r : g) = sqrt(0);"
"(sqrt(1) > 0 ? r : g) = half(sqrt(1));"
"(sqrt(0) > 0 ? r : g) = half(sqrt(0));"
"sk_FragColor = half4(r, g, 1, 1);"
"}",
*SkSL::ShaderCapsFactory::Default(),
@ -2027,7 +2027,7 @@ DEF_TEST(SkSLFrExp, r) {
"void main() {"
" int exp;"
" float foo = frexp(0.5, exp);"
" sk_FragColor = float4(exp);"
" sk_FragColor = half4(exp);"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
@ -2071,7 +2071,7 @@ DEF_TEST(SkSLWorkaroundUnfoldShortCircuitAsTernary, r) {
" bool combo = (x && y) || (x || y);"
" bool prec = (i + j == 3) && y;"
" while (andXY && orXY && combo && prec) {"
" sk_FragColor = float4(0);"
" sk_FragColor = half4(0);"
" break;"
" }"
"}",
@ -2102,7 +2102,7 @@ DEF_TEST(SkSLWorkaroundEmulateAbsIntFunction, r) {
"uniform float f;"
"void main() {"
" float output = abs(f) + abs(i);"
" sk_FragColor = float4(output);"
" sk_FragColor = half4(half(output));"
"}",
*SkSL::ShaderCapsFactory::EmulateAbsIntFunction(),
"#version 400\n"
@ -2130,7 +2130,7 @@ DEF_TEST(SkSLWorkaroundRewriteDoWhileLoops, r) {
" i++;"
" } while (true);"
" } while (i < 10);"
" sk_FragColor = float4(i);"
" sk_FragColor = half4(i);"
"}",
*SkSL::ShaderCapsFactory::RewriteDoWhileLoops(),
"#version 400\n"
@ -2173,7 +2173,7 @@ DEF_TEST(SkSLWorkaroundRemovePowWithConstantExponent, r) {
"uniform float y;"
"void main() {"
" float z = pow(x + 1.0, y + 2.0);"
" sk_FragColor = float4(z);"
" sk_FragColor = half4(half(z));"
"}",
*SkSL::ShaderCapsFactory::RemovePowWithConstantExponent(),
"#version 400\n"

View File

@ -42,7 +42,7 @@ static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& cap
DEF_TEST(SkSLMetalHelloWorld, r) {
test(r,
"void main() { sk_FragColor = float4(0.75); }",
"void main() { sk_FragColor = half4(0.75); }",
*SkSL::ShaderCapsFactory::Default(),
"#include <metal_stdlib>\n"
"#include <simd/simd.h>\n"
@ -77,8 +77,8 @@ DEF_TEST(SkSLMetalMatrices, r) {
"float3x3 m9 = float3x3(2);"
"float4x4 m10 = float4x4(1);"
"float4x4 m11 = float4x4(2);"
"sk_FragColor = half4(m1[0][0] + m2[0][0] + m3[0][0] + m4[0][0] + m5[0][0] + m6[0][0] + "
"m7[0][0] + m8[0][0] + m9[0][0] + m10[0][0] + m11[0][0]);"
"sk_FragColor = half4(half(m1[0][0] + m2[0][0] + m3[0][0] + m4[0][0] + m5[0][0] + "
"m6[0][0] + m7[0][0] + m8[0][0] + m9[0][0] + m10[0][0] + m11[0][0]));"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#include <metal_stdlib>\n"
@ -98,29 +98,20 @@ DEF_TEST(SkSLMetalMatrices, r) {
"float2x2 float2x2_from_float4(float4 v) {\n"
" return float2x2(float2(v[0], v[1]), float2(v[2], v[3]));\n"
"}\n"
"float2x2 float2x2_from_float(float x) {\n"
" return float2x2(float2(x, 0), float2(0, x));\n"
"}\n"
"float3x3 float3x3_from_float(float x) {\n"
" return float3x3(float3(x, 0, 0), float3(0, x, 0), float3(0, 0, x));\n"
"}\n"
"float4x4 float4x4_from_float(float x) {\n"
" return float4x4(float4(x, 0, 0, 0), float4(0, x, 0, 0), float4(0, 0, x, 0), float4(0,"
" 0, 0, x));\n"
" return float4x4(float4(x, 0, 0, 0), float4(0, x, 0, 0), float4(0, 0, x, 0), float4(0, 0, 0, x));\n"
"}\n"
"fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant sksl_synthetic_uniforms& "
"_anonInterface0 [[buffer(1)]], bool _frontFacing [[front_facing]], float4 "
"_fragCoord [[position]]) {\n"
"fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant sksl_synthetic_uniforms& _anonInterface0 [[buffer(1)]], bool _frontFacing [[front_facing]], float4 _fragCoord [[position]]) {\n"
" Outputs _outputStruct;\n"
" thread Outputs* _out = &_outputStruct;\n"
" float2x2 m5 = float2x2_from_float(float2x2_from_float4(float4(1.0, 2.0, 3.0, "
"4.0))[0][0]);\n"
" _out->sk_FragColor = float4((((((((((float2x2_from_float4(float4(1.0, 2.0, 3.0, "
"4.0))[0][0] + float2x2_from_float4(float4(0.0))[0][0]) + "
"float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0]) + "
"float2x2_from_float(1.0)[0][0]) + m5[0][0]) + float2x2(float2(1.0, 2.0), "
"float2(3.0, 4.0))[0][0]) + float2x2(float2(5.0, 6.0), float2(7.0, 8.0))[0][0]) + "
"float3x3_from_float(1.0)[0][0]) + float3x3_from_float(2.0)[0][0]) + "
"float4x4_from_float(1.0)[0][0]) + float4x4_from_float(2.0)[0][0]);\n"
" float2x2 m5 = float2x2_from_float(float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0]);\n"
" _out->sk_FragColor = float4((((((((((float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0] + float2x2_from_float4(float4(0.0))[0][0]) + float2x2_from_float4(float4(1.0, 2.0, 3.0, 4.0))[0][0]) + float2x2_from_float(1.0)[0][0]) + m5[0][0]) + float2x2(float2(1.0, 2.0), float2(3.0, 4.0))[0][0]) + float2x2(float2(5.0, 6.0), float2(7.0, 8.0))[0][0]) + float3x3_from_float(1.0)[0][0]) + float3x3_from_float(2.0)[0][0]) + float4x4_from_float(1.0)[0][0]) + float4x4_from_float(2.0)[0][0]);\n"
" return *_out;\n"
"}\n"
);
"}\n");
}

View File

@ -31,10 +31,10 @@ static void test_failure(skiatest::Reporter* r, const char* src, const char* err
DEF_TEST(SkSLBadOffset, r) {
test_failure(r,
"struct Bad { layout (offset = 5) int x; } bad; void main() { bad.x = 5; "
"sk_FragColor.r = float(bad.x); }",
"sk_FragColor.r = half(bad.x); }",
"error: 1: offset of field 'x' must be a multiple of 4\n1 error\n");
test_failure(r,
"struct Bad { int x; layout (offset = 0) int y; } bad; void main() { bad.x = 5; "
"sk_FragColor.r = float(bad.x); }",
"sk_FragColor.r = half(bad.x); }",
"error: 1: offset of field 'y' must be at least 4\n1 error\n");
}

View File

@ -46,7 +46,7 @@ public:
"// Copy Program VS\n"
"void main() {"
"vTexCoord = inPosition * uTexCoordXform.xy + uTexCoordXform.zw;"
"vTexCoord = half2(inPosition * uTexCoordXform.xy + uTexCoordXform.zw);"
"sk_Position.xy = inPosition * uPosXform.xy + uPosXform.zw;"
"sk_Position.zw = half2(0, 1);"
"}";