1d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian/*
2d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * Copyright (C) 2011 The Android Open Source Project
3d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian *
4d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * you may not use this file except in compliance with the License.
6d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * You may obtain a copy of the License at
7d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian *
8d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian *
10d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * Unless required by applicable law or agreed to in writing, software
11d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * See the License for the specific language governing permissions and
14d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian * limitations under the License.
15d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian */
16d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
17841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian
19d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <stdint.h>
20d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <sys/types.h>
21d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
22a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian#include <cutils/compiler.h>
23a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian
24d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/IDisplayEventConnection.h>
25d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <gui/DisplayEventReceiver.h>
26d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
27d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include <utils/Errors.h>
28921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include <utils/String8.h>
29841cde55549cea7a344a1705b18d57a0c6c8ec45Mathias Agopian#include <utils/Trace.h>
30d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
31d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "EventThread.h"
32d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian#include "SurfaceFlinger.h"
33d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
34d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------
35d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopiannamespace android {
36d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------
37ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi// time to wait between VSYNC requests before sending a VSYNC OFF power hint: 40msec.
38ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoiconst long vsyncHintOffDelay = 40000000;
39ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi
40ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoistatic void vsyncOffCallback(union sigval val) {
41ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    EventThread *ev = (EventThread *)val.sival_ptr;
42ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    ev->sendVsyncHintOff();
43ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    return;
44ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi}
45d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
46ab04685578b254c2eaf43bf5da85e5e922787825IrvelEventThread::EventThread(const sp<VSyncSource>& src, SurfaceFlinger& flinger, bool interceptVSyncs)
47faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    : mVSyncSource(src),
484a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray      mFlinger(flinger),
4922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian      mUseSoftwareVSync(false),
50faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis      mVsyncEnabled(false),
51ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi      mDebugVsyncEnabled(false),
52ab04685578b254c2eaf43bf5da85e5e922787825Irvel      mVsyncHintSent(false),
53ab04685578b254c2eaf43bf5da85e5e922787825Irvel      mInterceptVSyncs(interceptVSyncs) {
54ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian
559e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
56ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
57ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        mVSyncEvent[i].header.id = 0;
58ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        mVSyncEvent[i].header.timestamp = 0;
59ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        mVSyncEvent[i].vsync.count =  0;
60ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian    }
61ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    struct sigevent se;
62ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    se.sigev_notify = SIGEV_THREAD;
63ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    se.sigev_value.sival_ptr = this;
64ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    se.sigev_notify_function = vsyncOffCallback;
65ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    se.sigev_notify_attributes = NULL;
66ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
67ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi}
68ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi
69ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoivoid EventThread::sendVsyncHintOff() {
70ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    Mutex::Autolock _l(mLock);
71ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    mPowerHAL.vsyncHint(false);
72ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    mVsyncHintSent = false;
73ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi}
74ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi
75db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stozavoid EventThread::setPhaseOffset(nsecs_t phaseOffset) {
76db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    Mutex::Autolock _l(mLock);
77db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza    mVSyncSource->setPhaseOffset(phaseOffset);
78db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza}
79db4ac3ce63074f5602b46074ffeabfea4a14d032Dan Stoza
80ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoivoid EventThread::sendVsyncHintOnLocked() {
81ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    struct itimerspec ts;
82ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    if(!mVsyncHintSent) {
83ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi        mPowerHAL.vsyncHint(true);
84ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi        mVsyncHintSent = true;
85ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    }
86ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    ts.it_value.tv_sec = 0;
87ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    ts.it_value.tv_nsec = vsyncHintOffDelay;
88ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    ts.it_interval.tv_sec = 0;
89ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    ts.it_interval.tv_nsec = 0;
90ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    timer_settime(mTimerId, 0, &ts, NULL);
91d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
92d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
93d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianvoid EventThread::onFirstRef() {
94d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
95d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
96d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
97cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopiansp<EventThread::Connection> EventThread::createEventConnection() const {
98cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    return new Connection(const_cast<EventThread*>(this));
998aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian}
1008aedd4737d6ce8548d2fd5def65b1e1737283821Mathias Agopian
101d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianstatus_t EventThread::registerDisplayEventConnection(
102cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        const sp<EventThread::Connection>& connection) {
103d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    Mutex::Autolock _l(mLock);
104cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    mDisplayEventConnections.add(connection);
1057d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian    mCondition.broadcast();
106d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    return NO_ERROR;
107d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
108d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
109478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopianvoid EventThread::removeDisplayEventConnection(
110cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        const wp<EventThread::Connection>& connection) {
11123748668d33ac850e64d87e25ac4cc78679c9384Mathias Agopian    Mutex::Autolock _l(mLock);
112cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    mDisplayEventConnections.remove(connection);
113478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian}
114478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian
115478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopianvoid EventThread::setVsyncRate(uint32_t count,
116cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        const sp<EventThread::Connection>& connection) {
117478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian    if (int32_t(count) >= 0) { // server must protect against bad params
118478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian        Mutex::Autolock _l(mLock);
119cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        const int32_t new_count = (count == 0) ? -1 : count;
120cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        if (connection->count != new_count) {
121cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian            connection->count = new_count;
1227d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian            mCondition.broadcast();
123478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian        }
124478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian    }
125478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian}
126478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian
127478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopianvoid EventThread::requestNextVsync(
128cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        const sp<EventThread::Connection>& connection) {
129478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian    Mutex::Autolock _l(mLock);
1304a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
1314a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray    mFlinger.resyncWithRateLimit();
1324a4e4a239f034cb8af2df9a438b26c3bc088889cTim Murray
133cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    if (connection->count < 0) {
134cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        connection->count = 0;
1357d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian        mCondition.broadcast();
136478ae5eb5a0047e1b2988c896cff6363b455ee50Mathias Agopian    }
13723748668d33ac850e64d87e25ac4cc78679c9384Mathias Agopian}
13823748668d33ac850e64d87e25ac4cc78679c9384Mathias Agopian
13922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopianvoid EventThread::onScreenReleased() {
14022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    Mutex::Autolock _l(mLock);
14122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    if (!mUseSoftwareVSync) {
1427d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian        // disable reliance on h/w vsync
1437d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian        mUseSoftwareVSync = true;
1447d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian        mCondition.broadcast();
14522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    }
14622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian}
14722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
14822ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopianvoid EventThread::onScreenAcquired() {
14922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    Mutex::Autolock _l(mLock);
1507d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian    if (mUseSoftwareVSync) {
1517d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian        // resume use of h/w vsync
1527d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian        mUseSoftwareVSync = false;
1537d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian        mCondition.broadcast();
1547d886474734623fd2565ff40215ffe497e10b4ccMathias Agopian    }
15522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian}
15622ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian
157faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennisvoid EventThread::onVSyncEvent(nsecs_t timestamp) {
1583eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian    Mutex::Autolock _l(mLock);
159faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
160faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mVSyncEvent[0].header.id = 0;
161faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mVSyncEvent[0].header.timestamp = timestamp;
162faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mVSyncEvent[0].vsync.count++;
163faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    mCondition.broadcast();
1643eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian}
1653eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian
166148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopianvoid EventThread::onHotplugReceived(int type, bool connected) {
1679e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    ALOGE_IF(type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
1687adb0f8a9fdb961692ffd2f0c65cacb155143f64Jesse Hall            "received hotplug event for an invalid display (id=%d)", type);
169ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian
170148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    Mutex::Autolock _l(mLock);
1719e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall    if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
172ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        DisplayEventReceiver::Event event;
173ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
174ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        event.header.id = type;
175ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        event.header.timestamp = systemTime();
176ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        event.hotplug.connected = connected;
177ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        mPendingEvents.add(event);
178ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        mCondition.broadcast();
179ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian    }
180148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian}
181148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
182d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianbool EventThread::threadLoop() {
183b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian    DisplayEventReceiver::Event event;
184a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian    Vector< sp<EventThread::Connection> > signalConnections;
185b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian    signalConnections = waitForEvent(&event);
18623748668d33ac850e64d87e25ac4cc78679c9384Mathias Agopian
187148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian    // dispatch events to listeners...
188f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    const size_t count = signalConnections.size();
189f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
190f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        const sp<Connection>& conn(signalConnections[i]);
191b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian        // now see if we still need to report this event
192b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian        status_t err = conn->postEvent(event);
193f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        if (err == -EAGAIN || err == -EWOULDBLOCK) {
194f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // The destination doesn't accept events anymore, it's probably
195f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // full. For now, we just drop the events on the floor.
196b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian            // FIXME: Note that some events cannot be dropped and would have
197b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian            // to be re-sent later.
198b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian            // Right-now we don't have the ability to do this.
199b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian            ALOGW("EventThread: dropping event (%08x) for connection %p",
200b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                    event.header.type, conn.get());
201f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        } else if (err < 0) {
202f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // handle any other error on the pipe as fatal. the only
203f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // reasonable thing to do is to clean-up this connection.
204f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // The most common error we'll get here is -EPIPE.
205f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            removeDisplayEventConnection(signalConnections[i]);
206f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        }
207f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    }
208f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    return true;
209f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian}
210a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian
2116bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden// This will return when (1) a vsync event has been received, and (2) there was
2126bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden// at least one connection interested in receiving it when we started waiting.
213f6bbd44a23c2791277db7814a894633de04cd460Mathias AgopianVector< sp<EventThread::Connection> > EventThread::waitForEvent(
214f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        DisplayEventReceiver::Event* event)
215f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian{
216f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    Mutex::Autolock _l(mLock);
217f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    Vector< sp<EventThread::Connection> > signalConnections;
218a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian
219f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    do {
220148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        bool eventPending = false;
221a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian        bool waitForVSync = false;
222ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian
223ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        size_t vsyncCount = 0;
224ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        nsecs_t timestamp = 0;
2259e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall        for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
226ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian            timestamp = mVSyncEvent[i].header.timestamp;
227ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian            if (timestamp) {
228ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                // we have a vsync event to dispatch
229ab04685578b254c2eaf43bf5da85e5e922787825Irvel                if (mInterceptVSyncs) {
230ab04685578b254c2eaf43bf5da85e5e922787825Irvel                    mFlinger.mInterceptor.saveVSyncEvent(timestamp);
231ab04685578b254c2eaf43bf5da85e5e922787825Irvel                }
232ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                *event = mVSyncEvent[i];
233ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                mVSyncEvent[i].header.timestamp = 0;
234ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                vsyncCount = mVSyncEvent[i].vsync.count;
235ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                break;
236ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian            }
237ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        }
238ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian
239ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian        if (!timestamp) {
240ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian            // no vsync event, see if there are some other event
241148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian            eventPending = !mPendingEvents.isEmpty();
242148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian            if (eventPending) {
243148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian                // we have some other event to dispatch
244148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian                *event = mPendingEvents[0];
245148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian                mPendingEvents.removeAt(0);
246148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian            }
247148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        }
248148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian
249f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        // find out connections waiting for events
25010125f00a50d3edd05deef9fcd2d368cf2766683Mathias Agopian        size_t count = mDisplayEventConnections.size();
25110125f00a50d3edd05deef9fcd2d368cf2766683Mathias Agopian        for (size_t i=0 ; i<count ; i++) {
25210125f00a50d3edd05deef9fcd2d368cf2766683Mathias Agopian            sp<Connection> connection(mDisplayEventConnections[i].promote());
25310125f00a50d3edd05deef9fcd2d368cf2766683Mathias Agopian            if (connection != NULL) {
254b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                bool added = false;
25510125f00a50d3edd05deef9fcd2d368cf2766683Mathias Agopian                if (connection->count >= 0) {
256a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian                    // we need vsync events because at least
257a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian                    // one connection is waiting for it
258a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian                    waitForVSync = true;
259f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                    if (timestamp) {
260f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                        // we consume the event only if it's time
261f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                        // (ie: we received a vsync event)
262f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                        if (connection->count == 0) {
263f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                            // fired this time around
264a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian                            connection->count = -1;
265f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                            signalConnections.add(connection);
266b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                            added = true;
267f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                        } else if (connection->count == 1 ||
268f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                                (vsyncCount % connection->count) == 0) {
269f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                            // continuous event, and time to report it
270f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                            signalConnections.add(connection);
271b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                            added = true;
272a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian                        }
273a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian                    }
274a72d0db29213c407278a1d0257baa60db28c8471Mathias Agopian                }
275b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian
276b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                if (eventPending && !timestamp && !added) {
277b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                    // we don't have a vsync event to process
278b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                    // (timestamp==0), but we have some pending
279b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                    // messages.
280b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                    signalConnections.add(connection);
281b4d18ed34e3513f3a14ea0876c7e330bee72a529Mathias Agopian                }
282f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            } else {
283f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                // we couldn't promote this reference, the connection has
284f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                // died, so clean-up!
285f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                mDisplayEventConnections.removeAt(i);
286f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                --i; --count;
2873eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian            }
28810125f00a50d3edd05deef9fcd2d368cf2766683Mathias Agopian        }
2893eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian
290f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        // Here we figure out if we need to enable or disable vsyncs
291f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        if (timestamp && !waitForVSync) {
292f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // we received a VSYNC but we have no clients
293f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // don't report it, and disable VSYNC events
294f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            disableVSyncLocked();
295f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian        } else if (!timestamp && waitForVSync) {
2966bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden            // we have at least one client, so we want vsync enabled
2976bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden            // (TODO: this function is called right after we finish
2986bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden            // notifying clients of a vsync, so this call will be made
2996bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden            // at the vsync rate, e.g. 60fps.  If we can accurately
3006bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden            // track the current state we could avoid making this call
3016bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden            // so often.)
302f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            enableVSyncLocked();
30310125f00a50d3edd05deef9fcd2d368cf2766683Mathias Agopian        }
3043eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian
3056bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden        // note: !timestamp implies signalConnections.isEmpty(), because we
3066bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden        // don't populate signalConnections if there's no vsync pending
307148994e5f33ce240ff24ceb5bc0500b7f2001959Mathias Agopian        if (!timestamp && !eventPending) {
308f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            // wait for something to happen
3096bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden            if (waitForVSync) {
3106bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // This is where we spend most of our time, waiting
3116bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // for vsync events and new client registrations.
3126bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                //
3136bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // If the screen is off, we can't use h/w vsync, so we
3146bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // use a 16ms timeout instead.  It doesn't need to be
3156bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // precise, we just need to keep feeding our clients.
3166bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                //
3176bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // We don't want to stall if there's a driver bug, so we
3186bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // use a (long) timeout when waiting for h/w vsync, and
3196bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // generate fake events when necessary.
3206bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                bool softwareSync = mUseSoftwareVSync;
3216bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);
3226bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {
3236bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                    if (!softwareSync) {
3246bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                        ALOGW("Timed out waiting for hw vsync; faking it");
3256bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                    }
326ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                    // FIXME: how do we decide which display id the fake
327ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                    // vsync came from ?
328ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                    mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
3299e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall                    mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;
330ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                    mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
331ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian                    mVSyncEvent[0].vsync.count++;
332f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian                }
333f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian            } else {
3346bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // Nobody is interested in vsync, so we just want to sleep.
3356bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // h/w vsync should be disabled, so this will wait until we
3366bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // get a new connection, or an existing connection becomes
3376bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden                // interested in receiving vsync again.
338a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian                mCondition.wait(mLock);
339a4cb35a2864d58e9a764a17623e15ab25a9964a0Mathias Agopian            }
3403eb38cb33e41ce40dd1094bdec850f0fca9f8a53Mathias Agopian        }
341f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    } while (signalConnections.isEmpty());
342d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
343f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    // here we're guaranteed to have a timestamp and some connections to signal
3446bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden    // (The connections might have dropped out of mDisplayEventConnections
3456bf552ee02f8540a36cde7be90ffd840b2f6cd5cAndy McFadden    // while we were asleep, but we'll still have strong references to them.)
346f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    return signalConnections;
347d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
348d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
34922ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopianvoid EventThread::enableVSyncLocked() {
35022ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    if (!mUseSoftwareVSync) {
35122ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian        // never enable h/w VSYNC when screen is off
352faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        if (!mVsyncEnabled) {
353faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            mVsyncEnabled = true;
354faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
355faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis            mVSyncSource->setVSyncEnabled(true);
356faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        }
35722ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    }
358e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian    mDebugVsyncEnabled = true;
359ef472ec40a0fbb0ef96b79bef846f20b73da4971Ruchi Kandoi    sendVsyncHintOnLocked();
360e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian}
361e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian
36222ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopianvoid EventThread::disableVSyncLocked() {
363faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    if (mVsyncEnabled) {
364faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mVsyncEnabled = false;
365faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mVSyncSource->setVSyncEnabled(false);
366faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis        mDebugVsyncEnabled = false;
367faf77cce9d9ec0238d6999b3bd0d40c71ff403c5Jamie Gennis    }
368e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian}
369e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian
37074d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid EventThread::dump(String8& result) const {
371d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    Mutex::Autolock _l(mLock);
372e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian    result.appendFormat("VSYNC state: %s\n",
373e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian            mDebugVsyncEnabled?"enabled":"disabled");
37422ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian    result.appendFormat("  soft-vsync: %s\n",
37522ffb117b0c2a906bd04aef9738a52223cdd1dceMathias Agopian            mUseSoftwareVSync?"enabled":"disabled");
37686efcc0cbc1d94250b72ef1f2ea8700a04cd2781Greg Hackmann    result.appendFormat("  numListeners=%zu,\n  events-delivered: %u\n",
377ff28e201ec0c6d620eaaa29814ab52958487dc31Mathias Agopian            mDisplayEventConnections.size(),
3789e663de4fe1dcc872373ee530c60a375624671c3Jesse Hall            mVSyncEvent[DisplayDevice::DISPLAY_PRIMARY].vsync.count);
379e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian    for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) {
380e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian        sp<Connection> connection =
381e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian                mDisplayEventConnections.itemAt(i).promote();
382e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian        result.appendFormat("    %p: count=%d\n",
383e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian                connection.get(), connection!=NULL ? connection->count : 0);
384e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8Mathias Agopian    }
385d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}
386d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
387d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian// ---------------------------------------------------------------------------
388d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
389cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias AgopianEventThread::Connection::Connection(
390cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        const sp<EventThread>& eventThread)
3916b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza    : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize)
392cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian{
393cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian}
394cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
395cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias AgopianEventThread::Connection::~Connection() {
396f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    // do nothing here -- clean-up will happen automatically
397f6bbd44a23c2791277db7814a894633de04cd460Mathias Agopian    // when the main thread wakes up
398cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian}
399cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
400cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopianvoid EventThread::Connection::onFirstRef() {
401cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    // NOTE: mEventThread doesn't hold a strong reference on us
402cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    mEventThread->registerDisplayEventConnection(this);
403cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian}
404cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
4056b698e4fe4ff50dcef818452283637f9870ae770Dan Stozastatus_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {
4066b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza    outChannel->setReceiveFd(mChannel.moveReceiveFd());
407e1c599b52fcce94bd27ebbc4d74cd59c9e71b452Dan Stoza    return NO_ERROR;
408cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian}
409cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
410e1c599b52fcce94bd27ebbc4d74cd59c9e71b452Dan Stozastatus_t EventThread::Connection::setVsyncRate(uint32_t count) {
411cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    mEventThread->setVsyncRate(count, this);
412e1c599b52fcce94bd27ebbc4d74cd59c9e71b452Dan Stoza    return NO_ERROR;
413cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian}
414cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
415cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopianvoid EventThread::Connection::requestNextVsync() {
416cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    mEventThread->requestNextVsync(this);
417cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian}
418cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
419cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopianstatus_t EventThread::Connection::postEvent(
420cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian        const DisplayEventReceiver::Event& event) {
4216b698e4fe4ff50dcef818452283637f9870ae770Dan Stoza    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
422cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian    return size < 0 ? status_t(size) : status_t(NO_ERROR);
423cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian}
424cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
425cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian// ---------------------------------------------------------------------------
426cb9732a951d20cacb7ebe2dab132b5738226b1b6Mathias Agopian
427d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian}; // namespace android
428