diff options
author | 2018-12-26 17:29:57 -0800 | |
---|---|---|
committer | 2018-12-27 11:08:29 -0800 | |
commit | 85c39afcd961afd35d31050aadf3fb6cd16003a4 (patch) | |
tree | 24dbfd57afa173de7ca017715826c7a0226c22c9 | |
parent | 5302ea983dbd0c961e33e441aa49bd6667efc4f0 (diff) |
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
10 files changed, 108 insertions, 96 deletions
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 1f08f4e1fc..1683982485 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -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 diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 0773c0587c..66f54bddd0 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -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, - DisplayEventReceiver::Event* event) + 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; diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp index 58355ae3a5..36403cc346 100644 --- a/services/surfaceflinger/Scheduler/MessageQueue.cpp +++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp @@ -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()); } diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h index 2ec697ea35..24a383422a 100644 --- a/services/surfaceflinger/Scheduler/MessageQueue.h +++ b/services/surfaceflinger/Scheduler/MessageQueue.h @@ -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; diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index fad56e6617..c363ba57f7 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -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; } diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index 8d4514b995..9d7dd4df64 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -53,14 +53,14 @@ public: class Connection { public: - Connection(sp<ConnectionHandle> handle, sp<BnDisplayEventConnection> eventConnection, + Connection(sp<ConnectionHandle> handle, sp<EventThreadConnection> eventConnection, std::unique_ptr<EventThread> eventThread) : handle(handle), eventConnection(eventConnection), thread(std::move(eventThread)) {} ~Connection() = default; sp<ConnectionHandle> handle; - sp<BnDisplayEventConnection> eventConnection; + sp<EventThreadConnection> eventConnection; const std::unique_ptr<EventThread> thread; }; @@ -79,7 +79,7 @@ public: // Getter methods. EventThread* getEventThread(const sp<ConnectionHandle>& handle); - sp<BnDisplayEventConnection> getEventConnection(const sp<ConnectionHandle>& handle); + sp<EventThreadConnection> getEventConnection(const sp<ConnectionHandle>& handle); // Should be called when receiving a hotplug event. void hotplugReceived(const sp<ConnectionHandle>& handle, EventThread::DisplayType displayType, diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp index fb3b7a2951..acbed51e9d 100644 --- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp +++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp @@ -47,10 +47,10 @@ public: class EventThreadTest : public testing::Test { protected: - class MockEventThreadConnection : public android::impl::EventThread::Connection { + class MockEventThreadConnection : public android::EventThreadConnection { public: explicit MockEventThreadConnection(android::impl::EventThread* eventThread) - : android::impl::EventThread::Connection(eventThread) {} + : android::EventThreadConnection(eventThread) {} MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event)); }; diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp index 35f30d7da8..4253ad826f 100644 --- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp +++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp @@ -23,9 +23,10 @@ namespace android { class SchedulerTest : public testing::Test { protected: - class MockEventThreadConnection : public BnDisplayEventConnection { + class MockEventThreadConnection : public android::EventThreadConnection { public: - MockEventThreadConnection() = default; + explicit MockEventThreadConnection(EventThread* eventThread) + : EventThreadConnection(eventThread) {} ~MockEventThreadConnection() = default; MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel)); @@ -77,7 +78,9 @@ SchedulerTest::SchedulerTest() { std::unique_ptr<mock::EventThread> eventThread = std::make_unique<mock::EventThread>(); mEventThread = eventThread.get(); mScheduler = std::make_unique<MockScheduler>(std::move(eventThread)); - mEventThreadConnection = new MockEventThreadConnection(); + EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0)); + + mEventThreadConnection = new MockEventThreadConnection(mEventThread); // createConnection call to scheduler makes a createEventConnection call to EventThread. Make // sure that call gets executed and returns an EventThread::Connection object. diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h index 0a1c827f99..bb6e1831df 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h +++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h @@ -28,12 +28,16 @@ public: EventThread(); ~EventThread() override; - MOCK_CONST_METHOD0(createEventConnection, sp<BnDisplayEventConnection>()); + MOCK_CONST_METHOD0(createEventConnection, sp<EventThreadConnection>()); MOCK_METHOD0(onScreenReleased, void()); MOCK_METHOD0(onScreenAcquired, void()); MOCK_METHOD2(onHotplugReceived, void(DisplayType, bool)); MOCK_CONST_METHOD1(dump, void(std::string&)); MOCK_METHOD1(setPhaseOffset, void(nsecs_t phaseOffset)); + MOCK_METHOD1(registerDisplayEventConnection, + status_t(const sp<android::EventThreadConnection> &)); + MOCK_METHOD2(setVsyncRate, void(uint32_t, const sp<android::EventThreadConnection> &)); + MOCK_METHOD1(requestNextVsync, void(const sp<android::EventThreadConnection> &)); }; } // namespace mock diff --git a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h index f2f36758f9..dc8d606547 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h +++ b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h @@ -18,6 +18,7 @@ #include <gmock/gmock.h> +#include "Scheduler/EventThread.h" #include "Scheduler/MessageQueue.h" namespace android { @@ -30,7 +31,7 @@ public: MOCK_METHOD1(init, void(const sp<SurfaceFlinger>&)); MOCK_METHOD1(setEventThread, void(android::EventThread*)); - MOCK_METHOD1(setEventConnection, void(const sp<BnDisplayEventConnection>& connection)); + MOCK_METHOD1(setEventConnection, void(const sp<android::EventThreadConnection>& connection)); MOCK_METHOD0(waitMessage, void()); MOCK_METHOD2(postMessage, status_t(const sp<MessageBase>&, nsecs_t)); MOCK_METHOD0(invalidate, void()); |