写在前面
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通过getSurfaceControlcopy 给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,最终传给SurfaceControlLayerHandle是什么呢?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。