Roll Skia from 49e32eb178a7 to 3a3475d12f22 (2 revisions)

https://skia.googlesource.com/skia.git/+log/49e32eb178a7..3a3475d12f22

2023-12-12 kjlubick@google.com Fix defines for G3 android build
2023-12-12 michaelludwig@google.com [skif] Add non-strict asShader() to SkSpecialImage

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://skia-autoroll.corp.goog/r/android-master-autoroll
Please CC djsollen@google.com,rmistry@google.com,scroggo@google.com on the revert to ensure that a human
is aware of the problem.

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md

Test: Presubmit checks will test this change.
Exempt-From-Owner-Approval: The autoroll bot does not require owner approval.
Bug: b/305780908
Bug: b/315351386
Bug: b/186777432
Change-Id: Ifadf20f591483d5b6314a2124e8ef9b039b2ce2e
diff --git a/METADATA b/METADATA
index 2b4d876..6880cce 100644
--- a/METADATA
+++ b/METADATA
@@ -9,7 +9,7 @@
     type: GIT
     value: "https://skia.googlesource.com/skia"
   }
-  version: "49e32eb178a7b6ed5c598182329bf4f21e51157d"
+  version: "3a3475d12f220b795821eabae517ab7cb6f12c9f"
   license_type: RECIPROCAL
   last_upgrade_date {
     year: 2023
diff --git a/public.bzl b/public.bzl
index 8c44cb4..05d501b 100644
--- a/public.bzl
+++ b/public.bzl
@@ -2250,17 +2250,25 @@
     "SK_FONTMGR_FREETYPE_EMPTY_AVAILABLE",
     "SK_FONTMGR_FONTCONFIG_AVAILABLE",
 ]
