系列文章请扫关注公众号!
1、ViewRootImpl是View和WMS的沟通桥梁
ViewRootImpl 是 View 的最高层级,是所有 View 的根。ViewRootImpl 实现了 View 和 WindowManager 之间通信所需要的协议。ViewRootImpl 的创建过程是从 WindowManagerImpl 中开始的。View 的测量,布局,绘制以及上屏,都是从 ViewRootImpl 中开始的。
ViewRootImple对象创建时,调用WindowManagerGlobal的static getWindowSession(),获取WMS本地代理对象,调用WMS的openSession方法创建Session对象,流程如下:
WindowManagerGlobal是单例模式,其中维护ViewRootImpl数组,每一个window对应一个ViewRootImpl。在添加View时会通过requestLayout注册Choreagrapher监听,等待系统下发绘制信号,触发View的绘制流程,也就是measure、layout、draw流程。
2、SurfaceControl的初始化
ViewRootImpl内部有三个成员变量:
Para code#1 Android 13
//frameworks/base/core/java/android/view/ViewRootImpl.java
241 public final class ViewRootImpl ... {
649 // These can be accessed by any thread, must be protected with a lock.
650 // Surface can never be reassigned or cleared (use Surface.clear()).
651 @UnsupportedAppUsage
652 public final Surface mSurface = new Surface();
653 private final SurfaceControl mSurfaceControl = new SurfaceControl();
654
655 private BLASTBufferQueue mBlastBufferQueue;
}
来看下mSurface和mSurfaceControl初始化的流程。
2.1 Session的创建
应用程序的draw绘制需要通过WMS获取可用的画布。 在setView()中通过mWindowSession对象将window添加到wms,如下
Para code#2 Android 13
//frameworks/base/core/java/android/view/ViewRootImpl.java
426 final IWindowSession mWindowSession;
1099 public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
1100 int userId) {
......
//请求布局,执行 View 的绘制方法
1195 requestLayout();
1218 res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
1219 getHostVisibility(), mDisplay.getDisplayId(), userId,
1220 mInsetsController.getRequestedVisibilities(), inputChannel, mTempInsets,
1221 mTempControls);
mWindowSession是WMS的一个client端。
Session表示客户端和WMS交互的会话,每个进程都有一个Session对象与WMS交互。看几个Session的成员方法:
//Para code#3 Android 13
//frameworks/base/services/core/java/com/android/server/wm/Session.java
124 public Session(WindowManagerService service, IWindowSessionCallback callback) {
125 mService = service;
195 public int addToDisplay(...) {
199 return mService.addWindow(this, window, attrs, viewVisibility, displayId,
200 UserHandle.getUserId(mUid), requestedVisibilities, outInputChannel, outInsetsState,
201 outActiveControls);
202 }
203
205 public int addToDisplayAsUser(...) {
209 return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,
210 requestedVisibilities, outInputChannel, outInsetsState, outActiveControls);
211 }
212
214 public int addToDisplayWithoutInputChannel(...) {
216 return mService.addWindow(this, window, attrs, viewVisibility, displayId,
217 UserHandle.getUserId(mUid), mDummyRequestedVisibilities, null /* outInputChannel */,
218 outInsetsState, mDummyControls);
219 }
220
222 public void remove(IWindow window) {
223 mService.removeWindow(this, window);
224 }
所以mWindowSession最终调用的是WMS。
在创建ViewRootImple对象时,默认调用WindowManagerGlobal的静态方法getWindowSession。获取WMS本地代理对象,调用WMS的openSession方法创建Session对象,流程如下:
2.2 创建SurfaceControl
ViewRootImple在setView()时会注册Choreographer的监听,等系统下发绘制同步信号时,ViewRootImpl执行performTraversals方法,大致流程如下:
ViewRootImpl.setView()
-->ViewRootImpl.requestLayout
-->ViewRootImpl.scheduleTraversals
-->ViewRootImpl.performTraversals{
if (mFirst || viewVisibilityChanged) {
mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED;
}
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
}
当一个View树的子View的布局失效时,简单点就是画面有更新时,调用relayoutWindow方法会对整个View树的布局做重新处理。
ViewRootImpl.relayoutWindow进而调用Session对象的relayout方法。
Session对象又调用WindowManagerService的relayoutWindow方法。
WMS调用自身的createSurfaceControl方法,又new WindowSurfaceController()对象。
又调用WindowStateAnimator.createSurfaceLocked()方法初始化WindowSurfaceController。
//Para code#4 Android 13
//frameworks/base/core/java/android/view/ViewRootImpl.java
private int relayoutWindow(...)
-->relayoutResult = mWindowSession.relayout();
--> public int relayout()//frameworks/base/services/core/java/com/android/server/wm/Session.java
-->mService.relayoutWindow()
//frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
-->WindowManagerService.relayoutWindow
-->createSurfaceControl(outSurfaceControl, result, win, winAnimator);{
-->WindowSurfaceController surfaceController;
-->surfaceController = winAnimator.createSurfaceLocked();
}
//frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
291 WindowSurfaceController createSurfaceLocked() {
300 ProtoLog.i(WM_DEBUG_ANIM, "createSurface %s: mDrawState=DRAW_PENDING", this);
324 try {
325
329 //带参数初始化了 WindowSurfaceController()
330 mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,
331 flags, this, attrs.type);
344 }
369 return mSurfaceController;
370 }
在WindowSurfaceController对象实例化时,创建SurfaceControl对象。
//frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java
79 WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,
80 int windowType) {
//真正的创建SurfaceControl了
90 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
91 final SurfaceControl.Builder b = win.makeSurface()
92 .setParent(win.getSurfaceControl())
93 .setName(name)
94 .setFormat(format)
95 .setFlags(flags)
96 .setMetadata(METADATA_WINDOW_TYPE, windowType)
97 .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
98 .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
99 .setCallsite("WindowSurfaceController");
100 //这里判断是否使用BLASTBufferqueue,android 12、13都是使用这个的
101 final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
102 & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);
103
104 if (useBLAST) {
105 b.setBLASTLayer();
106 }
107
108 mSurfaceControl = b.build();
109
110 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
111 }
在SurfaceControl构造函数中调用了本地方法nativeCreate:
//frameworks/base/core/java/android/view/SurfaceControl.java
1537 private SurfaceControl(..) {
1561 mNativeObject = nativeCreate(session, name, w, h, format, flags,
1562 parent != null ? parent.mNativeObject : 0, metaParcel);
这个nativeCreate()方法用来生成一个有名字的Surface。
Surface创建标志明确了要创建哪种Surface和特定的选项,比如Surface可以被认为是不透明的,是否应该在初始的时候隐藏。Surface应该总是在创建的时候带着HIDDEN标志,以确保在Surface的属性配置好之前,Surface不会过早显示。
一个好的实践是,首先使用HIDDEN标志创建Surface,接着打开一个Transactionn,设置Surface的layer、layer堆栈、透明度、位置,然后再合适的时机调用Transaction.show,最后关闭Transactoin。
Surface的界限由它的crop和buffer尺寸决定。如果这个Surface没有buffer或者是crop,那么这个Surface就是无边界的,只被它的父Surface的界限尺寸所限制。
从java一路调用至native层的流程大致如下图:
2.3 Native SurfaceControl
SurfaceControl.java中的nativeCreate()函数调到android_view_SurfaceControl.nativeCreate。
nativeCreate()返回Surface的long指针,保存在SurfaceControl中,java层操作都是基于这个指针操作SurfaceControl。
//Para code#5 Android 13
//frameworks/base/core/jni/android_view_SurfaceControl.cpp
398 static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
399 jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
400 jobject metadataParcel) {
401 ScopedUtfChars name(env, nameStr);
402 sp<SurfaceComposerClient> client; //创建一个surfaceFlinger的client端。
403 if (sessionObj != NULL) {//如果已经创建过SurfaceComposerClient,获取
404 client = android_view_SurfaceSession_getClient(env, sessionObj);
405 } else {//获取默认SurfaceComposerClient
406 client = SurfaceComposerClient::getDefault();
407 }
408 SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
409 sp<SurfaceControl> surface;
410 LayerMetadata metadata;
411 Parcel* parcel = parcelForJavaObject(env, metadataParcel);
412 if (parcel && !parcel->objectsCount()) {
413 status_t err = metadata.readFromParcel(parcel);
414 if (err != NO_ERROR) {
415 jniThrowException(env, "java/lang/IllegalArgumentException",
416 "Metadata parcel has wrong format");
417 }
418 }
419
420 sp<IBinder> parentHandle;
421 if (parent != nullptr) {
422 parentHandle = parent->getHandle();
423 }
424 //调用到SurfaceFlinger的createSurfaceChecked函数,创建一个surface
425 status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
426 flags, parentHandle, std::move(metadata));
427 if (err == NAME_NOT_FOUND) {
428 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
429 return 0;
430 } else if (err != NO_ERROR) {
431 jniThrowException(env, OutOfResourcesException, NULL);
432 return 0;
433 }
434
435 surface->incStrong((void *)nativeCreate);
436 return reinterpret_cast<jlong>(surface.get());
437 }
上面出现了重要的对象SurfaceComposerClient,这个是SurfaceFlinger的client端,native层的交互基本都靠它。
2.4 SurfaceComposerClient
SurfaceComposerClient.createSurfaceChecked会一路调用到Client.cpp中。
//Para code#7 Android 13
//frameworks/native/services/surfaceflinger/Client.cpp
75 status_t Client::createSurface(const String8& name, uint32_t /* w */, uint32_t /* h */,
76 PixelFormat /* format */, uint32_t flags,
77 const sp<IBinder>& parentHandle, LayerMetadata metadata,
78 sp<IBinder>* outHandle, sp<IGraphicBufferProducer>* /* gbp */,
79 int32_t* outLayerId, uint32_t* outTransformHint) {
80 // We rely on createLayer to check permissions.
81 LayerCreationArgs args(mFlinger.get(), this, name.c_str(), flags, std::move(metadata));
82 return mFlinger->createLayer(args, outHandle, parentHandle, outLayerId, nullptr,
83 outTransformHint);
84 }
//frameworks/native/services/surfaceflinger/Client.h
71 sp<SurfaceFlinger> mFlinger;
调用mFlinger->createlayer方法,这里的mFlinger对象是什么呢?是SurfaceFlinger的指针。
2.5 SurfaceFlinger
进而调用到而来SurfaceFlinger.createSurface()。
//Para code#8 Android 13
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
4652 status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHandle,
4653 const sp<IBinder>& parentHandle, int32_t* outLayerId,
4654 const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
4660
4661 sp<Layer> layer;
4662
4663 switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
4664 case ISurfaceComposerClient::eFXSurfaceBufferQueue:
4665 case ISurfaceComposerClient::eFXSurfaceBufferState: {
4666 result = createBufferStateLayer(args, outHandle, &layer);
4667 std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
4668 if (pendingBufferCounter) {
4669 std::string counterName = layer->getPendingBufferCounterName();
4670 mBufferCountTracker.add((*outHandle)->localBinder(), counterName,
4671 pendingBufferCounter);
4672 }
4673 } break;
4674 case ISurfaceComposerClient::eFXSurfaceEffect:
4675 result = createEffectLayer(args, outHandle, &layer);
4676 break;
4677 case ISurfaceComposerClient::eFXSurfaceContainer:
4678 result = createContainerLayer(args, outHandle, &layer);
4679 break;
4680 default:
4681 result = BAD_VALUE;
4682 break;
4683 }
4689 bool addToRoot = args.addToRoot && callingThreadHasUnscopedSurfaceFlingerAccess();
4690 wp<Layer> parent(parentHandle != nullptr ? fromHandle(parentHandle) : parentLayer);
4706 if (mTransactionTracing) {
4707 mTransactionTracing->onLayerAdded((*outHandle)->localBinder(), layer->sequence, args.name,
4708 args.flags, parentId);
4709 }
4710
4711 result = addClientLayer(args.client, *outHandle, layer, parent, addToRoot, outTransformHint);
4712 if (result != NO_ERROR) {
4713 return result;
4714 }
4715
4716 *outLayerId = layer->sequence;
4717 return result;
4718 }
Android12 中有getUniqueLayerName函数保证每一个Layer都有一个独一无二的名字,名字的格式为:
uniqueName = base::StringPrintf("%s#%u", name, ++dupeCounter);
保证了即使是同一个Activity的两个窗口,也能根据“#0”,“#1”等序号进行区分。
2.6 Layer的几种类型
这里根据传入的flags参数的ISurfaceComposerClient::eFXSurfaceMask这一位去创建不同类型的Layer对象。
//frameworks/native/libs/gui/include/gui/ISurfaceComposerClient.h
35 // flags for createSurface()
36 enum { // (keep in sync with SurfaceControl.java)
48 eFXSurfaceBufferQueue = 0x00000000,
49 eFXSurfaceEffect = 0x00020000,
50 eFXSurfaceBufferState = 0x00040000,
51 eFXSurfaceContainer = 0x00080000,
53 };
· eFXSurfaceBufferQueue和eFXSurfaceBufferState,对应BufferStateLayer。
· eFXSurfaceEffect,对应EffectLayer。
· eFXSurfaceContainer,对应ContainerLayer。
2.7 BufferStateLayer的创建
。。。。。。
2.7.1 Layer向SurfaceFlinger进行注册
。。。。。。
2.7.2 Layer句柄的创建
。。。。。。
2.8 SurfaceFlinger.addClientLayer
。。。。。。
2.8.1 将<Handle, Layer>对记录到Client中
。。。。。。
2.8.2 将<Handle, Layer>对记录到SurfaceFlinger中
。。。。。。。
2.9 SurfaceControl的返回
。。。。。。。
3、小结
系列文章详情,请关注公众号