android 12 中的VSYNC的请求

1、App端Vsync信号的请求流程:

ViewRootImpl 复制代码
public void requestLayout() {
    if (!mHandlingLayoutInLayoutRequest) {
        ...
        scheduleTraversals();
    }
}

void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        ...
        //mChoreographer = Choreographer
        mChoreographer.postCallback(
                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        ...
        ;
    }
}

Choreographer请求Vsync

Choreographer 复制代码
private void scheduleVsyncLocked() {
    try {
        ...
        //mDisplayEventReceiver = FrameDisplayEventReceiver
        mDisplayEventReceiver.scheduleVsync();
    } finally {
        ...
    }
}

java层的DisplayEventReceiver

DisplayEventReceiver 复制代码
public void scheduleVsync() {
    //mReceiverPtr是native对象的地址
    if (mReceiverPtr == 0) {
        ...
    } else {
        nativeScheduleVsync(mReceiverPtr);
    }
}

调用android_view_DisplayEventReceiver.nativeScheduleVsync

android_view_DisplayEventReceiver 复制代码
//frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
209      sp<NativeDisplayEventReceiver> receiver =
210              reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
211      status_t status = receiver->scheduleVsync();
212      if (status) {
213          String8 message;
214          message.appendFormat("Failed to schedule next vertical sync pulse.  status=%d", status);
215          jniThrowRuntimeException(env, message.string());
216      }
217  }

调用DisplayEventDispatcher.scheduleVsync

DisplayEventDispatcher 复制代码
//frameworks/native/libs/gui/DisplayEventDispatcher.cpp
 status_t DisplayEventDispatcher::scheduleVsync() {
      if (!mWaitingForVsync) {
          ALOGV("dispatcher %p ~ Scheduling vsync.", this);
  
          // Drain all pending events.
          nsecs_t vsyncTimestamp;
          PhysicalDisplayId vsyncDisplayId;
          uint32_t vsyncCount;
          VsyncEventData vsyncEventData;
          if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncEventData)) {
              ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", this,
                    ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
          }
  
          //mReceiver = DisplayEventReceiver
          status_t status = mReceiver.requestNextVsync();
          if (status) {
              ALOGW("Failed to request next vsync, status=%d", status);
              return status;
          }
  
          mWaitingForVsync = true;
      }
      return OK;
  }

调用DisplayEventReceiver.requestNextVsync

scss 复制代码
//frameworks/native/libs/gui/DisplayEventReceiver.cpp
status_t DisplayEventReceiver::requestNextVsync() {
       if (mEventConnection != nullptr) {
           //mEventConnection是在构造函数中初始化的
           //sp<IDisplayEventConnection> mEventConnection;
           mEventConnection->requestNextVsync();
           return NO_ERROR;
       }
       return NO_INIT;
   }


//DisplayEventReceiver构造函数创建mEventConnection
 DisplayEventReceiver::DisplayEventReceiver(
           ISurfaceComposer::VsyncSource vsyncSource,
           ISurfaceComposer::EventRegistrationFlags eventRegistration) {
       sp<ISurfaceComposer> sf(ComposerService::getComposerService());
       if (sf != nullptr) {
           mEventConnection = sf->createDisplayEventConnection(vsyncSource, eventRegistration);
           if (mEventConnection != nullptr) {
               mDataChannel = std::make_unique<gui::BitTube>();
               mEventConnection->stealReceiveChannel(mDataChannel.get());
           }
       }
   }

在SurfaceFlinger中创建连接

yaml 复制代码
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
1685          ISurfaceComposer::VsyncSource vsyncSource,
1686          ISurfaceComposer::EventRegistrationFlags eventRegistration) {
1687      const auto& handle =
1688              vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
1689  
1690      return mScheduler->createDisplayEventConnection(handle, eventRegistration);
1691  }

调用Scheduler的createDisplayEventConnection

arduino 复制代码
//frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
297          ConnectionHandle handle, ISurfaceComposer::EventRegistrationFlags eventRegistration) {
298      std::lock_guard<std::mutex> lock(mConnectionsLock);
299      RETURN_IF_INVALID_HANDLE(handle, nullptr);
300      return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration);
301  }

调用EventThread的createEventConnection

EventThread 复制代码
//frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
 sp<EventThreadConnection> Scheduler::createConnectionInternal(
292          EventThread* eventThread, ISurfaceComposer::EventRegistrationFlags eventRegistration) {
293      return eventThread->createEventConnection([&] { resync(); }, eventRegistration);
294  }

创建BitTube管道用于后续消息通信

scss 复制代码
//frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
//mChannel = gui::BitTube mChannel
 EventThreadConnection::EventThreadConnection(
155          EventThread* eventThread, uid_t callingUid, ResyncCallback resyncCallback,
156          ISurfaceComposer::EventRegistrationFlags eventRegistration)
157        : resyncCallback(std::move(resyncCallback)),
158          mOwnerUid(callingUid),
159          mEventRegistration(eventRegistration),
160          mEventThread(eventThread),
161          mChannel(gui::BitTube::DefaultSize) {}

2、App端Vsync信号的接收处理流程:

Choreographer的初始化

