Loading services/surfaceflinger/SurfaceFlinger.cpp +142 −108 Original line number Diff line number Diff line Loading @@ -3178,7 +3178,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, if (mLayerLifecycleManagerEnabled) { mLayerSnapshotBuilder.forEachVisibleSnapshot( [&, compositionDisplay = compositionDisplay]( std::unique_ptr<frontend::LayerSnapshot>& snapshot) { std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(kMainThreadContext) { auto it = mLegacyLayers.find(snapshot->sequence); LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s", Loading Loading @@ -3237,7 +3238,7 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, if (mNumTrustedPresentationListeners > 0) { // We avoid any reverse traversal upwards so this shouldn't be too expensive traverseLegacyLayers([&](Layer* layer) { traverseLegacyLayers([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) { if (!layer->hasTrustedPresentationListener()) { return; } Loading Loading @@ -4150,7 +4151,7 @@ void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos, outWindowInfos.push_back(snapshot.inputInfo); }); } else { mDrawingState.traverseInReverseZOrder([&](Layer* layer) { mDrawingState.traverseInReverseZOrder([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) { if (!layer->needsInputInfo()) return; const auto opt = mFrontEndDisplayInfos.get(layer->getLayerStack()) Loading Loading @@ -4855,6 +4856,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC if (listener && (flushState.queueProcessTime - transaction.postTime) > std::chrono::nanoseconds(4s).count()) { // Used to add a stalled transaction which uses an internal lock. ftl::FakeGuard guard(kMainThreadContext); mTransactionHandler .onTransactionQueueStalled(transaction.id, {.pid = layer->getOwnerPid(), Loading @@ -4877,8 +4880,9 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC const TransactionHandler::TransactionFlushState& flushState) { using TransactionReadiness = TransactionHandler::TransactionReadiness; auto ready = TransactionReadiness::Ready; flushState.transaction->traverseStatesWithBuffersWhileTrue([&](const ResolvedComposerState& resolvedState) -> bool { flushState.transaction->traverseStatesWithBuffersWhileTrue( [&](const ResolvedComposerState& resolvedState) FTL_FAKE_GUARD( kMainThreadContext) -> bool { const frontend::RequestedLayerState* layer = mLayerLifecycleManager.getLayerFromId(resolvedState.layerId); const auto& transaction = *flushState.transaction; Loading @@ -4886,16 +4890,18 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC // check for barrier frames if (s.bufferData->hasBarrier) { // The current producerId is already a newer producer than the buffer that has a // barrier. This means the incoming buffer is older and we can release it here. We // don't wait on the barrier since we know that's stale information. // barrier. This means the incoming buffer is older and we can release it here. // We don't wait on the barrier since we know that's stale information. if (layer->barrierProducerId > s.bufferData->producerId) { if (s.bufferData->releaseBufferListener) { uint32_t currentMaxAcquiredBufferCount = getMaxAcquiredBufferCountForCurrentRefreshRate(layer->ownerUid.val()); getMaxAcquiredBufferCountForCurrentRefreshRate( layer->ownerUid.val()); ATRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, layer->name.c_str(), s.bufferData->frameNumber); s.bufferData->releaseBufferListener ->onReleaseBuffer({resolvedState.externalTexture->getBuffer()->getId(), ->onReleaseBuffer({resolvedState.externalTexture->getBuffer() ->getId(), s.bufferData->frameNumber}, s.bufferData->acquireFence ? s.bufferData->acquireFence Loading @@ -4903,10 +4909,12 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC currentMaxAcquiredBufferCount); } // Delete the entire state at this point and not just release the buffer because // everything associated with the Layer in this Transaction is now out of date. ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d", layer->name.c_str(), layer->barrierProducerId, s.bufferData->producerId); // Delete the entire state at this point and not just release the buffer // because everything associated with the Layer in this Transaction is now // out of date. ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d", layer->name.c_str(), layer->barrierProducerId, s.bufferData->producerId); return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL; } Loading @@ -4916,7 +4924,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >= s.bufferData->barrierFrameNumber)); if (!willApplyBarrierFrame) { ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 " > %" PRId64, ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 " > %" PRId64, layer->name.c_str(), layer->barrierFrameNumber, s.bufferData->barrierFrameNumber); ready = TransactionReadiness::NotReadyBarrier; Loading @@ -4929,7 +4938,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC // the transaction in the queue. const bool hasPendingBuffer = flushState.bufferLayersReadyToPresent.contains(s.surface.get()); if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) { if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) { ATRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str()); ready = TransactionReadiness::NotReady; return TraverseBuffersReturnValues::STOP_TRAVERSAL; Loading @@ -4942,11 +4952,13 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled; if (!fenceSignaled) { // check fence status const bool allowLatchUnsignaled = shouldLatchUnsignaled(s, transaction.states.size(), const bool allowLatchUnsignaled = shouldLatchUnsignaled(s, transaction.states.size(), flushState.firstTransaction) && layer->isSimpleBufferUpdate(s); if (allowLatchUnsignaled) { ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s", layer->name.c_str()); ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s", layer->name.c_str()); ready = TransactionReadiness::NotReadyUnsignaled; } else { ready = TransactionReadiness::NotReady; Loading @@ -4960,7 +4972,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC .layerId = layer->id, .layerName = layer->name, .bufferId = s.bufferData->getId(), .frameNumber = s.bufferData->frameNumber}); .frameNumber = s.bufferData->frameNumber}); } ATRACE_FORMAT("fence unsignaled %s", layer->name.c_str()); return TraverseBuffersReturnValues::STOP_TRAVERSAL; Loading Loading @@ -5188,7 +5201,13 @@ status_t SurfaceFlinger::setTransactionState( }(state.flags); const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone; { // Transactions are added via a lockless queue and does not need to be added from the main // thread. ftl::FakeGuard guard(kMainThreadContext); mTransactionHandler.queueTransaction(std::move(state)); } for (const auto& [displayId, data] : mNotifyExpectedPresentMap) { if (data.hintStatus.load() == NotifyExpectedPresentHintStatus::ScheduleOnTx) { scheduleNotifyExpectedPresentHint(displayId, VsyncId{frameTimelineInfo.vsyncId}); Loading Loading @@ -6030,7 +6049,11 @@ void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer, uint32 mDestroyedHandles.emplace_back(layerId, layer->getDebugName()); } { // Used to remove stalled transactions which uses an internal lock. ftl::FakeGuard guard(kMainThreadContext); mTransactionHandler.onLayerDestroyed(layerId); } Mutex::Autolock lock(mStateLock); markLayerPendingRemovalLocked(layer); Loading Loading @@ -6682,7 +6705,11 @@ void SurfaceFlinger::dumpOffscreenLayersProto(perfetto::protos::LayersProto& lay } perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) { return mScheduler->schedule([=, this] { return dumpDrawingStateProto(traceFlags); }).get(); return mScheduler ->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) { return dumpDrawingStateProto(traceFlags); }) .get(); } void SurfaceFlinger::dumpOffscreenLayers(std::string& result) { Loading Loading @@ -6731,7 +6758,8 @@ void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const { Layer::miniDumpHeader(result); const DisplayDevice& ref = *display; mLayerSnapshotBuilder.forEachVisibleSnapshot([&](const frontend::LayerSnapshot& snapshot) { mLayerSnapshotBuilder.forEachVisibleSnapshot( [&](const frontend::LayerSnapshot& snapshot) FTL_FAKE_GUARD(kMainThreadContext) { if (!snapshot.hasSomethingToDraw() || ref.getLayerStack() != snapshot.outputFilter.layerStack) { return; Loading Loading @@ -8057,7 +8085,8 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, } bool childrenOnly = args.childrenOnly; RenderAreaFuture renderAreaFuture = ftl::defer([=, this]() -> std::unique_ptr<RenderArea> { RenderAreaFuture renderAreaFuture = ftl::defer([=, this]() FTL_FAKE_GUARD(kMainThreadContext) -> std::unique_ptr<RenderArea> { ui::Transform layerTransform; Rect layerBufferSize; if (mLayerLifecycleManagerEnabled) { Loading Loading @@ -9029,6 +9058,8 @@ status_t SurfaceFlinger::removeWindowInfosListener( status_t SurfaceFlinger::getStalledTransactionInfo( int pid, std::optional<TransactionHandler::StalledTransactionInfo>& result) { // Used to add a stalled transaction which uses an internal lock. ftl::FakeGuard guard(kMainThreadContext); result = mTransactionHandler.getStalledTransactionInfo(pid); return NO_ERROR; } Loading Loading @@ -9229,7 +9260,8 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit if (mLayerLifecycleManagerEnabled) { nsecs_t currentTime = systemTime(); mLayerSnapshotBuilder.forEachVisibleSnapshot( [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) { [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( kMainThreadContext) { if (cursorOnly && snapshot->compositionType != aidl::android::hardware::graphics::composer3::Composition::CURSOR) { Loading Loading @@ -9290,11 +9322,12 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots( std::optional<ui::LayerStack> layerStack, uint32_t uid, std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)> snapshotFilterFn) { return [&, layerStack, uid]() { return [&, layerStack, uid]() FTL_FAKE_GUARD(kMainThreadContext) { std::vector<std::pair<Layer*, sp<LayerFE>>> layers; bool stopTraversal = false; mLayerSnapshotBuilder.forEachVisibleSnapshot( [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) { [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( kMainThreadContext) { if (stopTraversal) { return; } Loading Loading @@ -9329,7 +9362,8 @@ std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds) { return [&, layerStack, uid, excludeLayerIds = std::move(excludeLayerIds)]() { return [&, layerStack, uid, excludeLayerIds = std::move(excludeLayerIds)]() FTL_FAKE_GUARD(kMainThreadContext) { if (excludeLayerIds.empty()) { auto getLayerSnapshotsFn = getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr); Loading Loading @@ -9371,7 +9405,7 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t u bool childrenOnly, const std::optional<FloatRect>& parentCrop) { return [&, rootLayerId, uid, excludeLayerIds = std::move(excludeLayerIds), childrenOnly, parentCrop]() { parentCrop]() FTL_FAKE_GUARD(kMainThreadContext) { auto root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly); frontend::LayerSnapshotBuilder::Args args{.root = root, Loading services/surfaceflinger/SurfaceFlinger.h +35 −27 Original line number Diff line number Diff line Loading @@ -770,24 +770,27 @@ private: void updateLayerGeometry(); void updateLayerMetadataSnapshot(); std::vector<std::pair<Layer*, LayerFE*>> moveSnapshotsToCompositionArgs( compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly); compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) REQUIRES(kMainThreadContext); void moveSnapshotsFromCompositionArgs(compositionengine::CompositionRefreshArgs& refreshArgs, const std::vector<std::pair<Layer*, LayerFE*>>& layers); const std::vector<std::pair<Layer*, LayerFE*>>& layers) REQUIRES(kMainThreadContext); // Return true if we must composite this frame bool updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); // Return true if we must composite this frame bool updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); void updateLayerHistory(nsecs_t now); void updateLayerHistory(nsecs_t now) REQUIRES(kMainThreadContext); frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) REQUIRES(kMainThreadContext); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos, std::vector<gui::DisplayInfo>& outDisplayInfos); std::vector<gui::DisplayInfo>& outDisplayInfos) REQUIRES(kMainThreadContext); void commitInputWindowCommands() REQUIRES(mStateLock); void updateCursorAsync(); void updateCursorAsync() REQUIRES(kMainThreadContext); void initScheduler(const sp<const DisplayDevice>&) REQUIRES(kMainThreadContext, mStateLock); Loading @@ -803,7 +806,7 @@ private: const int64_t postTime, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid, uint64_t transactionId) REQUIRES(mStateLock); REQUIRES(mStateLock, kMainThreadContext); // Flush pending transactions that were presented after desiredPresentTime. // For test only bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext); Loading @@ -813,8 +816,8 @@ private: REQUIRES(kMainThreadContext, mStateLock); // Returns true if there is at least one transaction that needs to be flushed bool transactionFlushNeeded(); void addTransactionReadyFilters(); bool transactionFlushNeeded() REQUIRES(kMainThreadContext); void addTransactionReadyFilters() REQUIRES(kMainThreadContext); TransactionHandler::TransactionReadiness transactionReadyTimelineCheck( const TransactionHandler::TransactionFlushState& flushState) REQUIRES(kMainThreadContext); Loading @@ -831,7 +834,7 @@ private: uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock); REQUIRES(mStateLock, kMainThreadContext); uint32_t getTransactionFlags() const; // Sets the masked bits, and schedules a commit if needed. Loading @@ -847,7 +850,7 @@ private: static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const layer_state_t&, size_t numStates, bool firstTransaction) const; bool applyTransactionsLocked(std::vector<TransactionState>& transactions, VsyncId) REQUIRES(mStateLock); REQUIRES(mStateLock, kMainThreadContext); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock); Loading Loading @@ -1136,9 +1139,10 @@ private: void dumpHwcLayersMinidumpLockedLegacy(std::string& result) const REQUIRES(mStateLock); void appendSfConfigString(std::string& result) const; void listLayers(std::string& result) const; void dumpStats(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock); void clearStats(const DumpArgs& args, std::string& result); void listLayers(std::string& result) const REQUIRES(kMainThreadContext); void dumpStats(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock, kMainThreadContext); void clearStats(const DumpArgs& args, std::string& result) REQUIRES(kMainThreadContext); void dumpTimeStats(const DumpArgs& args, bool asProto, std::string& result) const; void dumpFrameTimeline(const DumpArgs& args, std::string& result) const; void logFrameStats(TimePoint now) REQUIRES(kMainThreadContext); Loading @@ -1156,7 +1160,8 @@ private: void dumpFrontEnd(std::string& result) REQUIRES(kMainThreadContext); void dumpVisibleFrontEnd(std::string& result) REQUIRES(mStateLock, kMainThreadContext); perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const; perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const REQUIRES(kMainThreadContext); void dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto, uint32_t traceFlags = LayerTracing::TRACE_ALL) const; google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> dumpDisplayProto() const; Loading Loading @@ -1204,7 +1209,8 @@ private: ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const REQUIRES(mStateLock); void traverseLegacyLayers(const LayerVector::Visitor& visitor) const; void traverseLegacyLayers(const LayerVector::Visitor& visitor) const REQUIRES(kMainThreadContext); void initBootProperties(); void initTransactionTraceWriter(); Loading Loading @@ -1482,23 +1488,25 @@ private: bool mLayerLifecycleManagerEnabled = false; bool mLegacyFrontEndEnabled = true; frontend::LayerLifecycleManager mLayerLifecycleManager; frontend::LayerHierarchyBuilder mLayerHierarchyBuilder; frontend::LayerSnapshotBuilder mLayerSnapshotBuilder; frontend::LayerLifecycleManager mLayerLifecycleManager GUARDED_BY(kMainThreadContext); frontend::LayerHierarchyBuilder mLayerHierarchyBuilder GUARDED_BY(kMainThreadContext); frontend::LayerSnapshotBuilder mLayerSnapshotBuilder GUARDED_BY(kMainThreadContext); std::vector<std::pair<uint32_t, std::string>> mDestroyedHandles; std::vector<std::unique_ptr<frontend::RequestedLayerState>> mNewLayers; std::vector<LayerCreationArgs> mNewLayerArgs; std::vector<std::pair<uint32_t, std::string>> mDestroyedHandles GUARDED_BY(mCreatedLayersLock); std::vector<std::unique_ptr<frontend::RequestedLayerState>> mNewLayers GUARDED_BY(mCreatedLayersLock); std::vector<LayerCreationArgs> mNewLayerArgs GUARDED_BY(mCreatedLayersLock); // These classes do not store any client state but help with managing transaction callbacks // and stats. std::unordered_map<uint32_t, sp<Layer>> mLegacyLayers; std::unordered_map<uint32_t, sp<Layer>> mLegacyLayers GUARDED_BY(kMainThreadContext); TransactionHandler mTransactionHandler; ui::DisplayMap<ui::LayerStack, frontend::DisplayInfo> mFrontEndDisplayInfos; bool mFrontEndDisplayInfosChanged = false; TransactionHandler mTransactionHandler GUARDED_BY(kMainThreadContext); ui::DisplayMap<ui::LayerStack, frontend::DisplayInfo> mFrontEndDisplayInfos GUARDED_BY(kMainThreadContext); bool mFrontEndDisplayInfosChanged GUARDED_BY(kMainThreadContext) = false; // WindowInfo ids visible during the last commit. std::unordered_set<int32_t> mVisibleWindowIds; std::unordered_set<int32_t> mVisibleWindowIds GUARDED_BY(kMainThreadContext); // Mirroring // Map of displayid to mirrorRoot Loading services/surfaceflinger/TransactionState.h +1 −1 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ struct TransactionState { } template <typename Visitor> void traverseStatesWithBuffersWhileTrue(Visitor&& visitor) { void traverseStatesWithBuffersWhileTrue(Visitor&& visitor) NO_THREAD_SAFETY_ANALYSIS { for (auto state = states.begin(); state != states.end();) { if (state->state.hasBufferChanges() && state->externalTexture && state->state.surface) { int result = visitor(*state); Loading services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +13 −4 Original line number Diff line number Diff line Loading @@ -492,9 +492,11 @@ public: auto& getTransactionQueue() { return mFlinger->mTransactionHandler.mLocklessTransactionQueue; } auto& getPendingTransactionQueue() { ftl::FakeGuard guard(kMainThreadContext); return mFlinger->mTransactionHandler.mPendingTransactionQueues; } size_t getPendingTransactionCount() { ftl::FakeGuard guard(kMainThreadContext); return mFlinger->mTransactionHandler.mPendingTransactionCount.load(); } Loading @@ -513,7 +515,9 @@ public: } auto setTransactionStateInternal(TransactionState& transaction) { return mFlinger->mTransactionHandler.queueTransaction(std::move(transaction)); return FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mTransactionHandler.queueTransaction( std::move(transaction))); } auto flushTransactionQueues() { Loading Loading @@ -598,15 +602,20 @@ public: } void injectLegacyLayer(sp<Layer> layer) { mFlinger->mLegacyLayers[static_cast<uint32_t>(layer->sequence)] = layer; FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mLegacyLayers[static_cast<uint32_t>(layer->sequence)] = layer); }; void releaseLegacyLayer(uint32_t sequence) { mFlinger->mLegacyLayers.erase(sequence); }; void releaseLegacyLayer(uint32_t sequence) { FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mLegacyLayers.erase(sequence)); }; auto setLayerHistoryDisplayArea(uint32_t displayArea) { return mFlinger->mScheduler->onActiveDisplayAreaChanged(displayArea); }; auto updateLayerHistory(nsecs_t now) { return mFlinger->updateLayerHistory(now); }; auto updateLayerHistory(nsecs_t now) { return FTL_FAKE_GUARD(kMainThreadContext, mFlinger->updateLayerHistory(now)); }; auto setDaltonizerType(ColorBlindnessType type) { mFlinger->mDaltonizer.setType(type); return mFlinger->updateColorMatrixLocked(); Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +142 −108 Original line number Diff line number Diff line Loading @@ -3178,7 +3178,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, if (mLayerLifecycleManagerEnabled) { mLayerSnapshotBuilder.forEachVisibleSnapshot( [&, compositionDisplay = compositionDisplay]( std::unique_ptr<frontend::LayerSnapshot>& snapshot) { std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(kMainThreadContext) { auto it = mLegacyLayers.find(snapshot->sequence); LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s", Loading Loading @@ -3237,7 +3238,7 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId, if (mNumTrustedPresentationListeners > 0) { // We avoid any reverse traversal upwards so this shouldn't be too expensive traverseLegacyLayers([&](Layer* layer) { traverseLegacyLayers([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) { if (!layer->hasTrustedPresentationListener()) { return; } Loading Loading @@ -4150,7 +4151,7 @@ void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos, outWindowInfos.push_back(snapshot.inputInfo); }); } else { mDrawingState.traverseInReverseZOrder([&](Layer* layer) { mDrawingState.traverseInReverseZOrder([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) { if (!layer->needsInputInfo()) return; const auto opt = mFrontEndDisplayInfos.get(layer->getLayerStack()) Loading Loading @@ -4855,6 +4856,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC if (listener && (flushState.queueProcessTime - transaction.postTime) > std::chrono::nanoseconds(4s).count()) { // Used to add a stalled transaction which uses an internal lock. ftl::FakeGuard guard(kMainThreadContext); mTransactionHandler .onTransactionQueueStalled(transaction.id, {.pid = layer->getOwnerPid(), Loading @@ -4877,8 +4880,9 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC const TransactionHandler::TransactionFlushState& flushState) { using TransactionReadiness = TransactionHandler::TransactionReadiness; auto ready = TransactionReadiness::Ready; flushState.transaction->traverseStatesWithBuffersWhileTrue([&](const ResolvedComposerState& resolvedState) -> bool { flushState.transaction->traverseStatesWithBuffersWhileTrue( [&](const ResolvedComposerState& resolvedState) FTL_FAKE_GUARD( kMainThreadContext) -> bool { const frontend::RequestedLayerState* layer = mLayerLifecycleManager.getLayerFromId(resolvedState.layerId); const auto& transaction = *flushState.transaction; Loading @@ -4886,16 +4890,18 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC // check for barrier frames if (s.bufferData->hasBarrier) { // The current producerId is already a newer producer than the buffer that has a // barrier. This means the incoming buffer is older and we can release it here. We // don't wait on the barrier since we know that's stale information. // barrier. This means the incoming buffer is older and we can release it here. // We don't wait on the barrier since we know that's stale information. if (layer->barrierProducerId > s.bufferData->producerId) { if (s.bufferData->releaseBufferListener) { uint32_t currentMaxAcquiredBufferCount = getMaxAcquiredBufferCountForCurrentRefreshRate(layer->ownerUid.val()); getMaxAcquiredBufferCountForCurrentRefreshRate( layer->ownerUid.val()); ATRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, layer->name.c_str(), s.bufferData->frameNumber); s.bufferData->releaseBufferListener ->onReleaseBuffer({resolvedState.externalTexture->getBuffer()->getId(), ->onReleaseBuffer({resolvedState.externalTexture->getBuffer() ->getId(), s.bufferData->frameNumber}, s.bufferData->acquireFence ? s.bufferData->acquireFence Loading @@ -4903,10 +4909,12 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC currentMaxAcquiredBufferCount); } // Delete the entire state at this point and not just release the buffer because // everything associated with the Layer in this Transaction is now out of date. ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d", layer->name.c_str(), layer->barrierProducerId, s.bufferData->producerId); // Delete the entire state at this point and not just release the buffer // because everything associated with the Layer in this Transaction is now // out of date. ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d", layer->name.c_str(), layer->barrierProducerId, s.bufferData->producerId); return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL; } Loading @@ -4916,7 +4924,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >= s.bufferData->barrierFrameNumber)); if (!willApplyBarrierFrame) { ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 " > %" PRId64, ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 " > %" PRId64, layer->name.c_str(), layer->barrierFrameNumber, s.bufferData->barrierFrameNumber); ready = TransactionReadiness::NotReadyBarrier; Loading @@ -4929,7 +4938,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC // the transaction in the queue. const bool hasPendingBuffer = flushState.bufferLayersReadyToPresent.contains(s.surface.get()); if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) { if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) { ATRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str()); ready = TransactionReadiness::NotReady; return TraverseBuffersReturnValues::STOP_TRAVERSAL; Loading @@ -4942,11 +4952,13 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled; if (!fenceSignaled) { // check fence status const bool allowLatchUnsignaled = shouldLatchUnsignaled(s, transaction.states.size(), const bool allowLatchUnsignaled = shouldLatchUnsignaled(s, transaction.states.size(), flushState.firstTransaction) && layer->isSimpleBufferUpdate(s); if (allowLatchUnsignaled) { ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s", layer->name.c_str()); ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s", layer->name.c_str()); ready = TransactionReadiness::NotReadyUnsignaled; } else { ready = TransactionReadiness::NotReady; Loading @@ -4960,7 +4972,8 @@ TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferC .layerId = layer->id, .layerName = layer->name, .bufferId = s.bufferData->getId(), .frameNumber = s.bufferData->frameNumber}); .frameNumber = s.bufferData->frameNumber}); } ATRACE_FORMAT("fence unsignaled %s", layer->name.c_str()); return TraverseBuffersReturnValues::STOP_TRAVERSAL; Loading Loading @@ -5188,7 +5201,13 @@ status_t SurfaceFlinger::setTransactionState( }(state.flags); const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone; { // Transactions are added via a lockless queue and does not need to be added from the main // thread. ftl::FakeGuard guard(kMainThreadContext); mTransactionHandler.queueTransaction(std::move(state)); } for (const auto& [displayId, data] : mNotifyExpectedPresentMap) { if (data.hintStatus.load() == NotifyExpectedPresentHintStatus::ScheduleOnTx) { scheduleNotifyExpectedPresentHint(displayId, VsyncId{frameTimelineInfo.vsyncId}); Loading Loading @@ -6030,7 +6049,11 @@ void SurfaceFlinger::onHandleDestroyed(BBinder* handle, sp<Layer>& layer, uint32 mDestroyedHandles.emplace_back(layerId, layer->getDebugName()); } { // Used to remove stalled transactions which uses an internal lock. ftl::FakeGuard guard(kMainThreadContext); mTransactionHandler.onLayerDestroyed(layerId); } Mutex::Autolock lock(mStateLock); markLayerPendingRemovalLocked(layer); Loading Loading @@ -6682,7 +6705,11 @@ void SurfaceFlinger::dumpOffscreenLayersProto(perfetto::protos::LayersProto& lay } perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) { return mScheduler->schedule([=, this] { return dumpDrawingStateProto(traceFlags); }).get(); return mScheduler ->schedule([=, this]() FTL_FAKE_GUARD(kMainThreadContext) { return dumpDrawingStateProto(traceFlags); }) .get(); } void SurfaceFlinger::dumpOffscreenLayers(std::string& result) { Loading Loading @@ -6731,7 +6758,8 @@ void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const { Layer::miniDumpHeader(result); const DisplayDevice& ref = *display; mLayerSnapshotBuilder.forEachVisibleSnapshot([&](const frontend::LayerSnapshot& snapshot) { mLayerSnapshotBuilder.forEachVisibleSnapshot( [&](const frontend::LayerSnapshot& snapshot) FTL_FAKE_GUARD(kMainThreadContext) { if (!snapshot.hasSomethingToDraw() || ref.getLayerStack() != snapshot.outputFilter.layerStack) { return; Loading Loading @@ -8057,7 +8085,8 @@ void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, } bool childrenOnly = args.childrenOnly; RenderAreaFuture renderAreaFuture = ftl::defer([=, this]() -> std::unique_ptr<RenderArea> { RenderAreaFuture renderAreaFuture = ftl::defer([=, this]() FTL_FAKE_GUARD(kMainThreadContext) -> std::unique_ptr<RenderArea> { ui::Transform layerTransform; Rect layerBufferSize; if (mLayerLifecycleManagerEnabled) { Loading Loading @@ -9029,6 +9058,8 @@ status_t SurfaceFlinger::removeWindowInfosListener( status_t SurfaceFlinger::getStalledTransactionInfo( int pid, std::optional<TransactionHandler::StalledTransactionInfo>& result) { // Used to add a stalled transaction which uses an internal lock. ftl::FakeGuard guard(kMainThreadContext); result = mTransactionHandler.getStalledTransactionInfo(pid); return NO_ERROR; } Loading Loading @@ -9229,7 +9260,8 @@ std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToComposit if (mLayerLifecycleManagerEnabled) { nsecs_t currentTime = systemTime(); mLayerSnapshotBuilder.forEachVisibleSnapshot( [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) { [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( kMainThreadContext) { if (cursorOnly && snapshot->compositionType != aidl::android::hardware::graphics::composer3::Composition::CURSOR) { Loading Loading @@ -9290,11 +9322,12 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots( std::optional<ui::LayerStack> layerStack, uint32_t uid, std::function<bool(const frontend::LayerSnapshot&, bool& outStopTraversal)> snapshotFilterFn) { return [&, layerStack, uid]() { return [&, layerStack, uid]() FTL_FAKE_GUARD(kMainThreadContext) { std::vector<std::pair<Layer*, sp<LayerFE>>> layers; bool stopTraversal = false; mLayerSnapshotBuilder.forEachVisibleSnapshot( [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) { [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD( kMainThreadContext) { if (stopTraversal) { return; } Loading Loading @@ -9329,7 +9362,8 @@ std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> SurfaceFlinger::getLayerSnapshotsForScreenshots(std::optional<ui::LayerStack> layerStack, uint32_t uid, std::unordered_set<uint32_t> excludeLayerIds) { return [&, layerStack, uid, excludeLayerIds = std::move(excludeLayerIds)]() { return [&, layerStack, uid, excludeLayerIds = std::move(excludeLayerIds)]() FTL_FAKE_GUARD(kMainThreadContext) { if (excludeLayerIds.empty()) { auto getLayerSnapshotsFn = getLayerSnapshotsForScreenshots(layerStack, uid, /*snapshotFilterFn=*/nullptr); Loading Loading @@ -9371,7 +9405,7 @@ SurfaceFlinger::getLayerSnapshotsForScreenshots(uint32_t rootLayerId, uint32_t u bool childrenOnly, const std::optional<FloatRect>& parentCrop) { return [&, rootLayerId, uid, excludeLayerIds = std::move(excludeLayerIds), childrenOnly, parentCrop]() { parentCrop]() FTL_FAKE_GUARD(kMainThreadContext) { auto root = mLayerHierarchyBuilder.getPartialHierarchy(rootLayerId, childrenOnly); frontend::LayerSnapshotBuilder::Args args{.root = root, Loading
services/surfaceflinger/SurfaceFlinger.h +35 −27 Original line number Diff line number Diff line Loading @@ -770,24 +770,27 @@ private: void updateLayerGeometry(); void updateLayerMetadataSnapshot(); std::vector<std::pair<Layer*, LayerFE*>> moveSnapshotsToCompositionArgs( compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly); compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) REQUIRES(kMainThreadContext); void moveSnapshotsFromCompositionArgs(compositionengine::CompositionRefreshArgs& refreshArgs, const std::vector<std::pair<Layer*, LayerFE*>>& layers); const std::vector<std::pair<Layer*, LayerFE*>>& layers) REQUIRES(kMainThreadContext); // Return true if we must composite this frame bool updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); // Return true if we must composite this frame bool updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); void updateLayerHistory(nsecs_t now); void updateLayerHistory(nsecs_t now) REQUIRES(kMainThreadContext); frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) REQUIRES(kMainThreadContext); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void buildWindowInfos(std::vector<gui::WindowInfo>& outWindowInfos, std::vector<gui::DisplayInfo>& outDisplayInfos); std::vector<gui::DisplayInfo>& outDisplayInfos) REQUIRES(kMainThreadContext); void commitInputWindowCommands() REQUIRES(mStateLock); void updateCursorAsync(); void updateCursorAsync() REQUIRES(kMainThreadContext); void initScheduler(const sp<const DisplayDevice>&) REQUIRES(kMainThreadContext, mStateLock); Loading @@ -803,7 +806,7 @@ private: const int64_t postTime, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid, uint64_t transactionId) REQUIRES(mStateLock); REQUIRES(mStateLock, kMainThreadContext); // Flush pending transactions that were presented after desiredPresentTime. // For test only bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext); Loading @@ -813,8 +816,8 @@ private: REQUIRES(kMainThreadContext, mStateLock); // Returns true if there is at least one transaction that needs to be flushed bool transactionFlushNeeded(); void addTransactionReadyFilters(); bool transactionFlushNeeded() REQUIRES(kMainThreadContext); void addTransactionReadyFilters() REQUIRES(kMainThreadContext); TransactionHandler::TransactionReadiness transactionReadyTimelineCheck( const TransactionHandler::TransactionFlushState& flushState) REQUIRES(kMainThreadContext); Loading @@ -831,7 +834,7 @@ private: uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock); REQUIRES(mStateLock, kMainThreadContext); uint32_t getTransactionFlags() const; // Sets the masked bits, and schedules a commit if needed. Loading @@ -847,7 +850,7 @@ private: static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const layer_state_t&, size_t numStates, bool firstTransaction) const; bool applyTransactionsLocked(std::vector<TransactionState>& transactions, VsyncId) REQUIRES(mStateLock); REQUIRES(mStateLock, kMainThreadContext); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock); Loading Loading @@ -1136,9 +1139,10 @@ private: void dumpHwcLayersMinidumpLockedLegacy(std::string& result) const REQUIRES(mStateLock); void appendSfConfigString(std::string& result) const; void listLayers(std::string& result) const; void dumpStats(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock); void clearStats(const DumpArgs& args, std::string& result); void listLayers(std::string& result) const REQUIRES(kMainThreadContext); void dumpStats(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock, kMainThreadContext); void clearStats(const DumpArgs& args, std::string& result) REQUIRES(kMainThreadContext); void dumpTimeStats(const DumpArgs& args, bool asProto, std::string& result) const; void dumpFrameTimeline(const DumpArgs& args, std::string& result) const; void logFrameStats(TimePoint now) REQUIRES(kMainThreadContext); Loading @@ -1156,7 +1160,8 @@ private: void dumpFrontEnd(std::string& result) REQUIRES(kMainThreadContext); void dumpVisibleFrontEnd(std::string& result) REQUIRES(mStateLock, kMainThreadContext); perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const; perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const REQUIRES(kMainThreadContext); void dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto, uint32_t traceFlags = LayerTracing::TRACE_ALL) const; google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> dumpDisplayProto() const; Loading Loading @@ -1204,7 +1209,8 @@ private: ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const REQUIRES(mStateLock); void traverseLegacyLayers(const LayerVector::Visitor& visitor) const; void traverseLegacyLayers(const LayerVector::Visitor& visitor) const REQUIRES(kMainThreadContext); void initBootProperties(); void initTransactionTraceWriter(); Loading Loading @@ -1482,23 +1488,25 @@ private: bool mLayerLifecycleManagerEnabled = false; bool mLegacyFrontEndEnabled = true; frontend::LayerLifecycleManager mLayerLifecycleManager; frontend::LayerHierarchyBuilder mLayerHierarchyBuilder; frontend::LayerSnapshotBuilder mLayerSnapshotBuilder; frontend::LayerLifecycleManager mLayerLifecycleManager GUARDED_BY(kMainThreadContext); frontend::LayerHierarchyBuilder mLayerHierarchyBuilder GUARDED_BY(kMainThreadContext); frontend::LayerSnapshotBuilder mLayerSnapshotBuilder GUARDED_BY(kMainThreadContext); std::vector<std::pair<uint32_t, std::string>> mDestroyedHandles; std::vector<std::unique_ptr<frontend::RequestedLayerState>> mNewLayers; std::vector<LayerCreationArgs> mNewLayerArgs; std::vector<std::pair<uint32_t, std::string>> mDestroyedHandles GUARDED_BY(mCreatedLayersLock); std::vector<std::unique_ptr<frontend::RequestedLayerState>> mNewLayers GUARDED_BY(mCreatedLayersLock); std::vector<LayerCreationArgs> mNewLayerArgs GUARDED_BY(mCreatedLayersLock); // These classes do not store any client state but help with managing transaction callbacks // and stats. std::unordered_map<uint32_t, sp<Layer>> mLegacyLayers; std::unordered_map<uint32_t, sp<Layer>> mLegacyLayers GUARDED_BY(kMainThreadContext); TransactionHandler mTransactionHandler; ui::DisplayMap<ui::LayerStack, frontend::DisplayInfo> mFrontEndDisplayInfos; bool mFrontEndDisplayInfosChanged = false; TransactionHandler mTransactionHandler GUARDED_BY(kMainThreadContext); ui::DisplayMap<ui::LayerStack, frontend::DisplayInfo> mFrontEndDisplayInfos GUARDED_BY(kMainThreadContext); bool mFrontEndDisplayInfosChanged GUARDED_BY(kMainThreadContext) = false; // WindowInfo ids visible during the last commit. std::unordered_set<int32_t> mVisibleWindowIds; std::unordered_set<int32_t> mVisibleWindowIds GUARDED_BY(kMainThreadContext); // Mirroring // Map of displayid to mirrorRoot Loading
services/surfaceflinger/TransactionState.h +1 −1 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ struct TransactionState { } template <typename Visitor> void traverseStatesWithBuffersWhileTrue(Visitor&& visitor) { void traverseStatesWithBuffersWhileTrue(Visitor&& visitor) NO_THREAD_SAFETY_ANALYSIS { for (auto state = states.begin(); state != states.end();) { if (state->state.hasBufferChanges() && state->externalTexture && state->state.surface) { int result = visitor(*state); Loading
services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +13 −4 Original line number Diff line number Diff line Loading @@ -492,9 +492,11 @@ public: auto& getTransactionQueue() { return mFlinger->mTransactionHandler.mLocklessTransactionQueue; } auto& getPendingTransactionQueue() { ftl::FakeGuard guard(kMainThreadContext); return mFlinger->mTransactionHandler.mPendingTransactionQueues; } size_t getPendingTransactionCount() { ftl::FakeGuard guard(kMainThreadContext); return mFlinger->mTransactionHandler.mPendingTransactionCount.load(); } Loading @@ -513,7 +515,9 @@ public: } auto setTransactionStateInternal(TransactionState& transaction) { return mFlinger->mTransactionHandler.queueTransaction(std::move(transaction)); return FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mTransactionHandler.queueTransaction( std::move(transaction))); } auto flushTransactionQueues() { Loading Loading @@ -598,15 +602,20 @@ public: } void injectLegacyLayer(sp<Layer> layer) { mFlinger->mLegacyLayers[static_cast<uint32_t>(layer->sequence)] = layer; FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mLegacyLayers[static_cast<uint32_t>(layer->sequence)] = layer); }; void releaseLegacyLayer(uint32_t sequence) { mFlinger->mLegacyLayers.erase(sequence); }; void releaseLegacyLayer(uint32_t sequence) { FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mLegacyLayers.erase(sequence)); }; auto setLayerHistoryDisplayArea(uint32_t displayArea) { return mFlinger->mScheduler->onActiveDisplayAreaChanged(displayArea); }; auto updateLayerHistory(nsecs_t now) { return mFlinger->updateLayerHistory(now); }; auto updateLayerHistory(nsecs_t now) { return FTL_FAKE_GUARD(kMainThreadContext, mFlinger->updateLayerHistory(now)); }; auto setDaltonizerType(ColorBlindnessType type) { mFlinger->mDaltonizer.setType(type); return mFlinger->updateColorMatrixLocked(); Loading