summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/MessageQueue.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-01-31 18:24:27 -0800
committerMathias Agopian <mathias@google.com>2012-02-01 20:43:06 -0800
commit99ce5cdeb383216dee95af4d90e47406b0948ea1 (patch)
tree4f96f44e8e55a6c72b4e640704868f23a5e7c72b /services/surfaceflinger/MessageQueue.cpp
parent93bfeedd3768e25c783e22ed88103c2c409894a4 (diff)
downloadframeworks_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.cpp80
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