diff options
author | Mathias Agopian <mathias@google.com> | 2012-01-31 18:24:27 -0800 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2012-02-01 20:43:06 -0800 |
commit | 99ce5cdeb383216dee95af4d90e47406b0948ea1 (patch) | |
tree | 4f96f44e8e55a6c72b4e640704868f23a5e7c72b /services/surfaceflinger/MessageQueue.cpp | |
parent | 93bfeedd3768e25c783e22ed88103c2c409894a4 (diff) | |
download | frameworks_native-99ce5cdeb383216dee95af4d90e47406b0948ea1.zip frameworks_native-99ce5cdeb383216dee95af4d90e47406b0948ea1.tar.gz frameworks_native-99ce5cdeb383216dee95af4d90e47406b0948ea1.tar.bz2 |
separate transactions from updates
with this changes, SF transactions are handled as soon as possible
but do not trigger updates. the update is delayed until the next
vsync.
this allows us to work much better without requiring triple-buffering.
Change-Id: I1fa10794d0cf742129f0877698b7b1e1f2ec7401
Diffstat (limited to 'services/surfaceflinger/MessageQueue.cpp')
-rw-r--r-- | services/surfaceflinger/MessageQueue.cpp | 80 |
1 files changed, 42 insertions, 38 deletions
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp index 70711e7..1ff3567 100644 --- a/services/surfaceflinger/MessageQueue.cpp +++ b/services/surfaceflinger/MessageQueue.cpp @@ -29,6 +29,7 @@ #include "MessageQueue.h" #include "EventThread.h" +#include "SurfaceFlinger.h" namespace android { @@ -48,14 +49,47 @@ void MessageBase::handleMessage(const Message&) { // --------------------------------------------------------------------------- +void MessageQueue::Handler::signalRefresh() { + if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) { + mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH)); + } +} + +void MessageQueue::Handler::signalInvalidate() { + if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) { + mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE)); + } +} + +void MessageQueue::Handler::handleMessage(const Message& message) { + switch (message.what) { + case INVALIDATE: + android_atomic_and(~eventMaskInvalidate, &mEventMask); + mQueue.mFlinger->onMessageReceived(message.what); + break; + case REFRESH: + android_atomic_and(~eventMaskRefresh, &mEventMask); + mQueue.mFlinger->onMessageReceived(message.what); + break; + } +} + +// --------------------------------------------------------------------------- + MessageQueue::MessageQueue() - : mLooper(new Looper(true)), mWorkPending(0) { } MessageQueue::~MessageQueue() { } +void MessageQueue::init(const sp<SurfaceFlinger>& flinger) +{ + mFlinger = flinger; + mLooper = new Looper(true); + mHandler = new Handler(*this); +} + void MessageQueue::setEventThread(const sp<EventThread>& eventThread) { mEventThread = eventThread; @@ -68,25 +102,16 @@ void MessageQueue::setEventThread(const sp<EventThread>& eventThread) void MessageQueue::waitMessage() { do { IPCThreadState::self()->flushCommands(); - int32_t ret = mLooper->pollOnce(-1); switch (ret) { case ALOOPER_POLL_WAKE: case ALOOPER_POLL_CALLBACK: - // callback and/or wake - if (android_atomic_and(0, &mWorkPending)) { - return; - } continue; - - case ALOOPER_POLL_TIMEOUT: - // timeout (should not happen) - continue; - case ALOOPER_POLL_ERROR: ALOGE("ALOOPER_POLL_ERROR"); + case ALOOPER_POLL_TIMEOUT: + // timeout (should not happen) continue; - default: // should not happen ALOGE("Looper::pollOnce() returned unknown status %d", ret); @@ -107,15 +132,12 @@ status_t MessageQueue::postMessage( return NO_ERROR; } -void MessageQueue::scheduleWorkASAP() { - if (android_atomic_or(1, &mWorkPending) == 0) { - mLooper->wake(); - } +void MessageQueue::invalidate() { + mHandler->signalInvalidate(); } -status_t MessageQueue::invalidate() { +void MessageQueue::refresh() { mEvents->requestNextVsync(); - return NO_ERROR; } int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { @@ -126,10 +148,10 @@ int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { int MessageQueue::eventReceiver(int fd, int events) { ssize_t n; DisplayEventReceiver::Event buffer[8]; - while ((n = getEvents(buffer, 8)) > 0) { + while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) { for (int i=0 ; i<n ; i++) { if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { - scheduleWorkASAP(); + mHandler->signalRefresh(); break; } } @@ -137,24 +159,6 @@ int MessageQueue::eventReceiver(int fd, int events) { 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 |