EventThread.cpp revision d0566bc26fcf6ca396118701fa11900b627f2c09
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdint.h> 18#include <sys/types.h> 19 20#include <gui/IDisplayEventConnection.h> 21#include <gui/DisplayEventReceiver.h> 22 23#include <utils/Errors.h> 24 25#include "DisplayHardware/DisplayHardware.h" 26#include "DisplayEventConnection.h" 27#include "EventThread.h" 28#include "SurfaceFlinger.h" 29 30// --------------------------------------------------------------------------- 31 32namespace android { 33 34// --------------------------------------------------------------------------- 35 36EventThread::EventThread(const sp<SurfaceFlinger>& flinger) 37 : mFlinger(flinger), 38 mHw(flinger->graphicPlane(0).displayHardware()), 39 mDeliveredEvents(0) 40{ 41} 42 43void EventThread::onFirstRef() { 44 run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); 45} 46 47status_t EventThread::registerDisplayEventConnection( 48 const sp<DisplayEventConnection>& connection) { 49 Mutex::Autolock _l(mLock); 50 mDisplayEventConnections.add(connection); 51 mCondition.signal(); 52 return NO_ERROR; 53} 54 55status_t EventThread::unregisterDisplayEventConnection( 56 const wp<DisplayEventConnection>& connection) { 57 Mutex::Autolock _l(mLock); 58 mDisplayEventConnections.remove(connection); 59 mCondition.signal(); 60 return NO_ERROR; 61} 62 63bool EventThread::threadLoop() { 64 65 nsecs_t timestamp; 66 Mutex::Autolock _l(mLock); 67 do { 68 // wait for listeners 69 while (!mDisplayEventConnections.size()) { 70 mCondition.wait(mLock); 71 } 72 73 // wait for vsync 74 mLock.unlock(); 75 timestamp = mHw.waitForVSync(); 76 mLock.lock(); 77 78 // make sure we still have some listeners 79 } while (!mDisplayEventConnections.size()); 80 81 82 // dispatch vsync events to listeners... 83 mDeliveredEvents++; 84 const size_t count = mDisplayEventConnections.size(); 85 86 DisplayEventReceiver::Event vsync; 87 vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; 88 vsync.header.timestamp = timestamp; 89 vsync.vsync.count = mDeliveredEvents; 90 91 for (size_t i=0 ; i<count ; i++) { 92 sp<DisplayEventConnection> conn(mDisplayEventConnections.itemAt(i).promote()); 93 // make sure the connection didn't die 94 if (conn != NULL) { 95 status_t err = conn->postEvent(vsync); 96 if (err == -EAGAIN || err == -EWOULDBLOCK) { 97 // The destination doesn't accept events anymore, it's probably 98 // full. For now, we just drop the events on the floor. 99 // Note that some events cannot be dropped and would have to be 100 // re-sent later. Right-now we don't have the ability to do 101 // this, but it doesn't matter for VSYNC. 102 } else if (err < 0) { 103 // handle any other error on the pipe as fatal. the only 104 // reasonable thing to do is to clean-up this connection. 105 // The most common error we'll get here is -EPIPE. 106 mDisplayEventConnections.remove(conn); 107 } 108 } 109 } 110 111 return true; 112} 113 114status_t EventThread::readyToRun() { 115 LOGI("EventThread ready to run."); 116 return NO_ERROR; 117} 118 119void EventThread::dump(String8& result, char* buffer, size_t SIZE) const { 120 Mutex::Autolock _l(mLock); 121 result.append("VSYNC state:\n"); 122 snprintf(buffer, SIZE, " numListeners=%u, events-delivered: %u\n", 123 mDisplayEventConnections.size(), mDeliveredEvents); 124 result.append(buffer); 125} 126 127// --------------------------------------------------------------------------- 128 129}; // namespace android 130