基础概念梳理

个人了解

在android中编写的view,终究需求经过OpenGl Es/Skia(Q以后使用Skia)向物理屏幕输出,终究显现咱们要显现的画面。

在这个过程中,android 需求供给一块画布,让咱们能够编写自己要显现的东西,这儿边就触及到SF(SurfaceFlinger) 和Surface,FrameBuffer等。
FrameBuffer 则是帧缓存驱动,便是体系特别为显现保存的一块内存,
输出需求显现的内容就往这儿写,屏幕需求显现的时分,也是从这儿取,一般数量为2,也便是双缓冲,也有三缓冲。

Surface究竟是什么? 对应内存里的一块区域,由SF分配,app会从SF那获取一块GraphicBuffer,经过OpenGL/Skia 将图形制作到GraphicBuffer上,SF会把各个应用的GraphicBuffer进行组成,终究经过SF 输出到屏幕上。 简单说便是SF的给的一块内存。

正常一个页面,顶部状态栏是一个buffer,底部导航栏是一个,中心的页面是一个,终究他们会被组成为一帧画面。

基础类和办法

ViewRoot中的Surface 创立过程 触及如下几个类和类里参数

ViewRootImp.java

特点
//空的结构 其实只是个占位后期需求copyFrom才干真实赋值 准确说是个壳子
public final Surface mSurface = new Surface();
//空结构 无用 后期也是赋值过来 
private final SurfaceControl mSurfaceControl = new SurfaceControl()
// mWindowSession 实践是Session的一个aidl的署理类  在当时类是仅有的 整个app有且只要一个
final IWindowSession mWindowSession;
//结构函数会调用到nativeCreate 会调用android_view_SurfaceSession.cpp里边的nativeCreate 是SF在C端的引证
private final SurfaceSession mSurfaceSession = new SurfaceSession();
​
final W mWindow;
​
留意点
  • 为什么app里只要一个Session

    //结构函数获取Session
    public ViewRootImpl(Context context, Display display) {
        this(context, display, WindowManagerGlobal.getWindowSession(),
            false /* useSfChoreographer */);
       }
      
    ​
    WindowManagerGlobal.java -->getWindowSession()
     //单例形式 跨进程 从WindowManagerService 获取 WindowManagerService 是承继完成了 IWindowManager.Stub
     public static IWindowSession getWindowSession() {
        synchronized (WindowManagerGlobal.class) {
          if (sWindowSession == null) {
            try {
             InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();
              IWindowManager windowManager = getWindowManagerService();
              sWindowSession = windowManager.openSession(
                  new IWindowSessionCallback.Stub() {
                    @Override
                    public void onAnimatorScaleChanged(float scale) {
                      ValueAnimator.setDurationScale(scale);
                     }
                   });
             } catch (RemoteException e) {
              throw e.rethrowFromSystemServer();
             }
           }
          return sWindowSession;
         }
       }
      
    
办法

进口

setView 会调用如下两个办法

requestLayout();->scheduleTraversals();->doTraversal()-> performTraversals()->
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
-->
 //这儿调用了Session.relayout 传递参数给Session
 //留意这儿的params 和宽高都传递过去了 由于在SF那边图层 需求宽高和format 类型 比方argb888之类的
 //实践调用是wms的relayoutWindow
 int relayoutResult = mWindowSession.relayout(mWindow, params,
         (int) (mView.getMeasuredWidth() * appScale + 0.5f),
         (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
        insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,          frameNumber,
        mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
        mTempControls, mSurfaceSize);
​
  //这儿是个重点 将mSurfaceControl里边的mNativeObject copy 过来 所以其实surface便是空壳子
  mSurface.copyFrom(mSurfaceControl);
//调用Session的addToDisplayAsUser  实践是调用了wms的addWindow
res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), userId, mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
              mTempControls);

Surface.java

copyFrom()
  @UnsupportedAppUsage
  public void copyFrom(SurfaceControl other) {
    if (other == null) {
      throw new IllegalArgumentException("other must not be null");
     }
​
    long surfaceControlPtr = other.mNativeObject;
    if (surfaceControlPtr == 0) {
      throw new NullPointerException(
          "null SurfaceControl native object. Are you using a released SurfaceControl?");
     }
    long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
    updateNativeObject(newNativeObject);
   }
​

Session.java

relayout
@Override
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
    int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
    ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
    SurfaceControl outSurfaceControl, InsetsState outInsetsState,
    InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
  int res = mService.relayoutWindow(this, window, attrs,
      requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
      outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
      outActiveControls, outSurfaceSize);
