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