1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 
21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
22 
23 #include <pthread.h>
24 #include <sched.h>
25 #include <sys/types.h>
26 
27 #include <chrono>
28 #include <cstdint>
29 #include <optional>
30 #include <type_traits>
31 #include <utility>
32 
33 #include <android-base/stringprintf.h>
34 
35 #include <binder/IPCThreadState.h>
36 
37 #include <cutils/compiler.h>
38 #include <cutils/sched_policy.h>
39 
40 #include <gui/DisplayEventReceiver.h>
41 #include <gui/SchedulingPolicy.h>
42 
43 #include <utils/Errors.h>
44 #include <utils/Trace.h>
45 
46 #include <common/FlagManager.h>
47 #include <scheduler/VsyncConfig.h>
48 #include "DisplayHardware/DisplayMode.h"
49 #include "FrameTimeline.h"
50 #include "VSyncDispatch.h"
51 #include "VSyncTracker.h"
52 
53 #include "EventThread.h"
54 
55 #undef LOG_TAG
56 #define LOG_TAG "EventThread"
57 
58 using namespace std::chrono_literals;
59 
60 namespace android {
61 
62 using base::StringAppendF;
63 using base::StringPrintf;
64 
65 namespace {
66 
vsyncPeriod(VSyncRequest request)67 auto vsyncPeriod(VSyncRequest request) {
68     return static_cast<std::underlying_type_t<VSyncRequest>>(request);
69 }
70 
toString(VSyncRequest request)71 std::string toString(VSyncRequest request) {
72     switch (request) {
73         case VSyncRequest::None:
74             return "VSyncRequest::None";
75         case VSyncRequest::Single:
76             return "VSyncRequest::Single";
77         case VSyncRequest::SingleSuppressCallback:
78             return "VSyncRequest::SingleSuppressCallback";
79         default:
80             return StringPrintf("VSyncRequest::Periodic{period=%d}", vsyncPeriod(request));
81     }
82 }
83 
toString(const EventThreadConnection & connection)84 std::string toString(const EventThreadConnection& connection) {
85     return StringPrintf("Connection{%p, %s}", &connection,
86                         toString(connection.vsyncRequest).c_str());
87 }
88 
toString(const DisplayEventReceiver::Event & event)89 std::string toString(const DisplayEventReceiver::Event& event) {
90     switch (event.header.type) {
91         case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
92             return StringPrintf("Hotplug{displayId=%s, %s}",
93                                 to_string(event.header.displayId).c_str(),
94                                 event.hotplug.connected ? "connected" : "disconnected");
95         case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
96             return StringPrintf("VSync{displayId=%s, count=%u, expectedPresentationTime=%" PRId64
97                                 "}",
98                                 to_string(event.header.displayId).c_str(), event.vsync.count,
99                                 event.vsync.vsyncData.preferredExpectedPresentationTime());
100         case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
101             return StringPrintf("ModeChanged{displayId=%s, modeId=%u}",
102                                 to_string(event.header.displayId).c_str(), event.modeChange.modeId);
103         case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
104             return StringPrintf("HdcpLevelsChange{displayId=%s, connectedLevel=%d, maxLevel=%d}",
105                                 to_string(event.header.displayId).c_str(),
106                                 event.hdcpLevelsChange.connectedLevel,
107                                 event.hdcpLevelsChange.maxLevel);
108         default:
109             return "Event{}";
110     }
111 }
112 
makeHotplug(PhysicalDisplayId displayId,nsecs_t timestamp,bool connected)113 DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t timestamp,
114                                         bool connected) {
115     DisplayEventReceiver::Event event;
116     event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, displayId, timestamp};
117     event.hotplug.connected = connected;
118     return event;
119 }
120 
makeHotplugError(nsecs_t timestamp,int32_t connectionError)121 DisplayEventReceiver::Event makeHotplugError(nsecs_t timestamp, int32_t connectionError) {
122     DisplayEventReceiver::Event event;
123     PhysicalDisplayId unusedDisplayId;
124     event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, unusedDisplayId, timestamp};
125     event.hotplug.connected = false;
126     event.hotplug.connectionError = connectionError;
127     return event;
128 }
129 
makeVSync(PhysicalDisplayId displayId,nsecs_t timestamp,uint32_t count,nsecs_t expectedPresentationTime,nsecs_t deadlineTimestamp)130 DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp,
131                                       uint32_t count, nsecs_t expectedPresentationTime,
132                                       nsecs_t deadlineTimestamp) {
133     DisplayEventReceiver::Event event;
134     event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp};
135     event.vsync.count = count;
136     event.vsync.vsyncData.preferredFrameTimelineIndex = 0;
137     // Temporarily store the current vsync information in frameTimelines[0], marked as
138     // platform-preferred. When the event is dispatched later, the frame interval at that time is
139     // used with this information to generate multiple frame timeline choices.
140     event.vsync.vsyncData.frameTimelines[0] = {.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID,
141                                                .deadlineTimestamp = deadlineTimestamp,
142                                                .expectedPresentationTime =
143                                                        expectedPresentationTime};
144     return event;
145 }
146 
makeModeChanged(const scheduler::FrameRateMode & mode)147 DisplayEventReceiver::Event makeModeChanged(const scheduler::FrameRateMode& mode) {
148     DisplayEventReceiver::Event event;
149     event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE,
150                     mode.modePtr->getPhysicalDisplayId(), systemTime()};
151     event.modeChange.modeId = ftl::to_underlying(mode.modePtr->getId());
152     event.modeChange.vsyncPeriod = mode.fps.getPeriodNsecs();
153     return event;
154 }
155 
makeFrameRateOverrideEvent(PhysicalDisplayId displayId,FrameRateOverride frameRateOverride)156 DisplayEventReceiver::Event makeFrameRateOverrideEvent(PhysicalDisplayId displayId,
157                                                        FrameRateOverride frameRateOverride) {
158     return DisplayEventReceiver::Event{
159             .header =
160                     DisplayEventReceiver::Event::Header{
161                             .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
162                             .displayId = displayId,
163                             .timestamp = systemTime(),
164                     },
165             .frameRateOverride = frameRateOverride,
166     };
167 }
168 
makeFrameRateOverrideFlushEvent(PhysicalDisplayId displayId)169 DisplayEventReceiver::Event makeFrameRateOverrideFlushEvent(PhysicalDisplayId displayId) {
170     return DisplayEventReceiver::Event{
171             .header = DisplayEventReceiver::Event::Header{
172                     .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH,
173                     .displayId = displayId,
174                     .timestamp = systemTime(),
175             }};
176 }
177 
makeHdcpLevelsChange(PhysicalDisplayId displayId,int32_t connectedLevel,int32_t maxLevel)178 DisplayEventReceiver::Event makeHdcpLevelsChange(PhysicalDisplayId displayId,
179                                                  int32_t connectedLevel, int32_t maxLevel) {
180     return DisplayEventReceiver::Event{
181             .header =
182                     DisplayEventReceiver::Event::Header{
183                             .type = DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE,
184                             .displayId = displayId,
185                             .timestamp = systemTime(),
186                     },
187             .hdcpLevelsChange.connectedLevel = connectedLevel,
188             .hdcpLevelsChange.maxLevel = maxLevel,
189     };
190 }
191 
192 } // namespace
193 
EventThreadConnection(EventThread * eventThread,uid_t callingUid,EventRegistrationFlags eventRegistration)194 EventThreadConnection::EventThreadConnection(EventThread* eventThread, uid_t callingUid,
195                                              EventRegistrationFlags eventRegistration)
196       : mOwnerUid(callingUid),
197         mEventRegistration(eventRegistration),
198         mEventThread(eventThread),
199         mChannel(gui::BitTube::DefaultSize) {}
200 
~EventThreadConnection()201 EventThreadConnection::~EventThreadConnection() {
202     // do nothing here -- clean-up will happen automatically
203     // when the main thread wakes up
204 }
205 
onFirstRef()206 void EventThreadConnection::onFirstRef() {
207     // NOTE: mEventThread doesn't hold a strong reference on us
208     mEventThread->registerDisplayEventConnection(sp<EventThreadConnection>::fromExisting(this));
209 }
210 
stealReceiveChannel(gui::BitTube * outChannel)211 binder::Status EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
212     std::scoped_lock lock(mLock);
213     if (mChannel.initCheck() != NO_ERROR) {
214         return binder::Status::fromStatusT(NAME_NOT_FOUND);
215     }
216 
217     outChannel->setReceiveFd(mChannel.moveReceiveFd());
218     outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd())));
219     return binder::Status::ok();
220 }
221 
setVsyncRate(int rate)222 binder::Status EventThreadConnection::setVsyncRate(int rate) {
223     mEventThread->setVsyncRate(static_cast<uint32_t>(rate),
224                                sp<EventThreadConnection>::fromExisting(this));
225     return binder::Status::ok();
226 }
227 
requestNextVsync()228 binder::Status EventThreadConnection::requestNextVsync() {
229     ATRACE_CALL();
230     mEventThread->requestNextVsync(sp<EventThreadConnection>::fromExisting(this));
231     return binder::Status::ok();
232 }
233 
getLatestVsyncEventData(ParcelableVsyncEventData * outVsyncEventData)234 binder::Status EventThreadConnection::getLatestVsyncEventData(
235         ParcelableVsyncEventData* outVsyncEventData) {
236     ATRACE_CALL();
237     outVsyncEventData->vsync =
238             mEventThread->getLatestVsyncEventData(sp<EventThreadConnection>::fromExisting(this),
239                                                   systemTime());
240     return binder::Status::ok();
241 }
242 
getSchedulingPolicy(gui::SchedulingPolicy * outPolicy)243 binder::Status EventThreadConnection::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) {
244     return gui::getSchedulingPolicy(outPolicy);
245 }
246 
postEvent(const DisplayEventReceiver::Event & event)247 status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
248     constexpr auto toStatus = [](ssize_t size) {
249         return size < 0 ? status_t(size) : status_t(NO_ERROR);
250     };
251 
252     if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE ||
253         event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) {
254         mPendingEvents.emplace_back(event);
255         if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) {
256             return status_t(NO_ERROR);
257         }
258 
259         auto size = DisplayEventReceiver::sendEvents(&mChannel, mPendingEvents.data(),
260                                                      mPendingEvents.size());
261         mPendingEvents.clear();
262         return toStatus(size);
263     }
264 
265     auto size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
266     return toStatus(size);
267 }
268 
269 // ---------------------------------------------------------------------------
270 
271 EventThread::~EventThread() = default;
272 
273 namespace impl {
274 
EventThread(const char * name,std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule,android::frametimeline::TokenManager * tokenManager,IEventThreadCallback & callback,std::chrono::nanoseconds workDuration,std::chrono::nanoseconds readyDuration)275 EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule,
276                          android::frametimeline::TokenManager* tokenManager,
277                          IEventThreadCallback& callback, std::chrono::nanoseconds workDuration,
278                          std::chrono::nanoseconds readyDuration)
279       : mThreadName(name),
280         mVsyncTracer(base::StringPrintf("VSYNC-%s", name), 0),
281         mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
282         mReadyDuration(readyDuration),
283         mVsyncSchedule(std::move(vsyncSchedule)),
284         mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name),
285         mTokenManager(tokenManager),
286         mCallback(callback) {
287     mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
288         std::unique_lock<std::mutex> lock(mMutex);
289         threadMain(lock);
290     });
291 
292     pthread_setname_np(mThread.native_handle(), mThreadName);
293 
294     pid_t tid = pthread_gettid_np(mThread.native_handle());
295 
296     // Use SCHED_FIFO to minimize jitter
297     constexpr int EVENT_THREAD_PRIORITY = 2;
298     struct sched_param param = {0};
299     param.sched_priority = EVENT_THREAD_PRIORITY;
300     if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, &param) != 0) {
301         ALOGE("Couldn't set SCHED_FIFO for EventThread");
302     }
303 
304     set_sched_policy(tid, SP_FOREGROUND);
305 }
306 
~EventThread()307 EventThread::~EventThread() {
308     {
309         std::lock_guard<std::mutex> lock(mMutex);
310         mState = State::Quit;
311         mCondition.notify_all();
312     }
313     mThread.join();
314 }
315 
setDuration(std::chrono::nanoseconds workDuration,std::chrono::nanoseconds readyDuration)316 void EventThread::setDuration(std::chrono::nanoseconds workDuration,
317                               std::chrono::nanoseconds readyDuration) {
318     std::lock_guard<std::mutex> lock(mMutex);
319     mWorkDuration = workDuration;
320     mReadyDuration = readyDuration;
321 
322     mVsyncRegistration.update({.workDuration = mWorkDuration.get().count(),
323                                .readyDuration = mReadyDuration.count(),
324                                .lastVsync = mLastVsyncCallbackTime.ns()});
325 }
326 
createEventConnection(EventRegistrationFlags eventRegistration) const327 sp<EventThreadConnection> EventThread::createEventConnection(
328         EventRegistrationFlags eventRegistration) const {
329     auto connection = sp<EventThreadConnection>::make(const_cast<EventThread*>(this),
330                                                       IPCThreadState::self()->getCallingUid(),
331                                                       eventRegistration);
332     if (FlagManager::getInstance().misc1()) {
333         const int policy = SCHED_FIFO;
334         connection->setMinSchedulerPolicy(policy, sched_get_priority_min(policy));
335     }
336     return connection;
337 }
338 
registerDisplayEventConnection(const sp<EventThreadConnection> & connection)339 status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
340     std::lock_guard<std::mutex> lock(mMutex);
341 
342     // this should never happen
343     auto it = std::find(mDisplayEventConnections.cbegin(),
344             mDisplayEventConnections.cend(), connection);
345     if (it != mDisplayEventConnections.cend()) {
346         ALOGW("DisplayEventConnection %p already exists", connection.get());
347         mCondition.notify_all();
348         return ALREADY_EXISTS;
349     }
350 
351     mDisplayEventConnections.push_back(connection);
352     mCondition.notify_all();
353     return NO_ERROR;
354 }
355 
removeDisplayEventConnectionLocked(const wp<EventThreadConnection> & connection)356 void EventThread::removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection) {
357     auto it = std::find(mDisplayEventConnections.cbegin(),
358             mDisplayEventConnections.cend(), connection);
359     if (it != mDisplayEventConnections.cend()) {
360         mDisplayEventConnections.erase(it);
361     }
362 }
363 
setVsyncRate(uint32_t rate,const sp<EventThreadConnection> & connection)364 void EventThread::setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) {
365     if (static_cast<std::underlying_type_t<VSyncRequest>>(rate) < 0) {
366         return;
367     }
368 
369     std::lock_guard<std::mutex> lock(mMutex);
370 
371     const auto request = rate == 0 ? VSyncRequest::None : static_cast<VSyncRequest>(rate);
372     if (connection->vsyncRequest != request) {
373         connection->vsyncRequest = request;
374         mCondition.notify_all();
375     }
376 }
377 
requestNextVsync(const sp<EventThreadConnection> & connection)378 void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
379     mCallback.resync();
380 
381     std::lock_guard<std::mutex> lock(mMutex);
382 
383     if (connection->vsyncRequest == VSyncRequest::None) {
384         connection->vsyncRequest = VSyncRequest::Single;
385         mCondition.notify_all();
386     } else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) {
387         connection->vsyncRequest = VSyncRequest::Single;
388     }
389 }
390 
getLatestVsyncEventData(const sp<EventThreadConnection> & connection,nsecs_t now) const391 VsyncEventData EventThread::getLatestVsyncEventData(const sp<EventThreadConnection>& connection,
392                                                     nsecs_t now) const {
393     // Resync so that the vsync is accurate with hardware. getLatestVsyncEventData is an alternate
394     // way to get vsync data (instead of posting callbacks to Choreographer).
395     mCallback.resync();
396 
397     VsyncEventData vsyncEventData;
398     const Period frameInterval = mCallback.getVsyncPeriod(connection->mOwnerUid);
399     vsyncEventData.frameInterval = frameInterval.ns();
400     const auto [presentTime, deadline] = [&]() -> std::pair<nsecs_t, nsecs_t> {
401         std::lock_guard<std::mutex> lock(mMutex);
402         const auto vsyncTime = mVsyncSchedule->getTracker().nextAnticipatedVSyncTimeFrom(
403                 now + mWorkDuration.get().count() + mReadyDuration.count());
404         return {vsyncTime, vsyncTime - mReadyDuration.count()};
405     }();
406     generateFrameTimeline(vsyncEventData, frameInterval.ns(), now, presentTime, deadline);
407     if (FlagManager::getInstance().vrr_config()) {
408         mCallback.onExpectedPresentTimePosted(TimePoint::fromNs(presentTime));
409     }
410     return vsyncEventData;
411 }
412 
enableSyntheticVsync(bool enable)413 void EventThread::enableSyntheticVsync(bool enable) {
414     std::lock_guard<std::mutex> lock(mMutex);
415     if (!mVSyncState || mVSyncState->synthetic == enable) {
416         return;
417     }
418 
419     mVSyncState->synthetic = enable;
420     mCondition.notify_all();
421 }
422 
onVsync(nsecs_t vsyncTime,nsecs_t wakeupTime,nsecs_t readyTime)423 void EventThread::onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
424     std::lock_guard<std::mutex> lock(mMutex);
425     mLastVsyncCallbackTime = TimePoint::fromNs(vsyncTime);
426 
427     LOG_FATAL_IF(!mVSyncState);
428     mVsyncTracer = (mVsyncTracer + 1) % 2;
429     mPendingEvents.push_back(makeVSync(mVSyncState->displayId, wakeupTime, ++mVSyncState->count,
430                                        vsyncTime, readyTime));
431     mCondition.notify_all();
432 }
433 
onHotplugReceived(PhysicalDisplayId displayId,bool connected)434 void EventThread::onHotplugReceived(PhysicalDisplayId displayId, bool connected) {
435     std::lock_guard<std::mutex> lock(mMutex);
436 
437     mPendingEvents.push_back(makeHotplug(displayId, systemTime(), connected));
438     mCondition.notify_all();
439 }
440 
onHotplugConnectionError(int32_t errorCode)441 void EventThread::onHotplugConnectionError(int32_t errorCode) {
442     std::lock_guard<std::mutex> lock(mMutex);
443 
444     mPendingEvents.push_back(makeHotplugError(systemTime(), errorCode));
445     mCondition.notify_all();
446 }
447 
onModeChanged(const scheduler::FrameRateMode & mode)448 void EventThread::onModeChanged(const scheduler::FrameRateMode& mode) {
449     std::lock_guard<std::mutex> lock(mMutex);
450 
451     mPendingEvents.push_back(makeModeChanged(mode));
452     mCondition.notify_all();
453 }
454 
onFrameRateOverridesChanged(PhysicalDisplayId displayId,std::vector<FrameRateOverride> overrides)455 void EventThread::onFrameRateOverridesChanged(PhysicalDisplayId displayId,
456                                               std::vector<FrameRateOverride> overrides) {
457     std::lock_guard<std::mutex> lock(mMutex);
458 
459     for (auto frameRateOverride : overrides) {
460         mPendingEvents.push_back(makeFrameRateOverrideEvent(displayId, frameRateOverride));
461     }
462     mPendingEvents.push_back(makeFrameRateOverrideFlushEvent(displayId));
463 
464     mCondition.notify_all();
465 }
466 
onHdcpLevelsChanged(PhysicalDisplayId displayId,int32_t connectedLevel,int32_t maxLevel)467 void EventThread::onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
468                                       int32_t maxLevel) {
469     std::lock_guard<std::mutex> lock(mMutex);
470 
471     mPendingEvents.push_back(makeHdcpLevelsChange(displayId, connectedLevel, maxLevel));
472     mCondition.notify_all();
473 }
474 
threadMain(std::unique_lock<std::mutex> & lock)475 void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
476     DisplayEventConsumers consumers;
477 
478     while (mState != State::Quit) {
479         std::optional<DisplayEventReceiver::Event> event;
480 
481         // Determine next event to dispatch.
482         if (!mPendingEvents.empty()) {
483             event = mPendingEvents.front();
484             mPendingEvents.pop_front();
485 
486             if (event->header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG) {
487                 if (event->hotplug.connectionError == 0) {
488                     if (event->hotplug.connected && !mVSyncState) {
489                         mVSyncState.emplace(event->header.displayId);
490                     } else if (!event->hotplug.connected && mVSyncState &&
491                                mVSyncState->displayId == event->header.displayId) {
492                         mVSyncState.reset();
493                     }
494                 } else {
495                     // Ignore vsync stuff on an error.
496                 }
497             }
498         }
499 
500         bool vsyncRequested = false;
501 
502         // Find connections that should consume this event.
503         auto it = mDisplayEventConnections.begin();
504         while (it != mDisplayEventConnections.end()) {
505             if (const auto connection = it->promote()) {
506                 if (event && shouldConsumeEvent(*event, connection)) {
507                     consumers.push_back(connection);
508                 }
509 
510                 vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
511 
512                 ++it;
513             } else {
514                 it = mDisplayEventConnections.erase(it);
515             }
516         }
517 
518         if (!consumers.empty()) {
519             dispatchEvent(*event, consumers);
520             consumers.clear();
521         }
522 
523         if (mVSyncState && vsyncRequested) {
524             mState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
525         } else {
526             ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
527             mState = State::Idle;
528         }
529 
530         if (mState == State::VSync) {
531             const auto scheduleResult =
532                     mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
533                                                  .readyDuration = mReadyDuration.count(),
534                                                  .lastVsync = mLastVsyncCallbackTime.ns()});
535             LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback");
536         } else {
537             mVsyncRegistration.cancel();
538         }
539 
540         if (!mPendingEvents.empty()) {
541             continue;
542         }
543 
544         // Wait for event or client registration/request.
545         if (mState == State::Idle) {
546             mCondition.wait(lock);
547         } else {
548             // Generate a fake VSYNC after a long timeout in case the driver stalls. When the
549             // display is off, keep feeding clients at 60 Hz.
550             const std::chrono::nanoseconds timeout =
551                     mState == State::SyntheticVSync ? 16ms : 1000ms;
552             if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
553                 if (mState == State::VSync) {
554                     ALOGW("Faking VSYNC due to driver stall for thread %s", mThreadName);
555                 }
556 
557                 LOG_FATAL_IF(!mVSyncState);
558                 const auto now = systemTime(SYSTEM_TIME_MONOTONIC);
559                 const auto deadlineTimestamp = now + timeout.count();
560                 const auto expectedVSyncTime = deadlineTimestamp + timeout.count();
561                 mPendingEvents.push_back(makeVSync(mVSyncState->displayId, now,
562                                                    ++mVSyncState->count, expectedVSyncTime,
563                                                    deadlineTimestamp));
564             }
565         }
566     }
567     // cancel any pending vsync event before exiting
568     mVsyncRegistration.cancel();
569 }
570 
shouldConsumeEvent(const DisplayEventReceiver::Event & event,const sp<EventThreadConnection> & connection) const571 bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
572                                      const sp<EventThreadConnection>& connection) const {
573     const auto throttleVsync = [&]() REQUIRES(mMutex) {
574         const auto& vsyncData = event.vsync.vsyncData;
575         if (connection->frameRate.isValid()) {
576             return !mVsyncSchedule->getTracker()
577                             .isVSyncInPhase(vsyncData.preferredExpectedPresentationTime(),
578                                             connection->frameRate);
579         }
580 
581         const auto expectedPresentTime =
582                 TimePoint::fromNs(event.vsync.vsyncData.preferredExpectedPresentationTime());
583         return mCallback.throttleVsync(expectedPresentTime, connection->mOwnerUid);
584     };
585 
586     switch (event.header.type) {
587         case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
588             return true;
589 
590         case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
591             return true;
592 
593         case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: {
594             return connection->mEventRegistration.test(
595                     gui::ISurfaceComposer::EventRegistration::modeChanged);
596         }
597 
598         case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
599             switch (connection->vsyncRequest) {
600                 case VSyncRequest::None:
601                     return false;
602                 case VSyncRequest::SingleSuppressCallback:
603                     connection->vsyncRequest = VSyncRequest::None;
604                     return false;
605                 case VSyncRequest::Single: {
606                     if (throttleVsync()) {
607                         return false;
608                     }
609                     connection->vsyncRequest = VSyncRequest::SingleSuppressCallback;
610                     return true;
611                 }
612                 case VSyncRequest::Periodic:
613                     if (throttleVsync()) {
614                         return false;
615                     }
616                     return true;
617                 default:
618                     // We don't throttle vsync if the app set a vsync request rate
619                     // since there is no easy way to do that and this is a very
620                     // rare case
621                     return event.vsync.count % vsyncPeriod(connection->vsyncRequest) == 0;
622             }
623 
624         case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
625             [[fallthrough]];
626         case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
627             return connection->mEventRegistration.test(
628                     gui::ISurfaceComposer::EventRegistration::frameRateOverride);
629 
630         default:
631             return false;
632     }
633 }
634 
generateToken(nsecs_t timestamp,nsecs_t deadlineTimestamp,nsecs_t expectedPresentationTime) const635 int64_t EventThread::generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp,
636                                    nsecs_t expectedPresentationTime) const {
637     if (mTokenManager != nullptr) {
638         return mTokenManager->generateTokenForPredictions(
639                 {timestamp, deadlineTimestamp, expectedPresentationTime});
640     }
641     return FrameTimelineInfo::INVALID_VSYNC_ID;
642 }
643 
generateFrameTimeline(VsyncEventData & outVsyncEventData,nsecs_t frameInterval,nsecs_t timestamp,nsecs_t preferredExpectedPresentationTime,nsecs_t preferredDeadlineTimestamp) const644 void EventThread::generateFrameTimeline(VsyncEventData& outVsyncEventData, nsecs_t frameInterval,
645                                         nsecs_t timestamp,
646                                         nsecs_t preferredExpectedPresentationTime,
647                                         nsecs_t preferredDeadlineTimestamp) const {
648     uint32_t currentIndex = 0;
649     // Add 1 to ensure the preferredFrameTimelineIndex entry (when multiplier == 0) is included.
650     for (int64_t multiplier = -VsyncEventData::kFrameTimelinesCapacity + 1;
651          currentIndex < VsyncEventData::kFrameTimelinesCapacity; multiplier++) {
652         nsecs_t deadlineTimestamp = preferredDeadlineTimestamp + multiplier * frameInterval;
653         // Valid possible frame timelines must have future values, so find a later frame timeline.
654         if (deadlineTimestamp <= timestamp) {
655             continue;
656         }
657 
658         nsecs_t expectedPresentationTime =
659                 preferredExpectedPresentationTime + multiplier * frameInterval;
660         if (expectedPresentationTime >= preferredExpectedPresentationTime +
661                     scheduler::VsyncConfig::kEarlyLatchMaxThreshold.count()) {
662             if (currentIndex == 0) {
663                 ALOGW("%s: Expected present time is too far in the future but no timelines are "
664                       "valid. preferred EPT=%" PRId64 ", Calculated EPT=%" PRId64
665                       ", multiplier=%" PRId64 ", frameInterval=%" PRId64 ", threshold=%" PRId64,
666                       __func__, preferredExpectedPresentationTime, expectedPresentationTime,
667                       multiplier, frameInterval,
668                       static_cast<int64_t>(
669                               scheduler::VsyncConfig::kEarlyLatchMaxThreshold.count()));
670             }
671             break;
672         }
673 
674         if (multiplier == 0) {
675             outVsyncEventData.preferredFrameTimelineIndex = currentIndex;
676         }
677 
678         outVsyncEventData.frameTimelines[currentIndex] =
679                 {.vsyncId = generateToken(timestamp, deadlineTimestamp, expectedPresentationTime),
680                  .deadlineTimestamp = deadlineTimestamp,
681                  .expectedPresentationTime = expectedPresentationTime};
682         currentIndex++;
683     }
684 
685     if (currentIndex == 0) {
686         ALOGW("%s: No timelines are valid. preferred EPT=%" PRId64 ", frameInterval=%" PRId64
687               ", threshold=%" PRId64,
688               __func__, preferredExpectedPresentationTime, frameInterval,
689               static_cast<int64_t>(scheduler::VsyncConfig::kEarlyLatchMaxThreshold.count()));
690         outVsyncEventData.frameTimelines[currentIndex] =
691                 {.vsyncId = generateToken(timestamp, preferredDeadlineTimestamp,
692                                           preferredExpectedPresentationTime),
693                  .deadlineTimestamp = preferredDeadlineTimestamp,
694                  .expectedPresentationTime = preferredExpectedPresentationTime};
695         currentIndex++;
696     }
697 
698     outVsyncEventData.frameTimelinesLength = currentIndex;
699 }
700 
dispatchEvent(const DisplayEventReceiver::Event & event,const DisplayEventConsumers & consumers)701 void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
702                                 const DisplayEventConsumers& consumers) {
703     for (const auto& consumer : consumers) {
704         DisplayEventReceiver::Event copy = event;
705         if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
706             const Period frameInterval = mCallback.getVsyncPeriod(consumer->mOwnerUid);
707             copy.vsync.vsyncData.frameInterval = frameInterval.ns();
708             generateFrameTimeline(copy.vsync.vsyncData, frameInterval.ns(), copy.header.timestamp,
709                                   event.vsync.vsyncData.preferredExpectedPresentationTime(),
710                                   event.vsync.vsyncData.preferredDeadlineTimestamp());
711         }
712         switch (consumer->postEvent(copy)) {
713             case NO_ERROR:
714                 break;
715 
716             case -EAGAIN:
717                 // TODO: Try again if pipe is full.
718                 ALOGW("Failed dispatching %s for %s", toString(event).c_str(),
719                       toString(*consumer).c_str());
720                 break;
721 
722             default:
723                 // Treat EPIPE and other errors as fatal.
724                 removeDisplayEventConnectionLocked(consumer);
725         }
726     }
727     if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC &&
728         FlagManager::getInstance().vrr_config()) {
729         mCallback.onExpectedPresentTimePosted(
730                 TimePoint::fromNs(event.vsync.vsyncData.preferredExpectedPresentationTime()));
731     }
732 }
733 
dump(std::string & result) const734 void EventThread::dump(std::string& result) const {
735     std::lock_guard<std::mutex> lock(mMutex);
736 
737     StringAppendF(&result, "%s: state=%s VSyncState=", mThreadName, toCString(mState));
738     if (mVSyncState) {
739         StringAppendF(&result, "{displayId=%s, count=%u%s}\n",
740                       to_string(mVSyncState->displayId).c_str(), mVSyncState->count,
741                       mVSyncState->synthetic ? ", synthetic" : "");
742     } else {
743         StringAppendF(&result, "none\n");
744     }
745 
746     const auto relativeLastCallTime =
747             ticks<std::milli, float>(mLastVsyncCallbackTime - TimePoint::now());
748     StringAppendF(&result, "mWorkDuration=%.2f mReadyDuration=%.2f last vsync time ",
749                   mWorkDuration.get().count() / 1e6f, mReadyDuration.count() / 1e6f);
750     StringAppendF(&result, "%.2fms relative to now\n", relativeLastCallTime);
751 
752     StringAppendF(&result, "  pending events (count=%zu):\n", mPendingEvents.size());
753     for (const auto& event : mPendingEvents) {
754         StringAppendF(&result, "    %s\n", toString(event).c_str());
755     }
756 
757     StringAppendF(&result, "  connections (count=%zu):\n", mDisplayEventConnections.size());
758     for (const auto& ptr : mDisplayEventConnections) {
759         if (const auto connection = ptr.promote()) {
760             StringAppendF(&result, "    %s\n", toString(*connection).c_str());
761         }
762     }
763     result += '\n';
764 }
765 
toCString(State state)766 const char* EventThread::toCString(State state) {
767     switch (state) {
768         case State::Idle:
769             return "Idle";
770         case State::Quit:
771             return "Quit";
772         case State::SyntheticVSync:
773             return "SyntheticVSync";
774         case State::VSync:
775             return "VSync";
776     }
777 }
778 
onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule> schedule)779 void EventThread::onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule> schedule) {
780     // Hold onto the old registration until after releasing the mutex to avoid deadlock.
781     scheduler::VSyncCallbackRegistration oldRegistration =
782             onNewVsyncScheduleInternal(std::move(schedule));
783 }
784 
onNewVsyncScheduleInternal(std::shared_ptr<scheduler::VsyncSchedule> schedule)785 scheduler::VSyncCallbackRegistration EventThread::onNewVsyncScheduleInternal(
786         std::shared_ptr<scheduler::VsyncSchedule> schedule) {
787     std::lock_guard<std::mutex> lock(mMutex);
788     const bool reschedule = mVsyncRegistration.cancel() == scheduler::CancelResult::Cancelled;
789     mVsyncSchedule = std::move(schedule);
790     auto oldRegistration =
791             std::exchange(mVsyncRegistration,
792                           scheduler::VSyncCallbackRegistration(mVsyncSchedule->getDispatch(),
793                                                                createDispatchCallback(),
794                                                                mThreadName));
795     if (reschedule) {
796         mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
797                                      .readyDuration = mReadyDuration.count(),
798                                      .lastVsync = mLastVsyncCallbackTime.ns()});
799     }
800     return oldRegistration;
801 }
802 
createDispatchCallback()803 scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() {
804     return [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
805         onVsync(vsyncTime, wakeupTime, readyTime);
806     };
807 }
808 
809 } // namespace impl
810 } // namespace android
811 
812 // TODO(b/129481165): remove the #pragma below and fix conversion issues
813 #pragma clang diagnostic pop // ignored "-Wconversion"
814