surfaceflinger: Add clientDrawnCornerRadius and clientDrawnShadowLength layer properties
Modify RoundedCornerState and ShadowSettings to account for client drawn corners and shadows. When equal to the requested values, SurfaceFlinger will not draw corners and shadows for the layer.
Bug: 375624570
Flag: com.android.window.flags.ignore_corner_radius_and_shadows
Test: atest SurfaceFlinger_test; manual test - PIP, freeform window, recents, app launch
Change-Id: Idde115b51a253a34cfadfbd1ff6c7b15c44518ef
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index c1a03fc..44aac9b 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -66,6 +66,8 @@
mask(0),
reserved(0),
cornerRadius(0.0f),
+ clientDrawnCornerRadius(0.0f),
+ clientDrawnShadowRadius(0.0f),
backgroundBlurRadius(0),
color(0),
bufferTransform(0),
@@ -140,6 +142,8 @@
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 @@
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 @@
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 @@
}
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 cabde22..2beeae0 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1695,6 +1695,29 @@
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 64f191b..16425c9 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -231,6 +231,8 @@
eBufferReleaseChannelChanged = 0x40000'00000000,
ePictureProfileHandleChanged = 0x80000'00000000,
eAppContentPriorityChanged = 0x100000'00000000,
+ eClientDrawnCornerRadiusChanged = 0x200000'00000000,
+ eClientDrawnShadowsChanged = 0x400000'00000000,
};
layer_state_t();
@@ -251,9 +253,9 @@
// 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 @@
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 @@
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 0f66c8b..d20b346 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -567,6 +567,15 @@
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 c0b83b8..06be6db 100644
--- a/libs/ui/include/ui/ShadowSettings.h
+++ b/libs/ui/include/ui/ShadowSettings.h
@@ -46,6 +46,9 @@
// 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 @@
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;
}