美文网首页Android开发经验
显示框架之Choreographer

显示框架之Choreographer

作者: Android图形显示之路 | 来源:发表于2022-04-19 14:14 被阅读0次

    Android为了提供一个稳定的帧率输出机制,让软件层和硬件层可以以共同的频率一起工作,引入了 Vsync + TripleBuffer + Choreographer 的刷帧机制。

    引入Choreographer

    Choreographer 的引入,主要是配合 Vsync ,给上层 App 的渲染提供一个稳定的 Message 处理的时机,也就是 Vsync 到来的时候 ,会唤醒Choreographer 来做 App 的绘制操作。

    Choreographer作用

    Choreographer 扮演 Android 渲染链路中承上启下的角色。

    承上:负责接收和处理 App 的各种更新消息和回调,等到 Vsync 到来的时候统一处理。比如集中处理 Input(主要是 Input 事件的处理) 、Animation(动画相关)、Traversal(包括 measure、layout、draw 等操作) ,判断卡顿掉帧情况,记录 CallBack 耗时等

    启下:负责请求和接收 Vsync 信号,通过申请和接收vsync来驱动app刷新。

    简单理解,Choreographer + SurfaceFlinger + Vsync + TripleBuffer这一套从上到下的机制,保证了 Android App 可以以一个稳定的帧率运行,减少帧率波动带来的不适感。下面从源码一探究竟Choreographer 的工作逻辑。

    Choreographer初始化

    文件:frameworks/base/core/java/android/view/ViewRootImpl.java
    
    public ViewRootImpl(Context context, Display display, IWindowSession session,
                boolean useSfChoreographer) {
           ...
           // ViewRootImpl 初始化的时候创建Choreographer
            mChoreographer = useSfChoreographer
                    ? Choreographer.getSfInstance() : Choreographer.getInstance();
           ...
    
    }
    
    文件:frameworks/base/core/java/android/view/Choreographer.java
    
    // Thread local storage for the choreographer.
        private static final ThreadLocal<Choreographer> sThreadInstance =
                new ThreadLocal<Choreographer>() {
            @Override
            protected Choreographer initialValue() {
               // 获取当前线程的looper
                Looper looper = Looper.myLooper();
                if (looper == null) {
                    throw new IllegalStateException("The current thread must have a looper!");
                }
               // 创建Choreographer 对象,source类型为app
                Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
                if (looper == Looper.getMainLooper()) {
                    mMainInstance = choreographer;
                }
                return choreographer;
            }
        };
    
      private Choreographer(Looper looper, int vsyncSource) {
            mLooper = looper;
            // 初始化 FrameHandler
            mHandler = new FrameHandler(looper);
           // 初始化 DisplayEventReceiver
            mDisplayEventReceiver = USE_VSYNC
                    ? new FrameDisplayEventReceiver(looper, vsyncSource)
                    : null;
            mLastFrameTimeNanos = Long.MIN_VALUE;
    
            mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
            // 初始化 CallbacksQueues,存放5种类型的callback
            mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
            for (int i = 0; i <= CALLBACK_LAST; i++) {
                mCallbackQueues[i] = new CallbackQueue();
            }
            // b/68769804: For low FPS experiments.
            setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1));
        }
    
         // 实现handleMessage 方法
        private final class FrameHandler extends Handler {
            public FrameHandler(Looper looper) {
                super(looper);
            }
    
            @Override
            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;
                }
            }
        }
    

    我们把FrameDisplayEventReceiver 的初始化单独拿出来分析。

    FrameDisplayEventReceiver初始化

    文件:frameworks/base/core/java/android/view/Choreographer.java 
    
    private final class FrameDisplayEventReceiver extends DisplayEventReceiver
                implements Runnable {
            private boolean mHavePendingVsync;
            private long mTimestampNanos;
            private int mFrame;
    
            public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
               // 执行DisplayEventReceiver 的初始化
                super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS);
            }
    
    文件:frameworks/base/core/java/android/view/DisplayEventReceiver.java 
    
    public DisplayEventReceiver(Looper looper, int vsyncSource, int configChanged) {
            if (looper == null) {
                throw new IllegalArgumentException("looper must not be null");
            }
    
            mMessageQueue = looper.getQueue();
            // 通过jni调到native层
            mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
                    vsyncSource, configChanged);
    
            mCloseGuard.open("dispose");
        }
    
    文件:frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
    
    static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
            jobject messageQueueObj, jint vsyncSource, jint configChanged) {
        ...
         // NativeDisplayEventReceiver 继承 DisplayEventDispatcher, 执行DisplayEventDispatcher的初始化
        sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
                receiverWeak, messageQueue, vsyncSource, configChanged);
        // 执行DisplayEventDispatcher::initialize
        status_t status = receiver->initialize();
        ...
    }
    
    文件:frameworks/native/libs/gui/DisplayEventDispatcher.cpp
    
    DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
                                                   ISurfaceComposer::VsyncSource vsyncSource,
                                                   ISurfaceComposer::ConfigChanged configChanged)
          : mLooper(looper), mReceiver(vsyncSource, configChanged), mWaitingForVsync(false) {
        ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
    }
    
    status_t DisplayEventDispatcher::initialize() {
        status_t result = mReceiver.initCheck();
        if (result) {
            ALOGW("Failed to initialize display event receiver, status=%d", result);
            return result;
        }
    
        if (mLooper != nullptr) {
            // 添加mReceiveFd 监控,同Surfaceflinger的Message添加fd类似,区别是looper在不同的线程,回调的方法也不一样
            int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
            if (rc < 0) {
                return UNKNOWN_ERROR;
            }
        }
    
        return OK;
    }
    

    这里重要的方法是mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL), 添加mReceiveFd 监控。那什么时候唤醒底层的loop等待呢?就是执行EventThread:: dispatchEvent,会对mSendFd进行write操作,这里采用socket通信,当监听到mReceiveFd 有事件来时,进行唤醒,从而执行回调函数handleEvent。

    文件:system/core/libutils/Looper.cpp
    
    int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
    ...
       Request request;
       request.fd = fd;
       request.ident = ident;
       request.events = events;
       request.seq = mNextRequestSeq++;
       request.callback = callback;
       request.data = data;
    ...
       if (requestIndex < 0) {
                // 添加mReceiveFd 进行监控
                int epollResult = epoll_ctl(mEpollFd.get(), 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);
    
    ...
    }
    
    
    int Looper::pollInner(int timeoutMillis) {
    ...
    int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
    ...
    for (size_t i = 0; i < mResponses.size(); i++) {
          ...
                // 执行addFd 时加入的回调函数
                int callbackResult = response.request.callback->handleEvent(fd, events, data);
          ...
        return result;
    }
    
    文件:frameworks/native/libs/gui/DisplayEventDispatcher.cpp 
    
    int DisplayEventDispatcher::handleEvent(int, int events, void*) {
        if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
            ALOGE("Display event receiver pipe was closed or an error occurred.  "
                  "events=0x%x",
                  events);
            return 0; // remove the callback
        }
    
        if (!(events & Looper::EVENT_INPUT)) {
            ALOGW("Received spurious callback for unhandled poll event.  "
                  "events=0x%x",
                  events);
            return 1; // keep the callback
        }
    
        // Drain all pending events, keep the last vsync.
        nsecs_t vsyncTimestamp;
        PhysicalDisplayId vsyncDisplayId;
        uint32_t vsyncCount;
        if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
            ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64
                  ", displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d",
                  this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
            mWaitingForVsync = false;
            dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
        }
    
        return 1; // keep the callback
    }
    

    到这里初始化完成,总结下做了哪些事情:

    1. 初始化DisplayEventDispatcher,添加mReceiveFd进行监控,为vsync事件到来做回调准备
    2. 初始化CallbacksQueues,里面存放5种类型的callback
    3. 初始化FrameHandler,实现了handleMessage 方法

    APP请求Vsync

    随着代码流程走到requestLayout(addView->setView->requestLayout->schduleTraversals)表示app要请求vsync刷帧,具体看下请求经过

    文件:frameworks/base/core/java/android/view/ViewRootImpl.java 
    
    void scheduleTraversals() {
            if (!mTraversalScheduled) {
                mTraversalScheduled = true;
                mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
                // 添加CALLBACK_TRAVERSAL 类型的回调
                mChoreographer.postCallback(
                        Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
                notifyRendererOfFramePending();
                pokeDrawLockIfNeeded();
            }
        }
    
    文件: frameworks/base/core/java/android/view/Choreographer.java 
    
    private void postCallbackDelayedInternal(int callbackType,
                Object action, Object token, long delayMillis) {
            if (DEBUG_FRAMES) {
                Log.d(TAG, "PostCallback: type=" + callbackType
                        + ", action=" + action + ", token=" + token
                        + ", delayMillis=" + delayMillis);
            }
    
            synchronized (mLock) {
                final long now = SystemClock.uptimeMillis();
                final long dueTime = now + delayMillis;
                // mCallbackQueues[CALLBACK_TRAVERSAL] 队列添加一个回调
                mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
    
                if (dueTime <= now) {
                    // dueTime == now ,从这里进来
                    scheduleFrameLocked(now);
                } else {
                    Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
                    msg.arg1 = callbackType;
                    msg.setAsynchronous(true);
                    mHandler.sendMessageAtTime(msg, dueTime);
                }
            }
        }
    
    // CallbackRecord 是个单链表,有3个成员,dueTime,action,token和1个next指针
    // 将回调加入到当前的链表中
    public void addCallbackLocked(long dueTime, Object action, Object token) {
                CallbackRecord callback = obtainCallbackLocked(dueTime, action, token);
                CallbackRecord entry = mHead;
                if (entry == null) {
                    mHead = callback;
                    return;
                }
                if (dueTime < entry.dueTime) {
                    callback.next = entry;
                    mHead = callback;
                    return;
                }
                while (entry.next != null) {
                    if (dueTime < entry.next.dueTime) {
                        callback.next = entry.next;
                        break;
                    }
                    entry = entry.next;
                }
                entry.next = callback;
            }
    
    // obtainCallbackLocked 的作用是如果当前pool里面没有回调,则新创建一个,如果有,则返回当前的回调并将mCallbackPool 指向下一个回调
    private CallbackRecord obtainCallbackLocked(long dueTime, Object action, Object token) {
            CallbackRecord callback = mCallbackPool;
            if (callback == null) {
                callback = new CallbackRecord();
            } else {
                mCallbackPool = callback.next;
                callback.next = null;
            }
            callback.dueTime = dueTime;
            callback.action = action;
            callback.token = token;
            return callback;
        }
    
     private void scheduleFrameLocked(long now) {
            if (!mFrameScheduled) {
                mFrameScheduled = true;
                if (USE_VSYNC) {
                    if (DEBUG_FRAMES) {
                        Log.d(TAG, "Scheduling next frame on vsync.");
                    }
    
                   // 判断looper是不是在主线程,这两个方法殊途同归,都会执行scheduleVsyncLocked
                    if (isRunningOnLooperThreadLocked()) {
                        scheduleVsyncLocked();
                    } else {
                        Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageAtFrontOfQueue(msg);
                    }
              ...
            }
        }
    
    private void scheduleVsyncLocked() {
            mDisplayEventReceiver.scheduleVsync();
        }
    
    文件:frameworks/native/libs/gui/DisplayEventDispatcher.cpp
    
    status_t DisplayEventDispatcher::scheduleVsync() {
        if (!mWaitingForVsync) {
            ...
            status_t status = mReceiver.requestNextVsync();
            if (status) {
                ALOGW("Failed to request next vsync, status=%d", status);
                return status;
            }
    
            mWaitingForVsync = true;
        }
        return OK;
    }
    
    文件:frameworks/native/libs/gui/DisplayEventReceiver.cpp 
    
    status_t DisplayEventReceiver::requestNextVsync() {
        if (mEventConnection != nullptr) {
            mEventConnection->requestNextVsync();
            return NO_ERROR;
        }
        return NO_INIT;
    }
    
    文件:frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp 
    
    void EventThreadConnection::requestNextVsync() {
        ATRACE_NAME("requestNextVsync");
        mEventThread->requestNextVsync(this);
    }
    
    void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
        if (connection->resyncCallback) {
            connection->resyncCallback();
        }
    
        std::lock_guard<std::mutex> lock(mMutex);
    
        if (connection->vsyncRequest == VSyncRequest::None) {
            connection->vsyncRequest = VSyncRequest::Single;
            mCondition.notify_all();
        }
    }
    

    跟着代码流程可以看到,最终调到app EventThread的requestNextVsync,将connection->vsyncRequest更新为Single,并唤醒mCondition的wait,用一副图表示。


    app请求vsync流程.png

    APP接收Vsync

    sw-vsync分发需要具备两个条件:1. 有请求vsync的动作 2. TimerDispatch线程定时时间到,会make一个vsync event。在当前帧请求vsync,在下一帧创造vsync event后就会回调给app。

    文件:frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
    
    void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
    DisplayEventConsumers consumers;
    
        while (mState != State::Quit) {
            std::optional<DisplayEventReceiver::Event> event;
    
            // Determine next event to dispatch.
            if (!mPendingEvents.empty()) {
                event = mPendingEvents.front();
                mPendingEvents.pop_front();
          ...
    
           if (!consumers.empty()) {
                 // 开始分发vsync event,如果是app eventthread就分发给app
                dispatchEvent(*event, consumers);
                consumers.clear();
            }
    ...
    }
    
    tatus_t EventThreadConnection::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);
    }
    
    ssize_t BitTube::write(void const* vaddr, size_t size) {
        ssize_t err, len;
        do {
            // 对端mReceiveFd,会唤醒epoll_wait
            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;
    }
    

    对端mReceiveFd 被添加到epllo fd进行监听,当事件来临时就会执行回调函数handleEvent

    文件:frameworks/native/libs/gui/DisplayEventDispatcher.cpp
    int DisplayEventDispatcher::handleEvent(int, int events, void*) {
        ...
        nsecs_t vsyncTimestamp;
        PhysicalDisplayId vsyncDisplayId;
        uint32_t vsyncCount;
        // 得到发送过来的vsync event
        if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
            ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64
                  ", displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d",
                  this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
            mWaitingForVsync = false;
            // 处理vsync event
            dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
        }
    
        return 1; // keep the callback
    }
    
    bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
                                                      PhysicalDisplayId* outDisplayId,
                                                      uint32_t* outCount) {
        bool gotVsync = false;
        DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
        ssize_t n;
        // 获取发送过来的vsync event
        while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
            ALOGV("dispatcher %p ~ Read %d events.", this, int(n));
            for (ssize_t i = 0; i < n; i++) {
                const DisplayEventReceiver::Event& ev = buf[i];
                switch (ev.header.type) {
                    case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                        // Later vsync events will just overwrite the info from earlier
                        // ones. That's fine, we only care about the most recent.
                        gotVsync = true;
                        *outTimestamp = ev.header.timestamp;
                        *outDisplayId = ev.header.displayId;
                        *outCount = ev.vsync.count;
                        break;
                   ...
        return gotVsync;
    }
    
    文件:frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
    
    void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
                                                   uint32_t count) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
    
        ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
        if (receiverObj.get()) {
            ALOGV("receiver %p ~ Invoking vsync handler.", this);
            // 从jni调到java方法
            env->CallVoidMethod(receiverObj.get(),
                    gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId, count);
            ALOGV("receiver %p ~ Returned from vsync handler.", this);
        }
    
        mMessageQueue->raiseAndClearException(env, "dispatchVsync");
    }
    
    文件:frameworks/base/core/java/android/view/DisplayEventReceiver.java
     private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
            onVsync(timestampNanos, physicalDisplayId, frame);
        }
    
    文件:frameworks/base/core/java/android/view/Choreographer.java
    public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
                ...
                mTimestampNanos = timestampNanos;
                mFrame = frame;
                // obtain 会new message,callback为FrameDisplayEventReceiver对象,实现了Runnable的方法
                Message msg = Message.obtain(mHandler, this);
                msg.setAsynchronous(true);
                // 发送message,唤醒loop wait
                mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
            }
    
    文件:frameworks/base/core/java/android/os/Message.java 
    public static Message obtain(Handler h, Runnable callback) {
            Message m = obtain();
            m.target = h;
            m.callback = callback;
    
            return m;
        }
    
    文件:frameworks/base/core/java/android/os/Handler.java
      public void dispatchMessage(@NonNull Message msg) {
            if (msg.callback != null) {
                // callback 不为空,走handleCallback
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }
    
     private static void handleCallback(Message message) {
            // 执行FrameDisplayEventReceiver的run方法
            message.callback.run();
        }
    
    文件:frameworks/base/core/java/android/view/Choreographer.java 
     public void run() {
                mHavePendingVsync = false;
                 // 处理 App 的各种更新消息和回调
                doFrame(mTimestampNanos, mFrame);
            }
        }
    

    从链路来看,最后会调到doFrame来处理 App 的各种更新消息和回调,用个图总结下。


    APP接收Vsync流程.png

    APP处理Vsync

    app接收到vsync信号后,就开始执行各种更新消息和回调,主要的处理逻辑在doFrame函数。

    文件:frameworks/base/core/java/android/view/Choreographer.java
    void doFrame(long frameTimeNanos, int frame) {
            // 处理掉帧逻辑,暂且不看
            ...
            try {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame");
                AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
                // 记录input开始时间
                mFrameInfo.markInputHandlingStart();
                // 回调input方法
                doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
                //记录动画开始时间
                mFrameInfo.markAnimationsStart();
                 //回调动画方法   
                doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
                doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameTimeNanos);
                 // 记录Traversal开始时间
                mFrameInfo.markPerformTraversalsStart();
                  // 回调Traversal 方法,重点看下
                doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
    
                doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
            } finally {
                AnimationUtils.unlockAnimationClock();
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
    
            if (DEBUG_FRAMES) {
                final long endNanos = System.nanoTime();
                Log.d(TAG, "Frame " + frame + ": Finished, took "
                        + (endNanos - startNanos) * 0.000001f + " ms, latency "
                        + (startNanos - frameTimeNanos) * 0.000001f + " ms.");
            }
        }
    
     void doCallbacks(int callbackType, long frameTimeNanos) {
                ...
                //取出对应的callback,还记得前面是通过addCallbackLocked将callback加入到链表里面,现将对应的callback取出
                callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked(
                        now / TimeUtils.NANOS_PER_MS);
                if (callbacks == null) {
                    return;
                }
                mCallbacksRunning = true;
    
                ...
    
            try {
                Trace.traceBegin(Trace.TRACE_TAG_VIEW, CALLBACK_TRACE_TITLES[callbackType]);
                for (CallbackRecord c = callbacks; c != null; c = c.next) {
                    if (DEBUG_FRAMES) {
                        Log.d(TAG, "RunCallback: type=" + callbackType
                                + ", action=" + c.action + ", token=" + c.token
                                + ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime));
                    }
                    // 执行CallbackRecord的run方法
                    c.run(frameTimeNanos);
                }
            ...
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
        }
    
     private static final class CallbackRecord {
            public CallbackRecord next;
            public long dueTime;
            public Object action; // Runnable or FrameCallback
            public Object token;
    
            @UnsupportedAppUsage
            public void run(long frameTimeNanos) {
                if (token == FRAME_CALLBACK_TOKEN) {
                    ((FrameCallback)action).doFrame(frameTimeNanos);
                } else {
                    // 执行mTraversalRunnable的run方法,在scheduleTraversals里面通过postCallback加入callback链表
                    ((Runnable)action).run();
                }
            }
        }
    
    文件:frameworks/base/core/java/android/view/ViewRootImpl.java 
    final class TraversalRunnable implements Runnable {
            @Override
            public void run() {
                //最后回调到这个方法,处理measure、layout、draw 
                doTraversal();
            }
        }
    
     private void performTraversals() {
    ...
     performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    ...
     performLayout(lp, mWidth, mHeight);
    ...
     performDraw();
    ...
    }
    

    可以看到当app接收到vsync信号后就开始处理各种回调的方法,由于有些内容并不是很熟悉,也就没能继续分析下去,文章只是分析了大致的流程,具体的细节遇到问题再分析。
    文章从app请求vsync,eventThread分发vsync,再到app处理vsync,分析了大致的流程,也印证了文章开始说的Choreographer作用: 1. 负责请求和接收 Vsync 信号 2. 负责接收和处理 App 的各种更新消息和回调,等到 Vsync 到来的时候统一处理。

    相关文章

      网友评论

        本文标题:显示框架之Choreographer

        本文链接:https://www.haomeiwen.com/subject/ezpsertx.html