diff options
-rw-r--r-- | libs/gui/LayerState.cpp | 6 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 12 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 8 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/ContainerLayer.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 37 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 12 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/CompositionTest.cpp | 2 |
9 files changed, 77 insertions, 11 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index e004e9584c..e392bc597f 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -406,6 +406,12 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eMetadataChanged; metadata.merge(other.metadata); } + + if (other.what & eShadowRadiusChanged) { + what |= eShadowRadiusChanged; + shadowRadius = other.shadowRadius; + } + if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIu64 " what=0x%" PRIu64, diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index e9079efd29..14f47c3509 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1335,6 +1335,18 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setGeome return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShadowRadius( + const sp<SurfaceControl>& sc, float shadowRadius) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eShadowRadiusChanged; + s->shadowRadius = shadowRadius; + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) { diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index a49ed525b6..c2b5119242 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -72,7 +72,7 @@ struct layer_state_t { eCropChanged_legacy = 0x00000100, eDeferTransaction_legacy = 0x00000200, eOverrideScalingModeChanged = 0x00000400, - // AVAILABLE 0x00000800, + eShadowRadiusChanged = 0x00000800, eReparentChildren = 0x00001000, eDetachChildren = 0x00002000, eRelativeLayerChanged = 0x00004000, @@ -126,7 +126,8 @@ struct layer_state_t { colorTransform(mat4()), bgColorAlpha(0), bgColorDataspace(ui::Dataspace::UNKNOWN), - colorSpaceAgnostic(false) { + colorSpaceAgnostic(false), + shadowRadius(0.0f) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -204,6 +205,9 @@ struct layer_state_t { bool colorSpaceAgnostic; std::vector<ListenerCallbacks> listeners; + + // Draws a shadow around the surface. + float shadowRadius; }; struct ComposerState { diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 08f4e9e9d3..a140142b37 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -474,6 +474,7 @@ public: Transaction& setGeometry(const sp<SurfaceControl>& sc, const Rect& source, const Rect& dst, int transform); + Transaction& setShadowRadius(const sp<SurfaceControl>& sc, float cornerRadius); status_t setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h index b48d471bde..9b7bab1e1d 100644 --- a/services/surfaceflinger/ContainerLayer.h +++ b/services/surfaceflinger/ContainerLayer.h @@ -34,6 +34,7 @@ public: 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 e19b79b7c5..b51653deb8 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -339,7 +339,8 @@ FloatRect Layer::getBoundsPreScaling(const ui::Transform& bufferScaleTransform) 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 @@ void Layer::computeBounds(FloatRect parentBounds, ui::Transform parentTransform) 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 @@ void Layer::latchPerFrameState(compositionengine::LayerFECompositionState& compo 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 @@ uint32_t Layer::getLayerStack() const { 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 @@ void Layer::setChildrenDrawingParent(const sp<Layer>& newParent) { 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 fdac98f317..648be3e182 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -216,6 +216,7 @@ public: std::deque<sp<CallbackHandle>> callbackHandles; bool colorSpaceAgnostic; nsecs_t desiredPresentTime = -1; + float shadowRadius; }; explicit Layer(const LayerCreationArgs& args); @@ -329,6 +330,7 @@ public: }; 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 @@ public: 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 @@ private: // 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 1acb2da051..953cb99c13 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2011,7 +2011,8 @@ void SurfaceFlinger::computeLayerBounds() { continue; } - layer->computeBounds(displayDevice->getViewport().toFloatRect(), ui::Transform()); + layer->computeBounds(displayDevice->getViewport().toFloatRect(), ui::Transform(), + 0.f /* shadowRadius */); } } } @@ -3335,6 +3336,9 @@ uint32_t SurfaceFlinger::setClientStateLocked( 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 @@ status_t SurfaceFlinger::captureLayers( 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 60da70fd25..143a7a0fb5 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -803,7 +803,7 @@ struct BaseLayerVariant { 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; } |