blob: 1683982485b8e67c3d000219f31a18c5ed43973b [file] [log] [blame]
Mathias Agopiand0566bc2011-11-17 17:49:17 -08001/*
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
Mathias Agopian841cde52012-03-01 15:44:37 -080017#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18
Lloyd Pique46a46b32018-01-31 19:01:18 -080019#include <pthread.h>
20#include <sched.h>
Mathias Agopiand0566bc2011-11-17 17:49:17 -080021#include <sys/types.h>
Lloyd Pique46a46b32018-01-31 19:01:18 -080022#include <chrono>
23#include <cstdint>
Mathias Agopiand0566bc2011-11-17 17:49:17 -080024
Yiwei Zhang5434a782018-12-05 18:06:32 -080025#include <android-base/stringprintf.h>
26
Mathias Agopiana4cb35a2012-08-20 20:07:34 -070027#include <cutils/compiler.h>
Lloyd Pique46a46b32018-01-31 19:01:18 -080028#include <cutils/sched_policy.h>
Mathias Agopiana4cb35a2012-08-20 20:07:34 -070029
Mathias Agopiand0566bc2011-11-17 17:49:17 -080030#include <gui/DisplayEventReceiver.h>
31
32#include <utils/Errors.h>
Mathias Agopian841cde52012-03-01 15:44:37 -080033#include <utils/Trace.h>
Mathias Agopiand0566bc2011-11-17 17:49:17 -080034
Mathias Agopiand0566bc2011-11-17 17:49:17 -080035#include "EventThread.h"
Mathias Agopiand0566bc2011-11-17 17:49:17 -080036
Lloyd Pique46a46b32018-01-31 19:01:18 -080037using namespace std::chrono_literals;
Yiwei Zhang5434a782018-12-05 18:06:32 -080038using android::base::StringAppendF;
Lloyd Pique46a46b32018-01-31 19:01:18 -080039
Mathias Agopiand0566bc2011-11-17 17:49:17 -080040// ---------------------------------------------------------------------------
41
Lloyd Pique46a46b32018-01-31 19:01:18 -080042namespace android {
43
44// ---------------------------------------------------------------------------
45
Ana Krulec85c39af2018-12-26 17:29:57 -080046EventThreadConnection::EventThreadConnection(EventThread* eventThread)
47 : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
48
49EventThreadConnection::~EventThreadConnection() {
50 // do nothing here -- clean-up will happen automatically
51 // when the main thread wakes up
52}
53
54void EventThreadConnection::onFirstRef() {
55 // NOTE: mEventThread doesn't hold a strong reference on us
56 mEventThread->registerDisplayEventConnection(this);
57}
58
59status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
60 outChannel->setReceiveFd(mChannel.moveReceiveFd());
61 return NO_ERROR;
62}
63
64status_t EventThreadConnection::setVsyncRate(uint32_t count) {
65 mEventThread->setVsyncRate(count, this);
66 return NO_ERROR;
67}
68
69void EventThreadConnection::requestNextVsync() {
70 mEventThread->requestNextVsync(this);
71}
72
73status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
74 ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
75 return size < 0 ? status_t(size) : status_t(NO_ERROR);
76}
77
78// ---------------------------------------------------------------------------
79
Lloyd Pique0fcde1b2017-12-20 16:50:21 -080080EventThread::~EventThread() = default;
81
82namespace impl {
83
Ana Krulec98b5b242018-08-10 15:03:23 -070084EventThread::EventThread(std::unique_ptr<VSyncSource> src,
Ana Krulecfb772822018-11-30 10:44:07 +010085 const ResyncWithRateLimitCallback& resyncWithRateLimitCallback,
86 const InterceptVSyncsCallback& interceptVSyncsCallback,
87 const ResetIdleTimerCallback& resetIdleTimerCallback,
88 const char* threadName)
Ana Krulec98b5b242018-08-10 15:03:23 -070089 : EventThread(nullptr, std::move(src), resyncWithRateLimitCallback, interceptVSyncsCallback,
Ana Krulecfb772822018-11-30 10:44:07 +010090 threadName) {
91 mResetIdleTimer = resetIdleTimerCallback;
92}
Ana Krulec98b5b242018-08-10 15:03:23 -070093
Lloyd Pique24b0a482018-03-09 18:52:26 -080094EventThread::EventThread(VSyncSource* src, ResyncWithRateLimitCallback resyncWithRateLimitCallback,
95 InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
Ana Krulec98b5b242018-08-10 15:03:23 -070096 : EventThread(src, nullptr, resyncWithRateLimitCallback, interceptVSyncsCallback,
97 threadName) {}
98
99EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
100 ResyncWithRateLimitCallback resyncWithRateLimitCallback,
101 InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
Lloyd Pique24b0a482018-03-09 18:52:26 -0800102 : mVSyncSource(src),
Ana Krulec98b5b242018-08-10 15:03:23 -0700103 mVSyncSourceUnique(std::move(uniqueSrc)),
Lloyd Pique24b0a482018-03-09 18:52:26 -0800104 mResyncWithRateLimitCallback(resyncWithRateLimitCallback),
105 mInterceptVSyncsCallback(interceptVSyncsCallback) {
Ana Krulec98b5b242018-08-10 15:03:23 -0700106 if (src == nullptr) {
107 mVSyncSource = mVSyncSourceUnique.get();
108 }
Lloyd Pique46a46b32018-01-31 19:01:18 -0800109 for (auto& event : mVSyncEvent) {
110 event.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
111 event.header.id = 0;
112 event.header.timestamp = 0;
113 event.vsync.count = 0;
Mathias Agopianff28e202012-09-20 23:24:19 -0700114 }
Lloyd Pique46a46b32018-01-31 19:01:18 -0800115
116 mThread = std::thread(&EventThread::threadMain, this);
117
118 pthread_setname_np(mThread.native_handle(), threadName);
119
120 pid_t tid = pthread_gettid_np(mThread.native_handle());
121
122 // Use SCHED_FIFO to minimize jitter
123 constexpr int EVENT_THREAD_PRIORITY = 2;
124 struct sched_param param = {0};
125 param.sched_priority = EVENT_THREAD_PRIORITY;
126 if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, &param) != 0) {
127 ALOGE("Couldn't set SCHED_FIFO for EventThread");
128 }
129
130 set_sched_policy(tid, SP_FOREGROUND);
131}
132
133EventThread::~EventThread() {
134 {
135 std::lock_guard<std::mutex> lock(mMutex);
136 mKeepRunning = false;
137 mCondition.notify_all();
138 }
139 mThread.join();
Ruchi Kandoief472ec2014-04-02 12:50:06 -0700140}
141
Dan Stozadb4ac3c2015-04-14 11:34:01 -0700142void EventThread::setPhaseOffset(nsecs_t phaseOffset) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800143 std::lock_guard<std::mutex> lock(mMutex);
Dan Stozadb4ac3c2015-04-14 11:34:01 -0700144 mVSyncSource->setPhaseOffset(phaseOffset);
145}
146
Ana Krulec85c39af2018-12-26 17:29:57 -0800147sp<EventThreadConnection> EventThread::createEventConnection() const {
148 return new EventThreadConnection(const_cast<EventThread*>(this));
Mathias Agopian8aedd472012-01-24 16:39:14 -0800149}
150
Ana Krulec85c39af2018-12-26 17:29:57 -0800151status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800152 std::lock_guard<std::mutex> lock(mMutex);
Chia-I Wu98cd38f2018-09-14 11:53:25 -0700153
154 // this should never happen
155 auto it = std::find(mDisplayEventConnections.cbegin(),
156 mDisplayEventConnections.cend(), connection);
157 if (it != mDisplayEventConnections.cend()) {
158 ALOGW("DisplayEventConnection %p already exists", connection.get());
159 mCondition.notify_all();
160 return ALREADY_EXISTS;
161 }
162
163 mDisplayEventConnections.push_back(connection);
Lloyd Pique46a46b32018-01-31 19:01:18 -0800164 mCondition.notify_all();
Mathias Agopiand0566bc2011-11-17 17:49:17 -0800165 return NO_ERROR;
166}
167
Ana Krulec85c39af2018-12-26 17:29:57 -0800168void EventThread::removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection) {
Chia-I Wu98cd38f2018-09-14 11:53:25 -0700169 auto it = std::find(mDisplayEventConnections.cbegin(),
170 mDisplayEventConnections.cend(), connection);
171 if (it != mDisplayEventConnections.cend()) {
172 mDisplayEventConnections.erase(it);
173 }
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800174}
175
Ana Krulec85c39af2018-12-26 17:29:57 -0800176void EventThread::setVsyncRate(uint32_t count, const sp<EventThreadConnection>& connection) {
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800177 if (int32_t(count) >= 0) { // server must protect against bad params
Lloyd Pique46a46b32018-01-31 19:01:18 -0800178 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700179 const int32_t new_count = (count == 0) ? -1 : count;
180 if (connection->count != new_count) {
181 connection->count = new_count;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800182 mCondition.notify_all();
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800183 }
184 }
185}
186
Ana Krulec85c39af2018-12-26 17:29:57 -0800187void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800188 std::lock_guard<std::mutex> lock(mMutex);
Ana Krulecfb772822018-11-30 10:44:07 +0100189 if (mResetIdleTimer) {
190 mResetIdleTimer();
191 }
Tim Murray4a4e4a22016-04-19 16:29:23 +0000192
Lloyd Pique24b0a482018-03-09 18:52:26 -0800193 if (mResyncWithRateLimitCallback) {
194 mResyncWithRateLimitCallback();
195 }
Tim Murray4a4e4a22016-04-19 16:29:23 +0000196
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700197 if (connection->count < 0) {
198 connection->count = 0;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800199 mCondition.notify_all();
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800200 }
Mathias Agopian23748662011-12-05 14:33:34 -0800201}
202
Mathias Agopian22ffb112012-04-10 21:04:02 -0700203void EventThread::onScreenReleased() {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800204 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopian22ffb112012-04-10 21:04:02 -0700205 if (!mUseSoftwareVSync) {
Mathias Agopian7d886472012-06-14 23:39:35 -0700206 // disable reliance on h/w vsync
207 mUseSoftwareVSync = true;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800208 mCondition.notify_all();
Mathias Agopian22ffb112012-04-10 21:04:02 -0700209 }
Mathias Agopian22ffb112012-04-10 21:04:02 -0700210}
211
212void EventThread::onScreenAcquired() {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800213 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopian7d886472012-06-14 23:39:35 -0700214 if (mUseSoftwareVSync) {
215 // resume use of h/w vsync
216 mUseSoftwareVSync = false;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800217 mCondition.notify_all();
Mathias Agopian7d886472012-06-14 23:39:35 -0700218 }
Mathias Agopian22ffb112012-04-10 21:04:02 -0700219}
220
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700221void EventThread::onVSyncEvent(nsecs_t timestamp) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800222 std::lock_guard<std::mutex> lock(mMutex);
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700223 mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
224 mVSyncEvent[0].header.id = 0;
225 mVSyncEvent[0].header.timestamp = timestamp;
226 mVSyncEvent[0].vsync.count++;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800227 mCondition.notify_all();
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700228}
229
Dominik Laskowski00a6fa22018-06-06 16:42:02 -0700230void EventThread::onHotplugReceived(DisplayType displayType, bool connected) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800231 std::lock_guard<std::mutex> lock(mMutex);
Dominik Laskowski00a6fa22018-06-06 16:42:02 -0700232
233 DisplayEventReceiver::Event event;
234 event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
235 event.header.id = displayType == DisplayType::Primary ? 0 : 1;
236 event.header.timestamp = systemTime();
237 event.hotplug.connected = connected;
238
Chia-I Wueac3db22018-09-14 11:28:03 -0700239 mPendingEvents.push(event);
Dominik Laskowski00a6fa22018-06-06 16:42:02 -0700240 mCondition.notify_all();
Mathias Agopian148994e2012-09-19 17:31:36 -0700241}
242
Lloyd Pique46a46b32018-01-31 19:01:18 -0800243void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
244 std::unique_lock<std::mutex> lock(mMutex);
245 while (mKeepRunning) {
246 DisplayEventReceiver::Event event;
Ana Krulec85c39af2018-12-26 17:29:57 -0800247 std::vector<sp<EventThreadConnection>> signalConnections;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800248 signalConnections = waitForEventLocked(&lock, &event);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700249
Lloyd Pique46a46b32018-01-31 19:01:18 -0800250 // dispatch events to listeners...
Ana Krulec85c39af2018-12-26 17:29:57 -0800251 for (const sp<EventThreadConnection>& conn : signalConnections) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800252 // now see if we still need to report this event
253 status_t err = conn->postEvent(event);
254 if (err == -EAGAIN || err == -EWOULDBLOCK) {
255 // The destination doesn't accept events anymore, it's probably
256 // full. For now, we just drop the events on the floor.
257 // FIXME: Note that some events cannot be dropped and would have
258 // to be re-sent later.
259 // Right-now we don't have the ability to do this.
260 ALOGW("EventThread: dropping event (%08x) for connection %p", event.header.type,
261 conn.get());
262 } else if (err < 0) {
263 // handle any other error on the pipe as fatal. the only
264 // reasonable thing to do is to clean-up this connection.
265 // The most common error we'll get here is -EPIPE.
Chia-I Wub02d51c2018-09-14 11:20:48 -0700266 removeDisplayEventConnectionLocked(conn);
Lloyd Pique46a46b32018-01-31 19:01:18 -0800267 }
Mathias Agopiand0566bc2011-11-17 17:49:17 -0800268 }
269 }
Mathias Agopiand0566bc2011-11-17 17:49:17 -0800270}
271
Andy McFadden6bf552e2012-08-30 16:34:41 -0700272// This will return when (1) a vsync event has been received, and (2) there was
273// at least one connection interested in receiving it when we started waiting.
Ana Krulec85c39af2018-12-26 17:29:57 -0800274std::vector<sp<EventThreadConnection>> EventThread::waitForEventLocked(
Dominik Laskowski00a6fa22018-06-06 16:42:02 -0700275 std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* outEvent) {
Ana Krulec85c39af2018-12-26 17:29:57 -0800276 std::vector<sp<EventThreadConnection>> signalConnections;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700277
Chia-I Wub02d51c2018-09-14 11:20:48 -0700278 while (signalConnections.empty() && mKeepRunning) {
Mathias Agopian148994e2012-09-19 17:31:36 -0700279 bool eventPending = false;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700280 bool waitForVSync = false;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700281
Mathias Agopianff28e202012-09-20 23:24:19 -0700282 size_t vsyncCount = 0;
283 nsecs_t timestamp = 0;
Dominik Laskowski00a6fa22018-06-06 16:42:02 -0700284 for (auto& event : mVSyncEvent) {
285 timestamp = event.header.timestamp;
Mathias Agopianff28e202012-09-20 23:24:19 -0700286 if (timestamp) {
287 // we have a vsync event to dispatch
Lloyd Pique24b0a482018-03-09 18:52:26 -0800288 if (mInterceptVSyncsCallback) {
289 mInterceptVSyncsCallback(timestamp);
Irvelab046852016-07-28 11:23:08 -0700290 }
Dominik Laskowski00a6fa22018-06-06 16:42:02 -0700291 *outEvent = event;
292 event.header.timestamp = 0;
293 vsyncCount = event.vsync.count;
Mathias Agopianff28e202012-09-20 23:24:19 -0700294 break;
295 }
296 }
297
298 if (!timestamp) {
299 // no vsync event, see if there are some other event
Chia-I Wueac3db22018-09-14 11:28:03 -0700300 eventPending = !mPendingEvents.empty();
Mathias Agopian148994e2012-09-19 17:31:36 -0700301 if (eventPending) {
302 // we have some other event to dispatch
Chia-I Wueac3db22018-09-14 11:28:03 -0700303 *outEvent = mPendingEvents.front();
304 mPendingEvents.pop();
Mathias Agopian148994e2012-09-19 17:31:36 -0700305 }
306 }
307
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700308 // find out connections waiting for events
Chia-I Wu98cd38f2018-09-14 11:53:25 -0700309 auto it = mDisplayEventConnections.begin();
310 while (it != mDisplayEventConnections.end()) {
Ana Krulec85c39af2018-12-26 17:29:57 -0800311 sp<EventThreadConnection> connection(it->promote());
Peiyong Lin566a3b42018-01-09 18:22:43 -0800312 if (connection != nullptr) {
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700313 bool added = false;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700314 if (connection->count >= 0) {
315 // we need vsync events because at least
316 // one connection is waiting for it
317 waitForVSync = true;
318 if (timestamp) {
319 // we consume the event only if it's time
320 // (ie: we received a vsync event)
321 if (connection->count == 0) {
322 // fired this time around
323 connection->count = -1;
Chia-I Wub02d51c2018-09-14 11:20:48 -0700324 signalConnections.push_back(connection);
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700325 added = true;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700326 } else if (connection->count == 1 ||
Lloyd Pique78ce4182018-01-31 16:39:51 -0800327 (vsyncCount % connection->count) == 0) {
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700328 // continuous event, and time to report it
Chia-I Wub02d51c2018-09-14 11:20:48 -0700329 signalConnections.push_back(connection);
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700330 added = true;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700331 }
332 }
333 }
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700334
335 if (eventPending && !timestamp && !added) {
336 // we don't have a vsync event to process
337 // (timestamp==0), but we have some pending
338 // messages.
Chia-I Wub02d51c2018-09-14 11:20:48 -0700339 signalConnections.push_back(connection);
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700340 }
Chia-I Wu98cd38f2018-09-14 11:53:25 -0700341 ++it;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700342 } else {
343 // we couldn't promote this reference, the connection has
344 // died, so clean-up!
Chia-I Wu98cd38f2018-09-14 11:53:25 -0700345 it = mDisplayEventConnections.erase(it);
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700346 }
347 }
348
349 // Here we figure out if we need to enable or disable vsyncs
350 if (timestamp && !waitForVSync) {
351 // we received a VSYNC but we have no clients
352 // don't report it, and disable VSYNC events
353 disableVSyncLocked();
354 } else if (!timestamp && waitForVSync) {
Andy McFadden6bf552e2012-08-30 16:34:41 -0700355 // we have at least one client, so we want vsync enabled
356 // (TODO: this function is called right after we finish
357 // notifying clients of a vsync, so this call will be made
358 // at the vsync rate, e.g. 60fps. If we can accurately
359 // track the current state we could avoid making this call
360 // so often.)
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700361 enableVSyncLocked();
362 }
363
Andy McFadden6bf552e2012-08-30 16:34:41 -0700364 // note: !timestamp implies signalConnections.isEmpty(), because we
365 // don't populate signalConnections if there's no vsync pending
Mathias Agopian148994e2012-09-19 17:31:36 -0700366 if (!timestamp && !eventPending) {
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700367 // wait for something to happen
Andy McFadden6bf552e2012-08-30 16:34:41 -0700368 if (waitForVSync) {
369 // This is where we spend most of our time, waiting
370 // for vsync events and new client registrations.
371 //
372 // If the screen is off, we can't use h/w vsync, so we
373 // use a 16ms timeout instead. It doesn't need to be
374 // precise, we just need to keep feeding our clients.
375 //
376 // We don't want to stall if there's a driver bug, so we
377 // use a (long) timeout when waiting for h/w vsync, and
378 // generate fake events when necessary.
379 bool softwareSync = mUseSoftwareVSync;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800380 auto timeout = softwareSync ? 16ms : 1000ms;
381 if (mCondition.wait_for(*lock, timeout) == std::cv_status::timeout) {
Andy McFadden6bf552e2012-08-30 16:34:41 -0700382 if (!softwareSync) {
383 ALOGW("Timed out waiting for hw vsync; faking it");
384 }
Mathias Agopianff28e202012-09-20 23:24:19 -0700385 // FIXME: how do we decide which display id the fake
386 // vsync came from ?
387 mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
Dominik Laskowski00a6fa22018-06-06 16:42:02 -0700388 mVSyncEvent[0].header.id = 0;
Mathias Agopianff28e202012-09-20 23:24:19 -0700389 mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
390 mVSyncEvent[0].vsync.count++;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700391 }
392 } else {
Andy McFadden6bf552e2012-08-30 16:34:41 -0700393 // Nobody is interested in vsync, so we just want to sleep.
394 // h/w vsync should be disabled, so this will wait until we
395 // get a new connection, or an existing connection becomes
396 // interested in receiving vsync again.
Lloyd Pique46a46b32018-01-31 19:01:18 -0800397 mCondition.wait(*lock);
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700398 }
399 }
Lloyd Pique46a46b32018-01-31 19:01:18 -0800400 }
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700401
402 // here we're guaranteed to have a timestamp and some connections to signal
Andy McFadden6bf552e2012-08-30 16:34:41 -0700403 // (The connections might have dropped out of mDisplayEventConnections
404 // while we were asleep, but we'll still have strong references to them.)
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700405 return signalConnections;
406}
407
Mathias Agopian22ffb112012-04-10 21:04:02 -0700408void EventThread::enableVSyncLocked() {
409 if (!mUseSoftwareVSync) {
410 // never enable h/w VSYNC when screen is off
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700411 if (!mVsyncEnabled) {
412 mVsyncEnabled = true;
Lloyd Piquee83f9312018-02-01 12:53:17 -0800413 mVSyncSource->setCallback(this);
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700414 mVSyncSource->setVSyncEnabled(true);
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700415 }
Mathias Agopian22ffb112012-04-10 21:04:02 -0700416 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700417 mDebugVsyncEnabled = true;
418}
419
Mathias Agopian22ffb112012-04-10 21:04:02 -0700420void EventThread::disableVSyncLocked() {
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700421 if (mVsyncEnabled) {
422 mVsyncEnabled = false;
423 mVSyncSource->setVSyncEnabled(false);
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700424 mDebugVsyncEnabled = false;
425 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700426}
427
Yiwei Zhang5434a782018-12-05 18:06:32 -0800428void EventThread::dump(std::string& result) const {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800429 std::lock_guard<std::mutex> lock(mMutex);
Yiwei Zhang5434a782018-12-05 18:06:32 -0800430 StringAppendF(&result, "VSYNC state: %s\n", mDebugVsyncEnabled ? "enabled" : "disabled");
431 StringAppendF(&result, " soft-vsync: %s\n", mUseSoftwareVSync ? "enabled" : "disabled");
432 StringAppendF(&result, " numListeners=%zu,\n events-delivered: %u\n",
433 mDisplayEventConnections.size(), mVSyncEvent[0].vsync.count);
Ana Krulec85c39af2018-12-26 17:29:57 -0800434 for (const wp<EventThreadConnection>& weak : mDisplayEventConnections) {
435 sp<EventThreadConnection> connection = weak.promote();
Yiwei Zhang5434a782018-12-05 18:06:32 -0800436 StringAppendF(&result, " %p: count=%d\n", connection.get(),
437 connection != nullptr ? connection->count : 0);
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700438 }
Yiwei Zhang5434a782018-12-05 18:06:32 -0800439 StringAppendF(&result, " other-events-pending: %zu\n", mPendingEvents.size());
Mathias Agopiand0566bc2011-11-17 17:49:17 -0800440}
441
Lloyd Pique0fcde1b2017-12-20 16:50:21 -0800442} // namespace impl
Lloyd Pique46a46b32018-01-31 19:01:18 -0800443} // namespace android