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

Commit f654d570 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Register resync callback per event connection

This CL ties the resync callback to an EventThreadConnection instead
of an EventThread. This is a step towards having IDisplayEventConnection
subscribe to a given display rather than the primary display implicitly.
Each display will then have SurfaceFlinger::VsyncState that resyncs
independently at potentially different rates. Callbacks have weak
references to the per-display VsyncState owned by SurfaceFlinger.

Bug: 74619554
Test: Boot and turn display on/off repeatedly
Change-Id: Ic7cc64e2004fa07a5d54431fc330995048a4ed20
parent e0d55a18
Loading
Loading
Loading
Loading
+15 −15
Original line number Original line Diff line number Diff line
@@ -43,8 +43,12 @@ namespace android {


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


EventThreadConnection::EventThreadConnection(EventThread* eventThread)
EventThreadConnection::EventThreadConnection(EventThread* eventThread,
      : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
                                             ResyncCallback resyncCallback)
      : resyncCallback(std::move(resyncCallback)),
        count(-1),
        mEventThread(eventThread),
        mChannel(gui::BitTube::DefaultSize) {}


EventThreadConnection::~EventThreadConnection() {
EventThreadConnection::~EventThreadConnection() {
    // do nothing here -- clean-up will happen automatically
    // do nothing here -- clean-up will happen automatically
@@ -88,26 +92,21 @@ EventThread::~EventThread() = default;
namespace impl {
namespace impl {


EventThread::EventThread(std::unique_ptr<VSyncSource> src,
EventThread::EventThread(std::unique_ptr<VSyncSource> src,
                         const ResyncWithRateLimitCallback& resyncWithRateLimitCallback,
                         const InterceptVSyncsCallback& interceptVSyncsCallback,
                         const InterceptVSyncsCallback& interceptVSyncsCallback,
                         const ResetIdleTimerCallback& resetIdleTimerCallback,
                         const ResetIdleTimerCallback& resetIdleTimerCallback,
                         const char* threadName)
                         const char* threadName)
      : EventThread(nullptr, std::move(src), resyncWithRateLimitCallback, interceptVSyncsCallback,
      : EventThread(nullptr, std::move(src), interceptVSyncsCallback, threadName) {
                    threadName) {
    mResetIdleTimer = resetIdleTimerCallback;
    mResetIdleTimer = resetIdleTimerCallback;
}
}


EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
EventThread::EventThread(VSyncSource* src, InterceptVSyncsCallback interceptVSyncsCallback,
                         InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
                         const char* threadName)
      : EventThread(src, nullptr, resyncWithRateLimitCallback, interceptVSyncsCallback,
      : EventThread(src, nullptr, interceptVSyncsCallback, threadName) {}
                    threadName) {}


EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
                         ResyncWithRateLimitCallback resyncWithRateLimitCallback,
                         InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
                         InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
      : mVSyncSource(src),
      : mVSyncSource(src),
        mVSyncSourceUnique(std::move(uniqueSrc)),
        mVSyncSourceUnique(std::move(uniqueSrc)),
        mResyncWithRateLimitCallback(resyncWithRateLimitCallback),
        mInterceptVSyncsCallback(interceptVSyncsCallback) {
        mInterceptVSyncsCallback(interceptVSyncsCallback) {
    if (src == nullptr) {
    if (src == nullptr) {
        mVSyncSource = mVSyncSourceUnique.get();
        mVSyncSource = mVSyncSourceUnique.get();
@@ -150,8 +149,8 @@ void EventThread::setPhaseOffset(nsecs_t phaseOffset) {
    mVSyncSource->setPhaseOffset(phaseOffset);
    mVSyncSource->setPhaseOffset(phaseOffset);
}
}


sp<EventThreadConnection> EventThread::createEventConnection() const {
sp<EventThreadConnection> EventThread::createEventConnection(ResyncCallback resyncCallback) const {
    return new EventThreadConnection(const_cast<EventThread*>(this));
    return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback));
}
}


status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
@@ -195,8 +194,9 @@ void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection,
        ATRACE_NAME("resetIdleTimer");
        ATRACE_NAME("resetIdleTimer");
        mResetIdleTimer();
        mResetIdleTimer();
    }
    }
    if (mResyncWithRateLimitCallback) {

        mResyncWithRateLimitCallback();
    if (connection->resyncCallback) {
        connection->resyncCallback();
    }
    }


    std::lock_guard<std::mutex> lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);
+11 −9
Original line number Original line Diff line number Diff line
@@ -44,6 +44,8 @@ class SurfaceFlinger;


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


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

class VSyncSource {
class VSyncSource {
public:
public:
    class Callback {
    class Callback {
@@ -60,7 +62,7 @@ public:


class EventThreadConnection : public BnDisplayEventConnection {
class EventThreadConnection : public BnDisplayEventConnection {
public:
public:
    explicit EventThreadConnection(EventThread* eventThread);
    EventThreadConnection(EventThread* eventThread, ResyncCallback resyncCallback);
    virtual ~EventThreadConnection();
    virtual ~EventThreadConnection();


    virtual status_t postEvent(const DisplayEventReceiver::Event& event);
    virtual status_t postEvent(const DisplayEventReceiver::Event& event);
@@ -72,6 +74,9 @@ public:
    // in order to update the configs.
    // in order to update the configs.
    void requestNextVsyncForHWC();
    void requestNextVsyncForHWC();


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

    // count >= 1 : continuous event. count is the vsync rate
    // count >= 1 : continuous event. count is the vsync rate
    // count == 0 : one-shot event that has not fired
    // count == 0 : one-shot event that has not fired
    // count ==-1 : one-shot event that fired this round / disabled
    // count ==-1 : one-shot event that fired this round / disabled
@@ -90,7 +95,8 @@ public:


    virtual ~EventThread();
    virtual ~EventThread();


    virtual sp<EventThreadConnection> createEventConnection() const = 0;
    virtual sp<EventThreadConnection> createEventConnection(
            ResyncCallback resyncCallback) const = 0;


    // called before the screen is turned off from main thread
    // called before the screen is turned off from main thread
    virtual void onScreenReleased() = 0;
    virtual void onScreenReleased() = 0;
@@ -117,20 +123,18 @@ namespace impl {


class EventThread : public android::EventThread, private VSyncSource::Callback {
class EventThread : public android::EventThread, private VSyncSource::Callback {
public:
public:
    using ResyncWithRateLimitCallback = std::function<void()>;
    using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
    using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
    using ResetIdleTimerCallback = std::function<void()>;
    using ResetIdleTimerCallback = std::function<void()>;


    // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
    // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
    EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
    EventThread(VSyncSource* src, InterceptVSyncsCallback interceptVSyncsCallback,
                InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
                const char* threadName);
    EventThread(std::unique_ptr<VSyncSource> src,
    EventThread(std::unique_ptr<VSyncSource> src,
                const ResyncWithRateLimitCallback& resyncWithRateLimitCallback,
                const InterceptVSyncsCallback& interceptVSyncsCallback,
                const InterceptVSyncsCallback& interceptVSyncsCallback,
                const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
                const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
    ~EventThread();
    ~EventThread();


    sp<EventThreadConnection> createEventConnection() const override;
    sp<EventThreadConnection> createEventConnection(ResyncCallback resyncCallback) const override;


    status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
    status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
    void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override;
    void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override;
@@ -155,7 +159,6 @@ private:


    // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
    // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete.
    EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
    EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
                ResyncWithRateLimitCallback resyncWithRateLimitCallback,
                InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);
                InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);




@@ -179,7 +182,6 @@ private:
    VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr;
    VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr;
    std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr;
    std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr;
    // constants
    // constants
    const ResyncWithRateLimitCallback mResyncWithRateLimitCallback;
    const InterceptVSyncsCallback mInterceptVSyncsCallback;
    const InterceptVSyncsCallback mInterceptVSyncsCallback;


    std::thread mThread;
    std::thread mThread;
+3 −2
Original line number Original line Diff line number Diff line
@@ -85,7 +85,8 @@ void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
    mHandler = new Handler(*this);
    mHandler = new Handler(*this);
}
}


void MessageQueue::setEventThread(android::EventThread* eventThread) {
void MessageQueue::setEventThread(android::EventThread* eventThread,
                                  ResyncCallback resyncCallback) {
    if (mEventThread == eventThread) {
    if (mEventThread == eventThread) {
        return;
        return;
    }
    }
@@ -95,7 +96,7 @@ void MessageQueue::setEventThread(android::EventThread* eventThread) {
    }
    }


    mEventThread = eventThread;
    mEventThread = eventThread;
    mEvents = eventThread->createEventConnection();
    mEvents = eventThread->createEventConnection(std::move(resyncCallback));
    mEvents->stealReceiveChannel(&mEventTube);
    mEvents->stealReceiveChannel(&mEventTube);
    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
                   this);
                   this);
+3 −3
Original line number Original line Diff line number Diff line
@@ -29,12 +29,12 @@
#include <private/gui/BitTube.h>
#include <private/gui/BitTube.h>


#include "Barrier.h"
#include "Barrier.h"
#include "EventThread.h"


#include <functional>
#include <functional>


namespace android {
namespace android {


class EventThread;
class SurfaceFlinger;
class SurfaceFlinger;


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
@@ -86,7 +86,7 @@ public:


    virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
    virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
    // TODO(akrulec): Remove this function once everything is migrated to Scheduler.
    // TODO(akrulec): Remove this function once everything is migrated to Scheduler.
    virtual void setEventThread(EventThread* events) = 0;
    virtual void setEventThread(EventThread* events, ResyncCallback resyncCallback) = 0;
    virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
    virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
    virtual void waitMessage() = 0;
    virtual void waitMessage() = 0;
    virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
    virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
@@ -127,7 +127,7 @@ class MessageQueue final : public android::MessageQueue {
public:
public:
    ~MessageQueue() override = default;
    ~MessageQueue() override = default;
    void init(const sp<SurfaceFlinger>& flinger) override;
    void init(const sp<SurfaceFlinger>& flinger) override;
    void setEventThread(android::EventThread* events) override;
    void setEventThread(android::EventThread* events, ResyncCallback resyncCallback) override;
    void setEventConnection(const sp<EventThreadConnection>& connection) override;
    void setEventConnection(const sp<EventThreadConnection>& connection) override;


    void waitMessage() override;
    void waitMessage() override;
+9 −10
Original line number Original line Diff line number Diff line
@@ -86,39 +86,38 @@ Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function)
Scheduler::~Scheduler() = default;
Scheduler::~Scheduler() = default;


sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
        const std::string& connectionName, int64_t phaseOffsetNs,
        const std::string& connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
        impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
    const int64_t id = sNextId++;
    const int64_t id = sNextId++;
    ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
    ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);


    std::unique_ptr<EventThread> eventThread =
    std::unique_ptr<EventThread> eventThread =
            makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs, resyncCallback,
            makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
                            interceptCallback);
                            interceptCallback);
    auto connection = std::make_unique<Connection>(new ConnectionHandle(id),
    auto connection = std::make_unique<Connection>(new ConnectionHandle(id),
                                                   eventThread->createEventConnection(),
                                                   eventThread->createEventConnection(
                                                           std::move(resyncCallback)),
                                                   std::move(eventThread));
                                                   std::move(eventThread));

    mConnections.insert(std::make_pair(id, std::move(connection)));
    mConnections.insert(std::make_pair(id, std::move(connection)));
    return mConnections[id]->handle;
    return mConnections[id]->handle;
}
}


std::unique_ptr<EventThread> Scheduler::makeEventThread(
std::unique_ptr<EventThread> Scheduler::makeEventThread(
        const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
        const std::string& connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
        impl::EventThread::ResyncWithRateLimitCallback resyncCallback,
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
    const std::string sourceName = connectionName + "Source";
    const std::string sourceName = connectionName + "Source";
    std::unique_ptr<VSyncSource> eventThreadSource =
    std::unique_ptr<VSyncSource> eventThreadSource =
            std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, sourceName.c_str());
            std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, sourceName.c_str());
    const std::string threadName = connectionName + "Thread";
    const std::string threadName = connectionName + "Thread";
    return std::make_unique<impl::EventThread>(std::move(eventThreadSource), resyncCallback,
    return std::make_unique<impl::EventThread>(std::move(eventThreadSource), interceptCallback,
                                               interceptCallback, [this] { resetIdleTimer(); },
                                               [this] { resetIdleTimer(); }, threadName.c_str());
                                               threadName.c_str());
}
}


sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
        const sp<Scheduler::ConnectionHandle>& handle) {
        const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback) {
    RETURN_VALUE_IF_INVALID(nullptr);
    RETURN_VALUE_IF_INVALID(nullptr);
    return mConnections[handle->id]->thread->createEventConnection();
    return mConnections[handle->id]->thread->createEventConnection(std::move(resyncCallback));
}
}


EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& handle) {
EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& handle) {
Loading