其他分享
首页 > 其他分享> > Android GUI系统之SurfaceFlinger(06)服务端分析1-处理VSYNC

Android GUI系统之SurfaceFlinger(06)服务端分析1-处理VSYNC

作者:互联网

该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录


本章关键点总结 & 说明:

本章节思维导图如上。主要讲述了SurfaceFlinger 处理Vsync机制的流程。分析到处理消息这一部分。


1 SurfaceFlinger使用VSync流程框架

APP将产生的界面提交Buffer时会调用queueBuffer的操作,最后会通知SF合成界面。SF需要合成界面的时候,发送请求Vsync信号请求给EventThread(SF),EventThread(SF) 再向DispSyncThread线程发送请求,DispSyncThread线程收到请求后,延迟offset2后将VSync-SF发送给EventThread(SF) 并唤醒, EventThread(SF)在收到Vsync-SF后唤醒SF,SF开始合成新界面。整体框架如下所示:

2 SurfaceFlinger使用VSync流程 源码分析

2.1 分析模式

以上面的框架为基础,这里详细分析下该流程。当应用程序构造好数据后 通知SurfacFlinger,这部分在之前的章节中过已经分享过,因此这里代码直接从框架图的 第2步 开始分析。

2.2 SF向EventThread-SF 请求VSync

这里实际上是继续 章节4(Android GUI系统之SurfaceFlinger(04)应用端分析3-提交Buffer)的分析,mFlinger->signalLayerUpdate(),代码如下:

void SurfaceFlinger::signalLayerUpdate() {
    mEventQueue.invalidate();
}

这里就是 唤醒 另外一个线程EventThread-SF,继续分析mEventQueue.invalidate,代码实现如下:

void MessageQueue::invalidate() {
#if INVALIDATE_ON_VSYNC
    mEvents->requestNextVsync();
#else
    mHandler->dispatchInvalidate();
#endif
}

mEvents是EventThread::Connection类型的,对应的代码如下:

void EventThread::Connection::requestNextVsync() {
    mEventThread->requestNextVsync(this);
}

这里继续分析EventThread的requestNextVsync方法,代码实现如下:

void EventThread::requestNextVsync(
        const sp<EventThread::Connection>& connection) {
    Mutex::Autolock _l(mLock);
    if (connection->count < 0) {
        connection->count = 0;
        mCondition.broadcast();
    }
}

这里条件变量唤醒了当前的线程EventThread,那么另一个地方的wait被唤醒,这里就是EventThread::waitForEvent方法中的mCondition.wait(mLock),被唤醒后继续执行。

2.3 EventThread-SF向 DispSyncThread请求VSync

首先分析下EventThread线程的启动,即threadLoop的实现,代码如下:

bool EventThread::threadLoop() {
    DisplayEventReceiver::Event event;
    Vector< sp<EventThread::Connection> > signalConnections;
    //关键点1:等待事件
    signalConnections = waitForEvent(&event);
    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
        //关键点2:post事件
        status_t err = conn->postEvent(event);
        if (err == -EAGAIN || err == -EWOULDBLOCK) {
            //...
        } else if (err < 0) {
            //...
            removeDisplayEventConnection(signalConnections[i]);
        }
    }
    return true;
}

