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

Commit 6c13c195 authored by Galia Peycheva's avatar Galia Peycheva Committed by Android (Google) Code Review
Browse files

Merge "Clip blur to bounds of layer"

parents 5ff58290 6c460658
Loading
Loading
Loading
Loading
+22 −11
Original line number Diff line number Diff line
@@ -512,7 +512,8 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
    // displays might have different scaling when compared to the physical screen.

    canvas->clipRect(getSkRect(display.physicalDisplay));
    canvas->translate(display.physicalDisplay.left, display.physicalDisplay.top);
    SkMatrix screenTransform;
    screenTransform.setTranslate(display.physicalDisplay.left, display.physicalDisplay.top);

    const auto clipWidth = display.clip.width();
    const auto clipHeight = display.clip.height();
@@ -526,25 +527,28 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
            static_cast<SkScalar>(rotatedClipWidth);
    const auto scaleY = static_cast<SkScalar>(display.physicalDisplay.height()) /
            static_cast<SkScalar>(rotatedClipHeight);
    canvas->scale(scaleX, scaleY);
    screenTransform.preScale(scaleX, scaleY);

    // Canvas rotation is done by centering the clip window at the origin, rotating, translating
    // back so that the top left corner of the clip is at (0, 0).
    canvas->translate(rotatedClipWidth / 2, rotatedClipHeight / 2);
    canvas->rotate(toDegrees(display.orientation));
    canvas->translate(-clipWidth / 2, -clipHeight / 2);
    canvas->translate(-display.clip.left, -display.clip.top);
    screenTransform.preTranslate(rotatedClipWidth / 2, rotatedClipHeight / 2);
    screenTransform.preRotate(toDegrees(display.orientation));
    screenTransform.preTranslate(-clipWidth / 2, -clipHeight / 2);
    screenTransform.preTranslate(-display.clip.left, -display.clip.top);
    for (const auto& layer : layers) {
        const SkMatrix drawTransform = getDrawTransform(layer, screenTransform);

        SkPaint paint;
        const auto& bounds = layer->geometry.boundaries;
        const auto dest = getSkRect(bounds);
        std::unordered_map<uint32_t, sk_sp<SkSurface>> cachedBlurs;

        if (mBlurFilter) {
            const auto layerRect = drawTransform.mapRect(dest);
            if (layer->backgroundBlurRadius > 0) {
                ATRACE_NAME("BackgroundBlur");
                auto blurredSurface =
                        mBlurFilter->draw(canvas, surface, layer->backgroundBlurRadius);
                        mBlurFilter->draw(canvas, surface, layer->backgroundBlurRadius, layerRect);
                cachedBlurs[layer->backgroundBlurRadius] = blurredSurface;
            }
            if (layer->blurRegions.size() > 0) {
@@ -553,7 +557,8 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                        continue;
                    }
                    ATRACE_NAME("BlurRegion");
                    auto blurredSurface = mBlurFilter->generate(canvas, surface, region.blurRadius);
                    auto blurredSurface =
                            mBlurFilter->generate(canvas, surface, region.blurRadius, layerRect);
                    cachedBlurs[region.blurRadius] = blurredSurface;
                }
            }
@@ -658,9 +663,8 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,

        paint.setColorFilter(SkColorFilters::Matrix(toSkColorMatrix(display.colorTransform)));

        // Layers have a local transform matrix that should be applied to them.
        canvas->save();
        canvas->concat(getSkM44(layer->geometry.positionTransform));
        canvas->concat(drawTransform);

        for (const auto effectRegion : layer->blurRegions) {
            drawBlurRegion(canvas, effectRegion, dest, cachedBlurs[effectRegion.blurRadius]);
@@ -737,6 +741,13 @@ inline SkM44 SkiaGLRenderEngine::getSkM44(const mat4& matrix) {
                 matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);
}

inline SkMatrix SkiaGLRenderEngine::getDrawTransform(const LayerSettings* layer,
                                                     const SkMatrix& screenTransform) {
    // Layers have a local transform matrix that should be applied to them.
    const auto layerTransform = getSkM44(layer->geometry.positionTransform).asM33();
    return SkMatrix::Concat(screenTransform, layerTransform);
}

inline SkPoint3 SkiaGLRenderEngine::getSkPoint3(const vec3& vector) {
    return SkPoint3::Make(vector.x, vector.y, vector.z);
}
+2 −1
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ private:
    inline SkRRect getRoundedRect(const LayerSettings* layer);
    inline SkColor getSkColor(const vec4& color);
    inline SkM44 getSkM44(const mat4& matrix);
    inline SkMatrix getDrawTransform(const LayerSettings* layer, const SkMatrix& screenTransform);
    inline SkPoint3 getSkPoint3(const vec3& vector);

    base::unique_fd flush();
