Choreographer原理

Posted by Gityuan on February 25, 2017
Choreographer.java
DisplayEventReceiver.java
frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
frameworks/native/libs/gui/DisplayEventReceiver.cpp

一. 概述

前面两篇文章介绍了SurfaceFlinger原理,讲述了SurfaceFlinger的启动过程,绘制过程,以及Vsync处理过程。 本文再介绍一下Choreographer的启动与Vsync处理过程。

二. Choreographer启动流程

在Activity启动过程,执行完onResume后,会调用Activity.makeVisible(),然后再调用到addView(), 层层调用会进入如下方法:

public ViewRootImpl(Context context, Display display) {
    ...
    //这里便出现获取Choreographer实例【见小节2.1】
    mChoreographer = Choreographer.getInstance();
    ...
}

2.1 getInstance

[-> Choreographer.java]

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); //【见小节2.2】
    }
};

当前所在线程为UI线程,也就是常说的主线程。

2.2 创建Choreographer

[-> Choreographer.java]

private Choreographer(Looper looper) {
    mLooper = looper;
    //创建Handler对象【见小节2.3】
    mHandler = new FrameHandler(looper);
    //创建用于接收VSync信号的对象【见小节2.4】
    mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;
    mLastFrameTimeNanos = Long.MIN_VALUE;
    mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
    //创建回调对象
    mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
    for (int i = 0; i <= CALLBACK_LAST; i++) {
        mCallbackQueues[i] = new CallbackQueue();
    }
}
  • mLastFrameTimeNanos:是指上一次帧绘制时间点;
  • mFrameIntervalNanos:帧间时长,一般等于16.7ms.

2.3 FrameHandler

[-> Choreographer.java ::FrameHandler]

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;
        }
    }
}

2.4 创建FrameDisplayEventReceiver

[-> Choreographer.java ::FrameDisplayEventReceiver]

private final class FrameDisplayEventReceiver extends DisplayEventReceiver
        implements Runnable {

    public FrameDisplayEventReceiver(Looper looper) {
        super(looper); //【见小节2.4.1】
    }
}

2.4.1 DisplayEventReceiver

[-> DisplayEventReceiver.java]

public DisplayEventReceiver(Looper looper) {
    mMessageQueue = looper.getQueue(); //获取主线程的消息队列
    //【见小节2.4.2】
    mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue);
}

经过JNI调用进入如下Native方法。

2.4.2 nativeInit

[-> android_view_DisplayEventReceiver.cpp]

static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
        jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    ...
    //【见小节2.4.3】
    sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
            receiverWeak, messageQueue);
    //【见小节2.4.4】
    status_t status = receiver->initialize();
    ...

    //获取DisplayEventReceiver对象的引用
    receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); 
    return reinterpret_cast<jlong>(receiver.get());
}

2.4.3 创建NativeDisplayEventReceiver

[-> android_view_DisplayEventReceiver.cpp]

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);
}

NativeDisplayEventReceiver继承于LooperCallback对象,此处mReceiverWeakGlobal记录的是Java层 DisplayEventReceiver对象的全局引用。

2.4.4 initialize

[-> android_view_DisplayEventReceiver.cpp]

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;
}

此处跟文章SurfaceFlinger原理(一)的【小节2.8】的监听原理一样。 监听mReceiver的所获取的文件句柄,一旦有数据到来,则回调this(此处NativeDisplayEventReceiver)中所复写LooperCallback对象的 handleEvent。

2.5 handleEvent

[-> android_view_DisplayEventReceiver.cpp]

int NativeDisplayEventReceiver::handleEvent(int receiveFd, int events, void* data) {
    ...
    nsecs_t vsyncTimestamp;
    int32_t vsyncDisplayId;
    uint32_t vsyncCount;
    //清除所有的pending事件,只保留最后一次vsync【见小节2.5.1】
    if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
        mWaitingForVsync = false;
        //分发Vsync【见小节2.5.2】
        dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
    }
    return 1;
}

2.5.1 processPendingEvents

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事件到来,则只关注最近一次的事件。

2.5.2 dispatchVsync

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()) {
        //【见小节2.6】
        env->CallVoidMethod(receiverObj.get(),
                gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count);
    }

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

此处调用到Java层的DisplayEventReceiver对象的dispatchVsync()方法,接下来进入Java层。

2.6 dispatchVsync

[-> DisplayEventReceiver.java]

private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
    //【见小节2.7】
    onVsync(timestampNanos, builtInDisplayId, frame);
}

