Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl

Posted 薛瑄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl相关的知识,希望对你有一定的参考价值。

前言

上一篇我们分析了,app与SurfaceFlinger建立连接的过程,现在我们就可以继续往下分析,看下创建Surface的过程。

我们可以将Surface理解为一个绘图表面,android应用程序负责往这个绘图表面上填内容,而SurfaceFlinger服务负责将这个绘图表面的内容取出来,并且渲染在显示屏上。

Android 图形架构 之一 ——概述
Android 图形架构 之二—— SurfaceFlinger 启动和连接
Android 图形架构 之三—— 创建Layer、Surface、SurfaceControl
Android 图形架构 之四——图形缓冲区的申请和消费流程及核心类
Android 图形架构 之五——深入分析addView所发生的的一切
Android 图形架构 之六——深入分析draw()是如何工作的
Android 图形架构 之七——Choreographer 源码分析
Android图形架构 之八——硬件VSync、VSync-app、Vsync-sf

概述

在Android中,Window与Surface一一对应。 如果说Window关心的是层次和布局,是从设计者角度定义的类,Surface则从实现角度出发,是工程师关系和考虑的类。Window的内容是变化 的,Surface需要有空间来记录每个时刻Window的内容。

在Android的SurfaceFlinger实现里,使用了三缓冲,保证了界面更新的稳定性和低延时。可参考这篇文章 了解更多

SurfaceFlinger 是运行在独立进程的Service, 它接收所有Window的Surface作为输入,根据Z-Order, 透明度,大小,位置等参数,计算出每个Surface在最终合成图像中的位置,然后交由HWComposer或OpenGL生成最终的显示Buffer, 然后显示到特定的显示设备上。SurfaceFlinger的会定期检查所有Layer的参数更新(LayerStack等),计算新的DirtyRegion,然后将结果推送给底层显示驱动进行显示。

在SurfaceFlinger服务中,绘图使用Layer类来描述。Layer是SurfaceFlinger 进行合成的基本操作单元。当应用创建Surface的时候在SurfaceFlinger内部创建Layer,因此一个Surface对应一个 Layer, 但注意,Surface不一定对应于Window,Android中有些Surface并不跟某个Window相关,而是有程序直接创建,比如说 StrictMode, 一块红色的背景,用于提示示Java代码中的一些异常, 还有SurfaceView, 用于显示有硬件输出的视频内容等。

Each Layer has:

  • Z order
  • Alpha value from 0 to 255
  • visibleRegion
  • crop region
  • transformation: rotate 0, 90, 180, 270: flip H, V: scale

当多个Layer进行合成的时候,并不是整个Layer的空间都会被完全显示,根据这个Layer最终的显示效果,一个Layer可以被划分成很多的Region, Android SurfaceFlinger 定义了以下一些Region类型:

  • TransparantRegion: 完全透明的区域,在它之下的区域将被显示出来。
  • OpaqueRegion: 完全不透明的区域,是否显示取决于它上面是否有遮挡或是否透明。
  • VisibleRegion: 可见区域,包括完全不透明无遮挡区域或半透明区域。 visibleRegion = Region - above OpaqueRegion.
  • CoveredRegion: 被遮挡区域,在它之上,有不透明或半透明区域。
  • DirtyRegion: 可见部分改变区域,包括新的被遮挡区域,和新的露出区域。

Android 系统支持多种显示设备,比如说,输出到手机屏幕,或者通过WiFi 投射到电视屏幕。Android用DisplayDevice类来表示这样的设备。不是所有的Layer都会输出到所有的Display, 比如说,我们可以只将Video Layer投射到电视, 而非整个屏幕。LayerStack 就是为此设计,LayerStack 是一个Display 对象的一个数值, 而类Layer里成员State结构体也有成员变量mLayerStack, 只有两者的mLayerStack 值相同,Layer才会被输出到给该Display设备。所以LayerStack 决定了每个Display设备上可以显示的Layer数目。

上面描述的几个概念,均是针对于显示这个层面,更多是涉及到中下层模块,应用层并不参与也无需关心。对于应用而言,它关心的是如何将内容画出来。Canvas 是Java层定义的一个类,它对应与Surface上的某个区域并提供了很多的2D绘制函数(借助于底层的Skia或OpenGL)。应用只需通过 LockCanvas() 来获取一个Canvas对象,并调用它的绘画方法,然后 unLockCanvasAndPost()来通知底层将更新内容进行显示。当然,并不是所有应用程序都需要直接操作Canva, 事实上只有少量应用需要直接操作Canvas, Android提供了很多封装好的控件 Widget,应用只需提供素材,如文字,图片,属性等等,这些控件会调用Canvas提供的接口帮用户完成绘制工作。

