diff options
Diffstat (limited to 'services/surfaceflinger/EventThread.cpp')
-rw-r--r-- | services/surfaceflinger/EventThread.cpp | 235 |
1 files changed, 0 insertions, 235 deletions
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp deleted file mode 100644 index 3c045d7..0000000 --- a/services/surfaceflinger/EventThread.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define ATRACE_TAG ATRACE_TAG_GRAPHICS - -#include <stdint.h> -#include <sys/types.h> - -#include <gui/IDisplayEventConnection.h> -#include <gui/DisplayEventReceiver.h> - -#include <utils/Errors.h> -#include <utils/Trace.h> - -#include "DisplayHardware/DisplayHardware.h" -#include "DisplayEventConnection.h" -#include "EventThread.h" -#include "SurfaceFlinger.h" - -// --------------------------------------------------------------------------- - -namespace android { - -// --------------------------------------------------------------------------- - -EventThread::EventThread(const sp<SurfaceFlinger>& flinger) - : mFlinger(flinger), - mHw(flinger->graphicPlane(0).displayHardware()), - mLastVSyncTimestamp(0), - mDeliveredEvents(0) -{ -} - -void EventThread::onFirstRef() { - run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); -} - -sp<DisplayEventConnection> EventThread::createEventConnection() const { - return new DisplayEventConnection(const_cast<EventThread*>(this)); -} - -nsecs_t EventThread::getLastVSyncTimestamp() const { - Mutex::Autolock _l(mLock); - return mLastVSyncTimestamp; -} - -nsecs_t EventThread::getVSyncPeriod() const { - return mHw.getRefreshPeriod(); - -} - -status_t EventThread::registerDisplayEventConnection( - const sp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - ConnectionInfo info; - mDisplayEventConnections.add(connection, info); - mCondition.signal(); - return NO_ERROR; -} - -status_t EventThread::unregisterDisplayEventConnection( - const wp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - mDisplayEventConnections.removeItem(connection); - mCondition.signal(); - return NO_ERROR; -} - -void EventThread::removeDisplayEventConnection( - const wp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - mDisplayEventConnections.removeItem(connection); -} - -EventThread::ConnectionInfo* EventThread::getConnectionInfoLocked( - const wp<DisplayEventConnection>& connection) { - ssize_t index = mDisplayEventConnections.indexOfKey(connection); - if (index < 0) return NULL; - return &mDisplayEventConnections.editValueAt(index); -} - -void EventThread::setVsyncRate(uint32_t count, - const wp<DisplayEventConnection>& connection) { - if (int32_t(count) >= 0) { // server must protect against bad params - Mutex::Autolock _l(mLock); - ConnectionInfo* info = getConnectionInfoLocked(connection); - if (info) { - const int32_t new_count = (count == 0) ? -1 : count; - if (info->count != new_count) { - info->count = new_count; - mCondition.signal(); - } - } - } -} - -void EventThread::requestNextVsync( - const wp<DisplayEventConnection>& connection) { - Mutex::Autolock _l(mLock); - ConnectionInfo* info = getConnectionInfoLocked(connection); - if (info && info->count < 0) { - info->count = 0; - mCondition.signal(); - } -} - -bool EventThread::threadLoop() { - - nsecs_t timestamp; - DisplayEventReceiver::Event vsync; - Vector< wp<DisplayEventConnection> > displayEventConnections; - - { // scope for the lock - Mutex::Autolock _l(mLock); - do { - // see if we need to wait for the VSYNC at all - do { - bool waitForNextVsync = false; - size_t count = mDisplayEventConnections.size(); - for (size_t i=0 ; i<count ; i++) { - const ConnectionInfo& info( - mDisplayEventConnections.valueAt(i)); - if (info.count >= 0) { - // at least one continuous mode or active one-shot event - waitForNextVsync = true; - break; - } - } - - if (waitForNextVsync) - break; - - mCondition.wait(mLock); - } while(true); - - // at least one listener requested VSYNC - mLock.unlock(); - timestamp = mHw.waitForRefresh(); - ATRACE_INT("VSYNC", mDeliveredEvents&1); - mLock.lock(); - mDeliveredEvents++; - mLastVSyncTimestamp = timestamp; - - // now see if we still need to report this VSYNC event - const size_t count = mDisplayEventConnections.size(); - for (size_t i=0 ; i<count ; i++) { - bool reportVsync = false; - const ConnectionInfo& info( - mDisplayEventConnections.valueAt(i)); - if (info.count >= 1) { - if (info.count==1 || (mDeliveredEvents % info.count) == 0) { - // continuous event, and time to report it - reportVsync = true; - } - } else if (info.count >= -1) { - ConnectionInfo& info( - mDisplayEventConnections.editValueAt(i)); - if (info.count == 0) { - // fired this time around - reportVsync = true; - } - info.count--; - } - if (reportVsync) { - displayEventConnections.add(mDisplayEventConnections.keyAt(i)); - } - } - } while (!displayEventConnections.size()); - - // dispatch vsync events to listeners... - vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; - vsync.header.timestamp = timestamp; - vsync.vsync.count = mDeliveredEvents; - } - - const size_t count = displayEventConnections.size(); - for (size_t i=0 ; i<count ; i++) { - sp<DisplayEventConnection> conn(displayEventConnections[i].promote()); - // make sure the connection didn't die - if (conn != NULL) { - status_t err = conn->postEvent(vsync); - if (err == -EAGAIN || err == -EWOULDBLOCK) { - // The destination doesn't accept events anymore, it's probably - // full. For now, we just drop the events on the floor. - // Note that some events cannot be dropped and would have to be - // re-sent later. Right-now we don't have the ability to do - // this, but it doesn't matter for VSYNC. - } else if (err < 0) { - // handle any other error on the pipe as fatal. the only - // reasonable thing to do is to clean-up this connection. - // The most common error we'll get here is -EPIPE. - removeDisplayEventConnection(displayEventConnections[i]); - } - } else { - // somehow the connection is dead, but we still have it in our list - // just clean the list. - removeDisplayEventConnection(displayEventConnections[i]); - } - } - - // clear all our references without holding mLock - displayEventConnections.clear(); - - return true; -} - -status_t EventThread::readyToRun() { - ALOGI("EventThread ready to run."); - return NO_ERROR; -} - -void EventThread::dump(String8& result, char* buffer, size_t SIZE) const { - Mutex::Autolock _l(mLock); - result.append("VSYNC state:\n"); - snprintf(buffer, SIZE, " numListeners=%u, events-delivered: %u\n", - mDisplayEventConnections.size(), mDeliveredEvents); - result.append(buffer); -} - -// --------------------------------------------------------------------------- - -}; // namespace android |