​
  return res;
}
addToDisplayAsUser
public int addToDisplayAsUser(IWindow window, WindowManager.LayoutParams attrs,
    int viewVisibility, int displayId, int userId, InsetsState requestedVisibility,
    InputChannel outInputChannel, InsetsState outInsetsState,
    InsetsSourceControl[] outActiveControls) {
 //wms 增加window
  return mService.addWindow(this, window, attrs, viewVisibility, displayId, userId,
      requestedVisibility, outInputChannel, outInsetsState, outActiveControls);
}
windowAddedLocked
void windowAddedLocked() {
  if (mPackageName == null) {
    final WindowProcessController wpc = mService.mAtmService.mProcessMap.getProcess(mPid);
    if (wpc != null) {
      mPackageName = wpc.mInfo.packageName;
      mRelayoutTag = "relayoutWindow: " + mPackageName;
     } else {
      Slog.e(TAG_WM, "Unknown process pid=" + mPid);
     }
   }
  if (mSurfaceSession == null) {
    if (DEBUG) {
      Slog.v(TAG_WM, "First window added to " + this + ", creating SurfaceSession");
     }
   //创立新 的SurfaceSession  在他的结构函数里会和native 通信
    mSurfaceSession = new SurfaceSession(); 
    ProtoLog.i(WM_SHOW_TRANSACTIONS, "  NEW SURFACE SESSION %s", mSurfaceSession);
   //wms里边的 mSessions 开端办理该Session
    mService.mSessions.add(this);
    if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
      mService.dispatchNewAnimatorScaleLocked(this);
     }
   }
 // 窗口数量增加
  mNumWindow++;
}

WindowManagerService.java

addWindow()
//中心代码 创立WindowState 并调用 attach
final WindowState win = new WindowState(this, session, client, token, parentWindow,
    appOp[0], attrs, viewVisibility, session.mUid, userId,
    session.mCanAddInternalSystemWindow);...
 win.attach();
relayoutWindow
//申请宽高
if (viewVisibility != View.GONE) { win.setRequestedSize(requestedWidth, requestedHeight);}
attrChanges = win.mAttrs.copyFrom(attrs);
//将viewRootimp 里边的 outSurfaceControl 传入办法开端创立
 result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
createSurfaceControl
//调用winAnimator
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
// copyFrom 赋值给viewRootImp里的SurfaceControl
 surfaceController.getSurfaceControl(outSurfaceControl);

WindowState.java

attach()
void attach() {
  if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
  mSession.windowAddedLocked();
}

SurfaceSession.java

结构函数
public SurfaceSession() {
  mNativeClient = nativeCreate();
}

WindowStateAnimator.java

createSurfaceLocked
//假如不为null 则直接回来 
if (mSurfaceController != null) {
  return mSurfaceController;
}
//否则创立
 mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
          height, format, flags, this, windowType);

WindowSurfaceController.java

结构函数(String name, int w, int h, int format,
   int flags, WindowStateAnimator animator, int windowType)
//会调用到SurfaceControl里的build()   
final SurfaceControl.Builder b = win.makeSurface()
         .setParent(win.getSurfaceControl())
         .setName(name)
         .setBufferSize(w, h)
         .setFormat(format)
         .setFlags(flags)
         .setMetadata(METADATA_WINDOW_TYPE, windowType)
         .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
         .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
         .setCallsite("WindowSurfaceController");
​
    final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
        & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);
​
    if (useBLAST) {
      b.setBLASTLayer();
     }
​
    mSurfaceControl = b.build();

SurfaceControl.java

mNativeObject

这儿的mNativeObject 其实指向的便是SF给拓荒的内存地址,后期会赋值给ViewRootImp里的surface

多结构参数办法
mNativeObject = nativeCreate(session, name, w, h, format, flags,
  parent != null ? parent.mNativeObject : 0, metaParcel);
build()
public SurfaceControl build() {
      if (mWidth < 0 || mHeight < 0) {
        throw new IllegalStateException(
            "width and height must be positive or unset");
       }
      if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) {
        throw new IllegalStateException(
            "Only buffer layers can set a valid buffer size.");
       }
​
      if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
        setBLASTLayer();
       }
​
      return new SurfaceControl(
          mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
          mLocalOwnerView, mCallsite);
     }
getSurfaceControl
void getSurfaceControl(SurfaceControl outSurfaceControl) {
  outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
}

android_view_surfaceControl.cpp

