Add support for background blurs
Bug: 141640413
Fixes: 146384234
Test: adb shell setprop debug.sf.disableBlurs 1
Test: adb shell setprop debug.sf.gaussianBlur 0
Test: adb shell setprop ro.surface_flinger.supports_background_blur 1
Test: ./SurfaceFlinger_test --gtest_filter=Layer*Tests/Layer*Test.SetBackgroundBlur*
Test: ./librenderengine_test --gtest_filter=*BlurBackground*"
Test: atest SurfaceFlinger_test:SurfaceInterceptorTest#InterceptBackgroundBlurRadiusUpdateWorks
Change-Id: I5194c910fe7062f33e70943867012539e6c6626a
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index a64fdbf..3dbd25e 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -63,6 +63,9 @@
// The alpha value for this layer
float alpha{1.f};
+ // Background blur in pixels
+ int backgroundBlurRadius{0};
+
// The transform from layer local coordinates to composition coordinates
ui::Transform geomLayerTransform;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 159e928..3a9776d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -116,6 +116,7 @@
private:
void dirtyEntireOutput();
+ compositionengine::OutputLayer* findLayerRequestingBackgroundComposition() const;
ui::Dataspace getBestDataspace(ui::Dataspace*, bool*) const;
compositionengine::Output::ColorProfile pickColorProfile(
const compositionengine::CompositionRefreshArgs&) const;
@@ -126,6 +127,7 @@
std::unique_ptr<compositionengine::RenderSurface> mRenderSurface;
ReleasedLayers mReleasedLayers;
+ OutputLayer* mLayerRequestingBackgroundBlur = nullptr;
};
// This template factory function standardizes the implementation details of the
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
index 085e838..8065e65 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
@@ -61,6 +61,7 @@
out.append("\n ");
dumpVal(out, "blend", toString(blendMode), blendMode);
dumpVal(out, "alpha", alpha);
+ dumpVal(out, "backgroundBlurRadius", backgroundBlurRadius);
out.append("\n ");
dumpVal(out, "type", type);
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 01413b9..650b5c1 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -578,15 +578,33 @@
return;
}
+ mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
+ bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;
+
for (auto* layer : getOutputLayersOrderedByZ()) {
layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
- refreshArgs.devOptForceClientComposition);
+ refreshArgs.devOptForceClientComposition ||
+ forceClientComposition);
+
+ if (mLayerRequestingBackgroundBlur == layer) {
+ forceClientComposition = false;
+ }
// Send the updated state to the HWC, if appropriate.
layer->writeStateToHWC(refreshArgs.updatingGeometryThisFrame);
}
}
+compositionengine::OutputLayer* Output::findLayerRequestingBackgroundComposition() const {
+ compositionengine::OutputLayer* layerRequestingBgComposition = nullptr;
+ for (auto* layer : getOutputLayersOrderedByZ()) {
+ if (layer->getLayer().getFEState().backgroundBlurRadius > 0) {
+ layerRequestingBgComposition = layer;
+ }
+ }
+ return layerRequestingBgComposition;
+}
+
void Output::updateColorProfile(const compositionengine::CompositionRefreshArgs& refreshArgs) {
setColorProfile(pickColorProfile(refreshArgs));
}
@@ -854,11 +872,12 @@
}
// We boost GPU frequency here because there will be color spaces conversion
- // and it's expensive. We boost the GPU frequency so that GPU composition can
- // finish in time. We must reset GPU frequency afterwards, because high frequency
- // consumes extra battery.
+ // or complex GPU shaders and it's expensive. We boost the GPU frequency so that
+ // GPU composition can finish in time. We must reset GPU frequency afterwards,
+ // because high frequency consumes extra battery.
const bool expensiveRenderingExpected =
- clientCompositionDisplay.outputDataspace == ui::Dataspace::DISPLAY_P3;
+ clientCompositionDisplay.outputDataspace == ui::Dataspace::DISPLAY_P3 ||
+ mLayerRequestingBackgroundBlur != nullptr;
if (expensiveRenderingExpected) {
setExpensiveRenderingExpected(true);
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 24311c7..6761b86 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -138,6 +138,10 @@
EXPECT_CALL(mLayer1, editFEState()).WillRepeatedly(ReturnRef(mLayer1FEState));
EXPECT_CALL(mLayer2, editFEState()).WillRepeatedly(ReturnRef(mLayer2FEState));
EXPECT_CALL(mLayer3, editFEState()).WillRepeatedly(ReturnRef(mLayer3FEState));
+
+ EXPECT_CALL(mLayer1, getFEState()).WillRepeatedly(ReturnRef(mLayer1FEState));
+ EXPECT_CALL(mLayer2, getFEState()).WillRepeatedly(ReturnRef(mLayer2FEState));
+ EXPECT_CALL(mLayer3, getFEState()).WillRepeatedly(ReturnRef(mLayer3FEState));
}
void injectLayer(std::unique_ptr<mock::OutputLayer> layer) {
@@ -3637,6 +3641,29 @@
kDisplayDataspace));
}
+TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
+ // Layer requesting blur, or below, should request client composition.
+ EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, true));
+ EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
+ EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, true));
+ EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
+ EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, false));
+ EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
+
+ mLayer2FEState.backgroundBlurRadius = 10;
+
+ injectLayer(std::move(mOutputLayer1));
+ injectLayer(std::move(mOutputLayer2));
+ injectLayer(std::move(mOutputLayer3));
+
+ mOutput->editState().isEnabled = true;
+
+ CompositionRefreshArgs args;
+ args.updatingGeometryThisFrame = false;
+ args.devOptForceClientComposition = false;
+ mOutput->updateAndWriteCompositionState(args);
+}
+
TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
// In split-screen landscape mode, the screen is rotated 90 degrees, with
// one layer on the left covering the left side of the output, and one layer
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 9c4a784..f4d4329 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -109,6 +109,7 @@
mCurrentState.hdrMetadata.validTypes = 0;
mCurrentState.surfaceDamageRegion = Region::INVALID_REGION;
mCurrentState.cornerRadius = 0.0f;
+ mCurrentState.backgroundBlurRadius = 0;
mCurrentState.api = -1;
mCurrentState.hasColorTransform = false;
mCurrentState.colorSpaceAgnostic = false;
@@ -448,6 +449,7 @@
compositionState.blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
compositionState.alpha = alpha;
+ compositionState.backgroundBlurRadius = drawingState.backgroundBlurRadius;
}
void Layer::latchGeometry(compositionengine::LayerFECompositionState& compositionState) const {
@@ -575,6 +577,7 @@
layerSettings.alpha = alpha;
layerSettings.sourceDataspace = getDataSpace();
+ layerSettings.backgroundBlurRadius = getBackgroundBlurRadius();
return layerSettings;
}
@@ -1103,6 +1106,16 @@
return true;
}
+bool Layer::setBackgroundBlurRadius(int backgroundBlurRadius) {
+ if (mCurrentState.backgroundBlurRadius == backgroundBlurRadius) return false;
+
+ mCurrentState.sequence++;
+ mCurrentState.backgroundBlurRadius = backgroundBlurRadius;
+ mCurrentState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+
bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix,
bool allowNonRectPreservingTransforms) {
ui::Transform t;
@@ -1873,6 +1886,10 @@
return half4(color.r, color.g, color.b, getAlpha());
}
+int32_t Layer::getBackgroundBlurRadius() const {
+ return getDrawingState().backgroundBlurRadius;
+}
+
Layer::RoundedCornerState Layer::getRoundedCornerState() const {
const auto& p = mDrawingParent.promote();
if (p != nullptr) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 0253098..ffe004f 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -179,6 +179,7 @@
half4 color;
float cornerRadius;
+ int backgroundBlurRadius;
bool inputInfoChanged;
InputWindowInfo inputInfo;
@@ -299,6 +300,9 @@
// The shape of the rounded corner rectangle is specified by the crop rectangle of the layer
// from which we inferred the rounded corner radius.
virtual bool setCornerRadius(float cornerRadius);
+ // When non-zero, everything below this layer will be blurred by backgroundBlurRadius, which
+ // is specified in pixels.
+ virtual bool setBackgroundBlurRadius(int backgroundBlurRadius);
virtual bool setTransparentRegionHint(const Region& transparent);
virtual bool setFlags(uint8_t flags, uint8_t mask);
virtual bool setLayerStack(uint32_t layerStack);
@@ -663,6 +667,7 @@
// down the hierarchy).
half getAlpha() const;
half4 getColor() const;
+ int32_t getBackgroundBlurRadius() const;
// Returns how rounded corners should be drawn for this layer.
// This will traverse the hierarchy until it reaches its root, finding topmost rounded
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0a33830..ba57d37 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -338,6 +338,14 @@
mLayerTripleBufferingDisabled = atoi(value);
ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");
+ property_get("ro.surface_flinger.supports_background_blur", value, "0");
+ bool supportsBlurs = atoi(value);
+ property_get("debug.sf.disableBlurs", value, "0");
+ bool disableBlurs = atoi(value);
+ mEnableBlurs = supportsBlurs && !disableBlurs;
+ ALOGI_IF(!mEnableBlurs, "Disabling blur effects. supported: %d, disabled: %d", supportsBlurs,
+ disableBlurs);
+
const size_t defaultListSize = MAX_LAYERS;
auto listSize = property_get_int32("debug.sf.max_igbp_list_size", int32_t(defaultListSize));
mMaxGraphicBufferProducerListSize = (listSize > 0) ? size_t(listSize) : defaultListSize;
@@ -580,6 +588,7 @@
.setUseColorManagerment(useColorManagement)
.setEnableProtectedContext(enable_protected_contents(false))
.setPrecacheToneMapperShaderOnly(false)
+ .setSupportsBackgroundBlur(mEnableBlurs)
.setContextPriority(useContextPriority
? renderengine::RenderEngine::ContextPriority::HIGH
: renderengine::RenderEngine::ContextPriority::MEDIUM)
@@ -3379,6 +3388,9 @@
if (layer->setCornerRadius(s.cornerRadius))
flags |= eTraversalNeeded;
}
+ if (what & layer_state_t::eBackgroundBlurRadiusChanged) {
+ if (layer->setBackgroundBlurRadius(s.backgroundBlurRadius)) flags |= eTraversalNeeded;
+ }
if (what & layer_state_t::eLayerStackChanged) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
// We only allow setting layer stacks for top level layers,
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 723e332..b9f230d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1025,6 +1025,7 @@
const std::shared_ptr<TimeStats> mTimeStats;
const std::unique_ptr<FrameTracer> mFrameTracer;
bool mUseHwcVirtualDisplays = false;
+ bool mEnableBlurs = false;
std::atomic<uint32_t> mFrameMissedCount = 0;
std::atomic<uint32_t> mHwcFrameMissedCount = 0;
std::atomic<uint32_t> mGpuFrameMissedCount = 0;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 79123f9..6884b4c 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -114,6 +114,7 @@
addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
addCropLocked(transaction, layerId, layer->mCurrentState.crop_legacy);
addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius);
+ addBackgroundBlurRadiusLocked(transaction, layerId, layer->mCurrentState.backgroundBlurRadius);
if (layer->mCurrentState.barrierLayer_legacy != nullptr) {
addDeferTransactionLocked(transaction, layerId,
layer->mCurrentState.barrierLayer_legacy.promote(),
@@ -322,6 +323,13 @@
cornerRadiusChange->set_corner_radius(cornerRadius);
}
+void SurfaceInterceptor::addBackgroundBlurRadiusLocked(Transaction* transaction, int32_t layerId,
+ int32_t backgroundBlurRadius) {
+ SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId));
+ BackgroundBlurRadiusChange* blurRadiusChange(change->mutable_background_blur_radius());
+ blurRadiusChange->set_background_blur_radius(backgroundBlurRadius);
+}
+
void SurfaceInterceptor::addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
const sp<const Layer>& layer, uint64_t frameNumber)
{
@@ -422,6 +430,9 @@
if (state.what & layer_state_t::eCornerRadiusChanged) {
addCornerRadiusLocked(transaction, layerId, state.cornerRadius);
}
+ if (state.what & layer_state_t::eBackgroundBlurRadiusChanged) {
+ addBackgroundBlurRadiusLocked(transaction, layerId, state.backgroundBlurRadius);
+ }
if (state.what & layer_state_t::eDeferTransaction_legacy) {
sp<Layer> otherLayer = nullptr;
if (state.barrierHandle_legacy != nullptr) {
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index c6f9e8a..a665f62 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -152,6 +152,8 @@
void addLayerStackLocked(Transaction* transaction, int32_t layerId, uint32_t layerStack);
void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
void addCornerRadiusLocked(Transaction* transaction, int32_t layerId, float cornerRadius);
+ void addBackgroundBlurRadiusLocked(Transaction* transaction, int32_t layerId,
+ int32_t backgroundBlurRadius);
void addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
const sp<const Layer>& layer, uint64_t frameNumber);
void addOverrideScalingModeLocked(Transaction* transaction, int32_t layerId,
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index ef27847..8fce0c9 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -106,6 +106,7 @@
layer.refreshPending = layerProto.refresh_pending();
layer.isProtected = layerProto.is_protected();
layer.cornerRadius = layerProto.corner_radius();
+ layer.backgroundBlurRadius = layerProto.background_blur_radius();
for (const auto& entry : layerProto.metadata()) {
const std::string& dataStr = entry.second;
std::vector<uint8_t>& outData = layer.metadata.mMap[entry.first];
@@ -290,6 +291,7 @@
StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str());
+ StringAppendF(&result, "backgroundBlurRadius=%1d, ", backgroundBlurRadius);
StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
static_cast<double>(color.r), static_cast<double>(color.g),
static_cast<double>(color.b), static_cast<double>(color.a), flags);
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
index 774b0e1..52b9165 100644
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
@@ -110,6 +110,7 @@
bool refreshPending;
bool isProtected;
float cornerRadius;
+ int backgroundBlurRadius;
LayerMetadata metadata;
LayerProtoParser::FloatRect cornerRadiusCrop;
float shadowRadius;
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index 41ecafa..8afe503 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -104,6 +104,8 @@
ColorTransformProto color_transform = 50;
bool is_relative_of = 51;
+ // Layer's background blur radius in pixels.
+ int32 background_blur_radius = 52;
}
message PositionProto {
diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
index 049c872..ed2b220 100644
--- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
+++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
@@ -371,3 +371,12 @@
access: Readonly
prop_name: "ro.surface_flinger.support_kernel_idle_timer"
}
+
+# Indicates whether background blurs are supported.
+prop {
+ api_name: "supports_background_blur"
+ type: Boolean
+ scope: Public
+ access: Readonly
+ prop_name: "ro.surface_flinger.supports_background_blur"
+}
diff --git a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
index 2d52507..d24ad18 100644
--- a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
+++ b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
@@ -104,6 +104,10 @@
prop_name: "ro.surface_flinger.support_kernel_idle_timer"
}
prop {
+ api_name: "supports_background_blur"
+ prop_name: "ro.surface_flinger.supports_background_blur"
+ }
+ prop {
api_name: "use_color_management"
prop_name: "ro.surface_flinger.use_color_management"
}
diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
index 71f01b0..3bbd12a 100644
--- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
@@ -18,6 +18,7 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
+#include <cutils/properties.h>
#include <gui/BufferItemConsumer.h>
#include "TransactionTestHarnesses.h"
@@ -243,6 +244,41 @@
shot->expectColor(Rect(right - testArea, bottom - testArea, right, bottom), Color::BLACK);
}
}
+
+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;
+ }
+
+ 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));
+
+ 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> blurLayer;
+ ASSERT_NO_FATAL_FAILURE(blurLayer = createLayer("blur", size, size));
+ ASSERT_NO_FATAL_FAILURE(fillLayerColor(blurLayer, Color::TRANSPARENT, size, size));
+
+ Transaction().setBackgroundBlurRadius(blurLayer, blurRadius).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 */);
+}
+
TEST_P(LayerTypeAndRenderTypeTransactionTest, SetColorWithBuffer) {
sp<SurfaceControl> bufferLayer;
ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayer("test", 32, 32));
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index 75d0761..4a2ab7c 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -53,6 +53,7 @@
constexpr int32_t RELATIVE_Z = 42;
constexpr float ALPHA_UPDATE = 0.29f;
constexpr float CORNER_RADIUS_UPDATE = 0.2f;
+constexpr int BACKGROUND_BLUR_RADIUS_UPDATE = 24;
constexpr float POSITION_UPDATE = 121;
const Rect CROP_UPDATE(16, 16, 32, 32);
const float SHADOW_RADIUS_UPDATE = 35.0f;
@@ -183,6 +184,8 @@
bool layerUpdateFound(const SurfaceChange& change, bool foundLayer);
bool cropUpdateFound(const SurfaceChange& change, bool foundCrop);
bool cornerRadiusUpdateFound(const SurfaceChange& change, bool foundCornerRadius);
+ bool backgroundBlurRadiusUpdateFound(const SurfaceChange& change,
+ bool foundBackgroundBlurRadius);
bool matrixUpdateFound(const SurfaceChange& change, bool foundMatrix);
bool scalingModeUpdateFound(const SurfaceChange& change, bool foundScalingMode);
bool transparentRegionHintUpdateFound(const SurfaceChange& change, bool foundTransparentRegion);
@@ -220,6 +223,7 @@
void layerUpdate(Transaction&);
void cropUpdate(Transaction&);
void cornerRadiusUpdate(Transaction&);
+ void backgroundBlurRadiusUpdate(Transaction&);
void matrixUpdate(Transaction&);
void overrideScalingModeUpdate(Transaction&);
void transparentRegionHintUpdate(Transaction&);
@@ -355,6 +359,10 @@
t.setCornerRadius(mBGSurfaceControl, CORNER_RADIUS_UPDATE);
}
+void SurfaceInterceptorTest::backgroundBlurRadiusUpdate(Transaction& t) {
+ t.setBackgroundBlurRadius(mBGSurfaceControl, BACKGROUND_BLUR_RADIUS_UPDATE);
+}
+
void SurfaceInterceptorTest::layerUpdate(Transaction& t) {
t.setLayer(mBGSurfaceControl, LAYER_UPDATE);
}
@@ -432,6 +440,7 @@
runInTransaction(&SurfaceInterceptorTest::sizeUpdate);
runInTransaction(&SurfaceInterceptorTest::alphaUpdate);
runInTransaction(&SurfaceInterceptorTest::cornerRadiusUpdate);
+ runInTransaction(&SurfaceInterceptorTest::backgroundBlurRadiusUpdate);
runInTransaction(&SurfaceInterceptorTest::layerUpdate);
runInTransaction(&SurfaceInterceptorTest::cropUpdate);
runInTransaction(&SurfaceInterceptorTest::matrixUpdate);
@@ -509,6 +518,18 @@
return foundCornerRadius;
}
+bool SurfaceInterceptorTest::backgroundBlurRadiusUpdateFound(const SurfaceChange& change,
+ bool foundBackgroundBlur) {
+ bool hasBackgroundBlur(change.background_blur_radius().background_blur_radius() ==
+ BACKGROUND_BLUR_RADIUS_UPDATE);
+ if (hasBackgroundBlur && !foundBackgroundBlur) {
+ foundBackgroundBlur = true;
+ } else if (hasBackgroundBlur && foundBackgroundBlur) {
+ []() { FAIL(); }();
+ }
+ return foundBackgroundBlur;
+}
+
bool SurfaceInterceptorTest::layerUpdateFound(const SurfaceChange& change, bool foundLayer) {
bool hasLayer(change.layer().layer() == LAYER_UPDATE);
if (hasLayer && !foundLayer) {
@@ -705,6 +726,9 @@
case SurfaceChange::SurfaceChangeCase::kCornerRadius:
foundUpdate = cornerRadiusUpdateFound(change, foundUpdate);
break;
+ case SurfaceChange::SurfaceChangeCase::kBackgroundBlurRadius:
+ foundUpdate = backgroundBlurRadiusUpdateFound(change, foundUpdate);
+ break;
case SurfaceChange::SurfaceChangeCase::kMatrix:
foundUpdate = matrixUpdateFound(change, foundUpdate);
break;
@@ -887,6 +911,11 @@
SurfaceChange::SurfaceChangeCase::kCornerRadius);
}
+TEST_F(SurfaceInterceptorTest, InterceptBackgroundBlurRadiusUpdateWorks) {
+ captureTest(&SurfaceInterceptorTest::backgroundBlurRadiusUpdate,
+ SurfaceChange::SurfaceChangeCase::kBackgroundBlurRadius);
+}
+
TEST_F(SurfaceInterceptorTest, InterceptMatrixUpdateWorks) {
captureTest(&SurfaceInterceptorTest::matrixUpdate, SurfaceChange::SurfaceChangeCase::kMatrix);
}