diff options
author | 2025-01-07 09:51:23 -0800 | |
---|---|---|
committer | 2025-01-07 09:51:23 -0800 | |
commit | 1926a933661dfbbfbcb6acdcbe8ce4b256d70a69 (patch) | |
tree | 9ceeeb9936ea689c5b1c736f58d74e2a354a7d8f | |
parent | 0ea3321806431e100e6784907711d6660dcaaebe (diff) | |
parent | 9674ffa1d161cd04b20789b4a960dfafc8cc140c (diff) |
Merge "surfaceflinger: Add clientDrawnCornerRadius and clientDrawnShadowLength layer properties" into main
-rw-r--r-- | libs/gui/LayerState.cpp | 16 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 23 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 14 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 9 | ||||
-rw-r--r-- | libs/ui/include/ui/ShadowSettings.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerSnapshot.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerSnapshot.h | 15 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp | 28 | ||||
-rw-r--r-- | services/surfaceflinger/FrontEnd/RequestedLayerState.cpp | 14 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp | 77 | ||||
-rw-r--r-- | services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h | 23 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp | 53 |
13 files changed, 267 insertions, 22 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index c1a03fcfea..44aac9bfae 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -66,6 +66,8 @@ layer_state_t::layer_state_t() mask(0), reserved(0), cornerRadius(0.0f), + clientDrawnCornerRadius(0.0f), + clientDrawnShadowRadius(0.0f), backgroundBlurRadius(0), color(0), bufferTransform(0), @@ -140,6 +142,8 @@ status_t layer_state_t::write(Parcel& output) const SAFE_PARCEL(output.write, colorTransform.asArray(), 16 * sizeof(float)); SAFE_PARCEL(output.writeFloat, cornerRadius); + SAFE_PARCEL(output.writeFloat, clientDrawnCornerRadius); + SAFE_PARCEL(output.writeFloat, clientDrawnShadowRadius); SAFE_PARCEL(output.writeUint32, backgroundBlurRadius); SAFE_PARCEL(output.writeParcelable, metadata); SAFE_PARCEL(output.writeFloat, bgColor.r); @@ -274,6 +278,8 @@ status_t layer_state_t::read(const Parcel& input) SAFE_PARCEL(input.read, &colorTransform, 16 * sizeof(float)); SAFE_PARCEL(input.readFloat, &cornerRadius); + SAFE_PARCEL(input.readFloat, &clientDrawnCornerRadius); + SAFE_PARCEL(input.readFloat, &clientDrawnShadowRadius); SAFE_PARCEL(input.readUint32, &backgroundBlurRadius); SAFE_PARCEL(input.readParcelable, &metadata); @@ -596,6 +602,14 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eCornerRadiusChanged; cornerRadius = other.cornerRadius; } + if (other.what & eClientDrawnCornerRadiusChanged) { + what |= eClientDrawnCornerRadiusChanged; + clientDrawnCornerRadius = other.clientDrawnCornerRadius; + } + if (other.what & eClientDrawnShadowsChanged) { + what |= eClientDrawnShadowsChanged; + clientDrawnShadowRadius = other.clientDrawnShadowRadius; + } if (other.what & eBackgroundBlurRadiusChanged) { what |= eBackgroundBlurRadiusChanged; backgroundBlurRadius = other.backgroundBlurRadius; @@ -809,6 +823,8 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const { } CHECK_DIFF(diff, eLayerStackChanged, other, layerStack); CHECK_DIFF(diff, eCornerRadiusChanged, other, cornerRadius); + CHECK_DIFF(diff, eClientDrawnCornerRadiusChanged, other, clientDrawnCornerRadius); + CHECK_DIFF(diff, eClientDrawnShadowsChanged, other, clientDrawnShadowRadius); CHECK_DIFF(diff, eBackgroundBlurRadiusChanged, other, backgroundBlurRadius); if (other.what & eBlurRegionsChanged) diff |= eBlurRegionsChanged; if (other.what & eRelativeLayerChanged) { diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index cabde22c6d..2beeae0201 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1695,6 +1695,29 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCorne return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setClientDrawnCornerRadius( + const sp<SurfaceControl>& sc, float clientDrawnCornerRadius) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eClientDrawnCornerRadiusChanged; + s->clientDrawnCornerRadius = clientDrawnCornerRadius; + return *this; +} + +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setClientDrawnShadowRadius( + const sp<SurfaceControl>& sc, float clientDrawnShadowRadius) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eClientDrawnShadowsChanged; + s->clientDrawnShadowRadius = clientDrawnShadowRadius; + return *this; +} SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundBlurRadius( const sp<SurfaceControl>& sc, int backgroundBlurRadius) { layer_state_t* s = getLayerState(sc); diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 64f191b867..16425c9872 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -231,6 +231,8 @@ struct layer_state_t { eBufferReleaseChannelChanged = 0x40000'00000000, ePictureProfileHandleChanged = 0x80000'00000000, eAppContentPriorityChanged = 0x100000'00000000, + eClientDrawnCornerRadiusChanged = 0x200000'00000000, + eClientDrawnShadowsChanged = 0x400000'00000000, }; layer_state_t(); @@ -251,9 +253,9 @@ struct layer_state_t { // Geometry updates. static constexpr uint64_t GEOMETRY_CHANGES = layer_state_t::eBufferCropChanged | layer_state_t::eBufferTransformChanged | layer_state_t::eCornerRadiusChanged | - layer_state_t::eCropChanged | layer_state_t::eDestinationFrameChanged | - layer_state_t::eMatrixChanged | layer_state_t::ePositionChanged | - layer_state_t::eTransformToDisplayInverseChanged | + layer_state_t::eClientDrawnCornerRadiusChanged | layer_state_t::eCropChanged | + layer_state_t::eDestinationFrameChanged | layer_state_t::eMatrixChanged | + layer_state_t::ePositionChanged | layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eTransparentRegionChanged | layer_state_t::eEdgeExtensionChanged; // Buffer and related updates. @@ -274,8 +276,8 @@ struct layer_state_t { layer_state_t::eColorSpaceAgnosticChanged | layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged | layer_state_t::eDimmingEnabledChanged | layer_state_t::eHdrMetadataChanged | layer_state_t::eShadowRadiusChanged | - layer_state_t::eStretchChanged | layer_state_t::ePictureProfileHandleChanged | - layer_state_t::eAppContentPriorityChanged; + layer_state_t::eClientDrawnShadowsChanged | layer_state_t::eStretchChanged | + layer_state_t::ePictureProfileHandleChanged | layer_state_t::eAppContentPriorityChanged; // Changes which invalidates the layer's visible region in CE. static constexpr uint64_t CONTENT_DIRTY = layer_state_t::CONTENT_CHANGES | @@ -328,6 +330,8 @@ struct layer_state_t { uint8_t reserved; matrix22_t matrix; float cornerRadius; + float clientDrawnCornerRadius; + float clientDrawnShadowRadius; uint32_t backgroundBlurRadius; sp<SurfaceControl> relativeLayerSurfaceControl; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 0f66c8b492..d20b3460b5 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -567,6 +567,15 @@ public: Transaction& setCrop(const sp<SurfaceControl>& sc, const Rect& crop); Transaction& setCrop(const sp<SurfaceControl>& sc, const FloatRect& crop); Transaction& setCornerRadius(const sp<SurfaceControl>& sc, float cornerRadius); + // Sets the client drawn corner radius for the layer. If both a corner radius and a client + // radius are sent to SF, the client radius will be used. This indicates that the corner + // radius is drawn by the client and not SurfaceFlinger. + Transaction& setClientDrawnCornerRadius(const sp<SurfaceControl>& sc, + float clientDrawnCornerRadius); + // Sets the client drawn shadow radius for the layer. This indicates that the shadows + // are drawn by the client and not SurfaceFlinger. + Transaction& setClientDrawnShadowRadius(const sp<SurfaceControl>& sc, + float clientDrawnShadowRadius); Transaction& setBackgroundBlurRadius(const sp<SurfaceControl>& sc, int backgroundBlurRadius); Transaction& setBlurRegions(const sp<SurfaceControl>& sc, diff --git a/libs/ui/include/ui/ShadowSettings.h b/libs/ui/include/ui/ShadowSettings.h index c0b83b8691..06be6dbbf5 100644 --- a/libs/ui/include/ui/ShadowSettings.h +++ b/libs/ui/include/ui/ShadowSettings.h @@ -46,6 +46,9 @@ struct ShadowSettings { // Length of the cast shadow. If length is <= 0.f no shadows will be drawn. float length = 0.f; + // Length of the cast shadow that is drawn by the client. + float clientDrawnLength = 0.f; + // If true fill in the casting layer is translucent and the shadow needs to fill the bounds. // Otherwise the shadow will only be drawn around the edges of the casting layer. bool casterIsTranslucent = false; @@ -55,6 +58,7 @@ static inline bool operator==(const ShadowSettings& lhs, const ShadowSettings& r return lhs.boundaries == rhs.boundaries && lhs.ambientColor == rhs.ambientColor && lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos && lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length && + lhs.clientDrawnLength == rhs.clientDrawnLength && lhs.casterIsTranslucent == rhs.casterIsTranslucent; } diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp index 367132c113..42f3202f20 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp @@ -398,9 +398,13 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate if (forceUpdate || requested.what & layer_state_t::eSidebandStreamChanged) { sidebandStream = requested.sidebandStream; } - if (forceUpdate || requested.what & layer_state_t::eShadowRadiusChanged) { - shadowSettings.length = requested.shadowRadius; + if (forceUpdate || requested.what & layer_state_t::eShadowRadiusChanged || + requested.what & layer_state_t::eClientDrawnShadowsChanged) { + shadowSettings.length = + requested.clientDrawnShadowRadius > 0 ? 0.f : requested.shadowRadius; + shadowSettings.clientDrawnLength = requested.clientDrawnShadowRadius; } + if (forceUpdate || requested.what & layer_state_t::eFrameRateSelectionPriority) { frameRateSelectionPriority = requested.frameRateSelectionPriority; } diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h index b8df3ed748..68b13959a8 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h +++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h @@ -28,16 +28,23 @@ namespace android::surfaceflinger::frontend { struct RoundedCornerState { RoundedCornerState() = default; - RoundedCornerState(const FloatRect& cropRect, const vec2& radius) - : cropRect(cropRect), radius(radius) {} // Rounded rectangle in local layer coordinate space. FloatRect cropRect = FloatRect(); - // Radius of the rounded rectangle. + // Radius of the rounded rectangle for composition vec2 radius; + // Requested radius of the rounded rectangle + vec2 requestedRadius; + // Radius drawn by client for the rounded rectangle + vec2 clientDrawnRadius; + bool hasClientDrawnRadius() const { + return clientDrawnRadius.x > 0.0f && clientDrawnRadius.y > 0.0f; + } + bool hasRequestedRadius() const { return requestedRadius.x > 0.0f && requestedRadius.y > 0.0f; } bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; } bool operator==(RoundedCornerState const& rhs) const { - return cropRect == rhs.cropRect && radius == rhs.radius; + return cropRect == rhs.cropRect && radius == rhs.radius && + clientDrawnRadius == rhs.clientDrawnRadius; } }; diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp index d0dc065353..0be3a1153d 100644 --- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp @@ -27,6 +27,7 @@ #include <common/FlagManager.h> #include <common/trace.h> #include <ftl/small_map.h> +#include <math/vec2.h> #include <ui/DisplayMap.h> #include <ui/FloatRect.h> @@ -934,7 +935,8 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a if (forceUpdate || snapshot.clientChanges & layer_state_t::eCornerRadiusChanged || snapshot.changes.any(RequestedLayerState::Changes::Geometry | - RequestedLayerState::Changes::BufferUsageFlags)) { + RequestedLayerState::Changes::BufferUsageFlags) || + snapshot.clientChanges & layer_state_t::eClientDrawnCornerRadiusChanged) { updateRoundedCorner(snapshot, requested, parentSnapshot, args); } @@ -974,7 +976,7 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, } snapshot.roundedCorner = RoundedCornerState(); RoundedCornerState parentRoundedCorner; - if (parentSnapshot.roundedCorner.hasRoundedCorners()) { + if (parentSnapshot.roundedCorner.hasRequestedRadius()) { parentRoundedCorner = parentSnapshot.roundedCorner; ui::Transform t = snapshot.localTransform.inverse(); parentRoundedCorner.cropRect = t.transform(parentRoundedCorner.cropRect); @@ -983,10 +985,16 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, } FloatRect layerCropRect = snapshot.croppedBufferSize; - const vec2 radius(requested.cornerRadius, requested.cornerRadius); - RoundedCornerState layerSettings(layerCropRect, radius); - const bool layerSettingsValid = layerSettings.hasRoundedCorners() && !layerCropRect.isEmpty(); - const bool parentRoundedCornerValid = parentRoundedCorner.hasRoundedCorners(); + const vec2 requestedRadius(requested.cornerRadius, requested.cornerRadius); + const vec2 clientDrawnRadius(requested.clientDrawnCornerRadius, + requested.clientDrawnCornerRadius); + RoundedCornerState layerSettings; + layerSettings.cropRect = layerCropRect; + layerSettings.requestedRadius = requestedRadius; + layerSettings.clientDrawnRadius = clientDrawnRadius; + + const bool layerSettingsValid = layerSettings.hasRequestedRadius() && !layerCropRect.isEmpty(); + const bool parentRoundedCornerValid = parentRoundedCorner.hasRequestedRadius(); if (layerSettingsValid && parentRoundedCornerValid) { // If the parent and the layer have rounded corner settings, use the parent settings if // the parent crop is entirely inside the layer crop. This has limitations and cause @@ -1004,6 +1012,14 @@ void LayerSnapshotBuilder::updateRoundedCorner(LayerSnapshot& snapshot, } else if (parentRoundedCornerValid) { snapshot.roundedCorner = parentRoundedCorner; } + + if (snapshot.roundedCorner.requestedRadius.x == requested.clientDrawnCornerRadius) { + // If the client drawn radius matches the requested radius, then surfaceflinger + // does not need to draw rounded corners for this layer + snapshot.roundedCorner.radius = vec2(0.f, 0.f); + } else { + snapshot.roundedCorner.radius = snapshot.roundedCorner.requestedRadius; + } } /** diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp index ee9302b937..591ebb2043 100644 --- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp +++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp @@ -107,6 +107,8 @@ RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args) hdrMetadata.validTypes = 0; surfaceDamageRegion = Region::INVALID_REGION; cornerRadius = 0.0f; + clientDrawnCornerRadius = 0.0f; + clientDrawnShadowRadius = 0.0f; backgroundBlurRadius = 0; api = -1; hasColorTransform = false; @@ -348,6 +350,16 @@ void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerSta requestedFrameRate.category = category; changes |= RequestedLayerState::Changes::FrameRate; } + + if (clientState.what & layer_state_t::eClientDrawnCornerRadiusChanged) { + clientDrawnCornerRadius = clientState.clientDrawnCornerRadius; + changes |= RequestedLayerState::Changes::Geometry; + } + + if (clientState.what & layer_state_t::eClientDrawnShadowsChanged) { + clientDrawnShadowRadius = clientState.clientDrawnShadowRadius; + changes |= RequestedLayerState::Changes::Geometry; + } } ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const { @@ -624,6 +636,8 @@ bool RequestedLayerState::isSimpleBufferUpdate(const layer_state_t& s) const { const uint64_t deniedChanges = layer_state_t::ePositionChanged | layer_state_t::eAlphaChanged | layer_state_t::eColorTransformChanged | layer_state_t::eBackgroundColorChanged | layer_state_t::eMatrixChanged | layer_state_t::eCornerRadiusChanged | + layer_state_t::eClientDrawnCornerRadiusChanged | + layer_state_t::eClientDrawnShadowsChanged | layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBufferTransformChanged | layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eCropChanged | layer_state_t::eDataspaceChanged | layer_state_t::eHdrMetadataChanged | diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c234a75693..6af0f59d51 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -516,11 +516,6 @@ private: bool mGetHandleCalled = false; - // The inherited shadow radius after taking into account the layer hierarchy. This is the - // final shadow radius for this layer. If a shadow is specified for a layer, then effective - // shadow radius is the set shadow radius, otherwise its the parent's shadow radius. - float mEffectiveShadowRadius = 0.f; - // Game mode for the layer. Set by WindowManagerShell and recorded by SurfaceFlingerStats. gui::GameMode mGameMode = gui::GameMode::Unsupported; diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp index f247c9f088..151611cad2 100644 --- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp +++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp @@ -585,6 +585,83 @@ TEST_P(LayerTypeAndRenderTypeTransactionTest, ParentCornerRadiusTakesPrecedence) } } +TEST_P(LayerTypeAndRenderTypeTransactionTest, SetClientDrawnCornerRadius) { + sp<SurfaceControl> layer; + const uint8_t size = 64; + const uint8_t testArea = 4; + const float cornerRadius = 20.0f; + ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", size, size)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(layer, Color::RED, size, size)); + + Transaction() + .setClientDrawnCornerRadius(layer, cornerRadius) + .setCornerRadius(layer, cornerRadius) + .setCrop(layer, Rect(size, size)) + .apply(); + + { + const uint8_t bottom = size - 1; + const uint8_t right = size - 1; + auto shot = getScreenCapture(); + // Solid corners + shot->expectColor(Rect(0, 0, testArea, testArea), Color::RED); + shot->expectColor(Rect(size - testArea, 0, right, testArea), Color::RED); + shot->expectColor(Rect(0, bottom - testArea, testArea, bottom), Color::RED); + shot->expectColor(Rect(size - testArea, bottom - testArea, right, bottom), Color::RED); + // Solid center + shot->expectColor(Rect(size / 2 - testArea / 2, size / 2 - testArea / 2, + size / 2 + testArea / 2, size / 2 + testArea / 2), + Color::RED); + } +} + +// Test if ParentCornerRadiusTakesPrecedence if the parent's client drawn corner radius crop +// is fully contained by the child corner radius crop. +TEST_P(LayerTypeAndRenderTypeTransactionTest, ParentCornerRadiusPrecedenceClientDrawnCornerRadius) { + sp<SurfaceControl> parent; + sp<SurfaceControl> child; + const uint32_t size = 64; + const uint32_t parentSize = size * 3; + const Rect parentCrop(size, size, size, size); + const uint32_t testLength = 4; + const float cornerRadius = 20.0f; + ASSERT_NO_FATAL_FAILURE(parent = createLayer("parent", parentSize, parentSize)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(parent, Color::RED, parentSize, parentSize)); + ASSERT_NO_FATAL_FAILURE(child = createLayer("child", size, size)); + ASSERT_NO_FATAL_FAILURE(fillLayerColor(child, Color::GREEN, size, size)); + + Transaction() + .setCornerRadius(parent, cornerRadius) + .setCrop(parent, parentCrop) + .setClientDrawnCornerRadius(parent, cornerRadius) + .reparent(child, parent) + .setPosition(child, size, size) + .apply(true); + + { + const uint32_t top = size; + const uint32_t left = size; + const uint32_t bottom = size * 2; + const uint32_t right = size * 2; + auto shot = getScreenCapture(); + // Corners are RED because parent's client drawn corner radius is actually 0 + // and the child is fully within the parent's crop + // TL + shot->expectColor(Rect(left, top, testLength, testLength), Color::RED); + // TR + shot->expectColor(Rect(right - testLength, top, testLength, testLength), Color::RED); + // BL + shot->expectColor(Rect(left, bottom - testLength, testLength, testLength), Color::RED); + // BR + shot->expectColor(Rect(right - testLength, bottom - testLength, testLength, testLength), + Color::RED); + // Solid center + shot->expectColor(Rect(parentSize / 2 - testLength, parentSize / 2 - testLength, testLength, + testLength), + Color::GREEN); + } +} + TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBackgroundBlurRadiusSimple) { if (!deviceSupportsBlurs()) GTEST_SKIP(); if (!deviceUsesSkiaRenderEngine()) GTEST_SKIP(); diff --git a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h index a894c418f6..ee5d9193ea 100644 --- a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h +++ b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h @@ -485,6 +485,29 @@ public: mLifecycleManager.applyTransactions(transactions); } + void setClientDrawnCornerRadius(uint32_t id, float clientDrawnCornerRadius) { + std::vector<QueuedTransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + + transactions.back().states.front().state.what = + layer_state_t::eClientDrawnCornerRadiusChanged; + transactions.back().states.front().layerId = id; + transactions.back().states.front().state.clientDrawnCornerRadius = clientDrawnCornerRadius; + mLifecycleManager.applyTransactions(transactions); + } + + void setClientDrawnShadowRadius(uint32_t id, float clientDrawnShadowRadius) { + std::vector<QueuedTransactionState> transactions; + transactions.emplace_back(); + transactions.back().states.push_back({}); + + transactions.back().states.front().state.what = layer_state_t::eClientDrawnShadowsChanged; + transactions.back().states.front().layerId = id; + transactions.back().states.front().state.clientDrawnShadowRadius = clientDrawnShadowRadius; + mLifecycleManager.applyTransactions(transactions); + } + void setShadowRadius(uint32_t id, float shadowRadius) { std::vector<QueuedTransactionState> transactions; transactions.emplace_back(); diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp index 1177d1601e..2deb177496 100644 --- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp @@ -1425,6 +1425,59 @@ TEST_F(LayerSnapshotTest, setBufferCrop) { EXPECT_EQ(getSnapshot(1)->geomContentCrop, Rect(0, 0, 100, 100)); } +TEST_F(LayerSnapshotTest, setCornerRadius) { + static constexpr float RADIUS = 123.f; + setRoundedCorners(1, RADIUS); + setCrop(1, Rect{1000, 1000}); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, RADIUS); +} + +TEST_F(LayerSnapshotTest, ignoreCornerRadius) { + static constexpr float RADIUS = 123.f; + setClientDrawnCornerRadius(1, RADIUS); + setRoundedCorners(1, RADIUS); + setCrop(1, Rect{1000, 1000}); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_TRUE(getSnapshot({.id = 1})->roundedCorner.hasClientDrawnRadius()); + EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, 0.f); +} + +TEST_F(LayerSnapshotTest, childInheritsParentIntendedCornerRadius) { + static constexpr float RADIUS = 123.f; + + setClientDrawnCornerRadius(1, RADIUS); + setRoundedCorners(1, RADIUS); + setCrop(1, Rect(1, 1, 999, 999)); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_TRUE(getSnapshot({.id = 1})->roundedCorner.hasClientDrawnRadius()); + EXPECT_TRUE(getSnapshot({.id = 11})->roundedCorner.hasRoundedCorners()); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.radius.x, RADIUS); +} + +TEST_F(LayerSnapshotTest, childIgnoreCornerRadiusOverridesParent) { + static constexpr float RADIUS = 123.f; + + setRoundedCorners(1, RADIUS); + setCrop(1, Rect(1, 1, 999, 999)); + + setClientDrawnCornerRadius(11, RADIUS); + + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_EQ(getSnapshot({.id = 1})->roundedCorner.radius.x, RADIUS); + EXPECT_EQ(getSnapshot({.id = 11})->roundedCorner.radius.x, 0.f); + EXPECT_EQ(getSnapshot({.id = 111})->roundedCorner.radius.x, RADIUS); +} + +TEST_F(LayerSnapshotTest, ignoreShadows) { + static constexpr float SHADOW_RADIUS = 123.f; + setClientDrawnShadowRadius(1, SHADOW_RADIUS); + setShadowRadius(1, SHADOW_RADIUS); + UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); + EXPECT_EQ(getSnapshot({.id = 1})->shadowSettings.length, 0.f); +} + TEST_F(LayerSnapshotTest, setShadowRadius) { static constexpr float SHADOW_RADIUS = 123.f; setShadowRadius(1, SHADOW_RADIUS); |