blob: 2cbc59edb49973e4001ef92d3d4f51dacf962010 [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
Mathias Agopiana4cb35a2012-08-20 20:07:34 -070025#include <cutils/compiler.h>
Lloyd Pique46a46b32018-01-31 19:01:18 -080026#include <cutils/sched_policy.h>
Mathias Agopiana4cb35a2012-08-20 20:07:34 -070027
Mathias Agopiand0566bc2011-11-17 17:49:17 -080028#include <gui/DisplayEventReceiver.h>
Lloyd Pique78ce4182018-01-31 16:39:51 -080029#include <gui/IDisplayEventConnection.h>
Mathias Agopiand0566bc2011-11-17 17:49:17 -080030
31#include <utils/Errors.h>
Mathias Agopian921e6ac2012-07-23 23:11:29 -070032#include <utils/String8.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"
36#include "SurfaceFlinger.h"
37
Lloyd Pique46a46b32018-01-31 19:01:18 -080038using namespace std::chrono_literals;
39
Mathias Agopiand0566bc2011-11-17 17:49:17 -080040// ---------------------------------------------------------------------------
41
Lloyd Pique46a46b32018-01-31 19:01:18 -080042namespace android {
43
44// ---------------------------------------------------------------------------
45
46EventThread::EventThread(const sp<VSyncSource>& src, SurfaceFlinger& flinger, bool interceptVSyncs,
47 const char* threadName)
48 : mVSyncSource(src), mFlinger(flinger), mInterceptVSyncs(interceptVSyncs) {
49 for (auto& event : mVSyncEvent) {
50 event.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
51 event.header.id = 0;
52 event.header.timestamp = 0;
53 event.vsync.count = 0;
Mathias Agopianff28e202012-09-20 23:24:19 -070054 }
Lloyd Pique46a46b32018-01-31 19:01:18 -080055
56 mThread = std::thread(&EventThread::threadMain, this);
57
58 pthread_setname_np(mThread.native_handle(), threadName);
59
60 pid_t tid = pthread_gettid_np(mThread.native_handle());
61
62 // Use SCHED_FIFO to minimize jitter
63 constexpr int EVENT_THREAD_PRIORITY = 2;
64 struct sched_param param = {0};
65 param.sched_priority = EVENT_THREAD_PRIORITY;
66 if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, &param) != 0) {
67 ALOGE("Couldn't set SCHED_FIFO for EventThread");
68 }
69
70 set_sched_policy(tid, SP_FOREGROUND);
71}
72
73EventThread::~EventThread() {
74 {
75 std::lock_guard<std::mutex> lock(mMutex);
76 mKeepRunning = false;
77 mCondition.notify_all();
78 }
79 mThread.join();
Ruchi Kandoief472ec2014-04-02 12:50:06 -070080}
81
Dan Stozadb4ac3c2015-04-14 11:34:01 -070082void EventThread::setPhaseOffset(nsecs_t phaseOffset) {
Lloyd Pique46a46b32018-01-31 19:01:18 -080083 std::lock_guard<std::mutex> lock(mMutex);
Dan Stozadb4ac3c2015-04-14 11:34:01 -070084 mVSyncSource->setPhaseOffset(phaseOffset);
85}
86
Mathias Agopiancb9732a2012-04-03 17:48:03 -070087sp<EventThread::Connection> EventThread::createEventConnection() const {
88 return new Connection(const_cast<EventThread*>(this));
Mathias Agopian8aedd472012-01-24 16:39:14 -080089}
90
Mathias Agopiand0566bc2011-11-17 17:49:17 -080091status_t EventThread::registerDisplayEventConnection(
Mathias Agopiancb9732a2012-04-03 17:48:03 -070092 const sp<EventThread::Connection>& connection) {
Lloyd Pique46a46b32018-01-31 19:01:18 -080093 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopiancb9732a2012-04-03 17:48:03 -070094 mDisplayEventConnections.add(connection);
Lloyd Pique46a46b32018-01-31 19:01:18 -080095 mCondition.notify_all();
Mathias Agopiand0566bc2011-11-17 17:49:17 -080096 return NO_ERROR;
97}
98
Lloyd Pique78ce4182018-01-31 16:39:51 -080099void EventThread::removeDisplayEventConnection(const wp<EventThread::Connection>& connection) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800100 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700101 mDisplayEventConnections.remove(connection);
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800102}
103
Lloyd Pique78ce4182018-01-31 16:39:51 -0800104void EventThread::setVsyncRate(uint32_t count, const sp<EventThread::Connection>& connection) {
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800105 if (int32_t(count) >= 0) { // server must protect against bad params
Lloyd Pique46a46b32018-01-31 19:01:18 -0800106 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700107 const int32_t new_count = (count == 0) ? -1 : count;
108 if (connection->count != new_count) {
109 connection->count = new_count;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800110 mCondition.notify_all();
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800111 }
112 }
113}
114
Lloyd Pique78ce4182018-01-31 16:39:51 -0800115void EventThread::requestNextVsync(const sp<EventThread::Connection>& connection) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800116 std::lock_guard<std::mutex> lock(mMutex);
Tim Murray4a4e4a22016-04-19 16:29:23 +0000117
118 mFlinger.resyncWithRateLimit();
119
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700120 if (connection->count < 0) {
121 connection->count = 0;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800122 mCondition.notify_all();
Mathias Agopian478ae5e2011-12-06 17:22:19 -0800123 }
Mathias Agopian23748662011-12-05 14:33:34 -0800124}
125
Mathias Agopian22ffb112012-04-10 21:04:02 -0700126void EventThread::onScreenReleased() {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800127 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopian22ffb112012-04-10 21:04:02 -0700128 if (!mUseSoftwareVSync) {
Mathias Agopian7d886472012-06-14 23:39:35 -0700129 // disable reliance on h/w vsync
130 mUseSoftwareVSync = true;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800131 mCondition.notify_all();
Mathias Agopian22ffb112012-04-10 21:04:02 -0700132 }
Mathias Agopian22ffb112012-04-10 21:04:02 -0700133}
134
135void EventThread::onScreenAcquired() {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800136 std::lock_guard<std::mutex> lock(mMutex);
Mathias Agopian7d886472012-06-14 23:39:35 -0700137 if (mUseSoftwareVSync) {
138 // resume use of h/w vsync
139 mUseSoftwareVSync = false;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800140 mCondition.notify_all();
Mathias Agopian7d886472012-06-14 23:39:35 -0700141 }
Mathias Agopian22ffb112012-04-10 21:04:02 -0700142}
143
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700144void EventThread::onVSyncEvent(nsecs_t timestamp) {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800145 std::lock_guard<std::mutex> lock(mMutex);
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700146 mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
147 mVSyncEvent[0].header.id = 0;
148 mVSyncEvent[0].header.timestamp = timestamp;
149 mVSyncEvent[0].vsync.count++;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800150 mCondition.notify_all();
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700151}
152
Mathias Agopian148994e2012-09-19 17:31:36 -0700153void EventThread::onHotplugReceived(int type, bool connected) {
Jesse Hall9e663de2013-08-16 14:28:37 -0700154 ALOGE_IF(type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
Lloyd Pique78ce4182018-01-31 16:39:51 -0800155 "received hotplug event for an invalid display (id=%d)", type);
Mathias Agopianff28e202012-09-20 23:24:19 -0700156
Lloyd Pique46a46b32018-01-31 19:01:18 -0800157 std::lock_guard<std::mutex> lock(mMutex);
Jesse Hall9e663de2013-08-16 14:28:37 -0700158 if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
Mathias Agopianff28e202012-09-20 23:24:19 -0700159 DisplayEventReceiver::Event event;
160 event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
161 event.header.id = type;
162 event.header.timestamp = systemTime();
163 event.hotplug.connected = connected;
164 mPendingEvents.add(event);
Lloyd Pique46a46b32018-01-31 19:01:18 -0800165 mCondition.notify_all();
Mathias Agopianff28e202012-09-20 23:24:19 -0700166 }
Mathias Agopian148994e2012-09-19 17:31:36 -0700167}
168
Lloyd Pique46a46b32018-01-31 19:01:18 -0800169void EventThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
170 std::unique_lock<std::mutex> lock(mMutex);
171 while (mKeepRunning) {
172 DisplayEventReceiver::Event event;
173 Vector<sp<EventThread::Connection> > signalConnections;
174 signalConnections = waitForEventLocked(&lock, &event);
Mathias Agopian3eb38cb2012-04-03 22:09:52 -0700175
Lloyd Pique46a46b32018-01-31 19:01:18 -0800176 // dispatch events to listeners...
177 const size_t count = signalConnections.size();
178 for (size_t i = 0; i < count; i++) {
179 const sp<Connection>& conn(signalConnections[i]);
180 // now see if we still need to report this event
181 status_t err = conn->postEvent(event);
182 if (err == -EAGAIN || err == -EWOULDBLOCK) {
183 // The destination doesn't accept events anymore, it's probably
184 // full. For now, we just drop the events on the floor.
185 // FIXME: Note that some events cannot be dropped and would have
186 // to be re-sent later.
187 // Right-now we don't have the ability to do this.
188 ALOGW("EventThread: dropping event (%08x) for connection %p", event.header.type,
189 conn.get());
190 } else if (err < 0) {
191 // handle any other error on the pipe as fatal. the only
192 // reasonable thing to do is to clean-up this connection.
193 // The most common error we'll get here is -EPIPE.
194 removeDisplayEventConnection(signalConnections[i]);
195 }
Mathias Agopiand0566bc2011-11-17 17:49:17 -0800196 }
197 }
Mathias Agopiand0566bc2011-11-17 17:49:17 -0800198}
199
Andy McFadden6bf552e2012-08-30 16:34:41 -0700200// This will return when (1) a vsync event has been received, and (2) there was
201// at least one connection interested in receiving it when we started waiting.
Lloyd Pique46a46b32018-01-31 19:01:18 -0800202Vector<sp<EventThread::Connection> > EventThread::waitForEventLocked(
203 std::unique_lock<std::mutex>* lock, DisplayEventReceiver::Event* event) {
Lloyd Pique78ce4182018-01-31 16:39:51 -0800204 Vector<sp<EventThread::Connection> > signalConnections;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700205
Lloyd Pique46a46b32018-01-31 19:01:18 -0800206 while (signalConnections.isEmpty() && mKeepRunning) {
Mathias Agopian148994e2012-09-19 17:31:36 -0700207 bool eventPending = false;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700208 bool waitForVSync = false;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700209
Mathias Agopianff28e202012-09-20 23:24:19 -0700210 size_t vsyncCount = 0;
211 nsecs_t timestamp = 0;
Lloyd Pique78ce4182018-01-31 16:39:51 -0800212 for (int32_t i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; i++) {
Mathias Agopianff28e202012-09-20 23:24:19 -0700213 timestamp = mVSyncEvent[i].header.timestamp;
214 if (timestamp) {
215 // we have a vsync event to dispatch
Irvelab046852016-07-28 11:23:08 -0700216 if (mInterceptVSyncs) {
217 mFlinger.mInterceptor.saveVSyncEvent(timestamp);
218 }
Mathias Agopianff28e202012-09-20 23:24:19 -0700219 *event = mVSyncEvent[i];
220 mVSyncEvent[i].header.timestamp = 0;
221 vsyncCount = mVSyncEvent[i].vsync.count;
222 break;
223 }
224 }
225
226 if (!timestamp) {
227 // no vsync event, see if there are some other event
Mathias Agopian148994e2012-09-19 17:31:36 -0700228 eventPending = !mPendingEvents.isEmpty();
229 if (eventPending) {
230 // we have some other event to dispatch
231 *event = mPendingEvents[0];
232 mPendingEvents.removeAt(0);
233 }
234 }
235
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700236 // find out connections waiting for events
237 size_t count = mDisplayEventConnections.size();
Lloyd Pique78ce4182018-01-31 16:39:51 -0800238 for (size_t i = 0; i < count;) {
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700239 sp<Connection> connection(mDisplayEventConnections[i].promote());
Peiyong Lin566a3b42018-01-09 18:22:43 -0800240 if (connection != nullptr) {
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700241 bool added = false;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700242 if (connection->count >= 0) {
243 // we need vsync events because at least
244 // one connection is waiting for it
245 waitForVSync = true;
246 if (timestamp) {
247 // we consume the event only if it's time
248 // (ie: we received a vsync event)
249 if (connection->count == 0) {
250 // fired this time around
251 connection->count = -1;
252 signalConnections.add(connection);
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700253 added = true;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700254 } else if (connection->count == 1 ||
Lloyd Pique78ce4182018-01-31 16:39:51 -0800255 (vsyncCount % connection->count) == 0) {
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700256 // continuous event, and time to report it
257 signalConnections.add(connection);
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700258 added = true;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700259 }
260 }
261 }
Mathias Agopianb4d18ed2012-09-20 23:14:05 -0700262
263 if (eventPending && !timestamp && !added) {
264 // we don't have a vsync event to process
265 // (timestamp==0), but we have some pending
266 // messages.
267 signalConnections.add(connection);
268 }
Ivan Lozano01be49f2017-11-09 10:03:38 -0800269 ++i;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700270 } else {
271 // we couldn't promote this reference, the connection has
272 // died, so clean-up!
273 mDisplayEventConnections.removeAt(i);
Ivan Lozano01be49f2017-11-09 10:03:38 -0800274 --count;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700275 }
276 }
277
278 // Here we figure out if we need to enable or disable vsyncs
279 if (timestamp && !waitForVSync) {
280 // we received a VSYNC but we have no clients
281 // don't report it, and disable VSYNC events
282 disableVSyncLocked();
283 } else if (!timestamp && waitForVSync) {
Andy McFadden6bf552e2012-08-30 16:34:41 -0700284 // we have at least one client, so we want vsync enabled
285 // (TODO: this function is called right after we finish
286 // notifying clients of a vsync, so this call will be made
287 // at the vsync rate, e.g. 60fps. If we can accurately
288 // track the current state we could avoid making this call
289 // so often.)
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700290 enableVSyncLocked();
291 }
292
Andy McFadden6bf552e2012-08-30 16:34:41 -0700293 // note: !timestamp implies signalConnections.isEmpty(), because we
294 // don't populate signalConnections if there's no vsync pending
Mathias Agopian148994e2012-09-19 17:31:36 -0700295 if (!timestamp && !eventPending) {
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700296 // wait for something to happen
Andy McFadden6bf552e2012-08-30 16:34:41 -0700297 if (waitForVSync) {
298 // This is where we spend most of our time, waiting
299 // for vsync events and new client registrations.
300 //
301 // If the screen is off, we can't use h/w vsync, so we
302 // use a 16ms timeout instead. It doesn't need to be
303 // precise, we just need to keep feeding our clients.
304 //
305 // We don't want to stall if there's a driver bug, so we
306 // use a (long) timeout when waiting for h/w vsync, and
307 // generate fake events when necessary.
308 bool softwareSync = mUseSoftwareVSync;
Lloyd Pique46a46b32018-01-31 19:01:18 -0800309 auto timeout = softwareSync ? 16ms : 1000ms;
310 if (mCondition.wait_for(*lock, timeout) == std::cv_status::timeout) {
Andy McFadden6bf552e2012-08-30 16:34:41 -0700311 if (!softwareSync) {
312 ALOGW("Timed out waiting for hw vsync; faking it");
313 }
Mathias Agopianff28e202012-09-20 23:24:19 -0700314 // FIXME: how do we decide which display id the fake
315 // vsync came from ?
316 mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
Jesse Hall9e663de2013-08-16 14:28:37 -0700317 mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;
Mathias Agopianff28e202012-09-20 23:24:19 -0700318 mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
319 mVSyncEvent[0].vsync.count++;
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700320 }
321 } else {
Andy McFadden6bf552e2012-08-30 16:34:41 -0700322 // Nobody is interested in vsync, so we just want to sleep.
323 // h/w vsync should be disabled, so this will wait until we
324 // get a new connection, or an existing connection becomes
325 // interested in receiving vsync again.
Lloyd Pique46a46b32018-01-31 19:01:18 -0800326 mCondition.wait(*lock);
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700327 }
328 }
Lloyd Pique46a46b32018-01-31 19:01:18 -0800329 }
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700330
331 // here we're guaranteed to have a timestamp and some connections to signal
Andy McFadden6bf552e2012-08-30 16:34:41 -0700332 // (The connections might have dropped out of mDisplayEventConnections
333 // while we were asleep, but we'll still have strong references to them.)
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700334 return signalConnections;
335}
336
Mathias Agopian22ffb112012-04-10 21:04:02 -0700337void EventThread::enableVSyncLocked() {
338 if (!mUseSoftwareVSync) {
339 // never enable h/w VSYNC when screen is off
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700340 if (!mVsyncEnabled) {
341 mVsyncEnabled = true;
342 mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
343 mVSyncSource->setVSyncEnabled(true);
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700344 }
Mathias Agopian22ffb112012-04-10 21:04:02 -0700345 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700346 mDebugVsyncEnabled = true;
347}
348
Mathias Agopian22ffb112012-04-10 21:04:02 -0700349void EventThread::disableVSyncLocked() {
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700350 if (mVsyncEnabled) {
351 mVsyncEnabled = false;
352 mVSyncSource->setVSyncEnabled(false);
Jamie Gennisfaf77cc2013-07-30 15:10:32 -0700353 mDebugVsyncEnabled = false;
354 }
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700355}
356
Mathias Agopian74d211a2013-04-22 16:55:35 +0200357void EventThread::dump(String8& result) const {
Lloyd Pique46a46b32018-01-31 19:01:18 -0800358 std::lock_guard<std::mutex> lock(mMutex);
Lloyd Pique78ce4182018-01-31 16:39:51 -0800359 result.appendFormat("VSYNC state: %s\n", mDebugVsyncEnabled ? "enabled" : "disabled");
360 result.appendFormat(" soft-vsync: %s\n", mUseSoftwareVSync ? "enabled" : "disabled");
Greg Hackmann86efcc02014-03-07 12:44:02 -0800361 result.appendFormat(" numListeners=%zu,\n events-delivered: %u\n",
Lloyd Pique78ce4182018-01-31 16:39:51 -0800362 mDisplayEventConnections.size(),
363 mVSyncEvent[DisplayDevice::DISPLAY_PRIMARY].vsync.count);
364 for (size_t i = 0; i < mDisplayEventConnections.size(); i++) {
365 sp<Connection> connection = mDisplayEventConnections.itemAt(i).promote();
366 result.appendFormat(" %p: count=%d\n", connection.get(),
367 connection != nullptr ? connection->count : 0);
Mathias Agopiane2c4f4e2012-04-10 18:25:31 -0700368 }
Mathias Agopiand0566bc2011-11-17 17:49:17 -0800369}
370
371// ---------------------------------------------------------------------------
372
Lloyd Pique78ce4182018-01-31 16:39:51 -0800373EventThread::Connection::Connection(const sp<EventThread>& eventThread)
374 : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize) {}
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700375
376EventThread::Connection::~Connection() {
Mathias Agopianf6bbd442012-08-21 15:47:28 -0700377 // do nothing here -- clean-up will happen automatically
378 // when the main thread wakes up
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700379}
380
381void EventThread::Connection::onFirstRef() {
382 // NOTE: mEventThread doesn't hold a strong reference on us
383 mEventThread->registerDisplayEventConnection(this);
384}
385
Dan Stoza6b698e42017-04-03 13:09:08 -0700386status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
387 outChannel->setReceiveFd(mChannel.moveReceiveFd());
Dan Stozae1c599b2017-03-30 16:37:19 -0700388 return NO_ERROR;
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700389}
390
Dan Stozae1c599b2017-03-30 16:37:19 -0700391status_t EventThread::Connection::setVsyncRate(uint32_t count) {
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700392 mEventThread->setVsyncRate(count, this);
Dan Stozae1c599b2017-03-30 16:37:19 -0700393 return NO_ERROR;
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700394}
395
396void EventThread::Connection::requestNextVsync() {
397 mEventThread->requestNextVsync(this);
398}
399
Lloyd Pique78ce4182018-01-31 16:39:51 -0800400status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event) {
Dan Stoza6b698e42017-04-03 13:09:08 -0700401 ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
Mathias Agopiancb9732a2012-04-03 17:48:03 -0700402 return size < 0 ? status_t(size) : status_t(NO_ERROR);
403}
404
405// ---------------------------------------------------------------------------
406
Lloyd Pique46a46b32018-01-31 19:01:18 -0800407} // namespace android