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:
parent
70df231b74
commit
e1f5502969
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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( "}");
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) / "
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
@ -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];");
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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 ||
|
||||
|
@ -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);
|
||||
|
@ -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())) {
|
||||
|
@ -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);");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);");
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);"
|
||||
"}"
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -29,7 +29,7 @@ void main() {
|
||||
bias = bias23;
|
||||
}
|
||||
|
||||
sk_OutColor = t * scale + bias;
|
||||
sk_OutColor = half4(t * scale + bias);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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]
|
||||
|
@ -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"));
|
||||
|
@ -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"),
|
||||
|
@ -119,7 +119,7 @@ void main() {
|
||||
break;
|
||||
}
|
||||
|
||||
sk_OutColor = half4(t, v, 0, 0);
|
||||
sk_OutColor = half4(half(t), v, 0, 0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -104,7 +104,7 @@ void main() {
|
||||
}
|
||||
}
|
||||
|
||||
sk_OutColor = t * scale + bias;
|
||||
sk_OutColor = half4(t * scale + bias);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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);");
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);"
|
||||
"}"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));",
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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()) {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -197,6 +197,12 @@ public:
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
if (fNameString == "$floatLiteral") {
|
||||
return "float";
|
||||
}
|
||||
if (fNameString == "$intLiteral") {
|
||||
return "int";
|
||||
}
|
||||
return fNameString;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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(),
|
||||
{
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);"
|
||||
"}";
|
||||
|
Loading…
Reference in New Issue
Block a user