diff options
Diffstat (limited to 'src/gpu/glsl')
-rw-r--r-- | src/gpu/glsl/GrGLSL.cpp | 20 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLBlend.cpp | 82 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLColorSpaceXformHelper.h | 4 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentProcessor.cpp | 2 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentProcessor.h | 8 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp | 26 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentShaderBuilder.h | 11 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 41 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp | 5 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLProgramBuilder.cpp | 7 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderBuilder.cpp | 8 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderBuilder.h | 10 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLUniformHandler.h | 17 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp | 20 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLXferProcessor.cpp | 26 |
15 files changed, 157 insertions, 130 deletions
diff --git a/src/gpu/glsl/GrGLSL.cpp b/src/gpu/glsl/GrGLSL.cpp index 8f3ef3102a..b580f0b8a7 100644 --- a/src/gpu/glsl/GrGLSL.cpp +++ b/src/gpu/glsl/GrGLSL.cpp @@ -25,3 +25,23 @@ bool GrGLSLSupportsNamedFragmentShaderOutputs(GrGLSLGeneration gen) { } return false; } + +void GrGLSLAppendDefaultFloatPrecisionDeclaration(GrSLPrecision p, + const GrShaderCaps& shaderCaps, + SkString* out) { + if (shaderCaps.usesPrecisionModifiers()) { + switch (p) { + case kHigh_GrSLPrecision: + out->append("precision highp float;\n"); + break; + case kMedium_GrSLPrecision: + out->append("precision mediump float;\n"); + break; + case kLow_GrSLPrecision: + out->append("precision lowp float;\n"); + break; + default: + SK_ABORT("Unknown precision value."); + } + } +} diff --git a/src/gpu/glsl/GrGLSLBlend.cpp b/src/gpu/glsl/GrGLSLBlend.cpp index 254f4816cb..34df0df410 100644 --- a/src/gpu/glsl/GrGLSLBlend.cpp +++ b/src/gpu/glsl/GrGLSLBlend.cpp @@ -50,7 +50,7 @@ static void color_dodge_component(GrGLSLFragmentBuilder* fsBuilder, fsBuilder->codeAppendf("%s.%c = %s.%c * (1.0 - %s.a);", final, component, src, component, dst); fsBuilder->codeAppend("} else {"); - fsBuilder->codeAppendf("half d = %s.a - %s.%c;", src, src, component); + fsBuilder->codeAppendf("float d = %s.a - %s.%c;", src, src, component); fsBuilder->codeAppend("if (0.0 == d) {"); fsBuilder->codeAppendf("%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);", final, component, src, dst, src, component, dst, dst, component, @@ -84,7 +84,7 @@ static void color_burn_component(GrGLSLFragmentBuilder* fsBuilder, fsBuilder->codeAppendf("%s.%c = %s.%c * (1.0 - %s.a);", final, component, dst, component, src); fsBuilder->codeAppend("} else {"); - fsBuilder->codeAppendf("half d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / (%s.%c %s));", + fsBuilder->codeAppendf("float d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / (%s.%c %s));", dst, dst, dst, component, src, src, component, divisorGuard); fsBuilder->codeAppendf("%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);", final, component, src, src, component, dst, dst, component, src); @@ -114,11 +114,11 @@ static void soft_light_component_pos_dst_alpha(GrGLSLFragmentBuilder* fsBuilder, // else if (4D < Da) fsBuilder->codeAppendf("} else if (4.0 * %s.%c <= %s.a) {", dst, component, dst); - fsBuilder->codeAppendf("half DSqd = %s.%c * %s.%c;", + fsBuilder->codeAppendf("float DSqd = %s.%c * %s.%c;", dst, component, dst, component); - fsBuilder->codeAppendf("half DCub = DSqd * %s.%c;", dst, component); - fsBuilder->codeAppendf("half DaSqd = %s.a * %s.a;", dst, dst); - fsBuilder->codeAppendf("half DaCub = DaSqd * %s.a;", dst); + fsBuilder->codeAppendf("float DCub = DSqd * %s.%c;", dst, component); + fsBuilder->codeAppendf("float DaSqd = %s.a * %s.a;", dst, dst); + fsBuilder->codeAppendf("float DaCub = DaSqd * %s.a;", dst); // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa-2 S))/Da^2 fsBuilder->codeAppendf("%s.%c =" "(DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) +" @@ -144,10 +144,10 @@ static void add_lum_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setLumF // Emit a helper that gets the luminance of a color. SkString getFunction; GrShaderVar getLumArgs[] = { - GrShaderVar("color", kHalf3_GrSLType), + GrShaderVar("color", kVec3f_GrSLType), }; - SkString getLumBody("return dot(highfloat3(0.3, 0.59, 0.11), color);"); - fsBuilder->emitFunction(kHalf_GrSLType, + SkString getLumBody("return dot(float3(0.3, 0.59, 0.11), color);"); + fsBuilder->emitFunction(kFloat_GrSLType, "luminance", SK_ARRAY_COUNT(getLumArgs), getLumArgs, getLumBody.c_str(), @@ -155,27 +155,27 @@ static void add_lum_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setLumF // Emit the set luminance function. GrShaderVar setLumArgs[] = { - GrShaderVar("hueSat", kHalf3_GrSLType), - GrShaderVar("alpha", kHalf_GrSLType), - GrShaderVar("lumColor", kHalf3_GrSLType), + GrShaderVar("hueSat", kVec3f_GrSLType), + GrShaderVar("alpha", kFloat_GrSLType), + GrShaderVar("lumColor", kVec3f_GrSLType), }; SkString setLumBody; - setLumBody.printf("half diff = %s(lumColor - hueSat);", getFunction.c_str()); - setLumBody.append("half3 outColor = hueSat + diff;"); - setLumBody.appendf("half outLum = %s(outColor);", getFunction.c_str()); - setLumBody.append("half minComp = min(min(outColor.r, outColor.g), outColor.b);" - "half maxComp = max(max(outColor.r, outColor.g), outColor.b);" + setLumBody.printf("float diff = %s(lumColor - hueSat);", getFunction.c_str()); + setLumBody.append("float3 outColor = hueSat + diff;"); + setLumBody.appendf("float outLum = %s(outColor);", getFunction.c_str()); + setLumBody.append("float minComp = min(min(outColor.r, outColor.g), outColor.b);" + "float maxComp = max(max(outColor.r, outColor.g), outColor.b);" "if (minComp < 0.0 && outLum != minComp) {" - "outColor = outLum + ((outColor - half3(outLum, outLum, outLum)) * outLum) /" + "outColor = outLum + ((outColor - float3(outLum, outLum, outLum)) * outLum) /" "(outLum - minComp);" "}" "if (maxComp > alpha && maxComp != outLum) {" "outColor = outLum +" - "((outColor - half3(outLum, outLum, outLum)) * (alpha - outLum)) /" + "((outColor - float3(outLum, outLum, outLum)) * (alpha - outLum)) /" "(maxComp - outLum);" "}" "return outColor;"); - fsBuilder->emitFunction(kHalf3_GrSLType, + fsBuilder->emitFunction(kVec3f_GrSLType, "set_luminance", SK_ARRAY_COUNT(setLumArgs), setLumArgs, setLumBody.c_str(), @@ -188,11 +188,11 @@ static void add_lum_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setLumF static void add_sat_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setSatFunction) { // Emit a helper that gets the saturation of a color SkString getFunction; - GrShaderVar getSatArgs[] = { GrShaderVar("color", kHalf3_GrSLType) }; + GrShaderVar getSatArgs[] = { GrShaderVar("color", kVec3f_GrSLType) }; SkString getSatBody; getSatBody.printf("return max(max(color.r, color.g), color.b) - " "min(min(color.r, color.g), color.b);"); - fsBuilder->emitFunction(kHalf_GrSLType, + fsBuilder->emitFunction(kFloat_GrSLType, "saturation", SK_ARRAY_COUNT(getSatArgs), getSatArgs, getSatBody.c_str(), @@ -204,33 +204,33 @@ static void add_sat_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setSatF // adjusted min, mid, and max inputs, respectively. SkString helperFunction; GrShaderVar helperArgs[] = { - GrShaderVar("minComp", kHalf_GrSLType), - GrShaderVar("midComp", kHalf_GrSLType), - GrShaderVar("maxComp", kHalf_GrSLType), - GrShaderVar("sat", kHalf_GrSLType), + GrShaderVar("minComp", kFloat_GrSLType), + GrShaderVar("midComp", kFloat_GrSLType), + GrShaderVar("maxComp", kFloat_GrSLType), + GrShaderVar("sat", kFloat_GrSLType), }; static const char kHelperBody[] = "if (minComp < maxComp) {" - "half3 result;" + "float3 result;" "result.r = 0.0;" "result.g = sat * (midComp - minComp) / (maxComp - minComp);" "result.b = sat;" "return result;" "} else {" - "return half3(0, 0, 0);" + "return float3(0, 0, 0);" "}"; - fsBuilder->emitFunction(kHalf3_GrSLType, + fsBuilder->emitFunction(kVec3f_GrSLType, "set_saturation_helper", SK_ARRAY_COUNT(helperArgs), helperArgs, kHelperBody, &helperFunction); GrShaderVar setSatArgs[] = { - GrShaderVar("hueLumColor", kHalf3_GrSLType), - GrShaderVar("satColor", kHalf3_GrSLType), + GrShaderVar("hueLumColor", kVec3f_GrSLType), + GrShaderVar("satColor", kVec3f_GrSLType), }; const char* helpFunc = helperFunction.c_str(); SkString setSatBody; - setSatBody.appendf("half sat = %s(satColor);" + setSatBody.appendf("float sat = %s(satColor);" "if (hueLumColor.r <= hueLumColor.g) {" "if (hueLumColor.g <= hueLumColor.b) {" "hueLumColor.rgb = %s(hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);" @@ -249,7 +249,7 @@ static void add_sat_function(GrGLSLFragmentBuilder* fsBuilder, SkString* setSatF "return hueLumColor;", getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc, helpFunc, helpFunc); - fsBuilder->emitFunction(kHalf3_GrSLType, + fsBuilder->emitFunction(kVec3f_GrSLType, "set_saturation", SK_ARRAY_COUNT(setSatArgs), setSatArgs, setSatBody.c_str(), @@ -330,7 +330,7 @@ static void emit_advanced_xfermode_code(GrGLSLFragmentBuilder* fsBuilder, const SkString setSat, setLum; add_sat_function(fsBuilder, &setSat); add_lum_function(fsBuilder, &setLum); - fsBuilder->codeAppendf("half4 dstSrcAlpha = %s * %s.a;", + fsBuilder->codeAppendf("float4 dstSrcAlpha = %s * %s.a;", dstColor, srcColor); fsBuilder->codeAppendf("%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb)," "dstSrcAlpha.a, dstSrcAlpha.rgb);", @@ -345,7 +345,7 @@ static void emit_advanced_xfermode_code(GrGLSLFragmentBuilder* fsBuilder, const SkString setSat, setLum; add_sat_function(fsBuilder, &setSat); add_lum_function(fsBuilder, &setLum); - fsBuilder->codeAppendf("half4 dstSrcAlpha = %s * %s.a;", + fsBuilder->codeAppendf("float4 dstSrcAlpha = %s * %s.a;", dstColor, srcColor); fsBuilder->codeAppendf("%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a)," "dstSrcAlpha.a, dstSrcAlpha.rgb);", @@ -359,7 +359,7 @@ static void emit_advanced_xfermode_code(GrGLSLFragmentBuilder* fsBuilder, const // SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S SkString setLum; add_lum_function(fsBuilder, &setLum); - fsBuilder->codeAppendf("half4 srcDstAlpha = %s * %s.a;", + fsBuilder->codeAppendf("float4 srcDstAlpha = %s * %s.a;", srcColor, dstColor); fsBuilder->codeAppendf("%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);", outputColor, setLum.c_str(), dstColor, srcColor); @@ -371,7 +371,7 @@ static void emit_advanced_xfermode_code(GrGLSLFragmentBuilder* fsBuilder, const // SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S SkString setLum; add_lum_function(fsBuilder, &setLum); - fsBuilder->codeAppendf("half4 srcDstAlpha = %s * %s.a;", + fsBuilder->codeAppendf("float4 srcDstAlpha = %s * %s.a;", srcColor, dstColor); fsBuilder->codeAppendf("%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);", outputColor, setLum.c_str(), dstColor, srcColor); @@ -406,13 +406,13 @@ static bool append_porterduff_term(GrGLSLFragmentBuilder* fsBuilder, SkBlendMode fsBuilder->codeAppendf(" * %s", srcColorName); break; case SkBlendModeCoeff::kISC: - fsBuilder->codeAppendf(" * (half4(1.0) - %s)", srcColorName); + fsBuilder->codeAppendf(" * (float4(1.0) - %s)", srcColorName); break; case SkBlendModeCoeff::kDC: fsBuilder->codeAppendf(" * %s", dstColorName); break; case SkBlendModeCoeff::kIDC: - fsBuilder->codeAppendf(" * (half4(1.0) - %s)", dstColorName); + fsBuilder->codeAppendf(" * (float4(1.0) - %s)", dstColorName); break; case SkBlendModeCoeff::kSA: fsBuilder->codeAppendf(" * %s.a", srcColorName); @@ -453,7 +453,7 @@ void GrGLSLBlend::AppendMode(GrGLSLFragmentBuilder* fsBuilder, const char* srcCo false); // append dst blend if(!append_porterduff_term(fsBuilder, dstCoeff, dstColor, srcColor, dstColor, didAppend)) { - fsBuilder->codeAppend("half4(0, 0, 0, 0)"); + fsBuilder->codeAppend("float4(0, 0, 0, 0)"); } if (clamp) { fsBuilder->codeAppend(", 0, 1);"); @@ -505,7 +505,7 @@ void GrGLSLBlend::AppendRegionOp(GrGLSLFragmentBuilder* fsBuilder, const char* s false); // append dst blend if(!append_porterduff_term(fsBuilder, dstCoeff, dstColor, srcColor, dstColor, didAppend)) { - fsBuilder->codeAppend("half4(0, 0, 0, 0)"); + fsBuilder->codeAppend("float4(0, 0, 0, 0)"); } fsBuilder->codeAppend(";"); } diff --git a/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h index f9ac30b6aa..b4605ba3ce 100644 --- a/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h +++ b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h @@ -24,8 +24,8 @@ public: uint32_t visibility = kFragment_GrShaderFlag) { SkASSERT(uniformHandler); if (colorSpaceXform) { - fGamutXformVar = uniformHandler->addUniform(visibility, kHalf4x4_GrSLType, - "ColorXform"); + fGamutXformVar = uniformHandler->addUniform(visibility, kMat44f_GrSLType, + kDefault_GrSLPrecision, "ColorXform"); fValid = true; } } diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp index ac2de139b0..6f75c16fe9 100644 --- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp +++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp @@ -29,7 +29,7 @@ void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor, SkASSERT(outputColor); GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; outputColor->append(fragBuilder->getMangleString()); - fragBuilder->codeAppendf("half4 %s;", outputColor->c_str()); + fragBuilder->codeAppendf("float4 %s;", outputColor->c_str()); this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args); } diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h index 68bd1f24c4..ed4b71ffa2 100644 --- a/src/gpu/glsl/GrGLSLFragmentProcessor.h +++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h @@ -86,9 +86,9 @@ public: @param fp The processor that generated this program stage. @param key The key that was computed by GenKey() from the generating GrProcessor. - @param outputColor A predefined half4 in the FS in which the stage should place its + @param outputColor A predefined float4 in the FS in which the stage should place its output color (or coverage). - @param inputColor A half4 that holds the input color to the stage in the FS. This may + @param inputColor A float4 that holds the input color to the stage in the FS. This may be nullptr in which case the implied input is solid white (all ones). TODO: Better system for communicating optimization info (e.g. input color is solid white, trans black, known to be opaque, @@ -152,7 +152,7 @@ public: } inline void emitChild(int childIndex, SkString* outputColor, EmitArgs& parentArgs) { - this->emitChild(childIndex, "half4(1.0)", outputColor, parentArgs); + this->emitChild(childIndex, "float4(1.0)", outputColor, parentArgs); } /** Will emit the code of a child proc in its own scope. Pass in the parent's EmitArgs and @@ -167,7 +167,7 @@ public: EmitArgs& parentArgs); inline void emitChild(int childIndex, EmitArgs& args) { - this->emitChild(childIndex, "half4(1.0)", args); + this->emitChild(childIndex, "float4(1.0)", args); } /** Variation that uses the parent's output color variable to hold the child's output.*/ diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp index 5dac06fee0..afbfa09a62 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp @@ -85,7 +85,8 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p , fCustomColorOutputIndex(-1) , fHasSecondaryOutput(false) , fUsedSampleOffsetArrays(0) - , fHasInitializedSampleMask(false) { + , fHasInitializedSampleMask(false) + , fDefaultPrecision(kMedium_GrSLPrecision) { fSubstageIndices.push_back(0); #ifdef SK_DEBUG fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures; @@ -111,14 +112,14 @@ bool GrGLSLFragmentShaderBuilder::enableFeature(GLSLFeature feature) { } SkString GrGLSLFragmentShaderBuilder::ensureCoords2D(const GrShaderVar& coords) { - if (kHighFloat3_GrSLType != coords.getType() && kHalf3_GrSLType != coords.getType()) { - SkASSERT(kHighFloat2_GrSLType == coords.getType() || kHalf2_GrSLType == coords.getType()); + if (kVec3f_GrSLType != coords.getType()) { + SkASSERT(kVec2f_GrSLType == coords.getType()); return coords.getName(); } SkString coords2D; coords2D.printf("%s_ensure2D", coords.c_str()); - this->codeAppendf("\thighfloat2 %s = %s.xy / %s.z;", coords2D.c_str(), coords.c_str(), + this->codeAppendf("\tfloat2 %s = %s.xy / %s.z;", coords2D.c_str(), coords.c_str(), coords.c_str()); return coords2D; } @@ -174,6 +175,10 @@ void GrGLSLFragmentShaderBuilder::overrideSampleCoverage(const char* mask) { fHasInitializedSampleMask = true; } +void GrGLSLFragmentShaderBuilder::elevateDefaultPrecision(GrSLPrecision precision) { + fDefaultPrecision = SkTMax(fDefaultPrecision, precision); +} + const char* GrGLSLFragmentShaderBuilder::dstColor() { SkDEBUGCODE(fHasReadDstColor = true;) @@ -194,7 +199,7 @@ const char* GrGLSLFragmentShaderBuilder::dstColor() { fOutputs[fCustomColorOutputIndex].setTypeModifier(GrShaderVar::kInOut_TypeModifier); fbFetchColorName = DeclaredColorOutputName(); // Set the dstColor to an intermediate variable so we don't override it with the output - this->codeAppendf("half4 %s = %s;", kDstColorName, fbFetchColorName); + this->codeAppendf("float4 %s = %s;", kDstColorName, fbFetchColorName); } else { return fbFetchColorName; } @@ -223,7 +228,7 @@ void GrGLSLFragmentShaderBuilder::enableCustomOutput() { if (!fHasCustomColorOutput) { fHasCustomColorOutput = true; fCustomColorOutputIndex = fOutputs.count(); - fOutputs.push_back().set(kHalf4_GrSLType, DeclaredColorOutputName(), + fOutputs.push_back().set(kVec4f_GrSLType, DeclaredColorOutputName(), GrShaderVar::kOut_TypeModifier); fProgramBuilder->finalizeFragmentOutputColor(fOutputs.back()); } @@ -242,7 +247,7 @@ void GrGLSLFragmentShaderBuilder::enableSecondaryOutput() { // output. The condition also co-incides with the condition in whici GLES SL 2.0 // requires the built-in gl_SecondaryFragColorEXT, where as 3.0 requires a custom output. if (caps.mustDeclareFragmentShaderOutput()) { - fOutputs.push_back().set(kHalf4_GrSLType, DeclaredSecondaryColorOutputName(), + fOutputs.push_back().set(kVec4f_GrSLType, DeclaredSecondaryColorOutputName(), GrShaderVar::kOut_TypeModifier); fProgramBuilder->finalizeFragmentSecondaryColor(fOutputs.back()); } @@ -275,6 +280,9 @@ GrSurfaceOrigin GrGLSLFragmentShaderBuilder::getSurfaceOrigin() const { void GrGLSLFragmentShaderBuilder::onFinalize() { fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outputs()); + GrGLSLAppendDefaultFloatPrecisionDeclaration(fDefaultPrecision, + *fProgramBuilder->shaderCaps(), + &this->precisionQualifier()); if (fUsedSampleOffsetArrays & (1 << kSkiaDevice_Coordinates)) { this->defineSampleOffsetArray(sample_offset_array_name(kSkiaDevice_Coordinates), SkMatrix::MakeTrans(-0.5f, -0.5f)); @@ -297,9 +305,9 @@ void GrGLSLFragmentShaderBuilder::defineSampleOffsetArray(const char* name, cons SkSTArray<16, SkPoint, true> offsets; offsets.push_back_n(specs.fEffectiveSampleCnt); m.mapPoints(offsets.begin(), specs.fSampleLocations, specs.fEffectiveSampleCnt); - this->definitions().appendf("const highfloat2 %s[] = highfloat2[](", name); + this->definitions().appendf("const highp float2 %s[] = float2[](", name); for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) { - this->definitions().appendf("highfloat2(%f, %f)", offsets[i].x(), offsets[i].y()); + this->definitions().appendf("float2(%f, %f)", offsets[i].x(), offsets[i].y()); this->definitions().append(i + 1 != specs.fEffectiveSampleCnt ? ", " : ");\n"); } } diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h index fa36f7b6d9..73fe51f171 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h @@ -40,7 +40,7 @@ public: /** * This returns a variable name to access the 2D, perspective correct version of the coords in - * the fragment shader. The passed in coordinates must either be of type kHalf2 or kHalf3. If + * the fragment shader. The passed in coordinates must either be of type kVec2f or kVec3f. If * the coordinates are 3-dimensional, it a perspective divide into is emitted into the * fragment shader (xy / z) to convert them to 2D. */ @@ -90,6 +90,13 @@ public: virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0; /** + * Overrides the default precision for the entire fragment program. Processors that require + * high precision input (eg from incoming texture samples) may use this. For calculations that + * are limited to a single processor's code, it is better to annotate individual declarations. + */ + virtual void elevateDefaultPrecision(GrSLPrecision) = 0; + + /** * Fragment procs with child procs should call these functions before/after calling emitCode * on a child proc. */ @@ -162,6 +169,7 @@ public: void appendOffsetToSample(const char* sampleIdx, Coordinates) override; void maskSampleCoverage(const char* mask, bool invert = false) override; void overrideSampleCoverage(const char* mask) override; + void elevateDefaultPrecision(GrSLPrecision) override; const SkString& getMangleString() const override { return fMangleString; } void onBeforeChildProcEmitCode() override; void onAfterChildProcEmitCode() override; @@ -226,6 +234,7 @@ private: bool fHasSecondaryOutput; uint8_t fUsedSampleOffsetArrays; bool fHasInitializedSampleMask; + GrSLPrecision fDefaultPrecision; #ifdef SK_DEBUG // some state to verify shaders and effects are consistent, this is reset between effects by diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp index 072d62c509..a390036fe2 100644 --- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp @@ -18,8 +18,7 @@ void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { GrGPArgs gpArgs; this->onEmitCode(args, &gpArgs); vBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar, args.fRTAdjustName); - if (kHighFloat2_GrSLType == gpArgs.fPositionVar.getType() || - kHalf2_GrSLType == gpArgs.fPositionVar.getType()) { + if (kVec2f_GrSLType == gpArgs.fPositionVar.getType()) { args.fVaryingHandler->setNoPerspective(); } } @@ -40,28 +39,32 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb, uint32_t type = coordTransform->getMatrix().getType(); type |= localMatrix.getType(); - varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kHighFloat3_GrSLType : - kHighFloat2_GrSLType; + varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType : + kVec2f_GrSLType; + // Coord transforms are always handled at high precision + const GrSLPrecision precision = kHigh_GrSLPrecision; + const char* uniName; fInstalledTransforms.push_back().fHandle = uniformHandler->addUniform(kVertex_GrShaderFlag, - kHighFloat3x3_GrSLType, + kMat33f_GrSLType, + precision, strUniName.c_str(), &uniName).toIndex(); SkString strVaryingName; strVaryingName.printf("TransformedCoords_%d", i); GrGLSLVertToFrag v(varyingType); - varyingHandler->addVarying(strVaryingName.c_str(), &v, kHigh_GrSLPrecision); + varyingHandler->addVarying(strVaryingName.c_str(), &v, precision); - SkASSERT(kHighFloat2_GrSLType == varyingType || kHighFloat3_GrSLType == varyingType); + SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType); - if (kHighFloat2_GrSLType == varyingType) { - vb->codeAppendf("%s = (%s * highfloat3(%s, 1)).xy;", v.vsOut(), uniName, localCoords); + if (kVec2f_GrSLType == varyingType) { + vb->codeAppendf("%s = (%s * float3(%s, 1)).xy;", v.vsOut(), uniName, localCoords); } else { - vb->codeAppendf("%s = %s * highfloat3(%s, 1);", v.vsOut(), uniName, localCoords); + vb->codeAppendf("%s = %s * float3(%s, 1);", v.vsOut(), uniName, localCoords); } ++i; } @@ -85,8 +88,8 @@ void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder, GrGPArgs* gpArgs, const char* posName) { - gpArgs->fPositionVar.set(kHighFloat2_GrSLType, "pos2"); - vertBuilder->codeAppendf("highfloat2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); + gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); + vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); } void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuilder, @@ -96,21 +99,21 @@ void GrGLSLGeometryProcessor::writeOutputPosition(GrGLSLVertexBuilder* vertBuild const SkMatrix& mat, UniformHandle* viewMatrixUniform) { if (mat.isIdentity()) { - gpArgs->fPositionVar.set(kHighFloat2_GrSLType, "pos2"); - vertBuilder->codeAppendf("highfloat2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); + gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); + vertBuilder->codeAppendf("float2 %s = %s;", gpArgs->fPositionVar.c_str(), posName); } else { const char* viewMatrixName; *viewMatrixUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, - kHighFloat3x3_GrSLType, + kMat33f_GrSLType, kHigh_GrSLPrecision, "uViewM", &viewMatrixName); if (!mat.hasPerspective()) { - gpArgs->fPositionVar.set(kHighFloat2_GrSLType, "pos2"); - vertBuilder->codeAppendf("highfloat2 %s = (%s * highfloat3(%s, 1)).xy;", + gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2"); + vertBuilder->codeAppendf("float2 %s = (%s * float3(%s, 1)).xy;", gpArgs->fPositionVar.c_str(), viewMatrixName, posName); } else { - gpArgs->fPositionVar.set(kHighFloat3_GrSLType, "pos3"); - vertBuilder->codeAppendf("highfloat3 %s = %s * highfloat3(%s, 1);", + gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3"); + vertBuilder->codeAppendf("float3 %s = %s * float3(%s, 1);", gpArgs->fPositionVar.c_str(), viewMatrixName, posName); } } diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp index 0cb7e4d541..d9d17e5356 100644 --- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp +++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp @@ -43,12 +43,13 @@ void GrGLSLPrimitiveProcessor::setupUniformColor(GrGLSLPPFragmentBuilder* fragBu SkASSERT(colorUniform); const char* stagedLocalVarName; *colorUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf4_GrSLType, + kVec4f_GrSLType, + kDefault_GrSLPrecision, "Color", &stagedLocalVarName); fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName); if (fragBuilder->getProgramBuilder()->shaderCaps()->mustObfuscateUniformColor()) { - fragBuilder->codeAppendf("%s = max(%s, half4(0, 0, 0, 0));", outputName, outputName); + fragBuilder->codeAppendf("%s = max(%s, float4(0, 0, 0, 0));", outputName, outputName); } } diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp index c4446ec1ad..bb3dc4f0a9 100644 --- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp +++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp @@ -82,7 +82,8 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr rtAdjustVisibility |= kGeometry_GrShaderFlag; } fUniformHandles.fRTAdjustmentUni = this->uniformHandler()->addUniform(rtAdjustVisibility, - kHalf4_GrSLType, + kVec4f_GrSLType, + kHigh_GrSLPrecision, "rtAdjustment"); const char* rtAdjustName = this->uniformHandler()->getUniformCStr(fUniformHandles.fRTAdjustmentUni); @@ -454,7 +455,7 @@ void GrGLSLProgramBuilder::nameExpression(SkString* output, const char* baseName } else { this->nameVariable(&outName, '\0', baseName); } - fFS.codeAppendf("half4 %s;", outName.c_str()); + fFS.codeAppendf("float4 %s;", outName.c_str()); *output = outName; } @@ -467,7 +468,7 @@ void GrGLSLProgramBuilder::addRTHeightUniform(const char* name) { GrGLSLUniformHandler* uniformHandler = this->uniformHandler(); fUniformHandles.fRTHeightUni = uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag, - kHalf_GrSLType, kDefault_GrSLPrecision, + kFloat_GrSLType, kDefault_GrSLPrecision, name, false, 0, nullptr); } diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp index ee99a068da..8f7d23dfe5 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp @@ -122,16 +122,16 @@ void GrGLSLShaderBuilder::appendColorGamutXform(SkString* out, // re-insert the original alpha. The supplied srcColor is likely to be of the form // "texture(...)", and we don't want to evaluate that twice, so wrap everything in a function. static const GrShaderVar gColorGamutXformArgs[] = { - GrShaderVar("color", kHalf4_GrSLType), - GrShaderVar("xform", kHalf4x4_GrSLType), + GrShaderVar("color", kVec4f_GrSLType), + GrShaderVar("xform", kMat44f_GrSLType), }; SkString functionBody; // Gamut xform, clamp to destination gamut. We only support/have premultiplied textures, so we // always just clamp to alpha. - functionBody.append("\tcolor.rgb = clamp((xform * half4(color.rgb, 1.0)).rgb, 0.0, color.a);\n"); + functionBody.append("\tcolor.rgb = clamp((xform * float4(color.rgb, 1.0)).rgb, 0.0, color.a);\n"); functionBody.append("\treturn color;"); SkString colorGamutXformFuncName; - this->emitFunction(kHalf4_GrSLType, + this->emitFunction(kVec4f_GrSLType, "colorGamutXform", SK_ARRAY_COUNT(gColorGamutXformArgs), gColorGamutXformArgs, diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h index 9ac6ab7626..4906c03b78 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLShaderBuilder.h @@ -37,23 +37,23 @@ public: void appendTextureLookup(SkString* out, SamplerHandle, const char* coordName, - GrSLType coordType = kHalf2_GrSLType) const; + GrSLType coordType = kVec2f_GrSLType) const; /** Version of above that appends the result to the shader code instead.*/ void appendTextureLookup(SamplerHandle, const char* coordName, - GrSLType coordType = kHalf2_GrSLType, + GrSLType coordType = kVec2f_GrSLType, GrGLSLColorSpaceXformHelper* colorXformHelper = nullptr); /** Does the work of appendTextureLookup and modulates the result by modulation. The result is - always a half4. modulation and the swizzle specified by SamplerHandle must both be - half4 or half. If modulation is "" or nullptr it this function acts as though + always a float4. modulation and the swizzle specified by SamplerHandle must both be + float4 or float. If modulation is "" or nullptr it this function acts as though appendTextureLookup were called. */ void appendTextureLookupAndModulate(const char* modulation, SamplerHandle, const char* coordName, - GrSLType coordType = kHalf2_GrSLType, + GrSLType coordType = kVec2f_GrSLType, GrGLSLColorSpaceXformHelper* colorXformHelper = nullptr); /** Adds a helper function to facilitate color gamut transformation, and produces code that diff --git a/src/gpu/glsl/GrGLSLUniformHandler.h b/src/gpu/glsl/GrGLSLUniformHandler.h index 84bbfa104c..cf80c3ff0a 100644 --- a/src/gpu/glsl/GrGLSLUniformHandler.h +++ b/src/gpu/glsl/GrGLSLUniformHandler.h @@ -38,13 +38,6 @@ public: return this->addUniformArray(visibility, type, precision, name, 0, outName); } - UniformHandle addUniform(uint32_t visibility, - GrSLType type, - const char* name, - const char** outName = nullptr) { - return this->addUniform(visibility, type, kDefault_GrSLPrecision, name, outName); - } - UniformHandle addUniformArray(uint32_t visibility, GrSLType type, GrSLPrecision precision, @@ -56,16 +49,6 @@ public: outName); } - UniformHandle addUniformArray(uint32_t visibility, - GrSLType type, - const char* name, - int arrayCount, - const char** outName = nullptr) { - SkASSERT(!GrSLTypeIsCombinedSamplerType(type)); - return this->internalAddUniformArray(visibility, type, kDefault_GrSLPrecision, name, true, - arrayCount, outName); - } - virtual const GrShaderVar& getUniformVariable(UniformHandle u) const = 0; /** diff --git a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp index 4e3b6446f8..e06ee2db6c 100644 --- a/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp @@ -18,25 +18,25 @@ void GrGLSLVertexBuilder::transformToNormalizedDeviceSpace(const GrShaderVar& po const char* rtAdjustName) { // setup RT Uniform if (this->getProgramBuilder()->desc()->header().fSnapVerticesToPixelCenters) { - if (kHighFloat3_GrSLType == posVar.getType()) { + if (kVec3f_GrSLType == posVar.getType()) { const char* p = posVar.c_str(); - this->codeAppendf("{highfloat2 _posTmp = highfloat2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p); + this->codeAppendf("{float2 _posTmp = float2(%s.x/%s.z, %s.y/%s.z);", p, p, p, p); } else { - SkASSERT(kHighFloat2_GrSLType == posVar.getType()); - this->codeAppendf("{highfloat2 _posTmp = %s;", posVar.c_str()); + SkASSERT(kVec2f_GrSLType == posVar.getType()); + this->codeAppendf("{float2 _posTmp = %s;", posVar.c_str()); } - this->codeAppendf("_posTmp = floor(_posTmp) + half2(0.5, 0.5);" - "gl_Position = highfloat4(_posTmp.x * %s.x + %s.y," + this->codeAppendf("_posTmp = floor(_posTmp) + float2(0.5, 0.5);" + "gl_Position = float4(_posTmp.x * %s.x + %s.y," "_posTmp.y * %s.z + %s.w, 0, 1);}", rtAdjustName, rtAdjustName, rtAdjustName, rtAdjustName); - } else if (kHighFloat3_GrSLType == posVar.getType()) { - this->codeAppendf("gl_Position = highfloat4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);", + } else if (kVec3f_GrSLType == posVar.getType()) { + this->codeAppendf("gl_Position = float4(dot(%s.xz, %s.xy), dot(%s.yz, %s.zw), 0, %s.z);", posVar.c_str(), rtAdjustName, posVar.c_str(), rtAdjustName, posVar.c_str()); } else { - SkASSERT(kHighFloat2_GrSLType == posVar.getType()); - this->codeAppendf("gl_Position = highfloat4(%s.x * %s.x + %s.y, %s.y * %s.z + %s.w, 0, 1);", + SkASSERT(kVec2f_GrSLType == posVar.getType()); + this->codeAppendf("gl_Position = float4(%s.x * %s.x + %s.y, %s.y * %s.z + %s.w, 0, 1);", posVar.c_str(), rtAdjustName, rtAdjustName, posVar.c_str(), rtAdjustName, rtAdjustName); } diff --git a/src/gpu/glsl/GrGLSLXferProcessor.cpp b/src/gpu/glsl/GrGLSLXferProcessor.cpp index 99862e2e23..6c2c460bec 100644 --- a/src/gpu/glsl/GrGLSLXferProcessor.cpp +++ b/src/gpu/glsl/GrGLSLXferProcessor.cpp @@ -52,7 +52,7 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { // The discard here also helps for batching text draws together which need to read from // a dst copy for blends. Though this only helps the case where the outer bounding boxes // of each letter overlap and not two actually parts of the text. - fragBuilder->codeAppendf("if (all(lessThanEqual(%s.rgb, half3(0)))) {" + fragBuilder->codeAppendf("if (all(lessThanEqual(%s.rgb, float3(0)))) {" " discard;" "}", args.fInputCoverage); } @@ -61,25 +61,27 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { const char* dstCoordScaleName; fDstTopLeftUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf2_GrSLType, + kVec2f_GrSLType, + kDefault_GrSLPrecision, "DstTextureUpperLeft", &dstTopLeftName); fDstScaleUni = uniformHandler->addUniform(kFragment_GrShaderFlag, - kHalf2_GrSLType, + kVec2f_GrSLType, + kDefault_GrSLPrecision, "DstTextureCoordScale", &dstCoordScaleName); fragBuilder->codeAppend("// Read color from copy of the destination.\n"); - fragBuilder->codeAppendf("half2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;", + fragBuilder->codeAppendf("float2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;", dstTopLeftName, dstCoordScaleName); if (flipY) { fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;"); } - fragBuilder->codeAppendf("half4 %s = ", dstColor); + fragBuilder->codeAppendf("float4 %s = ", dstColor); fragBuilder->appendTextureLookup(args.fDstTextureSamplerHandle, "_dstTexCoord", - kHalf2_GrSLType); + kVec2f_GrSLType); fragBuilder->codeAppend(";"); } else { needsLocalOutColor = args.fShaderCaps->requiresLocalOutputColorForFBFetch(); @@ -89,7 +91,7 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { if (!needsLocalOutColor) { outColor = args.fOutputPrimary; } else { - fragBuilder->codeAppendf("half4 %s;", outColor); + fragBuilder->codeAppendf("float4 %s;", outColor); } this->emitBlendCodeForDstRead(fragBuilder, @@ -137,18 +139,18 @@ void GrGLSLXferProcessor::DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fra fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage); fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCoverage); } else { - fragBuilder->codeAppendf("%s = half4(1.0);", outColorSecondary); + fragBuilder->codeAppendf("%s = float4(1.0);", outColorSecondary); } } else if (srcCoverage) { if (proc.isLCD()) { - fragBuilder->codeAppendf("half lerpRed = mix(%s.a, %s.a, %s.r);", + fragBuilder->codeAppendf("float lerpRed = mix(%s.a, %s.a, %s.r);", dstColor, outColor, srcCoverage); - fragBuilder->codeAppendf("half lerpBlue = mix(%s.a, %s.a, %s.g);", + fragBuilder->codeAppendf("float lerpBlue = mix(%s.a, %s.a, %s.g);", dstColor, outColor, srcCoverage); - fragBuilder->codeAppendf("half lerpGreen = mix(%s.a, %s.a, %s.b);", + fragBuilder->codeAppendf("float lerpGreen = mix(%s.a, %s.a, %s.b);", dstColor, outColor, srcCoverage); } - fragBuilder->codeAppendf("%s = %s * %s + (half4(1.0) - %s) * %s;", + fragBuilder->codeAppendf("%s = %s * %s + (float4(1.0) - %s) * %s;", outColor, srcCoverage, outColor, srcCoverage, dstColor); if (proc.isLCD()) { fragBuilder->codeAppendf("%s.a = max(max(lerpRed, lerpBlue), lerpGreen);", outColor); |