【Graphics & SF】【初始化】2、Surface的创建【Android 12】

3,110 阅读32分钟

ViewRootImpl内部有两个成员变量:

    // These can be accessed by any thread, must be protected with a lock.
    // Surface can never be reassigned or cleared (use Surface.clear()).
    @UnsupportedAppUsage
    public final Surface mSurface = new Surface();
    private final SurfaceControl mSurfaceControl = new SurfaceControl();

跟踪一下向mSurface和mSurfaceControl初始化的流程。

一、SurfaceControl的初始化

1 ViewRootImpl.relayoutWindow

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
        // ......

        int relayoutResult = mWindowSession.relayout(mWindow, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
                mTempControls, mSurfaceSize);
        mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
        if (mSurfaceControl.isValid()) {
            if (!useBLAST()) {
                mSurface.copyFrom(mSurfaceControl);
            } else {
                final Surface blastSurface = getOrCreateBLASTSurface();
                // If blastSurface == null that means it hasn't changed since the last time we
                // called. In this situation, avoid calling transferFrom as we would then
                // inc the generation ID and cause EGL resources to be recreated.
                if (blastSurface != null) {p n
                    mSurface.transferFrom(blastSurface);
                }
            }
			// ......
        } else {
            destroySurface();
        }

		// ......
    }

mWindowSession是IWindowSession的Binder远程代理对象,服务端的实现是Session,那么成员变量mSurfaceControl是通过Binder IPC,在系统进程中加载其中的内容的。

2 Session.relayout

    @Override
    public int relayout(IWindow window, WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
            ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
        if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
                + Binder.getCallingPid());
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
        int res = mService.relayoutWindow(this, window, attrs,
                requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
                outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
                outActiveControls, outSurfaceSize);
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
                + Binder.getCallingPid());
        return res;
    }

这里继续调用了WindowManagerService.relayoutWindow。

3 WindowManagerService.relayoutWindow

    public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags,
            long frameNumber, ClientWindowFrames outFrames, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Point outSurfaceSize) {
		// ......
        synchronized (mGlobalLock) {
            // ......
            
            // Create surfaceControl before surface placement otherwise layout will be skipped
            // (because WS.isGoneForLayout() is true when there is no surface.
            if (shouldRelayout) {
                try {
                    result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
                }
                // ......
            }
            
            // ......
        }
    }

只关注outSurfaceControl的数据是如何填充的,这里继续调用WindowManagerService.createSurfaceControl方法。

4 WindowManagerService.createSurfaceControl

    private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,
            WindowState win, WindowStateAnimator winAnimator) {
        if (!win.mHasSurface) {
            result |= RELAYOUT_RES_SURFACE_CHANGED;
        }

        WindowSurfaceController surfaceController;
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
            surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        if (surfaceController != null) {
            surfaceController.getSurfaceControl(outSurfaceControl);
            ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);

        } else {
            // For some reason there isn't a surface.  Clear the
            // caller's object so they see the same state.
            ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
            outSurfaceControl.release();
        }

        return result;
    }

有两个流程:

  • 调用WindowStateAnimator.createSurfaceLocked方法来创建一个WindowSurfaceController对象。

  • 调用WindowSurfaceController.getSurfaceControl来对outSurfaceControl赋值。

流程1涉及到Native层SurfaceControl的创建,需要跟踪完流程1才能知道流程2中的outSurfaceControl是怎么得到数据的。

5 WindowStateAnimator.createSurfaceLocked

    WindowSurfaceController createSurfaceLocked(int windowType) {
		// ......
        
        int flags = SurfaceControl.HIDDEN;
        final WindowManager.LayoutParams attrs = w.mAttrs;

        if (w.isSecureLocked()) {
            flags |= SurfaceControl.SECURE;
        }

        if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {
            flags |= SurfaceControl.SKIP_SCREENSHOT;
        }
        
        // ......

        // Set up surface control with initial size.
        try {
			// ......

            mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
                    height, format, flags, this, windowType);
			// ......
        }

		// ......

        return mSurfaceController;
    }

忽略非相关的内容,这里根据一些窗口的基本信息,如窗口名字、窗口宽高、窗口类型等,来创建一个WindowSurfaceController对象,并且赋值给WindowStateAnimator的mSurfaceController成员变量。

6 WindowSurfaceController.constructor

    WindowSurfaceController(String name, int w, int h, int format,
            int flags, WindowStateAnimator animator, int windowType) {
        mAnimator = animator;

        title = name;

        mService = animator.mService;
        final WindowState win = animator.mWin;
        mWindowType = windowType;
        mWindowSession = win.mSession;

        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
        final SurfaceControl.Builder b = win.makeSurface()
                .setParent(win.getSurfaceControl())
                .setName(name)
                .setBufferSize(w, h)
                .setFormat(format)
                .setFlags(flags)
                .setMetadata(METADATA_WINDOW_TYPE, windowType)
                .setMetadata(METADATA_OWNER_UID, mWindowSession.mUid)
                .setMetadata(METADATA_OWNER_PID, mWindowSession.mPid)
                .setCallsite("WindowSurfaceController");

        final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags
                & WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);

        if (useBLAST) {
            b.setBLASTLayer();
        }

        mSurfaceControl = b.build();

        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

这里先调用WindowState.makeSurface方法生成了一个SurfaceControl.Builder对象,然后提前设置了一些SurfaceControl.Builder的属性,这些属性最终是要应用给SurfaceControl的。接着调用SurfaceControl.Builder.build方法来生成一个SurfaceControl对象,并且赋值给WindowSurfaceController的成员变量mSurfaceControl。

7 SurfaceControl.Builder.build

        /**
         * Construct a new {@link SurfaceControl} with the set parameters. The builder
         * remains valid.
         */
        @NonNull
        public SurfaceControl build() {
            if (mWidth < 0 || mHeight < 0) {
                throw new IllegalStateException(
                        "width and height must be positive or unset");
            }
            if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) {
                throw new IllegalStateException(
                        "Only buffer layers can set a valid buffer size.");
            }

            if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
                setBLASTLayer();
            }

            return new SurfaceControl(
                    mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
                    mLocalOwnerView, mCallsite);
        }

先对这个即将创建的新的SurfaceControl的相关属性进行有效性检查,接着基于之前传入SurfaceControl.Builder的相关信息创建一个SurfaceControl对象。

另外在创建这里看到有一个设置flag的操作:

            if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
                setBLASTLayer();
            }

首先先看一下FX_SURFACE_MASK的相关信息,FX_SURFACE_MASK这一位的相关flag的定义如下:

    /**
     * Surface creation flag: Creates a normal surface.
     * This is the default.
     *
     * @hide
     */
    public static final int FX_SURFACE_NORMAL   = 0x00000000;

    /**
     * Surface creation flag: Creates a effect surface which
     * represents a solid color and or shadows.
     *
     * @hide
     */
    public static final int FX_SURFACE_EFFECT = 0x00020000;

    /**
     * Surface creation flag: Creates a container surface.
     * This surface will have no buffers and will only be used
     * as a container for other surfaces, or for its InputInfo.
     * @hide
     */
    public static final int FX_SURFACE_CONTAINER = 0x00080000;

    /**
     * @hide
     */
    public static final int FX_SURFACE_BLAST = 0x00040000;

    /**
     * Mask used for FX values above.
     *
     * @hide
     */
    public static final int FX_SURFACE_MASK = 0x000F0000;

