Choreographer

他是控制應(yīng)用進程繪制時機的,會在收到Vsync信號后調(diào)用應(yīng)用進程的刷新

Choreographer創(chuàng)建,他是跟ViewRootImpl一起創(chuàng)建的(在ViewRootImpl的構(gòu)造函數(shù)中)

   public static Choreographer getInstance() {
        return sThreadInstance.get();
    }

他是通過ThreadLocal存儲的也就是說一個線程只有一個Choreographer

DecorView在添加到ViewManager時會調(diào)用requestLayout

public void requestLayout() {
   scheduleTraversals();
}
void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        }
    }

1、設(shè)置一個標(biāo)記防止多次調(diào)用requestLayout
2、設(shè)置消息屏障(屏蔽普通消息,放行異步消息)
3、向Choreographer添加消息

  private void postCallbackDelayedInternal(int callbackType,
            Object action, Object token, long delayMillis) {
           ····
            mCallbackQueues[callbackType].addCallbackLocked(dueTime, action, token);
           ····
            scheduleFrameLocked(now);
    }
private void scheduleFrameLocked(long now) {
        if (!mFrameScheduled) {
                // 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()) {
                    scheduleVsyncLocked();
                } else {
                    Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
                    msg.setAsynchronous(true);
                    mHandler.sendMessageAtFrontOfQueue(msg);
                }
            }
        }
    }

如果當(dāng)前線程是Choreographer工作線程,通過 scheduleVsyncLocked();向SurfaceFlinger發(fā)送Vsync請求(通過socketpair)requestNextVsync,在構(gòu)造函數(shù)中通過parcel獲取。BitTube,這個Socket是surfaceflinger創(chuàng)建后傳遞過來的。否則發(fā)送消息到工作線程中

private final class FrameDisplayEventReceiver extends DisplayEventReceiver
            implements Runnable {
    
        @Override
        public void onVsync(long timestampNanos, int builtInDisplayId, 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() {
            doFrame(mTimestampNanos, mFrame);
        }
    }

信號發(fā)送回來會在這里接收到

void doFrame(long frameTimeNanos, int frame) {
       
            long intendedFrameTimeNanos = frameTimeNanos;
            startNanos = System.nanoTime();
            final long jitterNanos = startNanos - frameTimeNanos;
            if (jitterNanos >= mFrameIntervalNanos) {
                final long skippedFrames = jitterNanos / mFrameIntervalNanos;
                //跳過幀數(shù)過多
                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;

            ····
            doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
            doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
            doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
            doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);

    }

執(zhí)行callback

  void doTraversal() {
        if (mTraversalScheduled) {
            mTraversalScheduled = false;
            mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
            performTraversals();
        }
    }

在接到Vsync信號后,執(zhí)行doTraversal
1、撤銷標(biāo)記位
2、撤銷消息屏障
3、執(zhí)行performTraversals()

請求重繪
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容