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

Commit 25d6e331 authored by John Reck's avatar John Reck
Browse files

Simplify BackdropFilterDrawable

Remove a bunch of state that didn't need to be state
Only makeImageSnapshot of the bounds we need to sample

Bug: 353827335
Test: SilkFX view blur behind demo
Flag: EXEMPT bugfix

Change-Id: I37d39d40eb48f2817dde286bcdf65d636bf28d2f
parent bdadc6d2
Loading
Loading
Loading
Loading
+21 −44
Original line number Diff line number Diff line
@@ -29,37 +29,6 @@ namespace android {
namespace uirenderer {
namespace skiapipeline {

BackdropFilterDrawable::~BackdropFilterDrawable() {}

bool BackdropFilterDrawable::prepareToDraw(SkCanvas* canvas, const RenderProperties& properties,
                                           int backdropImageWidth, int backdropImageHeight) {
    // the drawing bounds for blurred content.
    mDstBounds.setWH(properties.getWidth(), properties.getHeight());

    float alphaMultiplier = 1.0f;
    RenderNodeDrawable::setViewProperties(properties, canvas, &alphaMultiplier, true);

    // get proper subset for previous content.
    canvas->getTotalMatrix().mapRect(&mImageSubset, mDstBounds);
    SkRect imageSubset(mImageSubset);
    // ensure the subset is inside bounds of previous content.
    if (!mImageSubset.intersect(SkRect::MakeWH(backdropImageWidth, backdropImageHeight))) {
        return false;
    }

    // correct the drawing bounds if subset was changed.
    if (mImageSubset != imageSubset) {
        SkMatrix inverse;
        if (canvas->getTotalMatrix().invert(&inverse)) {
            inverse.mapRect(&mDstBounds, mImageSubset);
        }
    }

    // follow the alpha from the target RenderNode.
    mPaint.setAlpha(properties.layerProperties().alpha() * alphaMultiplier);
    return true;
}

void BackdropFilterDrawable::onDraw(SkCanvas* canvas) {
    const RenderProperties& properties = mTargetRenderNode->properties();
    auto* backdropFilter = properties.layerProperties().getBackdropImageFilter();
@@ -68,33 +37,41 @@ void BackdropFilterDrawable::onDraw(SkCanvas* canvas) {
        return;
    }

    auto backdropImage = surface->makeImageSnapshot();
    // sync necessary properties from target RenderNode.
    if (!prepareToDraw(canvas, properties, backdropImage->width(), backdropImage->height())) {
    SkRect srcBounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());

    float alphaMultiplier = 1.0f;
    RenderNodeDrawable::setViewProperties(properties, canvas, &alphaMultiplier, true);
    SkPaint paint;
    paint.setAlpha(properties.layerProperties().alpha() * alphaMultiplier);

    SkRect surfaceSubset;
    canvas->getTotalMatrix().mapRect(&surfaceSubset, srcBounds);
    if (!surfaceSubset.intersect(SkRect::MakeWH(surface->width(), surface->height()))) {
        return;
    }

    auto imageSubset = mImageSubset.roundOut();
    auto backdropImage = surface->makeImageSnapshot(surfaceSubset.roundOut());

    SkIRect imageBounds = SkIRect::MakeWH(backdropImage->width(), backdropImage->height());
    SkIPoint offset;
    SkIRect imageSubset;

#ifdef __ANDROID__
    if (canvas->recordingContext()) {
        backdropImage =
                SkImages::MakeWithFilter(canvas->recordingContext(), backdropImage, backdropFilter,
                                         imageSubset, imageSubset, &mOutSubset, &mOutOffset);
                                         imageBounds, imageBounds, &imageSubset, &offset);
    } else
#endif
    {
        backdropImage = SkImages::MakeWithFilter(backdropImage, backdropFilter, imageSubset,
                                                 imageSubset, &mOutSubset, &mOutOffset);
        backdropImage = SkImages::MakeWithFilter(backdropImage, backdropFilter, imageBounds,
                                                 imageBounds, &imageSubset, &offset);
    }

    // backdropImage & mOutSubset are in post-pre-rotation space, whereas mDstBounds is in
    // prerotation space. So map dst bounds to post-pre-rotation space & draw there
    SkRect dst;
    canvas->getTotalMatrix().mapRect(&dst, mDstBounds);
    canvas->save();
    canvas->resetMatrix();
    canvas->drawImageRect(backdropImage, SkRect::Make(mOutSubset), dst,
                          SkSamplingOptions(SkFilterMode::kLinear), &mPaint,
    canvas->drawImageRect(backdropImage, SkRect::Make(imageSubset), surfaceSubset,
                          SkSamplingOptions(SkFilterMode::kLinear), &paint,
                          SkCanvas::kFast_SrcRectConstraint);
    canvas->restore();
}
+1 −14
Original line number Diff line number Diff line
@@ -37,23 +37,10 @@ public:
    BackdropFilterDrawable(RenderNode* renderNode, SkCanvas* canvas)
            : mTargetRenderNode(renderNode), mBounds(canvas->getLocalClipBounds()) {}

    ~BackdropFilterDrawable();
    ~BackdropFilterDrawable() = default;

private:
    RenderNode* mTargetRenderNode;
    SkPaint mPaint;

    SkRect mDstBounds;
    SkRect mImageSubset;
    SkIRect mOutSubset;
    SkIPoint mOutOffset;

    /**
     * Check all necessary properties before actual drawing.
     * Return true if ready to draw.
     */
    bool prepareToDraw(SkCanvas* canvas, const RenderProperties& properties, int backdropImageWidth,
                       int backdropImageHeight);

protected:
    void onDraw(SkCanvas* canvas) override;