这里看到FX_SURFACE_MASK代表的这一位把Surface分成了几种类型:

  • FX_SURFACE_NORMAL,代表了一个标准Surface,这个是默认设置。
  • FX_SURFACE_EFFECT,代表了一个有纯色或者阴影效果的Surface。
  • FX_SURFACE_CONTAINER,代表了一个容器类Surface,这种Surface没有缓冲区,只是用来作为其他Surface的容器,或者是它自己的InputInfo的容器。
  • FX_SURFACE_BLAST,结合这里的分析可以看到,FX_SURFACE_BLAST应该是等同于FX_SURFACE_NORMAL。

如果SurfaceControl.Builder的mFlags中的FX_SURFACE_MASK这一位是FX_SURFACE_NORMAL,那么调用SurfaceControl.setBLASTLayer方法:

        /**
         * @hide
         */
        public Builder setBLASTLayer() {
            return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK);
        }

将FX_SURFACE_MASK代表的这一位设置为FX_SURFACE_BLAST。

SurfaceControl.Builder的mFlags的值是从WindowStateAnimator.createSurfaceLocked中获取的,WindowStateAnimator.createSurfaceLocked方法中没有针对FX_SURFACE_MASK这一位进行特殊处理,那么也就是说,这里会调用setBLASTLayer方法将mFlags的FX_SURFACE_MASK代表的这一位设置为FX_SURFACE_BLAST。

8 Java层SurfaceControl.constructor

    /**
     * Create a surface with a name.
     * <p>
     * The surface creation flags specify what kind of surface to create and
     * certain options such as whether the surface can be assumed to be opaque
     * and whether it should be initially hidden.  Surfaces should always be
     * created with the {@link #HIDDEN} flag set to ensure that they are not
     * made visible prematurely before all of the surface's properties have been
     * configured.
     * <p>
     * Good practice is to first create the surface with the {@link #HIDDEN} flag
     * specified, open a transaction, set the surface layer, layer stack, alpha,
     * and position, call {@link Transaction#show(SurfaceControl)} if appropriate, and close the
     * transaction.
     * <p>
     * Bounds of the surface is determined by its crop and its buffer size. If the
     * surface has no buffer or crop, the surface is boundless and only constrained
     * by the size of its parent bounds.
     *
     * @param session  The surface session, must not be null.
     * @param name     The surface name, must not be null.
     * @param w        The surface initial width.
     * @param h        The surface initial height.
     * @param flags    The surface creation flags.
     * @param metadata Initial metadata.
     * @param callsite String uniquely identifying callsite that created this object. Used for
     *                 leakage tracking.
     * @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
     */
    private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
            SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
            String callsite)
                    throws OutOfResourcesException, IllegalArgumentException {
        if (name == null) {
            throw new IllegalArgumentException("name must not be null");
        }

        mName = name;
        mWidth = w;
        mHeight = h;
        mLocalOwnerView = localOwnerView;
        Parcel metaParcel = Parcel.obtain();
        try {
			// ......
            mNativeObject = nativeCreate(session, name, w, h, format, flags,
                    parent != null ? parent.mNativeObject : 0, metaParcel);
        } finally {
            metaParcel.recycle();
        }
        if (mNativeObject == 0) {
            throw new OutOfResourcesException(
                    "Couldn't allocate SurfaceControl native object");
        }
        mNativeHandle = nativeGetHandle(mNativeObject);
        mCloseGuard.openWithCallSite("release", callsite);
    }

渣翻:

这个方法用来生成一个有名字的Surface。

Surface创建标志明确了要创建哪种Surface和特定的选项,比如Surface可以被认为是不透明的,是否应该在初始的时候隐藏。Surface应该总是在创建的时候带着HIDDEN标志,以确保在Surface的属性配置好之前,Surface不会过早显示。

一个好的实践是,首先使用HIDDEN标志创建Surface,接着打开一个Transactionn,设置Surface的layer、layer堆栈、透明度、位置,然后再合适的时机调用Transaction.show,最后关闭Transactoin。

Surface的界限由它的crop和buffer尺寸决定。如果这个Surface没有buffer或者是crop,那么这个Surface就是无边界的,只被它的父Surface的界限尺寸所限制。

这里调用了nativeCreate来创建native层的SurfaceControl。

9 android_view_SurfaceControl.nativeCreate

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;
    if (sessionObj != NULL) {
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
        client = SurfaceComposerClient::getDefault();
    }
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
    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());
}

这里的sessionObj是一个Java层的SurfaceSession对象,之前分析App到SurfaceFlinger的连接时候有分析到,App在第一次添加窗口的时候,会创建一个SurfaceSession对象,然后在JNI层的SurfaceSession对象创建的时候,会创建一个SurfaceComposerClient对象来连接到SurfaceFlinger。

那么这里先根据传入的sessionObj对象获取到一个SurfaceComposerClient对象,然后调用SurfaceComposerClient.createSurfaceChecked生成一个Native层的SurfaceControl对象,最后调用incStrong将SurfaceControl的强引用计数增加1,这会导致SurfaceControl的onFirstRef函数被调用,最后将这个创建的Native层的SurfaceControl的地址转换成一个整型返回给上层的SurfaceControl对象。

10 SurfaceComposerClient.createSurfaceChecked

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;

    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;

        uint32_t transformHint = 0;
        int32_t id = -1;
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &id, &transformHint);
        if (outTransformHint) {
            *outTransformHint = transformHint;
        }
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
    return err;
}

1)、根据之前分析App到SurfaceFlinger的连接,知道SurfaceComposerClient的成员变量mClient是一个BpSurfaceComposerClient类型的Binder代理对象,它的服务端实现是在SurfaceFlinger服务的Client类,那么这里最终是调用了服务端Client.createSurface函数。

2)、基于从服务端返回的信息,创建一个surfaceControl对象,这部分要等分析完服务端的内容后才能继续分析。

11 Client.createSurface

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, int32_t* outLayerId,
                               uint32_t* outTransformHint) {
    // We rely on createLayer to check permissions.
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle, outLayerId, nullptr, outTransformHint);
}

已知在Client内部是通过一个sp<SurfaceFlinger>类型的成员变量mFlinger是一个SurfaceFlinger类型的强指针,那么这里调用的即是SurfaceFlinger.createLayer。

12 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, int32_t* outLayerId,
                                     const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
	// ......

    status_t result = NO_ERROR;

    sp<Layer> layer;

    std::string uniqueName = getUniqueLayerName(name.string());

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
        case ISurfaceComposerClient::eFXSurfaceBufferState: {
            result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), handle, &layer);
			// ......
        } break;
        case ISurfaceComposerClient::eFXSurfaceEffect:
			// ......

            result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
                                       std::move(metadata), handle, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceContainer:
			// ......	
            result = createContainerLayer(client, std::move(uniqueName), w, h, flags,
                                          std::move(metadata), handle, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }

    if (result != NO_ERROR) {
        return result;
    }

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

    setTransactionFlags(eTransactionNeeded);
    *outLayerId = layer->sequence;
    return result;
}

这里的getUniqueLayerName函数保证每一个Layer都有一个独一无二的名字,名字的格式为:

uniqueName = base::StringPrintf("%s#%u", name, ++dupeCounter);

保证了即使是同一个Activity的两个窗口,也能根据“#0”,“#1”等序号进行区分。

12.1 Layer的几种类型

