summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/MessageQueue.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-01-24 16:39:14 -0800
committerMathias Agopian <mathias@google.com>2012-01-30 15:21:23 -0800
commit8aedd4737d6ce8548d2fd5def65b1e1737283821 (patch)
tree263ab5aa922c97b30875b9e16dc89f1915691e1a /services/surfaceflinger/MessageQueue.cpp
parent54d89516ef816c73fdcfaf90d5d5c159e432c3a5 (diff)
downloadframeworks_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.cpp61
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