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

Commit f2851617 authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: add IEventThreadCallback to EventThread

.. so it will be easier to add more callbacks to EventThread

Bug: 299378819
Test: presubmit
Change-Id: I3787be9ad8162b059b4d59255581cd14cbcf1cd8
parent d03b24d6
Loading
Loading
Loading
Loading
+16 −28
Original line number Diff line number Diff line
@@ -171,10 +171,8 @@ DisplayEventReceiver::Event makeFrameRateOverrideFlushEvent(PhysicalDisplayId di
} // namespace

EventThreadConnection::EventThreadConnection(EventThread* eventThread, uid_t callingUid,
                                             ResyncCallback resyncCallback,
                                             EventRegistrationFlags eventRegistration)
      : resyncCallback(std::move(resyncCallback)),
        mOwnerUid(callingUid),
      : mOwnerUid(callingUid),
        mEventRegistration(eventRegistration),
        mEventThread(eventThread),
        mChannel(gui::BitTube::DefaultSize) {}
@@ -250,9 +248,7 @@ namespace impl {

EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule,
                         android::frametimeline::TokenManager* tokenManager,
                         ThrottleVsyncCallback throttleVsyncCallback,
                         GetVsyncPeriodFunction getVsyncPeriodFunction,
                         std::chrono::nanoseconds workDuration,
                         IEventThreadCallback& callback, std::chrono::nanoseconds workDuration,
                         std::chrono::nanoseconds readyDuration)
      : mThreadName(name),
        mVsyncTracer(base::StringPrintf("VSYNC-%s", name), 0),
@@ -261,11 +257,7 @@ EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSched
        mVsyncSchedule(std::move(vsyncSchedule)),
        mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name),
        mTokenManager(tokenManager),
        mThrottleVsyncCallback(std::move(throttleVsyncCallback)),
        mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)) {
    LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction == nullptr,
            "getVsyncPeriodFunction must not be null");

        mCallback(callback) {
    mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
        std::unique_lock<std::mutex> lock(mMutex);
        threadMain(lock);
@@ -307,10 +299,10 @@ void EventThread::setDuration(std::chrono::nanoseconds workDuration,
}

sp<EventThreadConnection> EventThread::createEventConnection(
        ResyncCallback resyncCallback, EventRegistrationFlags eventRegistration) const {
        EventRegistrationFlags eventRegistration) const {
    return sp<EventThreadConnection>::make(const_cast<EventThread*>(this),
                                           IPCThreadState::self()->getCallingUid(),
                                           std::move(resyncCallback), eventRegistration);
                                           eventRegistration);
}

status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
@@ -353,9 +345,7 @@ void EventThread::setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& c
}

void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
    if (connection->resyncCallback) {
        connection->resyncCallback();
    }
    mCallback.resync();

    std::lock_guard<std::mutex> lock(mMutex);