这里根据传入的flags参数的ISurfaceComposerClient::eFXSurfaceMask这一位去创建不同类型的Layer对象。这里的ISurfaceComposerClient中的定义的:

        eFXSurfaceBufferQueue = 0x00000000,
        eFXSurfaceEffect = 0x00020000,
        eFXSurfaceBufferState = 0x00040000,
        eFXSurfaceContainer = 0x00080000,
        eFXSurfaceMask = 0x000F0000,

这些flag和我们在分析SurfaceControl.Builder.build方法的内容的时候介绍的flag是一一对应的,这里看到:

  • eFXSurfaceBufferQueue和eFXSurfaceBufferState,对应BufferStateLayer。
  • eFXSurfaceEffect,对应EffectLayer。
  • eFXSurfaceContainer,对应ContainerLayer。

还有一种BufferQueueLayer,但是到Android 12这种BufferQueueLayer的相关代码虽然还保留,但是没有创建BufferQueueLayer的地方了。

上一张简单的类图看下这些Layer的关系:

Layer.png

12.2 BufferStateLayer的创建

根据之前的分析,我们这里要创建的是BufferStateLayer类型的Layer,那么走的是SurfaceFlinger.createBufferStateLayer:

status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::string name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, sp<IBinder>* handle,
                                                sp<Layer>* outLayer) {
    LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
    args.textureName = getNewTexture();
    sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
    *handle = layer->getHandle();
    *outLayer = layer;

    return NO_ERROR;
}

SurfaceFlinger创建createBufferStateLayer的流程比较简单,所以就不详细分析了,这里看下我觉得需要注意的几个点。

12.2.1 Layer向SurfaceFlinger进行注册

SurfaceFlinger.createBufferStateLayer中,在我们创建了一个BufferStateLayer对象后,将一个BufferStateLayer类型的强指针指向这个对象,

sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);

后续在Layer的onFirstRef函数中:

void Layer::onFirstRef() {
    mFlinger->onLayerFirstRef(this);
}

调用了SurfaceFlinger.onLayerFirstRef:

void SurfaceFlinger::onLayerFirstRef(Layer* layer) {
    mNumLayers++;
    if (!layer->isRemovedFromCurrentState()) {
        mScheduler->registerLayer(layer);
    }
}

这里看到SurfaceFlinger内部有一个成员变量

std::atomic<size_t> mNumLayers = 0;

负责对所有创建的Layer进行计数。

如果当前Layer有父Layer,那么继续调用Scheduler.registerLayer函数对新创建的Layer进行记录。

12.2.2 Layer句柄的创建

SurfaceFlinger.createBufferStateLayer在创建了BufferStateLayer对象后,这里又调用了Layer.getHandle函数:

*handle = layer->getHandle();

Layer.getHandle函数定义是:

    // Creates a new handle each time, so we only expect
    // this to be called once.
    sp<IBinder> getHandle();

Layer.getHandle函数只被期望在Layer创建的时候调用一次:

sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);
    if (mGetHandleCalled) {
        ALOGE("Get handle called twice" );
        return nullptr;
    }
    mGetHandleCalled = true;
    return new Handle(mFlinger, this);
}

Handle类的定义如下:

    /*
     * The layer handle is just a BBinder object passed to the client
     * (remote process) -- we don't keep any reference on our side such that
     * the dtor is called when the remote side let go of its reference.
     *
     * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
     * this layer when the handle is destroyed.
     */
    class Handle : public BBinder, public LayerCleaner {
    public:
        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
              : LayerCleaner(flinger, layer), owner(layer) {}

        wp<Layer> owner;
    };

Layer句柄只是一个传递给客户端进程的BBinder对象,我们不在本地保存任何引用,以便客户端在释放它的引用的时候析构函数可以被调用。最终这个句柄是要传给客户端,也就是SurfaceComposerClient处,然后SurfaceComposerClient基于这个Layer句柄创建一个SurfaceControl对象。那么我暂时像理解token一样,理解Layer句柄的作用为跨进程标识一个唯一的Layer。

LayerCleaner保证了当这个句柄销毁的时候SurfaceFlinger.onLayerDestroyed函数可以被调用,SurfaceFlinger.onLayerDestroyed函数即和我们上面讲的Layer创建的时候调用SurfaceFlinger.onLayerFirstRef这个函数相对。

13 SurfaceFlinger.addClientLayer

SurfaceFlinger.createLayer函数在创建了Layer后,继续调用了SurfaceFlinger.addClientLayer。

status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
                                        const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
                                        const sp<IBinder>& parentHandle,
                                        const sp<Layer>& parentLayer, bool addToRoot,
                                        uint32_t* outTransformHint) {
	// ......

    // Create a transaction includes the initial parent and producer.
    Vector<ComposerState> states;
    Vector<DisplayState> displays;

    ComposerState composerState;
    composerState.state.what = layer_state_t::eLayerCreated;
    composerState.state.surface = handle;
    states.add(composerState);

    // ......
    
    // attach this layer to the client
    client->attachLayer(handle, lbc);

    return setTransactionState(FrameTimelineInfo{}, states, displays, 0 /* flags */, nullptr,
                               InputWindowCommands{}, -1 /* desiredPresentTime */,
                               true /* isAutoTimestamp */, {}, false /* hasListenerCallbacks */, {},
                               0 /* Undefined transactionId */);
}

目前看到这个函数有两个作用:

  • 将<Handle, Layer>对记录到Client中
  • 将<Handle, Layer>对记录到SurfaceFlinger中

下面逐个分析。

13.1 将<Handle, Layer>对记录到Client中

这一步对应的是SurfaceFlinger.addClientLayer的如下内容:

    // attach this layer to the client
    client->attachLayer(handle, lbc);

Client.attachLayer函数很简单:

void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
{
    Mutex::Autolock _l(mLock);
    mLayers.add(handle, layer);
}

这里通过Client的成员变量mLayers:

    // protected by mLock
    DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;

将新创建的Layer和相应的Layer句柄保存在Client中,这样,每一个Client都维护了一个属于自己的Layer的表。

Layer句柄在SurfaceFlinger创建完Layer后,会返回给SurfaceComposerClient。那么后续SurfaceComposerClient发送Layer句柄到Client的时候,Client就可以通过该Layer句柄找到相应的Layer,就像下面的代码一样:

sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
{
    Mutex::Autolock _l(mLock);
    sp<Layer> lbc;
    wp<Layer> layer(mLayers.valueFor(handle));
    if (layer != 0) {
        lbc = layer.promote();
        ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
    }
    return lbc;
}

13.2 将<Handle, Layer>对记录到SurfaceFlinger中

SurfaceFlinger.addClientLayer还有一部分内容没讲到:

    // Create a transaction includes the initial parent and producer.
    Vector<ComposerState> states;
    Vector<DisplayState> displays;

    ComposerState composerState;
    composerState.state.what = layer_state_t::eLayerCreated;
    composerState.state.surface = handle;
    states.add(composerState);

	// ......

    return setTransactionState(FrameTimelineInfo{}, states, displays, 0 /* flags */, nullptr,
                               InputWindowCommands{}, -1 /* desiredPresentTime */,
                               true /* isAutoTimestamp */, {}, false /* hasListenerCallbacks */, {},
                               0 /* Undefined transactionId */);

这里首先初始化了一个ComposerState类型和DisplayState类型的Vector,接着创建了一个ComposerState类型的对象。

ComposerState和DisplayState这两个类型都定义在LayerState.h中:

struct ComposerState {
    layer_state_t state;
    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
};

