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
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 34ef0a4..39103df 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -487,6 +487,9 @@
     void fillBufferAndBlurBackground();
 
     template <typename SourceVariant>
+    void fillSmallLayerAndBlurBackground();
+
+    template <typename SourceVariant>
     void overlayCorners();
 
     void fillRedBufferTextureTransform();
@@ -971,6 +974,39 @@
 }
 
 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;
     settings.physicalDisplay = fullscreenRect();
@@ -1408,6 +1444,11 @@
     fillBufferAndBlurBackground<ColorSourceVariant>();
 }
 
+TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
+    initializeRenderEngine();
+    fillSmallLayerAndBlurBackground<ColorSourceVariant>();
+}
+
 TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
     initializeRenderEngine();
     overlayCorners<ColorSourceVariant>();
@@ -1484,6 +1525,11 @@
     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 @@
     fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
 }
 
+TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
+    initializeRenderEngine();
+    fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
 TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
     initializeRenderEngine();
     overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();