diff options
Diffstat (limited to 'services/surfaceflinger/Scheduler/MessageQueue.cpp')
-rw-r--r-- | services/surfaceflinger/Scheduler/MessageQueue.cpp | 149 |
1 files changed, 31 insertions, 118 deletions
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp index 4d51125156..6067e69ea0 100644 --- a/services/surfaceflinger/Scheduler/MessageQueue.cpp +++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp @@ -14,7 +14,9 @@ * limitations under the License. */ -#define ATRACE_TAG ATRACE_TAG_GRAPHICS +// TODO(b/129481165): remove the #pragma below and fix conversion issues +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wconversion" #include <binder/IPCThreadState.h> @@ -23,42 +25,36 @@ #include <utils/threads.h> #include <gui/DisplayEventReceiver.h> +#include <gui/IDisplayEventConnection.h> #include "EventThread.h" -#include "FrameTimeline.h" #include "MessageQueue.h" #include "SurfaceFlinger.h" namespace android::impl { void MessageQueue::Handler::dispatchRefresh() { - if ((mEventMask.fetch_or(eventMaskRefresh) & eventMaskRefresh) == 0) { + if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) { mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH)); } } -void MessageQueue::Handler::dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp) { - if ((mEventMask.fetch_or(eventMaskInvalidate) & eventMaskInvalidate) == 0) { - mVsyncId = vsyncId; +void MessageQueue::Handler::dispatchInvalidate(nsecs_t expectedVSyncTimestamp) { + if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) { mExpectedVSyncTime = expectedVSyncTimestamp; mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE)); } } -bool MessageQueue::Handler::invalidatePending() { - constexpr auto pendingMask = eventMaskInvalidate | eventMaskRefresh; - return (mEventMask.load() & pendingMask) != 0; -} - void MessageQueue::Handler::handleMessage(const Message& message) { switch (message.what) { case INVALIDATE: - mEventMask.fetch_and(~eventMaskInvalidate); - mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime); + android_atomic_and(~eventMaskInvalidate, &mEventMask); + mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime); break; case REFRESH: - mEventMask.fetch_and(~eventMaskRefresh); - mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime); + android_atomic_and(~eventMaskRefresh, &mEventMask); + mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime); break; } } @@ -71,75 +67,15 @@ void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { mHandler = new Handler(*this); } -// TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly -// and remove the EventThread from MessageQueue -void MessageQueue::setInjector(sp<EventThreadConnection> connection) { - auto& tube = mInjector.tube; - - if (const int fd = tube.getFd(); fd >= 0) { - mLooper->removeFd(fd); - } - - if (connection) { - // The EventThreadConnection is retained when disabling injection, so avoid subsequently - // stealing invalid FDs. Note that the stolen FDs are kept open. - if (tube.getFd() < 0) { - connection->stealReceiveChannel(&tube); - } else { - ALOGW("Recycling channel for VSYNC injection."); - } - - mLooper->addFd( - tube.getFd(), 0, Looper::EVENT_INPUT, - [](int, int, void* data) { - reinterpret_cast<MessageQueue*>(data)->injectorCallback(); - return 1; // Keep registration. - }, - this); - } - - std::lock_guard lock(mInjector.mutex); - mInjector.connection = std::move(connection); -} - -void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) { - ATRACE_CALL(); - // Trace VSYNC-sf - mVsync.value = (mVsync.value + 1) % 2; - - { - std::lock_guard lock(mVsync.mutex); - mVsync.lastCallbackTime = std::chrono::nanoseconds(vsyncTime); - mVsync.scheduled = false; +void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) { + if (mEventTube.getFd() >= 0) { + mLooper->removeFd(mEventTube.getFd()); } - mHandler->dispatchInvalidate(mVsync.tokenManager->generateTokenForPredictions( - {targetWakeupTime, readyTime, vsyncTime}), - vsyncTime); -} - -void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch, - frametimeline::TokenManager& tokenManager, - std::chrono::nanoseconds workDuration) { - setDuration(workDuration); - mVsync.tokenManager = &tokenManager; - mVsync.registration = std::make_unique< - scheduler::VSyncCallbackRegistration>(dispatch, - std::bind(&MessageQueue::vsyncCallback, this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3), - "sf"); -} -void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) { - ATRACE_CALL(); - std::lock_guard lock(mVsync.mutex); - mVsync.workDuration = workDuration; - if (mVsync.scheduled) { - mVsync.expectedWakeupTime = mVsync.registration->schedule( - {mVsync.workDuration.get().count(), - /*readyDuration=*/0, mVsync.lastCallbackTime.count()}); - } + mEvents = connection; + mEvents->stealReceiveChannel(&mEventTube); + mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, + this); } void MessageQueue::waitMessage() { @@ -169,56 +105,33 @@ void MessageQueue::postMessage(sp<MessageHandler>&& handler) { } void MessageQueue::invalidate() { - ATRACE_CALL(); - - { - std::lock_guard lock(mInjector.mutex); - if (CC_UNLIKELY(mInjector.connection)) { - ALOGD("%s while injecting VSYNC", __FUNCTION__); - mInjector.connection->requestNextVsync(); - return; - } - } - - std::lock_guard lock(mVsync.mutex); - mVsync.scheduled = true; - mVsync.expectedWakeupTime = - mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), - .readyDuration = 0, - .earliestVsync = mVsync.lastCallbackTime.count()}); + mEvents->requestNextVsync(); } void MessageQueue::refresh() { mHandler->dispatchRefresh(); } -void MessageQueue::injectorCallback() { +int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { + MessageQueue* queue = reinterpret_cast<MessageQueue*>(data); + return queue->eventReceiver(fd, events); +} + +int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { ssize_t n; DisplayEventReceiver::Event buffer[8]; - while ((n = DisplayEventReceiver::getEvents(&mInjector.tube, buffer, 8)) > 0) { + while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) { for (int i = 0; i < n; i++) { if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { - mHandler->dispatchInvalidate(buffer[i].vsync.vsyncId, - buffer[i].vsync.expectedVSyncTimestamp); + mHandler->dispatchInvalidate(buffer[i].vsync.expectedVSyncTimestamp); break; } } } -} - -std::optional<std::chrono::steady_clock::time_point> MessageQueue::nextExpectedInvalidate() { - if (mHandler->invalidatePending()) { - return std::chrono::steady_clock::now(); - } - - std::lock_guard lock(mVsync.mutex); - if (mVsync.scheduled) { - LOG_ALWAYS_FATAL_IF(!mVsync.expectedWakeupTime.has_value(), "callback was never scheduled"); - const auto expectedWakeupTime = std::chrono::nanoseconds(*mVsync.expectedWakeupTime); - return std::optional<std::chrono::steady_clock::time_point>(expectedWakeupTime); - } - - return std::nullopt; + return 1; } } // namespace android::impl + +// TODO(b/129481165): remove the #pragma below and fix conversion issues +#pragma clang diagnostic pop // ignored "-Wconversion" |