显示框架之Choreographer

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
}

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

初始化DisplayEventDispatcher,添加mReceiveFd进行监控,为vsync事件到来做回调准备
初始化CallbacksQueues,里面存放5种类型的callback
初始化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

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

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 到来的时候统一处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值