再回到【小节2.2】,可知Choreographer对象实例化的过程,创建的对象是DisplayEventReceiver子类 FrameDisplayEventReceiver对象,接下来进入该对象。

2.7 onVsync

[-> Choreographer.java ::FrameDisplayEventReceiver]

private final class FrameDisplayEventReceiver extends DisplayEventReceiver
        implements Runnable {
    private boolean mHavePendingVsync;
    private long mTimestampNanos;
    private int mFrame;

    @Override
    public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
        //忽略来自第二显示屏的Vsync
        if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
            scheduleVsync();
            return;
        }
        ...
        
        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);
    }

    @Override
    public void run() {
        mHavePendingVsync = false;
        doFrame(mTimestampNanos, mFrame); //【见小节2.8】
    }
}

可见onVsync()过程是通过FrameHandler向主线程Looper发送了一个自带callback的消息 callback为FrameDisplayEventReceiver。 当主线程Looper执行到该消息时,则调用FrameDisplayEventReceiver.run()方法,紧接着便是调用doFrame,如下:

2.8 doFrame

[-> Choreographer.java]

void doFrame(long frameTimeNanos, int frame) {
    final long startNanos;
    synchronized (mLock) {
        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; //对齐帧的时间间隔
        }

        if (frameTimeNanos < mLastFrameTimeNanos) {
            scheduleVsyncLocked();
            return;
        }

        mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos);
        mFrameScheduled = false;
        mLastFrameTimeNanos = frameTimeNanos;
    }

    try {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#doFrame");

        mFrameInfo.markInputHandlingStart();
        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);
    }
}
  1. 每调用一次scheduleFrameLocked(),则mFrameScheduled为true,能执行一次 doFrame()操作。
  2. 最终有4个回调方法,依次为如下:
    • INPUT:输入事件
    • ANIMATION:动画
    • TRAVERSAL:窗口刷新
    • COMMIT

2.8.1 doCallbacks

[-> Choreographer.java]

void doCallbacks(int callbackType, long frameTimeNanos) {
    CallbackRecord callbacks;
    synchronized (mLock) {
        final long now = System.nanoTime();
        // 从队列查找相应类型的CallbackRecord对象【见小节2.8.2】
        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); //【见小节2.9】
        }
    } finally {
        ... //回收callbacks,加入mCallbackPool对象池
    }
}

2.8.2 extractDueCallbacksLocked

[-> Choreographer.java ::CallbackQueue]

private final class CallbackQueue {
    public CallbackRecord extractDueCallbacksLocked(long now) {
        CallbackRecord callbacks = mHead;
        //当队列头部的callbacks对象为空,或者执行时间还没到达,则直接返回
        if (callbacks == null || callbacks.dueTime > now) {
            return null; 
        }

        CallbackRecord last = callbacks;
        CallbackRecord next = last.next;
        while (next != null) {
            if (next.dueTime > now) {
                last.next = null;
                break;
            }
            last = next;
            next = next.next;
        }
        mHead = next;
        return callbacks;
    }
}

2.9 CallbackRecord.run

[-> Choreographer.java ::CallbackRecord]

private static final class CallbackRecord {
    public CallbackRecord next;
    public long dueTime;
    public Object action; // Runnable or FrameCallback
    public Object token;

    public void run(long frameTimeNanos) {
        if (token == FRAME_CALLBACK_TOKEN) {
            ((FrameCallback)action).doFrame(frameTimeNanos);
        } else {
            ((Runnable)action).run();
        }
    }
}

这里的回调方法run()有两种执行情况:

  • 当token的数据类型为FRAME_CALLBACK_TOKEN,则执行该对象的doFrame()方法;
  • 当token为其他类型,则执行该对象的run()方法。

在前面小节【2.8】doFrame()过程有一个判断变量mFrameScheduled,有两种执行情况:

  • 当该值为true则执行动画,执行完本次操作则再次设置该值为false;
  • 否则并不会执行动画。

对于底层Vsync信号每间隔16.7ms,上层都会接收到该信号。但对于系统会有需要,才会更新动画, 那么需要的场景便是由WMS调用scheduleAnimationLocked()方法来设置mFrameScheduled=true来触发动画, 接下来说说动画控制的过程

三. 动画显示过程

调用栈:

WMS.scheduleAnimationLocked
  postFrameCallback
    postFrameCallbackDelayed
      postCallbackDelayedInternal
        scheduleFrameLocked

3.1 WMS.scheduleAnimationLocked

[-> WindowManagerService.java]

void scheduleAnimationLocked() {
     if (!mAnimationScheduled) { 
         mAnimationScheduled = true;
         //【见小节3.2】
         mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback);
     }
 }

