Avoid multiplication by alpha in fragment shader when known to be 1.
Implemented for image shaders, image draws, and gradient shaders.
Reimplement GrFragmentProcessor::OverrideInput as GrOverrideInputFragmentProcessor.fp.
It allows specification of whether the replacement input color should be
a literal in the shader code or a uniform. For above use case use with literal white.
Make key in variables in fp files work for 4f colors.
Fix issue in CPP code gen from .fp where when + key vars that pushed multiple values
into the shader key only skipped the first key value when the when condition is not
true.
Bug: skia:7722
Change-Id: Id7c865132d620e8cdea8b00f2a627103eef171ac
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201985
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 5fc363b..ac195bb 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -355,12 +355,13 @@
// Convert SkPaint color to 4f format in the destination color space
SkColor4f origColor = SkColor4fPrepForDst(skPaint.getColor4f(), colorSpaceInfo);
- const GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
+ GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
// Setup the initial color considering the shader, the SkPaint color, and the presence or not
// of per-vertex colors.
std::unique_ptr<GrFragmentProcessor> shaderFP;
if (!primColorMode || blend_requires_shader(*primColorMode)) {
+ fpArgs.fInputColorIsOpaque = origColor.isOpaque();
if (shaderProcessor) {
shaderFP = std::move(*shaderProcessor);
} else if (const auto* shader = as_SB(skPaint.getShader())) {
@@ -457,6 +458,8 @@
SkMaskFilterBase* maskFilter = as_MFB(skPaint.getMaskFilter());
if (maskFilter) {
+ // We may have set this before passing to the SkShader.
+ fpArgs.fInputColorIsOpaque = false;
if (auto mfFP = maskFilter->asFragmentProcessor(fpArgs)) {
grPaint->addCoverageFragmentProcessor(std::move(mfFP));
}
@@ -551,7 +554,11 @@
shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(std::move(fp));
}
} else {
- shaderFP = GrFragmentProcessor::MulChildByInputAlpha(std::move(fp));
+ if (paint.getColor4f().isOpaque()) {
+ shaderFP = GrFragmentProcessor::OverrideInput(std::move(fp), SK_PMColor4fWHITE, false);
+ } else {
+ shaderFP = GrFragmentProcessor::MulChildByInputAlpha(std::move(fp));
+ }
}
return SkPaintToGrPaintReplaceShader(context, colorSpaceInfo, paint, std::move(shaderFP),