Loading libs/gui/ISurfaceComposer.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -1140,8 +1140,7 @@ public: return err; } err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply, IBinder::FLAG_ONEWAY); err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply); if (err != NO_ERROR) { ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err); return err; Loading services/surfaceflinger/Layer.cpp +75 −10 Original line number Diff line number Diff line Loading @@ -116,6 +116,7 @@ Layer::Layer(const LayerCreationArgs& args) mCurrentState.frameRateSelectionPriority = PRIORITY_UNSET; mCurrentState.metadata = args.metadata; mCurrentState.shadowRadius = 0.f; mCurrentState.treeHasFrameRateVote = false; // drawing state & current state are identical mDrawingState = mCurrentState; Loading Loading @@ -1334,6 +1335,44 @@ bool Layer::setShadowRadius(float shadowRadius) { return true; } void Layer::updateTreeHasFrameRateVote() { const auto traverseTree = [&](const LayerVector::Visitor& visitor) { auto parent = getParent(); while (parent) { visitor(parent.get()); parent = parent->getParent(); } traverse(LayerVector::StateSet::Current, visitor); }; // update parents and children about the vote // First traverse the tree and count how many layers has votes int layersWithVote = 0; traverseTree([&layersWithVote](Layer* layer) { if (layer->mCurrentState.frameRate.rate > 0 || layer->mCurrentState.frameRate.type == FrameRateCompatibility::NoVote) { layersWithVote++; } }); // Now update the other layers bool transactionNeeded = false; traverseTree([layersWithVote, &transactionNeeded](Layer* layer) { if (layer->mCurrentState.treeHasFrameRateVote != layersWithVote > 0) { layer->mCurrentState.sequence++; layer->mCurrentState.treeHasFrameRateVote = layersWithVote > 0; layer->mCurrentState.modified = true; layer->setTransactionFlags(eTransactionNeeded); transactionNeeded = true; } }); if (transactionNeeded) { mFlinger->setTransactionFlags(eTraversalNeeded); } } bool Layer::setFrameRate(FrameRate frameRate) { if (!mFlinger->useFrameRateApi) { return false; Loading @@ -1345,12 +1384,26 @@ bool Layer::setFrameRate(FrameRate frameRate) { mCurrentState.sequence++; mCurrentState.frameRate = frameRate; mCurrentState.modified = true; updateTreeHasFrameRateVote(); setTransactionFlags(eTransactionNeeded); return true; } Layer::FrameRate Layer::getFrameRate() const { return getDrawingState().frameRate; Layer::FrameRate Layer::getFrameRateForLayerTree() const { const auto frameRate = getDrawingState().frameRate; if (frameRate.rate > 0 || frameRate.type == FrameRateCompatibility::NoVote) { return frameRate; } // This layer doesn't have a frame rate. If one of its ancestors or successors // have a vote, return a NoVote for ancestors/successors to set the vote if (getDrawingState().treeHasFrameRateVote) { return {0, FrameRateCompatibility::NoVote}; } return frameRate; } void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) { Loading Loading @@ -1608,6 +1661,7 @@ void Layer::addChild(const sp<Layer>& layer) { mCurrentChildren.add(layer); layer->setParent(this); updateTreeHasFrameRateVote(); } ssize_t Layer::removeChild(const sp<Layer>& layer) { Loading @@ -1615,7 +1669,24 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) { setTransactionFlags(eTransactionNeeded); layer->setParent(nullptr); return mCurrentChildren.remove(layer); const auto removeResult = mCurrentChildren.remove(layer); updateTreeHasFrameRateVote(); layer->updateTreeHasFrameRateVote(); return removeResult; } void Layer::reparentChildren(const sp<Layer>& newParent) { if (attachChildren()) { setTransactionFlags(eTransactionNeeded); } for (const sp<Layer>& child : mCurrentChildren) { newParent->addChild(child); } mCurrentChildren.clear(); updateTreeHasFrameRateVote(); } bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) { Loading @@ -1631,13 +1702,7 @@ bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) { return false; } if (attachChildren()) { setTransactionFlags(eTransactionNeeded); } for (const sp<Layer>& child : mCurrentChildren) { newParent->addChild(child); } mCurrentChildren.clear(); reparentChildren(newParent); return true; } Loading services/surfaceflinger/Layer.h +9 −2 Original line number Diff line number Diff line Loading @@ -259,6 +259,9 @@ public: int32_t frameRateSelectionPriority; FrameRate frameRate; // Indicates whether parents / children of this layer had set FrameRate bool treeHasFrameRateVote; }; explicit Layer(const LayerCreationArgs& args); Loading Loading @@ -344,7 +347,8 @@ public: virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber); virtual bool setOverrideScalingMode(int32_t overrideScalingMode); virtual bool setMetadata(const LayerMetadata& data); virtual bool reparentChildren(const sp<IBinder>& layer); bool reparentChildren(const sp<IBinder>& newParentHandle); void reparentChildren(const sp<Layer>& newParent); virtual void setChildrenDrawingParent(const sp<Layer>& layer); virtual bool reparent(const sp<IBinder>& newParentHandle); virtual bool detachChildren(); Loading Loading @@ -801,7 +805,7 @@ public: Rect getCroppedBufferSize(const Layer::State& s) const; bool setFrameRate(FrameRate frameRate); virtual FrameRate getFrameRate() const; virtual FrameRate getFrameRateForLayerTree() const; protected: // constant Loading Loading @@ -830,6 +834,7 @@ protected: // For unit tests friend class TestableSurfaceFlinger; friend class RefreshRateSelectionTest; friend class SetFrameRateTest; virtual void commitTransaction(const State& stateToCommit); Loading Loading @@ -1017,6 +1022,8 @@ private: LayerVector makeChildrenTraversalList(LayerVector::StateSet stateSet, const std::vector<Layer*>& layersInTree); void updateTreeHasFrameRateVote(); // Cached properties computed from drawing state // Effective transform taking into account parent transforms and any parent scaling. ui::Transform mEffectiveTransform; Loading services/surfaceflinger/Scheduler/LayerHistory.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ namespace android::scheduler::impl { namespace { bool isLayerActive(const Layer& layer, const LayerInfo& info, nsecs_t threshold) { if (layer.getFrameRate().rate > 0) { if (layer.getFrameRateForLayerTree().rate > 0) { return layer.isVisible(); } return layer.isVisible() && info.getLastUpdatedTime() >= threshold; Loading Loading @@ -109,7 +109,7 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) { // Only use the layer if the reference still exists. if (layer || CC_UNLIKELY(mTraceEnabled)) { // Check if frame rate was set on layer. const auto frameRate = layer->getFrameRate(); const auto frameRate = layer->getFrameRateForLayerTree(); if (frameRate.rate > 0.f) { const auto voteType = [&]() { switch (frameRate.type) { Loading services/surfaceflinger/Scheduler/LayerHistoryV2.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ namespace android::scheduler::impl { namespace { bool isLayerActive(const Layer& layer, const LayerInfoV2& info, nsecs_t threshold) { if (layer.getFrameRate().rate > 0) { if (layer.getFrameRateForLayerTree().rate > 0) { return layer.isVisible(); } return layer.isVisible() && info.getLastUpdatedTime() >= threshold; Loading Loading @@ -166,7 +166,7 @@ void LayerHistoryV2::partitionLayers(nsecs_t now) { if (const auto layer = weak.promote(); layer && isLayerActive(*layer, *info, threshold)) { i++; // Set layer vote if set const auto frameRate = layer->getFrameRate(); const auto frameRate = layer->getFrameRateForLayerTree(); const auto voteType = [&]() { switch (frameRate.type) { case Layer::FrameRateCompatibility::Default: Loading Loading
libs/gui/ISurfaceComposer.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -1140,8 +1140,7 @@ public: return err; } err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply, IBinder::FLAG_ONEWAY); err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply); if (err != NO_ERROR) { ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err); return err; Loading
services/surfaceflinger/Layer.cpp +75 −10 Original line number Diff line number Diff line Loading @@ -116,6 +116,7 @@ Layer::Layer(const LayerCreationArgs& args) mCurrentState.frameRateSelectionPriority = PRIORITY_UNSET; mCurrentState.metadata = args.metadata; mCurrentState.shadowRadius = 0.f; mCurrentState.treeHasFrameRateVote = false; // drawing state & current state are identical mDrawingState = mCurrentState; Loading Loading @@ -1334,6 +1335,44 @@ bool Layer::setShadowRadius(float shadowRadius) { return true; } void Layer::updateTreeHasFrameRateVote() { const auto traverseTree = [&](const LayerVector::Visitor& visitor) { auto parent = getParent(); while (parent) { visitor(parent.get()); parent = parent->getParent(); } traverse(LayerVector::StateSet::Current, visitor); }; // update parents and children about the vote // First traverse the tree and count how many layers has votes int layersWithVote = 0; traverseTree([&layersWithVote](Layer* layer) { if (layer->mCurrentState.frameRate.rate > 0 || layer->mCurrentState.frameRate.type == FrameRateCompatibility::NoVote) { layersWithVote++; } }); // Now update the other layers bool transactionNeeded = false; traverseTree([layersWithVote, &transactionNeeded](Layer* layer) { if (layer->mCurrentState.treeHasFrameRateVote != layersWithVote > 0) { layer->mCurrentState.sequence++; layer->mCurrentState.treeHasFrameRateVote = layersWithVote > 0; layer->mCurrentState.modified = true; layer->setTransactionFlags(eTransactionNeeded); transactionNeeded = true; } }); if (transactionNeeded) { mFlinger->setTransactionFlags(eTraversalNeeded); } } bool Layer::setFrameRate(FrameRate frameRate) { if (!mFlinger->useFrameRateApi) { return false; Loading @@ -1345,12 +1384,26 @@ bool Layer::setFrameRate(FrameRate frameRate) { mCurrentState.sequence++; mCurrentState.frameRate = frameRate; mCurrentState.modified = true; updateTreeHasFrameRateVote(); setTransactionFlags(eTransactionNeeded); return true; } Layer::FrameRate Layer::getFrameRate() const { return getDrawingState().frameRate; Layer::FrameRate Layer::getFrameRateForLayerTree() const { const auto frameRate = getDrawingState().frameRate; if (frameRate.rate > 0 || frameRate.type == FrameRateCompatibility::NoVote) { return frameRate; } // This layer doesn't have a frame rate. If one of its ancestors or successors // have a vote, return a NoVote for ancestors/successors to set the vote if (getDrawingState().treeHasFrameRateVote) { return {0, FrameRateCompatibility::NoVote}; } return frameRate; } void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) { Loading Loading @@ -1608,6 +1661,7 @@ void Layer::addChild(const sp<Layer>& layer) { mCurrentChildren.add(layer); layer->setParent(this); updateTreeHasFrameRateVote(); } ssize_t Layer::removeChild(const sp<Layer>& layer) { Loading @@ -1615,7 +1669,24 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) { setTransactionFlags(eTransactionNeeded); layer->setParent(nullptr); return mCurrentChildren.remove(layer); const auto removeResult = mCurrentChildren.remove(layer); updateTreeHasFrameRateVote(); layer->updateTreeHasFrameRateVote(); return removeResult; } void Layer::reparentChildren(const sp<Layer>& newParent) { if (attachChildren()) { setTransactionFlags(eTransactionNeeded); } for (const sp<Layer>& child : mCurrentChildren) { newParent->addChild(child); } mCurrentChildren.clear(); updateTreeHasFrameRateVote(); } bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) { Loading @@ -1631,13 +1702,7 @@ bool Layer::reparentChildren(const sp<IBinder>& newParentHandle) { return false; } if (attachChildren()) { setTransactionFlags(eTransactionNeeded); } for (const sp<Layer>& child : mCurrentChildren) { newParent->addChild(child); } mCurrentChildren.clear(); reparentChildren(newParent); return true; } Loading
services/surfaceflinger/Layer.h +9 −2 Original line number Diff line number Diff line Loading @@ -259,6 +259,9 @@ public: int32_t frameRateSelectionPriority; FrameRate frameRate; // Indicates whether parents / children of this layer had set FrameRate bool treeHasFrameRateVote; }; explicit Layer(const LayerCreationArgs& args); Loading Loading @@ -344,7 +347,8 @@ public: virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber); virtual bool setOverrideScalingMode(int32_t overrideScalingMode); virtual bool setMetadata(const LayerMetadata& data); virtual bool reparentChildren(const sp<IBinder>& layer); bool reparentChildren(const sp<IBinder>& newParentHandle); void reparentChildren(const sp<Layer>& newParent); virtual void setChildrenDrawingParent(const sp<Layer>& layer); virtual bool reparent(const sp<IBinder>& newParentHandle); virtual bool detachChildren(); Loading Loading @@ -801,7 +805,7 @@ public: Rect getCroppedBufferSize(const Layer::State& s) const; bool setFrameRate(FrameRate frameRate); virtual FrameRate getFrameRate() const; virtual FrameRate getFrameRateForLayerTree() const; protected: // constant Loading Loading @@ -830,6 +834,7 @@ protected: // For unit tests friend class TestableSurfaceFlinger; friend class RefreshRateSelectionTest; friend class SetFrameRateTest; virtual void commitTransaction(const State& stateToCommit); Loading Loading @@ -1017,6 +1022,8 @@ private: LayerVector makeChildrenTraversalList(LayerVector::StateSet stateSet, const std::vector<Layer*>& layersInTree); void updateTreeHasFrameRateVote(); // Cached properties computed from drawing state // Effective transform taking into account parent transforms and any parent scaling. ui::Transform mEffectiveTransform; Loading
services/surfaceflinger/Scheduler/LayerHistory.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ namespace android::scheduler::impl { namespace { bool isLayerActive(const Layer& layer, const LayerInfo& info, nsecs_t threshold) { if (layer.getFrameRate().rate > 0) { if (layer.getFrameRateForLayerTree().rate > 0) { return layer.isVisible(); } return layer.isVisible() && info.getLastUpdatedTime() >= threshold; Loading Loading @@ -109,7 +109,7 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) { // Only use the layer if the reference still exists. if (layer || CC_UNLIKELY(mTraceEnabled)) { // Check if frame rate was set on layer. const auto frameRate = layer->getFrameRate(); const auto frameRate = layer->getFrameRateForLayerTree(); if (frameRate.rate > 0.f) { const auto voteType = [&]() { switch (frameRate.type) { Loading
services/surfaceflinger/Scheduler/LayerHistoryV2.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ namespace android::scheduler::impl { namespace { bool isLayerActive(const Layer& layer, const LayerInfoV2& info, nsecs_t threshold) { if (layer.getFrameRate().rate > 0) { if (layer.getFrameRateForLayerTree().rate > 0) { return layer.isVisible(); } return layer.isVisible() && info.getLastUpdatedTime() >= threshold; Loading Loading @@ -166,7 +166,7 @@ void LayerHistoryV2::partitionLayers(nsecs_t now) { if (const auto layer = weak.promote(); layer && isLayerActive(*layer, *info, threshold)) { i++; // Set layer vote if set const auto frameRate = layer->getFrameRate(); const auto frameRate = layer->getFrameRateForLayerTree(); const auto voteType = [&]() { switch (frameRate.type) { case Layer::FrameRateCompatibility::Default: Loading