Android为了提供一个稳定的帧率输出机制,让软件层和硬件层可以以共同的频率一起工作,引入了 Vsync + TripleBuffer + 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 的工作逻辑。
文件: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 的初始化单独拿出来分析。
文件: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 方法
随着代码流程走到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,用一副图表示。
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信号后,就开始执行各种更新消息和回调,主要的处理逻辑在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 到来的时候统一处理。