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)×tamp;    //调用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(            const_cast(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(this));//this指的是当前的surfaceflinger对象        } else {            status_t err = mDispSync->removeEventListener(                    static_cast(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 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& 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 > signalConnections;    signalConnections = waitForEvent(&event); //等待事件    // dispatch events to listeners...    const size_t count = signalConnections.size();    for (size_t i=0 ; iconst sp& 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 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;            }        }    }

更多相关文章

  1. Android内存管理哪些事
  2. 总结Android(安卓)Socket开发中可能遇到的问题
  3. Android(安卓)消息循环知识
  4. Android异步任务的处理方法
  5. API Guides——Toasts
  6. Android消息队列(二)--异步消息处理
  7. 文章标题:Android活动的生命周期
  8. 浅谈android的线程池
  9. Android内存小谈 - Birdmafly

随机推荐

  1. Android注入框架你应该知道的一切------
  2. Android中如何以编程方式(programmatical
  3. Android 接口回调机制详解
  4. android应用Theme(一)
  5. [置顶] Handler有何作用?如何使用?
  6. 中介者模式下的Android底部导航栏
  7. Android 的快速增长让一些开发人员担忧
  8. [置顶] Android(安卓)进程常驻(5)----开机
  9. Android根据内网外网连接情况配置服务器
  10. 【转】Android -- 探究Android的多分辨率