一、App进程中 相关 过程分析

下图是主要函数的时序图,接下来我们分析,如何调用和获取 SurfaceFlinger、SurfaceControl、Surface。也就是从下图中的第8步,开始分析, 在后续的文章会分析第8步之前的流程

和Native 层创建Surface 一样,通过 SurfaceFlinger,先创建一个SurfaceControl,然后利用SurfaceControl创建Surface。下面就来具体看看在Java层是如何实现的,其实都是通过jni 调用对应的Native函数

1.1、创建SurfaceSession

代码位于frameworks/base/core/java/android/view/SurfaceSession.java:

代码一:
public final class SurfaceSession 
    // Note: This field is accessed by native code.
    private long mNativeClient; // SurfaceComposerClient*
    
    private static native long nativeCreate();
    
    /** Create a new connection with the surface flinger. */
    public SurfaceSession() 
        mNativeClient = nativeCreate();
    
    

nativeCreate 是一个JNI调用,来看看对应代码frameworks/base/core/jni/android_view_SurfaceSession.cpp:

代码二:
static jlong nativeCreate(JNIEnv* env, jclass clazz) 
    //SurfaceComposerClient专门用来和surfaceflinger建立connection(ISurfaceComposerClient)
    SurfaceComposerClient* client = new SurfaceComposerClient();
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);

在文章Android 图形架构 之二—— SurfaceFlinger 启动和连接介绍过,SurfaceFlinger 进行通信的就是通过SurfaceComposerClient,他们是进程间通信,在SurfaceComposerClient中有对应的Binder代理对象mClient,对应 SurfaceFlinger 的Binder本地 Client 对象。

在SurfaceSession中获取到了SurfaceComposerClient对象,接下来就可以与SurfaceFlinger 进行通信了。

1.2、创建SurfaceControl

在App进程中,每一个界面都用一个Surface对象来描述,每一个Surface对象都是由一个SurfaceControl对象来创建的。Surface类和SurfaceControl类的关系以及实现如图所示:

位于frameworks/native/libs/gui/SurfaceControl.java:

代码三:
public SurfaceControl(SurfaceSession session,
        String name, int w, int h, int format, int flags)
                throws OutOfResourcesException 
    ......
    mName = name;
    //调用nativeCreate本地方法
    mNativeObject = nativeCreate(session, name, w, h, format, flags);
    ......

private final String mName;
long mNativeObject; // package visibility only for Surface.java access
private static native long nativeCreate(SurfaceSession session, String name,
        int w, int h, int format, int flags)
        throws OutOfResourcesException;

nativeCreate 是一个JNI调用,来看看对应代码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) 
    ScopedUtfChars name(env, nameStr);
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
    //调用SurfaceComposerClient的createSurface,就会调用到代码五的createSurfaceChecked,在Native层,
    //createSurface 返回是的 SurfaceControl 对象
    sp<SurfaceControl> surface = client->createSurface(
            String8(name.c_str()), w, h, format, flags);
    。。。
    surface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(surface.get());

调用到SurfaceComposerClient类的createSurfaceChecked,创建Layer(到SurfaceFling进程中)和Surface(在App进程中)

代码五:
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     SurfaceControl* parent,
                                                     LayerMetadata metadata) 
    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();
        
		// 这里是创建Layer,使用mClient 进程间通信,最终在Client类中进行具体操作
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp);

        if (err == NO_ERROR) 
            //创建一个SurfaceControl,使用它创建surface
            *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
        
    
    return err;

该函数的流程图如下

在文章Android 图形架构 之二—— SurfaceFlinger 启动和连接分析过,SurfaceComposerClient中的mClient 是通过SurfaceFling进程返回的,用于进程间通信。所以mClient->createSurface 会调用到SurfaceFling进程中。

下面先分析 new SurfaceControl流程(上图第11步之后)。后面章节再分析SurfaceFling进程的mClient->createSurface流程(上图第2步之后)

SurfaceControl的构造函数也比较简单,位于frameworks/native/libs/gui/SurfaceControl.cpp中:

代码六:
SurfaceControl::SurfaceControl(
        const sp<SurfaceComposerClient>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbp,
        bool owned)
    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)


  • SurfaceControl类的成员变量mClient是一个类型为SurfaceComposerClient对象,Android应用程序主要就是通过SurfaceComposerClient来和SurfaceFlinger服务建立连接的

  • SurfaceControl类的成员变量mHandle是指向创建Layer时,将Layer和SurfaceFlinger作为构造函数的参数创建一个Handle对象,这个Handle是一个Binder的实现,就是标识Surface的全局唯一性。

  • SurfaceControl类的成员变量mGraphicBufferProducer是指向Layer中的gbp参数,

  • SurfaceControl类的成员变量mSurfaceData是一个类型为Surface的强指针,它指向了一个Surface对象。

