Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7be2760b authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Add thread safety annotations to frontend

Fixes: 281857977
Test: builds
Change-Id: Ic80fbadc6d5a15a021fb54f4f6e03601b7454b64
parent 06bf5557
Loading
Loading
Loading
Loading
+142 −108
Original line number Diff line number Diff line
@@ -3171,7 +3171,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",
@@ -3230,7 +3231,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;
            }
@@ -4143,7 +4144,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())
@@ -4848,6 +4849,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(),
@@ -4870,8 +4873,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;
@@ -4879,16 +4883,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
@@ -4896,10 +4902,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;
                    }

@@ -4909,7 +4917,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;
@@ -4922,7 +4931,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;
@@ -4935,11 +4945,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;
@@ -4953,7 +4965,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;
@@ -5181,7 +5194,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});
@@ -6023,7 +6042,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);
@@ -6675,7 +6698,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) {
@@ -6724,7 +6751,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;
@@ -8044,7 +8072,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) {
@@ -9014,6 +9043,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;
}
@@ -9214,7 +9245,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) {
@@ -9275,11 +9307,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;
                    }
@@ -9314,7 +9347,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);
@@ -9356,7 +9390,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,
+35 −27
Original line number Diff line number Diff line
@@ -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);

@@ -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);
@@ -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);
@@ -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.
@@ -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);
@@ -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);
@@ -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;
@@ -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();
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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);
+13 −4
Original line number Diff line number Diff line
@@ -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();
    }

@@ -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() {
@@ -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();