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

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

Merge changes I8d2a0988,I5f8f7c4a into sc-dev

* changes:
  Fix bg blur not showing when layer alpha is 0
  Fix blur sampling outside bounds of layer
parents 785ac97f e7f6ee7e
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -36,13 +36,18 @@ BlurFilter::BlurFilter() {
    SkString blurString(R"(
        in shader input;
        uniform float2 in_blurOffset;
        uniform float2 in_maxSizeXY;

        half4 main(float2 xy) {
            half4 c = sample(input, xy);
            c += sample(input, xy + float2( in_blurOffset.x,  in_blurOffset.y));
            c += sample(input, xy + float2( in_blurOffset.x, -in_blurOffset.y));
            c += sample(input, xy + float2(-in_blurOffset.x,  in_blurOffset.y));
            c += sample(input, xy + float2(-in_blurOffset.x, -in_blurOffset.y));
            c += sample(input, float2( clamp( in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
                                       clamp(in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));
            c += sample(input, float2( clamp( in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
                                       clamp(-in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));
            c += sample(input, float2( clamp( -in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
                                       clamp(in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));
            c += sample(input, float2( clamp( -in_blurOffset.x + xy.x, 0, in_maxSizeXY.x),
                                       clamp(-in_blurOffset.y + xy.y, 0, in_maxSizeXY.y)));

            return half4(c.rgb * 0.2, 1.0);
        }
@@ -99,6 +104,8 @@ sk_sp<SkImage> BlurFilter::generate(GrRecordingContext* context, const uint32_t
    blurBuilder.child("input") =
            input->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, linear, blurMatrix);
    blurBuilder.uniform("in_blurOffset") = SkV2{stepX * kInputScale, stepY * kInputScale};
    blurBuilder.uniform("in_maxSizeXY") =
            SkV2{blurRect.width() * kInputScale - 1, blurRect.height() * kInputScale - 1};

    sk_sp<SkImage> tmpBlur(blurBuilder.makeImage(context, nullptr, scaledInfo, false));

@@ -108,6 +115,8 @@ sk_sp<SkImage> BlurFilter::generate(GrRecordingContext* context, const uint32_t
        blurBuilder.child("input") =
                tmpBlur->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, linear);
        blurBuilder.uniform("in_blurOffset") = SkV2{stepX * stepScale, stepY * stepScale};
        blurBuilder.uniform("in_maxSizeXY") =
                SkV2{blurRect.width() * kInputScale - 1, blurRect.height() * kInputScale - 1};
        tmpBlur = blurBuilder.makeImage(context, nullptr, scaledInfo, false);
    }

+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ std::vector<compositionengine::LayerFE::LayerSettings> EffectLayer::prepareClien
}

bool EffectLayer::isVisible() const {
    return !isHiddenByPolicy() && getAlpha() > 0.0_hf && hasSomethingToDraw();
    return !isHiddenByPolicy() && (getAlpha() > 0.0_hf || hasBlur()) && hasSomethingToDraw();
}

bool EffectLayer::setColor(const half3& color) {
+66 −0
Original line number Diff line number Diff line
@@ -111,6 +111,72 @@ TEST_F(EffectLayerTest, EffectLayerCanSetColor) {
    }
}

TEST_F(EffectLayerTest, BlurEffectLayerIsVisible) {
    if (!deviceSupportsBlurs()) GTEST_SKIP();
    if (!deviceUsesSkiaRenderEngine()) GTEST_SKIP();

    const auto canvasSize = 256;

    sp<SurfaceControl> leftLayer = createColorLayer("Left", Color::BLUE);
    sp<SurfaceControl> rightLayer = createColorLayer("Right", Color::GREEN);
    sp<SurfaceControl> blurLayer;
    const auto leftRect = Rect(0, 0, canvasSize / 2, canvasSize);
    const auto rightRect = Rect(canvasSize / 2, 0, canvasSize, canvasSize);
    const auto blurRect = Rect(0, 0, canvasSize, canvasSize);

    asTransaction([&](Transaction& t) {
        t.setLayer(leftLayer, mLayerZBase + 1);
        t.reparent(leftLayer, mParentLayer);
        t.setCrop_legacy(leftLayer, leftRect);
        t.setLayer(rightLayer, mLayerZBase + 2);
        t.reparent(rightLayer, mParentLayer);
        t.setCrop_legacy(rightLayer, rightRect);
        t.show(leftLayer);
        t.show(rightLayer);
    });

    {
        auto shot = screenshot();
        shot->expectColor(leftRect, Color::BLUE);
        shot->expectColor(rightRect, Color::GREEN);
    }

    ASSERT_NO_FATAL_FAILURE(blurLayer = createColorLayer("BackgroundBlur", Color::TRANSPARENT));

    const auto blurRadius = canvasSize / 2;
    asTransaction([&](Transaction& t) {
        t.setLayer(blurLayer, mLayerZBase + 3);
        t.reparent(blurLayer, mParentLayer);
        t.setBackgroundBlurRadius(blurLayer, blurRadius);
        t.setCrop_legacy(blurLayer, blurRect);
        t.setFrame(blurLayer, blurRect);
        t.setAlpha(blurLayer, 0.0f);
        t.show(blurLayer);
    });

    {
        auto shot = screenshot();

        const auto stepSize = 1;
        const auto blurAreaOffset = blurRadius * 0.7f;
        const auto blurAreaStartX = canvasSize / 2 - blurRadius + blurAreaOffset;
        const auto blurAreaEndX = canvasSize / 2 + blurRadius - blurAreaOffset;
        Color previousColor;
        Color currentColor;
        for (int y = 0; y < canvasSize; y++) {
            shot->checkPixel(0, y, /* r = */ 0, /* g = */ 0, /* b = */ 255);
            previousColor = shot->getPixelColor(0, y);
            for (int x = blurAreaStartX; x < blurAreaEndX; x += stepSize) {
                currentColor = shot->getPixelColor(x, y);
                ASSERT_GT(currentColor.g, previousColor.g);
                ASSERT_LT(currentColor.b, previousColor.b);
                ASSERT_EQ(0, currentColor.r);
            }
            shot->checkPixel(canvasSize - 1, y, 0, 255, 0);
        }
    }
}

} // namespace android

// TODO(b/129481165): remove the #pragma below and fix conversion issues
+14 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wextra"

#include <cutils/properties.h>
#include <gtest/gtest.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
@@ -245,6 +246,18 @@ protected:

    sp<SurfaceComposerClient> mClient;

    bool deviceSupportsBlurs() {
        char value[PROPERTY_VALUE_MAX];
        property_get("ro.surface_flinger.supports_background_blur", value, "0");
        return atoi(value);
    }

    bool deviceUsesSkiaRenderEngine() {
        char value[PROPERTY_VALUE_MAX];
        property_get("debug.renderengine.backend", value, "default");
        return strstr(value, "skia") != nullptr;
    }

    sp<IBinder> mDisplay;
    uint32_t mDisplayWidth;
    uint32_t mDisplayHeight;
+74 −46
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"

#include <cutils/properties.h>
#include <gui/BufferItemConsumer.h>
#include "TransactionTestHarnesses.h"

@@ -301,47 +300,86 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetCornerRadiusChildCrop) {
    }
}

TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadius) {
    char value[PROPERTY_VALUE_MAX];
    property_get("ro.surface_flinger.supports_background_blur", value, "0");
    if (!atoi(value)) {
        // This device doesn't support blurs, no-op.
        return;
    }
TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) {
    if (!deviceSupportsBlurs()) GTEST_SKIP();
    if (!deviceUsesSkiaRenderEngine()) GTEST_SKIP();

    auto size = 256;
    auto center = size / 2;
    auto blurRadius = 50;

    sp<SurfaceControl> backgroundLayer;
    ASSERT_NO_FATAL_FAILURE(backgroundLayer = createLayer("background", size, size));
    ASSERT_NO_FATAL_FAILURE(fillLayerColor(backgroundLayer, Color::GREEN, size, size));
    const auto canvasSize = 256;

    sp<SurfaceControl> leftLayer;
    ASSERT_NO_FATAL_FAILURE(leftLayer = createLayer("left", size / 2, size));
    ASSERT_NO_FATAL_FAILURE(fillLayerColor(leftLayer, Color::RED, size / 2, size));

    sp<SurfaceControl> rightLayer;
    sp<SurfaceControl> greenLayer;
    sp<SurfaceControl> blurLayer;
    ASSERT_NO_FATAL_FAILURE(blurLayer = createLayer("blur", size, size));
    ASSERT_NO_FATAL_FAILURE(fillLayerColor(blurLayer, Color::TRANSPARENT, size, size));
    const auto leftRect = Rect(0, 0, canvasSize / 2, canvasSize);
    const auto rightRect = Rect(canvasSize / 2, 0, canvasSize, canvasSize);
    const auto blurRect = Rect(0, 0, canvasSize, canvasSize);

    Transaction().setBackgroundBlurRadius(blurLayer, blurRadius).apply();
    ASSERT_NO_FATAL_FAILURE(leftLayer =
                                    createLayer("Left", leftRect.getWidth(), leftRect.getHeight()));
    ASSERT_NO_FATAL_FAILURE(
            fillLayerColor(leftLayer, Color::BLUE, leftRect.getWidth(), leftRect.getHeight()));
    ASSERT_NO_FATAL_FAILURE(greenLayer = createLayer("Green", canvasSize * 2, canvasSize * 2));
    ASSERT_NO_FATAL_FAILURE(
            fillLayerColor(greenLayer, Color::GREEN, canvasSize * 2, canvasSize * 2));
    ASSERT_NO_FATAL_FAILURE(
            rightLayer = createLayer("Right", rightRect.getWidth(), rightRect.getHeight()));
    ASSERT_NO_FATAL_FAILURE(
            fillLayerColor(rightLayer, Color::RED, rightRect.getWidth(), rightRect.getHeight()));

    Transaction()
            .setLayer(greenLayer, mLayerZBase)
            .setFrame(leftLayer, {0, 0, canvasSize * 2, canvasSize * 2})
            .setLayer(leftLayer, mLayerZBase + 1)
            .setFrame(leftLayer, leftRect)
            .setLayer(rightLayer, mLayerZBase + 2)
            .setPosition(rightLayer, rightRect.left, rightRect.top)
            .setFrame(rightLayer, rightRect)
            .apply();

    {
        auto shot = getScreenCapture();
    // Edges are mixed
    shot->expectColor(Rect(center - 1, center - 5, center, center + 5), Color{150, 150, 0, 255},
                      50 /* tolerance */);
    shot->expectColor(Rect(center, center - 5, center + 1, center + 5), Color{150, 150, 0, 255},
                      50 /* tolerance */);
        shot->expectColor(leftRect, Color::BLUE);
        shot->expectColor(rightRect, Color::RED);
    }

TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusOnMultipleLayers) {
    char value[PROPERTY_VALUE_MAX];
    property_get("ro.surface_flinger.supports_background_blur", value, "0");
    if (!atoi(value)) {
        // This device doesn't support blurs, no-op.
        return;
    ASSERT_NO_FATAL_FAILURE(blurLayer = createColorLayer("BackgroundBlur", Color::TRANSPARENT));

    const auto blurRadius = canvasSize / 2;
    Transaction()
            .setLayer(blurLayer, mLayerZBase + 3)
            .setBackgroundBlurRadius(blurLayer, blurRadius)
            .setCrop_legacy(blurLayer, blurRect)
            .setFrame(blurLayer, blurRect)
            .setSize(blurLayer, blurRect.getWidth(), blurRect.getHeight())
            .setAlpha(blurLayer, 0.0f)
            .apply();

    {
        auto shot = getScreenCapture();

        const auto stepSize = 1;
        const auto blurAreaOffset = blurRadius * 0.7f;
        const auto blurAreaStartX = canvasSize / 2 - blurRadius + blurAreaOffset;
        const auto blurAreaEndX = canvasSize / 2 + blurRadius - blurAreaOffset;
        Color previousColor;
        Color currentColor;
        for (int y = 0; y < canvasSize; y++) {
            shot->checkPixel(0, y, /* r = */ 0, /* g = */ 0, /* b = */ 255);
            previousColor = shot->getPixelColor(0, y);
            for (int x = blurAreaStartX; x < blurAreaEndX; x += stepSize) {
                currentColor = shot->getPixelColor(x, y);
                ASSERT_GT(currentColor.r, previousColor.r);
                ASSERT_LT(currentColor.b, previousColor.b);
                ASSERT_EQ(0, currentColor.g);
            }
            shot->checkPixel(canvasSize - 1, y, 255, 0, 0);
        }
    }
}

TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusOnMultipleLayers) {
    if (!deviceSupportsBlurs()) GTEST_SKIP();
    if (!deviceUsesSkiaRenderEngine()) GTEST_SKIP();

    auto size = 256;
    auto center = size / 2;
@@ -378,25 +416,15 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusOnMultipleL
}

TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurAffectedByParentAlpha) {
    char value[PROPERTY_VALUE_MAX];
    property_get("ro.surface_flinger.supports_background_blur", value, "0");
    if (!atoi(value)) {
        // This device doesn't support blurs, no-op.
        return;
    }

    property_get("debug.renderengine.backend", value, "");
    if (strcmp(value, "skiagl") != 0) {
        // This device isn't using Skia render engine, no-op.
        return;
    }
    if (!deviceSupportsBlurs()) GTEST_SKIP();
    if (!deviceUsesSkiaRenderEngine()) GTEST_SKIP();

    sp<SurfaceControl> left;
    sp<SurfaceControl> right;
    sp<SurfaceControl> blur;
    sp<SurfaceControl> blurParent;

    const auto size = 32;
    const auto size = 256;
    ASSERT_NO_FATAL_FAILURE(left = createLayer("Left", size, size));
    ASSERT_NO_FATAL_FAILURE(fillLayerColor(left, Color::BLUE, size, size));
    ASSERT_NO_FATAL_FAILURE(right = createLayer("Right", size, size));
Loading