extend opacity tests in SkVM blits

- Have SkVMBlitter also check the color type for opacity,
  and commit to this opacity as a guarantee rather than optional
  optimization.
- Have SkImageShader do the same when sampling.

This will make it easier to work with opaque formats like 888x, 101010x,
and should mean sampling from opaque images is a bit cheaper, skipping
any work to unpack and convert alpha.

Change-Id: I0d20418f8335bd07c8b1a80b042636424854df18
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/270607
Auto-Submit: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/src/core/SkVMBlitter.cpp b/src/core/SkVMBlitter.cpp
index 4fefc69..38002f8 100644
--- a/src/core/SkVMBlitter.cpp
+++ b/src/core/SkVMBlitter.cpp
@@ -276,11 +276,11 @@
                                              break;
             }
 
-            // When a destination is tagged opaque, we may assume it both starts and stays fully
-            // opaque, ignoring any math that disagrees.  So anything involving force_opaque is
-            // optional, and sometimes helps cut a small amount of work in these programs.
-            const bool force_opaque = true && params.alphaType == kOpaque_SkAlphaType;
-            if (force_opaque) {
+            // When a destination is known opaque, we may assume it both starts and stays fully
+            // opaque, ignoring any math that disagrees.  This sometimes trims a little work.
+            const bool dst_is_opaque = SkAlphaTypeIsOpaque(params.alphaType)
+                                    || SkColorTypeIsAlwaysOpaque(params.colorType);
+            if (dst_is_opaque) {
                 dst.a = splat(1.0f);
             } else if (params.alphaType == kUnpremul_SkAlphaType) {
                 premul(&dst.r, &dst.g, &dst.b, dst.a);
@@ -311,7 +311,7 @@
                 src.b = clamp(src.b, splat(0.0f), splat(1.0f));
                 src.a = clamp(src.a, splat(0.0f), splat(1.0f));
             }
-            if (force_opaque) {
+            if (dst_is_opaque) {
                 src.a = splat(1.0f);
             } else if (params.alphaType == kUnpremul_SkAlphaType) {
                 unpremul(&src.r, &src.g, &src.b, src.a);
diff --git a/src/shaders/SkImageShader.cpp b/src/shaders/SkImageShader.cpp
index 9e6a3fc..6aa1d35 100755
--- a/src/shaders/SkImageShader.cpp
+++ b/src/shaders/SkImageShader.cpp
@@ -737,6 +737,10 @@
                                          std::swap(c.r, c.b);
                                          break;
         }
+        // TODO: move this later, as *a = p->splat(1.0f) after all sampling's done?
+        if (SkAlphaTypeIsOpaque(pm.alphaType()) || SkColorTypeIsAlwaysOpaque(pm.colorType())) {
+            c.a = p->splat(1.0f);
+        }
 
         // Mask away any pixels that we tried to sample outside the bounds in kDecal.
         if (fTileModeX == SkTileMode::kDecal || fTileModeY == SkTileMode::kDecal) {