只有当mAnimationScheduled=false时,才会执行postFrameCallback(),其中参数为mAnimator对象的 成员变量mAnimationFrameCallback,该对象的初始化过程:

3.1.1 创建WMS

private WindowManagerService(
    ...
    mAnimator = new WindowAnimator(this); //【见小节3.1.2】
    ...
}

3.1.2 创建WindowAnimator

[-> WindowAnimator.java]

WindowAnimator(final WindowManagerService service) {
    mService = service;
    mContext = service.mContext;
    mPolicy = service.mPolicy;

    mAnimationFrameCallback = new Choreographer.FrameCallback() {
        public void doFrame(long frameTimeNs) {
            synchronized (mService.mWindowMap) {
                mService.mAnimationScheduled = false;
                animateLocked(frameTimeNs);
            }
        }
    };
}

mAnimationFrameCallback的数据类型为Choreographer.FrameCallback。

3.2 postFrameCallback

[-> Choreographer.java]

public void postFrameCallback(FrameCallback callback) {
    postFrameCallbackDelayed(callback, 0);
}

public void postFrameCallbackDelayed(FrameCallback callback, long delayMillis) {
    ...
    //【见小节3.3】
    postCallbackDelayedInternal(CALLBACK_ANIMATION,
            callback, FRAME_CALLBACK_TOKEN, delayMillis);
}

3.3 postCallbackDelayedInternal

[-> Choreographer.java]

// callbackType为动画,action为mAnimationFrameCallback
// token为FRAME_CALLBACK_TOKEN,delayMillis=0
private void postCallbackDelayedInternal(int callbackType,
    Object action, Object token, long delayMillis) {

    synchronized (mLock) {
        final long now = SystemClock.uptimeMillis();
        final long dueTime = now + delayMillis;
        //添加到mCallbackQueues队列
        mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);

        if (dueTime <= now) {
            scheduleFrameLocked(now);
        } else {
            //发送消息MSG_DO_SCHEDULE_CALLBACK
            Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_CALLBACK, action);
            msg.arg1 = callbackType;
            msg.setAsynchronous(true);
            mHandler.sendMessageAtTime(msg, dueTime);
        }
    }
}

发送MSG_DO_SCHEDULE_CALLBACK消息后,主线程接收后进入FrameHandler的handleMessage()操作,如下方法。

3.4 MSG_DO_SCHEDULE_CALLBACK

[-> Choreographer.java ::FrameHandler]

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); //【见小节3.5】
                break;
        }
    }
}

3.5 doScheduleCallback

[-> Choreographer.java]

void doScheduleCallback(int callbackType) {
    synchronized (mLock) {
        if (!mFrameScheduled) {
            final long now = SystemClock.uptimeMillis();
            if (mCallbackQueues[callbackType].hasDueCallbacksLocked(now)) {
                scheduleFrameLocked(now); //【见小节3.6】
            }
        }
    }
}

3.6 scheduleFrameLocked

[-> Choreographer.java]

private void scheduleFrameLocked(long now) {
    if (!mFrameScheduled) {
        mFrameScheduled = true;
        if (USE_VSYNC) {
            if (isRunningOnLooperThreadLocked()) {
                //当运行在Looper线程,则立刻调度vsync
                scheduleVsyncLocked(); 
            } else {
                //否则,发送消息到UI线程
                Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
                msg.setAsynchronous(true);
                mHandler.sendMessageAtFrontOfQueue(msg);
            }
        } else {
            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);
        }
    }
}

该方法的功能:

  1. 当运行在Looper线程,则立刻调度scheduleVsyncLocked();
  2. 当运行在其他线程,则通过发送一个消息到Looper线程,然后再执行scheduleVsyncLocked();

3.7 scheduleVsyncLocked

[-> Choreographer.java]

private void scheduleVsyncLocked() {
    mDisplayEventReceiver.scheduleVsync(); //【见小节3.8】
}

mDisplayEventReceiver对象是在【小节2.2】Choreographer的实例化过程所创建的。

3.8 scheduleVsync

[-> DisplayEventReceiver.java]

public void scheduleVsync() {
     if (mReceiverPtr == 0) {
        ...
     } else {
         nativeScheduleVsync(mReceiverPtr);
     }
}

3.9 nativeScheduleVsync

[-> android_view_DisplayEventReceiver.cpp]

static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
    sp<NativeDisplayEventReceiver> receiver =
            reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
    status_t status = receiver->scheduleVsync();
    ...
}

3.10 scheduleVsync

