summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/Scheduler/MessageQueue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/Scheduler/MessageQueue.cpp')
-rw-r--r--services/surfaceflinger/Scheduler/MessageQueue.cpp149
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"