ViewRootImpl
的mSurface
变量指向Surface
对象,这个surface对象是硬件渲染UI时OpenGL
所使用的ANativeWindow
,本文记录了这个surface时如何创建的。
ViewRoot,WMS,SurfaceFlinger三者的binder连接。
ViewRootImpl构造时会创建到wms的连接:
public ViewRootImpl(Context context, Display display) {
mContext = context;
mWindowSession = WindowManagerGlobal.getWindowSession();
ViewRootImpl.setView里会跨进程调用wms的addwindow将当前窗口添加到wms中:
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mInputChannel);
@Override
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
Rect outOutsets, InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outStableInsets, outOutsets, outInputChannel);
}
wms.addWindow中创建WindowState,WindowState包装了client的跨进程回调接口,用来通知ViewRootIml一些消息。
WindowState win = new WindowState(this, session, client, token,
attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
......
win.attach();
WindowState.attach
void attach() {
if (WindowManagerService.localLOGV) Slog.v(
TAG, "Attaching " + this + " token=" + mToken
+ ", list=" + mToken.windows);
mSession.windowAddedLocked();
}
Session.windowAddedLocked中创建了SurfaceSession
void windowAddedLocked() {
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的构造函数中调用native方法nativeCreate中连接SurfaceFlinger
创建SurfaceComposerClient
,SurfaceFlinger中对应的BnBinder是Client。
public SurfaceSession() {
mNativeClient = nativeCreate();
}
连接是建立好了,接下来就要创建surface了
ViewRootImpl.relayoutWindow中调用windowSession的relayout。将mSurface传入函数作为outSurface。
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
......
int relayoutResult = mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration,
mSurface);
wms的relayout
会调用
result = createSurfaceControl(outSurface, result, win, winAnimator);
private int createSurfaceControl(Surface outSurface, int result, WindowState win,
WindowStateAnimator winAnimator) {
if (!win.mHasSurface) {
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked();
if (surfaceController != null) {
surfaceController.getSurface(outSurface);
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.
outSurface.release();
}
return result;
}
WindowStateAnimator.createSurfaceLocked()
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format, flags, this);
public WindowSurfaceController(SurfaceSession s,
String name, int w, int h, int format, int flags, WindowStateAnimator animator) {
mAnimator = animator;
mSurfaceW = w;
mSurfaceH = h;
title = name;
// For opaque child windows placed under parent windows,
// we use a special SurfaceControl which mirrors commands
// to a black-out layer placed one Z-layer below the surface.
// This prevents holes to whatever app/wallpaper is underneath.
if (animator.mWin.isChildWindow() &&
animator.mWin.mSubLayer < 0 &&
animator.mWin.mAppToken != null) {
mSurfaceControl = new SurfaceControlWithBackground(s,
name, w, h, format, flags, animator.mWin.mAppToken);
} else if (DEBUG_SURFACE_TRACE) {
mSurfaceControl = new SurfaceTrace(
s, name, w, h, format, flags);
} else {
mSurfaceControl = new SurfaceControl(
s, name, w, h, format, flags);
}
}
SurfaceControl的构造函数里会请求SurfaceFlinger创建surface
public SurfaceControl(SurfaceSession session,
String name, int w, int h, int format, int flags)
throws OutOfResourcesException {
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;
mNativeObject = nativeCreate(session, name, w, h, format, flags);
if (mNativeObject == 0) {
throw new OutOfResourcesException(
"Couldn't allocate SurfaceControl native object");
}
mCloseGuard.open("release");
}
SurfaceControl.nativeCreate
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags) {
ScopedUtfChars name(env, nameStr);
sp client(android_view_SurfaceSession_getClient(env, sessionObj));
sp surface = client->createSurface(
String8(name.c_str()), w, h, format, flags);
if (surface == NULL) {
jniThrowException(env, OutOfResourcesException, NULL);
return 0;
}
surface->incStrong((void *)nativeCreate);
return reinterpret_cast(surface.get());
}
具体SurfaceFlinger怎么创建surface的,可以参考这篇文章
简单来说,就是在SurfaceFlinger中创建了Layer对象
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp* handle,
sp* gbp)
{
/*
* createSurface must be called from the GL thread so that it can
* have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client* client;
sp* handle;
sp* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp* handle,
sp* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp), result(NO_ERROR),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
};
sp msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast( msg.get() )->getResult();
}
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp* handle, sp* gbp)
{
......
result = createNormalLayer(client,
name, w, h, flags, format,
handle, gbp, &layer);
break;
.......
}
status_t SurfaceFlinger::createNormalLayer(const sp& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
sp* handle, sp* gbp, sp* outLayer)
{
*outLayer = new Layer(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getProducer();
}
}
Layer对象其实是包装了IGraphicBufferProducer
和IGraphicBufferConsumer
,consumer应该是指SurfaceFlinger,producer会传到应用那边,作为UI图像的生产者。
void Layer::onFirstRef() {
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp producer;
sp consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new MonitoredProducer(producer, mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
mProducer->setMaxDequeuedBufferCount(2);
}
sp Layer::getHandle() {
Mutex::Autolock _l(mLock);
LOG_ALWAYS_FATAL_IF(mHasSurface,
"Layer::getHandle() has already been called");
mHasSurface = true;
return new Handle(mFlinger, this);
}
sp Layer::getProducer() const {
return mProducer;
}
SurfaceControl包装了handle和gbp
sp SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
....
sur = new SurfaceControl(this, handle, gbp);
.....
return sur;
}
回到wms的relayout中,WindowSurfaceController会调用getSurface去填充outSurface。
WindowSurfaceController.getSurface
void getSurface(Surface outSurface) {
outSurface.copyFrom(mSurfaceControl);
}
Surface.java
public void copyFrom(SurfaceControl other) {
....
long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
synchronized (mLock) {
if (mNativeObject != 0) {
nativeRelease(mNativeObject);
}
setNativeObjectLocked(newNativeObject);
}
}
nativeCreateFromSurfaceControl将SurfaceControl中的surface拷贝到Surface中。这样ViewRootImpl就拥有了自己的Surface。
static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
jlong surfaceControlNativeObj) {
sp ctrl(reinterpret_cast(surfaceControlNativeObj));
sp surface(ctrl->getSurface());
if (surface != NULL) {
surface->incStrong(&sRefBaseOwner);
}
return reinterpret_cast(surface.get());
}
sp SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = new Surface(mGraphicBufferProducer, false);
}
return mSurfaceData;
}
另外一个有趣的地方是,虽然ViewRoot的Surface和WMS的Surface在两个进程,所以这两个Surface是两个完全不同的东西。Surface在序列化传输时是吧GraphicBufferProducer这个binder进行序列化传输了。