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();