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

Commit 85c39afc authored by Ana Krulec's avatar Ana Krulec
Browse files

SF: Moving EventThread::Connection out of impl class

This is part of Scheduler refactoring. EventThread::Connection should be
a wrapper that translates IDisplayEventConnection into EventThread calls.

Test: SF tests pass.
Bug: 113612090
Change-Id: I2bcf0c45a33638c59f7828085c563dbc52b2d66e
parent 5302ea98
Loading
Loading
Loading
Loading
+47 −51
Original line number Diff line number Diff line
@@ -43,6 +43,40 @@ namespace android {

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

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

EventThreadConnection::~EventThreadConnection() {
    // do nothing here -- clean-up will happen automatically
    // when the main thread wakes up
}

void EventThreadConnection::onFirstRef() {
    // NOTE: mEventThread doesn't hold a strong reference on us
    mEventThread->registerDisplayEventConnection(this);
}

status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
    outChannel->setReceiveFd(mChannel.moveReceiveFd());
    return NO_ERROR;
}

status_t EventThreadConnection::setVsyncRate(uint32_t count) {
    mEventThread->setVsyncRate(count, this);
    return NO_ERROR;
}

void EventThreadConnection::requestNextVsync() {
    mEventThread->requestNextVsync(this);
}

status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
    return size < 0 ? status_t(size) : status_t(NO_ERROR);
}

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

EventThread::~EventThread() = default;

