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

Commit 46f3e3b6 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Merge commit/composite in MessageQueue

scheduleComposite is unnecessary, as commit and/or composite are
dispatched from the same message/task.

Bug: 185535769
Test: libsurfaceflinger_unittest
Change-Id: I8de8b89d9311049598165a46a30ddbf6a4d0c8d4
parent 3ecdfeaf
Loading
Loading
Loading
Loading
+18 −33
Original line number Diff line number Diff line
@@ -30,41 +30,30 @@

namespace android::impl {

void MessageQueue::Handler::dispatchComposite() {
    if ((mEventMask.fetch_or(kComposite) & kComposite) == 0) {
        mQueue.mLooper->sendMessage(this, Message(kComposite));
    }
}

void MessageQueue::Handler::dispatchCommit(int64_t vsyncId, nsecs_t expectedVsyncTime) {
    if ((mEventMask.fetch_or(kCommit) & kCommit) == 0) {
void MessageQueue::Handler::dispatchFrame(int64_t vsyncId, nsecs_t expectedVsyncTime) {
    if (!mFramePending.exchange(true)) {
        mVsyncId = vsyncId;
        mExpectedVsyncTime = expectedVsyncTime;
        mQueue.mLooper->sendMessage(this, Message(kCommit));
        mQueue.mLooper->sendMessage(this, Message());
    }
}

bool MessageQueue::Handler::isFramePending() const {
    constexpr auto kPendingMask = kCommit | kComposite;
    return (mEventMask.load() & kPendingMask) != 0;
    return mFramePending.load();
}

void MessageQueue::Handler::handleMessage(const Message& message) {
void MessageQueue::Handler::handleMessage(const Message&) {
    mFramePending.store(false);

    const nsecs_t frameTime = systemTime();
    switch (message.what) {
        case kCommit:
            mEventMask.fetch_and(~kCommit);
            if (!mQueue.mCompositor.commit(frameTime, mVsyncId, mExpectedVsyncTime)) {
    auto& compositor = mQueue.mCompositor;

    if (!compositor.commit(frameTime, mVsyncId, mExpectedVsyncTime)) {
        return;
    }
            // Composite immediately, rather than after pending tasks through scheduleComposite.
            [[fallthrough]];
        case kComposite:
            mEventMask.fetch_and(~kComposite);
            mQueue.mCompositor.composite(frameTime);
            mQueue.mCompositor.sample();
            break;
    }

    compositor.composite(frameTime);
    compositor.sample();
}

MessageQueue::MessageQueue(ICompositor& compositor)
@@ -122,7 +111,7 @@ void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, ns
    const auto vsyncId = mVsync.tokenManager->generateTokenForPredictions(
            {targetWakeupTime, readyTime, vsyncTime});

    mHandler->dispatchCommit(vsyncId, vsyncTime);
    mHandler->dispatchFrame(vsyncId, vsyncTime);
}

void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch,
@@ -176,7 +165,7 @@ void MessageQueue::postMessage(sp<MessageHandler>&& handler) {
    mLooper->sendMessage(handler, Message());
}

void MessageQueue::scheduleCommit() {
void MessageQueue::scheduleFrame() {
    ATRACE_CALL();

    {
@@ -195,18 +184,14 @@ void MessageQueue::scheduleCommit() {
                                           .earliestVsync = mVsync.lastCallbackTime.count()});
}

void MessageQueue::scheduleComposite() {
    mHandler->dispatchComposite();
}

void MessageQueue::injectorCallback() {
    ssize_t n;
    DisplayEventReceiver::Event buffer[8];
    while ((n = DisplayEventReceiver::getEvents(&mInjector.tube, buffer, 8)) > 0) {
        for (int i = 0; i < n; i++) {
            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                mHandler->dispatchCommit(buffer[i].vsync.vsyncId,
                                         buffer[i].vsync.expectedVSyncTimestamp);
                auto& vsync = buffer[i].vsync;
                mHandler->dispatchFrame(vsync.vsyncId, vsync.expectedVSyncTimestamp);
                break;
            }
        }
+4 −10
Original line number Diff line number Diff line
@@ -71,8 +71,7 @@ public:
    virtual void setInjector(sp<EventThreadConnection>) = 0;
    virtual void waitMessage() = 0;
    virtual void postMessage(sp<MessageHandler>&&) = 0;
    virtual void scheduleCommit() = 0;
    virtual void scheduleComposite() = 0;
    virtual void scheduleFrame() = 0;

    using Clock = std::chrono::steady_clock;
    virtual std::optional<Clock::time_point> getScheduledFrameTime() const = 0;
@@ -83,11 +82,8 @@ namespace impl {
class MessageQueue : public android::MessageQueue {
protected:
    class Handler : public MessageHandler {
        static constexpr uint32_t kCommit = 0b1;
        static constexpr uint32_t kComposite = 0b10;

        MessageQueue& mQueue;
        std::atomic<uint32_t> mEventMask = 0;
        std::atomic_bool mFramePending = false;
        std::atomic<int64_t> mVsyncId = 0;
        std::atomic<nsecs_t> mExpectedVsyncTime = 0;

@@ -97,8 +93,7 @@ protected:

        bool isFramePending() const;

        virtual void dispatchCommit(int64_t vsyncId, nsecs_t expectedVsyncTime);
        void dispatchComposite();
        virtual void dispatchFrame(int64_t vsyncId, nsecs_t expectedVsyncTime);
    };

    friend class Handler;
@@ -147,8 +142,7 @@ public:
    void waitMessage() override;
    void postMessage(sp<MessageHandler>&&) override;

    void scheduleCommit() override;
    void scheduleComposite() override;
    void scheduleFrame() override;

    std::optional<Clock::time_point> getScheduledFrameTime() const override;
};
+1 −2
Original line number Diff line number Diff line
@@ -97,8 +97,7 @@ public:
    using Impl::getScheduledFrameTime;
    using Impl::setDuration;

    using Impl::scheduleCommit;
    using Impl::scheduleComposite;
    using Impl::scheduleFrame;

    // Schedule an asynchronous or synchronous task on the main thread.
    template <typename F, typename T = std::invoke_result_t<F>>
+4 −6
Original line number Diff line number Diff line
@@ -1702,7 +1702,7 @@ void SurfaceFlinger::scheduleCommit(FrameHint hint) {
        mScheduler->resetIdleTimer();
    }
    mPowerAdvisor.notifyDisplayUpdateImminent();
    mScheduler->scheduleCommit();
    mScheduler->scheduleFrame();
}

void SurfaceFlinger::scheduleComposite(FrameHint hint) {
@@ -1928,7 +1928,7 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected
    // fired yet just wait for the next commit.
    if (mSetActiveModePending) {
        if (framePending) {
            mScheduler->scheduleCommit();
            mScheduler->scheduleFrame();
            return false;
        }

@@ -5324,6 +5324,7 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
                scheduleRepaint();
                return NO_ERROR;
            case 1004: // Force composite ahead of next VSYNC.
            case 1006:
                scheduleComposite(FrameHint::kActive);
                return NO_ERROR;
            case 1005: { // Force commit ahead of next VSYNC.
@@ -5332,9 +5333,6 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
                                    eTraversalNeeded);
                return NO_ERROR;
            }
            case 1006: // Force composite immediately.
                mScheduler->scheduleComposite();
                return NO_ERROR;
            case 1007: // Unused.
                return NAME_NOT_FOUND;
            case 1008: // Toggle forced GPU composition.
@@ -5752,7 +5750,7 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) {
        const bool timerExpired = mKernelIdleTimerEnabled && expired;

        if (display->onKernelTimerChanged(desiredModeId, timerExpired)) {
            mScheduler->scheduleCommit();
            mScheduler->scheduleFrame();
        }
    }));
}
+1 −1
Original line number Diff line number Diff line
@@ -536,7 +536,7 @@ struct BaseLayerProperties {
        ASSERT_EQ(NO_ERROR, err);
        Mock::VerifyAndClear(test->mRenderEngine);

        EXPECT_CALL(*test->mFlinger.scheduler(), scheduleCommit()).Times(1);
        EXPECT_CALL(*test->mFlinger.scheduler(), scheduleFrame()).Times(1);
        enqueueBuffer(test, layer);
        Mock::VerifyAndClearExpectations(test->mFlinger.scheduler());

Loading