Loading services/surfaceflinger/BufferLayer.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -295,7 +295,7 @@ bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId, const CompositorTiming& compositorTiming) { // mFrameLatencyNeeded is true when a new frame was latched for the // composition. if (!mFrameLatencyNeeded) return false; if (!mBufferInfo.mFrameLatencyNeeded) return false; // Update mFrameEventHistory. { Loading Loading @@ -337,7 +337,7 @@ bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId, } mFrameTracker.advanceFrame(); mFrameLatencyNeeded = false; mBufferInfo.mFrameLatencyNeeded = false; return true; } Loading Loading @@ -401,7 +401,7 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, gatherBufferInfo(); mRefreshPending = true; mFrameLatencyNeeded = true; mBufferInfo.mFrameLatencyNeeded = true; if (oldBufferInfo.mBuffer == nullptr) { // the first time we receive a buffer, we need to trigger a // geometry invalidation. Loading Loading @@ -735,6 +735,35 @@ void BufferLayer::setInitialValuesForClone(const sp<Layer>& clonedFrom) { mPremultipliedAlpha = bufferClonedFrom->mPremultipliedAlpha; mPotentialCursor = bufferClonedFrom->mPotentialCursor; mProtectedByApp = bufferClonedFrom->mProtectedByApp; updateCloneBufferInfo(); } void BufferLayer::updateCloneBufferInfo() { if (!isClone() || !isClonedFromAlive()) { return; } sp<BufferLayer> clonedFrom = static_cast<BufferLayer*>(getClonedFrom().get()); mBufferInfo = clonedFrom->mBufferInfo; mSidebandStream = clonedFrom->mSidebandStream; surfaceDamageRegion = clonedFrom->surfaceDamageRegion; mCurrentFrameNumber = clonedFrom->mCurrentFrameNumber.load(); mPreviousFrameNumber = clonedFrom->mPreviousFrameNumber; // After buffer info is updated, the drawingState from the real layer needs to be copied into // the cloned. This is because some properties of drawingState can change when latchBuffer is // called. However, copying the drawingState would also overwrite the cloned layer's relatives. // Therefore, temporarily store the relatives so they can be set in the cloned drawingState // again. wp<Layer> tmpZOrderRelativeOf = mDrawingState.zOrderRelativeOf; SortedVector<wp<Layer>> tmpZOrderRelatives = mDrawingState.zOrderRelatives; mDrawingState = clonedFrom->mDrawingState; // TODO: (b/140756730) Ignore input for now since InputDispatcher doesn't support multiple // InputWindows per client token yet. mDrawingState.inputInfo.token = nullptr; mDrawingState.zOrderRelativeOf = tmpZOrderRelativeOf; mDrawingState.zOrderRelatives = tmpZOrderRelatives; } } // namespace android Loading services/surfaceflinger/BufferLayer.h +4 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,8 @@ protected: sp<GraphicBuffer> mBuffer; int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT}; bool mFrameLatencyNeeded{false}; }; BufferInfo mBufferInfo; Loading Loading @@ -195,6 +197,8 @@ protected: ui::Dataspace translateDataspace(ui::Dataspace dataspace); void setInitialValuesForClone(const sp<Layer>& clonedFrom); void updateCloneBufferInfo() override; uint64_t mPreviousFrameNumber = 0; private: // Returns true if this layer requires filtering Loading services/surfaceflinger/BufferQueueLayer.h +0 −2 Original line number Diff line number Diff line Loading @@ -111,8 +111,6 @@ private: PixelFormat mFormat{PIXEL_FORMAT_NONE}; // Only accessed on the main thread. uint64_t mPreviousFrameNumber{0}; bool mUpdateTexImageFailed{false}; uint64_t mPreviousBufferId = 0; Loading services/surfaceflinger/BufferStateLayer.h +0 −1 Original line number Diff line number Diff line Loading @@ -143,7 +143,6 @@ private: sp<Fence> mPreviousReleaseFence; uint64_t mPreviousBufferId = 0; uint64_t mPreviousFrameNumber = 0; uint64_t mPreviousReleasedFrameNumber = 0; mutable bool mCurrentStateModified = false; Loading services/surfaceflinger/Layer.cpp +112 −0 Original line number Diff line number Diff line Loading @@ -2034,6 +2034,118 @@ void Layer::setInitialValuesForClone(const sp<Layer>& clonedFrom) { // InputWindows per client token yet. mDrawingState.inputInfo.token = nullptr; } void Layer::updateMirrorInfo() { if (mClonedChild == nullptr || !mClonedChild->isClonedFromAlive()) { // If mClonedChild is null, there is nothing to mirror. If isClonedFromAlive returns false, // it means that there is a clone, but the layer it was cloned from has been destroyed. In // that case, we want to delete the reference to the clone since we want it to get // destroyed. The root, this layer, will still be around since the client can continue // to hold a reference, but no cloned layers will be displayed. mClonedChild = nullptr; return; } std::map<sp<Layer>, sp<Layer>> clonedLayersMap; // If the real layer exists and is in current state, add the clone as a child of the root. // There's no need to remove from drawingState when the layer is offscreen since currentState is // copied to drawingState for the root layer. So the clonedChild is always removed from // drawingState and then needs to be added back each traversal. if (!mClonedChild->getClonedFrom()->isRemovedFromCurrentState()) { addChildToDrawing(mClonedChild); } mClonedChild->updateClonedDrawingState(clonedLayersMap); mClonedChild->updateClonedChildren(this, clonedLayersMap); mClonedChild->updateClonedRelatives(clonedLayersMap); } void Layer::updateClonedDrawingState(std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) { // If the layer the clone was cloned from is alive, copy the content of the drawingState // to the clone. If the real layer is no longer alive, continue traversing the children // since we may be able to pull out other children that are still alive. if (isClonedFromAlive()) { sp<Layer> clonedFrom = getClonedFrom(); mDrawingState = clonedFrom->mDrawingState; // TODO: (b/140756730) Ignore input for now since InputDispatcher doesn't support multiple // InputWindows per client token yet. mDrawingState.inputInfo.token = nullptr; clonedLayersMap.emplace(clonedFrom, this); } // The clone layer may have children in drawingState since they may have been created and // added from a previous request to updateMirorInfo. This is to ensure we don't recreate clones // that already exist, since we can just re-use them. // The drawingChildren will not get overwritten by the currentChildren since the clones are // not updated in the regular traversal. They are skipped since the root will lose the // reference to them when it copies its currentChildren to drawing. for (sp<Layer>& child : mDrawingChildren) { child->updateClonedDrawingState(clonedLayersMap); } } void Layer::updateClonedChildren(const sp<Layer>& mirrorRoot, std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) { mDrawingChildren.clear(); if (!isClonedFromAlive()) { return; } sp<Layer> clonedFrom = getClonedFrom(); for (sp<Layer>& child : clonedFrom->mDrawingChildren) { if (child == mirrorRoot) { // This is to avoid cyclical mirroring. continue; } sp<Layer> clonedChild = clonedLayersMap[child]; if (clonedChild == nullptr) { clonedChild = child->createClone(); clonedLayersMap[child] = clonedChild; } addChildToDrawing(clonedChild); clonedChild->updateClonedChildren(mirrorRoot, clonedLayersMap); } } void Layer::updateClonedRelatives(std::map<sp<Layer>, sp<Layer>> clonedLayersMap) { mDrawingState.zOrderRelativeOf = nullptr; mDrawingState.zOrderRelatives.clear(); if (!isClonedFromAlive()) { return; } sp<Layer> clonedFrom = getClonedFrom(); for (wp<Layer>& relativeWeak : clonedFrom->mDrawingState.zOrderRelatives) { sp<Layer> relative = relativeWeak.promote(); auto clonedRelative = clonedLayersMap[relative]; if (clonedRelative != nullptr) { mDrawingState.zOrderRelatives.add(clonedRelative); } } // Check if the relativeLayer for the real layer is part of the cloned hierarchy. // It's possible that the layer it's relative to is outside the requested cloned hierarchy. // In that case, we treat the layer as if the relativeOf has been removed. This way, it will // still traverse the children, but the layer with the missing relativeOf will not be shown // on screen. sp<Layer> relativeOf = clonedFrom->mDrawingState.zOrderRelativeOf.promote(); sp<Layer> clonedRelativeOf = clonedLayersMap[relativeOf]; if (clonedRelativeOf != nullptr) { mDrawingState.zOrderRelativeOf = clonedRelativeOf; } for (sp<Layer>& child : mDrawingChildren) { child->updateClonedRelatives(clonedLayersMap); } } void Layer::addChildToDrawing(const sp<Layer>& layer) { mDrawingChildren.add(layer); layer->mDrawingParent = this; } // --------------------------------------------------------------------------- }; // namespace android Loading Loading
services/surfaceflinger/BufferLayer.cpp +32 −3 Original line number Diff line number Diff line Loading @@ -295,7 +295,7 @@ bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId, const CompositorTiming& compositorTiming) { // mFrameLatencyNeeded is true when a new frame was latched for the // composition. if (!mFrameLatencyNeeded) return false; if (!mBufferInfo.mFrameLatencyNeeded) return false; // Update mFrameEventHistory. { Loading Loading @@ -337,7 +337,7 @@ bool BufferLayer::onPostComposition(const std::optional<DisplayId>& displayId, } mFrameTracker.advanceFrame(); mFrameLatencyNeeded = false; mBufferInfo.mFrameLatencyNeeded = false; return true; } Loading Loading @@ -401,7 +401,7 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, gatherBufferInfo(); mRefreshPending = true; mFrameLatencyNeeded = true; mBufferInfo.mFrameLatencyNeeded = true; if (oldBufferInfo.mBuffer == nullptr) { // the first time we receive a buffer, we need to trigger a // geometry invalidation. Loading Loading @@ -735,6 +735,35 @@ void BufferLayer::setInitialValuesForClone(const sp<Layer>& clonedFrom) { mPremultipliedAlpha = bufferClonedFrom->mPremultipliedAlpha; mPotentialCursor = bufferClonedFrom->mPotentialCursor; mProtectedByApp = bufferClonedFrom->mProtectedByApp; updateCloneBufferInfo(); } void BufferLayer::updateCloneBufferInfo() { if (!isClone() || !isClonedFromAlive()) { return; } sp<BufferLayer> clonedFrom = static_cast<BufferLayer*>(getClonedFrom().get()); mBufferInfo = clonedFrom->mBufferInfo; mSidebandStream = clonedFrom->mSidebandStream; surfaceDamageRegion = clonedFrom->surfaceDamageRegion; mCurrentFrameNumber = clonedFrom->mCurrentFrameNumber.load(); mPreviousFrameNumber = clonedFrom->mPreviousFrameNumber; // After buffer info is updated, the drawingState from the real layer needs to be copied into // the cloned. This is because some properties of drawingState can change when latchBuffer is // called. However, copying the drawingState would also overwrite the cloned layer's relatives. // Therefore, temporarily store the relatives so they can be set in the cloned drawingState // again. wp<Layer> tmpZOrderRelativeOf = mDrawingState.zOrderRelativeOf; SortedVector<wp<Layer>> tmpZOrderRelatives = mDrawingState.zOrderRelatives; mDrawingState = clonedFrom->mDrawingState; // TODO: (b/140756730) Ignore input for now since InputDispatcher doesn't support multiple // InputWindows per client token yet. mDrawingState.inputInfo.token = nullptr; mDrawingState.zOrderRelativeOf = tmpZOrderRelativeOf; mDrawingState.zOrderRelatives = tmpZOrderRelatives; } } // namespace android Loading
services/surfaceflinger/BufferLayer.h +4 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,8 @@ protected: sp<GraphicBuffer> mBuffer; int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT}; bool mFrameLatencyNeeded{false}; }; BufferInfo mBufferInfo; Loading Loading @@ -195,6 +197,8 @@ protected: ui::Dataspace translateDataspace(ui::Dataspace dataspace); void setInitialValuesForClone(const sp<Layer>& clonedFrom); void updateCloneBufferInfo() override; uint64_t mPreviousFrameNumber = 0; private: // Returns true if this layer requires filtering Loading
services/surfaceflinger/BufferQueueLayer.h +0 −2 Original line number Diff line number Diff line Loading @@ -111,8 +111,6 @@ private: PixelFormat mFormat{PIXEL_FORMAT_NONE}; // Only accessed on the main thread. uint64_t mPreviousFrameNumber{0}; bool mUpdateTexImageFailed{false}; uint64_t mPreviousBufferId = 0; Loading
services/surfaceflinger/BufferStateLayer.h +0 −1 Original line number Diff line number Diff line Loading @@ -143,7 +143,6 @@ private: sp<Fence> mPreviousReleaseFence; uint64_t mPreviousBufferId = 0; uint64_t mPreviousFrameNumber = 0; uint64_t mPreviousReleasedFrameNumber = 0; mutable bool mCurrentStateModified = false; Loading
services/surfaceflinger/Layer.cpp +112 −0 Original line number Diff line number Diff line Loading @@ -2034,6 +2034,118 @@ void Layer::setInitialValuesForClone(const sp<Layer>& clonedFrom) { // InputWindows per client token yet. mDrawingState.inputInfo.token = nullptr; } void Layer::updateMirrorInfo() { if (mClonedChild == nullptr || !mClonedChild->isClonedFromAlive()) { // If mClonedChild is null, there is nothing to mirror. If isClonedFromAlive returns false, // it means that there is a clone, but the layer it was cloned from has been destroyed. In // that case, we want to delete the reference to the clone since we want it to get // destroyed. The root, this layer, will still be around since the client can continue // to hold a reference, but no cloned layers will be displayed. mClonedChild = nullptr; return; } std::map<sp<Layer>, sp<Layer>> clonedLayersMap; // If the real layer exists and is in current state, add the clone as a child of the root. // There's no need to remove from drawingState when the layer is offscreen since currentState is // copied to drawingState for the root layer. So the clonedChild is always removed from // drawingState and then needs to be added back each traversal. if (!mClonedChild->getClonedFrom()->isRemovedFromCurrentState()) { addChildToDrawing(mClonedChild); } mClonedChild->updateClonedDrawingState(clonedLayersMap); mClonedChild->updateClonedChildren(this, clonedLayersMap); mClonedChild->updateClonedRelatives(clonedLayersMap); } void Layer::updateClonedDrawingState(std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) { // If the layer the clone was cloned from is alive, copy the content of the drawingState // to the clone. If the real layer is no longer alive, continue traversing the children // since we may be able to pull out other children that are still alive. if (isClonedFromAlive()) { sp<Layer> clonedFrom = getClonedFrom(); mDrawingState = clonedFrom->mDrawingState; // TODO: (b/140756730) Ignore input for now since InputDispatcher doesn't support multiple // InputWindows per client token yet. mDrawingState.inputInfo.token = nullptr; clonedLayersMap.emplace(clonedFrom, this); } // The clone layer may have children in drawingState since they may have been created and // added from a previous request to updateMirorInfo. This is to ensure we don't recreate clones // that already exist, since we can just re-use them. // The drawingChildren will not get overwritten by the currentChildren since the clones are // not updated in the regular traversal. They are skipped since the root will lose the // reference to them when it copies its currentChildren to drawing. for (sp<Layer>& child : mDrawingChildren) { child->updateClonedDrawingState(clonedLayersMap); } } void Layer::updateClonedChildren(const sp<Layer>& mirrorRoot, std::map<sp<Layer>, sp<Layer>>& clonedLayersMap) { mDrawingChildren.clear(); if (!isClonedFromAlive()) { return; } sp<Layer> clonedFrom = getClonedFrom(); for (sp<Layer>& child : clonedFrom->mDrawingChildren) { if (child == mirrorRoot) { // This is to avoid cyclical mirroring. continue; } sp<Layer> clonedChild = clonedLayersMap[child]; if (clonedChild == nullptr) { clonedChild = child->createClone(); clonedLayersMap[child] = clonedChild; } addChildToDrawing(clonedChild); clonedChild->updateClonedChildren(mirrorRoot, clonedLayersMap); } } void Layer::updateClonedRelatives(std::map<sp<Layer>, sp<Layer>> clonedLayersMap) { mDrawingState.zOrderRelativeOf = nullptr; mDrawingState.zOrderRelatives.clear(); if (!isClonedFromAlive()) { return; } sp<Layer> clonedFrom = getClonedFrom(); for (wp<Layer>& relativeWeak : clonedFrom->mDrawingState.zOrderRelatives) { sp<Layer> relative = relativeWeak.promote(); auto clonedRelative = clonedLayersMap[relative]; if (clonedRelative != nullptr) { mDrawingState.zOrderRelatives.add(clonedRelative); } } // Check if the relativeLayer for the real layer is part of the cloned hierarchy. // It's possible that the layer it's relative to is outside the requested cloned hierarchy. // In that case, we treat the layer as if the relativeOf has been removed. This way, it will // still traverse the children, but the layer with the missing relativeOf will not be shown // on screen. sp<Layer> relativeOf = clonedFrom->mDrawingState.zOrderRelativeOf.promote(); sp<Layer> clonedRelativeOf = clonedLayersMap[relativeOf]; if (clonedRelativeOf != nullptr) { mDrawingState.zOrderRelativeOf = clonedRelativeOf; } for (sp<Layer>& child : mDrawingChildren) { child->updateClonedRelatives(clonedLayersMap); } } void Layer::addChildToDrawing(const sp<Layer>& layer) { mDrawingChildren.add(layer); layer->mDrawingParent = this; } // --------------------------------------------------------------------------- }; // namespace android Loading