+16 −8
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ BlurFilter::BlurFilter() {
}

sk_sp<SkSurface> BlurFilter::generate(SkCanvas* canvas, const sk_sp<SkSurface> input,
                                      const uint32_t blurRadius) const {
                                      const uint32_t blurRadius, SkRect rect) const {
    ATRACE_CALL();

    // Kawase is an approximation of Gaussian, but it behaves differently from it.
@@ -68,6 +68,9 @@ sk_sp<SkSurface> BlurFilter::generate(SkCanvas* canvas, const sk_sp<SkSurface> i

    SkImageInfo scaledInfo = SkImageInfo::MakeN32Premul((float)input->width() * kInputScale,
                                                        (float)input->height() * kInputScale);

    SkRect scaledRect = {rect.fLeft * kInputScale, rect.fTop * kInputScale,
                         rect.fRight * kInputScale, rect.fBottom * kInputScale};
    auto drawSurface = canvas->makeSurface(scaledInfo);

    const float stepX = radiusByPasses;
@@ -88,7 +91,9 @@ sk_sp<SkSurface> BlurFilter::generate(SkCanvas* canvas, const sk_sp<SkSurface> i
        SkPaint paint;
        paint.setShader(blurBuilder.makeShader(nullptr, false));
        paint.setFilterQuality(kLow_SkFilterQuality);
        drawSurface->getCanvas()->drawIRect(scaledInfo.bounds(), paint);

        drawSurface->getCanvas()->drawRect(scaledRect, paint);

        blurBuilder.child("input") = nullptr;
    }

@@ -110,7 +115,8 @@ sk_sp<SkSurface> BlurFilter::generate(SkCanvas* canvas, const sk_sp<SkSurface> i
            SkPaint paint;
            paint.setShader(blurBuilder.makeShader(nullptr, false));
            paint.setFilterQuality(kLow_SkFilterQuality);
            drawSurface->getCanvas()->drawIRect(scaledInfo.bounds(), paint);

            drawSurface->getCanvas()->drawRect(scaledRect, paint);

            // Swap buffers for next iteration
            const auto tmp = drawSurface;
@@ -125,16 +131,18 @@ sk_sp<SkSurface> BlurFilter::generate(SkCanvas* canvas, const sk_sp<SkSurface> i
}

sk_sp<SkSurface> BlurFilter::draw(SkCanvas* canvas, const sk_sp<SkSurface> input,
                                  const uint32_t blurRadius) const {
                                  const uint32_t blurRadius, SkRect rect) const {
    ATRACE_CALL();
    auto surface = generate(canvas, input, blurRadius);
    sk_sp<SkSurface> surface = generate(canvas, input, blurRadius, rect);
    const auto image = surface->makeImageSnapshot();

    SkPaint paint;
    const auto image = surface->makeImageSnapshot();
    paint.setShader(image->makeShader(SkMatrix::MakeScale(kInverseInputScale)));
    paint.setFilterQuality(kLow_SkFilterQuality);
    paint.setAlpha(std::min(1.0f, (float)blurRadius / kMaxCrossFadeRadius) * 255);
    canvas->drawIRect(SkIRect::MakeWH(input->width(), input->height()), paint);

    canvas->drawRect(rect, paint);

    return surface;
}

+4 −4
Original line number Diff line number Diff line
@@ -48,11 +48,11 @@ public:
    virtual ~BlurFilter(){};

    // Execute blur, saving it to a texture
    sk_sp<SkSurface> generate(SkCanvas* canvas, const sk_sp<SkSurface> input,
                              const uint32_t radius) const;
    sk_sp<SkSurface> generate(SkCanvas* canvas, const sk_sp<SkSurface> input, const uint32_t radius,
                              SkRect rect) const;
    // Same as generate but also drawing to the screen
    sk_sp<SkSurface> draw(SkCanvas* canvas, const sk_sp<SkSurface> input,
                          const uint32_t radius) const;
    sk_sp<SkSurface> draw(SkCanvas* canvas, const sk_sp<SkSurface> input, const uint32_t radius,
                          SkRect rect) const;
    // Returns a matrix that should be applied to the blur shader
    SkMatrix getShaderMatrix(const SkMatrix& transformMatrix) const;