VSync是Android4.1黄油计划引入的三大核心元素之一,主要为解决用户交互体验差的问题。Android通过VSync机制来提高显示效果,通常这个信号是由显示驱动产生,这样才能达到最佳效果。但是Android为了能运行在不支持VSync机制的设备上,也提供了软件模拟产生VSync信号的手段。vsync信号主要由闸刀控制线程EventControlThread,事件线程EventThread,控制线程VsyncThread,BitTube , MessageQueue来实现。

1. VSYNC信号的传递

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
在SurfaceFlinger的init()函数

    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,            vsyncPhaseOffsetNs, true, "app"); //app同步源    mEventThread = new EventThread(vsyncSrc, *this, false);//事件线程    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,            sfVsyncPhaseOffsetNs, true, "sf");    mSFEventThread = new EventThread(sfVsyncSrc, *this, true); //    mEventQueue.setEventThread(mSFEventThread); //绑定事件队列

frameworks/native/services/surfaceflinger/MessageQueue.cpp

void MessageQueue::setEventThread(const sp<EventThread>& eventThread){    mEventThread = eventThread;    mEvents = eventThread->createEventConnection(); //创建连接    mEvents->stealReceiveChannel(&mEventTube);//事件Tunnel, mEventTube是BitTube    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, //向消息循环注册事件            MessageQueue::cb_eventReceiver, this); //cb_eventReceiver处理BitTunnel来的事件}

frameworks/native/services/surfaceflinger/EventThread.cpp
创建Connection与BitTube通讯

sp<EventThread::Connection> EventThread::createEventConnection() const {    return new Connection(const_cast<EventThread*>(this));}

frameworks/native/services/surfaceflinger/EventThread.cpp
初始化

EventThread::Connection::Connection(        const sp<EventThread>& eventThread)    : count(-1), mEventThread(eventThread), mChannel(gui::BitTube::DefaultSize){}

frameworks/native/services/surfaceflinger/MessageQueue.cpp
//设置文件描述符

status_t EventThread::Connection::stealReceiveChannel(gui::BitTube* outChannel) {    outChannel->setReceiveFd(mChannel.moveReceiveFd());    return NO_ERROR;}

frameworks/native/libs/gui/BitTube.cpp

void BitTube::setReceiveFd(base::unique_fd&& receiveFd) {    mReceiveFd = std::move(receiveFd);}

frameworks/native/services/surfaceflinger/EventThread.h
Connection是EventThread的内部类

class EventThread : public Thread, private VSyncSource::Callback {    class Connection : public BnDisplayEventConnection { //事件连接的Binder服务端    public:        explicit Connection(const sp<EventThread>& eventThread);        status_t postEvent(const DisplayEventReceiver::Event& event);        // count >= 1 : continuous event. count is the vsync rate        // count == 0 : one-shot event that has not fired        // count ==-1 : one-shot event that fired this round / disabled        int32_t count;    private:        virtual ~Connection();        virtual void onFirstRef();        status_t stealReceiveChannel(gui::BitTube* outChannel) override;        status_t setVsyncRate(uint32_t count) override;        void requestNextVsync() override;    // asynchronous        sp<EventThread> const mEventThread;        gui::BitTube mChannel;    };    ...... }

system/core/libutils/Looper.cpp
这部分属于消息循环,借助epoll的多路IO复用,阻塞机制;详细以后再讲,最终会执行Looper_callbackFunc callback回调函数也就是上文所描述的MessageQueue::cb_eventReceiver函数

int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {    return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);}int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {  .......    if (!callback.get()) {        if (! mAllowNonCallbacks) {            ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");            return -1;        }        if (ident < 0) {            ALOGE("Invalid attempt to set NULL callback with ident < 0.");            return -1;        }    } else {        ident = POLL_CALLBACK;    }    { // acquire lock        AutoMutex _l(mLock);        Request request;        request.fd = fd;        request.ident = ident;        request.events = events;        request.seq = mNextRequestSeq++;        request.callback = callback;        request.data = data;        if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1        struct epoll_event eventItem;  //linux系统多路IO复用epoll        request.initEventItem(&eventItem);        ssize_t requestIndex = mRequests.indexOfKey(fd); //查找requestIndex        if (requestIndex < 0) { //未找到则新建            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);            if (epollResult < 0) {                ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));                return -1;            }            mRequests.add(fd, request); //加入请求队列        } else { //找到则更新修改            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);            if (epollResult < 0) { /如果/修改失败,新建                if (errno == ENOENT) {                    // Tolerate ENOENT because it means that an older file descriptor was                    // closed before its callback was unregistered and meanwhile a new                    // file descriptor with the same number has been created and is now                    // being registered for the first time.  This error may occur naturally                    // when a callback has the side-effect of closing the file descriptor                    // before returning and unregistering itself.  Callback sequence number                    // checks further ensure that the race is benign.                    //                    // Unfortunately due to kernel limitations we need to rebuild the epoll                    // set from scratch because it may contain an old file handle that we are                    // now unable to remove since its file descriptor is no longer valid.                    // No such problem would have occurred if we were using the poll system                    // call instead, but that approach carries others disadvantages.#if DEBUG_CALLBACKS                    ALOGD("%p ~ addFd - EPOLL_CTL_MOD failed due to file descriptor "                            "being recycled, falling back on EPOLL_CTL_ADD: %s",                            this, strerror(errno));#endif                    epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); //新建                    if (epollResult < 0) {                        ALOGE("Error modifying or adding epoll events for fd %d: %s",                                fd, strerror(errno));                        return -1;                    }                    scheduleEpollRebuildLocked();                } else { //修改成功                    ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno));                    return -1;                }            }            mRequests.replaceValueAt(requestIndex, request); //替换request        }    } // release lock    return 1;}

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger启动时会对消息队列初始化

void SurfaceFlinger::onFirstRef(){    mEventQueue.init(this);}

frameworks/native/services/surfaceflinger/MessageQueue.cpp

void MessageQueue::init(const sp<SurfaceFlinger>& flinger){    mFlinger = flinger;    mLooper = new Looper(true);    mHandler = new Handler(*this);}

frameworks/native/services/surfaceflinger/EventThread.cpp
EventThread开始处理队列事件

bool EventThread::threadLoop() {    DisplayEventReceiver::Event event;    Vector< sp<EventThread::Connection> > signalConnections; //连接队列    signalConnections = waitForEvent(&event); //等待    // dispatch events to listeners...    const size_t count = signalConnections.size(); //连接数量    for (size_t i=0 ; i<count ; i++) {        const sp<Connection>& conn(signalConnections[i]); //取        // now see if we still need to report this event        status_t err = conn->postEvent(event); //提交事件        if (err == -EAGAIN || err == -EWOULDBLOCK) {            // The destination doesn't accept events anymore, it's probably            // full. For now, we just drop the events on the floor.            // FIXME: Note that some events cannot be dropped and would have            // to be re-sent later.            // Right-now we don't have the ability to do this.            ALOGW("EventThread: dropping event (%08x) for connection %p",                    event.header.type, conn.get());        } else if (err < 0) {            // handle any other error on the pipe as fatal. the only            // reasonable thing to do is to clean-up this connection.            // The most common error we'll get here is -EPIPE.            removeDisplayEventConnection(signalConnections[i]);        }    }    return true;}

frameworks/native/services/surfaceflinger/EventThread.cpp
向BitTube发送事件

status_t EventThread::Connection::postEvent(        const DisplayEventReceiver::Event& event) {    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);    return size < 0 ? status_t(size) : status_t(NO_ERROR);}

frameworks/native/libs/gui/DisplayEventReceiver.cpp

ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,        Event const* events, size_t count){    return gui::BitTube::sendObjects(dataChannel, events, count);}

frameworks/native/libs/gui/BitTube.cpp

ssize_t BitTube::sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize) {    const char* vaddr = reinterpret_cast<const char*>(events);    ssize_t size = tube->write(vaddr, count * objSize); //写数据    // should never happen because of SOCK_SEQPACKET    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),                        "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were "                        "sent!)",                        count, objSize, size);    // ALOGE_IF(size<0, "error %d sending %d events", size, count);    return size < 0 ? size : size / static_cast<ssize_t>(objSize);}

frameworks/native/libs/gui/BitTube.cpp

ssize_t BitTube::write(void const* vaddr, size_t size) {    ssize_t err, len;    do {        len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL); //往套接发送信号        // cannot return less than size, since we're using SOCK_SEQPACKET        err = len < 0 ? errno : 0;    } while (err == EINTR);    return err == 0 ? len : -err;}

rameworks/native/libs/gui/BitTube.cpp
从BitTube的初始化函数可以看出使用了套接来通讯

void BitTube::init(size_t rcvbuf, size_t sndbuf) {    int sockets[2];    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {        size_t size = DEFAULT_SOCKET_BUFFER_SIZE;        setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));        setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));        // since we don't use the "return channel", we keep it small...        setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));        setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));        fcntl(sockets[0], F_SETFL, O_NONBLOCK);        fcntl(sockets[1], F_SETFL, O_NONBLOCK);        mReceiveFd.reset(sockets[0]);        mSendFd.reset(sockets[1]);    } else {        mReceiveFd.reset();        ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));    }}

frameworks/native/services/surfaceflinger/MessageQueue.cpp
消息循环的回调函数cb_eventReceiver主动读取BitTube端的数据

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 = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {        for (int i=0 ; i<n ; i++) {            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {                mHandler->dispatchInvalidate(); //派发事件                break;            }        }    }    return 1;}

那么为什么消息循环会知道Event何时被发送到BitTube,然后从BitTube的socket接收端读取呢,我们不得不回到setEventThread函数,设计得相当精妙

void MessageQueue::setEventThread(const sp<EventThread>& eventThread){    //mEventTube是 gui::BitTube,也就是mEventTube.getFd() 是消息队列与BitTube共用的文件描述符    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT,            MessageQueue::cb_eventReceiver, this);}

frameworks/native/libs/gui/DisplayEventReceiver.cpp

ssize_t DisplayEventReceiver::getEvents(gui::BitTube* dataChannel,        Event* events, size_t count){    return gui::BitTube::recvObjects(dataChannel, events, count);}

frameworks/native/libs/gui/DisplayEventReceiver.cpp

ssize_t BitTube::recvObjects(BitTube* tube, void* events, size_t count, size_t objSize) {    char* vaddr = reinterpret_cast<char*>(events);    ssize_t size = tube->read(vaddr, count * objSize);    // should never happen because of SOCK_SEQPACKET    LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),                        "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were "                        "received!)",                        count, objSize, size);    // ALOGE_IF(size<0, "error %d receiving %d events", size, count);    return size < 0 ? size : size / static_cast<ssize_t>(objSize);}

frameworks/native/libs/gui/DisplayEventReceiver.cpp

ssize_t BitTube::read(void* vaddr, size_t size) {    ssize_t err, len;    do {        len = ::recv(mReceiveFd, vaddr, size, MSG_DONTWAIT);        err = len < 0 ? errno : 0;    } while (err == EINTR);    if (err == EAGAIN || err == EWOULDBLOCK) {        // EAGAIN means that we have non-blocking I/O but there was no data to be read. Nothing the        // client should care about.        return 0;    }    return err == 0 ? len : -err;}

frameworks/native/services/surfaceflinger/MessageQueue.cpp
cb_eventReceiver函数读取到BitTube的数据后调用:Handler::dispatchInvalidate函数,最终由Handler::handleMessage处理

void MessageQueue::Handler::dispatchInvalidate() {    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));    }}//处理来自消息对列的消息,调用SurfaceFlinger来处理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;    }}

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
处理同步事件,对应于HardwareComposer调用册是onVSyncReceived

void SurfaceFlinger::onMessageReceived(int32_t what) {  ...... 在此处理同步事件}

2. vsync信号的控制

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger构造函数中初始化DispSync

 ...... mPrimaryDispSync.init(hasSyncFramework, dispSyncPresentTimeOffset); //初始化DispSync ......

frameworks/native/services/surfaceflinger/DispSync.cpp
主要启动显示同步线程

void DispSync::init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset) {    mIgnorePresentFences = !hasSyncFramework;    mPresentTimeOffset = dispSyncPresentTimeOffset;    mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); //启动线程}

frameworks/native/services/surfaceflinger/DispSync.cpp
线程循环

virtual bool threadLoop() {        status_t err;        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);        while (true) {            Vector<CallbackInvocation> callbackInvocations; //回调向量            nsecs_t targetTime = 0;            { // Scope for lock                Mutex::Autolock lock(mMutex);                if (kTraceDetailedInfo) {                    ATRACE_INT64("DispSync:Frame", mFrameNumber);                }                ALOGV("[%s] Frame %" PRId64, mName, mFrameNumber);                ++mFrameNumber;                if (mStop) {                    return false;                }                if (mPeriod == 0) {                    err = mCond.wait(mMutex); //事件等待signal                    if (err != NO_ERROR) {                        ALOGE("error waiting for new events: %s (%d)",                                strerror(-err), err);                        return false;                    }                    continue;                }                targetTime = computeNextEventTimeLocked(now); //计算下一次执行时间                bool isWakeup = false;                if (now < targetTime) { //事件还没到                    if (kTraceDetailedInfo) ATRACE_NAME("DispSync waiting");                    if (targetTime == INT64_MAX) {                        ALOGV("[%s] Waiting forever", mName);                        err = mCond.wait(mMutex);  //等待                    } else {                        ALOGV("[%s] Waiting until %" PRId64, mName,                                ns2us(targetTime));                        err = mCond.waitRelative(mMutex, targetTime - now); //设定等待时间                    }                    if (err == TIMED_OUT) {                        isWakeup = true; //超时唤醒                    } else if (err != NO_ERROR) {                        ALOGE("error waiting for next event: %s (%d)",                                strerror(-err), err);                        return false;                    }                }                now = systemTime(SYSTEM_TIME_MONOTONIC);                // Don't correct by more than 1.5 ms                static const nsecs_t kMaxWakeupLatency = us2ns(1500);                if (isWakeup) {                    mWakeupLatency = ((mWakeupLatency * 63) +                            (now - targetTime)) / 64;                    mWakeupLatency = min(mWakeupLatency, kMaxWakeupLatency);                    if (kTraceDetailedInfo) {                        ATRACE_INT64("DispSync:WakeupLat", now - targetTime);                        ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);                    }                }                callbackInvocations = gatherCallbackInvocationsLocked(now); //回调转换            }            if (callbackInvocations.size() > 0) {                fireCallbackInvocations(callbackInvocations); //调用回调            }        }        return false;    }

frameworks/native/services/surfaceflinger/DispSync.cpp
将mEventListeners回调队列转到callbackInvocations

 Vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) {        if (kTraceDetailedInfo) ATRACE_CALL();        ALOGV("[%s] gatherCallbackInvocationsLocked @ %" PRId64, mName,                ns2us(now));        Vector<CallbackInvocation> callbackInvocations;        nsecs_t onePeriodAgo = now - mPeriod;        for (size_t i = 0; i < mEventListeners.size(); i++) {            nsecs_t t = computeListenerNextEventTimeLocked(mEventListeners[i],                    onePeriodAgo);            if (t < now) {                CallbackInvocation ci;                ci.mCallback = mEventListeners[i].mCallback;                ci.mEventTime = t;                ALOGV("[%s] [%s] Preparing to fire", mName,                        mEventListeners[i].mName);                callbackInvocations.push(ci);                mEventListeners.editItemAt(i).mLastEventTime = t;            }        }        return callbackInvocations;    }

frameworks/native/services/surfaceflinger/DispSync.cpp
执行回调,此回调类型为DispSync::Callback,再SurfaceFlinger我们向EventThread传入了DispSyncSource对象

 void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {        if (kTraceDetailedInfo) ATRACE_CALL();        for (size_t i = 0; i < callbacks.size(); i++) {            callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);        }    }

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
DispSyncSource是SyncSource,DispSync::Callback子类,DispSyncSource 通过addEventListener向DispSync注册监听

class DispSyncSource : public VSyncSource, private DispSync::Callback {public:    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,        const char* name) :            mName(name),            mValue(0),            mTraceVsync(traceVsync),            mVsyncOnLabel(String8::format("VsyncOn-%s", name)),            mVsyncEventLabel(String8::format("VSYNC-%s", name)),            mDispSync(dispSync),            mCallbackMutex(),            mCallback(),            mVsyncMutex(),            mPhaseOffset(phaseOffset),            mEnabled(false) {}    virtual ~DispSyncSource() {}    virtual void setVSyncEnabled(bool enable) { //注册DispSync::Callback回调事件        Mutex::Autolock lock(mVsyncMutex);        if (enable) {            status_t err = mDispSync->addEventListener(mName, mPhaseOffset,                    static_cast<DispSync::Callback*>(this));            if (err != NO_ERROR) {                ALOGE("error registering vsync callback: %s (%d)",                        strerror(-err), err);            }            //ATRACE_INT(mVsyncOnLabel.string(), 1);        } else {            status_t err = mDispSync->removeEventListener(                    static_cast<DispSync::Callback*>(this));            if (err != NO_ERROR) {                ALOGE("error unregistering vsync callback: %s (%d)",                        strerror(-err), err);            }            //ATRACE_INT(mVsyncOnLabel.string(), 0);        }        mEnabled = enable;    }    virtual void setCallback(const sp<VSyncSource::Callback>& callback) { //绑定 VSyncSource::Callback        Mutex::Autolock lock(mCallbackMutex);        mCallback = callback;    }   ......private:    virtual void onDispSyncEvent(nsecs_t when) { //执行VSyncSource::Callback->onVSyncEvent        sp<VSyncSource::Callback> callback;        {            Mutex::Autolock lock(mCallbackMutex);            callback = mCallback;            if (mTraceVsync) {                mValue = (mValue + 1) % 2;                ATRACE_INT(mVsyncEventLabel.string(), mValue);            }        }        if (callback != NULL) {            callback->onVSyncEvent(when); //回调        }    }    ......};

frameworks/native/services/surfaceflinger/EventThread.cpp
回调函数VSyncSource::Callback在EventThread被执行

void EventThread::onVSyncEvent(nsecs_t timestamp) {    Mutex::Autolock _l(mLock);    mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;    mVSyncEvent[0].header.id = 0;    mVSyncEvent[0].header.timestamp = timestamp;    mVSyncEvent[0].vsync.count++;    mCondition.broadcast(); //发出同步广播}

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
闸刀控制线程将通过signal控制同步事件

    mEventControlThread = new EventControlThread(this);    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
bool EventControlThread::threadLoop() {    enum class VsyncState {Unset, On, Off};    auto currentVsyncState = VsyncState::Unset;    while (true) {        auto requestedVsyncState = VsyncState::On;        {            Mutex::Autolock lock(mMutex);            requestedVsyncState =                    mVsyncEnabled ? VsyncState::On : VsyncState::Off;            while (currentVsyncState == requestedVsyncState) {                status_t err = mCond.wait(mMutex);                if (err != NO_ERROR) {                    ALOGE("error waiting for new events: %s (%d)",                          strerror(-err), err);                    return false;                }                requestedVsyncState =                        mVsyncEnabled ? VsyncState::On : VsyncState::Off;            }        }        bool enable = requestedVsyncState == VsyncState::On;#ifdef USE_HWC2        mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY, enable);#else        mFlinger->eventControl(HWC_DISPLAY_PRIMARY,                SurfaceFlinger::EVENT_VSYNC, enable);#endif        currentVsyncState = requestedVsyncState;    }    return false;}

使用了Hardware同步

void SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {    ATRACE_CALL();    Mutex::Autolock lock(mStateLock);    getHwComposer().setVsyncEnabled(disp,            enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);}

来自Hardware的同步回调

void SurfaceFlinger::onVsyncReceived(int32_t sequenceId,        hwc2_display_t displayId, int64_t timestamp) {      { // Scope for the lock        Mutex::Autolock _l(mHWVsyncLock);        if (type == DisplayDevice::DISPLAY_PRIMARY && mPrimaryHWVsyncEnabled) {            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); //计算是否需要硬件同步        }    }    if (needsHwVsync) {        enableHardwareVsync(); //使能硬件同步    } else {        disableHardwareVsync(false);    }}

计算是否需要硬件同步

bool DispSync::addResyncSample(nsecs_t timestamp) {    Mutex::Autolock lock(mMutex);    ALOGV("[%s] addResyncSample(%" PRId64 ")", mName, ns2us(timestamp));    size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;    mResyncSamples[idx] = timestamp;    if (mNumResyncSamples == 0) { //如果重采样数为0        mPhase = 0;        mReferenceTime = timestamp;        ALOGV("[%s] First resync sample: mPeriod = %" PRId64 ", mPhase = 0, "                "mReferenceTime = %" PRId64, mName, ns2us(mPeriod),                ns2us(mReferenceTime));        mThread->updateModel(mPeriod, mPhase, mReferenceTime); //更新    }    if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {        mNumResyncSamples++;    } else {        mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;    }    updateModelLocked();    ......    return !modelLocked;}

将会触发同步事件信号,通知DispSyncThread执行回调函数

    void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {        if (kTraceDetailedInfo) ATRACE_CALL();        Mutex::Autolock lock(mMutex);        mPeriod = period;        mPhase = phase;        mReferenceTime = referenceTime;        ALOGV("[%s] updateModel: mPeriod = %" PRId64 ", mPhase = %" PRId64                " mReferenceTime = %" PRId64, mName, ns2us(mPeriod),                ns2us(mPhase), ns2us(mReferenceTime));        mCond.signal(); //执行    }

使能硬件同步也会放出signal信号,触发同步

void SurfaceFlinger::enableHardwareVsync() {    Mutex::Autolock _l(mHWVsyncLock);    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {        mPrimaryDispSync.beginResync();        //eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);        mEventControlThread->setVsyncEnabled(true); //开闸        mPrimaryHWVsyncEnabled = true;    }}

至此,我们从vsync信号的产生传递,vsync切换两个角度来看整个同步过程,vsync信号主要通过EventThread处理vsync事件,消息循环和BitTube来进行通讯,EventControlThread进行软硬件信号的切换,DispSync处理vsync切换事件并把切换事件回调给EventThread处理,可以说设计得相当精妙。共勉,共勉!

更多相关文章

  1. C语言函数的递归(上)
  2. android 实现表格上下滑,左右滑,并且标题也跟着滑
  3. Android(安卓)动画框架详解
  4. Android加载动态库不成功处理方法
  5. 为什么Looper.loop()死循环不会导致ANR
  6. Android(安卓)JNI概述
  7. ios开发之ios中控件
  8. Android技术博文汇总
  9. 从华为事件,看 Google Android(安卓)的独断专制!

随机推荐

  1. Google Maps Android(安卓)API v2 (googl
  2. 错误总结1,动态加载部分不能显示的原因
  3. android tv基础之焦点(二)
  4. Android(安卓)捕获运行时异常详解
  5. JNI开发第二步:20130726 NDK_JNI使用
  6. Android(安卓)Native层Binder.transact()
  7. Android(安卓)LsitView的实现
  8. 栈处理问题
  9. android back和home键的捕获
  10. Android——拍照、剪切、得到图片/从相册