1.3、 创建Surface

从SurfaceControl获取Surface信息。位于frameworks/base/core/java/android/view/Surface.java:

代码七:
public void copyFrom(SurfaceControl other) 
    。。。 

    long surfaceControlPtr = other.mNativeObject;
    。。。
    //在Native层创建surface,并返回给newNativeObject
    //代码八分析
    long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);

    synchronized (mLock) 
        if (mNativeObject != 0) 
            nativeRelease(mNativeObject);
        
        //把Native的surface 句柄 ,赋值给java层的surface 的成员变量
        //代码十一分析
        setNativeObjectLocked(newNativeObject);
    

nativeCreateFromSurfaceControl 是jni调用
对应的代码 位于 frameworks/base/core/jni/android_view_Surface.cpp:

代码八:
static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
        jlong surfaceControlNativeObj) 
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
     //调用SurfaceControl的getSurface函数,最终会调用代码九 generateSurfaceLocked,创建了Native层的surface,
    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) 
        surface->incStrong(&sRefBaseOwner);
    
    return reinterpret_cast<jlong>(surface.get());

最终调用到SurfaceControl的generateSurfaceLocked() ,来创建一个Surface

代码九:
sp<Surface> SurfaceControl::generateSurfaceLocked() const

    // This surface is always consumed by SurfaceFlinger, so the
    // producerControlledByApp value doesn't matter; using false.
    mSurfaceData = new Surface(mGraphicBufferProducer, false);

    return mSurfaceData;

参数 mGraphicBufferProducer 是Layer中的gbp 参数,它是一个sp< IGraphicBufferProducer > 类型的对象,MonitoredProducer只是一个代理类,真正的实现是producer参数。

Android系统是通过OpenGL库来绘制UI的。OpenGL库在绘制UI的时候,需要底层的系统提供一个本地窗口给它,以便它可以将UI绘制在这个本地窗口上。Android系统为OpenGL库定提供的本地窗口是ANativeWindow,Surface类通过ANativeObjectBase类间接地继承了ANativeWindow类,因此,Surface类就是一个本地窗口。因此可以将Surface类看作OpenGL库与Android的UI系统之间的一个桥梁。

看看Surface的构造函数,位于frameworks/native/libs/gui/Surface.cpp:

代码十:
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp)
      : mGraphicBufferProducer(bufferProducer),
        mCrop(Rect::EMPTY_RECT),
        mBufferAge(0),
        mGenerationNumber(0),
        mSharedBufferMode(false),
        mAutoRefresh(false),
        mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
        mSharedBufferHasBeenQueued(false),
        mQueriedSupportedTimestamps(false),
        mFrameTimestampsSupportsPresent(false),
        mEnableFrameTimestamps(false),
        mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) 
    // Initialize the ANativeWindow function pointers.
    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
    ANativeWindow::queueBuffer      = hook_queueBuffer;
    ANativeWindow::query            = hook_query;
    ANativeWindow::perform          = hook_perform;

    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;

    const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;

    mReqWidth = 0;
    mReqHeight = 0;
    mReqFormat = 0;
    mReqUsage = 0;
    mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
    mDataSpace = Dataspace::UNKNOWN;
    mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
    mTransform = 0;
    mStickyTransform = 0;
    mDefaultWidth = 0;
    mDefaultHeight = 0;
    mUserWidth = 0;
    mUserHeight = 0;
    mTransformHint = 0;
    mConsumerRunningBehind = false;
    mConnectedToCpu = false;
    mProducerControlledByApp = controlledByApp;
    mSwapIntervalZero = false;

主要是设置了一些钩子方法,用于创建GraphicBuffer等等。还有一些变量的初始化。所以重点应该在这些钩子方法当中。

Surface 创建完成了,回到代码七,继续执行 setNativeObjectLocked()

代码十一:
    private void setNativeObjectLocked(long ptr) 
        //句柄值,是否与上一次的一样
        if (mNativeObject != ptr) 
            if (mNativeObject == 0 && ptr != 0) 
                mCloseGuard.open("release");
             else if (mNativeObject != 0 && ptr == 0) 
                mCloseGuard.close();
            
            //赋值句柄值,到surface 的成员变量mNativeObject
            mNativeObject = ptr;
            mGenerationId += 1;
            if (mHwuiContext != null) 
                mHwuiContext.updateSurface();
            
        
    

