Android surfaceflinger (4) -Vsync产生上报流程

1、垂直同步信号

VSync(即V-Sync垂直同步)的具体含义和用途文章不细说,看下图的VSync的位置大致也就知道它的用途(简单理解成是硬件定时中断貌似也可以,周期性的硬件中断,频率为60Hz,周期为0.0167s,也就是16ms)。
本文主要关注以下几个问题: \
(1)VSync是如何产生的? \
(2)VSync是如何分发到应用进程的?

2、流程框图

这里写图片描述

3、VSync产生

VSync事件一般由硬件周期性产生,如果没有相应的硬件产生VSync事件,则通过软件模拟。下面主要看下从硬件产生VSync事件。

bool VSyncThread::threadLoop()
{
    if (mFakeVSync) {
        performFakeVSync();//软件模拟产生
    }
    else {
        performVSync();//硬件产生
    }

    return true;
}

void VSyncThread::performVSync()
{
    uint64_t timestamp = 0;
    uint32_t crt = (uint32_t)&timestamp;

    //调用kernel等待VSync信号
    int err = ioctl(mCtx->mDispInfo[HWC_DISPLAY_PRIMARY].fd,
                    MXCFB_WAIT_FOR_VSYNC, crt);
    if ( err < 0 ) {
        ALOGE("FBIO_WAITFORVSYNC error: %s\n", strerror(errno));
        return;
    }

    //回调至HWComposer类的hook_vsync方法 详见第3节
    mCtx->m_callback->vsync(mCtx->m_callback, 0, timestamp);
    ..........
}

4、VSync信号上报过程

4.1 HWComposer至DispSyncThread过程

在上面分析到了HWComposer类,hook_vsync实现如下:

void HWComposer::hook_vsync(const struct hwc_procs* procs, int disp,
        int64_t timestamp) {
    cb_context* ctx = reinterpret_cast<cb_context*>(
            const_cast<hwc_procs_t*>(procs));
    ctx->hwc->vsync(disp, timestamp);
}

ctx->hwc指向的就是当前的this指针,也就是当前的对象,因此调用的就是当前对象的vsync函数,看一下这个函数:

void HWComposer::vsync(int disp, int64_t timestamp) {
    if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
        ........
        mEventHandler.onVSyncReceived(disp, timestamp);
    }
}

最重要的就是调用了mEventHandler.onVSyncReceived()函数,这里mEventHandler是在HWComposer初始化的,实际上就是创建当前HWComposer对象的SurfaceFlinger对象,因此该函数回调至SurfaceFlinger.onVSyncReceived()函数,故HWC硬件产生的同步信号就可以到达SurfaceFlinger里面了。onVSyncReceived的实现如下:

void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
        .........
            needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
        .......
#endif
}

mPrimaryDispSync是一个DispSync对象,其初始化是在surfaceflinger::init()完成的。

回调的流程为DispSync.addResyncSample—–>DispSync.DispSyncThread.updateModel,如下所示:

bool DispSync::addResyncSample(nsecs_t timestamp) {
   .......
    updateModelLocked();
    .......
}
void DispSync::updateModelLocked() {
        .......
        mThread->updateModel(mPeriod, mPhase);

}

mThread指的是DispSyncThread线程,故上述调用的是DispSyncThread线程中的updateModel方法。

    void updateModel(nsecs_t period, nsecs_t phase) {
        .......
        mCond.signal();//唤醒被阻塞的DispSyncThread线程
    }

DispSyncThread线程在实时监测,一旦监测到退出信号就会退出阻塞

