
Android Surface创建
Surface的创建是Android图形渲染链路中最核心的跨进程协同环节,涉及应用进程(Java层)、SystemServer进程(WMS,Java层)、SurfaceFlinger进程(C++层)三方交互,且整个流程是"Java层封装调用 + C++层核心实现"的典型分层架构。
本文将以源码级视角,拆解Surface创建的完整步骤,并逐一解析Java层与C++层的具体实现逻辑。
前置核心认知
在拆解流程前,需明确Surface创建涉及的核心组件及其分层实现,这是理解Java/C++交互的关键:
| 层级 | 核心组件 | 语言 | 核心作用 |
|---|---|---|---|
| 应用进程-Java | ViewRootImpl、Surface、Session | Java | 发起Surface申请,接收并封装SurfaceFlinger返回的Producer端 |
| SystemServer-Java | WMS(WindowManagerService)、SurfaceControl | Java | 校验窗口属性,转发Surface创建请求至SurfaceFlinger |
| SurfaceFlinger-C++ | SurfaceFlinger、BufferQueue、Layer、IGraphicBufferProducer | C++ | 创建BufferQueue/显存缓冲区,生成Producer端,是Surface的核心实现层 |
| 跨进程通信 | Binder(IWindowSession、ISurfaceComposer、IGraphicBufferProducer) | 混合 | Java层通过AIDL生成Binder代理,C++层通过Binder接口实现跨进程调用 |
核心结论:Java层仅负责"发起请求"和"封装结果",Surface的核心创建逻辑(BufferQueue、显存管理、Producer/Consumer构建)全部在C++层的SurfaceFlinger中实现。
Surface创建全流程拆解
Surface创建的核心链路为:应用进程Java层 → SystemServer(WMS)Java层 → SurfaceFlinger C++层 → WMS Java层 → 应用进程Java层,共5个核心步骤,以下逐步骤解析。
步骤1:应用进程Java层发起Surface申请(ViewRootImpl → WMS)
触发时机
ViewRootImpl在performTraversals方法中(View绘制总入口),检测到当前Window无可用Surface时,触发relayoutWindow请求------这是应用侧发起Surface创建的起点。
Java层实现细节
-
ViewRootImpl封装请求参数
ViewRootImpl构建
WindowManager.LayoutParams(窗口尺寸、类型、Z轴层级等),调用mWindowSession.relayout()方法,核心代码片段:java// ViewRootImpl.java private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, ...) { // 1. 封装请求参数:是否需要创建Surface、窗口尺寸、像素格式等 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, mSurfaceControl); // 关键:SurfaceControl用于接收结果 // 2. 若返回SurfaceControl非空,初始化应用侧Surface if (mSurfaceControl != null && mSurfaceControl.isValid()) { mSurface = new Surface(mSurfaceControl); // 绑定Producer端 } return relayoutResult; }mWindowSession:是IWindowSession的Binder代理对象(应用进程→WMS的通信通道),由WMS创建并返回。mSurfaceControl:空对象传入,用于接收WMS返回的、包含Producer端的SurfaceControl实例。
-
Binder跨进程调用WMS
IWindowSession是AIDL生成的接口,应用进程的Session.relayout()会通过Binder触发SystemServer进程中WMS的Session.relayout()方法,核心AIDL定义:aidl// IWindowSession.aidl interface IWindowSession { int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, out Rect outFrame, ..., out SurfaceControl outSurfaceControl); }
步骤2:SystemServer进程(WMS)Java层处理请求
WMS接收到应用的relayout请求后,先校验窗口合法性,再通过Native层接口向SurfaceFlinger发起Surface创建请求。
步骤2.1:WMS校验与参数预处理(Java层)
java
// WindowManagerService.java
@Override
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, ..., SurfaceControl outSurfaceControl) {
// 1. 校验窗口权限、令牌(WindowToken)、尺寸等合法性
WindowState win = windowForClientLocked(session, window, false);
if (win == null) throw new IllegalArgumentException("Invalid window");
// 2. 若需要创建Surface,调用WindowState的relayout方法
int res = win.relayout(attrs, requestedWidth, requestedHeight, viewVisibility, flags, ...);
// 3. 将SurfaceFlinger返回的SurfaceControl写入out参数,透传给应用进程
if (win.mSurfaceControl != null) {
outSurfaceControl.copyFrom(win.mSurfaceControl);
}
return res;
}
WindowState:WMS中每个Window的封装对象,存储窗口属性和SurfaceControl引用。- 核心逻辑:WMS不直接创建Surface,仅做"权限校验 + 参数转发"。
步骤2.2:WMS通过SurfaceControl调用Native层(Java→C++)
WMS的WindowState.relayout()最终调用SurfaceControl.createSurface(),这是Java层触达SurfaceFlinger C++层的关键:
java
// SurfaceControl.java (SystemServer进程)
public static SurfaceControl createSurface(Session session, String name, int width, int height,
int format, int flags, SurfaceControl parent, int zOrder) {
// 调用Native层方法,向SurfaceFlinger发起创建请求
long ptr = nativeCreateSurface(session.mNativeClient, name, width, height, format, flags,
parent != null ? parent.mNativeObject : 0, zOrder);
return new SurfaceControl(session, ptr);
}
nativeCreateSurface:JNI方法,对应C++层的android_view_SurfaceControl_nativeCreateSurface。session.mNativeClient:是SurfaceComposerClient(C++)的指针,WMS通过它与SurfaceFlinger通信。
步骤2.3:WMS Native层转发请求(C++)
JNI方法最终调用SurfaceComposerClient::createSurface,向SurfaceFlinger发起跨进程请求:
cpp
// SurfaceComposerClient.cpp (SystemServer进程Native层)
sp<SurfaceControl> SurfaceComposerClient::createSurface(
const String8& name, uint32_t width, uint32_t height, PixelFormat format, uint32_t flags) {
// 1. 获取ISurfaceComposer接口(SurfaceFlinger的Binder代理)
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
// 2. 向SurfaceFlinger发起createSurface请求
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp; // 核心:Producer端
status_t err = sf->createSurface(name, width, height, format, flags, &handle, &gbp);
// 3. 封装为SurfaceControl(Native层),返回给Java层
return new SurfaceControl(this, handle, gbp);
}
ISurfaceComposer:SurfaceFlinger的C++ Binder接口,是SystemServer→SurfaceFlinger的通信核心。IGraphicBufferProducer:Surface的核心Producer端接口,由SurfaceFlinger创建并返回。
步骤3:SurfaceFlinger进程C++层创建Surface核心对象
这是Surface创建的"核心实现层",SurfaceFlinger接收请求后,创建BufferQueue、Layer、GraphicBuffer等核心对象,并生成Producer端。
步骤3.1:SurfaceFlinger接收createSurface请求
cpp
// SurfaceFlinger.cpp
status_t SurfaceFlinger::createSurface(
const String8& name, uint32_t width, uint32_t height, PixelFormat format,
uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) {
// 1. 校验权限(如是否允许创建窗口Surface)
if (!checkPermission()) return PERMISSION_DENIED;
// 2. 创建Layer(每个Surface对应一个Layer,管理Z轴、透明度、显存等)
sp<Layer> layer = createLayer(name, width, height, format, flags);
// 3. 获取Layer的Producer端(IGraphicBufferProducer)
*gbp = layer->getProducer();
*handle = layer->getHandle();
return NO_ERROR;
}
Layer:SurfaceFlinger中对Surface的抽象,每个Window的Surface对应一个Layer,负责管理BufferQueue、Z轴层级、合成属性等。- 关键:
Layer的创建是SurfaceFlinger的核心逻辑,包含BufferQueue的初始化。
步骤3.2:创建BufferQueue(显存缓冲区队列)
Layer的构造函数中会创建BufferQueue,这是Surface的"显存调度中枢":
cpp
// Layer.cpp
Layer::Layer(SurfaceFlinger* flinger, const String8& name) : mFlinger(flinger) {
// 1. 创建BufferQueue:分离Producer和Consumer端
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer); // 核心:创建双端队列
// 2. 初始化Consumer端(SurfaceFlinger自身作为Consumer)
mConsumer = new BufferLayerConsumer(consumer, mTextureName);
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
mConsumer->setDefaultBufferSize(width, height);
mConsumer->setDefaultBufferFormat(format);
// 3. 保存Producer端,供返回给应用进程
mProducer = producer;
// 4. 初始化GraphicBufferAllocator(显存分配器)
mGraphicBufferAllocator = new GraphicBufferAllocator();
}
BufferQueue::createBufferQueue:创建生产者(Producer)和消费者(Consumer),默认维护2~3个GraphicBuffer(双/三重缓冲)。GraphicBufferAllocator:负责分配物理显存(Ashmem共享内存),避免CPU/GPU数据拷贝。
步骤3.3:封装Producer端为Binder对象
SurfaceFlinger将IGraphicBufferProducer(Producer端)封装为Binder代理对象,通过createSurface的返回值传递给WMS的Native层:
IGraphicBufferProducer是C++ Binder接口,继承自IBinder,支持跨进程传递。- 应用进程最终拿到的是该接口的Binder代理,而非实际对象(跨进程通信核心)。
步骤4:SurfaceFlinger返回结果,经WMS透传至应用进程
步骤4.1:WMS接收并封装结果(C++→Java)
- SurfaceFlinger将
IGraphicBufferProducer(Producer)和Layer的Handle返回给WMS的SurfaceComposerClient; - Native层
SurfaceControl封装Producer和Handle,通过JNI返回给WMS的Java层SurfaceControl; - WMS将Java层
SurfaceControl通过relayout的outSurfaceControl参数,透传给应用进程的ViewRootImpl。
步骤4.2:应用进程接收SurfaceControl(Java层)
ViewRootImpl接收到WMS返回的SurfaceControl后,初始化应用侧的Surface对象:
java
// ViewRootImpl.java
mSurface = new Surface(mSurfaceControl);
步骤5:应用进程初始化Surface(Java+C++)
应用进程的Surface(Java层)是对Native层Surface(C++)的封装,核心是绑定Producer端。
步骤5.1:Java层Surface构造
java
// Surface.java (应用进程)
public Surface(SurfaceControl surfaceControl) {
// 调用Native方法,绑定SurfaceControl中的Producer端
mNativeObject = nativeCreateFromSurfaceControl(surfaceControl);
mCloseGuard.open("release");
}
步骤5.2:Native层Surface封装Producer端(C++)
JNI方法nativeCreateFromSurfaceControl最终创建应用进程Native层的Surface对象,绑定Producer端:
cpp
// Surface.cpp (应用进程Native层)
sp<Surface> Surface::createFromSurfaceControl(const sp<SurfaceControl>& sc) {
// 1. 从SurfaceControl中取出IGraphicBufferProducer(Producer端)
sp<IGraphicBufferProducer> gbp = sc->getIGraphicBufferProducer();
// 2. 创建应用侧Native层Surface,绑定Producer
return new Surface(gbp);
}
// Surface构造函数:持有Producer端,为后续绘制做准备
Surface::Surface(const sp<IGraphicBufferProducer>& gbp) : mGraphicBufferProducer(gbp) {
// 初始化BufferQueue相关参数(如缓冲区数量、像素格式)
mGraphicBufferProducer->connect(new BufferProducerListener(this), NATIVE_WINDOW_API_CPU);
}
- 至此,应用进程的Surface完成初始化:持有
IGraphicBufferProducer(Producer端),具备申请GraphicBuffer、写入渲染数据的能力。
核心机制补充
1. Binder接口的跨层映射
Surface创建的跨进程通信依赖"Java AIDL + C++ Binder接口"的映射:
| Java层接口 | C++层接口 | 作用 |
|---|---|---|
| IWindowSession | - | 应用→WMS的窗口请求通信 |
| ISurfaceComposer | ISurfaceComposer (C++) | WMS→SurfaceFlinger的核心通信 |
| - | IGraphicBufferProducer | SurfaceFlinger→应用的Producer通信 |
2. 显存缓冲区(GraphicBuffer)的预分配逻辑
- SurfaceFlinger创建BufferQueue时,不会立即分配GraphicBuffer ,而是在应用进程首次调用
lockCanvas()时,由Producer端向SurfaceFlinger申请空闲GraphicBuffer; - GraphicBuffer基于Ashmem(匿名共享内存)实现跨进程共享,应用进程写入数据后,SurfaceFlinger可直接访问,无需拷贝(零拷贝)。
3. 异常处理:Surface创建失败的兜底逻辑
- WMS侧:若窗口属性非法(如尺寸为0、无权限),返回空SurfaceControl,应用进程
mSurface为null,触发SurfaceHolder.Callback.surfaceDestroyed; - SurfaceFlinger侧:若显存不足,创建Layer失败,返回错误码,WMS会通知应用进程重新发起请求。
常见问题
1. 为什么Surface创建是跨进程的?
- Surface的核心是显存缓冲区(GraphicBuffer),由GPU/显示硬件管理,SurfaceFlinger是系统级显存管理者(运行在独立进程),必须由它统一分配和管理显存;
- 多应用的Surface需要SurfaceFlinger统一合成(按Z轴层级),因此Surface的创建必须由SurfaceFlinger主导。
2. Java层的Surface和C++层的Surface有什么区别?
- Java层
android.view.Surface:仅为Native层Surface的封装,提供lockCanvas()/unlockCanvasAndPost()等上层API; - C++层
android::Surface:核心实现层,持有IGraphicBufferProducer,负责与BufferQueue交互、申请GraphicBuffer。
3. SurfaceControl的作用是什么?
- SurfaceControl是"Surface的控制器",Java/C++层均有实现,核心作用是:
- 封装
IGraphicBufferProducer(Producer端); - 管理Surface的属性(如尺寸、透明度、Z轴层级);
- 作为应用/WMS/SurfaceFlinger之间传递Surface的载体。
- 封装
总结
Surface的创建流程是Android分层架构的典型体现:
- Java层(应用/WMS) 负责"发起请求、校验参数、封装结果",是面向开发者的上层抽象;
- C++层(SurfaceFlinger) 负责"创建BufferQueue、分配显存、生成Producer端",是Surface的核心实现层;
- 跨进程通信依赖Binder,
IGraphicBufferProducer是连接应用进程与SurfaceFlinger的核心接口,也是Surface的本质。
