Do not use SkImageFilter for Stretch

Refactor stretch implementation to manually
draw the shader as a rect instead of using
SkImageFilter

Bug: 184184033
Test: Re-ran stretch tests
Change-Id: I6263f5474b185b3f81ef9fd1bec3e43e86da49f2
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
index d7162b9..de14beb 100644
--- a/libs/hwui/effects/StretchEffect.cpp
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -171,13 +171,13 @@
 static const float ZERO = 0.f;
 static const float CONTENT_DISTANCE_STRETCHED = 1.f;
 
-sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapshotImage) const {
+sk_sp<SkShader> StretchEffect::getShader(const sk_sp<SkImage>& snapshotImage) const {
     if (isEmpty()) {
         return nullptr;
     }
 
-    if (mStretchFilter != nullptr) {
-        return mStretchFilter;
+    if (mStretchShader != nullptr) {
+        return mStretchShader;
     }
 
     float viewportWidth = stretchArea.width();
@@ -212,10 +212,9 @@
     mBuilder->uniform("viewportWidth").set(&viewportWidth, 1);
     mBuilder->uniform("viewportHeight").set(&viewportHeight, 1);
 
-    mStretchFilter = SkImageFilters::Shader(mBuilder->makeShader(nullptr, false),
-                                            SkRect{0, 0, viewportWidth, viewportHeight});
+    mStretchShader = mBuilder->makeShader(nullptr, false);
 
-    return mStretchFilter;
+    return mStretchShader;
 }
 
 sk_sp<SkRuntimeEffect> StretchEffect::getStretchEffect() {
diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h
index 8221b41..546d53b 100644
--- a/libs/hwui/effects/StretchEffect.h
+++ b/libs/hwui/effects/StretchEffect.h
@@ -53,7 +53,7 @@
     StretchEffect& operator=(const StretchEffect& other) {
         this->stretchArea = other.stretchArea;
         this->mStretchDirection = other.mStretchDirection;
-        this->mStretchFilter = nullptr;
+        this->mStretchShader = other.mStretchShader;
         this->maxStretchAmountX = other.maxStretchAmountX;
         this->maxStretchAmountY = other.maxStretchAmountY;
         return *this;
@@ -76,14 +76,14 @@
         maxStretchAmountY = std::max(maxStretchAmountY, other.maxStretchAmountY);
     }
 
-    sk_sp<SkImageFilter> getImageFilter(const sk_sp<SkImage>& snapshotImage) const;
+    sk_sp<SkShader> getShader(const sk_sp<SkImage>& snapshotImage) const;
 
     SkRect stretchArea {0, 0, 0, 0};
     float maxStretchAmountX = 0;
     float maxStretchAmountY = 0;
 
     void setStretchDirection(const SkVector& direction) {
-        mStretchFilter = nullptr;
+        mStretchShader = nullptr;
         mStretchDirection = direction;
     }
 
@@ -93,7 +93,7 @@
     static sk_sp<SkRuntimeEffect> getStretchEffect();
     mutable SkVector mStretchDirection{0, 0};
     mutable std::unique_ptr<SkRuntimeShaderBuilder> mBuilder;
-    mutable sk_sp<SkImageFilter> mStretchFilter;
+    mutable sk_sp<SkShader> mStretchShader;
 };
 
 } // namespace android::uirenderer
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 5627a7e..77d99a6 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -180,20 +180,7 @@
         paint->setColorFilter(sk_ref_sp(properties.getColorFilter()));
 
         sk_sp<SkImageFilter> imageFilter = sk_ref_sp(properties.getImageFilter());
-        sk_sp<SkImageFilter> stretchFilter =
-                properties.getStretchEffect().getImageFilter(snapshotImage);
-        sk_sp<SkImageFilter> filter;
-        if (imageFilter && stretchFilter) {
-            filter = SkImageFilters::Compose(
-                  std::move(stretchFilter),
-                  std::move(imageFilter)
-            );
-        } else if (stretchFilter) {
-            filter = std::move(stretchFilter);
-        } else {
-            filter = std::move(imageFilter);
-        }
-        paint->setImageFilter(std::move(filter));
+        paint->setImageFilter(std::move(imageFilter));
         return true;
     }
     return false;
@@ -262,8 +249,16 @@
                 TransformCanvas transformCanvas(canvas);
                 displayList->draw(&transformCanvas);
             }
-            canvas->drawImageRect(snapshotImage, bounds, bounds, sampling, &paint,
-                                  SkCanvas::kStrict_SrcRectConstraint);
+
+            const StretchEffect& stretch = properties.layerProperties().getStretchEffect();
+            if (stretch.isEmpty()) {
+                canvas->drawImageRect(snapshotImage, bounds, bounds, sampling, &paint,
+                                      SkCanvas::kStrict_SrcRectConstraint);
+            } else {
+                sk_sp<SkShader> stretchShader = stretch.getShader(snapshotImage);
+                paint.setShader(stretchShader);
+                canvas->drawRect(bounds, paint);
+            }
 
             if (!renderNode->getSkiaLayer()->hasRenderedSinceRepaint) {
                 renderNode->getSkiaLayer()->hasRenderedSinceRepaint = true;