diff options
author | 2017-09-15 11:42:17 -0400 | |
---|---|---|
committer | 2017-09-15 18:50:54 +0000 | |
commit | 05d5a13fea6246648de7e41358ed338d53c85ea2 (patch) | |
tree | 695fdbeae1116f8ce813288e47b31c2a99f28f1f /src/gpu/effects | |
parent | 49f1f34438d3431f6d7e32847accd2ba96948a73 (diff) |
Revert "Revert "Switched highp float to highfloat and mediump float to half.""
This reverts commit 1d816b92bb7cf2258007f3f74ffd143b89f25d01.
Bug: skia:
Change-Id: I388b5e5e9bf619db48297a80c9a80c039f26c9f1
Reviewed-on: https://skia-review.googlesource.com/46464
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src/gpu/effects')
30 files changed, 371 insertions, 402 deletions
diff --git a/src/gpu/effects/GrAtlasedShaderHelpers.h b/src/gpu/effects/GrAtlasedShaderHelpers.h index 67f2c242c2..b0704954d3 100644 --- a/src/gpu/effects/GrAtlasedShaderHelpers.h +++ b/src/gpu/effects/GrAtlasedShaderHelpers.h @@ -22,11 +22,11 @@ static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args, // This extracts the texture index and texel coordinates from the same variable // Packing structure: texel coordinates are multiplied by 2 (or shifted left 1) // texture index is stored as lower bits of both x and y - args.fVertBuilder->codeAppendf("float2 indexTexCoords = float2(%s.x, %s.y);", + args.fVertBuilder->codeAppendf("half2 indexTexCoords = half2(%s.x, %s.y);", inTexCoordsName, inTexCoordsName); - args.fVertBuilder->codeAppend("float2 intCoords = floor(0.5*indexTexCoords);"); - args.fVertBuilder->codeAppend("float2 diff = indexTexCoords - 2.0*intCoords;"); - args.fVertBuilder->codeAppend("float texIdx = 2.0*diff.x + diff.y;"); + args.fVertBuilder->codeAppend("half2 intCoords = floor(0.5*indexTexCoords);"); + args.fVertBuilder->codeAppend("half2 diff = indexTexCoords - 2.0*intCoords;"); + args.fVertBuilder->codeAppend("half texIdx = 2.0*diff.x + diff.y;"); // Multiply by 1/atlasSize to get normalized texture coordinates args.fVaryingHandler->addVarying("TextureCoords", uv, kHigh_GrSLPrecision); @@ -51,11 +51,11 @@ static void append_multitexture_lookup(GrGLSLPrimitiveProcessor::EmitArgs& args, args.fFragBuilder->codeAppendf("if (%s == 0) ", texIdx.fsIn()); } args.fFragBuilder->codeAppendf("{ %s = ", colorName); - args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], coordName, kVec2f_GrSLType); + args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], coordName, kHighFloat2_GrSLType); args.fFragBuilder->codeAppend("; }"); for (int i = 1; i < numTextureSamplers; ++i) { args.fFragBuilder->codeAppendf("else if (%s == %d) { %s =", texIdx.fsIn(), i, colorName); - args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName, kVec2f_GrSLType); + args.fFragBuilder->appendTextureLookup(args.fTexSamplers[i], coordName, kHighFloat2_GrSLType); args.fFragBuilder->codeAppend("; }"); } } diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index aa9a509887..5848888208 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -77,7 +77,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit attributes varyingHandler->emitAttributes(gp); - GrGLSLVertToFrag v(kVec4f_GrSLType); + GrGLSLVertToFrag v(kHighFloat4_GrSLType); varyingHandler->addVarying("ConicCoeffs", &v, kHigh_GrSLPrecision); vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName); @@ -102,26 +102,18 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { gp.localMatrix(), args.fFPCoordTransformHandler); - // TODO: this precision check should actually be a check on the number of bits - // high and medium provide and the selection of the lowest level that suffices. - // Additionally we should assert that the upstream code only lets us get here if - // either high or medium provides the required number of bits. - GrSLPrecision precision = kHigh_GrSLPrecision; - const GrShaderCaps::PrecisionInfo& highP = args.fShaderCaps->getFloatShaderPrecisionInfo( - kFragment_GrShaderType, - kHigh_GrSLPrecision); - if (!highP.supported()) { - precision = kMedium_GrSLPrecision; - } + // TODO: we should check on the number of bits float and half provide and use the smallest one + // 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, precision); - GrShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, precision); - GrShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, precision); - GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0, precision); - GrShaderVar dfdy("dfdy", kFloat_GrSLType, 0, precision); - GrShaderVar gF("gF", kVec2f_GrSLType, 0, precision); - GrShaderVar gFM("gFM", kFloat_GrSLType, 0, precision); - GrShaderVar func("func", kFloat_GrSLType, 0, precision); + GrShaderVar edgeAlpha("edgeAlpha", kHighFloat_GrSLType, 0); + GrShaderVar dklmdx("dklmdx", kHighFloat3_GrSLType, 0); + GrShaderVar dklmdy("dklmdy", kHighFloat3_GrSLType, 0); + GrShaderVar dfdx("dfdx", kHighFloat_GrSLType, 0); + GrShaderVar dfdy("dfdy", kHighFloat_GrSLType, 0); + GrShaderVar gF("gF", kHighFloat2_GrSLType, 0); + GrShaderVar gFM("gFM", kHighFloat_GrSLType, 0); + GrShaderVar func("func", kHighFloat_GrSLType, 0); fragBuilder->declAppend(edgeAlpha); fragBuilder->declAppend(dklmdx); @@ -146,7 +138,8 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { v.fsIn(), dklmdy.c_str(), v.fsIn(), dklmdy.c_str(), v.fsIn(), dklmdy.c_str()); - fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str()); + fragBuilder->codeAppendf("%s = highfloat2(%s, %s);", gF.c_str(), dfdx.c_str(), + dfdy.c_str()); fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str()); fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;", @@ -175,7 +168,8 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { v.fsIn(), dklmdy.c_str(), v.fsIn(), dklmdy.c_str(), v.fsIn(), dklmdy.c_str()); - fragBuilder->codeAppendf("%s = float2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str()); + fragBuilder->codeAppendf("%s = highfloat2(%s, %s);", gF.c_str(), dfdx.c_str(), + dfdy.c_str()); fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str()); fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;", @@ -191,7 +185,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { case kFillBW_GrProcessorEdgeType: { fragBuilder->codeAppendf("%s = %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 = highfloat(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str()); break; } @@ -203,14 +197,13 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { if (gp.coverageScale() != 0xff) { const char* coverageScale; fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, - kHigh_GrSLPrecision, + kHighFloat_GrSLType, "Coverage", &coverageScale); - fragBuilder->codeAppendf("%s = float4(%s * %s);", + fragBuilder->codeAppendf("%s = half4(%s * %s);", args.fOutputCoverage, coverageScale, edgeAlpha.c_str()); } else { - fragBuilder->codeAppendf("%s = float4(%s);", args.fOutputCoverage, edgeAlpha.c_str()); + fragBuilder->codeAppendf("%s = half4(%s);", args.fOutputCoverage, edgeAlpha.c_str()); } } @@ -338,7 +331,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // emit attributes varyingHandler->emitAttributes(gp); - GrGLSLVertToFrag v(kVec4f_GrSLType); + GrGLSLVertToFrag v(kHalf4_GrSLType); varyingHandler->addVarying("HairQuadEdge", &v); vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName); @@ -363,13 +356,13 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { gp.localMatrix(), args.fFPCoordTransformHandler); - fragBuilder->codeAppendf("float edgeAlpha;"); + fragBuilder->codeAppendf("half edgeAlpha;"); switch (fEdgeType) { case kHairlineAA_GrProcessorEdgeType: { - fragBuilder->codeAppendf("float2 duvdx = dFdx(%s.xy);", v.fsIn()); - fragBuilder->codeAppendf("float2 duvdy = dFdy(%s.xy);", v.fsIn()); - fragBuilder->codeAppendf("float2 gF = float2(2.0 * %s.x * duvdx.x - duvdx.y," + fragBuilder->codeAppendf("half2 duvdx = dFdx(%s.xy);", v.fsIn()); + fragBuilder->codeAppendf("half2 duvdy = 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);", @@ -381,9 +374,9 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { break; } case kFillAA_GrProcessorEdgeType: { - fragBuilder->codeAppendf("float2 duvdx = dFdx(%s.xy);", v.fsIn()); - fragBuilder->codeAppendf("float2 duvdy = dFdy(%s.xy);", v.fsIn()); - fragBuilder->codeAppendf("float2 gF = float2(2.0 * %s.x * duvdx.x - duvdx.y," + fragBuilder->codeAppendf("half2 duvdx = dFdx(%s.xy);", v.fsIn()); + fragBuilder->codeAppendf("half2 duvdy = 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);", @@ -397,7 +390,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { case kFillBW_GrProcessorEdgeType: { fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn()); - fragBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);"); + fragBuilder->codeAppend("edgeAlpha = half(edgeAlpha < 0.0);"); break; } default: @@ -407,13 +400,13 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { if (0xff != gp.coverageScale()) { const char* coverageScale; fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, - kDefault_GrSLPrecision, + kHalf_GrSLType, "Coverage", &coverageScale); - fragBuilder->codeAppendf("%s = float4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale); + fragBuilder->codeAppendf("%s = half4(%s * edgeAlpha);", args.fOutputCoverage, + coverageScale); } else { - fragBuilder->codeAppendf("%s = float4(edgeAlpha);", args.fOutputCoverage); + fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage); } } @@ -561,25 +554,25 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { // Setup KLM const char* devkLMMatrixName; - fDevKLMUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, kMat33f_GrSLType, - kHigh_GrSLPrecision, "KLM", &devkLMMatrixName); - GrGLSLVertToFrag v(kVec3f_GrSLType); + fDevKLMUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, kHighFloat3x3_GrSLType, "KLM", + &devkLMMatrixName); + GrGLSLVertToFrag v(kHighFloat3_GrSLType); varyingHandler->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("%s = %s * float3(%s, 1);", + vertBuilder->codeAppendf("%s = %s * highfloat3(%s, 1);", v.vsOut(), devkLMMatrixName, gpArgs->fPositionVar.c_str()); - GrGLSLVertToFrag gradCoeffs(kVec4f_GrSLType); + GrGLSLVertToFrag gradCoeffs(kHighFloat4_GrSLType); if (kFillAA_GrProcessorEdgeType == fEdgeType || kHairlineAA_GrProcessorEdgeType == fEdgeType) { varyingHandler->addVarying("GradCoeffs", &gradCoeffs, kHigh_GrSLPrecision); - vertBuilder->codeAppendf("highp float k = %s[0], l = %s[1], m = %s[2];", + vertBuilder->codeAppendf("highfloat k = %s[0], l = %s[1], m = %s[2];", v.vsOut(), v.vsOut(), v.vsOut()); - vertBuilder->codeAppendf("highp float2 gk = float2(%s[0][0], %s[1][0]), " - "gl = float2(%s[0][1], %s[1][1]), " - "gm = float2(%s[0][2], %s[1][2]);", + vertBuilder->codeAppendf("highfloat2 gk = highfloat2(%s[0][0], %s[1][0]), " + "gl = highfloat2(%s[0][1], %s[1][1]), " + "gm = highfloat2(%s[0][2], %s[1][2]);", devkLMMatrixName, devkLMMatrixName, devkLMMatrixName, devkLMMatrixName, devkLMMatrixName, devkLMMatrixName); - vertBuilder->codeAppendf("%s = float4(3 * k * gk, -m * gl - l * gm);", + vertBuilder->codeAppendf("%s = highfloat4(3 * k * gk, -m * gl - l * gm);", gradCoeffs.vsOut()); } @@ -592,9 +585,9 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { args.fFPCoordTransformHandler); - GrShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision); - GrShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision); - GrShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision); + GrShaderVar edgeAlpha("edgeAlpha", kHighFloat_GrSLType, 0); + GrShaderVar gF("gF", kHighFloat2_GrSLType, 0); + GrShaderVar func("func", kHighFloat_GrSLType, 0); fragBuilder->declAppend(edgeAlpha); fragBuilder->declAppend(gF); @@ -638,7 +631,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;", edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn()); - fragBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str()); + fragBuilder->codeAppendf("%s = half(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str()); break; } default: @@ -646,7 +639,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { } - fragBuilder->codeAppendf("%s = float4(%s);", args.fOutputCoverage, edgeAlpha.c_str()); + fragBuilder->codeAppendf("%s = highfloat4(%s);", args.fOutputCoverage, edgeAlpha.c_str()); } void GrGLCubicEffect::GenKey(const GrGeometryProcessor& gp, diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp index 7417e29f12..743b9e094f 100644 --- a/src/gpu/effects/GrBicubicEffect.cpp +++ b/src/gpu/effects/GrBicubicEffect.cpp @@ -42,8 +42,7 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) { const GrBicubicEffect& bicubicEffect = args.fFp.cast<GrBicubicEffect>(); GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec2f_GrSLType, kDefault_GrSLPrecision, + fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "ImageIncrement"); const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); @@ -71,26 +70,26 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) { * * This is GLSL, so the matrix is column-major (transposed from standard matrix notation). */ - fragBuilder->codeAppend("float4x4 kMitchellCoefficients = float4x4(" + fragBuilder->codeAppend("half4x4 kMitchellCoefficients = half4x4(" " 1.0 / 18.0, 16.0 / 18.0, 1.0 / 18.0, 0.0 / 18.0," "-9.0 / 18.0, 0.0 / 18.0, 9.0 / 18.0, 0.0 / 18.0," "15.0 / 18.0, -36.0 / 18.0, 27.0 / 18.0, -6.0 / 18.0," "-7.0 / 18.0, 21.0 / 18.0, -21.0 / 18.0, 7.0 / 18.0);"); - fragBuilder->codeAppendf("float2 coord = %s - %s * float2(0.5);", coords2D.c_str(), imgInc); + fragBuilder->codeAppendf("highfloat2 coord = %s - %s * highfloat2(0.5);", coords2D.c_str(), imgInc); // We unnormalize the coord in order to determine our fractional offset (f) within the texel // We then snap coord to a texel center and renormalize. The snap prevents cases where the // 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("float4 wx = kMitchellCoefficients * float4(1.0, f.x, f.x * f.x, f.x * f.x * f.x);"); - fragBuilder->codeAppend("float4 wy = kMitchellCoefficients * float4(1.0, f.y, f.y * f.y, f.y * f.y * f.y);"); - fragBuilder->codeAppend("float4 rowColors[4];"); + fragBuilder->codeAppend("highfloat2 f = fract(coord);"); + fragBuilder->codeAppendf("coord = (coord - f + highfloat2(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];"); for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { SkString coord; - coord.printf("coord + %s * float2(%d, %d)", imgInc, x - 1, y - 1); + coord.printf("coord + %s * highfloat2(%d, %d)", imgInc, x - 1, y - 1); SkString sampleVar; sampleVar.printf("rowColors[%d]", x); fDomain.sampleTexture(fragBuilder, @@ -102,7 +101,7 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) { args.fTexSamplers[0]); } fragBuilder->codeAppendf( - "float4 s%d = wx.x * rowColors[0] + wx.y * rowColors[1] + wx.z * rowColors[2] + wx.w * rowColors[3];", + "half4 s%d = wx.x * rowColors[0] + wx.y * rowColors[1] + wx.z * rowColors[2] + wx.w * rowColors[3];", y); } SkString bicubicColor("(wy.x * s0 + wy.y * s1 + wy.z * s2 + wy.w * s3)"); diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 2d665c50cb..dfdd5addc1 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -32,13 +32,13 @@ public: const char* atlasSizeInvName; fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, - kVec2f_GrSLType, + kHighFloat2_GrSLType, kHigh_GrSLPrecision, "AtlasSizeInv", &atlasSizeInvName); - GrGLSLVertToFrag uv(kVec2f_GrSLType); - GrGLSLVertToFrag texIdx(kFloat_GrSLType); + GrGLSLVertToFrag uv(kHighFloat2_GrSLType); + GrGLSLVertToFrag texIdx(kHalf_GrSLType); append_index_uv_varyings(args, btgp.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, nullptr); @@ -63,14 +63,14 @@ public: btgp.localMatrix(), args.fFPCoordTransformHandler); - fragBuilder->codeAppend("float4 texColor;"); + fragBuilder->codeAppend("half4 texColor;"); append_multitexture_lookup(args, btgp.numTextureSamplers(), texIdx, uv.fsIn(), "texColor"); if (btgp.maskFormat() == kARGB_GrMaskFormat) { // modulate by color fragBuilder->codeAppendf("%s = %s * texColor;", args.fOutputColor, args.fOutputColor); - fragBuilder->codeAppendf("%s = float4(1);", args.fOutputCoverage); + fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage); } else { fragBuilder->codeAppendf("%s = texColor;", args.fOutputCoverage); } diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp index 1b5ea600f9..ff997cdec4 100644 --- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp +++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp @@ -25,12 +25,12 @@ public: args.fFp.cast<GrBlurredEdgeFragmentProcessor>(); (void)_outer; fragBuilder->codeAppendf( - "float 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 = " - "float4(factor);\n", - args.fInputColor ? args.fInputColor : "float4(1)", _outer.mode(), - args.fOutputColor); + "half factor = half(1.0 - highfloat(%s.w));\n@switch (%d) {\n case 0:\n " + "factor = half(exp(highfloat(highfloat(-factor * factor) * 4.0)) - " + "0.017999999999999999);\n break;\n case 1:\n factor = " + "half(smoothstep(1.0, 0.0, highfloat(factor)));\n break;\n}\n%s = " + "half4(factor);\n", + args.fInputColor ? args.fInputColor : "half4(1)", _outer.mode(), args.fOutputColor); } private: diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp index 3ff233a705..fe5ffd5eb3 100644 --- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp +++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp @@ -15,7 +15,7 @@ layout(key) in int mode; void main() { - float factor = 1.0 - sk_InColor.a; + half factor = 1.0 - sk_InColor.a; @switch (mode) { case 0: // kGaussian_Mode factor = exp(-factor * factor * 4.0) - 0.018; @@ -24,5 +24,5 @@ void main() { factor = smoothstep(1.0, 0.0, factor); break; } - sk_OutColor = float4(factor); + sk_OutColor = half4(factor); } diff --git a/src/gpu/effects/GrCircleEffect.cpp b/src/gpu/effects/GrCircleEffect.cpp index b764559ed4..7b4a9f7794 100644 --- a/src/gpu/effects/GrCircleEffect.cpp +++ b/src/gpu/effects/GrCircleEffect.cpp @@ -24,14 +24,15 @@ public: const GrCircleEffect& _outer = args.fFp.cast<GrCircleEffect>(); (void)_outer; prevRadius = -1.0; - fCircleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, + fCircleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, kDefault_GrSLPrecision, "circle"); fragBuilder->codeAppendf( - "float2 prevCenter;\nfloat prevRadius = %f;\nfloat d;\n@if (%d == 2 || %d == 3) " - "{\n d = (length((%s.xy - sk_FragCoord.xy) * %s.w) - 1.0) * %s.z;\n} else {\n " - " d = (1.0 - length((%s.xy - sk_FragCoord.xy) * %s.w)) * %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", + "half2 prevCenter;\nhalf prevRadius = %f;\nhalf d;\n@if (%d == 2 || %d == 3) {\n " + " d = (highfloat(length((%s.xy - half2(sk_FragCoord.xy)) * %s.w)) - 1.0) * " + "%s.z;\n} else {\n d = half((1.0 - highfloat(length((%s.xy - " + "half2(sk_FragCoord.xy)) * %s.w))) * highfloat(%s.z));\n}\n@if ((%d == 1 || %d == " + "3) || %d == 4) {\n d = half(clamp(highfloat(d), 0.0, 1.0));\n} else {\n d = " + "half(highfloat(d) > 0.5 ? 1.0 : 0.0);\n}\n%s = %s * d;\n", prevRadius, _outer.edgeType(), _outer.edgeType(), args.fUniformHandler->getUniformCStr(fCircleVar), args.fUniformHandler->getUniformCStr(fCircleVar), @@ -40,7 +41,7 @@ public: args.fUniformHandler->getUniformCStr(fCircleVar), args.fUniformHandler->getUniformCStr(fCircleVar), _outer.edgeType(), _outer.edgeType(), _outer.edgeType(), args.fOutputColor, - args.fInputColor ? args.fInputColor : "float4(1)"); + args.fInputColor ? args.fInputColor : "half4(1)"); } private: diff --git a/src/gpu/effects/GrCircleEffect.fp b/src/gpu/effects/GrCircleEffect.fp index 884112ecc9..031b2ee0a6 100644 --- a/src/gpu/effects/GrCircleEffect.fp +++ b/src/gpu/effects/GrCircleEffect.fp @@ -6,14 +6,14 @@ */ layout(key) in int edgeType; -in float2 center; -in float radius; +in half2 center; +in half radius; -float2 prevCenter; -float prevRadius = -1; +half2 prevCenter; +half prevRadius = -1; // The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.5)) for regular // fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills. -uniform float4 circle; +uniform half4 circle; @optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag } @@ -36,7 +36,7 @@ void main() { // TODO: Right now the distance to circle caclulation is performed in a space normalized to the // radius and then denormalized. This is to prevent overflow on devices that have a "real" // mediump. It'd be nice to only do this on mediump devices. - float d; + half d; @if (edgeType == 2 /* kInverseFillBW_GrProcessorEdgeType */ || edgeType == 3 /* kInverseFillAA_GrProcessorEdgeType */) { d = (length((circle.xy - sk_FragCoord.xy) * circle.w) - 1.0) * circle.z; diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index 2cf7919543..e1ecc7f864 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -21,16 +21,16 @@ public: GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; // Use highp throughout the shader to avoid some precision issues on specific GPUs. - fragBuilder->elevateDefaultPrecision(kHigh_GrSLPrecision); + fragBuilder->forceHighPrecision(); if (nullptr == args.fInputColor) { // could optimize this case, but we aren't for now. - args.fInputColor = "float4(1)"; + args.fInputColor = "half4(1)"; } // Aggressively round to the nearest exact (N / 255) floating point value. This lets us // find a round-trip preserving pair on some GPUs that do odd byte to float conversion. - fragBuilder->codeAppendf("float4 color = floor(%s * 255.0 + 0.5) / 255.0;", args.fInputColor); + fragBuilder->codeAppendf("half4 color = floor(%s * 255.0 + 0.5) / 255.0;", args.fInputColor); switch (cce.pmConversion()) { case GrConfigConversionEffect::kToPremul_PMConversion: @@ -40,7 +40,7 @@ public: case GrConfigConversionEffect::kToUnpremul_PMConversion: fragBuilder->codeAppend( - "color.rgb = color.a <= 0.0 ? float3(0,0,0) : floor(color.rgb / color.a * 255.0 + 0.5) / 255.0;"); + "color.rgb = color.a <= 0.0 ? half3(0,0,0) : floor(color.rgb / color.a * 255.0 + 0.5) / 255.0;"); break; default: diff --git a/src/gpu/effects/GrConstColorProcessor.cpp b/src/gpu/effects/GrConstColorProcessor.cpp index a8b328e9b9..7051872bf3 100644 --- a/src/gpu/effects/GrConstColorProcessor.cpp +++ b/src/gpu/effects/GrConstColorProcessor.cpp @@ -19,7 +19,7 @@ public: GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; const char* colorUni; fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, kMedium_GrSLPrecision, + kHalf4_GrSLType, "constantColor", &colorUni); GrConstColorProcessor::InputMode mode = args.fFp.cast<GrConstColorProcessor>().inputMode(); diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp index e61923c29e..97f456953d 100644 --- a/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/src/gpu/effects/GrConvexPolyEffect.cpp @@ -103,8 +103,7 @@ void GLAARectEffect::emitCode(EmitArgs& args) { // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), // respectively. fRectUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, - kDefault_GrSLPrecision, + kHalf4_GrSLType, "rect", &rectName); @@ -112,16 +111,16 @@ void GLAARectEffect::emitCode(EmitArgs& args) { if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) { // 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("\t\tfloat xSub, ySub;\n"); + fragBuilder->codeAppend("\t\thalf xSub, ySub;\n"); fragBuilder->codeAppendf("\t\txSub = min(sk_FragCoord.x - %s.x, 0.0);\n", rectName); fragBuilder->codeAppendf("\t\txSub += min(%s.z - sk_FragCoord.x, 0.0);\n", rectName); fragBuilder->codeAppendf("\t\tySub = min(sk_FragCoord.y - %s.y, 0.0);\n", rectName); fragBuilder->codeAppendf("\t\tySub += min(%s.w - sk_FragCoord.y, 0.0);\n", rectName); // Now compute coverage in x and y and multiply them to get the fraction of the pixel // covered. - fragBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); + fragBuilder->codeAppendf("\t\thalf alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); } else { - fragBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); + fragBuilder->codeAppendf("\t\thalf alpha = 1.0;\n"); fragBuilder->codeAppendf("\t\talpha *= (sk_FragCoord.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName); fragBuilder->codeAppendf("\t\talpha *= (%s.z - sk_FragCoord.x) > -0.5 ? 1.0 : 0.0;\n", @@ -191,16 +190,15 @@ void GrGLConvexPolyEffect::emitCode(EmitArgs& args) { const char *edgeArrayName; fEdgeUniform = args.fUniformHandler->addUniformArray(kFragment_GrShaderFlag, - kVec3f_GrSLType, - kDefault_GrSLPrecision, + kHalf3_GrSLType, "edges", cpe.getEdgeCount(), &edgeArrayName); GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - fragBuilder->codeAppend("\t\tfloat alpha = 1.0;\n"); - fragBuilder->codeAppend("\t\tfloat edge;\n"); + 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], float3(sk_FragCoord.x, sk_FragCoord.y, " + fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], half3(sk_FragCoord.x, sk_FragCoord.y, " "1));\n", edgeArrayName, i); if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) { diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index 2d66e1e1b6..ab0d835cf8 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp @@ -53,7 +53,7 @@ private: // you do not give gl_FragColor a value, the gl context is lost and we end up drawing // nothing. So this fix just sets the gl_FragColor arbitrarily to 0. GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; - fragBuilder->codeAppendf("%s = float4(0);", args.fOutputPrimary); + fragBuilder->codeAppendf("%s = half4(0);", args.fOutputPrimary); } void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {} diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index 66e96199eb..7800186d05 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -45,7 +45,7 @@ public: const char* atlasSizeInvName; fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, - kVec2f_GrSLType, + kHighFloat2_GrSLType, kHigh_GrSLPrecision, "AtlasSizeInv", &atlasSizeInvName); @@ -53,8 +53,7 @@ public: // adjust based on gamma const char* distanceAdjustUniName = nullptr; // width, height, 1/(3*width) - fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, kDefault_GrSLPrecision, + fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "DistanceAdjust", &distanceAdjustUniName); #endif @@ -78,9 +77,9 @@ public: args.fFPCoordTransformHandler); // add varyings - GrGLSLVertToFrag uv(kVec2f_GrSLType); - GrGLSLVertToFrag texIdx(kFloat_GrSLType); - GrGLSLVertToFrag st(kVec2f_GrSLType); + GrGLSLVertToFrag uv(kHighFloat2_GrSLType); + GrGLSLVertToFrag texIdx(kHalf_GrSLType); + GrGLSLVertToFrag st(kHighFloat2_GrSLType); append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, &st); @@ -93,19 +92,19 @@ public: SkToBool(dfTexEffect.getFlags() & kAliased_DistanceFieldEffectFlag); // Use highp to work around aliasing issues - fragBuilder->codeAppendf("highp float2 uv = %s;\n", uv.fsIn()); - fragBuilder->codeAppend("float4 texColor;"); + fragBuilder->codeAppendf("highfloat2 uv = %s;\n", uv.fsIn()); + fragBuilder->codeAppend("half4 texColor;"); append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), texIdx, "uv", "texColor"); - fragBuilder->codeAppend("float distance = " + fragBuilder->codeAppend("half distance = " SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");"); #ifdef SK_GAMMA_APPLY_TO_A8 // adjust width based on gamma fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); #endif - fragBuilder->codeAppend("float afwidth;"); + fragBuilder->codeAppend("half afwidth;"); if (isUniformScale) { // For uniform scale, we adjust for the effect of the transformation on the distance // by using the length of the gradient of the t coordinate in the y direction. @@ -128,29 +127,29 @@ public: // this gives us a smooth step across approximately one fragment #ifdef SK_VULKAN - fragBuilder->codeAppendf("float st_grad_len = length(dFdx(%s));", st.fsIn()); + fragBuilder->codeAppendf("half st_grad_len = 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("float st_grad_len = length(dFdy(%s));", st.fsIn()); + fragBuilder->codeAppendf("half st_grad_len = 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("float2 dist_grad = float2(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("float dg_len2 = dot(dist_grad, dist_grad);"); + fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);"); fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); - fragBuilder->codeAppend("dist_grad = float2(0.7071, 0.7071);"); + fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);"); fragBuilder->codeAppend("} else {"); fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); fragBuilder->codeAppend("}"); - fragBuilder->codeAppendf("float2 Jdx = dFdx(%s);", st.fsIn()); - fragBuilder->codeAppendf("float2 Jdy = dFdy(%s);", st.fsIn()); - fragBuilder->codeAppend("float2 grad = float2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); + fragBuilder->codeAppendf("half2 Jdx = dFdx(%s);", st.fsIn()); + fragBuilder->codeAppendf("half2 Jdy = 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);"); // this gives us a smooth step across approximately one fragment @@ -158,18 +157,18 @@ public: } if (isAliased) { - fragBuilder->codeAppend("float val = distance > 0 ? 1.0 : 0.0;"); + fragBuilder->codeAppend("half val = distance > 0 ? 1.0 : 0.0;"); } else if (isGammaCorrect) { // The smoothstep falloff compensates for the non-linear sRGB response curve. If we are // doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want // distance mapped linearly to coverage, so use a linear step: fragBuilder->codeAppend( - "float val = clamp((distance + afwidth) / (2.0 * afwidth), 0.0, 1.0);"); + "half val = clamp((distance + afwidth) / (2.0 * afwidth), 0.0, 1.0);"); } else { - fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);"); + fragBuilder->codeAppend("half val = smoothstep(-afwidth, afwidth, distance);"); } - fragBuilder->codeAppendf("%s = float4(val);", args.fOutputCoverage); + fragBuilder->codeAppendf("%s = half4(val);", args.fOutputCoverage); } void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, @@ -331,14 +330,14 @@ public: const char* atlasSizeInvName; fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, - kVec2f_GrSLType, + kHighFloat2_GrSLType, kHigh_GrSLPrecision, "AtlasSizeInv", &atlasSizeInvName); - GrGLSLVertToFrag uv(kVec2f_GrSLType); - GrGLSLVertToFrag texIdx(kFloat_GrSLType); - GrGLSLVertToFrag st(kVec2f_GrSLType); + GrGLSLVertToFrag uv(kHighFloat2_GrSLType); + GrGLSLVertToFrag texIdx(kHalf_GrSLType); + GrGLSLVertToFrag st(kHighFloat2_GrSLType); append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, &st); @@ -362,15 +361,15 @@ public: args.fFPCoordTransformHandler); // Use highp to work around aliasing issues - fragBuilder->codeAppendf("highp float2 uv = %s;", uv.fsIn()); - fragBuilder->codeAppend("float4 texColor;"); + fragBuilder->codeAppendf("highfloat2 uv = %s;", uv.fsIn()); + fragBuilder->codeAppend("half4 texColor;"); append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), texIdx, "uv", "texColor"); - fragBuilder->codeAppend("float distance = " + fragBuilder->codeAppend("half distance = " SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");"); - fragBuilder->codeAppend("float afwidth;"); + fragBuilder->codeAppend("half afwidth;"); bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == kUniformScale_DistanceFieldEffectMask; bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); @@ -397,30 +396,30 @@ public: // this gives us a smooth step across approximately one fragment #ifdef SK_VULKAN - fragBuilder->codeAppendf("float st_grad_len = length(dFdx(%s));", st.fsIn()); + fragBuilder->codeAppendf("half st_grad_len = 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("float st_grad_len = length(dFdy(%s));", st.fsIn()); + fragBuilder->codeAppendf("half st_grad_len = 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("float2 dist_grad = float2(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("float dg_len2 = dot(dist_grad, dist_grad);"); + fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);"); fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); - fragBuilder->codeAppend("dist_grad = float2(0.7071, 0.7071);"); + fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);"); fragBuilder->codeAppend("} else {"); fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); fragBuilder->codeAppend("}"); - fragBuilder->codeAppendf("float2 Jdx = dFdx(%s);", st.fsIn()); - fragBuilder->codeAppendf("float2 Jdy = dFdy(%s);", st.fsIn()); - fragBuilder->codeAppend("float2 grad = float2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); - fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);"); + fragBuilder->codeAppendf("half2 Jdx = dFdx(%s);", st.fsIn()); + fragBuilder->codeAppendf("half2 Jdy = 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);"); // this gives us a smooth step across approximately one fragment fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);"); @@ -430,12 +429,12 @@ public: // mapped linearly to coverage, so use a linear step: if (isGammaCorrect) { fragBuilder->codeAppend( - "float val = clamp((distance + afwidth) / (2.0 * afwidth), 0.0, 1.0);"); + "half val = clamp((distance + afwidth) / (2.0 * afwidth), 0.0, 1.0);"); } else { - fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);"); + fragBuilder->codeAppend("half val = smoothstep(-afwidth, afwidth, distance);"); } - fragBuilder->codeAppendf("%s = float4(val);", args.fOutputCoverage); + fragBuilder->codeAppendf("%s = half4(val);", args.fOutputCoverage); } void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, @@ -580,7 +579,7 @@ public: const char* atlasSizeInvName; fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, - kVec2f_GrSLType, + kHighFloat2_GrSLType, kHigh_GrSLPrecision, "AtlasSizeInv", &atlasSizeInvName); @@ -607,13 +606,13 @@ public: args.fFPCoordTransformHandler); // set up varyings - GrGLSLVertToFrag uv(kVec2f_GrSLType); - GrGLSLVertToFrag texIdx(kFloat_GrSLType); - GrGLSLVertToFrag st(kVec2f_GrSLType); + GrGLSLVertToFrag uv(kHighFloat2_GrSLType); + GrGLSLVertToFrag texIdx(kHalf_GrSLType); + GrGLSLVertToFrag st(kHighFloat2_GrSLType); append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName, &uv, &texIdx, &st); - GrGLSLVertToFrag delta(kFloat_GrSLType); + GrGLSLVertToFrag delta(kHighFloat_GrSLType); varyingHandler->addVarying("Delta", &delta, kHigh_GrSLPrecision); if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { vertBuilder->codeAppendf("%s = -%s.x/3.0;", delta.vsOut(), atlasSizeInvName); @@ -630,48 +629,48 @@ public: // create LCD offset adjusted by inverse of transform // Use highp to work around aliasing issues - fragBuilder->codeAppendf("highp float2 uv = %s;\n", uv.fsIn()); + fragBuilder->codeAppendf("highfloat2 uv = %s;\n", uv.fsIn()); if (isUniformScale) { #ifdef SK_VULKAN - fragBuilder->codeAppendf("float st_grad_len = abs(dFdx(%s.x));", st.fsIn()); + fragBuilder->codeAppendf("half st_grad_len = 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("float st_grad_len = abs(dFdy(%s.y));", st.fsIn()); + fragBuilder->codeAppendf("half st_grad_len = abs(dFdy(%s.y));", st.fsIn()); #endif - fragBuilder->codeAppendf("float2 offset = float2(st_grad_len*%s, 0.0);", delta.fsIn()); + fragBuilder->codeAppendf("half2 offset = half2(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("float2 st_grad = dFdx(%s);", st.fsIn()); - fragBuilder->codeAppendf("float2 offset = %s*st_grad;", delta.fsIn()); + fragBuilder->codeAppendf("half2 st_grad = dFdx(%s);", st.fsIn()); + fragBuilder->codeAppendf("half2 offset = %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("float2 st_grad = dFdy(%s);", st.fsIn()); - fragBuilder->codeAppendf("float2 offset = %s*float2(st_grad.y, -st_grad.x);", + fragBuilder->codeAppendf("half2 st_grad = dFdy(%s);", st.fsIn()); + fragBuilder->codeAppendf("half2 offset = %s*half2(st_grad.y, -st_grad.x);", delta.fsIn()); #endif - fragBuilder->codeAppend("float st_grad_len = length(st_grad);"); + fragBuilder->codeAppend("half st_grad_len = length(st_grad);"); } else { - fragBuilder->codeAppendf("float2 st = %s;\n", st.fsIn()); + fragBuilder->codeAppendf("half2 st = %s;\n", st.fsIn()); - fragBuilder->codeAppend("float2 Jdx = dFdx(st);"); - fragBuilder->codeAppend("float2 Jdy = dFdy(st);"); - fragBuilder->codeAppendf("float2 offset = %s*Jdx;", delta.fsIn()); + fragBuilder->codeAppend("half2 Jdx = dFdx(st);"); + fragBuilder->codeAppend("half2 Jdy = dFdy(st);"); + fragBuilder->codeAppendf("half2 offset = %s*Jdx;", delta.fsIn()); } // sample the texture by index - fragBuilder->codeAppend("float4 texColor;"); + fragBuilder->codeAppend("half4 texColor;"); append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), texIdx, "uv", "texColor"); // green is distance to uv center - fragBuilder->codeAppend("float3 distance;"); + fragBuilder->codeAppend("half3 distance;"); fragBuilder->codeAppend("distance.y = texColor.r;"); // red is distance to left offset - fragBuilder->codeAppend("float2 uv_adjusted = uv - offset;"); + fragBuilder->codeAppend("half2 uv_adjusted = uv - offset;"); append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(), texIdx, "uv_adjusted", "texColor"); fragBuilder->codeAppend("distance.x = texColor.r;"); @@ -682,12 +681,11 @@ public: fragBuilder->codeAppend("distance.z = texColor.r;"); fragBuilder->codeAppend("distance = " - "float3(" SK_DistanceFieldMultiplier ")*(distance - float3(" SK_DistanceFieldThreshold"));"); + "half3(" SK_DistanceFieldMultiplier ")*(distance - half3(" SK_DistanceFieldThreshold"));"); // adjust width based on gamma const char* distanceAdjustUniName = nullptr; - fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec3f_GrSLType, kDefault_GrSLPrecision, + fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf3_GrSLType, "DistanceAdjust", &distanceAdjustUniName); fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); @@ -695,7 +693,7 @@ public: // for each color component. However, this is only important when using perspective // transformations, and even then using a single factor seems like a reasonable // trade-off between quality and speed. - fragBuilder->codeAppend("float afwidth;"); + fragBuilder->codeAppend("half afwidth;"); if (isSimilarity) { // For similarity transform (uniform scale-only is a subset of this), we adjust for the // effect of the transformation on the distance by using the length of the gradient of @@ -708,16 +706,16 @@ 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("float2 dist_grad = float2(dFdx(distance.r), dFdy(distance.r));"); + fragBuilder->codeAppend("half2 dist_grad = half2(dFdx(distance.r), 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("float dg_len2 = dot(dist_grad, dist_grad);"); + fragBuilder->codeAppend("half dg_len2 = dot(dist_grad, dist_grad);"); fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); - fragBuilder->codeAppend("dist_grad = float2(0.7071, 0.7071);"); + fragBuilder->codeAppend("dist_grad = half2(0.7071, 0.7071);"); fragBuilder->codeAppend("} else {"); fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);"); fragBuilder->codeAppend("}"); - fragBuilder->codeAppend("float2 grad = float2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,"); + 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);"); // this gives us a smooth step across approximately one fragment @@ -729,11 +727,11 @@ public: // mapped linearly to coverage, so use a linear step: if (isGammaCorrect) { fragBuilder->codeAppendf("%s = " - "float4(clamp((distance + float3(afwidth)) / float3(2.0 * afwidth), 0.0, 1.0), 1.0);", + "half4(clamp((distance + half3(afwidth)) / half3(2.0 * afwidth), 0.0, 1.0), 1.0);", args.fOutputCoverage); } else { fragBuilder->codeAppendf( - "%s = float4(smoothstep(float3(-afwidth), float3(afwidth), distance), 1.0);", + "%s = half4(smoothstep(half3(-afwidth), half3(afwidth), distance), 1.0);", args.fOutputCoverage); } } diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp index d78af4ee5a..6f5266e738 100644 --- a/src/gpu/effects/GrDitherEffect.cpp +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -24,21 +24,22 @@ public: const GrDitherEffect& _outer = args.fFp.cast<GrDitherEffect>(); (void)_outer; fragBuilder->codeAppendf( - "float value;\nfloat range;\n@switch (%d) {\n case 0:\n range = " + "half value;\nhalf range;\n@switch (%d) {\n case 0:\n range = " "0.0039215686274509803;\n break;\n case 1:\n range = " "0.015873015873015872;\n break;\n default:\n range = " "0.066666666666666666;\n break;\n}\n@if (sk_Caps.integerSupport) {\n " "uint x = uint(sk_FragCoord.x);\n uint y = uint(sk_FragCoord.y);\n uint m = " "(((((y & 1) << 5 | (x & 1) << 4) | (y & 2) << 2) | (x & 2) << 1) | (y & 4) >> 1) " - "| (x & 4) >> 2;\n value = float(m) / 64.0 - 0.4921875;\n} else {\n float4 " - "modValues = mod(sk_FragCoord.xyxy, float4(2.0, 2.0, 4.0, 4.0));\n float4 " - "stepValues = step(modValues, float4(1.0, 1.0, 2.0, 2.0));\n value = " - "dot(stepValues, float4(0.5, 0.25, 0.125, 0.0625)) - 0.46875;\n}\n%s = " - "float4(clamp(%s.xyz + value * range, 0.0, %s.w), %s.w);\n", + "| (x & 4) >> 2;\n value = highfloat(highfloat(half(m)) / 64.0) - 0.4921875;\n} " + "else {\n half4 modValues = half4(mod(sk_FragCoord.xyxy, highfloat4(half4(2.0, " + "2.0, 4.0, 4.0))));\n half4 stepValues = half4(step(highfloat4(modValues), " + "highfloat4(half4(1.0, 1.0, 2.0, 2.0))));\n value = highfloat(dot(stepValues, " + "half4(0.5, 0.25, 0.125, 0.0625))) - 0.46875;\n}\n%s = " + "half4(clamp(highfloat3(%s.xyz + value * range), 0.0, highfloat(%s.w)), %s.w);\n", _outer.rangeType(), args.fOutputColor, - args.fInputColor ? args.fInputColor : "float4(1)", - args.fInputColor ? args.fInputColor : "float4(1)", - args.fInputColor ? args.fInputColor : "float4(1)"); + args.fInputColor ? args.fInputColor : "half4(1)", + args.fInputColor ? args.fInputColor : "half4(1)", + args.fInputColor ? args.fInputColor : "half4(1)"); } private: diff --git a/src/gpu/effects/GrDitherEffect.fp b/src/gpu/effects/GrDitherEffect.fp index fe641c6132..f2d54cf2eb 100644 --- a/src/gpu/effects/GrDitherEffect.fp +++ b/src/gpu/effects/GrDitherEffect.fp @@ -32,8 +32,8 @@ layout(key) in int rangeType; } void main() { - float value; - float range; + half value; + half range; @switch (rangeType) { case 0: range = 1.0 / 255.0; @@ -53,17 +53,17 @@ void main() { uint m = (y & 1) << 5 | (x & 1) << 4 | (y & 2) << 2 | (x & 2) << 1 | (y & 4) >> 1 | (x & 4) >> 2; - value = float(m) * 1.0 / 64.0 - 63.0 / 128.0; + value = half(m) * 1.0 / 64.0 - 63.0 / 128.0; } else { // Simulate the integer effect used above using step/mod. For speed, simulates a 4x4 // dither pattern rather than an 8x8 one. - float4 modValues = mod(sk_FragCoord.xyxy, float4(2.0, 2.0, 4.0, 4.0)); - float4 stepValues = step(modValues, float4(1.0, 1.0, 2.0, 2.0)); - value = dot(stepValues, float4(8.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0)) - 15.0 / 32.0; + half4 modValues = mod(sk_FragCoord.xyxy, 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; } // For each color channel, add the random offset to the channel value and then clamp // between 0 and alpha to keep the color premultiplied. - sk_OutColor = float4(clamp(sk_InColor.rgb + value * range, 0, sk_InColor.a), sk_InColor.a); + sk_OutColor = half4(clamp(sk_InColor.rgb + value * range, 0, sk_InColor.a), sk_InColor.a); } @test(testData) { diff --git a/src/gpu/effects/GrEllipseEffect.cpp b/src/gpu/effects/GrEllipseEffect.cpp index 30391450d8..3f35311717 100644 --- a/src/gpu/effects/GrEllipseEffect.cpp +++ b/src/gpu/effects/GrEllipseEffect.cpp @@ -23,35 +23,34 @@ public: GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>(); (void)_outer; - prevRadii = float2(-1.0); + prevRadii = half2(-1.0); useScale = sk_Caps.floatPrecisionVaries; - fEllipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, - kHigh_GrSLPrecision, "ellipse"); + fEllipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHighFloat4_GrSLType, + kDefault_GrSLPrecision, "ellipse"); if (useScale) { - fScaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec2f_GrSLType, + fScaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, kDefault_GrSLPrecision, "scale"); } fragBuilder->codeAppendf( - "float2 prevCenter;\nfloat2 prevRadii = float2(%f, %f);\nbool useScale = " - "%s;\nfloat2 d = sk_FragCoord.xy - %s.xy;\n@if (useScale) {\n d *= " - "%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}\nfloat alpha;\n@switch (%d) {\n case 0:\n alpha = approx_dist " - "> 0.0 ? 0.0 : 1.0;\n break;\n case 1:\n alpha = clamp(0.5 - " - "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 + " - "approx_dist, 0.0, 1.0);\n break;\n default:\n discard;\n}\n%s = " - "%s * alpha;\n", + "half2 prevCenter;\nhalf2 prevRadii = half2(%f, %f);\nbool useScale = %s;\nhalf2 d " + "= half2(sk_FragCoord.xy - %s.xy);\n@if (useScale) {\n d *= %s.y;\n}\nhalf2 Z = " + "d * half2(%s.zw);\nhalf implicit = dot(Z, d) - 1.0;\nhalf grad_dot = 4.0 * dot(Z, " + "Z);\ngrad_dot = half(max(highfloat(grad_dot), 0.0001));\nhalf approx_dist = " + "highfloat(implicit) * inversesqrt(highfloat(grad_dot));\n@if (useScale) {\n " + "approx_dist *= %s.x;\n}\nhalf alpha;\n@switch (%d) {\n case 0:\n alpha " + "= half(highfloat(approx_dist) > 0.0 ? 0.0 : 1.0);\n break;\n case 1:\n " + " alpha = half(clamp(0.5 - highfloat(approx_dist), 0.0, 1.0));\n " + "break;\n case 2:\n alpha = half(highfloat(approx_dist) > 0.0 ? 1.0 : " + "0.0);\n break;\n case 3:\n alpha = half(clamp(0.5 + " + "highfloat(approx_dist), 0.0, 1.0));\n break;\n default:\n " + "discard;\n}\n%s = %s * alpha;\n", prevRadii.fX, prevRadii.fY, (useScale ? "true" : "false"), args.fUniformHandler->getUniformCStr(fEllipseVar), - fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) - : "float2(0.0)", + fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "half2(0)", args.fUniformHandler->getUniformCStr(fEllipseVar), - fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) - : "float2(0.0)", + fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "half2(0)", _outer.edgeType(), args.fOutputColor, - args.fInputColor ? args.fInputColor : "float4(1)"); + args.fInputColor ? args.fInputColor : "half4(1)"); } private: diff --git a/src/gpu/effects/GrEllipseEffect.fp b/src/gpu/effects/GrEllipseEffect.fp index 85c4c96f75..3663d5622e 100644 --- a/src/gpu/effects/GrEllipseEffect.fp +++ b/src/gpu/effects/GrEllipseEffect.fp @@ -6,17 +6,17 @@ */ layout(key) in int edgeType; -in float2 center; -in float2 radii; +in half2 center; +in half2 radii; -float2 prevCenter; -float2 prevRadii = float2(-1); +half2 prevCenter; +half2 prevRadii = half2(-1); // The ellipse uniform is (center.x, center.y, 1 / rx^2, 1 / ry^2) -// The last two terms can underflow on mediump, so we use highp. -uniform highp float4 ellipse; +// The last two terms can underflow with halfs, so we use floats. +uniform highfloat4 ellipse; bool useScale = sk_Caps.floatPrecisionVaries; -layout(when=useScale) uniform float2 scale; +layout(when=useScale) uniform half2 scale; @optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag } @@ -50,7 +50,7 @@ layout(when=useScale) uniform float2 scale; void main() { // d is the offset to the ellipse center - float2 d = sk_FragCoord.xy - ellipse.xy; + half2 d = sk_FragCoord.xy - ellipse.xy; // If we're on a device with a "real" mediump then we'll do the distance computation in a space // that is normalized by the larger radius. The scale uniform will be scale, 1/scale. The // inverse squared radii uniform values are already in this normalized space. The center is @@ -58,19 +58,19 @@ void main() { @if (useScale) { d *= scale.y; } - float2 Z = d * ellipse.zw; + half2 Z = d * ellipse.zw; // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1. - float implicit = dot(Z, d) - 1; + half implicit = dot(Z, d) - 1; // grad_dot is the squared length of the gradient of the implicit. - float grad_dot = 4 * dot(Z, Z); + half grad_dot = 4 * dot(Z, Z); // Avoid calling inversesqrt on zero. grad_dot = max(grad_dot, 1e-4); - float approx_dist = implicit * inversesqrt(grad_dot); + half approx_dist = implicit * inversesqrt(grad_dot); @if (useScale) { approx_dist *= scale.x; } - float alpha; + half alpha; @switch (edgeType) { case 0 /* kFillBW_GrProcessorEdgeType */: alpha = approx_dist > 0.0 ? 0.0 : 1.0; diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp index 23b617849c..dfbe17a289 100644 --- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp +++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp @@ -41,11 +41,11 @@ void GrGLConvolutionEffect::emitCode(EmitArgs& args) { args.fFp.cast<GrGaussianConvolutionFragmentProcessor>(); GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kVec2f_GrSLType, - kDefault_GrSLPrecision, "ImageIncrement"); + fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, + "ImageIncrement"); if (ce.useBounds()) { - fBoundsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kVec2f_GrSLType, - kDefault_GrSLPrecision, "Bounds"); + fBoundsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, + "Bounds"); } int width = ce.width(); @@ -53,19 +53,19 @@ void GrGLConvolutionEffect::emitCode(EmitArgs& args) { int arrayCount = (width + 3) / 4; SkASSERT(4 * arrayCount >= width); - fKernelUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, kVec4f_GrSLType, - kDefault_GrSLPrecision, "Kernel", arrayCount); + fKernelUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, kHalf4_GrSLType, + "Kernel", arrayCount); GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); - fragBuilder->codeAppendf("%s = float4(0, 0, 0, 0);", args.fOutputColor); + fragBuilder->codeAppendf("%s = half4(0, 0, 0, 0);", args.fOutputColor); const GrShaderVar& kernel = uniformHandler->getUniformVariable(fKernelUni); const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); - fragBuilder->codeAppendf("float2 coord = %s - %d.0 * %s;", coords2D.c_str(), ce.radius(), imgInc); - fragBuilder->codeAppend("float2 coordSampled = float2(0, 0);"); + fragBuilder->codeAppendf("highfloat2 coord = %s - %d.0 * %s;", coords2D.c_str(), ce.radius(), imgInc); + fragBuilder->codeAppend("highfloat2 coordSampled = half2(0, 0);"); // Manually unroll loop because some drivers don't; yields 20-30% speedup. const char* kVecSuffix[4] = {".x", ".y", ".z", ".w"}; diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp index 9d9a03ed4b..063f8f3772 100644 --- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp +++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp @@ -47,20 +47,15 @@ void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) { SkASSERT(4 * arrayCount >= kWidth * kHeight); GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec2f_GrSLType, kDefault_GrSLPrecision, + fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "ImageIncrement"); - fKernelUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, - kVec4f_GrSLType, kDefault_GrSLPrecision, + fKernelUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, kHalf4_GrSLType, "Kernel", arrayCount); - fKernelOffsetUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec2f_GrSLType, kDefault_GrSLPrecision, + fKernelOffsetUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "KernelOffset"); - fGainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, kDefault_GrSLPrecision, "Gain"); - fBiasUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kFloat_GrSLType, kDefault_GrSLPrecision, "Bias"); + fGainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "Gain"); + fBiasUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "Bias"); const char* kernelOffset = uniformHandler->getUniformCStr(fKernelOffsetUni); const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); @@ -70,9 +65,9 @@ void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) { GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); - fragBuilder->codeAppend("float4 sum = float4(0, 0, 0, 0);"); - fragBuilder->codeAppendf("float2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset, imgInc); - fragBuilder->codeAppend("float4 c;"); + fragBuilder->codeAppend("half4 sum = half4(0, 0, 0, 0);"); + fragBuilder->codeAppendf("highfloat2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset, imgInc); + fragBuilder->codeAppend("half4 c;"); const char* kVecSuffix[4] = { ".x", ".y", ".z", ".w" }; for (int y = 0; y < kHeight; y++) { @@ -80,10 +75,10 @@ void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) { GrGLSLShaderBuilder::ShaderBlock block(fragBuilder); int offset = y*kWidth + x; - fragBuilder->codeAppendf("float k = %s[%d]%s;", kernel, offset / 4, + fragBuilder->codeAppendf("half k = %s[%d]%s;", kernel, offset / 4, kVecSuffix[offset & 0x3]); SkString coord; - coord.printf("coord + float2(%d, %d) * %s", x, y, imgInc); + coord.printf("coord + half2(%d, %d) * %s", x, y, imgInc); fDomain.sampleTexture(fragBuilder, uniformHandler, args.fShaderCaps, diff --git a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp index b30746acb7..fee7f17992 100644 --- a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp +++ b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp @@ -23,24 +23,21 @@ public: const char* srcCoeffsName = nullptr; if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kSrcTransfer_Op)) { fSrcTransferFnUni = uniformHandler->addUniformArray( - kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, - "SrcTransferFn", GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, - &srcCoeffsName); + kFragment_GrShaderFlag, kHalf_GrSLType, "SrcTransferFn", + GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, &srcCoeffsName); } const char* dstCoeffsName = nullptr; if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kDstTransfer_Op)) { fDstTransferFnUni = uniformHandler->addUniformArray( - kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, - "DstTransferFn", GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, - &dstCoeffsName); + kFragment_GrShaderFlag, kHalf_GrSLType, "DstTransferFn", + GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, &dstCoeffsName); } const char* gamutXformName = nullptr; if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kGamutXform_Op)) { - fGamutXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat44f_GrSLType, - kDefault_GrSLPrecision, "GamutXform", - &gamutXformName); + fGamutXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4x4_GrSLType, + "GamutXform", &gamutXformName); } // Helper function to apply the src or dst transfer function to a single value @@ -52,32 +49,32 @@ public: } const char* fnName = i ? "dst_transfer_fn" : "src_transfer_fn"; static const GrShaderVar gTransferFnFuncArgs[] = { - GrShaderVar("x", kFloat_GrSLType), + GrShaderVar("x", kHalf_GrSLType), }; SkString transferFnBody; // Temporaries to make evaluation line readable - transferFnBody.printf("float A = %s[0];", coeffsName); - transferFnBody.appendf("float B = %s[1];", coeffsName); - transferFnBody.appendf("float C = %s[2];", coeffsName); - transferFnBody.appendf("float D = %s[3];", coeffsName); - transferFnBody.appendf("float E = %s[4];", coeffsName); - transferFnBody.appendf("float F = %s[5];", coeffsName); - transferFnBody.appendf("float G = %s[6];", coeffsName); - transferFnBody.append("float s = sign(x);"); + transferFnBody.printf("half A = %s[0];", coeffsName); + transferFnBody.appendf("half B = %s[1];", coeffsName); + transferFnBody.appendf("half C = %s[2];", coeffsName); + transferFnBody.appendf("half D = %s[3];", coeffsName); + transferFnBody.appendf("half E = %s[4];", coeffsName); + transferFnBody.appendf("half F = %s[5];", coeffsName); + transferFnBody.appendf("half G = %s[6];", coeffsName); + transferFnBody.append("half s = sign(x);"); transferFnBody.append("x = abs(x);"); transferFnBody.appendf("return s * ((x < D) ? (C * x) + F : pow(A * x + B, G) + E);"); - fragBuilder->emitFunction(kFloat_GrSLType, fnName, SK_ARRAY_COUNT(gTransferFnFuncArgs), + fragBuilder->emitFunction(kHalf_GrSLType, fnName, SK_ARRAY_COUNT(gTransferFnFuncArgs), gTransferFnFuncArgs, transferFnBody.c_str(), &tfFuncNames[i]); } if (nullptr == args.fInputColor) { - args.fInputColor = "float4(1)"; + args.fInputColor = "half4(1)"; } - fragBuilder->codeAppendf("float4 color = %s;", args.fInputColor); + fragBuilder->codeAppendf("half4 color = %s;", args.fInputColor); // 1: Un-premultiply the input color (if necessary) - fragBuilder->codeAppendf("float nonZeroAlpha = max(color.a, 0.00001);"); - fragBuilder->codeAppendf("color = float4(color.rgb / nonZeroAlpha, nonZeroAlpha);"); + fragBuilder->codeAppendf("half nonZeroAlpha = max(color.a, 0.00001);"); + fragBuilder->codeAppendf("color = half4(color.rgb / nonZeroAlpha, nonZeroAlpha);"); // 2: Apply src transfer function (to get to linear RGB) if (srcCoeffsName) { @@ -89,7 +86,7 @@ public: // 3: Apply gamut matrix if (gamutXformName) { fragBuilder->codeAppendf( - "color.rgb = (%s * float4(color.rgb, 1.0)).rgb;", gamutXformName); + "color.rgb = (%s * half4(color.rgb, 1.0)).rgb;", gamutXformName); } // 4: Apply dst transfer fn @@ -100,7 +97,7 @@ public: } // 5: Premultiply again - fragBuilder->codeAppendf("%s = float4(color.rgb * color.a, color.a);", args.fOutputColor); + fragBuilder->codeAppendf("%s = half4(color.rgb * color.a, color.a);", args.fOutputColor); } static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&, diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 658f190621..e6c7bf9a80 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -440,7 +440,7 @@ static void append_color_output(const PorterDuffXferProcessor& xp, SkASSERT(inColor); switch (outputType) { case BlendFormula::kNone_OutputType: - fragBuilder->codeAppendf("%s = float4(0.0);", output); + fragBuilder->codeAppendf("%s = half4(0.0);", output); break; case BlendFormula::kCoverage_OutputType: // We can have a coverage formula while not reading coverage if there are mixed samples. @@ -456,7 +456,7 @@ static void append_color_output(const PorterDuffXferProcessor& xp, fragBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColor, inCoverage); break; case BlendFormula::kISCModulate_OutputType: - fragBuilder->codeAppendf("%s = (float4(1.0) - %s) * %s;", output, inColor, inCoverage); + fragBuilder->codeAppendf("%s = (half4(1.0) - %s) * %s;", output, inColor, inCoverage); break; default: SK_ABORT("Unsupported output type."); @@ -629,8 +629,8 @@ public: private: void emitOutputsForBlendState(const EmitArgs& args) override { const char* alpha; - fAlphaUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, - kDefault_GrSLPrecision, "alpha", &alpha); + fAlphaUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, + "alpha", &alpha); GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; // We want to force our primary output to be alpha * Coverage, where alpha is the alpha // value of the src color. We know that there are no color stages (or we wouldn't have diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp index 6d47e58292..7ad354cee3 100644 --- a/src/gpu/effects/GrRRectEffect.cpp +++ b/src/gpu/effects/GrRRectEffect.cpp @@ -160,15 +160,11 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) { // edges correspond to components x, y, z, and w, respectively. When a side of the rrect has // only rectangular corners, that side's value corresponds to the rect edge's value outset by // half a pixel. - fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, kDefault_GrSLPrecision, - "innerRect", - &rectName); + fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, + "innerRect", &rectName); // x is (r + .5) and y is 1/(r + .5) - fRadiusPlusHalfUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec2f_GrSLType, kDefault_GrSLPrecision, - "radiusPlusHalf", - &radiusPlusHalfName); + fRadiusPlusHalfUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, + "radiusPlusHalf", &radiusPlusHalfName); // If we're on a device with a "real" mediump then the length calculation could overflow. SkString clampedCircleDistance; @@ -197,87 +193,87 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) { // alphas together. switch (crre.getCircularCornerFlags()) { case CircularRRectEffect::kAll_CornerFlags: - 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("float alpha = %s;", clampedCircleDistance.c_str()); + fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); + fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppend("half2 dxy = max(max(dxy0, dxy1), 0.0);"); + fragBuilder->codeAppendf("half alpha = %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kTopLeft_CornerFlag: - fragBuilder->codeAppendf("float2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);", + fragBuilder->codeAppendf("half2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);", rectName); - fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);", + fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);", + fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = bottomAlpha * rightAlpha * %s;", + fragBuilder->codeAppendf("half alpha = bottomAlpha * rightAlpha * %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);", + fragBuilder->codeAppendf("half2 dxy = max(half2(sk_FragCoord.x - %s.z, " + "%s.y - sk_FragCoord.y), 0.0);", rectName, rectName); - fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);", + fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);", + fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = bottomAlpha * leftAlpha * %s;", + fragBuilder->codeAppendf("half alpha = bottomAlpha * leftAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kBottomRight_CornerFlag: - fragBuilder->codeAppendf("float2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);", + fragBuilder->codeAppendf("half2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);", rectName); - fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);", + fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);", + fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = topAlpha * leftAlpha * %s;", + fragBuilder->codeAppendf("half alpha = topAlpha * leftAlpha * %s;", clampedCircleDistance.c_str()); break; case CircularRRectEffect::kBottomLeft_CornerFlag: - fragBuilder->codeAppendf("float2 dxy = max(float2(%s.x - sk_FragCoord.x, sk_FragCoord.y - " + fragBuilder->codeAppendf("half2 dxy = max(half2(%s.x - sk_FragCoord.x, sk_FragCoord.y - " "%s.w), 0.0);", rectName, rectName); - fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);", + fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);", + fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = topAlpha * rightAlpha * %s;", + fragBuilder->codeAppendf("half alpha = topAlpha * rightAlpha * %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("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);", + fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); + fragBuilder->codeAppendf("half dy1 = sk_FragCoord.y - %s.w;", rectName); + fragBuilder->codeAppend("half2 dxy = max(half2(dxy0.x, max(dxy0.y, dy1)), 0.0);"); + fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = rightAlpha * %s;", + fragBuilder->codeAppendf("half alpha = rightAlpha * %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("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);", + fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); + fragBuilder->codeAppendf("half dx1 = sk_FragCoord.x - %s.z;", rectName); + fragBuilder->codeAppend("half2 dxy = max(half2(max(dxy0.x, dx1), dxy0.y), 0.0);"); + fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = bottomAlpha * %s;", + fragBuilder->codeAppendf("half alpha = bottomAlpha * %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("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);", + fragBuilder->codeAppendf("half dy0 = %s.y - sk_FragCoord.y;", rectName); + fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppend("half2 dxy = max(half2(dxy1.x, max(dy0, dxy1.y)), 0.0);"); + fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = leftAlpha * %s;", + fragBuilder->codeAppendf("half alpha = leftAlpha * %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("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);", + fragBuilder->codeAppendf("half dx0 = %s.x - sk_FragCoord.x;", rectName); + fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppend("half2 dxy = max(half2(max(dx0, dxy1.x), dxy1.y), 0.0);"); + fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);", rectName); - fragBuilder->codeAppendf("float alpha = topAlpha * %s;", + fragBuilder->codeAppendf("half alpha = topAlpha * %s;", clampedCircleDistance.c_str()); break; } @@ -514,10 +510,8 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) { GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; const char *rectName; // The inner rect is the rrect bounds inset by the x/y radii - fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, kDefault_GrSLPrecision, - "innerRect", - &rectName); + fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, + "innerRect", &rectName); GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos @@ -532,17 +526,16 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) { // The code below is a simplified version of the above that performs maxs on the vector // components before computing distances and alpha values so that only one distance computation // need be computed to determine the min alpha. - fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); - fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); + fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName); + fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName); // If we're on a device with a "real" mediump then we'll do the distance computation in a space // that is normalized by the largest radius. The scale uniform will be scale, 1/scale. The // radii uniform values are already in this normalized space. const char* scaleName = nullptr; if (args.fShaderCaps->floatPrecisionVaries()) { - fScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec2f_GrSLType, kDefault_GrSLPrecision, - "scale", &scaleName); + fScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "scale", + &scaleName); } // The uniforms with the inv squared radii are highp to prevent underflow. @@ -550,34 +543,32 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) { case SkRRect::kSimple_Type: { const char *invRadiiXYSqdName; fInvRadiiSqdUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec2f_GrSLType, - kDefault_GrSLPrecision, + kHalf2_GrSLType, "invRadiiXY", &invRadiiXYSqdName); - fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);"); + fragBuilder->codeAppend("half2 dxy = max(max(dxy0, dxy1), 0.0);"); if (scaleName) { fragBuilder->codeAppendf("dxy *= %s.y;", scaleName); } // Z is the x/y offsets divided by squared radii. - fragBuilder->codeAppendf("float2 Z = dxy * %s.xy;", invRadiiXYSqdName); + fragBuilder->codeAppendf("half2 Z = dxy * %s.xy;", invRadiiXYSqdName); break; } case SkRRect::kNinePatch_Type: { const char *invRadiiLTRBSqdName; fInvRadiiSqdUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, - kDefault_GrSLPrecision, + kHalf4_GrSLType, "invRadiiLTRB", &invRadiiLTRBSqdName); if (scaleName) { fragBuilder->codeAppendf("dxy0 *= %s.y;", scaleName); fragBuilder->codeAppendf("dxy1 *= %s.y;", scaleName); } - fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);"); + fragBuilder->codeAppend("half2 dxy = max(max(dxy0, dxy1), 0.0);"); // Z is the x/y offsets divided by squared radii. We only care about the (at most) one // corner where both the x and y offsets are positive, hence the maxes. (The inverse // squared radii will always be positive.) - fragBuilder->codeAppendf("float2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);", + fragBuilder->codeAppendf("half2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);", invRadiiLTRBSqdName, invRadiiLTRBSqdName); break; @@ -586,20 +577,20 @@ 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 = 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 = 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 * inversesqrt(grad_dot);"); if (scaleName) { fragBuilder->codeAppendf("approx_dist *= %s.x;", scaleName); } if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) { - fragBuilder->codeAppend("float alpha = clamp(0.5 - approx_dist, 0.0, 1.0);"); + fragBuilder->codeAppend("half alpha = clamp(0.5 - approx_dist, 0.0, 1.0);"); } else { - fragBuilder->codeAppend("float alpha = clamp(0.5 + approx_dist, 0.0, 1.0);"); + fragBuilder->codeAppend("half alpha = clamp(0.5 + approx_dist, 0.0, 1.0);"); } fragBuilder->codeAppendf("%s = %s * alpha;", args.fOutputColor, args.fInputColor); diff --git a/src/gpu/effects/GrSRGBEffect.cpp b/src/gpu/effects/GrSRGBEffect.cpp index f415a6cef1..0e56dfcdb9 100644 --- a/src/gpu/effects/GrSRGBEffect.cpp +++ b/src/gpu/effects/GrSRGBEffect.cpp @@ -20,11 +20,11 @@ public: SkString srgbFuncName; static const GrShaderVar gSrgbArgs[] = { - GrShaderVar("x", kFloat_GrSLType), + GrShaderVar("x", kHalf_GrSLType), }; switch (srgbe.mode()) { case GrSRGBEffect::Mode::kLinearToSRGB: - fragBuilder->emitFunction(kFloat_GrSLType, + fragBuilder->emitFunction(kHalf_GrSLType, "linear_to_srgb", SK_ARRAY_COUNT(gSrgbArgs), gSrgbArgs, @@ -33,7 +33,7 @@ public: &srgbFuncName); break; case GrSRGBEffect::Mode::kSRGBToLinear: - fragBuilder->emitFunction(kFloat_GrSLType, + fragBuilder->emitFunction(kHalf_GrSLType, "srgb_to_linear", SK_ARRAY_COUNT(gSrgbArgs), gSrgbArgs, @@ -44,20 +44,20 @@ public: } if (nullptr == args.fInputColor) { - args.fInputColor = "float4(1)"; + args.fInputColor = "half4(1)"; } - fragBuilder->codeAppendf("float4 color = %s;", args.fInputColor); + fragBuilder->codeAppendf("half4 color = %s;", args.fInputColor); if (srgbe.alpha() == GrSRGBEffect::Alpha::kPremul) { - fragBuilder->codeAppendf("float nonZeroAlpha = max(color.a, 0.00001);"); - fragBuilder->codeAppendf("color = float4(color.rgb / nonZeroAlpha, color.a);"); + fragBuilder->codeAppendf("half nonZeroAlpha = max(color.a, 0.00001);"); + fragBuilder->codeAppendf("color = half4(color.rgb / nonZeroAlpha, color.a);"); } - fragBuilder->codeAppendf("color = float4(%s(color.r), %s(color.g), %s(color.b), color.a);", + fragBuilder->codeAppendf("color = half4(%s(color.r), %s(color.g), %s(color.b), color.a);", srgbFuncName.c_str(), srgbFuncName.c_str(), srgbFuncName.c_str()); if (srgbe.alpha() == GrSRGBEffect::Alpha::kPremul) { - fragBuilder->codeAppendf("color = float4(color.rgb, 1) * color.a;"); + fragBuilder->codeAppendf("color = half4(color.rgb, 1) * color.a;"); } fragBuilder->codeAppendf("%s = color;", args.fOutputColor); } diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp index 297dd50ada..ca4c5dba75 100644 --- a/src/gpu/effects/GrShadowGeoProc.cpp +++ b/src/gpu/effects/GrShadowGeoProc.cpp @@ -26,7 +26,7 @@ public: // emit attributes varyingHandler->emitAttributes(rsgp); - fragBuilder->codeAppend("float4 shadowParams;"); + fragBuilder->codeAppend("half4 shadowParams;"); varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams"); // setup pass through color @@ -43,12 +43,12 @@ public: rsgp.inPosition()->fName, args.fFPCoordTransformHandler); - fragBuilder->codeAppend("float d = length(shadowParams.xy);"); - fragBuilder->codeAppend("float distance = shadowParams.z * (1.0 - d);"); + fragBuilder->codeAppend("half d = length(shadowParams.xy);"); + fragBuilder->codeAppend("half distance = shadowParams.z * (1.0 - d);"); - fragBuilder->codeAppend("float factor = 1.0 - clamp(distance, 0.0, shadowParams.w);"); + fragBuilder->codeAppend("half factor = 1.0 - clamp(distance, 0.0, shadowParams.w);"); fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;"); - fragBuilder->codeAppendf("%s = float4(factor);", + fragBuilder->codeAppendf("%s = half4(factor);", args.fOutputCoverage); } diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp index 3301694004..ad2a5339f0 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.cpp +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -26,15 +26,15 @@ public: fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get()); SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); fragBuilder->codeAppendf( - "float4 _tmpVar1;%s = %s * %stexture(%s, %s).%s%s;\n", args.fOutputColor, - args.fInputColor ? args.fInputColor : "float4(1)", + "half4 _tmpVar1;%s = %s * %stexture(%s, %s).%s%s;\n", args.fOutputColor, + args.fInputColor ? args.fInputColor : "half4(1)", fColorSpaceHelper.isValid() ? "(_tmpVar1 = " : "", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), sk_TransformedCoords2D_0.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() - ? SkStringPrintf(", float4(clamp((%s * float4(_tmpVar1.rgb, 1.0)).rgb, " - "0.0, _tmpVar1.a), _tmpVar1.a))", + ? SkStringPrintf(", half4(clamp((%s * half4(_tmpVar1.rgb, 1.0)).rgb, 0.0, " + "_tmpVar1.a), _tmpVar1.a))", args.fUniformHandler->getUniformCStr( fColorSpaceHelper.gamutXformUniform())) .c_str() diff --git a/src/gpu/effects/GrSimpleTextureEffect.fp b/src/gpu/effects/GrSimpleTextureEffect.fp index a4275b566f..456448a6ea 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.fp +++ b/src/gpu/effects/GrSimpleTextureEffect.fp @@ -7,7 +7,7 @@ in uniform sampler2D image; in uniform colorSpaceXform colorXform; -in float4x4 matrix; +in half4x4 matrix; @constructorParams { GrSamplerState samplerParams diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index 3bb96b23cd..c297560cea 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -78,8 +78,7 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, if (textureDomain.fIndex >= 0) { uniName.appendS32(textureDomain.fIndex); } - fDomainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, kDefault_GrSLPrecision, + fDomainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, uniName.c_str(), &name); fDomainName = name; } @@ -88,7 +87,7 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, case kIgnore_Mode: { builder->codeAppendf("%s = ", outColor); builder->appendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str(), - kVec2f_GrSLType, colorXformHelper); + kHighFloat2_GrSLType, colorXformHelper); builder->codeAppend(";"); break; } @@ -99,7 +98,7 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, builder->codeAppendf("%s = ", outColor); builder->appendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str(), - kVec2f_GrSLType, colorXformHelper); + kHighFloat2_GrSLType, colorXformHelper); builder->codeAppend(";"); break; } @@ -115,20 +114,20 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, // may return undefined results". This appears to be an issue with // the 'any' call since even the simple "result=black; if (any()) // result=white;" code fails to compile. - builder->codeAppend("float4 outside = float4(0.0, 0.0, 0.0, 0.0);"); - builder->codeAppend("float4 inside = "); + builder->codeAppend("half4 outside = half4(0.0, 0.0, 0.0, 0.0);"); + builder->codeAppend("half4 inside = "); builder->appendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str(), - kVec2f_GrSLType, colorXformHelper); + kHighFloat2_GrSLType, colorXformHelper); builder->codeAppend(";"); - builder->codeAppendf("highp float x = (%s).x;", inCoords.c_str()); - builder->codeAppendf("highp float y = (%s).y;", inCoords.c_str()); + builder->codeAppendf("highfloat x = (%s).x;", inCoords.c_str()); + builder->codeAppendf("highfloat y = (%s).y;", inCoords.c_str()); builder->codeAppendf("x = abs(2.0*(x - %s.x)/(%s.z - %s.x) - 1.0);", domain, domain, domain); builder->codeAppendf("y = abs(2.0*(y - %s.y)/(%s.w - %s.y) - 1.0);", domain, domain, domain); - builder->codeAppend("float blend = step(1.0, max(x, y));"); + builder->codeAppend("half blend = step(1.0, max(x, y));"); builder->codeAppendf("%s = mix(inside, outside, blend);", outColor); } else { builder->codeAppend("bool4 outside;\n"); @@ -136,10 +135,10 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, domain); builder->codeAppendf("outside.zw = greaterThan(%s, %s.zw);", inCoords.c_str(), domain); - builder->codeAppendf("%s = any(outside) ? float4(0.0, 0.0, 0.0, 0.0) : ", + builder->codeAppendf("%s = any(outside) ? half4(0.0, 0.0, 0.0, 0.0) : ", outColor); builder->appendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str(), - kVec2f_GrSLType, colorXformHelper); + kHighFloat2_GrSLType, colorXformHelper); builder->codeAppend(";"); } break; @@ -152,7 +151,7 @@ void GrTextureDomain::GLDomain::sampleTexture(GrGLSLShaderBuilder* builder, builder->codeAppendf("%s = ", outColor); builder->appendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str(), - kVec2f_GrSLType, colorXformHelper); + kHighFloat2_GrSLType, colorXformHelper); builder->codeAppend(";"); break; } @@ -377,11 +376,10 @@ GrGLSLFragmentProcessor* GrDeviceSpaceTextureDecalFragmentProcessor::onCreateGLS args.fFp.cast<GrDeviceSpaceTextureDecalFragmentProcessor>(); const char* scaleAndTranslateName; fScaleAndTranslateUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, - kVec4f_GrSLType, - kDefault_GrSLPrecision, + kHalf4_GrSLType, "scaleAndTranslate", &scaleAndTranslateName); - args.fFragBuilder->codeAppendf("float2 coords = sk_FragCoord.xy * %s.xy + %s.zw;", + args.fFragBuilder->codeAppendf("half2 coords = sk_FragCoord.xy * %s.xy + %s.zw;", scaleAndTranslateName, scaleAndTranslateName); fGLDomain.sampleTexture(args.fFragBuilder, args.fUniformHandler, diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h index ec0ef4ea8b..6d1f4b268c 100644 --- a/src/gpu/effects/GrTextureDomain.h +++ b/src/gpu/effects/GrTextureDomain.h @@ -23,7 +23,7 @@ struct SkRect; /** * Limits a texture's lookup coordinates to a domain. Samples outside the domain are either clamped - * the edge of the domain or result in a float4 of zeros (decal mode). The domain is clipped to + * the edge of the domain or result in a half4 of zeros (decal mode). The domain is clipped to * normalized texture coords ([0,1]x[0,1] square). Bilinear filtering can cause texels outside the * domain to affect the read value unless the caller considers this when calculating the domain. */ @@ -98,7 +98,7 @@ public: * Call this from GrGLSLFragmentProcessor::emitCode() to sample the texture W.R.T. the * domain and mode. * - * @param outcolor name of float4 variable to hold the sampled color. + * @param outcolor name of half4 variable to hold the sampled color. * @param inCoords name of float2 variable containing the coords to be used with the domain. * It is assumed that this is a variable and not an expression. * @param inModulateColor if non-nullptr the sampled color will be modulated with this diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp index 3b9b44cd57..11dee67f29 100644 --- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp +++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp @@ -217,7 +217,7 @@ void GLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) { const char* inputColor = nullptr; if (args.fInputColor) { inputColor = "inputColor"; - fragBuilder->codeAppendf("float4 inputColor = float4(%s.rgb, 1.0);", args.fInputColor); + fragBuilder->codeAppendf("half4 inputColor = half4(%s.rgb, 1.0);", args.fInputColor); } // declare outputColor and emit the code for each of the two children @@ -452,7 +452,7 @@ public: const char* inputColor = args.fInputColor; // We don't try to optimize for this case at all if (!inputColor) { - fragBuilder->codeAppendf("const float4 ones = float4(1);"); + fragBuilder->codeAppendf("const half4 ones = half4(1);"); inputColor = "ones"; } diff --git a/src/gpu/effects/GrYUVEffect.cpp b/src/gpu/effects/GrYUVEffect.cpp index c45e9b257e..bf9e94ff76 100644 --- a/src/gpu/effects/GrYUVEffect.cpp +++ b/src/gpu/effects/GrYUVEffect.cpp @@ -89,10 +89,9 @@ public: const YUVtoRGBEffect& effect = args.fFp.cast<YUVtoRGBEffect>(); const char* colorSpaceMatrix = nullptr; - fMatrixUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, - kMat44f_GrSLType, kDefault_GrSLPrecision, + fMatrixUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4x4_GrSLType, "ColorSpaceMatrix", &colorSpaceMatrix); - fragBuilder->codeAppendf("%s = float4(", args.fOutputColor); + fragBuilder->codeAppendf("%s = half4(", args.fOutputColor); fragBuilder->appendTextureLookup(args.fTexSamplers[0], args.fTransformedCoords[0].c_str(), args.fTransformedCoords[0].getType()); |