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

Commit ef9960b6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add thread safety annotations to frontend" into main

parents 05a16bf2 7be2760b
Loading
Loading
Loading
Loading
+142 −108
Original line number Diff line number Diff line
@@ -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",
@@ -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;
            }
@@ -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())
@@ -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(),
@@ -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;
@@ -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
@@ -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;
                    }

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