这里详细分析下waitForEvent,代码如下:

Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
        DisplayEventReceiver::Event* event)
{
    Mutex::Autolock _l(mLock);
    Vector< sp<EventThread::Connection> > signalConnections;

    do {
        bool eventPending = false;
        bool waitForVSync = false;

        size_t vsyncCount = 0;
        nsecs_t timestamp = 0;
        for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
            timestamp = mVSyncEvent[i].header.timestamp;
            if (timestamp) {
                // we have a vsync event to dispatch
                *event = mVSyncEvent[i];
                mVSyncEvent[i].header.timestamp = 0;
                vsyncCount = mVSyncEvent[i].vsync.count;
                break;
            }
        }

        if (!timestamp) {
            // no vsync event, see if there are some other event
            eventPending = !mPendingEvents.isEmpty();
            if (eventPending) {
                // we have some other event to dispatch
                *event = mPendingEvents[0];
                mPendingEvents.removeAt(0);
            }
        }

        // find out connections waiting for events
        size_t count = mDisplayEventConnections.size();
        for (size_t i=0 ; i<count ; i++) {
            sp<Connection> connection(mDisplayEventConnections[i].promote());
            if (connection != NULL) {
                bool added = false;
                if (connection->count >= 0) {//表示需要得到VSync
                    waitForVSync = true;
                    if (timestamp) {
                        if (connection->count == 0) {
                            connection->count = -1;
                            signalConnections.add(connection);
                            added = true;
                        } else if (connection->count == 1 ||
                                (vsyncCount % connection->count) == 0) {
                            signalConnections.add(connection);
                            added = true;
                        }
                    }
                }

                if (eventPending && !timestamp && !added) {
                    signalConnections.add(connection);
                }
            } else {
                mDisplayEventConnections.removeAt(i);
                --i; --count;
            }
        }

        // Here we figure out if we need to enable or disable vsyncs
        if (timestamp && !waitForVSync) {
            disableVSyncLocked();
        } else if (!timestamp && waitForVSync) {
            //如果需要Vsync,则调用该方法
            enableVSyncLocked();
        }

        if (!timestamp && !eventPending) {
            // wait for something to happen
            if (waitForVSync) {
                bool softwareSync = mUseSoftwareVSync;
                nsecs_t timeout = softwareSync ? ms2ns(16) : ms2ns(1000);
                if (mCondition.waitRelative(mLock, timeout) == TIMED_OUT) {
                    mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
                    mVSyncEvent[0].header.id = DisplayDevice::DISPLAY_PRIMARY;
                    mVSyncEvent[0].header.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
                    mVSyncEvent[0].vsync.count++;
                }
            } else {
                //休眠,等待下一个VSync到来
                mCondition.wait(mLock);
            }
        }
    } while (signalConnections.isEmpty());
    return signalConnections;
}

这里一旦表明需要VSync,则会调用关键方法enableVSyncLocked,代码实现如下:

void EventThread::enableVSyncLocked() {
    if (!mUseSoftwareVSync) {
        // never enable h/w VSYNC when screen is off
        if (!mVsyncEnabled) {
            mVsyncEnabled = true;
            //这里的mVSyncSource是DispSyncSource类型的
            //实际上是给DispSyncThread线程设置Callback
            mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
            mVSyncSource->setVSyncEnabled(true);
        }
    }
    mDebugVsyncEnabled = true;
    sendVsyncHintOnLocked();
}

继续分析,mVSyncSource是DispSyncSource类的对象,因此setCallback的代码实现如下:

    virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
        Mutex::Autolock lock(mMutex);
        mCallback = callback;
    }

这里设置了callback,后面 DispSyncThread就可以在收到VSync信号时调用该callback方法了。

2.4 唤醒DispSyncThread

这里以HWC的VSyncThread(实际上软件硬件 实现最终结果都是一样的),也就是软件实现的VSync来分析,软件VsyncThread的线程代码实现如下:

bool HWComposer::VSyncThread::threadLoop() {
    { // scope for lock
        Mutex::Autolock _l(mLock);
        while (!mEnabled) {
            mCondition.wait(mLock);
        }
    }
    const nsecs_t period = mRefreshPeriod;
    const nsecs_t now = systemTime(CLOCK_MONOTONIC);
    nsecs_t next_vsync = mNextFakeVSync;
    nsecs_t sleep = next_vsync - now;
    if (sleep < 0) {
        // we missed, find where the next vsync should be
        sleep = (period - ((now - next_vsync) % period));
        next_vsync = now + sleep;
    }
    mNextFakeVSync = next_vsync + period;
    struct timespec spec;
    spec.tv_sec  = next_vsync / 1000000000;
    spec.tv_nsec = next_vsync % 1000000000;

    int err;
    do {
        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
    } while (err<0 && errno == EINTR);

    if (err == 0) {
        mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
    }
    return true;
}

这里经过一段运算后,调用了 mHwc.mEventHandler.onVSyncReceived方法,mHwc.mEventHandler的值实际上就是SurafceFlinger,这在SurafceFlinger的init函数中有做,代码如下:

mHwc = new HWComposer(this,
            *static_cast<HWComposer::EventHandler *>(this));

