Restore batching of (varying) paint alpha to shader FP trees
The previous version forced unique draws as the alpha changed (because paint color was converted to a uniform). This version just uses a simple wrapper FP that invokes the shader FP with the opaque paint color, then multiplies the paint alpha against the result. Bug: skia:11942 Bug: chromium:1265678 Bug: chromium:1265736 Cq-Include-Trybots: luci.skia.skia.primary:Canary-Chromium Change-Id: I21fab1f1b0746e410509ddb4cbce5acdd21c89db Reviewed-on: https://skia-review.googlesource.com/c/skia/+/467077 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
390edeb88d
commit
02b8a09274
@ -220,6 +220,20 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha(
|
||||
SkBlendMode::kSrcIn);
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ApplyPaintAlpha(
|
||||
std::unique_ptr<GrFragmentProcessor> child) {
|
||||
SkASSERT(child);
|
||||
static auto effect = SkMakeRuntimeEffect(SkRuntimeEffect::MakeForColorFilter, R"(
|
||||
uniform colorFilter fp;
|
||||
half4 main(half4 inColor) {
|
||||
return fp.eval(inColor.rgb1) * inColor.a;
|
||||
}
|
||||
)");
|
||||
return GrSkSLFP::Make(effect, "ApplyPaintAlpha", /*inputFP=*/nullptr,
|
||||
GrSkSLFP::OptFlags::kPreservesOpaqueInput,
|
||||
"fp", std::move(child));
|
||||
}
|
||||
|
||||
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ModulateAlpha(
|
||||
std::unique_ptr<GrFragmentProcessor> inputFP, const SkPMColor4f& color) {
|
||||
auto colorFP = MakeColor(color);
|
||||
|
@ -71,6 +71,13 @@ public:
|
||||
static std::unique_ptr<GrFragmentProcessor> MulInputByChildAlpha(
|
||||
std::unique_ptr<GrFragmentProcessor> child);
|
||||
|
||||
/**
|
||||
* Invokes child with an opaque version of the input color, then applies the input alpha to
|
||||
* the result. Used to incorporate paint alpha to the evaluation of an SkShader tree FP.
|
||||
*/
|
||||
static std::unique_ptr<GrFragmentProcessor> ApplyPaintAlpha(
|
||||
std::unique_ptr<GrFragmentProcessor> child);
|
||||
|
||||
/**
|
||||
* Returns a fragment processor that generates the passed-in color, modulated by the child's
|
||||
* alpha channel. The child's input color will be the parent's fInputColor. (Pass a null FP to
|
||||
|
@ -473,19 +473,10 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
||||
#else
|
||||
float paintAlpha = skPaint.getColor4f().fA;
|
||||
if (paintAlpha != 1.0f) {
|
||||
// TODO (skbug.com/11942): Can we instead make a single FP that does:
|
||||
// uniform colorFilter fp;
|
||||
// half4 main(half4 inColor) {
|
||||
// return fp.eval(inColor.rgb1) * inColor.a;
|
||||
// }
|
||||
// That's slightly different - we're relying on the input color being the paint
|
||||
// color, but it would avoid the uniform (so might restore batching)?
|
||||
SkPMColor4f shaderInput = origColor.makeOpaque().premul();
|
||||
paintFP = GrFragmentProcessor::OverrideInput(std::move(paintFP), shaderInput);
|
||||
|
||||
paintFP = GrFragmentProcessor::ModulateRGBA(
|
||||
std::move(paintFP), {paintAlpha, paintAlpha, paintAlpha, paintAlpha});
|
||||
grPaint->setColor4f(shaderInput);
|
||||
// This invokes the shader's FP tree with an opaque version of the paint color,
|
||||
// then multiplies the final result by the incoming (paint) alpha.
|
||||
paintFP = GrFragmentProcessor::ApplyPaintAlpha(std::move(paintFP));
|
||||
grPaint->setColor4f({origColor.fR, origColor.fG, origColor.fB, origColor.fA});
|
||||
} else {
|
||||
grPaint->setColor4f(origColor.premul());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user