Choreographer.java 复制代码
private Choreographer(Looper looper, int vsyncSource) {
    mLooper = looper;
    mHandler = new FrameHandler(looper);
    //创建FrameDisplayEventReceiver
    mDisplayEventReceiver = USE_VSYNC
            ? new FrameDisplayEventReceiver(looper, vsyncSource)
            : 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();
    }
    // b/68769804: For low FPS experiments.
    setFPSDivisor(SystemProperties.getInt(ThreadedRenderer.DEBUG_FPS_DIVISOR, 1));
}

创建FrameDisplayEventReceiver的对象,会在Native层创建NativeDisplayEventReceiver

DisplayEventReceiver.java 复制代码
public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration) {
    if (looper == null) {
        throw new IllegalArgumentException("looper must not be null");
    }

    mMessageQueue = looper.getQueue();
    mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
            vsyncSource, eventRegistration);
}

Native层创建NativeDisplayEventReceiver

android_view_DisplayEventReceiver 复制代码
//frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
  static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj,
                          jint vsyncSource, jint eventRegistration) {
      sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
      if (messageQueue == NULL) {
          jniThrowRuntimeException(env, "MessageQueue is not initialized.");
          return 0;
      }
  
      sp<NativeDisplayEventReceiver> receiver =
              new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource,
                                             eventRegistration);
      status_t status = receiver->initialize();
      if (status) {
          String8 message;
          message.appendFormat("Failed to initialize display event receiver.  status=%d", status);
          jniThrowRuntimeException(env, message.string());
          return 0;
      }
  
      receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
      return reinterpret_cast<jlong>(receiver.get());
  }

NativeDisplayEventReceiver构造函数初始化,又创建了DisplayEventDispatcher

android_view_DisplayEventReceiver 复制代码
//frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
  NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
                                                         const sp<MessageQueue>& messageQueue,
                                                         jint vsyncSource, jint eventRegistration)
        : DisplayEventDispatcher(messageQueue->getLooper(),
                                 static_cast<ISurfaceComposer::VsyncSource>(vsyncSource),
                                 static_cast<ISurfaceComposer::EventRegistration>(eventRegistration)),
          mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
          mMessageQueue(messageQueue) {
      ALOGV("receiver %p ~ Initializing display event receiver.", this);
  }

DisplayEventDispatcher初始化,其成员变量mReceiver = DisplayEventReceiver

css 复制代码
//frameworks/native/libs/gui/DisplayEventDispatcher.cpp

 DisplayEventDispatcher::DisplayEventDispatcher(
          const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource,
          ISurfaceComposer::EventRegistrationFlags eventRegistration)
        : mLooper(looper), mReceiver(vsyncSource, eventRegistration), mWaitingForVsync(false) {
      ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
  }
  
 

DisplayEventReceiver初始化会创建连接

scss 复制代码
//frameworks/native/libs/gui/DisplayEventReceiver.cpp)
 DisplayEventReceiver::DisplayEventReceiver(
           ISurfaceComposer::VsyncSource vsyncSource,
           ISurfaceComposer::EventRegistrationFlags eventRegistration) {
       sp<ISurfaceComposer> sf(ComposerService::getComposerService());
       if (sf != nullptr) {
           mEventConnection = sf->createDisplayEventConnection(vsyncSource, eventRegistration);
           if (mEventConnection != nullptr) {
               mDataChannel = std::make_unique<gui::BitTube>();
               mEventConnection->stealReceiveChannel(mDataChannel.get());
           }
       }
   }

Looper 监听到 BitTube 可读回调

arduino 复制代码
//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;
      VsyncEventData vsyncEventData;
      if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncEventData)) {
          ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64
                ", displayId=%s, count=%d, vsyncId=%" PRId64,
                this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount,
                vsyncEventData.id);
          mWaitingForVsync = false;
             //Vsync事件分发
          dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncEventData);
      }
  
      return 1; // keep the callback
  }

APP端Vsync事件分发,NativeDisplayEventReceiver 继承DisplayEventDispatcher

scss 复制代码
 void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
                                                 uint32_t count, VsyncEventData vsyncEventData) {
      JNIEnv* env = AndroidRuntime::getJNIEnv();
  
      ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
      if (receiverObj.get()) {
          ALOGV("receiver %p ~ Invoking vsync handler.", this);
          //调用java层DisplayEventReceiver的dispatchVsync
          env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
                              timestamp, displayId.value, count, vsyncEventData.id,
                              vsyncEventData.deadlineTimestamp, vsyncEventData.frameInterval);
          ALOGV("receiver %p ~ Returned from vsync handler.", this);
      }
  
      mMessageQueue->raiseAndClearException(env, "dispatchVsync");
  }

调用java层DisplayEventReceiver的dispatchVsync,Choreographer的FrameDisplayEventReceiver继承DisplayEventReceiver,最终回调FrameDisplayEventReceiver的onVsync

FrameDisplayEventReceiver 复制代码
public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
        VsyncEventData vsyncEventData) {
}

public void run() {
    mHavePendingVsync = false;
    //开始绘制流程
    doFrame(mTimestampNanos, mFrame, mLastVsyncEventData);
}
相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui