他是控制应用进程绘制时机的,会在收到Vsync信号后调用应用进程的刷新
Choreographer创建,他是跟ViewRootImpl一起创建的(在ViewRootImpl的构造函数中)
public static Choreographer getInstance() {
return sThreadInstance.get();
}
他是通过ThreadLocal存储的也就是说一个线程只有一个Choreographer
DecorView在添加到ViewManager时会调用requestLayout
public void requestLayout() {
scheduleTraversals();
}
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
}
}
1、设置一个标记防止多次调用requestLayout
2、设置消息屏障(屏蔽普通消息,放行异步消息)
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);
}
}
}
}
如果当前线程是Choreographer工作线程,通过 scheduleVsyncLocked();向SurfaceFlinger发送Vsync请求(通过socketpair)requestNextVsync,在构造函数中通过parcel获取。BitTube,这个Socket是surfaceflinger创建后传递过来的。否则发送消息到工作线程中
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);
}
}
信号发送回来会在这里接收到
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;
//跳过帧数过多
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);
}
执行callback
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
performTraversals();
}
}
在接到Vsync信号后,执行doTraversal
1、撤销标记位
2、撤销消息屏障
3、执行performTraversals()
网友评论