struct DisplayState {
	// ......

    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
};

这里主要关注ComposerState类型。

ComposerState结构体中又有一个layer_state_t类型的成员:

/*
 * Used to communicate layer information between SurfaceFlinger and its clients.
 */
struct layer_state_t {
    // ......
    sp<IBinder> surface;
    // ......
    uint64_t what;
    // ......
}

layer_state_t用来在SurfaceFlinger和它的客户端,也就是SurfaceComposerClient,交流Layer信息。

这里主要做了以下几件事:

1)、设置了该ComposerState对象中的layer_state_t对象的what成员为layer_state_t::eLayerCreated。

2)、设置了该ComposerState对象中的layer_state_t对象的surface成员为handle,那么这个layer_state_t里就保存了Layer的句柄。

3)、然后把这个创建的ComposerState添加到上面的ComposerState向量中。

4)、最后调用SurfaceFlinger.setTransactionState。

SurfaceFlinger.setTransactionStat调用后,中间的步骤暂不去考虑,最终在SurfaceFlinger.setClientStateLocked函数中,可以看到:

uint32_t SurfaceFlinger::setClientStateLocked(
        const FrameTimelineInfo& frameTimelineInfo, const ComposerState& composerState,
        int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint32_t permissions,
        std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& outListenerCallbacks) {
    const layer_state_t& s = composerState.state;
	// ......

    const uint64_t what = s.what;
    uint32_t flags = 0;
    sp<Layer> layer = nullptr;
    if (s.surface) {
        if (what & layer_state_t::eLayerCreated) {
            layer = handleLayerCreatedLocked(s.surface);
            if (layer) {
                // put the created layer into mLayersByLocalBinderToken.
                mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
                flags |= eTransactionNeeded | eTraversalNeeded;
                mLayersAdded = true;
            }
        } else {
            layer = fromHandleLocked(s.surface).promote();
        }
    }
    // ......
}

当检测到layer_state_t的what包含layer_state_t::eLayerCreated时,会调用以下代码:

            layer = handleLayerCreatedLocked(s.surface);
            if (layer) {
                // put the created layer into mLayersByLocalBinderToken.
                mLayersByLocalBinderToken.emplace(s.surface->localBinder(), layer);
                flags |= eTransactionNeeded | eTraversalNeeded;
                mLayersAdded = true;
            }

主要内容为:

1)、调用handleLayerCreatedLocked,从传入的composerState对象的layer_state_t类型的state中,拿到Layer句柄中保存的Layer对象,再根据Layer的parent情况选择是添加还是移除:

    if (parent == nullptr && allowAddRoot) {
        layer->setIsAtRoot(true);
        mCurrentState.layersSortedByZ.add(layer);
    } else if (parent == nullptr) {
        layer->onRemovedFromCurrentState();
    } else if (parent->isRemovedFromCurrentState()) {
        parent->addChild(layer);
        layer->onRemovedFromCurrentState();
    } else {
        parent->addChild(layer);
    }

在我们的流程中,这里会将该Layer加入到父Layer之中,那么这个Layer才算真正加入到了Layer的层级结构中。

2)、将<Handle, Layer>记录到SurfaceFlinger的成员变量mLayersByLocalBinderToken中:

std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);

这样SurfaceFlinger也可以直接通过Layer句柄找到对应的Layer。

14 C++层SurfaceControl.constructor

SurfaceFlinger这边分析完了,再回到客户端SurfaceComposerClient.createSurfaceChecked:

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;

    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;

        uint32_t transformHint = 0;
        int32_t id = -1;
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &id, &transformHint);
		// ......
        if (err == NO_ERROR) {
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
	// ......
}

通过跨进程调用Client.createSurface,我们最终是在SurfaceFlinger服务端生成了一个Layer,并且返回了一个Layer的句柄,接着我们基于这些信息创建一个SurfaceControl对象:

SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
                               const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
                               uint32_t w, uint32_t h, PixelFormat format, uint32_t transform,
                               uint32_t flags)
      : mClient(client),
        mHandle(handle),
        mGraphicBufferProducer(gbp),
        mLayerId(layerId),
        mTransformHint(transform),
        mWidth(w),
        mHeight(h),
        mFormat(format),
        mCreateFlags(flags) {
}

在SurfaceControl内部,则保存了SurfaceComposerClient、Layer句柄等相关信息:

    sp<SurfaceComposerClient>   mClient;
    sp<IBinder>                 mHandle;
    sp<IGraphicBufferProducer>  mGraphicBufferProducer;

这样客户端的SurfaceControl便和服务端中的一个具体的Layer通过Layer句柄联系起来了。

15 WindowSurfaceController.getSurfaceControl

回看Java层SurfaceControl的构造方法:

private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
        SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
        String callsite)
                throws OutOfResourcesException, IllegalArgumentException {
	// .......
    try {
		// ......
        mNativeObject = nativeCreate(session, name, w, h, format, flags,
                parent != null ? parent.mNativeObject : 0, metaParcel);
    } finally {
        metaParcel.recycle();
    }
	// ......
    mNativeHandle = nativeGetHandle(mNativeObject);
}

其内部的两个成员变量:

     /**
     * @hide
     */
    public long mNativeObject;
    private long mNativeHandle;

分别保存了Native层的SurfaceControl对象的地址和Layer句柄的地址。

然后回看WindowManagerService.createSurfaceControl方法,是调用了WindowSurfaceController.getSurfaceControl方法来为outSurfaceControl进行赋值:

    void getSurfaceControl(SurfaceControl outSurfaceControl) {
        outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
    }

这里调用了SurfaceControl的copyFrom方法,copyFrom方法内部又调用了SurfaceControl的assignNativeObject方法:

    private void assignNativeObject(long nativeObject, String callsite) {
        if (mNativeObject != 0) {
            release();
        }
        if (nativeObject != 0) {
            mCloseGuard.openWithCallSite("release", callsite);
        }
        mNativeObject = nativeObject;
        mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0;
    }

    /**
     * @hide
     */
    public void copyFrom(@NonNull SurfaceControl other, String callsite) {
        mName = other.mName;
        mWidth = other.mWidth;
        mHeight = other.mHeight;
        mLocalOwnerView = other.mLocalOwnerView;
        assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
    }

那么最终的结果是,WindowManagerService(WindowSurfaceController)和ViewRootImpl分别持有的Java层的SurfaceControl对象都指向同一个Native层的SurfaceControl。

经评论区提醒这里的分析有误,看copyForm这里会继续调用nativeCopyFromSurfaceControl:

image.png

那么拷贝的时候也会创建一个native的SurfaceControl对象。

所以最终结果应该是ViewRootImpl在拷贝系统进程的java层SurfaceControl时,会同步拷贝native层的SurfaceControl,并非之前所说的指向同一个native层的SurfaceControl,并且拷贝的时候layerId以及layer句柄都是直接拷贝的,因此他们指向的仍是同一个Layer。

16 小结

SurfaceControl的创建.png

1)、Java层创建了两个SurfaceControl对象,分别由ViewRootImpl和WindowSurfaceController持有。

2)、C++层创建了一个SurfaceControl对象,它的指针地址被转为long型保存在Java层的SurfaceControl的mNativeObject中,那么C++层就可以通过从Java传来的long型变量得到C++层的SurfaceControl指针。

3)、每一个客户端的SurfaceControl对象持有一个IBinder类型的Layer句柄,该Layer句柄跨进程标识了一个SurfaceFlinger服务端的Layer对象,可以向SurfaceFlinger传入该Layer句柄从而找到该SurfaceControl对应的Layer对象。