namespace impl {
@@ -110,12 +144,11 @@ void EventThread::setPhaseOffset(nsecs_t phaseOffset) {
    mVSyncSource->setPhaseOffset(phaseOffset);
}

sp<BnDisplayEventConnection> EventThread::createEventConnection() const {
    return new Connection(const_cast<EventThread*>(this));
sp<EventThreadConnection> EventThread::createEventConnection() const {
    return new EventThreadConnection(const_cast<EventThread*>(this));
}

status_t EventThread::registerDisplayEventConnection(
        const sp<EventThread::Connection>& connection) {
status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
    std::lock_guard<std::mutex> lock(mMutex);

    // this should never happen
@@ -132,8 +165,7 @@ status_t EventThread::registerDisplayEventConnection(
    return NO_ERROR;
}

void EventThread::removeDisplayEventConnectionLocked(
        const wp<EventThread::Connection>& connection) {
void EventThread::removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection) {
    auto it = std::find(mDisplayEventConnections.cbegin(),
            mDisplayEventConnections.cend(), connection);
    if (it != mDisplayEventConnections.cend()) {
@@ -141,7 +173,7 @@ void EventThread::removeDisplayEventConnectionLocked(
    }
}

void EventThread::setVsyncRate(uint32_t count, const sp<EventThread::Connection>& connection) {
void EventThread::setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) {
    if (int32_t(count) >= 0) { // server must protect against bad params
        std::lock_guard<std::mutex> lock(mMutex);
        const int32_t new_count = (count == 0) ? -1 : count;
@@ -152,7 +184,7 @@ void EventThread::setVsyncRate(uint32_t count, const sp<EventThread::Connection>
    }
}

void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection) {
void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
    std::lock_guard<std::mutex> lock(mMutex);
    if (mResetIdleTimer) {
        mResetIdleTimer();
@@ -212,11 +244,11 @@ void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
    std::unique_lock<std::mutex> lock(mMutex);
    while (mKeepRunning) {
        DisplayEventReceiver::Event event;
        std::vector<sp<EventThread::Connection>> signalConnections;
        std::vector<sp<EventThreadConnection>> signalConnections;
        signalConnections = waitForEventLocked(&lock, &event);

        // dispatch events to listeners...
        for (const sp<Connection>& conn : signalConnections) {
        for (const sp<EventThreadConnection>& conn : signalConnections) {
            // now see if we still need to report this event
            status_t err = conn->postEvent(event);
            if (err == -EAGAIN || err == -EWOULDBLOCK) {
@@ -239,9 +271,9 @@ void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {

// This will return when (1) a vsync event has been received, and (2) there was
// at least one connection interested in receiving it when we started waiting.
std::vector<sp<EventThread::Connection>> EventThread::waitForEventLocked(
std::vector<sp<EventThreadConnection>> EventThread::waitForEventLocked(
        std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* outEvent) {
    std::vector<sp<EventThread::Connection>> signalConnections;
    std::vector<sp<EventThreadConnection>> signalConnections;

    while (signalConnections.empty() && mKeepRunning) {
        bool eventPending = false;
@@ -276,7 +308,7 @@ std::vector<sp<EventThread::Connection>> EventThread::waitForEventLocked(
        // find out connections waiting for events
        auto it = mDisplayEventConnections.begin();
        while (it != mDisplayEventConnections.end()) {
            sp<Connection> connection(it->promote());
            sp<EventThreadConnection> connection(it->promote());
            if (connection != nullptr) {
                bool added = false;
                if (connection->count >= 0) {
@@ -399,49 +431,13 @@ void EventThread::dump(std::string& result) const {
    StringAppendF(&result, "  soft-vsync: %s\n", mUseSoftwareVSync ? "enabled" : "disabled");
    StringAppendF(&result, "  numListeners=%zu,\n  events-delivered: %u\n",
                  mDisplayEventConnections.size(), mVSyncEvent[0].vsync.count);
    for (const wp<Connection>& weak : mDisplayEventConnections) {
        sp<Connection> connection = weak.promote();
    for (const wp<EventThreadConnection>& weak : mDisplayEventConnections) {
        sp<EventThreadConnection> connection = weak.promote();
        StringAppendF(&result, "    %p: count=%d\n", connection.get(),
                      connection != nullptr ? connection->count : 0);
    }
    StringAppendF(&result, "  other-events-pending: %zu\n", mPendingEvents.size());
}

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

EventThread::Connection::Connection(EventThread* eventThread)
      : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}

EventThread::Connection::~Connection() {
    // do nothing here -- clean-up will happen automatically
    // when the main thread wakes up
}

void EventThread::Connection::onFirstRef() {
    // NOTE: mEventThread doesn't hold a strong reference on us
    mEventThread->registerDisplayEventConnection(this);
}

status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
    outChannel->setReceiveFd(mChannel.moveReceiveFd());
    return NO_ERROR;
}

status_t EventThread::Connection::setVsyncRate(uint32_t count) {
    mEventThread->setVsyncRate(count, this);
    return NO_ERROR;
}

void EventThread::Connection::requestNextVsync() {
    mEventThread->requestNextVsync(this);
}

status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event) {
    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
    return size < 0 ? status_t(size) : status_t(NO_ERROR);
}

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

} // namespace impl
} // namespace android
+38 −30
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
namespace android {
// ---------------------------------------------------------------------------

class EventThread;
class EventThreadTest;
class SurfaceFlinger;

@@ -57,6 +58,28 @@ public:
    virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;
};

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

    virtual status_t postEvent(const DisplayEventReceiver::Event& event);

    status_t stealReceiveChannel(gui::BitTube* outChannel) override;
    status_t setVsyncRate(uint32_t count) override;
    void requestNextVsync() override; // asynchronous

    // count >= 1 : continuous event. count is the vsync rate
    // count == 0 : one-shot event that has not fired
    // count ==-1 : one-shot event that fired this round / disabled
    int32_t count;

private:
    virtual void onFirstRef();
    EventThread* const mEventThread;
    gui::BitTube mChannel;
};

class EventThread {
public:
    // TODO: Remove once stable display IDs are plumbed through SF/WM interface.
@@ -64,7 +87,7 @@ public:

    virtual ~EventThread();

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

    // called before the screen is turned off from main thread
    virtual void onScreenReleased() = 0;
@@ -78,32 +101,16 @@ public:
    virtual void dump(std::string& result) const = 0;

    virtual void setPhaseOffset(nsecs_t phaseOffset) = 0;

    virtual status_t registerDisplayEventConnection(
            const sp<EventThreadConnection>& connection) = 0;
    virtual void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) = 0;
    virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
};

namespace impl {

class EventThread : public android::EventThread, private VSyncSource::Callback {
    class Connection : public BnDisplayEventConnection {
    public:
        explicit Connection(EventThread* eventThread);
        virtual ~Connection();

        virtual status_t postEvent(const DisplayEventReceiver::Event& event);

        // count >= 1 : continuous event. count is the vsync rate
        // count == 0 : one-shot event that has not fired
        // count ==-1 : one-shot event that fired this round / disabled
        int32_t count;

    private:
        virtual void onFirstRef();
        status_t stealReceiveChannel(gui::BitTube* outChannel) override;
        status_t setVsyncRate(uint32_t count) override;
        void requestNextVsync() override; // asynchronous
        EventThread* const mEventThread;
        gui::BitTube mChannel;
    };

public:
    using ResyncWithRateLimitCallback = std::function<void()>;
    using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
@@ -118,10 +125,11 @@ public:
                const ResetIdleTimerCallback& resetIdleTimerCallback, const char* threadName);
    ~EventThread();

    sp<BnDisplayEventConnection> createEventConnection() const override;
    sp<EventThreadConnection> createEventConnection() const override;

    void setVsyncRate(uint32_t count, const sp<Connection>& connection);
    void requestNextVsync(const sp<Connection>& connection);
    status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
    void setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) override;
    void requestNextVsync(const sp<EventThreadConnection>& connection) override;

    // called before the screen is turned off from main thread
    void onScreenReleased() override;
@@ -144,14 +152,14 @@ private:
                ResyncWithRateLimitCallback resyncWithRateLimitCallback,
                InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName);

    status_t registerDisplayEventConnection(const sp<Connection>& connection);

    void threadMain();
    std::vector<sp<EventThread::Connection>> waitForEventLocked(std::unique_lock<std::mutex>* lock,
    std::vector<sp<EventThreadConnection>> waitForEventLocked(std::unique_lock<std::mutex>* lock,
                                                              DisplayEventReceiver::Event* event)
            REQUIRES(mMutex);

    void removeDisplayEventConnectionLocked(const wp<Connection>& connection) REQUIRES(mMutex);
    void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection)
            REQUIRES(mMutex);
    void enableVSyncLocked() REQUIRES(mMutex);
    void disableVSyncLocked() REQUIRES(mMutex);

@@ -170,7 +178,7 @@ private:
    mutable std::condition_variable mCondition;

    // protected by mLock
    std::vector<wp<Connection>> mDisplayEventConnections GUARDED_BY(mMutex);
    std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
    std::queue<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
    std::array<DisplayEventReceiver::Event, 2> mVSyncEvent GUARDED_BY(mMutex);
    bool mUseSoftwareVSync GUARDED_BY(mMutex) = false;
+1 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ void MessageQueue::setEventThread(android::EventThread* eventThread) {
                   this);
}

void MessageQueue::setEventConnection(const sp<BnDisplayEventConnection>& connection) {
void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
    if (mEventTube.getFd() >= 0) {
        mLooper->removeFd(mEventTube.getFd());
    }
+3 −3
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ public:
    virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
    // TODO(akrulec): Remove this function once everything is migrated to Scheduler.
    virtual void setEventThread(EventThread* events) = 0;
    virtual void setEventConnection(const sp<BnDisplayEventConnection>& connection) = 0;
    virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
    virtual void waitMessage() = 0;
    virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
    virtual void invalidate() = 0;
@@ -116,7 +116,7 @@ class MessageQueue final : public android::MessageQueue {
    sp<SurfaceFlinger> mFlinger;
    sp<Looper> mLooper;
    android::EventThread* mEventThread;
    sp<IDisplayEventConnection> mEvents;
    sp<EventThreadConnection> mEvents;
    gui::BitTube mEventTube;
    sp<Handler> mHandler;

@@ -127,7 +127,7 @@ public:
    ~MessageQueue() override = default;
    void init(const sp<SurfaceFlinger>& flinger) override;
    void setEventThread(android::EventThread* events) override;
    void setEventConnection(const sp<BnDisplayEventConnection>& connection) override;
    void setEventConnection(const sp<EventThreadConnection>& connection) override;

    void waitMessage() override;
    status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) override;
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& ha
    return mConnections[handle->id]->thread.get();
}

sp<BnDisplayEventConnection> Scheduler::getEventConnection(const sp<ConnectionHandle>& handle) {
sp<EventThreadConnection> Scheduler::getEventConnection(const sp<ConnectionHandle>& handle) {
    RETURN_VALUE_IF_INVALID(nullptr);
    return mConnections[handle->id]->eventConnection;
}
Loading