Basic pipeline blend mode strength reductions:
- when the shader is opaque, srcover becomes src
- don't load dst when blitting in src mode with full coverage
- fold coverage into src alpha when in srcover mode
It's not obvious that we can fold coverage into src alpha when using a 565 mask, so I've not attempted that. What would we do about alpha?
Over all GMs this causes a single 1-bit difference in sRGB mode. No 565 or f16 diffs.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4349
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot
Change-Id: Ib9161f498c4efa6b348ca74522166da64d09a7da
Reviewed-on: https://skia-review.googlesource.com/4349
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index f680069..31c188e 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -103,14 +103,19 @@
bool shaderIsOpaque = (paintColor >> 24) == 0xff;
SkRasterPipeline shader, colorFilter;
- if (paint.getShader()) {
- shaderIsOpaque = paint.getShader()->isOpaque();
+ if (auto s = paint.getShader()) {
+ shaderIsOpaque = s->isOpaque();
}
- if ( paint.getColorFilter() &&
- !paint.getColorFilter()->appendStages(&colorFilter, shaderIsOpaque)) {
- return nullptr;
+ if (auto cf = paint.getColorFilter()) {
+ if (!cf->appendStages(&colorFilter, shaderIsOpaque)) {
+ return nullptr;
+ }
+ shaderIsOpaque = shaderIsOpaque && (cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
}
+ if (shaderIsOpaque && blend == SkBlendMode::kSrcOver) {
+ blend = SkBlendMode::kSrc;
+ }
SkColor4f color;
if (dst.info().colorSpace()) {
@@ -179,9 +184,11 @@
if (!fBlitH) {
SkRasterPipeline p;
p.extend(fShader);
- this->append_load_d(&p);
- this->append_blend(&p);
- this->maybe_clamp(&p);
+ if (fBlend != SkBlendMode::kSrc) {
+ this->append_load_d(&p);
+ this->append_blend(&p);
+ this->maybe_clamp(&p);
+ }
this->append_store(&p);
fBlitH = p.compile();
}
@@ -194,9 +201,15 @@
if (!fBlitAntiH) {
SkRasterPipeline p;
p.extend(fShader);
- this->append_load_d(&p);
- this->append_blend(&p);
- p.append(SkRasterPipeline::lerp_constant_float, &fConstantCoverage);
+ if (fBlend == SkBlendMode::kSrcOver) {
+ p.append(SkRasterPipeline::scale_constant_float, &fConstantCoverage);
+ this->append_load_d(&p);
+ this->append_blend(&p);
+ } else {
+ this->append_load_d(&p);
+ this->append_blend(&p);
+ p.append(SkRasterPipeline::lerp_constant_float, &fConstantCoverage);
+ }
this->maybe_clamp(&p);
this->append_store(&p);
fBlitAntiH = p.compile();
@@ -222,9 +235,15 @@
if (mask.fFormat == SkMask::kA8_Format && !fBlitMaskA8) {
SkRasterPipeline p;
p.extend(fShader);
- this->append_load_d(&p);
- this->append_blend(&p);
- p.append(SkRasterPipeline::lerp_u8, &fMaskPtr);
+ if (fBlend == SkBlendMode::kSrcOver) {
+ p.append(SkRasterPipeline::scale_u8, &fMaskPtr);
+ this->append_load_d(&p);
+ this->append_blend(&p);
+ } else {
+ this->append_load_d(&p);
+ this->append_blend(&p);
+ p.append(SkRasterPipeline::lerp_u8, &fMaskPtr);
+ }
this->maybe_clamp(&p);
this->append_store(&p);
fBlitMaskA8 = p.compile();