写在前面
Surface
是整个 Android 显示框架中最重要也是最基础的一个概念,它承担着 App UI 的显示需求,App 需要展示的 UI 都必须要画到这个 Surface
上才能被显示出来。通过学习本章内容,你会了解:
- 什么是
Surface
- App 是如何获取
Surface
Surface
/SurfaceControl
/Layer
这些基本概念的区别与联系
什么是 Surface
我们知道 App 的 UI 最终都是通过 SurfaceFlinger
合成之后,然后提交给 Display 进行显示。而 Surface
就是 App
和 SurfaceFlinger
之间的桥梁。 我们从源码的角度来分析 Surface
arduino
// frameworks/native/libs/gui/include/gui/Surface.h
class Surface
: public ANativeObjectBase<ANativeWindow, Surface, RefBase>
{
sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
...
virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd);
...
}
getIGraphicBufferProducer :从名字可以看出,这个变量是 GraphicBuffer
的生产者 。GraphicBuffer
是什么呢? GraphicBuffer
代表着一块可以被 CPU/GPU 访问的图像缓冲区。App 可以通过第三方渲染引擎,如 OpenGL/SKia 等, 把 UI 渲染到这个一块缓冲区。GraphicBuffer
后面会单独拿一下小节讲解。
dequeueBuffer : 通过 dequeueBuffer 可以从 Buffer Queue 中获取一块 GraphicBuffer
,用于 App 进行渲染。
queueBuffer :通过 queueBuffer 可以把渲染好的 GraphicBuffer 提交到 Buffer Queue 中,然后再提交给 SurfaceFlinger
进行合成,最终提交到 Display 进行显示。
那么 Buffer Queue 是由谁管理的呢? 为什么 Surface 的 dequeueBuffer/queueBuffer
就能从 Buffer Queue 中获取 Buffer 呢?实际上 Buffer Queue 管理以及 dequeueBuffer/queueBuffer
的实现都是由 BLASTBufferQueue
实现的,这个后面会单独拿一个小节来说。
那么 Surface 是什么时候被创建的呢?Surface 是运行在哪个进程?
Surface/SurfaceControl/Layer 创建
Surface 的创建是在 Activity 的 ViewRootImpl
进行 performTraversal
(至于什么时候进行 performTraversal
,后面会具体分析,先说结论:当 Vsync
来的时候,Activity 的 ViewRootImpl
会进行 performTraversal
) 时候。
csharp
// frameworks/base/core/java/android/view/ViewRootImpl.java
private void performTraversals() {
...
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
...
}
csharp
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,boolean insetsPending){
...
relayoutResult = mWindowSession.relayout(mWindow, params,
requestedWidth, requestedHeight, viewVisibility,
insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mRelayoutSeq, mLastSyncSeqId, mRelayoutResult);
...
}
其中 mRelayoutResult
包含了一个重要的参数 mSurfaceControl
,这里留意一下,后面会具体说到这个 mSurfaceControl
。
mWindowSession
是一个 AIDL 接口, 所以 mWindowSession.relayout
是一个跨进程的方法,它的实现在另外一个进程中(WMS 所在的进程)
java
// frameworks/base/services/core/java/com/android/server/wm/Session.java
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
int lastSyncSeqId, WindowRelayoutResult outRelayoutResult) {
int res = mService.relayoutWindow(this, window, attrs, requestedWidth,
requestedHeight, viewFlags, flags, seq, lastSyncSeqId, outRelayoutResult);
return res;
}
这里的 mService 指的就是 WindowServiceManager
, 所以 App 进程中通过 mWindowSession.relayout
最终通过跨进程调用到了 WindowManagerService
的 relayoutWindow
java
// frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
int lastSyncSeqId, WindowRelayoutResult outRelayoutResult) {
final ClientWindowFrames outFrames;
final MergedConfiguration outMergedConfiguration;
final SurfaceControl outSurfaceControl;
final InsetsState outInsetsState;
final InsetsSourceControl.Array outActiveControls;
if (outRelayoutResult != null) {
...
把 SurfaceControl 从 WindowRelayoutResult 拿出来
outSurfaceControl = outRelayoutResult.surfaceControl;
...
}
// 创建一个 SurfaceControl
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
...
}
SurfaceControl 创建
csharp
// frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
WindowState win, WindowStateAnimator winAnimator) {
SurfaceControl surfaceControl;
try {
surfaceControl = winAnimator.createSurfaceLocked();
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
if (surfaceControl != null) {
winAnimator.getSurfaceControl(outSurfaceControl);
ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);
}
...
}
在 createSurfaceControl
中
WindowStateAnimator.createSurfaceLocked
创建一个surfaceControl
(这里其实可以猜到Surface
和SurfaceControl
的关系很暧昧了,明明是创建一个SurfaceControl
, 但是方法名却是createSurfaceLocked
)- 把创建的
SurfaceControl
通过getSurfaceControl
copy 给outSurfaceControl
, 这个outSurfaceControl
也就是在RootViewImpl
创建并作为参数传过来的 WMS的SurfaceControl
。所以把创建好的 SurfaceControl copy 给 outSurfaceControl, 也就是把这个的SurfaceControl
返回给了RootViewImpl
所持有
接下来继续分析 WindowStateAnimator.createSurfaceLocked
scss
// frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
SurfaceControl createSurfaceLocked() {
...
mSurfaceControl = mWin.makeSurface()
.setParent(mWin.mSurfaceControl)
.setName(mTitle)
.setFormat(format)
.setFlags(flags)
.setMetadata(METADATA_WINDOW_TYPE, attrs.type)
.setMetadata(METADATA_OWNER_UID, mSession.mUid)
.setMetadata(METADATA_OWNER_PID, mSession.mPid)
.setCallsite("WindowSurfaceController")
.setBLASTLayer().build();
...
}
这里会对 SurfaceControl
做一些参数设置, 然后会调用 SurfaceControl.Builder
的 build
来构建 SurfaceControl
csharp
// frameworks/base/core/java/android/view/SurfaceControl.java
public SurfaceControl build() {
...
return new SurfaceControl(
mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata, mLocalOwnerView, mCallsite);
}
这里会调用 SurfaceControl
的带参构造函数
csharp
// frameworks/base/core/java/android/view/SurfaceControl.java
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
...
nativeObject = nativeCreate(session, name, w, h, format, flags,
parent != null ? parent.mNativeObject : 0, metaParcel);
...
}
nativeCreate
是一个 JNI 方法,继续来看在 native 的实现
kotlin
// frameworks/base/core/jni/android_view_SurfaceControl.cpp
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;
sp<SurfaceControl> surface;
...
status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
flags, parentHandle, std::move(metadata));
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
}
SurfaceComposerClient->createSurfaceChecked
c
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
PixelFormat format,
sp<SurfaceControl>* outSurface, int32_t flags,
const sp<IBinder>& parentHandle,
LayerMetadata metadata,
uint32_t* outTransformHint) {
...
gui::CreateSurfaceResult result;
// 跨进程调用 createSurface
binder::Status status = mClient->createSurface(std::string(name.c_str()), flags,
parentHandle, std::move(metadata), &result);
...
// 最终创建了 C++ 层的 SurfaceControl
*outSurface = sp<SurfaceControl>::make(this, result.handle, result.layerId,
toString(result.layerName), w, h, format,
result.transformHint, flags);
}
return err;
}
mClient
是ISurfaceComposerClient
接口的 Binder 客户端代理对象,所以mClient->createSurface
是一个 Binder call,它的服务端实现在 SurfaceFlinger 所运行的进程。 所以Create Surface
由WMS
所在进程跑到了SurfaceFlinger
所在的进程。SurfaceControl
的构造函数可以看出,SurfaceControl
的主要成员变量由CreateSurfaceResult
提供,比如CreateSurfaceResult.handle
,CreateSurfaceResult.layerId
等,通过mClient->createSurface
创建完成之后,最终创建了 C++ 层的SurfaceControl
,并返回给 Java 层。所以这里重点关注mClient->createSurface
的实现。
Layer 创建
rust
binder::Status Client::createSurface(const std::string& name, int32_t flags,
const sp<IBinder>& parent, const gui::LayerMetadata& metadata,
gui::CreateSurfaceResult* outResult) {
...
const status_t status = mFlinger->createLayer(args, *outResult);
return binderStatusFromStatusT(status);
}
这里的 mFlinger
指的就是 SurfaceFlinger
ini
status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurfaceResult& outResult) {
status_t result = NO_ERROR;
// 声明一个 Layer
sp<Layer> layer;
switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
...
// 创建一块 Layer
result = createBufferStateLayer(args, &outResult.handle, &layer);
} break;
}
...
outResult.transformHint = static_cast<int32_t>(outTransformHint);
outResult.layerId = layer->sequence;
outResult.layerName = String16(layer->getDebugName());
return result;
}
这里我们重点看一下 createBufferStateLayer
的实现
scss
status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle,
sp<Layer>* outLayer) {
// getFactory() 返回的是 DefaultFactory
*outLayer = getFactory().createBufferStateLayer(args);
// 把 Layer Handle 交给 outResult.handle,也就是 CreateSurfaceResult.handle
// CreateSurfaceResult.handle 最终会作为 SurfaceControl 构造函数的参数传递给 SurfaceControl
*handle = (*outLayer)->getHandle();
}
sp<Layer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
return sp<Layer>::make(args);
}
这里总结一下:
Client::createSurface
最终会在 SurfaceFlinger 这边创建一块 Layer 对象- 把
LayerHandle
赋给CreateSurfaceResult.handle
,最终传给SurfaceControl
LayerHandle
是什么呢?LayerHandle
本质上是一个BBinder
,提供了getLayer
等实现
arduino
class LayerHandle : public BBinder {
public:
LayerHandle(const sp<android::SurfaceFlinger>& flinger, const sp<android::Layer>& layer);
static sp<LayerHandle> fromIBinder(const sp<IBinder>& handle);
static sp<android::Layer> getLayer(const sp<IBinder>& handle);
static uint32_t getLayerId(const sp<IBinder>& handle);
...
private:
sp<android::SurfaceFlinger> mFlinger;
sp<android::Layer> mLayer;
const uint32_t mLayerId;
};
所以到这里,关于 SurfaceControl
和 Layer
的联系就很清晰了
SurfaceControl
和 Layer
是一一对应的关系,并且 SurfaceControl
间接持有 Layer
,这意味着 SurfaceControl
能够控制 Layer
。
到目前为止,SurfaceControl
和 Layer
的创建就已经完成了,但是今天的主角 Surface
并没有实际创建出来(我这里说的 Surface 指的是 C++ 层的 Surface,而不是 Java 层的 Surface), Surface 的真正创建发生在updateBlastSurfaceIfNeeded
Surface 创建
arduino
// frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
int lastSyncSeqId, WindowRelayoutResult outRelayoutResult) {
// 创建 SurfaceControl
result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
...
updateBlastSurfaceIfNeeded();
...
}
ini
void updateBlastSurfaceIfNeeded() {
...
blastSurface = mBlastBufferQueue.createSurface();
...
mSurface.transferFrom(blastSurface);
}
mBlastBufferQueue 是 BLASTBufferQueue
,关于 BLASTBufferQueue
可以参考鄙人另外一篇文章,这里只做简单的介绍:
BLASTBufferQueue 由 "Producer" + "Comsumer" + BufferQueueCore,
- Producer 申请
GraphicBuffer
,绘制 UI 到GraphicBuffer
; - Comsumer 可以消费
GraphicBuffer
,并且把GraphicBuffer
提交到SurfaceFlinger
- BufferQueueCore 队列负责管理 GraphicBuffer 在 Producer 和 Comsumer 之间的移动。
通过 BLASTBufferQueue
的 createSurface
来创建一个 blastSurface
,然后把这个 blastSurface
赋给 ViewRootImpl
的 mSurface
。接下来我们分析 BLASTBufferQueue.createSurface
的实现
kotlin
// frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java
public Surface createSurface() {
// nativeGetSurface 是一个 native 方法
return nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */);
}
// frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
static jobject nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr,
jboolean includeSurfaceControlHandle) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
return android_view_Surface_createFromSurface(env,
queue->getSurface(includeSurfaceControlHandle));
}
这里最终会调用 BLASTBufferQueue.cpp
的 getSurface
方法
arduino
sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
std::lock_guard _lock{mMutex};
sp<IBinder> scHandle = nullptr;
if (includeSurfaceControlHandle && mSurfaceControl) {
// scHandle 指的就是 LayerHandle
scHandle = mSurfaceControl->getHandle();
}
return sp<BBQSurface>::make(mProducer, true, scHandle, this);
}
- 在这里真正创建了
BBQSurface
,BBQSurface
是Surface
的子类,并且把BLASTBufferQueue
的mProducer
作为构造函数的参数传给了BBQSurface/Surface
,这就意味着BBQSurface/Surface
能通过mProducer
来申请GraphicBuffer
来进行绘制,并把绘制好的 Buffer 插入BLASTBufferQueue
,由 Comsumer 进行消费 - 从代码里面也可以看出 Surface 和 SurfaceControl 以及 Layer 之间的关系: Surface 通过 SurfaceControl 间接持有 Layer
到这里 native
层的 Surface
终于创建完成了, 并返回给 ViewRootImpl
。