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

Commit e8489fdd authored by Alec Mouri's avatar Alec Mouri
Browse files

Guarantee that blur surface has valid dimensions.

When scaling the blur rectangle, take the ceiling rather than the floor
so that integer division does not round down to zero for small
dimensions.

Bug: 182216890
Test: letterbox test app
Test: librenderengine_test
Change-Id: I6792331d7282fcbdcf406ae06dc63ac8ba8cf0a2
parent c1815199
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -86,8 +86,8 @@ sk_sp<SkImage> BlurFilter::generate(GrRecordingContext* context, const uint32_t
    float radiusByPasses = tmpRadius / (float)numberOfPasses;

    // create blur surface with the bit depth and colorspace of the original surface
    SkImageInfo scaledInfo = input->imageInfo().makeWH(blurRect.width() * kInputScale,
                                                       blurRect.height() * kInputScale);
    SkImageInfo scaledInfo = input->imageInfo().makeWH(std::ceil(blurRect.width() * kInputScale),
                                                       std::ceil(blurRect.height() * kInputScale));

    const float stepX = radiusByPasses;
    const float stepY = radiusByPasses;
@@ -105,7 +105,7 @@ sk_sp<SkImage> BlurFilter::generate(GrRecordingContext* context, const uint32_t
            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};
            SkV2{blurRect.width() * kInputScale, blurRect.height() * kInputScale};

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

@@ -116,7 +116,7 @@ sk_sp<SkImage> BlurFilter::generate(GrRecordingContext* context, const uint32_t
                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};
                SkV2{blurRect.width() * kInputScale, blurRect.height() * kInputScale};
        tmpBlur = blurBuilder.makeImage(context, nullptr, scaledInfo, false);
    }

+51 −0
Original line number Diff line number Diff line
@@ -486,6 +486,9 @@ public:
    template <typename SourceVariant>
    void fillBufferAndBlurBackground();

    template <typename SourceVariant>
    void fillSmallLayerAndBlurBackground();

    template <typename SourceVariant>
    void overlayCorners();

@@ -970,6 +973,39 @@ void RenderEngineTest::fillBufferAndBlurBackground() {
    }
}

template <typename SourceVariant>
void RenderEngineTest::fillSmallLayerAndBlurBackground() {
    auto blurRadius = 50;
    renderengine::DisplaySettings settings;
    settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
    settings.physicalDisplay = fullscreenRect();
    settings.clip = fullscreenRect();

    std::vector<const renderengine::LayerSettings*> layers;

    renderengine::LayerSettings backgroundLayer;
    backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
    backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
    SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
    backgroundLayer.alpha = 1.0f;
    layers.push_back(&backgroundLayer);

    renderengine::LayerSettings blurLayer;
    blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
    blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
    blurLayer.backgroundBlurRadius = blurRadius;
    SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
    blurLayer.alpha = 0;
    layers.push_back(&blurLayer);

    invokeDraw(settings, layers);

    // Give a generous tolerance - the blur rectangle is very small and this test is
    // mainly concerned with ensuring that there's no device failure.
    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
                      40 /* tolerance */);
}

template <typename SourceVariant>
void RenderEngineTest::overlayCorners() {
    renderengine::DisplaySettings settings;
@@ -1408,6 +1444,11 @@ TEST_P(RenderEngineTest, DISABLED_drawLayers_fillBufferAndBlurBackground_colorSo
    fillBufferAndBlurBackground<ColorSourceVariant>();
}

TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
    initializeRenderEngine();
    fillSmallLayerAndBlurBackground<ColorSourceVariant>();
}

TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
    initializeRenderEngine();
    overlayCorners<ColorSourceVariant>();
@@ -1484,6 +1525,11 @@ TEST_P(RenderEngineTest, DISABLED_drawLayers_fillBufferAndBlurBackground_opaqueB
    fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
}

TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
    initializeRenderEngine();
    fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
}

TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
    initializeRenderEngine();
    overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
@@ -1560,6 +1606,11 @@ TEST_P(RenderEngineTest, DISABLED_drawLayers_fillBufferAndBlurBackground_bufferS
    fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
}

TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
    initializeRenderEngine();
    fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
}

TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
    initializeRenderEngine();
    overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();