Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8f5d66b7 authored by Nader Jawad's avatar Nader Jawad
Browse files

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
parent 41a5cb89
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -171,13 +171,13 @@ static const SkString stretchShader = SkString(R"(
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 @@ sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapsho
    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() {
+4 −4
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ public:
    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 @@ public:
        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 @@ private:
    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
+11 −16
Original line number Diff line number Diff line
@@ -180,20 +180,7 @@ static bool layerNeedsPaint(const sk_sp<SkImage>& snapshotImage, const LayerProp
        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 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const {
                TransformCanvas transformCanvas(canvas);
                displayList->draw(&transformCanvas);
            }

            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;