因此,这里继续分析SurafceFlinger的onVSyncReceived方法的实现,代码如下:

void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
    bool needsHwVsync = false;

    { // Scope for the lock
        Mutex::Autolock _l(mHWVsyncLock);
        if (type == 0 && mPrimaryHWVsyncEnabled) {
            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
        }
    }

    if (needsHwVsync) {
        enableHardwareVsync();
    } else {
        disableHardwareVsync(false);
    }
}

这里继续分析DispSync的addResyncSample的实现,代码如下:

bool DispSync::addResyncSample(nsecs_t timestamp) {
    Mutex::Autolock lock(mMutex);

    size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
    mResyncSamples[idx] = timestamp;

    if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
        mNumResyncSamples++;
    } else {
        mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
    }

    updateModelLocked();

    if (mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {
        resetErrorLocked();
    }

    if (kIgnorePresentFences) {
        return mThread->hasAnyEventListeners();
    }

    return mPeriod == 0 || mError > kErrorThreshold;
}

这里继续分析DispSync的updateModelLocked的实现,代码如下:

void DispSync::updateModelLocked() {
    if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {
        nsecs_t durationSum = 0;
        for (size_t i = 1; i < mNumResyncSamples; i++) {
            size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
            size_t prev = (idx + MAX_RESYNC_SAMPLES - 1) % MAX_RESYNC_SAMPLES;
            durationSum += mResyncSamples[idx] - mResyncSamples[prev];
        }

        mPeriod = durationSum / (mNumResyncSamples - 1);

        double sampleAvgX = 0;
        double sampleAvgY = 0;
        double scale = 2.0 * M_PI / double(mPeriod);
        for (size_t i = 0; i < mNumResyncSamples; i++) {
            size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
            nsecs_t sample = mResyncSamples[idx];
            double samplePhase = double(sample % mPeriod) * scale;
            sampleAvgX += cos(samplePhase);
            sampleAvgY += sin(samplePhase);
        }

        sampleAvgX /= double(mNumResyncSamples);
        sampleAvgY /= double(mNumResyncSamples);

        mPhase = nsecs_t(atan2(sampleAvgY, sampleAvgX) / scale);

        if (mPhase < 0) {
            mPhase += mPeriod;
        }

        // Artificially inflate the period if requested.
        mPeriod += mPeriod * mRefreshSkipCount;

        mThread->updateModel(mPeriod, mPhase);
    }
}

这里继续分析mThread->updateModel的实现,代码如下:

void updateModel(nsecs_t period, nsecs_t phase) {
    Mutex::Autolock lock(mMutex);
    mPeriod = period;
    mPhase = phase;
    mCond.signal();
}

经过一系列的分析,SurafceFlinger的onVSyncReceived方法最终会唤醒DispSyncThread线程。

2.5 DispSyncThread唤醒EventThread

有mCond.signal()就有对应的mCond.wait(),该方法在线程执行体中threadloop中,threadloop的代码如下:

virtual bool threadLoop() {
    status_t err;
    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    nsecs_t nextEventTime = 0;

    while (true) {
        Vector<CallbackInvocation> callbackInvocations;

        nsecs_t targetTime = 0;

        { // Scope for lock
            Mutex::Autolock lock(mMutex);

            if (mStop) {
                return false;
            }

            if (mPeriod == 0) {
                err = mCond.wait(mMutex);
                //...
                continue;
            }
            /*计算最近的EventThread的时间。
              Eventthread发现connection>=0时,
              向线程DispSyncThread注册成callback,成为listener
            */
            nextEventTime = computeNextEventTimeLocked(now);
            targetTime = nextEventTime;

            bool isWakeup = false;

            if (now < targetTime) {//休眠
                err = mCond.waitRelative(mMutex, targetTime - now);

                if (err == TIMED_OUT) {
                    isWakeup = true;
                } else if (err != NO_ERROR) {
                    //...
                }
            }

            now = systemTime(SYSTEM_TIME_MONOTONIC);

            if (isWakeup) {
                mWakeupLatency = ((mWakeupLatency * 63) +
                        (now - targetTime)) / 64;
                if (mWakeupLatency > 500000) {
                    // Don't correct by more than 500 us
                    mWakeupLatency = 500000;
                }
            }
            //手机所有的callback
            callbackInvocations = gatherCallbackInvocationsLocked(now);
        }

        if (callbackInvocations.size() > 0) {
            //调用callback
            fireCallbackInvocations(callbackInvocations);
        }
    }
    return false;
}

