Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8aedd473 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

SF now synchronizes to VSYNC

Change-Id: Ic5e4f2ea9927ce133eef9499c03161325e9d02c5
parent 54d89516
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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 \
+23 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ namespace android {
EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
    : mFlinger(flinger),
      mHw(flinger->graphicPlane(0).displayHardware()),
      mLastVSyncTimestamp(0),
      mDeliveredEvents(0)
{
}
@@ -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);
@@ -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();
    }
}
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ namespace android {

class SurfaceFlinger;
class DisplayHardware;
class DisplayEventConnection;

// ---------------------------------------------------------------------------

@@ -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);

@@ -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:
@@ -88,6 +95,7 @@ private:

    // protected by mLock
    KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > mDisplayEventConnections;
    nsecs_t mLastVSyncTimestamp;

    // main thread only
    size_t mDeliveredEvents;
+5 −0
Original line number Diff line number Diff line
@@ -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()
+58 −3
Original line number Diff line number Diff line
@@ -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
Loading