@@ -371,20 +361,18 @@ VsyncEventData EventThread::getLatestVsyncEventData(
        const sp<EventThreadConnection>& connection) const {
    // Resync so that the vsync is accurate with hardware. getLatestVsyncEventData is an alternate
    // way to get vsync data (instead of posting callbacks to Choreographer).
    if (connection->resyncCallback) {
        connection->resyncCallback();
    }
    mCallback.resync();

    VsyncEventData vsyncEventData;
    nsecs_t frameInterval = mGetVsyncPeriodFunction(connection->mOwnerUid);
    vsyncEventData.frameInterval = frameInterval;
    const Period frameInterval = mCallback.getVsyncPeriod(connection->mOwnerUid);
    vsyncEventData.frameInterval = frameInterval.ns();
    const auto [presentTime, deadline] = [&]() -> std::pair<nsecs_t, nsecs_t> {
        std::lock_guard<std::mutex> lock(mMutex);
        const auto vsyncTime = mVsyncSchedule->getTracker().nextAnticipatedVSyncTimeFrom(
                systemTime() + mWorkDuration.get().count() + mReadyDuration.count());
        return {vsyncTime, vsyncTime - mReadyDuration.count()};
    }();
    generateFrameTimeline(vsyncEventData, frameInterval, systemTime(SYSTEM_TIME_MONOTONIC),
    generateFrameTimeline(vsyncEventData, frameInterval.ns(), systemTime(SYSTEM_TIME_MONOTONIC),
                          presentTime, deadline);
    return vsyncEventData;
}
@@ -549,9 +537,9 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
                                            connection->frameRate);
        }

        return mThrottleVsyncCallback &&
                mThrottleVsyncCallback(event.vsync.vsyncData.preferredExpectedPresentationTime(),
                                       connection->mOwnerUid);
        const auto expectedPresentTime =
                TimePoint::fromNs(event.vsync.vsyncData.preferredExpectedPresentationTime());
        return mCallback.throttleVsync(expectedPresentTime, connection->mOwnerUid);
    };

    switch (event.header.type) {
@@ -671,9 +659,9 @@ void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
    for (const auto& consumer : consumers) {
        DisplayEventReceiver::Event copy = event;
        if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
            const int64_t frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
            copy.vsync.vsyncData.frameInterval = frameInterval;
            generateFrameTimeline(copy.vsync.vsyncData, frameInterval, copy.header.timestamp,
            const Period frameInterval = mCallback.getVsyncPeriod(consumer->mOwnerUid);
            copy.vsync.vsyncData.frameInterval = frameInterval.ns();
            generateFrameTimeline(copy.vsync.vsyncData, frameInterval.ns(), copy.header.timestamp,
                                  event.vsync.vsyncData.preferredExpectedPresentationTime(),
                                  event.vsync.vsyncData.preferredDeadlineTimestamp());
        }
+13 −13
Original line number Diff line number Diff line
@@ -54,7 +54,6 @@ using gui::VsyncEventData;

// ---------------------------------------------------------------------------

using ResyncCallback = std::function<void()>;
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;

enum class VSyncRequest {
@@ -69,7 +68,7 @@ enum class VSyncRequest {

class EventThreadConnection : public gui::BnDisplayEventConnection {
public:
    EventThreadConnection(EventThread*, uid_t callingUid, ResyncCallback,
    EventThreadConnection(EventThread*, uid_t callingUid,
                          EventRegistrationFlags eventRegistration = {});
    virtual ~EventThreadConnection();

@@ -80,9 +79,6 @@ public:
    binder::Status requestNextVsync() override; // asynchronous
    binder::Status getLatestVsyncEventData(ParcelableVsyncEventData* outVsyncEventData) override;

    // Called in response to requestNextVsync.
    const ResyncCallback resyncCallback;

    VSyncRequest vsyncRequest = VSyncRequest::None;
    const uid_t mOwnerUid;
    const EventRegistrationFlags mEventRegistration;
@@ -104,7 +100,7 @@ public:
    virtual ~EventThread();

    virtual sp<EventThreadConnection> createEventConnection(
            ResyncCallback, EventRegistrationFlags eventRegistration = {}) const = 0;
            EventRegistrationFlags eventRegistration = {}) const = 0;

    // Feed clients with fake VSYNC, e.g. while the display is off.
    virtual void enableSyntheticVsync(bool) = 0;
@@ -136,20 +132,25 @@ public:
    virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0;
};

struct IEventThreadCallback {
    virtual ~IEventThreadCallback() = default;

    virtual bool throttleVsync(TimePoint, uid_t) = 0;
    virtual Period getVsyncPeriod(uid_t) = 0;
    virtual void resync() = 0;
};

namespace impl {

class EventThread : public android::EventThread {
public:
    using ThrottleVsyncCallback = std::function<bool(nsecs_t, uid_t)>;
    using GetVsyncPeriodFunction = std::function<nsecs_t(uid_t)>;

    EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule>,
                frametimeline::TokenManager*, ThrottleVsyncCallback, GetVsyncPeriodFunction,
                frametimeline::TokenManager*, IEventThreadCallback& callback,
                std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration);
    ~EventThread();

    sp<EventThreadConnection> createEventConnection(
            ResyncCallback, EventRegistrationFlags eventRegistration = {}) const override;
            EventRegistrationFlags eventRegistration = {}) const override;

    status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
    void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
@@ -214,8 +215,7 @@ private:
    scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex);
    frametimeline::TokenManager* const mTokenManager;

    const ThrottleVsyncCallback mThrottleVsyncCallback;
    const GetVsyncPeriodFunction mGetVsyncPeriodFunction;
    IEventThreadCallback& mCallback;

    std::thread mThread;
    mutable std::mutex mMutex;
+27 −31
Original line number Diff line number Diff line
@@ -242,14 +242,11 @@ bool Scheduler::isVsyncInPhase(TimePoint expectedVsyncTime, Fps frameRate) const
    return getVsyncSchedule()->getTracker().isVSyncInPhase(expectedVsyncTime.ns(), frameRate);
}

impl::EventThread::ThrottleVsyncCallback Scheduler::makeThrottleVsyncCallback() const {
    return [this](nsecs_t expectedVsyncTime, uid_t uid) {
        return !isVsyncValid(TimePoint::fromNs(expectedVsyncTime), uid);
    };
bool Scheduler::throttleVsync(android::TimePoint expectedPresentTime, uid_t uid) {
    return !isVsyncValid(expectedPresentTime, uid);
}

impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction() const {
    return [this](uid_t uid) {
Period Scheduler::getVsyncPeriod(uid_t uid) {
    const auto [refreshRate, period] = [this] {
        std::scoped_lock lock(mDisplayLock);
        const auto pacesetterOpt = pacesetterDisplayLocked();
@@ -263,15 +260,17 @@ impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction(

    const auto frameRate = getFrameRateOverride(uid);
    if (!frameRate.has_value()) {
            return currentPeriod.ns();
        return currentPeriod;
    }

    const auto divisor = RefreshRateSelector::getFrameRateDivisor(refreshRate, *frameRate);
    if (divisor <= 1) {
            return currentPeriod.ns();
        return currentPeriod;
    }
        return currentPeriod.ns() * divisor;
    };

    // TODO(b/299378819): the casting is not needed, but we need a flag as it might change
    // behaviour.
    return Period::fromNs(currentPeriod.ns() * divisor);
}

ConnectionHandle Scheduler::createEventThread(Cycle cycle,
@@ -279,9 +278,7 @@ ConnectionHandle Scheduler::createEventThread(Cycle cycle,
                                              std::chrono::nanoseconds workDuration,
                                              std::chrono::nanoseconds readyDuration) {
    auto eventThread = std::make_unique<impl::EventThread>(cycle == Cycle::Render ? "app" : "appSf",
                                                           getVsyncSchedule(), tokenManager,
                                                           makeThrottleVsyncCallback(),
                                                           makeGetVsyncPeriodFunction(),
                                                           getVsyncSchedule(), tokenManager, *this,
                                                           workDuration, readyDuration);

    auto& handle = cycle == Cycle::Render ? mAppConnectionHandle : mSfConnectionHandle;
@@ -293,7 +290,7 @@ ConnectionHandle Scheduler::createConnection(std::unique_ptr<EventThread> eventT
    const ConnectionHandle handle = ConnectionHandle{mNextConnectionHandleId++};
    ALOGV("Creating a connection handle with ID %" PRIuPTR, handle.id);

    auto connection = eventThread->createEventConnection([&] { resync(); });
    auto connection = eventThread->createEventConnection();

    std::lock_guard<std::mutex> lock(mConnectionsLock);
    mConnections.emplace(handle, Connection{connection, std::move(eventThread)});
@@ -307,8 +304,7 @@ sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
        std::scoped_lock lock(mConnectionsLock);
        RETURN_IF_INVALID_HANDLE(handle, nullptr);

        return mConnections[handle].thread->createEventConnection([&] { resync(); },
                                                                  eventRegistration);
        return mConnections[handle].thread->createEventConnection(eventRegistration);
    }();
    const auto layerId = static_cast<int32_t>(LayerHandle::getLayerId(layerHandle));

+5 −4
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ using GlobalSignals = RefreshRateSelector::GlobalSignals;

class VsyncSchedule;

class Scheduler : android::impl::MessageQueue {
class Scheduler : public IEventThreadCallback, android::impl::MessageQueue {
    using Impl = android::impl::MessageQueue;

public:
@@ -217,7 +217,6 @@ public:
        ftl::FakeGuard guard(kMainThreadContext);
        resyncToHardwareVsyncLocked(id, allowToEnable, refreshRate);
    }
    void resync() EXCLUDES(mDisplayLock);
    void forceNextResync() { mLastResyncTime = 0; }

    // Passes a vsync sample to VsyncController. Returns true if
@@ -420,8 +419,10 @@ private:

    void dispatchCachedReportedMode() REQUIRES(mPolicyLock) EXCLUDES(mDisplayLock);

    android::impl::EventThread::ThrottleVsyncCallback makeThrottleVsyncCallback() const;
    android::impl::EventThread::GetVsyncPeriodFunction makeGetVsyncPeriodFunction() const;
    // IEventThreadCallback overrides
    bool throttleVsync(TimePoint, uid_t) override;
    Period getVsyncPeriod(uid_t) override EXCLUDES(mDisplayLock);
    void resync() override EXCLUDES(mDisplayLock);

    // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
    struct Connection {
+9 −4
Original line number Diff line number Diff line
@@ -97,21 +97,26 @@ PhysicalDisplayId SchedulerFuzzer::getPhysicalDisplayId() {
    return displayId;
}

struct EventThreadCallback : public IEventThreadCallback {
    bool throttleVsync(TimePoint, uid_t) override { return false; }
    Period getVsyncPeriod(uid_t) override { return kSyncPeriod; }
    void resync() override {}
};

void SchedulerFuzzer::fuzzEventThread() {
    mVsyncSchedule = std::shared_ptr<scheduler::VsyncSchedule>(
            new scheduler::VsyncSchedule(getPhysicalDisplayId(),
                                         std::make_shared<mock::VSyncTracker>(),
                                         std::make_shared<mock::VSyncDispatch>(), nullptr));
    const auto getVsyncPeriod = [](uid_t /* uid */) { return kSyncPeriod.count(); };
    EventThreadCallback callback;
    std::unique_ptr<android::impl::EventThread> thread = std::make_unique<
            android::impl::EventThread>("fuzzer", mVsyncSchedule, nullptr, nullptr, getVsyncPeriod,
            android::impl::EventThread>("fuzzer", mVsyncSchedule, nullptr, callback,
                                        (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>(),
                                        (std::chrono::nanoseconds)mFdp.ConsumeIntegral<uint64_t>());

    thread->onHotplugReceived(getPhysicalDisplayId(), mFdp.ConsumeBool());
    sp<EventThreadConnection> connection =
            sp<EventThreadConnection>::make(thread.get(), mFdp.ConsumeIntegral<uint16_t>(),
                                            nullptr);
            sp<EventThreadConnection>::make(thread.get(), mFdp.ConsumeIntegral<uint16_t>());
    thread->requestNextVsync(connection);
    thread->setVsyncRate(mFdp.ConsumeIntegral<uint32_t>() /*rate*/, connection);

Loading