二、BLASTBufferQueue的创建

回看ViewRootImpl.relayoutWindow方法:

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
        // ......

        int relayoutResult = mWindowSession.relayout(mWindow, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
                mTempControls, mSurfaceSize);
        mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
        if (mSurfaceControl.isValid()) {
            if (!useBLAST()) {
                mSurface.copyFrom(mSurfaceControl);
            } else {
                final Surface blastSurface = getOrCreateBLASTSurface();
                // If blastSurface == null that means it hasn't changed since the last time we
                // called. In this situation, avoid calling transferFrom as we would then
                // inc the generation ID and cause EGL resources to be recreated.
                if (blastSurface != null) {
                    mSurface.transferFrom(blastSurface);
                }
            }
			// ......
        } else {
            destroySurface();
        }

		// ......
    }

不管是通过启动Activity的方式来创建App类型的窗口,还是通过主动调用WindowManager.addView的方式来创建非App类型的窗口,流程都是一样,最终都是通过ViewRootImpl与WMS通信来创建一个窗口。

    boolean useBLAST() {
        return mUseBLASTAdapter && !mForceDisableBLAST;
    }

mUseBLASTAdapter受以下Settings数据库字段控制,默认是true。mForceDisableBLAST只有ViewRootImpl.forceDisableBLAST显式调用才会被设置为true,这里是false。

        /**
         * If true, submit buffers using blast in ViewRootImpl.
         * (0 = false, 1 = true)
         * @hide
         */
        @Readable
        public static final String DEVELOPMENT_USE_BLAST_ADAPTER_VR =
                "use_blast_adapter_vr";

那么这里走的逻辑是先通过ViewRootImpl.getOrCreateBLASTSurface方法得到一个Surface对象,然后调用Surface.transferFrom完成对mSurface的内容填充。

1 ViewRootImpl.getOrCreateBLASTSurface

    Surface getOrCreateBLASTSurface() {
        if (!mSurfaceControl.isValid()) {
            return null;
        }

        Surface ret = null;
        if (mBlastBufferQueue == null) {
            mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
                mSurfaceSize.x, mSurfaceSize.y,
                mWindowAttributes.format);
            // We only return the Surface the first time, as otherwise
            // it hasn't changed and there is no need to update.
            ret = mBlastBufferQueue.createSurface();
        } else {
            mBlastBufferQueue.update(mSurfaceControl,
                mSurfaceSize.x, mSurfaceSize.y,
                mWindowAttributes.format);
        }

        return ret;
    }

因为我们是初次调用这个方法,因此mBlastBufferQueue是null。另外一提,mBlastBufferQueue唯一赋值的地方就是这里。

先看下BLASTBufferQueue对象的创建流程。

2 BLASTBufferQueue.constructor

    /** Create a new connection with the surface flinger. */
    public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
            @PixelFormat.Format int format) {
        mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format);
    }

调用JNI的nativeCreate函数,long型的mNativeObject保存Native层的BLASTBufferQueue对象的指针。

3 android_graphics_BLASTBufferQueue.nativeCreate

static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
                          jlong width, jlong height, jint format) {
    String8 str8;
    if (jName) {
        const jchar* str16 = env->GetStringCritical(jName, nullptr);
        if (str16) {
            str8 = String8(reinterpret_cast<const char16_t*>(str16), env->GetStringLength(jName));
            env->ReleaseStringCritical(jName, str16);
            str16 = nullptr;
        }
    }
    std::string name = str8.string();
    sp<BLASTBufferQueue> queue =
            new BLASTBufferQueue(name, reinterpret_cast<SurfaceControl*>(surfaceControl), width,
                                 height, format);
    queue->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(queue.get());
}

创建一个Native层的BLASTBufferQueue对象,并且触发它的onFirstRef函数。

4 BLASTBufferQueue.constructor

BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
                                   int width, int height, int32_t format)
      : mSurfaceControl(surface),
        mSize(width, height),
        mRequestedSize(mSize),
        mFormat(format),
        mNextTransaction(nullptr) {
    createBufferQueue(&mProducer, &mConsumer);
    // since the adapter is in the client process, set dequeue timeout
    // explicitly so that dequeueBuffer will block
    mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());

    // safe default, most producers are expected to override this
    // 设置生产者执行一次dequeue可以获得的最大缓冲区数。
    mProducer->setMaxDequeuedBufferCount(2);
    mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
                                                      GraphicBuffer::USAGE_HW_COMPOSER |
                                                              GraphicBuffer::USAGE_HW_TEXTURE,
                                                      1, false);
    static int32_t id = 0;
    mName = name + "#" + std::to_string(id);
    auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
    mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
    id++;
    mBufferItemConsumer->setName(String8(consumerName.c_str()));
    // 设置当一个新的帧变为可用后会被通知的监听器对象。
    mBufferItemConsumer->setFrameAvailableListener(this);
    // 设置当一个旧的缓冲区被释放后会被通知的监听器对象。
    mBufferItemConsumer->setBufferFreedListener(this);
    // 设置当宽度和高度被请求为0时从dequeueBuffer返回的缓冲区的大小。默认是1x1。
    mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
    mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
    // 将BlastBufferItemConsumer的成员变量mBLASTBufferQueue指向当前BlastBufferQueue对象。
    mBufferItemConsumer->setBlastBufferQueue(this);

    // 得到SurfaceFlinger需要获取的缓冲区的数量。        
    ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
    // 设置消费者可以一次获取的缓冲区的最大值(默认为1)。
    mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);

    mTransformHint = mSurfaceControl->getTransformHint();
    mBufferItemConsumer->setTransformHint(mTransformHint);
    SurfaceComposerClient::Transaction()
            .setFlags(surface, layer_state_t::eEnableBackpressure,
                      layer_state_t::eEnableBackpressure)
            .setApplyToken(mApplyToken)
            .apply();
    mNumAcquired = 0;
    mNumFrameAvailable = 0;
    BQA_LOGV("BLASTBufferQueue created width=%d height=%d format=%d mTransformHint=%d", width,
             height, format, mTransformHint);
}

4.1 BLASTBufferQueue.createBufferQueue

// Similar to BufferQueue::createBufferQueue but creates an adapter specific bufferqueue producer.
// This BQP allows invoking client specified ProducerListeners and invoke them asynchronously,
// emulating one way binder call behavior. Without this, if the listener calls back into the queue,
// we can deadlock.
void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                                         sp<IGraphicBufferConsumer>* outConsumer) {
    LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BLASTBufferQueue: outProducer must not be NULL");
    LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BLASTBufferQueue: outConsumer must not be NULL");

    sp<BufferQueueCore> core(new BufferQueueCore());
    LOG_ALWAYS_FATAL_IF(core == nullptr, "BLASTBufferQueue: failed to create BufferQueueCore");

    sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core));
    LOG_ALWAYS_FATAL_IF(producer == nullptr,
                        "BLASTBufferQueue: failed to create BBQBufferQueueProducer");

    sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
    consumer->setAllowExtraAcquire(true);
    LOG_ALWAYS_FATAL_IF(consumer == nullptr,
                        "BLASTBufferQueue: failed to create BufferQueueConsumer");

    *outProducer = producer;
    *outConsumer = consumer;
}