-ANDROID_DEFINES = [
+ANDROID_BASE_DEFINES = [
     "SK_BUILD_FOR_ANDROID",
-    "SK_CODEC_DECODES_PNG",
-    "SK_CODEC_DECODES_WEBP",
     "SK_GL",
-    "SK_CODEC_DECODES_JPEG",
+]
+ANDROID_FONT_DEFINES = [
     "SK_FONTMGR_ANDROID_AVAILABLE",
     "SK_FONTMGR_FREETYPE_DIRECTORY_AVAILABLE",
     "SK_FONTMGR_FREETYPE_EMPTY_AVAILABLE",
     "SK_FONTMGR_FONTCONFIG_AVAILABLE",
 ]
+ANDROID_CODEC_DEFINES = [
+    "SK_CODEC_DECODES_PNG",
+    "SK_CODEC_DECODES_WEBP",
+    "SK_CODEC_DECODES_JPEG",
+]
+
+# TODO(kjlubick) Delete these once we use the more granular versions
+ANDROID_DEFINES = ANDROID_BASE_DEFINES + ANDROID_FONT_DEFINES + ANDROID_CODEC_DEFINES
+ANDROID_NO_CODECS_DEFINES = ANDROID_BASE_DEFINES
 IOS_DEFINES = [
     "SK_BUILD_FOR_IOS",
     "SK_CODEC_DECODES_JPEG",
@@ -2292,10 +2300,6 @@
     "SK_CODEC_DECODES_JPEG",
     "SK_FONTMGR_CORETEXT_AVAILABLE",
 ]
-ANDROID_NO_CODECS_DEFINES = [
-    "SK_BUILD_FOR_ANDROID",
-    "SK_GL",
-]
 
 ################################################################################
 ## sksg_lib
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index bedb563..1a61e27 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -12,11 +12,13 @@
 #include "include/core/SkColorType.h"
 #include "include/core/SkImage.h"
 #include "include/core/SkMatrix.h"
+#include "include/core/SkPoint.h"
 #include "include/core/SkShader.h"
 #include "include/core/SkTileMode.h"
 #include "include/private/base/SkAssert.h"
 #include "src/core/SkNextID.h"
 #include "src/image/SkImage_Base.h"
+#include "src/shaders/SkImageShader.h"
 
 // Currently, the raster imagefilters can only handle certain imageinfos. Call this to know if
 // a given info is supported.
@@ -49,16 +51,40 @@
 sk_sp<SkShader> SkSpecialImage::asShader(SkTileMode tileMode,
                                          const SkSamplingOptions& sampling,
                                          const SkMatrix& lm) const {
-    return this->onAsShader(tileMode, sampling, lm);
+    return this->onAsShader(tileMode, sampling, lm, /*strict=*/true);
 }
 
-sk_sp<SkShader> SkSpecialImage::asShader(const SkSamplingOptions& sampling) const {
-    return this->asShader(sampling, SkMatrix::I());
+sk_sp<SkShader> SkSpecialImage::asShaderFast(const SkSamplingOptions& sampling,
+                                             const SkMatrix& lm) const {
+    // Since this should only be used when safely sampling within the subset, the tile mode is
+    // irrelevant, but kClamp is a good default.
+    return this->onAsShader(SkTileMode::kClamp, sampling, lm, /*strict=*/false);
 }
 
-sk_sp<SkShader> SkSpecialImage::asShader(const SkSamplingOptions& sampling,
-                                         const SkMatrix& lm) const {
-    return this->asShader(SkTileMode::kClamp, sampling, lm);
+// TODO(skbug.com/12784): Once bitmap images work with SkImageShader::MakeSubset(), this does not
+// need to be virtual anymore.
+sk_sp<SkShader> SkSpecialImage::onAsShader(SkTileMode tileMode,
+                                           const SkSamplingOptions& sampling,
+                                           const SkMatrix& lm,
+                                           bool strict) const {
+    // The special image's logical (0,0) is at its subset's topLeft() so we need to account for
+    // that in the local matrix used when sampling.
+    SkMatrix subsetOrigin = SkMatrix::Translate(-this->subset().topLeft());
+    subsetOrigin.postConcat(lm);
+
+    if (strict) {
+        // However, we don't need to modify the subset itself since that is defined with respect
+        // to the base image, and the local matrix is applied before any tiling/clamping.
+        const SkRect subset = SkRect::Make(this->subset());
+
+        // asImage() w/o a subset makes no copy; create the SkImageShader directly to remember
+        // the subset used to access the image.
+        return SkImageShader::MakeSubset(
+                this->asImage(), subset, tileMode, tileMode, sampling, &subsetOrigin);
+    } else {
+        // Ignore 'subset' other than its origin translation applied to the local matrix.
+        return this->asImage()->makeShader(tileMode, tileMode, sampling, subsetOrigin);
+    }
 }
 
 class SkSpecialImage_Raster final : public SkSpecialImage {
@@ -85,14 +111,24 @@
 
     sk_sp<SkShader> onAsShader(SkTileMode tileMode,
                                const SkSamplingOptions& sampling,
-                               const SkMatrix& lm) const override {
-        // TODO(skbug.com/12784): SkImage::makeShader() doesn't support a subset yet, but SkBitmap
-        // supports subset views so create the shader from the subset bitmap instead of fBitmap.
-        SkBitmap subsetBM;
-        if (!this->getROPixels(&subsetBM)) {
-            return nullptr;
+                               const SkMatrix& lm,
+                               bool strict) const override {
+        if (strict) {
+            // TODO(skbug.com/12784): SkImage::makeShader() doesn't support a subset yet, but
+            // SkBitmap supports subset views so create the shader from the subset bitmap instead of
+            // fBitmap.
+            SkBitmap subsetBM;
+            if (!this->getROPixels(&subsetBM)) {
+                return nullptr;
+            }
+            return subsetBM.makeShader(tileMode, tileMode, sampling, lm);
+        } else {
+            // The special image's logical (0,0) is at its subset's topLeft() so we need to
+            // account for that in the local matrix used when sampling.
+            SkMatrix subsetOrigin = SkMatrix::Translate(-this->subset().topLeft());
+            subsetOrigin.postConcat(lm);
+            return fBitmap.makeShader(tileMode, tileMode, sampling, subsetOrigin);
         }
-        return subsetBM.asImage()->makeShader(tileMode, tileMode, sampling, lm);
     }
 
 private:
diff --git a/src/core/SkSpecialImage.h b/src/core/SkSpecialImage.h
index 89c82bb..6a08f74 100644
--- a/src/core/SkSpecialImage.h
+++ b/src/core/SkSpecialImage.h
@@ -104,8 +104,12 @@
      * any sample that falls outside its internal subset.
      */
     sk_sp<SkShader> asShader(SkTileMode, const SkSamplingOptions&, const SkMatrix& lm) const;
-    sk_sp<SkShader> asShader(const SkSamplingOptions& sampling) const;
-    sk_sp<SkShader> asShader(const SkSamplingOptions& sampling, const SkMatrix& lm) const;
+    /**
+     * Create an SkShader that samples the contents of this special image, assuming that the
+     * coords it's evaluated at will not access pixels beyond its subset
+     * (i.e., non-strict sampling).
+     */
+    sk_sp<SkShader> asShaderFast(const SkSamplingOptions& sampling, const SkMatrix& lm) const;
 
     /**
      *  If the SpecialImage is backed by a gpu texture, return true.
@@ -128,9 +132,11 @@
     // from the content rect by the non-virtual makeSubset().
     virtual sk_sp<SkSpecialImage> onMakeSubset(const SkIRect& subset) const = 0;
 
+    // The default implementation calls `asImage()` or `SkImageShader::MakeSubset` based on `strict`
     virtual sk_sp<SkShader> onAsShader(SkTileMode,
                                        const SkSamplingOptions&,
-                                       const SkMatrix&) const = 0;
+                                       const SkMatrix&,
+                                       bool strict) const;
 
 private:
     const SkIRect        fSubset;
diff --git a/src/gpu/ganesh/image/SkSpecialImage_Ganesh.cpp b/src/gpu/ganesh/image/SkSpecialImage_Ganesh.cpp
index 2b61fe2..bc7babe 100644
--- a/src/gpu/ganesh/image/SkSpecialImage_Ganesh.cpp
+++ b/src/gpu/ganesh/image/SkSpecialImage_Ganesh.cpp
@@ -10,12 +10,10 @@
 #include "include/core/SkColorSpace.h"  // IWYU pragma: keep
 #include "include/core/SkImage.h"
 #include "include/core/SkImageInfo.h"
-#include "include/core/SkMatrix.h"
 #include "include/core/SkRect.h"
 #include "include/gpu/GpuTypes.h"
 #include "include/gpu/GrRecordingContext.h"
 #include "include/private/base/SkAssert.h"
-#include "include/private/base/SkPoint_impl.h"
 #include "include/private/gpu/ganesh/GrTypesPriv.h"
 #include "src/core/SkSpecialImage.h"
 #include "src/gpu/ganesh/GrSurfaceProxy.h"
@@ -23,15 +21,11 @@
 #include "src/gpu/ganesh/GrSurfaceProxyView.h"
 #include "src/gpu/ganesh/image/GrImageUtils.h"
 #include "src/gpu/ganesh/image/SkImage_Ganesh.h"
-#include "src/shaders/SkImageShader.h"
 
 #include <cstddef>
 #include <utility>
 
-class SkShader;
-struct SkSamplingOptions;
 enum SkColorType : int;
-enum class SkTileMode;
 
 class SkSpecialImage_Gpu final : public SkSpecialImage {
 public:
@@ -64,23 +58,6 @@
                 sk_ref_sp(fContext), this->uniqueID(), fView, this->colorInfo());
     }
 
-    sk_sp<SkShader> onAsShader(SkTileMode tileMode,
-                               const SkSamplingOptions& sampling,
-                               const SkMatrix& lm) const override {
-        // The special image's logical (0,0) is at its subset's topLeft() so we need to account for
-        // that in the local matrix used when sampling.
-        SkMatrix subsetOrigin = SkMatrix::Translate(-this->subset().topLeft());
-        subsetOrigin.postConcat(lm);
-        // However, we don't need to modify the subset itself since that is defined with respect to
-        // the base image, and the local matrix is applied before any tiling/clamping.
-        const SkRect subset = SkRect::Make(this->subset());
-
-        // asImage() w/o a subset makes no copy; create the SkImageShader directly to remember the
-        // subset used to access the image.
-        return SkImageShader::MakeSubset(
-                this->asImage(), subset, tileMode, tileMode, sampling, &subsetOrigin);
-    }
-
 private:
     GrRecordingContext* fContext;
     GrSurfaceProxyView fView;
diff --git a/src/gpu/graphite/SpecialImage_Graphite.cpp b/src/gpu/graphite/SpecialImage_Graphite.cpp
index c44438e..fe1c48b 100644
--- a/src/gpu/graphite/SpecialImage_Graphite.cpp
+++ b/src/gpu/graphite/SpecialImage_Graphite.cpp
@@ -14,7 +14,6 @@
 #include "src/gpu/graphite/Image_Graphite.h"
 #include "src/gpu/graphite/Surface_Graphite.h"
 #include "src/gpu/graphite/TextureUtils.h"
-#include "src/shaders/SkImageShader.h"
 
 namespace skgpu::graphite {
 
@@ -50,23 +49,6 @@
         return sk_make_sp<Image>(this->uniqueID(), fTextureProxyView, this->colorInfo());
     }
 
-    sk_sp<SkShader> onAsShader(SkTileMode tileMode,
-                               const SkSamplingOptions& sampling,
-                               const SkMatrix& lm) const override {
-        // The special image's logical (0,0) is at its subset's topLeft() so we need to account for
-        // that in the local matrix used when sampling.
-        SkMatrix subsetOrigin = SkMatrix::Translate(-this->subset().topLeft());
-        subsetOrigin.postConcat(lm);
-        // However, we don't need to modify the subset itself since that is defined with respect to
-        // the base image, and the local matrix is applied before any tiling/clamping.
-        const SkRect subset = SkRect::Make(this->subset());
-
-        // asImage() w/o a subset makes no copy; create the SkImageShader directly to remember the
-        // subset used to access the image.
-        return SkImageShader::MakeSubset(this->asImage(), subset, tileMode, tileMode,
-                                         sampling, &subsetOrigin);
-    }
-
 private:
     TextureProxyView fTextureProxyView;
 };