前言
前面几章主要阐述了窗口相关数据结构的创建,窗口的大小的计算,布局等等问题;本章主要学习与Surface相关的一些代码,Surface与窗口的显示息息相关
Surface创建相关逻辑
Android Surface的创建涉及三个进程
1.App 进程
Surface本质上是一个Native Window, 并且保存着需要在屏幕上显示的数据(buffer), 它通常包含 triple-buffers 以防止Jank。
那么谁要创建Surface呢? 当然是App了,App需要将自己的内容显示在屏幕上,所以App负责发起Surface创建请求,创建好Surface后, 就可以直接可以在canvas上画图等,最终都会保存到Surface里的buffer里,最后由SurfaceFlinger合成并显示。
2.System_Server进程
主要是其中的WindowManagerService, 负责接收APP请求,向SurfaceFlinger发起具体的请求创建Surface, 且WMS需要创建Surface的辅助管理类,如SurfaceControl(与Window一一对应)。
为什么需要与system进程打交道呢?App直接通知SurfaceFlinger创建Surface不就行了?为什么还需要通过system进程呢?个人猜想可能是统一由WMS管理,以及当前系统中的窗口的Z -order计算, 减轻SurfaceFlinger的负担。
3.SurfaceFlinger
为App进程创建具体的Surface, 在SurfaceFlinger里对应成Layer, 然后负责管理、合成显示。
前面说到会在WMS的relayoutWindow调用createSurfaceControl
system_server端的SurfaceControl(java和native)
WindowManagerService#createSurfaceControl
创建windowState对应的SurfaceControl
private int createSurfaceControl(Surface outSurface, int result, WindowState win,
WindowStateAnimator winAnimator) {
if (!win.mHasSurface) {
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
WindowSurfaceController surfaceController;
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
//SurfaceControl: 用于创建、获取、设置Surface
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
if (surfaceController != null) {
//进行copy
surfaceController.getSurface(outSurface); //outSurface赋值为win.mWinAnimator.mSurfaceController.mSurfaceControl
if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurface + ": copied");
} else {
// For some reason there isn't a surface. Clear the
// caller's object so they see the same state.
Slog.w(TAG_WM, "Failed to create surface control for " + win);
outSurface.release();
}
return result;
}
WindowStateAnimator#createSurfaceLocked
创建WindowSurfaceController
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();
mService.makeWindowFreezingScreenIfNeededLocked(w);
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
if (mService.isSecureLocked(w)) {
flags |= SurfaceControl.SECURE;
}
mTmpSize.set(0, 0, 0, 0);
calculateSurfaceBounds(w, attrs);
final int width = mTmpSize.width();
final int height = mTmpSize.height();
if (DEBUG_VISIBILITY) {
Slog.v(TAG, "Creating surface in session "
+ mSession.mSurfaceSession + " window " + this
+ " w=" + width + " h=" + height
+ " x=" + mTmpSize.left + " y=" + mTmpSize.top
+ " format=" + attrs.format + " flags=" + flags);
}
// We may abort, so initialize to defaults.
mLastClipRect.set(0, 0, 0, 0);
// Set up surface control with initial size.
try {
final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
if (!PixelFormat.formatHasAlpha(attrs.format)
// Don't make surface with surfaceInsets opaque as they display a
// translucent shadow.
&& attrs.surfaceInsets.left == 0
&& attrs.surfaceInsets.top == 0
&& attrs.surfaceInsets.right == 0
&& attrs.surfaceInsets.bottom == 0
// Don't make surface opaque when resizing to reduce the amount of
// artifacts shown in areas the app isn't drawing content to.
&& !w.isDragResizing()) {
flags |= SurfaceControl.OPAQUE;
}
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
attrs.getTitle().toString(), width, height, format, flags, this,
windowType, ownerUid); //调用WindowSurfaceController构造函数,为mSurfaceControl赋值
setOffsetPositionForStackResize(false);
mSurfaceFormat = format;
w.setHasSurface(true); //将WindowState的mHasSurface置为true
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
Slog.i(TAG, " CREATE SURFACE "
+ mSurfaceController + " IN SESSION "
+ mSession.mSurfaceSession
+ ": pid=" + mSession.mPid + " format="
+ attrs.format + " flags=0x"
+ Integer.toHexString(flags)
+ " / " + this);
}
} catch (OutOfResourcesException e) {
Slog.w(TAG, "OutOfResourcesException creating surface");
mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
mDrawState = NO_SURFACE;
return null;
} catch (Exception e) {
Slog.e(TAG, "Exception creating surface (parent dead?)", e);
mDrawState = NO_SURFACE;
return null;
}
if (WindowManagerService.localLOGV) Slog.v(TAG, "Got surface: " + mSurfaceController
+ ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
+ ", animLayer=" + mAnimLayer);
if (SHOW_LIGHT_TRANSACTIONS) {
Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
WindowManagerService.logSurface(w, "CREATE pos=("
+ w.mFrame.left + "," + w.mFrame.top + ") ("
+ width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
}
mLastHidden = true;
if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
return mSurfaceController; //返回WindowSurfaceController对象 (win.mWinAnimator.mSurfaceController)
}
WindowSurfaceController构造函数
public WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format,
int flags, WindowStateAnimator animator, int windowType, int ownerUid) {
mAnimator = animator;
mSurfaceW = w;
mSurfaceH = h;
title = name;
mService = animator.mService;
final WindowState win = animator.mWin;
mWindowType = windowType;
mWindowSession = win.mSession;
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
final SurfaceControl.Builder b = win.makeSurface()
.setParent(win.getSurfaceControl())
.setName(name)
.setSize(w, h)
.setFormat(format)
.setFlags(flags)
.setMetadata(windowType, ownerUid);
mSurfaceControl = b.build();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
创建java层的SurfaceControl,此时进程相应的SurfaceSession已经创建完毕
SurfaceControl$Builder#build
/**
* Builder class for {@link SurfaceControl} objects.
*/
public static class Builder {
private SurfaceSession mSession;
private int mFlags = HIDDEN;
private int mWidth;
private int mHeight;
private int mFormat = PixelFormat.OPAQUE;
private String mName;
private SurfaceControl mParent;
private int mWindowType = -1;
private int mOwnerUid = -1;
/**
* Begin building a SurfaceControl with a given {@link SurfaceSession}.
*
* @param session The {@link SurfaceSession} with which to eventually construct the surface.
*/
public Builder(SurfaceSession session) {
mSession = session;
}
/**
* Construct a new {@link SurfaceControl} with the set parameters.
*/
public SurfaceControl build() {
if (mWidth <= 0 || mHeight <= 0) {
throw new IllegalArgumentException(
"width and height must be set");
}
return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat,
mFlags, mParent, mWindowType, mOwnerUid);
//java层创建SurfaceControl
}
SurfaceControl#SurfaceControl
/**
* Create a surface with a name.
* <p>
* The surface creation flags specify what kind of surface to create and
* certain options such as whether the surface can be assumed to be opaque
* and whether it should be initially hidden. Surfaces should always be
* created with the {@link #HIDDEN} flag set to ensure that they are not
* made visible prematurely before all of the surface's properties have been
* configured.
* <p>
* Good practice is to first create the surface with the {@link #HIDDEN} flag
* specified, open a transaction, set the surface layer, layer stack, alpha,
* and position, call {@link #show} if appropriate, and close the transaction.
*
* @param session The surface session, must not be null.
* @param name The surface name, must not be null.
* @param w The surface initial width.
* @param h The surface initial height.
* @param flags The surface creation flags. Should always include {@link #HIDDEN}
* in the creation flags.
* @param windowType The type of the window as specified in WindowManager.java.
* @param ownerUid A unique per-app ID.
*
* @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
*/
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
SurfaceControl parent, int windowType, int ownerUid)
throws OutOfResourcesException, IllegalArgumentException {
if (session == null) {
throw new IllegalArgumentException("session must not be null");
}
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
if ((flags & SurfaceControl.HIDDEN) == 0) {
Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
+ "to ensure that they are not made visible prematurely before "
+ "all of the surface's properties have been configured. "
+ "Set the other properties and make the surface visible within "
+ "a transaction. New surface name: " + name,
new Throwable());
}
mName = name;
mWidth = w;
mHeight = h;
mNativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, windowType, ownerUid); //mNativeObject 指向native层的SurfaceControl
if (mNativeObject == 0) {
throw new OutOfResourcesException(
"Couldn't allocate SurfaceControl native object");
}
mCloseGuard.open("release");
}
进入JNI,创建native层的SurfaceControl
android_view_SurfaceControl#nativeCreate
SurfaceControl中的client为SurfaceComposerClient
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
jint windowType, jint ownerUid) {
ScopedUtfChars name(env, nameStr);
sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
sp<SurfaceControl> surface;
status_t err = client->createSurfaceChecked(
String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid); //此时创建好了SurfaceFlinger中的surface以及WMS中对应的SurfaceControl
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());
}
返回的是native的SurfaceControl的指针;其创建时通过调用client(SurfaceComposerClient)的createSurfaceChecked进行创建的;
SurfaceComposerClient的创建流程
android_view_SurfaceSession_getClient 这里关系到SurfaceSession类;首先在WindowManagerService#addWindow中会调用win.attach();则其在相应窗口走到performTraversals的relayoutWindow之前,说明先创建SurfaceSession(与进程对应),再创建Window对应的SurfaceControl
WindowState#attach
void attach() {
if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
mSession.windowAddedLocked(mAttrs.packageName);
}
Session#windowAddedLocked
void windowAddedLocked(String packageName) {
mPackageName = packageName;
mRelayoutTag = "relayoutWindow: " + mPackageName;
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
TAG_WM, "First window added to " + this + ", creating SurfaceSession");
mSurfaceSession = new SurfaceSession();
if (SHOW_TRANSACTIONS) Slog.i(
TAG_WM, " NEW SURFACE SESSION " + mSurfaceSession);
mService.mSessions.add(this);
if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
mService.dispatchNewAnimatorScaleLocked(this);
}
}
mNumWindow++;
}
创建SurfaceSession
/** Create a new connection with the surface flinger. */
public SurfaceSession() {
mNativeClient = nativeCreate(); //创建SurfaceComposerClient对象,并将其JNI对象地址保存到mNativeClient中
}
java层的SurfaceSession;保存了jni层创建的SurfaceComposerClient的地址
android_view_SurfaceSeesion#nativeCreate
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient(); //创建SurfaceComposerClient(与进程对应)
client->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(client);
}
SurfaceComposerClient的构造函数
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT)
{
}
所以前面android_view_SurfaceControl中的client就是sp<SurfaceComposerClient>
创建native SurfaceControl
SurfaceComposerClient::createSurfaceChecked
status_t SurfaceComposerClient::createSurfaceChecked(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
sp<SurfaceControl>* outSurface,
uint32_t flags,
SurfaceControl* parent,
int32_t windowType,
int32_t ownerUid)
{
sp<SurfaceControl> sur;
status_t err = mStatus;
if (mStatus == NO_ERROR) {
sp<IBinder> handle;
sp<IBinder> parentHandle;
sp<IGraphicBufferProducer> gbp;
if (parent != nullptr) {
parentHandle = parent->getHandle();
}
err = mClient->createSurface(name, w, h, format, flags, parentHandle,
windowType, ownerUid, &handle, &gbp); //可见这里是调用SurfaceFlinger进程中的Client的createSurface,创建Surface;并返回SurfaceFlinger中的Handle以及IGraphicsBufferProducer的代理
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */); //native层创建SurfaceControl
//当SurfaceFlinger中创建好Surface后,在WMS的JNI层创建一个SurfaceControl, SurfaceControl顾名思义就是控制、操作Surface的类
}
}
return err;
}