Loading services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -320,11 +320,8 @@ void updateMetadata(LayerSnapshot& snapshot, const RequestedLayerState& requeste void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerState& requested, const LayerSnapshotBuilder::Args& args, const LayerSnapshot& parentSnapshot) { if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) { snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode : parentSnapshot.gameMode; } updateMetadata(snapshot, requested, args); if (args.includeMetadata) { snapshot.layerMetadata = parentSnapshot.layerMetadata; Loading Loading @@ -780,7 +777,8 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a } if (forceUpdate || (args.includeMetadata && snapshot.changes.test(RequestedLayerState::Changes::Metadata))) { snapshot.changes.any(RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Geometry))) { updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } return; Loading Loading @@ -848,7 +846,9 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a } } if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) { if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Hierarchy)) { updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } Loading services/surfaceflinger/Layer.cpp +24 −36 Original line number Diff line number Diff line Loading @@ -1314,7 +1314,7 @@ bool Layer::setFrameRateSelectionStrategy(FrameRateSelectionStrategy strategy) { } void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime) { nsecs_t postTime, gui::GameMode gameMode) { mDrawingState.postTime = postTime; // Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if Loading @@ -1330,14 +1330,15 @@ void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& i mDrawingState.bufferSurfaceFrameTX->setActualQueueTime(postTime); } else { mDrawingState.bufferSurfaceFrameTX = createSurfaceFrameForBuffer(info, postTime, mTransactionName); createSurfaceFrameForBuffer(info, postTime, mTransactionName, gameMode); } setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName); setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode); } void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info, nsecs_t postTime) { nsecs_t postTime, gui::GameMode gameMode) { mDrawingState.frameTimelineInfo = info; mDrawingState.postTime = postTime; mDrawingState.modified = true; Loading @@ -1356,17 +1357,17 @@ void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInf // targeting different vsyncs). auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId); if (it == mDrawingState.bufferlessSurfaceFramesTX.end()) { auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime); auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime, gameMode); mDrawingState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame; } else { if (it->second->getPresentState() == PresentState::Presented) { // If the SurfaceFrame was already presented, its safe to overwrite it since it must // have been from previous vsync. it->second = createSurfaceFrameForTransaction(info, postTime); it->second = createSurfaceFrameForTransaction(info, postTime, gameMode); } } setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName); setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode); } void Layer::addSurfaceFrameDroppedForBuffer( Loading @@ -1386,12 +1387,12 @@ void Layer::addSurfaceFramePresentedForBuffer( } std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransaction( const FrameTimelineInfo& info, nsecs_t postTime) { const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) { auto surfaceFrame = mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid, getSequence(), mName, mTransactionName, /*isBuffer*/ false, getGameMode()); /*isBuffer*/ false, gameMode); surfaceFrame->setActualStartTime(info.startTimeNanos); // For Transactions, the post time is considered to be both queue and acquire fence time. surfaceFrame->setActualQueueTime(postTime); Loading @@ -1404,11 +1405,12 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransac } std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer( const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName) { const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName, gui::GameMode gameMode) { auto surfaceFrame = mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid, getSequence(), mName, debugName, /*isBuffer*/ true, getGameMode()); /*isBuffer*/ true, gameMode); surfaceFrame->setActualStartTime(info.startTimeNanos); // For buffers, acquire fence time will set during latch. surfaceFrame->setActualQueueTime(queueTime); Loading @@ -1420,7 +1422,7 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer( } void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime, std::string debugName) { std::string debugName, gui::GameMode gameMode) { if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) { return; } Loading @@ -1432,7 +1434,7 @@ void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, mFlinger->mFrameTimeline->createSurfaceFrameForToken(skippedFrameTimelineInfo, mOwnerPid, mOwnerUid, getSequence(), mName, debugName, /*isBuffer*/ false, getGameMode()); /*isBuffer*/ false, gameMode); surfaceFrame->setActualStartTime(skippedFrameTimelineInfo.skippedFrameStartTimeNanos); // For Transactions, the post time is considered to be both queue and acquire fence time. surfaceFrame->setActualQueueTime(postTime); Loading Loading @@ -1671,25 +1673,12 @@ size_t Layer::getDescendantCount() const { return count; } void Layer::setGameModeForTree(GameMode gameMode) { const auto& currentState = getDrawingState(); if (currentState.metadata.has(gui::METADATA_GAME_MODE)) { gameMode = static_cast<GameMode>(currentState.metadata.getInt32(gui::METADATA_GAME_MODE, 0)); } setGameMode(gameMode); for (const sp<Layer>& child : mCurrentChildren) { child->setGameModeForTree(gameMode); } } void Layer::addChild(const sp<Layer>& layer) { mFlinger->mSomeChildrenChanged = true; setTransactionFlags(eTransactionNeeded); mCurrentChildren.add(layer); layer->setParent(sp<Layer>::fromExisting(this)); layer->setGameModeForTree(mGameMode); updateTreeHasFrameRateVote(); } Loading @@ -1701,7 +1690,6 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) { const auto removeResult = mCurrentChildren.remove(layer); updateTreeHasFrameRateVote(); layer->setGameModeForTree(GameMode::Unsupported); layer->updateTreeHasFrameRateVote(); return removeResult; Loading Loading @@ -3082,7 +3070,7 @@ void Layer::resetDrawingStateBufferInfo() { bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer, const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const FrameTimelineInfo& info) { bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) { SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false")); const bool frameNumberChanged = Loading @@ -3108,12 +3096,12 @@ bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer, resetDrawingStateBufferInfo(); setTransactionFlags(eTransactionNeeded); mDrawingState.bufferSurfaceFrameTX = nullptr; setFrameTimelineVsyncForBufferlessTransaction(info, postTime); setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode); return true; } else { // release sideband stream if it exists and a non null buffer is being set if (mDrawingState.sidebandStream != nullptr) { setSidebandStream(nullptr, info, postTime); setSidebandStream(nullptr, info, postTime, gameMode); } } Loading Loading @@ -3152,9 +3140,9 @@ bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer, const int32_t layerId = getSequence(); mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(), mOwnerUid, postTime, getGameMode()); mOwnerUid, postTime, gameMode); setFrameTimelineVsyncForBufferTransaction(info, postTime); setFrameTimelineVsyncForBufferTransaction(info, postTime, gameMode); if (bufferData.dequeueTime > 0) { const uint64_t bufferId = mDrawingState.buffer->getId(); Loading Loading @@ -3309,7 +3297,7 @@ bool Layer::setApi(int32_t api) { } bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const FrameTimelineInfo& info, nsecs_t postTime) { nsecs_t postTime, gui::GameMode gameMode) { if (mDrawingState.sidebandStream == sidebandStream) return false; if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) { Loading @@ -3324,7 +3312,7 @@ bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const Fram releasePreviousBuffer(); resetDrawingStateBufferInfo(); mDrawingState.bufferSurfaceFrameTX = nullptr; setFrameTimelineVsyncForBufferlessTransaction(info, postTime); setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode); } setTransactionFlags(eTransactionNeeded); if (!mSidebandStreamChanged.exchange(true)) { Loading Loading @@ -3982,7 +3970,8 @@ bool Layer::isVisible() const { void Layer::onCompositionPresented(const DisplayDevice* display, const std::shared_ptr<FenceTime>& glDoneFence, const std::shared_ptr<FenceTime>& presentFence, const CompositorTiming& compositorTiming) { const CompositorTiming& compositorTiming, gui::GameMode gameMode) { // mFrameLatencyNeeded is true when a new frame was latched for the // composition. if (!mBufferInfo.mFrameLatencyNeeded) return; Loading Loading @@ -4029,7 +4018,6 @@ void Layer::onCompositionPresented(const DisplayDevice* display, mFlinger->mScheduler->getFrameRateOverride(getOwnerUid()); const auto vote = frameRateToSetFrameRateVotePayload(getFrameRateForLayerTree()); const auto gameMode = getGameMode(); if (presentFence->isValid()) { mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence, Loading services/surfaceflinger/Layer.h +11 −15 Original line number Diff line number Diff line Loading @@ -312,7 +312,7 @@ public: bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */, const BufferData& /* bufferData */, nsecs_t /* postTime */, nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, const FrameTimelineInfo& /*info*/); const FrameTimelineInfo& /*info*/, gui::GameMode gameMode); void setDesiredPresentTime(nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/); bool setDataspace(ui::Dataspace /*dataspace*/); bool setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio); Loading @@ -322,7 +322,8 @@ public: bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/); bool setApi(int32_t /*api*/); bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/, const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */); const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */, gui::GameMode gameMode); bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/, bool willPresent); virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace) Loading Loading @@ -439,7 +440,7 @@ public: void onCompositionPresented(const DisplayDevice*, const std::shared_ptr<FenceTime>& /*glDoneFence*/, const std::shared_ptr<FenceTime>& /*presentFence*/, const CompositorTiming&); const CompositorTiming&, gui::GameMode gameMode); // If a buffer was replaced this frame, release the former buffer void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/); Loading Loading @@ -794,9 +795,10 @@ public: bool setFrameRateSelectionStrategy(FrameRateSelectionStrategy); virtual void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& /*info*/) {} void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime); void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode); void setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info, nsecs_t postTime); nsecs_t postTime, gui::GameMode gameMode); void addSurfaceFrameDroppedForBuffer(std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t dropTime); Loading @@ -805,11 +807,12 @@ public: nsecs_t currentLatchTime); std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForTransaction( const FrameTimelineInfo& info, nsecs_t postTime); const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode); std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForBuffer( const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName); const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName, gui::GameMode gameMode); void setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime, std::string debugName); std::string debugName, gui::GameMode gameMode); bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds, TrustedPresentationListener const& listener); Loading @@ -832,13 +835,6 @@ public: */ bool hasInputInfo() const; // Sets the gui::GameMode for the tree rooted at this layer. A layer in the tree inherits this // gui::GameMode unless it (or an ancestor) has GAME_MODE_METADATA. void setGameModeForTree(gui::GameMode); void setGameMode(gui::GameMode gameMode) { mGameMode = gameMode; } gui::GameMode getGameMode() const { return mGameMode; } virtual uid_t getOwnerUid() const { return mOwnerUid; } pid_t getOwnerPid() { return mOwnerPid; } Loading services/surfaceflinger/SurfaceFlinger.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -2521,7 +2521,9 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, it->second->latchBufferImpl(unused, latchTime, bgColorOnly); newDataLatched = true; mLayersWithQueuedFrames.emplace(it->second); frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence); gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported; mLayersWithQueuedFrames.emplace(it->second, gameMode); mLayersIdsWithQueuedFrames.emplace(it->second->sequence); } Loading Loading @@ -2755,7 +2757,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( if (!FlagManager::getInstance().ce_fence_promise()) { refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size()); for (auto& layer : mLayersWithQueuedFrames) { for (auto& [layer, _] : mLayersWithQueuedFrames) { if (const auto& layerFE = layer->getCompositionEngineLayerFE()) refreshArgs.layersWithQueuedFrames.push_back(layerFE); } Loading Loading @@ -2831,7 +2833,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( } refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size()); for (auto& layer : mLayersWithQueuedFrames) { for (auto& [layer, _] : mLayersWithQueuedFrames) { if (const auto& layerFE = layer->getCompositionEngineLayerFE()) { refreshArgs.layersWithQueuedFrames.push_back(layerFE); // Some layers are not displayed and do not yet have a future release fence Loading Loading @@ -3137,10 +3139,10 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, } mLayersWithBuffersRemoved.clear(); for (const auto& layer: mLayersWithQueuedFrames) { for (const auto& [layer, gameMode] : mLayersWithQueuedFrames) { layer->onCompositionPresented(pacesetterDisplay.get(), pacesetterGpuCompositionDoneFenceTime, pacesetterPresentFenceTime, compositorTiming); pacesetterPresentFenceTime, compositorTiming, gameMode); layer->releasePendingBuffer(presentTime.ns()); } Loading Loading @@ -5187,6 +5189,17 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f sp<CallbackHandle>::make(listener, callbackIds, s.surface)); } } frontend::LayerSnapshot* snapshot = nullptr; gui::GameMode gameMode = gui::GameMode::Unsupported; if (what & (layer_state_t::eSidebandStreamChanged | layer_state_t::eBufferChanged) || frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); if (snapshot) { gameMode = snapshot->gameMode; } } // TODO(b/238781169) remove after screenshot refactor, currently screenshots // requires to read drawing state from binder thread. So we need to fix that // before removing this. Loading @@ -5201,7 +5214,7 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; } if (what & layer_state_t::eSidebandStreamChanged) { if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime)) if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime, gameMode)) flags |= eTraversalNeeded; } if (what & layer_state_t::eDataspaceChanged) { Loading @@ -5219,18 +5232,17 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f } if (what & layer_state_t::eBufferChanged) { std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt; frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); if (snapshot) { transformHint = snapshot->transformHint; } layer->setTransformHint(transformHint); if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, frameTimelineInfo)) { desiredPresentTime, isAutoTimestamp, frameTimelineInfo, gameMode)) { flags |= eTraversalNeeded; } mLayersWithQueuedFrames.emplace(layer); mLayersWithQueuedFrames.emplace(layer, gameMode); } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime); layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime, gameMode); } if ((what & layer_state_t::eBufferChanged) == 0) { Loading services/surfaceflinger/SurfaceFlinger.h +8 −1 Original line number Diff line number Diff line Loading @@ -1274,10 +1274,17 @@ private: bool mForceTransactionDisplayChange = false; bool mUpdateAttachedChoreographer = false; struct LayerIntHash { size_t operator()(const std::pair<sp<Layer>, gui::GameMode>& k) const { return std::hash<Layer*>()(k.first.get()) ^ std::hash<int32_t>()(static_cast<int32_t>(k.second)); } }; // TODO(b/238781169) validate these on composition // Tracks layers that have pending frames which are candidates for being // latched. std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithQueuedFrames; std::unordered_set<std::pair<sp<Layer>, gui::GameMode>, LayerIntHash> mLayersWithQueuedFrames; std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved; std::unordered_set<uint32_t> mLayersIdsWithQueuedFrames; Loading Loading
services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -320,11 +320,8 @@ void updateMetadata(LayerSnapshot& snapshot, const RequestedLayerState& requeste void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerState& requested, const LayerSnapshotBuilder::Args& args, const LayerSnapshot& parentSnapshot) { if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) { snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode : parentSnapshot.gameMode; } updateMetadata(snapshot, requested, args); if (args.includeMetadata) { snapshot.layerMetadata = parentSnapshot.layerMetadata; Loading Loading @@ -780,7 +777,8 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a } if (forceUpdate || (args.includeMetadata && snapshot.changes.test(RequestedLayerState::Changes::Metadata))) { snapshot.changes.any(RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Geometry))) { updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } return; Loading Loading @@ -848,7 +846,9 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a } } if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) { if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Hierarchy)) { updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot); } Loading
services/surfaceflinger/Layer.cpp +24 −36 Original line number Diff line number Diff line Loading @@ -1314,7 +1314,7 @@ bool Layer::setFrameRateSelectionStrategy(FrameRateSelectionStrategy strategy) { } void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime) { nsecs_t postTime, gui::GameMode gameMode) { mDrawingState.postTime = postTime; // Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if Loading @@ -1330,14 +1330,15 @@ void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& i mDrawingState.bufferSurfaceFrameTX->setActualQueueTime(postTime); } else { mDrawingState.bufferSurfaceFrameTX = createSurfaceFrameForBuffer(info, postTime, mTransactionName); createSurfaceFrameForBuffer(info, postTime, mTransactionName, gameMode); } setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName); setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode); } void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info, nsecs_t postTime) { nsecs_t postTime, gui::GameMode gameMode) { mDrawingState.frameTimelineInfo = info; mDrawingState.postTime = postTime; mDrawingState.modified = true; Loading @@ -1356,17 +1357,17 @@ void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInf // targeting different vsyncs). auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId); if (it == mDrawingState.bufferlessSurfaceFramesTX.end()) { auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime); auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime, gameMode); mDrawingState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame; } else { if (it->second->getPresentState() == PresentState::Presented) { // If the SurfaceFrame was already presented, its safe to overwrite it since it must // have been from previous vsync. it->second = createSurfaceFrameForTransaction(info, postTime); it->second = createSurfaceFrameForTransaction(info, postTime, gameMode); } } setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName); setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode); } void Layer::addSurfaceFrameDroppedForBuffer( Loading @@ -1386,12 +1387,12 @@ void Layer::addSurfaceFramePresentedForBuffer( } std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransaction( const FrameTimelineInfo& info, nsecs_t postTime) { const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) { auto surfaceFrame = mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid, getSequence(), mName, mTransactionName, /*isBuffer*/ false, getGameMode()); /*isBuffer*/ false, gameMode); surfaceFrame->setActualStartTime(info.startTimeNanos); // For Transactions, the post time is considered to be both queue and acquire fence time. surfaceFrame->setActualQueueTime(postTime); Loading @@ -1404,11 +1405,12 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransac } std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer( const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName) { const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName, gui::GameMode gameMode) { auto surfaceFrame = mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid, getSequence(), mName, debugName, /*isBuffer*/ true, getGameMode()); /*isBuffer*/ true, gameMode); surfaceFrame->setActualStartTime(info.startTimeNanos); // For buffers, acquire fence time will set during latch. surfaceFrame->setActualQueueTime(queueTime); Loading @@ -1420,7 +1422,7 @@ std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer( } void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime, std::string debugName) { std::string debugName, gui::GameMode gameMode) { if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) { return; } Loading @@ -1432,7 +1434,7 @@ void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, mFlinger->mFrameTimeline->createSurfaceFrameForToken(skippedFrameTimelineInfo, mOwnerPid, mOwnerUid, getSequence(), mName, debugName, /*isBuffer*/ false, getGameMode()); /*isBuffer*/ false, gameMode); surfaceFrame->setActualStartTime(skippedFrameTimelineInfo.skippedFrameStartTimeNanos); // For Transactions, the post time is considered to be both queue and acquire fence time. surfaceFrame->setActualQueueTime(postTime); Loading Loading @@ -1671,25 +1673,12 @@ size_t Layer::getDescendantCount() const { return count; } void Layer::setGameModeForTree(GameMode gameMode) { const auto& currentState = getDrawingState(); if (currentState.metadata.has(gui::METADATA_GAME_MODE)) { gameMode = static_cast<GameMode>(currentState.metadata.getInt32(gui::METADATA_GAME_MODE, 0)); } setGameMode(gameMode); for (const sp<Layer>& child : mCurrentChildren) { child->setGameModeForTree(gameMode); } } void Layer::addChild(const sp<Layer>& layer) { mFlinger->mSomeChildrenChanged = true; setTransactionFlags(eTransactionNeeded); mCurrentChildren.add(layer); layer->setParent(sp<Layer>::fromExisting(this)); layer->setGameModeForTree(mGameMode); updateTreeHasFrameRateVote(); } Loading @@ -1701,7 +1690,6 @@ ssize_t Layer::removeChild(const sp<Layer>& layer) { const auto removeResult = mCurrentChildren.remove(layer); updateTreeHasFrameRateVote(); layer->setGameModeForTree(GameMode::Unsupported); layer->updateTreeHasFrameRateVote(); return removeResult; Loading Loading @@ -3082,7 +3070,7 @@ void Layer::resetDrawingStateBufferInfo() { bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer, const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const FrameTimelineInfo& info) { bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) { SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false")); const bool frameNumberChanged = Loading @@ -3108,12 +3096,12 @@ bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer, resetDrawingStateBufferInfo(); setTransactionFlags(eTransactionNeeded); mDrawingState.bufferSurfaceFrameTX = nullptr; setFrameTimelineVsyncForBufferlessTransaction(info, postTime); setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode); return true; } else { // release sideband stream if it exists and a non null buffer is being set if (mDrawingState.sidebandStream != nullptr) { setSidebandStream(nullptr, info, postTime); setSidebandStream(nullptr, info, postTime, gameMode); } } Loading Loading @@ -3152,9 +3140,9 @@ bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer, const int32_t layerId = getSequence(); mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(), mOwnerUid, postTime, getGameMode()); mOwnerUid, postTime, gameMode); setFrameTimelineVsyncForBufferTransaction(info, postTime); setFrameTimelineVsyncForBufferTransaction(info, postTime, gameMode); if (bufferData.dequeueTime > 0) { const uint64_t bufferId = mDrawingState.buffer->getId(); Loading Loading @@ -3309,7 +3297,7 @@ bool Layer::setApi(int32_t api) { } bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const FrameTimelineInfo& info, nsecs_t postTime) { nsecs_t postTime, gui::GameMode gameMode) { if (mDrawingState.sidebandStream == sidebandStream) return false; if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) { Loading @@ -3324,7 +3312,7 @@ bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const Fram releasePreviousBuffer(); resetDrawingStateBufferInfo(); mDrawingState.bufferSurfaceFrameTX = nullptr; setFrameTimelineVsyncForBufferlessTransaction(info, postTime); setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode); } setTransactionFlags(eTransactionNeeded); if (!mSidebandStreamChanged.exchange(true)) { Loading Loading @@ -3982,7 +3970,8 @@ bool Layer::isVisible() const { void Layer::onCompositionPresented(const DisplayDevice* display, const std::shared_ptr<FenceTime>& glDoneFence, const std::shared_ptr<FenceTime>& presentFence, const CompositorTiming& compositorTiming) { const CompositorTiming& compositorTiming, gui::GameMode gameMode) { // mFrameLatencyNeeded is true when a new frame was latched for the // composition. if (!mBufferInfo.mFrameLatencyNeeded) return; Loading Loading @@ -4029,7 +4018,6 @@ void Layer::onCompositionPresented(const DisplayDevice* display, mFlinger->mScheduler->getFrameRateOverride(getOwnerUid()); const auto vote = frameRateToSetFrameRateVotePayload(getFrameRateForLayerTree()); const auto gameMode = getGameMode(); if (presentFence->isValid()) { mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence, Loading
services/surfaceflinger/Layer.h +11 −15 Original line number Diff line number Diff line Loading @@ -312,7 +312,7 @@ public: bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */, const BufferData& /* bufferData */, nsecs_t /* postTime */, nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, const FrameTimelineInfo& /*info*/); const FrameTimelineInfo& /*info*/, gui::GameMode gameMode); void setDesiredPresentTime(nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/); bool setDataspace(ui::Dataspace /*dataspace*/); bool setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio); Loading @@ -322,7 +322,8 @@ public: bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/); bool setApi(int32_t /*api*/); bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/, const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */); const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */, gui::GameMode gameMode); bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/, bool willPresent); virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace) Loading Loading @@ -439,7 +440,7 @@ public: void onCompositionPresented(const DisplayDevice*, const std::shared_ptr<FenceTime>& /*glDoneFence*/, const std::shared_ptr<FenceTime>& /*presentFence*/, const CompositorTiming&); const CompositorTiming&, gui::GameMode gameMode); // If a buffer was replaced this frame, release the former buffer void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/); Loading Loading @@ -794,9 +795,10 @@ public: bool setFrameRateSelectionStrategy(FrameRateSelectionStrategy); virtual void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& /*info*/) {} void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime); void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode); void setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info, nsecs_t postTime); nsecs_t postTime, gui::GameMode gameMode); void addSurfaceFrameDroppedForBuffer(std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame, nsecs_t dropTime); Loading @@ -805,11 +807,12 @@ public: nsecs_t currentLatchTime); std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForTransaction( const FrameTimelineInfo& info, nsecs_t postTime); const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode); std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForBuffer( const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName); const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName, gui::GameMode gameMode); void setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime, std::string debugName); std::string debugName, gui::GameMode gameMode); bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds, TrustedPresentationListener const& listener); Loading @@ -832,13 +835,6 @@ public: */ bool hasInputInfo() const; // Sets the gui::GameMode for the tree rooted at this layer. A layer in the tree inherits this // gui::GameMode unless it (or an ancestor) has GAME_MODE_METADATA. void setGameModeForTree(gui::GameMode); void setGameMode(gui::GameMode gameMode) { mGameMode = gameMode; } gui::GameMode getGameMode() const { return mGameMode; } virtual uid_t getOwnerUid() const { return mOwnerUid; } pid_t getOwnerPid() { return mOwnerPid; } Loading
services/surfaceflinger/SurfaceFlinger.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -2521,7 +2521,9 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, it->second->latchBufferImpl(unused, latchTime, bgColorOnly); newDataLatched = true; mLayersWithQueuedFrames.emplace(it->second); frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence); gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported; mLayersWithQueuedFrames.emplace(it->second, gameMode); mLayersIdsWithQueuedFrames.emplace(it->second->sequence); } Loading Loading @@ -2755,7 +2757,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( if (!FlagManager::getInstance().ce_fence_promise()) { refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size()); for (auto& layer : mLayersWithQueuedFrames) { for (auto& [layer, _] : mLayersWithQueuedFrames) { if (const auto& layerFE = layer->getCompositionEngineLayerFE()) refreshArgs.layersWithQueuedFrames.push_back(layerFE); } Loading Loading @@ -2831,7 +2833,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite( } refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size()); for (auto& layer : mLayersWithQueuedFrames) { for (auto& [layer, _] : mLayersWithQueuedFrames) { if (const auto& layerFE = layer->getCompositionEngineLayerFE()) { refreshArgs.layersWithQueuedFrames.push_back(layerFE); // Some layers are not displayed and do not yet have a future release fence Loading Loading @@ -3137,10 +3139,10 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, } mLayersWithBuffersRemoved.clear(); for (const auto& layer: mLayersWithQueuedFrames) { for (const auto& [layer, gameMode] : mLayersWithQueuedFrames) { layer->onCompositionPresented(pacesetterDisplay.get(), pacesetterGpuCompositionDoneFenceTime, pacesetterPresentFenceTime, compositorTiming); pacesetterPresentFenceTime, compositorTiming, gameMode); layer->releasePendingBuffer(presentTime.ns()); } Loading Loading @@ -5187,6 +5189,17 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f sp<CallbackHandle>::make(listener, callbackIds, s.surface)); } } frontend::LayerSnapshot* snapshot = nullptr; gui::GameMode gameMode = gui::GameMode::Unsupported; if (what & (layer_state_t::eSidebandStreamChanged | layer_state_t::eBufferChanged) || frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); if (snapshot) { gameMode = snapshot->gameMode; } } // TODO(b/238781169) remove after screenshot refactor, currently screenshots // requires to read drawing state from binder thread. So we need to fix that // before removing this. Loading @@ -5201,7 +5214,7 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f if (layer->setCrop(s.crop)) flags |= eTraversalNeeded; } if (what & layer_state_t::eSidebandStreamChanged) { if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime)) if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime, gameMode)) flags |= eTraversalNeeded; } if (what & layer_state_t::eDataspaceChanged) { Loading @@ -5219,18 +5232,17 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f } if (what & layer_state_t::eBufferChanged) { std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt; frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence); if (snapshot) { transformHint = snapshot->transformHint; } layer->setTransformHint(transformHint); if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, frameTimelineInfo)) { desiredPresentTime, isAutoTimestamp, frameTimelineInfo, gameMode)) { flags |= eTraversalNeeded; } mLayersWithQueuedFrames.emplace(layer); mLayersWithQueuedFrames.emplace(layer, gameMode); } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime); layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime, gameMode); } if ((what & layer_state_t::eBufferChanged) == 0) { Loading
services/surfaceflinger/SurfaceFlinger.h +8 −1 Original line number Diff line number Diff line Loading @@ -1274,10 +1274,17 @@ private: bool mForceTransactionDisplayChange = false; bool mUpdateAttachedChoreographer = false; struct LayerIntHash { size_t operator()(const std::pair<sp<Layer>, gui::GameMode>& k) const { return std::hash<Layer*>()(k.first.get()) ^ std::hash<int32_t>()(static_cast<int32_t>(k.second)); } }; // TODO(b/238781169) validate these on composition // Tracks layers that have pending frames which are candidates for being // latched. std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithQueuedFrames; std::unordered_set<std::pair<sp<Layer>, gui::GameMode>, LayerIntHash> mLayersWithQueuedFrames; std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved; std::unordered_set<uint32_t> mLayersIdsWithQueuedFrames; Loading