类似于BufferQueue::createBufferQueue,但是创建了一个适配器专用的BufferQueue生产者。这个BQP允许调用客户端指定的ProducerListener并异步调用它们,模拟单向Binder调用行为。如果ProducerListener在没有它的情况下回调进入BLASTBufferQueue,我们就会死锁。

这个函数创建了三个对象,BufferQueueCore、BBQBufferQueueProducer和BufferQueueConsumer。暂时还不清楚这几个对象的作用,先从为数不多的注释去了解。

4.1.1 BufferQueueCore
sp<BufferQueueCore> core(new BufferQueueCore());

创建了一个BufferQueueCore对象。

4.1.1.1 BufferQueueCore的继承关系

BufferQueueCore对象继承自:

class BufferQueueCore : public virtual RefBase {

没有什么太值得关注的。

4.1.1.2 BufferQueueCore的构造函数

BufferQueueCore的定义可以从它的构造函数的注释中去理解:

    // BufferQueueCore manages a pool of gralloc memory slots to be used by
    // producers and consumers.
    BufferQueueCore();

BufferQueueCore管理一个由生产者和消费者使用的gralloc内存槽池。Gralloc查阅google文档:

Gralloc 内存分配器会进行缓冲区分配,并通过两个特定于供应商的 HIDL 接口来进行实现(请参阅 hardware/interfaces/graphics/allocator/ 和 hardware/interfaces/graphics/mapper/)。allocate() 函数采用预期的参数(宽度、高度、像素格式)以及一组用法标志。

构造函数是:

BufferQueueCore::BufferQueueCore()
      : mMutex(),
// ......
{
    // getMaxBufferCountLocked返回一次可以分配的缓冲区的最大数量。
    int numStartingBuffers = getMaxBufferCountLocked();
    for (int s = 0; s < numStartingBuffers; s++) {
        // mFreeSlots包含了所有的处于FREE状态并且当前没有缓冲区附着的槽。
        mFreeSlots.insert(s);
    }
    for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;
            s++) {
        // mUnusedSlots包含了当前没有被使用的所有槽。它们应该是空闲且没有附着一个缓冲区的。
        mUnusedSlots.push_front(s);
    }
}
4.1.2 BBQBufferQueueProducer
sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core));

创建了一个BBQBufferQueueProducer对象。

4.1.2.1 BBQBufferQueueProducer的继承关系

BBQBufferQueueProducer继承BufferQueueProducer:

// Extends the BufferQueueProducer to create a wrapper around the listener so the listener calls
// can be non-blocking when the producer is in the client process.
class BBQBufferQueueProducer : public BufferQueueProducer {

BBQBufferQueueProducer创建一层对listener(IProducerListener)的封装,以便当生产者在客户端进程的时候listener调用可以是非阻塞的。

暂时不太清楚BufferQueueProducer的作用,只看到是BufferQueueProducer是继承BnGraphicBufferProducer的:

class BufferQueueProducer : public BnGraphicBufferProducer {

BnGraphicBufferProducer又是继承IGraphicBufferProducer的:

class BnGraphicBufferProducer : public IGraphicBufferProducer {

IGraphicBufferProducer的定义是:

/*
 * This class defines the Binder IPC interface for the producer side of
 * a queue of graphics buffers.  It's used to send graphics data from one
 * component to another.  For example, a class that decodes video for
 * playback might use this to provide frames.  This is typically done
 * indirectly, through Surface.
 *
 * The underlying mechanism is a BufferQueue, which implements
 * BnGraphicBufferProducer.  In normal operation, the producer calls
 * dequeueBuffer() to get an empty buffer, fills it with data, then
 * calls queueBuffer() to make it available to the consumer.
 *
 * This class was previously called ISurfaceTexture.
 */
#ifndef NO_BINDER
class IGraphicBufferProducer : public IInterface {
    DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer,
                                  HGraphicBufferProducerV1_0,
                                  HGraphicBufferProducerV2_0)
#else
class IGraphicBufferProducer : public RefBase {

这个类为图形缓冲区队列的生产者端定义了Binder IPC接口。它用于将图形数据从一个组件发送到另一个组件。例如,一个用作回放的解码视频的类可以使用它来提供帧。这通常是通过Surface间接完成的。

底层机制是一个BufferQueue,它实现了BnGraphicBufferProducer。在通常操作中,生产者调用dequeueBuffer()来获得一个空缓冲区,用数据填充它,然后调用queueBuffer()使消费者可以使用它。

这个类以前被称为ISurfaceTexture。

4.1.2.2 BBQBufferQueueProducer的构造函数
    BBQBufferQueueProducer(const sp<BufferQueueCore>& core)
          : BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/) {}

再看BufferQueueProducer的构造函数:

BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
        bool consumerIsSurfaceFlinger) :
    mCore(core),
    mSlots(core->mSlots),
    mConsumerName(),
    mStickyTransform(0),
    mConsumerIsSurfaceFlinger(consumerIsSurfaceFlinger),
    mLastQueueBufferFence(Fence::NO_FENCE),
    mLastQueuedTransform(0),
    mCallbackMutex(),
    mNextCallbackTicket(0),
    mCurrentCallbackTicket(0),
    mCallbackCondition(),
    mDequeueTimeout(-1),
    mDequeueWaitingForAllocation(false) {}

将sp<BufferQueueCore>类型的成员变量mCore指向上面创建的BufferQueueCore对象。

4.1.3 BufferQueueConsumer
sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));

创建了一个BufferQueueConsumer对象。

4.1.3.1 BufferQueueConsumer的继承关系

BufferQueueConsumer继承自BnGraphicBufferConsumer:

class BufferQueueConsumer : public BnGraphicBufferConsumer {

BnGraphicBufferConsumer又继承自IGraphicBufferConsumer:

class BnGraphicBufferConsumer : public IGraphicBufferConsumer {

目前从BufferQueueConsumer的继承关系中无法得知BufferQueueConsumer的具体作用。

4.1.3.2 BufferQueueConsumer的构造函数
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
    mCore(core),
    mSlots(core->mSlots),
    mConsumerName() {}

将sp<BufferQueueCore>类型的成员变量mCore指向上面创建的BufferQueueCore对象。

4.2 BLASTBufferItemConsumer

    mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
                                                      GraphicBuffer::USAGE_HW_COMPOSER |
                                                              GraphicBuffer::USAGE_HW_TEXTURE,
                                                      1, false);
    static int32_t id = 0;
    mName = name + "#" + std::to_string(id);
    auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
    mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
    id++;
    mBufferItemConsumer->setName(String8(consumerName.c_str()));
    // 设置当一个新的帧变为可用后会被通知的监听器对象。
    mBufferItemConsumer->setFrameAvailableListener(this);
    // 设置当一个旧的缓冲区被释放后会被通知的监听器对象。
    mBufferItemConsumer->setBufferFreedListener(this);
    // 设置当宽度和高度被请求为0时从dequeueBuffer返回的缓冲区的大小。默认是1x1。
    mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
    mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
    // 将BlastBufferItemConsumer的成员变量mBLASTBufferQueue指向当前BlastBufferQueue对象。
    mBufferItemConsumer->setBlastBufferQueue(this);

这里看到,基于上一步得到的sp<IGraphicBufferConsumer>类型的成员变量mConsumer,创建了一个BLASTBufferItemConsumer对象。

4.2.1 BufferItemConsumer

BLASTBufferItemConsumer继承自BufferItemConsumer:

class BLASTBufferItemConsumer : public BufferItemConsumer {

BufferItemConsumer继承自ConsumerBase:

/**
 * BufferItemConsumer is a BufferQueue consumer endpoint that allows clients
 * access to the whole BufferItem entry from BufferQueue. Multiple buffers may
 * be acquired at once, to be used concurrently by the client. This consumer can
 * operate either in synchronous or asynchronous mode.
 */
class BufferItemConsumer: public ConsumerBase

BufferItemConsumer是一个BufferQueue消费者端点,允许客户端从BufferQueue访问整个BufferItem条目。多个缓冲区可以被同时获取,供客户端并发使用。此消费者可以以同步或异步模式操作。

构造函数是:

BufferItemConsumer::BufferItemConsumer(
        const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
        int bufferCount, bool controlledByApp) :
    ConsumerBase(consumer, controlledByApp)
{
    // setConsumerUsageBits将为dequeueBuffer打开额外的使用位。它们与传递给dequeueBuffer的位合并。    
    status_t err = mConsumer->setConsumerUsageBits(consumerUsage);
    LOG_ALWAYS_FATAL_IF(err != OK,
            "Failed to set consumer usage bits to %#" PRIx64, consumerUsage);
    if (bufferCount != DEFAULT_MAX_BUFFERS) {
        // setMaxAcquiredBufferCount设置消费者一次可以取得的缓冲区的最大数量。
        err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
        LOG_ALWAYS_FATAL_IF(err != OK,
                "Failed to set max acquired buffer count to %d", bufferCount);
    }
}
4.2.2 ConsumerBase
// ConsumerBase is a base class for BufferQueue consumer end-points. It
// handles common tasks like management of the connection to the BufferQueue
// and the buffer pool.
class ConsumerBase : public virtual RefBase,
        protected ConsumerListener {

ConsumerBase是BufferQueue消费者端点的基类。它处理一些常见的任务,比如管理到BufferQueue和缓冲池的连接。

再看它的构造函数的定义:

    // ConsumerBase constructs a new ConsumerBase object to consume image
    // buffers from the given IGraphicBufferConsumer.
    // The controlledByApp flag indicates that this consumer is under the application's
    // control.
    explicit ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false);

ConsumerBase构造一个新的ConsumerBase对象来消费来自给定的IGraphicBufferConsumer的图像缓冲区。controlledByApp标志表明该消费者处于应用程序的控制之下。

最后看下构造函数里的具体内容:

ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
        mAbandoned(false),
        mConsumer(bufferQueue),
        mPrevFinalReleaseFence(Fence::NO_FENCE) {
    // Choose a name using the PID and a process-unique ID.
    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());

    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
    // reference once the ctor ends, as that would cause the refcount of 'this'
    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
    // that's what we create.
    wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
    sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);

    status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
    if (err != NO_ERROR) {
        CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
                strerror(-err), err);
    } else {
        mConsumer->setConsumerName(mName);
    }
}

1)、将上面创建的BLASTBufferQueue的成员变量mConsumer赋值给ConsumerBase的sp<IGraphicBufferConsumer>类型的成员变量mConsumer。

2)、将当前ConsumerBase转为一个ConsumerListener的弱引用,然后封装到ProxyConsumerListener中。ProxyConsumerListener是IConsumerListener的实现,保存了真正的消费者对象的弱引用。所有对ProxyConsumerListener的调用都会转为对这个消费者对象的调用。

3)、接着调用consumerConnect将消费者连接到BufferQueue。只有一个消费者可以连接,当这个消费者断开连接时,BufferQueue就会被置为“abandoned”状态,导致生产者与BufferQueue的大多数交互都失败。controlledByApp指示使用者是否被应用程序控制。

看到BufferQueueConsumer.h中的定义:

    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
            bool controlledByApp) {
        return connect(consumer, controlledByApp);
    }

接着调用BufferQueueConsumer.connect函数:

status_t BufferQueueConsumer::connect(
        const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
	// ......

    mCore->mConsumerListener = consumerListener;
    mCore->mConsumerControlledByApp = controlledByApp;

    return NO_ERROR;
}

最终是将BufferQueueConsumer的sp<BufferQueueCore>类型的成员变量mCore,中的sp<IConsumerListener>类型的成员变量mConsumerListener指向了一个封装了BLASTBufferItemConsumer对象的ProxyConsumerListener对象,即完成了从BLASTBufferItemConsumer到BufferQueue的连接。

5 小结

由于对这一部分不熟悉,所以一下子出现的这么多新的类感觉有点乱,先简单总结一下各个类之间的关系:

BLASTBufferQueue.png

三、Surface的初始化

回看ViewRootImpl.getOrCreateBLASTSurface方法:

    Surface getOrCreateBLASTSurface() {
        if (!mSurfaceControl.isValid()) {
            return null;
        }

        Surface ret = null;
        if (mBlastBufferQueue == null) {
            mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl,
                mSurfaceSize.x, mSurfaceSize.y,
                mWindowAttributes.format);
            // We only return the Surface the first time, as otherwise
            // it hasn't changed and there is no need to update.
            ret = mBlastBufferQueue.createSurface();
        } else {
            mBlastBufferQueue.update(mSurfaceControl,
                mSurfaceSize.x, mSurfaceSize.y,
                mWindowAttributes.format);
        }

        return ret;
    }

创建了一个BLASTBufferQueue对象后,接着就是调用BLASTBufferQueue.createSurface创建一个Surface对象。

1 BLASTBufferQueue.createSurface

    /**
     * @return a new Surface instance from the IGraphicsBufferProducer of the adapter.
     */
    public Surface createSurface() {
        return nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */);
    }

从适配器的IGraphicsBufferProducer处返回一个新的Surface实例。

2 android_graphics_BLASTBufferQueue.nativeGetSurface

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));
}

这里传入的ptr即上一节我们创建BLASTBufferQueue后,从C++层返回给Java层的BLASTBufferQueue指针,所以这里我们可以拿到上一节创建的BLASTBufferQueue对象。

接着调用BLASTBufferQueue.getSurface函数。

3 BLASTBufferQueue.getSurface

sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
    std::unique_lock _lock{mMutex};
    sp<IBinder> scHandle = nullptr;
    if (includeSurfaceControlHandle && mSurfaceControl) {
        scHandle = mSurfaceControl->getHandle();
    }
    return new BBQSurface(mProducer, true, scHandle, this);
}

这里传入的includeSurfaceControlHandle是false,所以这里的handle为空。上面分析SurfaceControl的创建流程的时候,知道SurfaceControl保存的handle是其在SurfaceFlinger处对应的Layer的句柄。

接着创建了一个BBQSurface对象。

4 BBQSurface

class BBQSurface : public Surface {
private:
    sp<BLASTBufferQueue> mBbq;
public:
    BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
               const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
          : Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {}
     // ......
}

BBQSurface继承Surface,内部有一个sp<BLASTBufferQueue>类型的成员变量mBbq指向一个BLASTBufferQueue对象。还是要去看Surface的构造函数。

5 Surface

1)、Surface类继承ANativeObjectBase:

/*
 * An implementation of ANativeWindow that feeds graphics buffers into a
 * BufferQueue.
 *
 * This is typically used by programs that want to render frames through
 * some means (maybe OpenGL, a software renderer, or a hardware decoder)
 * and have the frames they create forwarded to SurfaceFlinger for
 * compositing.  For example, a video decoder could render a frame and call
 * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by
 * Surface.  Surface then forwards the buffers through Binder IPC
 * to the BufferQueue's producer interface, providing the new frame to a
 * consumer such as GLConsumer.
 */
