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, ¶m) != 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