diff options
author | Mathias Agopian <mathias@google.com> | 2012-01-24 16:39:14 -0800 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2012-01-30 15:21:23 -0800 |
commit | 8aedd4737d6ce8548d2fd5def65b1e1737283821 (patch) | |
tree | 263ab5aa922c97b30875b9e16dc89f1915691e1a /services/surfaceflinger/MessageQueue.cpp | |
parent | 54d89516ef816c73fdcfaf90d5d5c159e432c3a5 (diff) | |
download | frameworks_native-8aedd4737d6ce8548d2fd5def65b1e1737283821.zip frameworks_native-8aedd4737d6ce8548d2fd5def65b1e1737283821.tar.gz frameworks_native-8aedd4737d6ce8548d2fd5def65b1e1737283821.tar.bz2 |
SF now synchronizes to VSYNC
Change-Id: Ic5e4f2ea9927ce133eef9499c03161325e9d02c5
Diffstat (limited to 'services/surfaceflinger/MessageQueue.cpp')
-rw-r--r-- | services/surfaceflinger/MessageQueue.cpp | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp index cbd530c..70711e7 100644 --- a/services/surfaceflinger/MessageQueue.cpp +++ b/services/surfaceflinger/MessageQueue.cpp @@ -18,12 +18,17 @@ #include <errno.h> #include <sys/types.h> +#include <binder/IPCThreadState.h> + #include <utils/threads.h> #include <utils/Timers.h> #include <utils/Log.h> -#include <binder/IPCThreadState.h> + +#include <gui/IDisplayEventConnection.h> +#include <gui/BitTube.h> #include "MessageQueue.h" +#include "EventThread.h" namespace android { @@ -51,6 +56,15 @@ MessageQueue::MessageQueue() MessageQueue::~MessageQueue() { } +void MessageQueue::setEventThread(const sp<EventThread>& eventThread) +{ + mEventThread = eventThread; + mEvents = eventThread->createEventConnection(); + mEventTube = mEvents->getDataChannel(); + mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT, + MessageQueue::cb_eventReceiver, this); +} + void MessageQueue::waitMessage() { do { IPCThreadState::self()->flushCommands(); @@ -93,13 +107,54 @@ status_t MessageQueue::postMessage( return NO_ERROR; } -status_t MessageQueue::invalidate() { +void MessageQueue::scheduleWorkASAP() { if (android_atomic_or(1, &mWorkPending) == 0) { mLooper->wake(); - } + } +} + +status_t MessageQueue::invalidate() { + mEvents->requestNextVsync(); return NO_ERROR; } +int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { + MessageQueue* queue = reinterpret_cast<MessageQueue *>(data); + return queue->eventReceiver(fd, events); +} + +int MessageQueue::eventReceiver(int fd, int events) { + ssize_t n; + DisplayEventReceiver::Event buffer[8]; + while ((n = getEvents(buffer, 8)) > 0) { + for (int i=0 ; i<n ; i++) { + if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { + scheduleWorkASAP(); + break; + } + } + } + return 1; +} + +ssize_t MessageQueue::getEvents( + DisplayEventReceiver::Event* events, size_t count) +{ + ssize_t size = mEventTube->read(events, sizeof(events[0])*count); + ALOGE_IF(size<0, "MessageQueue::getEvents error (%s)", strerror(-size)); + if (size >= 0) { + // Note: if (size % sizeof(events[0])) != 0, we've got a + // partial read. This can happen if the queue filed up (ie: if we + // didn't pull from it fast enough). + // We discard the partial event and rely on the sender to + // re-send the event if appropriate (some events, like VSYNC + // can be lost forever). + // returns number of events read + size /= sizeof(events[0]); + } + return size; +} + // --------------------------------------------------------------------------- }; // namespace android |