基于API 23w
图文概述 Choreographer 编舞者。统一动画、输入和绘制时机 Choreographer 的作用,主要是配合 Vsync ,给上层 App 的渲染提供一个稳定的 Message 处理的时机,即 Vsync 到来的时候 ,系统通过对 Vsync 信号周期的调整,来控制每一帧绘制操作的时机
Choreographer启动流程 Window添加流程中,当Activity启动执行onResume后,会执行到创建ViewRootImpt Android系统_Window的创建和添加流程分析
1 2 3 4 5 6 public ViewRootImpl(Context context, Display display) { ... // VoewRootImpl 构造方法 会获取Choreographer实例 mChoreographer = Choreographer.getInstance(); ... }
Choreographer构造 通过单例模式构建,这里是每一个线程有一个Choreographer对象,而这里的线程为应用进程的主线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static Choreographer getInstance() { return sThreadInstance.get(); //单例模式 } private static final ThreadLocal<Choreographer> sThreadInstance = new ThreadLocal<Choreographer>() { protected Choreographer initialValue() { Looper looper = Looper.myLooper(); //获取当前线程的Looper if (looper == null) { throw new IllegalStateException("The current thread must have a looper!"); } return new Choreographer(looper); 创建 } };
Choreographer构造方法 初始化一个Looper和一个FrameHandler变量用来处理消息,另外创建了一个 FrameDisplayEventReceiver用来请求和接受Vysnc事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private Choreographer(Looper looper) { mLooper = looper; //创建Handler对象 mHandler = new FrameHandler(looper); //创建用于接收VSync信号的对象 (使用Vsync同步机制情况下创建) mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null; //是指上一次帧绘制时间点 mLastFrameTimeNanos = Long.MIN_VALUE; //帧间时长,默认16.7ms. mFrameIntervalNanos = (long)(1000000000 / getRefreshRate()); //创建回调对象 mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1]; for (int i = 0; i <= CALLBACK_LAST; i++) { mCallbackQueues[i] = new CallbackQueue(); } }
创建FrameHandler Choreographer 处理绘制的逻辑核心在 Choreographer.doFrame 函数中,doFrame 函数主要做三件事情,计算掉帧逻辑、记录帧绘制信息、 执行 CALLBACK_INPUT、CALLBACK_ANIMATION、CALLBACK_INSETS_ANIMATION、CALLBACK_TRAVERSAL、CALLBACK_COMMIT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 它继承DisPlayEvetReceiver,调用父类构造方法 另外FrameDisplayEventReceiver中三个比较重要的方法
onVsync – Vsync 信号回调
run – 执行 doFrame
scheduleVsync – 请求 Vsync 信号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private final class FrameDisplayEventReceiver extends DisplayEventReceiver implements Runnable { public FrameDisplayEventReceiver(Looper looper, int vsyncSource) { super(looper, vsyncSource); } @Override public void onVsync(long timestampNanos, long physicalDisplayId, int frame) { ...... mTimestampNanos = timestampNanos; mFrame = frame; Message msg = Message.obtain(mHandler, this); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); } @Override public void run() { mHavePendingVsync = false; doFrame(mTimestampNanos, mFrame); } public void scheduleVsync() { ...... nativeScheduleVsync(mReceiverPtr); } }
DisplayEventReceiver构造 1 2 3 4 5 public DisplayEventReceiver(Looper looper) { mMessageQueue = looper.getQueue(); //获取主线程的消息队列 // 通过JNI执行native层初始化 mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue); }
android_view_DisplayEventReceiver.cpp 初始化 创建NativeDisplayEventReceiver, 监听mReceiver的所获取的文件句柄,一旦有数据到来,则回调this(此处NativeDisplayEventReceiver)中所复写LooperCallback对象的 handleEvent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); ... //创建NativeDisplayEventReceiver sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue); //初始化 status_t status = receiver->initialize(); ... //获取DisplayEventReceiver对象的引用 receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); return reinterpret_cast<jlong>(receiver.get()); } // NativeDisplayEventReceiver继承于LooperCallback对象,此处mReceiverWeakGlobal记录的是Java层 DisplayEventReceiver对象的全局引用 NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp<MessageQueue>& messageQueue) : mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mMessageQueue(messageQueue), mWaitingForVsync(false) { ALOGV("receiver %p ~ Initializing display event receiver.", this); } status_t NativeDisplayEventReceiver::initialize() { //mReceiver为DisplayEventReceiver类型 status_t result = mReceiver.initCheck(); ... //监听mReceiver的所获取的文件句柄。 int rc = mMessageQueue->getLooper()->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL); ... return OK; }
Callback添加流程 Choreographer提供postCallback和postFrameCallback两种回调方式及对应的delay两种,其最终执行的内部postCallbackDelayedInternal方法
Choreographer.postCallbackDelayedInternal 创建Callback,然后添加到mCallbackQueues队列上, 然后根据是否立即执行,决定是发消息还是直接调用 最终执行scheduleFrameLocked方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 private void postCallbackDelayedInternal(int callbackType, Object action, Object token, long delayMillis) { synchronized (mLock) { //当前时间 final long now = SystemClock.uptimeMillis(); //回调执行时间,=当前时间+delay时间 final long dueTime = now + delayMillis; //添加到callback队列 mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token); if (dueTime <= now) { scheduleFrameLocked(now); // 立即执行 } else { // 发送消息执行 Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action); msg.arg1 = callbackType; msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, dueTime); } } }
Choreographer.scheduleFrameLocked 使用Vsync,按时间执行到scheduleVsyncLocked方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private void scheduleFrameLocked(long now) { if (!mFrameScheduled) { mFrameScheduled = true; if (USE_VSYNC) { // If running on the Looper thread, then schedule the vsync immediately, // otherwise post a message to schedule the vsync from the UI thread // as soon as possible. if (isRunningOnLooperThreadLocked()) { // 请求Vsync信号,最终会调用到native层,natie层处理完成后出发onVsync信号接收回调流程 scheduleVsyncLocked(); } else { // 发送消息,delay后执行此方法 Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC); msg.setAsynchronous(true); mHandler.sendMessageAtFrontOfQueue(msg); } } else { // 没有使用Vsync 则直接发送msg,然后调用doFrame final long nextFrameTime = Math.max( mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now); Message msg = mHandler.obtainMessage(MSG_DO_FRAME); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, nextFrameTime); } } }
Choreographer.scheduleVsyncLocked 执行FrameDisplayEventReceiver.scheduleVsync di层向SurfaceFlinger服务注册,即下一次Vsync事件会调用DisplayEventReceiver的disptachVsync方法
1 2 3 4 5 6 7 8 private void scheduleVsyncLocked() { mDisplayEventReceiver.scheduleVsync(); } public void scheduleVsync() { nativeScheduleVsync(mReceiverPtr); }
Vsync回调流程 当vysnc信号由底层HWC触发后会执行android_view_DisplayEventReceiver的handleEvent方法。 JNI层接受HWC的Vysnc信号,过滤处理,分发到Java层DisplayEventReceiver
android_view_DisplayEventReceiver.handleEvent 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) { ... nsecs_t vsyncTimestamp; int32_t vsyncDisplayId; uint32_t vsyncCount; //清除所有的pending事件,只保留最后一次vsync if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { mWaitingForVsync = false; //分发Vsync dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount); } return 1; } // 遍历所有的事件,当有多个VSync事件到来,则只关注最近一次的事件 bool NativeDisplayEventReceiver::processPendingEvents( nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) { bool gotVsync = false; DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; ssize_t n; while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { for (ssize_t i = 0; i < n; i++) { const DisplayEventReceiver::Event& ev = buf[i]; switch (ev.header.type) { case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: gotVsync = true; //获取VSync信号 *outTimestamp = ev.header.timestamp; *outId = ev.header.id; *outCount = ev.vsync.count; break; case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected); break; default: break; } } } return gotVsync; } // 分发Vsync ,DisplayEventReceiver进行接受 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()) { // 此处调用到Java层的DisplayEventReceiver对象的dispatchVsync()方法,执行进入Java层 env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count); } mMessageQueue->raiseAndClearException(env, "dispatchVsync"); }
FrameDisplayEventReceiver.onVsync Java层接受Vsync事件,通过Handler通信机制发送消息,后续执行到它自身的run方法,然后执行doFrame操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 private final class FrameDisplayEventReceiver extends DisplayEventReceiver implements Runnable { private boolean mHavePendingVsync; private long mTimestampNanos; private int mFrame; @Override public void run() { mHavePendingVsync = false; doFrame(mTimestampNanos, mFrame); } @Override public void onVsync(long timestampNanos, int builtInDisplayId, int frame) { ... mTimestampNanos = timestampNanos; mFrame = frame; //该消息的callback为当前对象FrameDisplayEventReceiver Message msg = Message.obtain(mHandler, this); msg.setAsynchronous(true); //此处mHandler为FrameHandler mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); } ... }
Choreographer.doFrame
先判断Vsync信号间隔时间和刷新时间是否符合
顺序执行4种时间对应的CallbackQueue队列中注册的回调函数
CALLBACK_INPUT : 处理输入事件处理有关
CALLBACK_ANIMATION : 处理 Animation 的处理有关
CALLBACK_INSETS_ANIMATION : 处理 Insets Animation 的相关回调
CALLBACK_TRAVERSAL : 处理和 UI 等控件绘制有关
CALLBACK_COMMIT : 处理 Commit 相关回调
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 void doFrame(long frameTimeNanos, int frame) { final long startNanos; synchronized (mLock) { // 每调用一次scheduleFrameLocked(),则mFrameScheduled=true,能执行一次doFrame()操作,执行完doFrame()并设置mFrameScheduled=false; if (!mFrameScheduled) { return; // mFrameScheduled=false,则直接返回。 } //原本计划的绘帧时间点 long intendedFrameTimeNanos = frameTimeNanos; //起始时间 startNanos = System.nanoTime(); //计算消息发送与函数调用开始之间所花费的时间 final long jitterNanos = startNanos - frameTimeNanos; //如果线程处理该消息的时间超过了屏幕刷新周期 if (jitterNanos >= mFrameIntervalNanos) { // 计算函数调用期间所错过的帧数 final long skippedFrames = jitterNanos / mFrameIntervalNanos; //当掉帧个数超过30,则输出相应log if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) { Log.i(TAG, "Skipped " + skippedFrames + " frames! " + "The application may be doing too much work on its main thread."); } final long lastFrameOffset = jitterNanos % mFrameIntervalNanos; //对齐帧的时间间隔 frameTimeNanos = startNanos - lastFrameOffset; } //此处frameTimeNanos是底层VSYNC信号到达的时间戳,如果frameTimeNanos小于一个屏幕刷新周期,则重新请求VSync信号 if (frameTimeNanos < mLastFrameTimeNanos) { scheduleVsyncLocked(); return; } mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos); mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; } try { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame"); mFrameInfo.markInputHandlingStart(); //执行4种事件对应的回调方法 doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos); //标记动画开始时间 mFrameInfo.markAnimationsStart(); doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos); mFrameInfo.markPerformTraversalsStart(); doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } }
Choreographer.doCallbacks
从队列头mHead查找CallbackRecord对象,当队列头部的callbacks对象为空或者执行时间还没到达,则直接返回;
开始执行相应回调的run()方法;
回收callbacks,加入对象池mCallbackPool,就是说callback一旦执行完成,则会被回收。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 void doCallbacks(int callbackType, long frameTimeNanos) { CallbackRecord callbacks; synchronized (mLock) { final long now = System.nanoTime(); // 从队列查找相应类型的CallbackRecord对象 callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked( now / TimeUtils.NANOS_PER_MS); if (callbacks == null) { return; //当队列为空,则直接返回 } mCallbacksRunning = true; if (callbackType == Choreographer.CALLBACK_COMMIT) { final long jitterNanos = now - frameTimeNanos; //当commit类型回调执行的时间点超过2帧,则更新mLastFrameTimeNanos。 if (jitterNanos >= 2 * mFrameIntervalNanos) { final long lastFrameOffset = jitterNanos % mFrameIntervalNanos + mFrameIntervalNanos; frameTimeNanos = now - lastFrameOffset; mLastFrameTimeNanos = frameTimeNanos; } } } try { for (CallbackRecord c = callbacks; c != null; c = c.next) { c.run(frameTimeNanos); } } finally { synchronized (mLock) { mCallbacksRunning = false; //回收callbacks,加入对象池mCallbackPool do { final CallbackRecord next = callbacks.next; recycleCallbackLocked(callbacks); callbacks = next; } while (callbacks != null); } Trace.traceEnd(Trace.TRACE_TAG_VIEW); } }
CallbackRecord.run
当token的数据类型为FRAME_CALLBACK_TOKEN,则执行该对象的doFrame()方法;
当token为其他类型,则执行该对象的run()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private static final class CallbackRecord { public CallbackRecord next; public long dueTime; public Object action; // Runnable或者 FrameCallback public Object token; public void run(long frameTimeNanos) { if (token == FRAME_CALLBACK_TOKEN) { ((FrameCallback)action).doFrame(frameTimeNanos); } else { ((Runnable)action).run(); } } }
Choreographer.CALLBACK_TRAVERSAL 这里主要分析Traversal类型,即View的绘制流程
ViewRootImpl.scheduleTraversals , 添加callback
回调 TraversalRunnable.run 方法
开始View的绘制流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; //为了提高优先级,先 postSyncBarrier mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); } } final class TraversalRunnable implements Runnable { @Override public void run() { // 真正开始执行 measure、layout、draw doTraversal(); } } void doTraversal() { if (mTraversalScheduled) { mTraversalScheduled = false; // 这里把 SyncBarrier remove mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier); // 真正开始 performTraversals(); } } private void performTraversals() { // measure 操作 if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight() || contentInsetsChanged || updatedConfiguration) { performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); } // layout 操作 if (didLayout) { performLayout(lp, mWidth, mHeight); } // draw 操作 if (!cancelDraw && !newSurface) { performDraw(); } }
推荐阅读:图形系统总结 参考Android 基于 Choreographer 的渲染机制详解 Choreographer原理 源码分析