Android Display Graphics #从Activity看surface的创建(2)

Android智能座舱系列

系列文章请扫关注公众号!

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、小结

系列文章详情,请关注公众号

  • 26
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值