3.Surface创建总结
surface的创建已经分析,从App点击启动一个MainActivity来介绍此流程
3.1 APP/WMS/SurfaceFlinger通信流程创建
App启动Main Activity:
-
首先创建好与WMS通信的媒介Session,
-
然后通过Session将Window加入到WMS中,这时会触发 SurfaceSession的创建
-
SurfaceSession的创建又会在WMS Native创建SurfaceComposerClient,
-
最终在SurfaceFlinger里创建与SurfaceComposerClient对应的Client 至此 整个通信通道
(APP(Session) -> WMS, WMS(SurfaceComposerClient) -> SurfaceFlinger(Client))
已经建立起来了
3.2 对Window进行布局(relayout)
relayout 主要是
-
创建 Jave/Native端的 SurfaceControl
-
通过 SurfaceComposerClient 通知 Client(SurfaceFlinger中)去创建 Layer, 并由SurfaceFlinger管理起来
-
SurfaceControl创建好后就开始创建真正的 native的Surface
-
App Surface通过relayout返回的parcel创建出App端的Surface
整体流程如下:
4 DrawState
在window被显示出来会经过如下几个状态:
String drawStateToString() {
switch (mDrawState) {
case NO_SURFACE: return "NO_SURFACE";
case DRAW_PENDING: return "DRAW_PENDING";
case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
case READY_TO_SHOW: return "READY_TO_SHOW";
case HAS_DRAWN: return "HAS_DRAWN";
default: return Integer.toString(mDrawState);
}
}
4.1 DRAW_PENDING
在WindowStateAnimator调用createSurfaceLocked方法创建layer的surface之前的状态,代码如下:
if (!mWin.mAppToken.isSelfAnimating()) {
mWin.mAppToken.clearAllDrawn();
} else {
// Currently animating, persist current state of allDrawn until animation
// is complete.
mWin.mAppToken.deferClearAllDrawn = true;
}
}
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
final WindowState w = mWin;
if (mSurfaceController != null) {
return mSurfaceController;
}
mChildrenDetached = false;
if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
windowType = SurfaceControl.WINDOW_TYPE_DONT_SCREENSHOT;
}
w.setHasSurface(false);
if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
"createSurface " + this + ": mDrawState=DRAW_PENDING");
resetDrawState();//设置为DRAW_PENDING的状态
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
attrs.getTitle().toString(), width, height, format, flags, this,
windowType, ownerUid);
...........
return mSurfaceController;
}
4.2 COMMIT_DRAW_PENDING
从代码逻辑看到在WindowStateAnimator的finishDrawingLocked方法中将DrawState设置为:COMMIT_DRAW_PENDING的状态
frameworks\base\services\core\java\com\android\server\wm\WindowStateAnimator.java
boolean finishDrawingLocked() { final boolean startingWindow = mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; if (DEBUG_STARTING_WINDOW && startingWindow) { Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
+ drawStateToString());
}
boolean layoutNeeded = false;
if (mDrawState == DRAW_PENDING) { if (DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + mWin + " in "
-
mSurfaceController); INDOW && startingWindow) {
Slog.v(TAG, "Draw state now committed in " + mWin); } mDrawState = COMMIT_DRAW_PENDING; layoutNeeded = true; }
return layoutNeeded;
接下来分析finishDrawingLocked方法被调用的逻辑,调用堆栈如下:
调用栈:
924 1142 V WindowManager: finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING Window{93fd5d8 u0 Splash Screen com.android.dialer} in Surface(name=Splash Screen com.android.dialer)/@0x8283a2
924 1142 V WindowManager: java.lang.Throwable
924 1142 V Wind