到此,Layer、Surface、SurfaceControl 的创建过程,分析完了,但是前后的流程还不完整。
例如: -> java 层surface -> native 层 surface ,谁来调用java层的,也就是这个? 是什么样的逻辑,实现什么功能。在文章Android 图形架构 之五—— 深入分析addView所发生的的一切进行了详细分析

下面我们接着上面代码五的流程分析 mClient->createSurface ,进入到SurfaceFlinger进程中

二、 SurfaceFlinger进程中创建Layer

Android应用程序主要就是通过SurfaceComposerClient来和SurfaceFlinger服务建立连接,建立完成后,会得到一个Client的Binder代理对象,保存变量mClient中。(这个过程查看 Android 图形架构 之二—— SurfaceFlinger 启动和连接

2.1、 Layer创建

因为mClient 是Client 的代理对象,所以会执行到 SurfaceFling进程中 Client的createSurface 函数
在frameworks/native/services/surfaceflinger/Client.cpp中

代码十二:
status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                               uint32_t flags, const sp<IBinder>& parentHandle,
                               LayerMetadata metadata, sp<IBinder>* handle,
                               sp<IGraphicBufferProducer>* gbp) 
    // We rely on createLayer to check permissions.
    //这个mFlinger 就是SurfaceFlinger对象
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle);

下面来看看SurfaceFlinger的createLayer函数

代码十三:
status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                     uint32_t h, PixelFormat format, uint32_t flags,
                                     LayerMetadata metadata, sp<IBinder>* handle,
                                     sp<IGraphicBufferProducer>* gbp,
                                     const sp<IBinder>& parentHandle,
                                     const sp<Layer>& parentLayer) 


     。。。省略代码。。。
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) 
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
            result = createBufferQueueLayer(client, uniqueName, w, h, flags, std::move(metadata),
                                            format, handle, gbp, &layer);

            break;
        。。。省略代码,这里是有多种Layer的,由于时间和能力有限、暂不分析其他的Layer,和本系列文章关系最紧要的就是BufferQueueLayer。。。
        default:
            result = BAD_VALUE;
            break;
    

    if (result != NO_ERROR) 
        return result;
    

    if (primaryDisplayOnly) 
        layer->setPrimaryDisplayOnly();
    

    bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                            addToCurrentState);
    if (result != NO_ERROR) 
        return result;
    
    mInterceptor->saveSurfaceCreation(layer);

    setTransactionFlags(eTransactionNeeded);
    return result;

下面来看看createBufferQueueLayer

代码十四:
status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, const String8& name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, PixelFormat& format,
                                                sp<IBinder>* handle,
                                                sp<IGraphicBufferProducer>* gbp,
                                                sp<Layer>* outLayer) 
    // initialize the surfaces
    switch (format) 
    case PIXEL_FORMAT_TRANSPARENT:
    case PIXEL_FORMAT_TRANSLUCENT:
        format = PIXEL_FORMAT_RGBA_8888;
        break;
    case PIXEL_FORMAT_OPAQUE:
        format = PIXEL_FORMAT_RGBX_8888;
        break;
    
	//使用工厂模式,创建BufferQueueLayer,
    sp<BufferQueueLayer> layer = getFactory().createBufferQueueLayer(
            LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));
    //设置layer的缓冲区默认属性        
    status_t err = layer->setDefaultBufferProperties(w, h, format);
    if (err == NO_ERROR) 
        //参数handle 和 gbp,在创建应用端 的surface 使用到了,下面会分析
        *handle = layer->getHandle();
        *gbp = layer->getProducer();
        *outLayer = layer;
    

    ALOGE_IF(err, "createBufferQueueLayer() failed (%s)", strerror(-err));
    return err;

BufferQueueLayer 继承了BufferLayer,后者继承了Layer,主要是在Layer构造函数中进行了一些初始化的工作,宽高、z轴、透明度等(其实很多值 的含义,我还不知道)

代码十五:
BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) 

对象第一次被赋值给强指针会调用onFirstRef函数:

代码十六:
void BufferQueueLayer::onFirstRef() 
    BufferLayer::onFirstRef();

    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    //创建了生产者和消费者缓冲区,这两个缓冲区将来会存放UI的内容数据
    //这里是重点,会面会有文章详细分析
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicB

以上是关于Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl的主要内容,如果未能解决你的问题,请参考以下文章

Android 图形架构 之二—— SurfaceFlinger 启动和连接

Android 图形架构 之二—— SurfaceFlinger 启动和连接

Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl

Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl

Android 图形架构 之五—— 深入分析addView所发生的的一切

Android 图形架构 之五—— 深入分析addView所发生的的一切