前言
在《浅析Android中View的测量布局流程》中我们对VSYNC信号到达App进程之后开启的View布局过程进行了分析,经过对整个App界面的View树进行遍历完成了测量和布局,确定了View的大小以及在屏幕中所处的位置。但是,如果想让用户在屏幕上看到View的内容,还需要根据View的绘制生成图形数据并交由硬件进行屏幕刷新。
View的绘制主要负责将业务层的各种API调用转换为指令,然后交给渲染引擎进行处理,最终生成能够被硬件直接处理的数据。这个过程主要分为渲染数据的生产以及消费,一般来说,渲染数据的生产者是各个App进程,而消费者则是SurfaceFlinger进程,这里会涉及到渲染数据的跨进程传输问题。下面将会对渲染数据的跨进程传输的实现进行分析。
Surface作为数据载体负责打通App进程与SurfaceFlinger进程之间的数据交互,同时Surface是属于App进程内的资源,因此先从App进程这个生产者出发,基于Surface的创建流程及其使用,对渲染数据的传递机制进行分析。
绘制前的准备
在《浅析Android中View的测量布局流程》中有分析到,当测量数据发生变化时,需要对窗体大小进行更新,因为测量数据的变化导致视图展示区域随之发生变化。
根据分析测量布局流程的相关源码实现可知,一个ViewRootImpl对象被创建时,都会创建一个Surface对象以及SurfaceControl对象,但是Surface对象并不是立即可用于绘制渲染的,而只是一个壳子,其真正的实现是在native层。而在测量之后宽高如果发生变化,则需要对窗口大小进行更新,此时会对Surface以及SurfaceControl对象进行处理,即更新native层的Surface以及SurfaceControl对象,之后Surface对象将进入可用状态。
SurfaceControl的创建
首先,App进程为每一个Activity创建了一个Window,而每一个Window会对应一个ViewRootImpl,每一个ViewRootImpl持有一个Surface以及SurfaceControl对象。然后,SystemServer进程会对应地为App进程的每一个Window创建一个Window,相对应地,也会为每一个Window创建一个SurfaceControl对象。下面我们看下SystemServer进程中的SurfaceControl的创建过程。
public final class ViewRootImpl implements ViewParent, View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks, AttachedSurfaceControl {
final W mWindow; // mWindow = new W(this);
public final Surface mSurface = new Surface();
private final SurfaceControl mSurfaceControl = new SurfaceControl();
// ...
private void performTraversals() {
// ...
boolean windowShouldResize = layoutRequested && windowSizeMayChange && ((mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) || (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT && frame.width() < desiredWindowWidth && frame.width() != mWidth) || (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT && frame.height() < desiredWindowHeight && frame.height() != mHeight));
// ...
if (mFirst || windowShouldResize || viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
try {
// ...
// 更新window
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
// ...
} catch (RemoteException e) {
} finally {
// ...
}
}
// ...
}
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException {
// ...
if (LOCAL_LAYOUT) {
// ...
} else {
// mWindowSession是IWindowSession类型的对象,即Binder代理对象,对应实现是SystemServer进程中的Session类的实例,每个进程的IWindowSession对应SystemServer进程中一个Session实例
relayoutResult = mWindowSession.relayout(mWindow, params, requestedWidth, requestedHeight, viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls, mRelayoutBundle);
// ...
}
// ...
// mSurfaceControl实例可用之后,根据mSurfaceControl的Surface信息对mSurface进行更新
if (mSurfaceControl.isValid()) {
if (!useBLAST()) {
mSurface.copyFrom(mSurfaceControl);
} else {
updateBlastSurfaceIfNeeded();
}
// ...
} else {
// ...
}
// ...
return relayoutResult;
}
// ...
}
relayoutWindow方法会通过Binder请求到SystemServer进程,对之前SystemServer进程中创建的window实例进行更新。mWindowSession.relayout会调用到WindowManagerService中的相关逻辑,经过relayout方法调用了WindowManagerService#createSurfaceControl方法,完成SystemServer进程中SurfaceControl对象的创建。
从SystemServer进程返回之后,通过getSurfaceControl方法将新创建的SurfaceControl对象的属性拷贝回App进程的SurfaceControl对象(即ViewRootImpl#mSurfaceControl)中。
// com.android.server.wm.Session
/**
* Session代表一个活跃的客户端session。SystemServer进程中会为每个进程维护一个Session对象,用于window相关的Binder通信。
*/
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
// ...
@Override
public int relayout(IWindow window, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq, int lastSyncSeqId, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Bundle outSyncSeqIdBundle) {
// ...
int res = mService.relayoutWindow(this, window, attrs, requestedWidth, requestedHeight, viewFlags, flags, seq, lastSyncSeqId, outFrames, mergedConfiguration, outSurfaceControl, outInsetsState, outActiveControls, outSyncSeqIdBundle);
// ...
return res;
}
// ...
}
// com.android.server.wm.WindowManagerService
public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
// ...
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq, int lastSyncSeqId, ClientWindowFrames outFrames, MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls, Bundle outSyncIdBundle) {
// ...
synchronized (mGlobalLock) {
// 获取窗体状态描述,每一个Window(通常对应一个Activity)都对应一个WindowState。
final WindowState win = windowForClientLocked(session, client, false);
// 获取WindowStateAnimator,用于创建SurfaceControl
WindowStateAnimator winAnimator = win.mWinAnimator;
// ...
// 只有view可见或者相关联的appToken没有隐藏时才应该relayout。
final boolean shouldRelayout = viewVisibility == View.VISIBLE && (win.mActivityRecord == null || win.mAttrs.type == TYPE_APPLICATION_STARTING || win.mActivityRecord.isClientVisible());
// ...
if (shouldRelayout && outSurfaceControl != null) {
try {
// 创建SurfaceControl并将其拷贝到outSurfaceControl,outSurfaceControl
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
} catch (Exception e) {
// ...
return 0;
}
}
// ...
}
// ...
return result;
}
private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win, WindowStateAnimator winAnimator) {
if (!win.mHasSurface) {
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
WindowSurfaceController surfaceController;
try {
// 1. 通过WindowStateAnimator对象创建WindowSurfaceController对象
surfaceController = winAnimator.createSurfaceLocked();
} finally {
// ...
}
if (surfaceController != null) {
// 2. 通过WindowSurfaceController将SurfaceController拷贝到outSurfaceControl中,outSurfaceControl对应App进程中的ViewRootImpl的mSurfaceControl变量
surfaceController.getSurfaceControl(outSurfaceControl);
} else {
// ...
outSurfaceControl.release();
}
return result;
}
// ...
}
/**
* 为单个WindowState跟踪动画和surface的操作.
**/
// com.android.server.wm.WindowStateAnimator
class WindowStateAnimator {
final WindowState mWin;
WindowSurfaceController mSurfaceController;
// 创建WindowSurfaceController
WindowSurfaceController createSurfaceLocked() {
final WindowState w = mWin;
// 如果已经创建过就不会重复创建了
if (mSurfaceController != null) {
return mSurfaceController;
}
try {
// ...
mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format, flags, this, attrs.type);
// ...
} catch (OutOfResourcesException e) {
// ...
return null;
} catch (Exception e) {
// ...
return null;
}
// ...
return mSurfaceController;
}
// ...
}
// com.android.server.wm.WindowSurfaceController
class WindowSurfaceController {
WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator, int windowType) {
// ...
final SurfaceControl.Builder b = win.makeSurface()
.setParent(win.getSurfaceControl())
.setName(name)
.setFormat(format)
.setFlags(flags)
.setMetadata(METADATA_WINDOW_TYPE, windowType)
.setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
.setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
.setCallsite("WindowSurfaceController");
// ...
mSurfaceControl = b.build();
}
public static class Builder {
@NonNull
public SurfaceControl build() {
// ....
return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata, mLocalOwnerView, mCallsite);
}
}
}
可以看出,WindowSurfaceController是SurfaceControl的包装类,通过持有SurfaceControl对象来对Surface进行操作,WindowSurfaceController以及SurfaceControl都是在SystemServer进程创建的。接下来,继续跟着SurfaceControl的构造函数看下,SurfaceControl的创建具体做了哪些事情。
/**
* 持有一个由系统合成器管理的Surface对象。这个SurfaceControl对象由buffer以及如何显示buffer的信息组成。
* 通过构造的Surface对象可以提交数据到buffer,用于合成上屏。
*/
public final class SurfaceControl implements Parcelable {
public long mNativeObject;
private long mNativeHandle;
private SurfaceControl(


3390

被折叠的 条评论
为什么被折叠?



