[Shadows] Add shadow radius to sf layer state (2/n)
Bug: 136561771
Test: atest SurfaceFlinger_Test
Change-Id: Icafe852eaad195163b48b802db2a4b092aa30926
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index b48d471..9b7bab1 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -34,6 +34,7 @@
bool isCreatedFromMainThread() const override { return true; }
protected:
+ bool canDrawShadows() const override { return false; }
sp<Layer> createClone() override;
};
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e19b79b..b51653d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -339,7 +339,8 @@
return bufferScaleTransform.inverse().transform(mBounds);
}
-void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform) {
+void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform,
+ float parentShadowRadius) {
const State& s(getDrawingState());
// Calculate effective layer transform
@@ -362,11 +363,23 @@
mBounds = bounds;
mScreenBounds = mEffectiveTransform.transform(mBounds);
+ // Use the layer's own shadow radius if set. Otherwise get the radius from
+ // parent.
+ if (s.shadowRadius > 0.f) {
+ mEffectiveShadowRadius = s.shadowRadius;
+ } else {
+ mEffectiveShadowRadius = parentShadowRadius;
+ }
+
+ // Shadow radius is passed down to only one layer so if the layer can draw shadows,
+ // don't pass it to its children.
+ const float childShadowRadius = canDrawShadows() ? 0.f : mEffectiveShadowRadius;
+
// Add any buffer scaling to the layer's children.
ui::Transform bufferScaleTransform = getBufferScaleTransform();
for (const sp<Layer>& child : mDrawingChildren) {
child->computeBounds(getBoundsPreScaling(bufferScaleTransform),
- getTransformWithScale(bufferScaleTransform));
+ getTransformWithScale(bufferScaleTransform), childShadowRadius);
}
}
@@ -466,11 +479,13 @@
compositionState.hasProtectedContent = isProtected();
const bool usesRoundedCorners = getRoundedCornerState().radius != 0.f;
+ const bool drawsShadows = mEffectiveShadowRadius != 0.f;
+
compositionState.isOpaque =
isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf;
// Force client composition for special cases known only to the front-end.
- if (isHdrY410() || usesRoundedCorners) {
+ if (isHdrY410() || usesRoundedCorners || drawsShadows) {
compositionState.forceClientComposition = true;
}
}
@@ -1116,6 +1131,18 @@
return p->getLayerStack();
}
+bool Layer::setShadowRadius(float shadowRadius) {
+ if (mCurrentState.shadowRadius == shadowRadius) {
+ return false;
+ }
+
+ mCurrentState.sequence++;
+ mCurrentState.shadowRadius = shadowRadius;
+ mCurrentState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+
void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
ATRACE_CALL();
mCurrentState.barrierLayer_legacy = barrierLayer;
@@ -1410,8 +1437,8 @@
for (const sp<Layer>& child : mDrawingChildren) {
child->mDrawingParent = newParent;
child->computeBounds(newParent->mBounds,
- newParent->getTransformWithScale(
- newParent->getBufferScaleTransform()));
+ newParent->getTransformWithScale(newParent->getBufferScaleTransform()),
+ newParent->mEffectiveShadowRadius);
}
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index fdac98f..648be3e 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -216,6 +216,7 @@
std::deque<sp<CallbackHandle>> callbackHandles;
bool colorSpaceAgnostic;
nsecs_t desiredPresentTime = -1;
+ float shadowRadius;
};
explicit Layer(const LayerCreationArgs& args);
@@ -329,6 +330,7 @@
};
virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace);
virtual bool setColorSpaceAgnostic(const bool agnostic);
+ bool setShadowRadius(float shadowRadius);
virtual ui::Dataspace getDataSpace() const { return ui::Dataspace::UNKNOWN; }
@@ -362,7 +364,7 @@
FloatRect getBounds() const;
// Compute bounds for the layer and cache the results.
- void computeBounds(FloatRect parentBounds, ui::Transform parentTransform);
+ void computeBounds(FloatRect parentBounds, ui::Transform parentTransform, float shadowRadius);
// Returns the buffer scale transform if a scaling mode is set.
ui::Transform getBufferScaleTransform() const;
@@ -942,6 +944,14 @@
// this layer will update it's buffer. When mClonedFrom updates it's drawing state, children,
// and relatives, this layer will update as well.
wp<Layer> mClonedFrom;
+
+ // 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;
+
+ // Returns true if the layer can draw shadows on its border.
+ virtual bool canDrawShadows() const { return true; }
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1acb2da..953cb99 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2011,7 +2011,8 @@
continue;
}
- layer->computeBounds(displayDevice->getViewport().toFloatRect(), ui::Transform());
+ layer->computeBounds(displayDevice->getViewport().toFloatRect(), ui::Transform(),
+ 0.f /* shadowRadius */);
}
}
}
@@ -3335,6 +3336,9 @@
flags |= eTraversalNeeded;
}
}
+ if (what & layer_state_t::eShadowRadiusChanged) {
+ if (layer->setShadowRadius(s.shadowRadius)) flags |= eTraversalNeeded;
+ }
// This has to happen after we reparent children because when we reparent to null we remove
// child layers from current state and remove its relative z. If the children are reparented in
// the same transaction, then we have to make sure we reparent the children first so we do not
@@ -5010,7 +5014,8 @@
const Rect& drawingBounds)
: oldParent(oldParent), newParent(newParent) {
// Compute and cache the bounds for the new parent layer.
- newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform());
+ newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(),
+ 0.f /* shadowRadius */);
oldParent->setChildrenDrawingParent(newParent);
}
~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); }
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 60da70f..143a7a0 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -803,7 +803,7 @@
layerDrawingState.active.h = 100;
layerDrawingState.color = half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
LayerProperties::COLOR[2], LayerProperties::COLOR[3]);
- layer->computeBounds(FloatRect(0, 0, 100, 100), ui::Transform());
+ layer->computeBounds(FloatRect(0, 0, 100, 100), ui::Transform(), 0.f /* shadowRadius */);
return layer;
}