4.2 DispSyncThread至EventThread过程


    virtual bool threadLoop() {

        while (true) {
            .........
                    err = mCond.wait(mMutex);//线程阻塞等待           
            .........
            //从mEventListeners中收集所有满足时间条件的EventListener 详见第3.2.1节
                callbackInvocations = gatherCallbackInvocationsLocked(now);
             .........            
            fireCallbackInvocations(callbackInvocations);//详见第3.2.2节
             .........
    }

4.2.1 EventListener的初始化

在surfaceflinger::init中创建DispSyncSource对象,执行构造函数时会调用addEventListener进行初始化

class DispSyncSource : public VSyncSource, private DispSync::Callback {
public:
    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
        const char* label) :
            mValue(0),
            mTraceVsync(traceVsync),
            mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
            mVsyncEventLabel(String8::format("VSYNC-%s", label)),
            mDispSync(dispSync),
            mCallbackMutex(),
            mCallback(),
            mVsyncMutex(),
            mPhaseOffset(phaseOffset),
            mEnabled(false) {}


    virtual void setVSyncEnabled(bool enable) {
        Mutex::Autolock lock(mVsyncMutex);
        if (enable) {
            status_t err = mDispSync->addEventListener(mPhaseOffset,
                    static_cast<DispSync::Callback*>(this));//this指的是当前的surfaceflinger对象
        } else {
            status_t err = mDispSync->removeEventListener(
                    static_cast<DispSync::Callback*>(this));
        }
        mEnabled = enable;
    }
status_t DispSync::addEventListener(nsecs_t phase,
        const sp<Callback>& callback) {

    Mutex::Autolock lock(mMutex);
    return mThread->addEventListener(phase, callback);//callback即surfaceflinger对象
}
    status_t addEventListener(nsecs_t phase, const sp<DispSync::Callback>& callback) {
        .......
        listener.mCallback = callback;//callback即surfaceflinger对象

        mEventListeners.push(listener);

        mCond.signal();

        return NO_ERROR;
    }
    Vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) {
            ........
              if (t < now) {
                CallbackInvocation ci;
                ci.mCallback = mEventListeners[i].mCallback;//mCallback即surfaceflinger对象
                ci.mEventTime = t;
                callbackInvocations.push(ci);
                mEventListeners.editItemAt(i).mLastEventTime = t;
            }

        return callbackInvocations;
    }

4.2.2 回调至EventThread

    void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {
        for (size_t i = 0; i < callbacks.size(); i++) {
            callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);//回调至surfaceflinger对象的onDispSyncEvent方法
        }
    }
    virtual void onDispSyncEvent(nsecs_t when) {
        sp<VSyncSource::Callback> callback;
        {
            Mutex::Autolock lock(mCallbackMutex);
            callback = mCallback;//mCallback指的是EventThread对象

            if (mTraceVsync) {
                mValue = (mValue + 1) % 2;
                ATRACE_INT(mVsyncEventLabel.string(), mValue);
            }
        }

        if (callback != NULL) {
            callback->onVSyncEvent(when);//调用至EventThread
        }
    }
void EventThread::onVSyncEvent(nsecs_t timestamp) {
    .......
    mCondition.broadcast();//发广播释放线程阻塞
}

4.3 EventThread至jni

先看一下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);//消息继续上报
        ........
    }
    return true;
}
Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
        DisplayEventReceiver::Event* event)
{
    Mutex::Autolock _l(mLock);
    Vector< sp<EventThread::Connection> > signalConnections;

    do {
       .......
        mCondition.wait(mLock);//线程阻塞等待
        ......   

    } while (signalConnections.isEmpty());

    return signalConnections;
}

postEvent会调用DisplayEventReceiver::sendEvents()->BitTube::sendObjects();然后通过BitTube与jni进行通信,调用NativeDisplayEventReceiver::handleEvent()

int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) {
    .......

    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {//processPendingEvents获取信号
        ALOGV("receiver %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d",
                this, vsyncTimestamp, vsyncDisplayId, vsyncCount);
        mWaitingForVsync = false;
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);//信号分发
    }

    return 1; // keep the callback
}
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();

    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
    if (receiverObj.get()) {
        env->CallVoidMethod(receiverObj.get(),
                gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count);//回调Java层
        ALOGV("=zsx= receiver %p ~ Returned from vsync handler.", this);
    }

    mMessageQueue->raiseAndClearException(env, "dispatchVsync");
}

由上面分析可知,将回调至Choreographer.java中FrameDisplayEventReceiver类中的onVsync方法。

5、Java层

    public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
            .......
            mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
        }
  private final class FrameHandler extends Handler {

        public void handleMessage(Message msg) {//根据不同消息类型进行处理
            switch (msg.what) {
                case MSG_DO_FRAME:
                    doFrame(System.nanoTime(), 0);
                    break;
                case MSG_DO_SCHEDULE_VSYNC:
                    doScheduleVsync();
                    break;
                case MSG_DO_SCHEDULE_CALLBACK:
                    doScheduleCallback(msg.arg1);
                    break;
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/marshal_zsx/article/details/78346780
今日推荐