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