nativeCreate()
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
    jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
    jobject metadataParcel) {
  ScopedUtfChars name(env, nameStr);
  sp<SurfaceComposerClient> client;
 //创立sf 在C端的署理
  if (sessionObj != NULL) {
   //从session拿 其实调用的是android_view_SurfaceSession.cpp里边的mNativeClient
   //然后从SurfaceSession 获取 mNativeClient  其实便是一个 SurfaceComposerClient
    client = android_view_SurfaceSession_getClient(env, sessionObj);
   } else {
   //获取默许的cliden 回来一个 SurfaceComposerClient
    client = SurfaceComposerClient::getDefault();
   }
  SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
  sp<SurfaceControl> surface;
  LayerMetadata metadata;
  Parcel* parcel = parcelForJavaObject(env, metadataParcel);
  if (parcel && !parcel->objectsCount()) {
    status_t err = metadata.readFromParcel(parcel);
    if (err != NO_ERROR) {
     jniThrowException(env, "java/lang/IllegalArgumentException",
              "Metadata parcel has wrong format");
     }
   }
​
  sp<IBinder> parentHandle;
  if (parent != nullptr) {
    parentHandle = parent->getHandle();
   }
​
 //sf 创立Surface
  status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
                        flags, parentHandle, std::move(metadata));
  if (err == NAME_NOT_FOUND) {
    jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    return 0;
   } else if (err != NO_ERROR) {
    jniThrowException(env, OutOfResourcesException, NULL);
    return 0;
   }
​
  surface->incStrong((void *)nativeCreate);
  return reinterpret_cast<jlong>(surface.get());
}

android_view_SurfaceSession.cpp

nativeCreate()
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
  SurfaceComposerClient* client = new SurfaceComposerClient();
  client->incStrong((void*)nativeCreate);
  return reinterpret_cast<jlong>(client);
}
register_android_view_SurfaceSession
//其实从SurfaceSession.java去获取mNativeClient  赋值给 自己内部的mNativeClient
int register_android_view_SurfaceSession(JNIEnv* env) {
  int res = jniRegisterNativeMethods(env, "android/view/SurfaceSession",
      gMethods, NELEM(gMethods));
  LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
​
  jclass clazz = env->FindClass("android/view/SurfaceSession");
  gSurfaceSessionClassInfo.mNativeClient = env->GetFieldID(clazz, "mNativeClient", "J");
  return 0;
}

SurfaceComposerClient.cpp

createSurfaceChecked()
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                           PixelFormat format,
                           sp<SurfaceControl>* outSurface, uint32_t flags,
                           const sp<IBinder>& parentHandle,
                           LayerMetadata metadata,
                           uint32_t* outTransformHint) {
  sp<SurfaceControl> sur;
  status_t err = mStatus;
​
  if (mStatus == NO_ERROR) {
    sp<IBinder> handle;
    sp<IGraphicBufferProducer> gbp;
​
    uint32_t transformHint = 0;
    int32_t id = -1;
     //创立surface
    err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                   &handle, &gbp, &id, &transformHint);
​
    if (outTransformHint) {
      *outTransformHint = transformHint;
     }
    ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
    if (err == NO_ERROR) {
      *outSurface =
          new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
     }
   }
  return err;
}
结构函数
SurfaceComposerClient::SurfaceComposerClient()
   : mStatus(NO_INIT)
{
}
onFirstRef
//结构调用
void SurfaceComposerClient::onFirstRef() {
  //这儿便是binder 调用 SF
  sp<ISurfaceComposer> sf(ComposerService::getComposerService());
  if (sf != nullptr && mStatus == NO_INIT) {
   //跨进程调用SF的createConnection
    sp<ISurfaceComposerClient> conn;
    conn = sf->createConnection(); //调用到 SurfaceFlinger 的 createConnection
    if (conn != nullptr) {
      mClient = conn;
      mStatus = NO_ERROR;
     }
   }
}

整体串联

串联Activity->ViewRootImp

ActivityThread.handleResumeActivity()
-->wm.addView(decor, l);
-->WindowManagerImp.addView()
-->mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
        mContext.getUserId());
-->WindowManagerGlobal.addView()
--> root = new ViewRootImpl(view.getContext(), display);//创立ViewRootImo
-->root.setView()
...
​

surface的创立流程

ViewRootImp-->
//(详情看ViewRootImp的办法和特点)
-->setView()
  --> requestLayout();
   -->...doTraversal()-->performTraversals();
   --> relayoutResult = relayoutWindow(mWindow, params,widhth,height..mSurfaceControl)
    //将内部surfaceControl,宽高,参数 传递给wms
   -->mWindowSession.relayout(...)
   -->Aidl调用Session.relayout(...)
    -->WindowManagerService.relayoutWindow(...attrs,..outSurfaceControl,)
    --> createSurfaceControl(outSurfaceControl, result, win, winAnimator)
    -->surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
     -->WindowStateAnimator.createSurfaceLocked//WindowStateAnimator 对应办法
      --> 不为null回来mSurfaceController 
       -->null调用 回来 new WindowSurfaceController() 
        --> 调用SurfaceControl.Builder.build()
        --> new SurfaceControl(
          mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
          mLocalOwnerView, mCallsite);
        --> mNativeObject = nativeCreate(session, name, w, h, format, flags,
          parent != null ? parent.mNativeObject : 0, metaParcel);
          -->android_view_SurfaceControl.cpp.nativeCreate()
           -->client->createSurfaceChecked()//详细看android_view_SurfaceControl.cpp
           --> 回来
    -->surfaceController.getSurfaceControl(outSurfaceControl)//c++层创立的mSurfaceControl  拷贝到ViewTRootImp 传递过来的outSurfaceControl
     
   
