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

Commit 590f9e20 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "SF now synchronizes to VSYNC"

parents a70c6e98 8aedd473
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