[-> android_view_DisplayEventReceiver.cpp]

status_t NativeDisplayEventReceiver::scheduleVsync() {
    if (!mWaitingForVsync) {
        nsecs_t vsyncTimestamp;
        int32_t vsyncDisplayId;
        uint32_t vsyncCount;
        processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount);
        //【见小节3.11】
        status_t status = mReceiver.requestNextVsync();
        ...

        mWaitingForVsync = true;
    }
    return OK;
}

3.11 requestNextVsync

[-> DisplayEventReceiver.cpp]

status_t DisplayEventReceiver::requestNextVsync() {
    if (mEventConnection != NULL) {
        mEventConnection->requestNextVsync();
        return NO_ERROR;
    }
    return NO_INIT;
}

这里就先不继续往下写了,该方法的作用请求下一次Vsync信息处理。 当Vsync信号到来,由于mFrameScheduled=true,则继续【小节2.9】CallbackRecord.run()方法。

四. 动画处理

根据[小节3.1.2]mAnimationFrameCallback.FrameCallback方法,进而调用animateLocked().

4.1 animateLocked

[-> WindowAnimator.java]

private void animateLocked(long frameTimeNs) {
    if (!mInitialized) {
        return;
    }

    mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
    mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
    boolean wasAnimating = mAnimating;
    mAnimating = false;
    mAppWindowAnimating = false;

    SurfaceControl.openTransaction(); //打开transacion
    SurfaceControl.setAnimationTransaction();
    try {
        final int numDisplays = mDisplayContentsAnimators.size();
        for (int i = 0; i < numDisplays; i++) {
            final int displayId = mDisplayContentsAnimators.keyAt(i);
            updateAppWindowsLocked(displayId);
            DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);

            final ScreenRotationAnimation screenRotationAnimation =
                    displayAnimator.mScreenRotationAnimation;
            if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
                if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
                    mAnimating = true;
                } else {
                    mBulkUpdateParams |= SET_UPDATE_ROTATION;
                    screenRotationAnimation.kill();
                    displayAnimator.mScreenRotationAnimation = null;

                    if (mService.mAccessibilityController != null
                            && displayId == Display.DEFAULT_DISPLAY) {
                        mService.mAccessibilityController.onRotationChangedLocked(
                                mService.getDefaultDisplayContentLocked(), mService.mRotation);
                    }
                }
            }

            //更新所有应用的动画,包括正在退出的应用
            updateWindowsLocked(displayId);
            updateWallpaperLocked(displayId);

            final WindowList windows = mService.getWindowListLocked(displayId);
            final int N = windows.size();
            for (int j = 0; j < N; j++) {
                //输出动画
                windows.get(j).mWinAnimator.prepareSurfaceLocked(true);
            }
        }

        for (int i = 0; i < numDisplays; i++) {
            final int displayId = mDisplayContentsAnimators.keyAt(i);

            testTokenMayBeDrawnLocked(displayId);

            final ScreenRotationAnimation screenRotationAnimation =
                    mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation;
            if (screenRotationAnimation != null) {
                screenRotationAnimation.updateSurfacesInTransaction();
            }

            mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers();

            if (mService.mAccessibilityController != null
                    && displayId == Display.DEFAULT_DISPLAY) {
                mService.mAccessibilityController.drawMagnifiedRegionBorderIfNeededLocked();
            }
        }

        if (mAnimating) {
            mService.scheduleAnimationLocked();
        }

        mService.setFocusedStackLayer();

        if (mService.mWatermark != null) {
            mService.mWatermark.drawIfNeeded();
        }
    } catch (RuntimeException e) {
        Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
    } finally {
        SurfaceControl.closeTransaction(); //关闭transacion
    }

    boolean hasPendingLayoutChanges = false;
    final int numDisplays = mService.mDisplayContents.size();
    for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
        final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
        final int pendingChanges = getPendingLayoutChanges(displayContent.getDisplayId());
        if ((pendingChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
            mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
        }
        if (pendingChanges != 0) {
            hasPendingLayoutChanges = true;
        }
    }

    boolean doRequest = false;
    if (mBulkUpdateParams != 0) {
        doRequest = mService.copyAnimToLayoutParamsLocked();
    }

    if (hasPendingLayoutChanges || doRequest) {
        mService.requestTraversalLocked();
    }

    if (!mAnimating && wasAnimating) {
        mService.requestTraversalLocked();
    }
}

未完待续。。。


欢迎关注我的微博: weibo.com/gityuan !请随意 ¥打赏支持 将激励创作更多技术干货!