这里fireCallbackInvocations的调用Callback实际上最终调用的就是EventThread-SF的onVSyncEvent,代码如下:


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();
}

至此EventThread-SF就被DispSyncThread给唤醒了。

2.6 EventThread-SF唤醒SurfaceFlinger

被DispSyncThread线程唤醒后,会执行对应的mCondition.wait,相关代码在waitforEvent中,相关代码如下:

bool EventThread::threadLoop() {
    DisplayEventReceiver::Event event;
    Vector< sp<EventThread::Connection> > signalConnections;
    //关键点1:等待事件
    signalConnections = waitForEvent(&event);
    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
        //关键点2:post事件
        status_t err = conn->postEvent(event);
        if (err == -EAGAIN || err == -EWOULDBLOCK) {
            //...
        } else if (err < 0) {
            //...
            removeDisplayEventConnection(signalConnections[i]);
        }
    }
    return true;
}

此时waitforEvent结束后,会进入到这个循环,会调用connection的 postEvent方法,继续分析,代码实现如下:

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

 

前面发送消息后必然会有一个接收端。但接收端直接分析并不容易,我们需要从SF中查找,在SF的init的代码中 ,关注这段代码:

void SurfaceFlinger::init()
{
    //...
    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            vsyncPhaseOffsetNs, true, "app");
    mEventThread = new EventThread(vsyncSrc);
    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
            sfVsyncPhaseOffsetNs, true, "sf");
    mSFEventThread = new EventThread(sfVsyncSrc);
    mEventQueue.setEventThread(mSFEventThread);//关键点
    //...
}

专门分析mEventQueue.setEventThread(mSFEventThread)的实现,代码如下:

void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
    mEventThread = eventThread;
    mEvents = eventThread->createEventConnection();
    mEventTube = mEvents->getDataChannel();
    mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
            MessageQueue::cb_eventReceiver, this);
}

这里主要是监听 EventThread是否有数据,专注分析MessageQueue::cb_eventReceiver的实现,代码如下:

int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
    MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
    return queue->eventReceiver(fd, events);
}

这里继续分析queue->eventReceiver,代码实现如下:

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) {
#if INVALIDATE_ON_VSYNC
                mHandler->dispatchInvalidate();
#else
                mHandler->dispatchRefresh();
#endif
                break;
            }
        }
    }
    return 1;
}

这里DisplayEventReceiver::getEvents 和 之前的sendEvent操作相对应。即SF 执行init后一直监听事件,如果有的话,则调用

mHandler->dispatchInvalidate()方法。

2.7 处理

void MessageQueue::Handler::dispatchInvalidate() {
    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
    }
}

这里实用了handler Message机制,因此直接看handleMessage的处理,如下:

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;
        case TRANSACTION:
            android_atomic_and(~eventMaskTransaction, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
    }
}

这里的INVALIDATE对应mQueue.mFlinger->onMessageReceived(message.what)方法的执行,onMessageReceived代码实现如下:

void SurfaceFlinger::onMessageReceived(int32_t what) {
    switch (what) {
        case MessageQueue::TRANSACTION: {
            handleMessageTransaction();
            break;
        }
        case MessageQueue::INVALIDATE: {
            //关键语句
            bool refreshNeeded = handleMessageTransaction();//1 
            refreshNeeded |= handleMessageInvalidate();//2 
            refreshNeeded |= mRepaintEverything;
            if (refreshNeeded) {
                signalRefresh();//3
            }
            break;
        }
        case MessageQueue::REFRESH: {
            handleMessageRefresh();
            break;
        }
    }
}

针对INVALIDATE消息,关键执行代码中标识的几句话。第7节我们详细分析这一部分。

 

 

标签:代码,EventThread,06,GUI,nsecs,SurfaceFlinger,void,SF,size
来源: https://blog.csdn.net/vviccc/article/details/104541964