---------------------------------------------------------
  --> mWindowSession.addToDisplayAsUser()
    -->Aidl调用Session.addToDisplayAsUser()
    --> mService.addWindow()
    --> 创立windowState 调用attach() 
    -->Session.windowAddedLocked();//将surfaceSession 创立 并 wms办理当时Session 也便是当时app仅有的Session
    --> mSurfaceSession = new SurfaceSession();
      mService.mSessions.add(this);
      mNumWindow++;
     --> SurfaceSession 结构函数  mNativeClient = nativeCreate();
     -->android_view_SurfaceSession.cpp -->nativeCreate()//创立SurfaceComposerClient 回来 能够了解为 SF的在APP端的署理  这儿会有疑问,为什么这个代码在下面,由于上面的 performTraversals 需求监听到 SF 的callBack 才会履行,这会就现已初始化完成了
      
  -->   
    

SF在C端的创立流程

SF的创立在 SurfaceSession 的结构函数里,Session便是会话的意思

android_view_SurfaceSession.cpp
 -->nativeCreate()
 ---> SurfaceComposerClient* client = new SurfaceComposerClient();
​
 ...
  --> 首次会调用 SurfaceComposerClient的onFirstRef 办法 调用sf->createConnection()
  --> SurFaceFlinger.createConnection()
​
  --> 创立一个 Client 回来
  sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
  const sp<Client> client = new Client(this);
  return client->initCheck() == NO_ERROR ? client : nullptr;
}

view 怎么转化到屏幕上的?

中心类

  • ThreadedRenderer
ViewRootImp.draw()
->mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
-->ThreadRenderer.draw()
  -->updateRootDisplayList(view, callbacks);
    --> updateViewTreeDisplayList(view);
    --> view.updateDisplayListIfDirty();//烘托自己的Node View办法 终究回来RenDerNode
     --> if (renderNode.hasDisplayList(){ dispatchGetDisplayList(); //遍历子节点 ViewGroup }
                       
  -->registerAnimatingRenderNode()//办法注册动画 Render Node
  -->syncAndDrawFrame()//通知RenderThread 烘托下一帧
  • RecordingCanvas
//真实的制作 RecordingCanvas  绘图指令员
if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {
      RecordingCanvas canvas = mRootNode.beginRecording(mSurfaceWidth, mSurfaceHeight);
      try {
        final int saveCount = canvas.save();
        canvas.translate(mInsetLeft, mInsetTop);
        callbacks.onPreDraw(canvas);
​
        canvas.enableZ();
        canvas.drawRenderNode(view.updateDisplayListIfDirty());
        canvas.disableZ();
​
        callbacks.onPostDraw(canvas);
        canvas.restoreToCount(saveCount);
        mRootNodeNeedsUpdate = false;
       } finally {
        mRootNode.endRecording();
       }
     }
  • RenderNode

会包括DisPlayList ,DisPlayList里边也或许包括RenderNode,套娃。

真实的制作者
performTraversals()-->performDraw();
-->....-> CanvasContext.draw()
​
  • CanvasContext.cpp
Frame frame = mRenderPipeline->getFrame();
SkRect windowDirty = computeDirtyRect(frame, &dirty);
​
bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
                 mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,
                 &(profiler()));
  • 总结

    Surface 具有一个buffer,可是buffer不能直接给屏幕用,就需求提交给SF的行列,SF处理后再给屏幕。
    在这个过程中,屏幕用完这个buffer 会再次还给SF,防止消耗。

常见问题题梳理

  • 图层面板是什么?

android 里每个Activity都有一个独立的画布,应用端叫surface 在

SF里叫layer, 无论多么复杂的view结构 其实都是画在了所在的Activity上。

  • 为什么规划成C/S架构

防止崩溃 影响体系服务。

  • buffer是什么

buffer缓存了图形的内存空间,被surface办理

  • Surface 对其他逻辑的影响

Surface画布的影响 到Window窗口的巨细,影响wms 服务的控制巨细,(更新window)