class Surface
    : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
{

一个ANativeWindow的实现,它将图形缓冲区提供给BufferQueue。

这通常是由想要通过一些方法(可能是OpenGL,软件渲染器,或硬件解码器)渲染帧的程序使用,并且这些程序拥有它们创建的并且可以转发到SurfaceFlinger进行合成的帧。例如,视频解码器可以渲染一帧并调用eglSwapBuffers(),这个函数调用由Surface定义的ANativeWindow回调。然后,Surface通过Binder IPC将缓冲区转发到BufferQueue的生产者接口,并向GLConsumer等消费者提供新的帧。

再看到ANativeObjectBase的定义:

/*
 * This helper class turns a ANativeXXX object type into a C++
 * reference-counted object; with proper type conversions.
 */
template <typename NATIVE_TYPE, typename TYPE, typename REF,
        typename NATIVE_BASE = android_native_base_t>
class ANativeObjectBase : public NATIVE_TYPE, public REF
{

那么这里NATIVE_TYPE的是ANativeWindow,即Surface实际继承的是ANativeWindow。

2)、再看Surface构造函数的定义:

    /*
     * creates a Surface from the given IGraphicBufferProducer (which concrete
     * implementation is a BufferQueue).
     *
     * Surface is mainly state-less while it's disconnected, it can be
     * viewed as a glorified IGraphicBufferProducer holder. It's therefore
     * safe to create other Surfaces from the same IGraphicBufferProducer.
     *
     * However, once a Surface is connected, it'll prevent other Surfaces
     * referring to the same IGraphicBufferProducer to become connected and
     * therefore prevent them to be used as actual producers of buffers.
     *
     * the controlledByApp flag indicates that this Surface (producer) is
     * controlled by the application. This flag is used at connect time.
     *
     * Pass in the SurfaceControlHandle to store a weak reference to the layer
     * that the Surface was created from. This handle can be used to create a
     * child surface without using the IGBP to identify the layer. This is used
     * for surfaces created by the BlastBufferQueue whose IGBP is created on the
     * client and cannot be verified in SF.
     */
    explicit Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp = false,
                     const sp<IBinder>& surfaceControlHandle = nullptr);

从给定的IGraphicBufferProducer(具体实现是BufferQueue)创建一个Surface。

当它断开连接时,Surface主要是无状态的,它可以被视为美化的IGraphicBufferProducer持有者。因此,从同一个IGraphicBufferProducer中创建其他Surface是安全的。

然而,一旦一个Surface被连接,它将阻止其他引用相同的IGraphicBufferProducer的Surface被连接,从而防止它们被用作缓冲区的实际生产者。

controlledByApp标志表示这个Surface(生产者)由应用程序控制。此标志在连接时使用。

传入SurfaceControlHandle来存储创建Surface的Layer的弱引用。这个句柄可以用来创建子Surface,而不用IGBP来识别Layer。这用于由BlastBufferQueue创建的Surface,它的IGBP是在客户端创建的,不能在SF中验证。

3)、最后看下Surface的构造函数的具体内容:

Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
                 const sp<IBinder>& surfaceControlHandle)
      : mGraphicBufferProducer(bufferProducer),
        mCrop(Rect::EMPTY_RECT),
        mBufferAge(0),
        mGenerationNumber(0),
        mSharedBufferMode(false),
        mAutoRefresh(false),
        mAutoPrerotation(false),
        mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
        mSharedBufferHasBeenQueued(false),
        mQueriedSupportedTimestamps(false),
        mFrameTimestampsSupportsPresent(false),
        mEnableFrameTimestamps(false),
        mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
	// ......
    mSurfaceControlHandle = surfaceControlHandle;
}

这里传入的bufferProduer参数是BLASTBufferQueue的sp<IGraphicBufferProducer>类型的成员变量mProducer。

然后将成员变量mSurfaceControlHandle指向传入的surfaceControlHandle。

    // Reference to the SurfaceFlinger layer that was used to create this
    // surface. This is only populated when the Surface is created from
    // a BlastBufferQueue.
    sp<IBinder> mSurfaceControlHandle;

但是根据我们分析的这个流程,这里传入的surfaceControlHandle应该为空。

6 android_view_Surface.android_view_Surface_createFromSurface

回到android_graphics_BLASTBufferQueue.nativeGetSurface:

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.getSurface创建了一个新的Surface对象,接着调用android_view_Surface_createFromSurface函数:

jobject android_view_Surface_createFromSurface(JNIEnv* env, const sp<Surface>& surface) {
    jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz,
            gSurfaceClassInfo.ctor, (jlong)surface.get());
	// ......
    return surfaceObj;
}

这里创建了Java层的Surface,将Surface的指针地址转化为了一个Java的long型,因此调用的是Surface的如下构造方法:

    /* called from android_view_Surface_createFromIGraphicBufferProducer() */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private Surface(long nativeObject) {
        synchronized (mLock) {
            setNativeObjectLocked(nativeObject);
        }
    }

最终调用Surface.setNativeObjectLocked将C++层的Surface的地址保存在了Java层的Surface的mNativeObject中。

7 Surface.transferFrom

再次回到ViewRootImpl.relayoutWindow中。

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
        // ......

        int relayoutResult = mWindowSession.relayout(mWindow, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets,
                mTempControls, mSurfaceSize);
        mPendingBackDropFrame.set(mTmpFrames.backdropFrame);
        if (mSurfaceControl.isValid()) {
            if (!useBLAST()) {
                mSurface.copyFrom(mSurfaceControl);
            } else {
                final Surface blastSurface = getOrCreateBLASTSurface();
                // If blastSurface == null that means it hasn't changed since the last time we
                // called. In this situation, avoid calling transferFrom as we would then
                // inc the generation ID and cause EGL resources to be recreated.
                if (blastSurface != null) {
                    mSurface.transferFrom(blastSurface);
                }
            }
			// ......
        } else {
            destroySurface();
        }

		// ......
    }

此时经过ViewRootImpl.getOrCreateBLASTSurface方法,我们得到了一个Surface对象,接着调用Surface.transferFrom:

    /**
     * This is intended to be used by {@link SurfaceView#updateWindow} only.
     * @param other access is not thread safe
     * @hide
     * @deprecated
     */
    @Deprecated
    @UnsupportedAppUsage
    public void transferFrom(Surface other) {
        if (other == null) {
            throw new IllegalArgumentException("other must not be null");
        }
        if (other != this) {
            final long newPtr;
            synchronized (other.mLock) {
                newPtr = other.mNativeObject;
                other.setNativeObjectLocked(0);
            }

            synchronized (mLock) {
                if (mNativeObject != 0) {
                    nativeRelease(mNativeObject);
                }
                setNativeObjectLocked(newPtr);
            }
        }
    }

很简单,将other的mNativeObject赋值给当前Surface,并且将other的mNativeObject置为0,将other无效化。

8 小结

Surface的创建.png

1)、Surface的创建的时候接受BLASTBufferQueue对象和BLASTBufferQueue的mProducer成员变量为参数,这使得Surface与BufferQueue建立起了关系。

2)、Surface与SurfaceControl关系的建立应该是靠它的成员变量mSurfaceControlHandle,通过这个句柄它可以和SurfaceControl指向同一个Layer图层,但是我们分析的这个流程,最终Surface初始化后mSurfaceControlHandle仍然为空,这一点暂时还不太懂是什么情况。