Loading services/surfaceflinger/Android.mk +5 −1 Original line number Diff line number Diff line Loading @@ -23,18 +23,22 @@ LOCAL_SRC_FILES:= \ LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES ifeq ($(TARGET_HAS_WAITFORVSYNC), true) LOCAL_CFLAGS += -DHAS_WAITFORVSYNC endif ifeq ($(TARGET_BOARD_PLATFORM), omap3) LOCAL_CFLAGS += -DNO_RGBX_8888 endif ifeq ($(TARGET_BOARD_PLATFORM), omap4) LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY LOCAL_CFLAGS += -DUSE_TRIPLE_BUFFERING=1 endif ifeq ($(TARGET_BOARD_PLATFORM), s5pc110) LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE LOCAL_CFLAGS += -DREFRESH_RATE=56 endif LOCAL_SHARED_LIBRARIES := \ libcutils \ libhardware \ Loading services/surfaceflinger/EventThread.cpp +23 −6 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ namespace android { EventThread::EventThread(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger), mHw(flinger->graphicPlane(0).displayHardware()), mLastVSyncTimestamp(0), mDeliveredEvents(0) { } Loading @@ -44,6 +45,20 @@ 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); Loading Loading @@ -80,20 +95,21 @@ void EventThread::setVsyncRate(uint32_t count, Mutex::Autolock _l(mLock); ConnectionInfo* info = getConnectionInfoLocked(connection); if (info) { info->count = (count == 0) ? -1 : count; 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) { if (info->count < 0) { if (info && info->count < 0) { info->count = 0; } mCondition.signal(); } } Loading Loading @@ -132,6 +148,7 @@ bool EventThread::threadLoop() { timestamp = mHw.waitForRefresh(); mLock.lock(); mDeliveredEvents++; mLastVSyncTimestamp = timestamp; // now see if we still need to report this VSYNC event bool reportVsync = false; Loading services/surfaceflinger/EventThread.h +8 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ namespace android { class SurfaceFlinger; class DisplayHardware; class DisplayEventConnection; // --------------------------------------------------------------------------- Loading @@ -45,6 +46,8 @@ class EventThread : public Thread { public: EventThread(const sp<SurfaceFlinger>& flinger); sp<DisplayEventConnection> createEventConnection() const; status_t registerDisplayEventConnection( const sp<DisplayEventConnection>& connection); Loading @@ -56,6 +59,10 @@ public: void requestNextVsync(const wp<DisplayEventConnection>& connection); nsecs_t getLastVSyncTimestamp() const; nsecs_t getVSyncPeriod() const; void dump(String8& result, char* buffer, size_t SIZE) const; private: Loading Loading @@ -88,6 +95,7 @@ private: // protected by mLock KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > mDisplayEventConnections; nsecs_t mLastVSyncTimestamp; // main thread only size_t mDeliveredEvents; Loading services/surfaceflinger/Layer.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -97,7 +97,12 @@ void Layer::onFirstRef() mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this); mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); mSurfaceTexture->setSynchronousMode(true); #ifdef USE_TRIPLE_BUFFERING #warning "using triple buffering" mSurfaceTexture->setBufferCountServer(3); #else mSurfaceTexture->setBufferCountServer(2); #endif } Layer::~Layer() Loading services/surfaceflinger/MessageQueue.cpp +58 −3 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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(); Loading Loading @@ -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 Loading
services/surfaceflinger/Android.mk +5 −1 Original line number Diff line number Diff line Loading @@ -23,18 +23,22 @@ LOCAL_SRC_FILES:= \ LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES ifeq ($(TARGET_HAS_WAITFORVSYNC), true) LOCAL_CFLAGS += -DHAS_WAITFORVSYNC endif ifeq ($(TARGET_BOARD_PLATFORM), omap3) LOCAL_CFLAGS += -DNO_RGBX_8888 endif ifeq ($(TARGET_BOARD_PLATFORM), omap4) LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY LOCAL_CFLAGS += -DUSE_TRIPLE_BUFFERING=1 endif ifeq ($(TARGET_BOARD_PLATFORM), s5pc110) LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE LOCAL_CFLAGS += -DREFRESH_RATE=56 endif LOCAL_SHARED_LIBRARIES := \ libcutils \ libhardware \ Loading
services/surfaceflinger/EventThread.cpp +23 −6 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ namespace android { EventThread::EventThread(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger), mHw(flinger->graphicPlane(0).displayHardware()), mLastVSyncTimestamp(0), mDeliveredEvents(0) { } Loading @@ -44,6 +45,20 @@ 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); Loading Loading @@ -80,20 +95,21 @@ void EventThread::setVsyncRate(uint32_t count, Mutex::Autolock _l(mLock); ConnectionInfo* info = getConnectionInfoLocked(connection); if (info) { info->count = (count == 0) ? -1 : count; 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) { if (info->count < 0) { if (info && info->count < 0) { info->count = 0; } mCondition.signal(); } } Loading Loading @@ -132,6 +148,7 @@ bool EventThread::threadLoop() { timestamp = mHw.waitForRefresh(); mLock.lock(); mDeliveredEvents++; mLastVSyncTimestamp = timestamp; // now see if we still need to report this VSYNC event bool reportVsync = false; Loading
services/surfaceflinger/EventThread.h +8 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ namespace android { class SurfaceFlinger; class DisplayHardware; class DisplayEventConnection; // --------------------------------------------------------------------------- Loading @@ -45,6 +46,8 @@ class EventThread : public Thread { public: EventThread(const sp<SurfaceFlinger>& flinger); sp<DisplayEventConnection> createEventConnection() const; status_t registerDisplayEventConnection( const sp<DisplayEventConnection>& connection); Loading @@ -56,6 +59,10 @@ public: void requestNextVsync(const wp<DisplayEventConnection>& connection); nsecs_t getLastVSyncTimestamp() const; nsecs_t getVSyncPeriod() const; void dump(String8& result, char* buffer, size_t SIZE) const; private: Loading Loading @@ -88,6 +95,7 @@ private: // protected by mLock KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > mDisplayEventConnections; nsecs_t mLastVSyncTimestamp; // main thread only size_t mDeliveredEvents; Loading
services/surfaceflinger/Layer.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -97,7 +97,12 @@ void Layer::onFirstRef() mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this); mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); mSurfaceTexture->setSynchronousMode(true); #ifdef USE_TRIPLE_BUFFERING #warning "using triple buffering" mSurfaceTexture->setBufferCountServer(3); #else mSurfaceTexture->setBufferCountServer(2); #endif } Layer::~Layer() Loading
services/surfaceflinger/MessageQueue.cpp +58 −3 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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(); Loading Loading @@ -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