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);
}
相关推荐
YF02111 小时前
详解Android所有文件访问权限
android
时间的拾荒人3 小时前
MySQL C语言连接 - 从入门到实战
android·c语言·mysql
Meteors.3 小时前
Android性能优化:01. 指标体系 + 分析工具链
android
jike_20264 小时前
安卓平台免费录音转文字工具深度测评:5 款 APP 功能对比与选型指南
android·智能电视
Code Man4 小时前
Windows 下使用 Appium
android·windows·appium
码农coding5 小时前
android 12 中的VSYNC接收
android
GitLqr5 小时前
Flutter 3.44 性能飞跃:深度解析 Android Platform View 的 HCPP 新特性
android·flutter·性能优化
码农coding5 小时前
android 12 SurfaceFlinger中的CompositionEngine
android
Mem0rin6 小时前
[MySQL] 聚合函数、分组查询、连接查询
android·mysql