View绘制原理(04)-生成Surface

作者: 代码多哥 | 来源:发表于2023-07-12 19:44 被阅读0次

    前面View绘制原理中Vsync流程基本上已经分析完毕。前文分析了performTraversals的四个重要流程,第一步就是relayoutWindow,它的作用之一就是为界面生成Surface。本文将详细介绍这个relayoutWindow关于生成Surface的部分原理。

    1. SurfaceControl.

    这是一个稍微有一点难理解的类,而且的创建过程也非常晦涩。我们来看一下它的原理

    首先在ViewRootImpl初始化的时候,就会调用SurfaceControl和Surface的构造函数生成它们的实例
    frameworks/base/core/java/android/view/ViewRootImpl.java

        public final Surface mSurface = new Surface();
        private final SurfaceControl mSurfaceControl = new SurfaceControl();
    

    frameworks/base/core/java/android/view/SurfaceControl.java

        public SurfaceControl() {
        }
    

    frameworks/base/core/java/android/view/Surface.java

    public Surface() {
        }
    

    这个里虽然生成了Surface和SurfaceControl对象,但是因为它没有生成底层的对应的对象,所以是无效的,还不能用于绘制

    2. 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);
                    }
                }
                if (mAttachInfo.mThreadedRenderer != null) {
                    if (HardwareRenderer.isWebViewOverlaysEnabled()) {
                        addPrepareSurfaceControlForWebviewCallback();
                        addASurfaceTransactionCallback();
                    }
                    mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
                }
            } else {
                destroySurface();
            }
        ...
        }
    

    这个方法内部,调用了mWindowSession.relayoutWindow方法,并且传入了mSurfaceControl, 这是一个IPC方法,因为SurfaceControl也实现了Parcelable接口,所以可以跨进程传递。当方法返回来之后,接着判断mSurfaceControl.isValid()

    public boolean isValid() {
            return mNativeObject != 0;
        }
    

    就是看看mNativeObject是否为0, 初始化时时空函数,因此肯定为0, 如果此时不为零,它就是在mWindowSession.relayout内赋值了。因此我们来看看mWindowSeesion.relayout作了什么操作。

    3 APP与WMS通信

    ViewRootImpl有一个mWindowSeesion成员,是构造ViewRootImpl的时候通过调用WindowManagerGlobal.getWindowSession获取的

    
     public ViewRootImpl(Context context, Display display) {
            this(context, display, WindowManagerGlobal.getWindowSession(),
                    false /* useSfChoreographer */);
        }
    
     public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
                boolean useSfChoreographer) {
            mContext = context;
            mWindowSession = session;
            ...
            }
    
     @UnsupportedAppUsage
        public static IWindowSession getWindowSession() {
              ...
              IWindowManager windowManager = getWindowManagerService();
              sWindowSession = windowManager.openSession(
                     new IWindowSessionCallback.Stub() {
                        @Override
                             public void onAnimatorScaleChanged(float scale) {
                                  ValueAnimator.setDurationScale(scale);
                              }
                });
             
                return sWindowSession;
            }
        }
    

    于是IPC呼叫到到WindowManagerService.openSession方法
    frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

     @Override
        public IWindowSession openSession(IWindowSessionCallback callback) {
            return new Session(this, callback);
        }
    

    返回一个Session对象,它继承自IWindowSession.Stub ,所以是工作在服务端的实际干活的对象,传送到客户端后,客户端可以获取到句柄并转换成IWindowSession接口,然后远程呼叫这个Session的addToDisplay和relayout等方法, 这些方法内部,会调用WMS的相对应的方法,
    frameworks/base/services/core/java/com/android/server/wm/Session.java

    class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
    @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) {
          
            ...
            int res = mService.relayoutWindow(this, window, attrs,
                    requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
                    outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
                    outActiveControls, outSurfaceSize);
             ....
            return res;
        }
       ...
     }
    

    4. WindowManagerService

    WindnowManagerServicec初始化的时候会和SurfaceFlinger服务建立会话,这样后面就可以直接调用SurfaceFlinger的方法。

    frameworks/base/core/java/android/view/ViewRootImpl.java

    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
                int userId) {
                       ...
                        
                      res = mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes,
                                getHostVisibility(), mDisplay.getDisplayId(), userId,
                                mInsetsController.getRequestedVisibility(), inputChannel, mTempInsets,
                                mTempControls);
                      ...
       }
    

    这是上面介绍过的App与WMS的远程调用
    frameworks/base/services/core/java/com/android/server/wm/Session.java

     @Override
        public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
                int viewVisibility, int displayId, InsetsState requestedVisibility,
                InputChannel outInputChannel, InsetsState outInsetsState,
                InsetsSourceControl[] outActiveControls) {
            return mService.addWindow(this, window, attrs, viewVisibility, displayId,
                    UserHandle.getUserId(mUid), requestedVisibility, outInputChannel, outInsetsState,
                    outActiveControls);
        }
    

    frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

    public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
                int displayId, int requestUserId, InsetsState requestedVisibility,
                InputChannel outInputChannel, InsetsState outInsetsState,
                InsetsSourceControl[] outActiveControls) {
               ...
               final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);    
               ...
        }
    
    private DisplayContent getDisplayContentOrCreate(int displayId, IBinder token) {
            if (token != null) {
                final WindowToken wToken = mRoot.getWindowToken(token);
                if (wToken != null) {
                    return wToken.getDisplayContent();
                }
            }
    
            return mRoot.getDisplayContentOrCreate(displayId);
        }
    

    调用RootWindowContainer创建一个DisplayContent,并调用addChild将其加入到RootWindowContainer的下一级。
    frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

    DisplayContent getDisplayContentOrCreate(int displayId) {
            DisplayContent displayContent = getDisplayContent(displayId);
            if (displayContent != null) {
                return displayContent;
            }
           ...
            displayContent = new DisplayContent(display, this);
            addChild(displayContent, POSITION_BOTTOM);
            return displayContent;
        }
    

    DisplayContent有一个成员变量mSession是SurfaceSession类型,它是在申明时初始化的,因此调用构造函数即可以初始化mSession,它就代表和SurfaceFlinger的会话。它实际持有一个mNativeClient指针,指向一个SurfaceComposerClient对象,即SurfaceFlinger的客户端。
    frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

    class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {
          ...
          private final SurfaceSession mSession = new SurfaceSession();
          ...
    }
    

    frameworks/base/core/java/android/view/SurfaceSession.java

    public final class SurfaceSession {
      
        private long mNativeClient; // SurfaceComposerClient*
    
        private static native long nativeCreate();
        private static native void nativeDestroy(long ptr);
    
      
        public SurfaceSession() {
            mNativeClient = nativeCreate();
       }
    

    frameworks/base/core/jni/android_view_SurfaceSession.cpp

    static jlong nativeCreate(JNIEnv* env, jclass clazz) {
        SurfaceComposerClient* client = new SurfaceComposerClient();
        client->incStrong((void*)nativeCreate);
        return reinterpret_cast<jlong>(client);
    }
    

    frameworks/native/libs/gui/SurfaceComposerClient.cpp

    SurfaceComposerClient::SurfaceComposerClient()
        : mStatus(NO_INIT)
    {
    }
    
    SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
        : mStatus(NO_ERROR), mClient(client)
    {
    }
    
    void SurfaceComposerClient::onFirstRef() {
        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
        if (sf != nullptr && mStatus == NO_INIT) {
            sp<ISurfaceComposerClient> conn;
            conn = sf->createConnection();
            if (conn != nullptr) {
                mClient = conn;
                mStatus = NO_ERROR;
            }
        }
    }
    

    到这里就生成了一个SurfaceComposerClient对象,通过这个对象可以和ComposerService的实现者SurfaceFlinger通信,并调用了createConnection这个远程函数来创建一个连接conn后赋值给mClient。生成的这个SurfaceComposerClient的指针返回给JAVA层,保存在SurfaceSession.mNativeClient.

    到这里就具备了和SurfaceFlinger通信的能力。

    5 创建SurfaceControl

    在ViewRootImpl里面构造了一个SurfaceControl,但是它只是一个空白的对象,不能使用,现在来看看有效的SurfaceControl是怎么生成的。我们把app远程调用部分省略了,直接进入到WMS的relayoutWindow方法,它的内容非常多,这里仅仅介绍一下创建SurfaceControl的逻辑

    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) {
                final WindowState win = windowForClientLocked(session, client, false);
               ...
                win.setViewVisibility(viewVisibility);
               ...
                if (shouldRelayout) {
                    try {
                        result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
                    }
                }
               ...
            return result;
        }
    

    首先找到这个WindowState对象(它在WMS代表一个window,在次之前,已经通过session.addToDisplay添加进来),然后调用createSurfaceControl方法来创建一个WindowSurfaceController对象

    private int createSurfaceControl (SurfaceControl outSurfaceControl, int result,
                WindowState win, WindowStateAnimator winAnimator) {
          
                WindowSurfaceController surfaceController;
                ...
                surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type);
               ...
                surfaceController.getSurfaceControl(outSurfaceControl);
                ....
                return result;
        }
    

    内部调用winAnimator来创建一个WindowSurfaceController对象,然后,将该对象复制给outSurfaceControl,而这个outSurfaceControl就是ViewRootImpl中创建的对象。此后,ViewRootImpl的mSurfaceControl变成有效可用。 但是如何生成这个可用对象的,还需要继续分析。

     WindowSurfaceController createSurfaceLocked(int windowType) {
            ...
            mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), width,
                        height, format, flags, this, windowType);
            return mSurfaceController;
        }
    

    生成WindowSurfaceController返回给回去。在构造这个对象时,内部会生成一个新的SurfaceControl
    frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java

    WindowSurfaceController(String name, int w, int h, int format,
                int flags, WindowStateAnimator animator, int windowType) {
          ...
            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();
        }
    

    这里调用WindowState生成了一个SurfaceControl.Builder ,通过它的build来生成SurfaceControl,但是逻辑有一点绕:

    SurfaceControl.Builder makeSurface() {
            final WindowContainer p = getParent();
            return p.makeChildSurface(this);
        }
        
    SurfaceControl.Builder makeChildSurface(WindowContainer child) {
            final WindowContainer p = getParent();
            // Give the parent a chance to set properties. In hierarchy v1 we rely
            // on this to set full-screen dimensions on all our Surface-less Layers.
            return p.makeChildSurface(child)
                    .setParent(mSurfaceControl);
        }
    

    这里存在多态的情况.win的类型是WindowState,它继承自WindowContainer,它调用getParent返回的也是一个WindowContainer,好像会无限循环找到根,但是因为在父容器里有一级是我们上面分析过的DisplayContent,它重写了makeChildSurface方法
    frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

    SurfaceControl.Builder makeChildSurface(WindowContainer child) {
            SurfaceSession s = child != null ? child.getSession() : getSession();
            final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(s).setContainerLayer();
            if (child == null) {
                return b;
            }
    
            return b.setName(child.getName())
                    .setParent(mSurfaceControl);
        }
    

    在这里它阻断了这个递归,并且调用了mWmService.makeSurfaceBuilder(s)来生成Builder对象。 这个DisplayContent我们上面也介绍过,它持有一个SurfaceSession成员,这里正好用它来生成SurfaceControl。生成了Builder之后调用build生成SurfaceControl对象。
    frameworks/base/core/java/android/view/SurfaceControl.java

    public SurfaceControl build() {
               ...
                if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {
                    setBLASTLayer();
                }
    
                return new SurfaceControl(
                        mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,
                        mLocalOwnerView, mCallsite);
            }
    

    这里调用的构造方法和ViewRootImpl中调用的不同,传了非常多的参数包括用于和SurfaceFling通信的session,生成layer类型的flags等,这表示它将生成一个有效的SurfaceControl。

    private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
                SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,
                String callsite) {
            ...
            mNativeObject = nativeCreate(session, name, w, h, format, flags, parent != null ? parent.mNativeObject : 0, metaParcel);
            ...
            mNativeHandle = nativeGetHandle(mNativeObject);
            mCloseGuard.openWithCallSite("release", callsite);
        }
    

    这里会进入到了SurfaceControl的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, jlong parentObject,
            jobject metadataParcel) {
       
        sp<SurfaceControl> surface;
        sp<SurfaceComposerClient> client;
        if (sessionObj != NULL) {
            client = android_view_SurfaceSession_getClient(env, sessionObj);
        } else {
            client = SurfaceComposerClient::getDefault();
        }
        ...
        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());
    }
    

    nativeCreate的参数sessionOb是一个SurfaceSession,它来自DisplayContent,在其初始化时生成了这个对象,并连接SurfaceFlinger创建回话。
    这里先调用 android_view_SurfaceSession_getClient(env, sessionObj)获取到SurfaceSession对象client,它是一个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;
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;
           ...
            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);
            }
        }
        return err;
    }
    

    于是就远程呼叫Client的createSurface方法,同时会传入一个handle的地址,这个handle将存放即将创建的Layer的handle,以及gbp的地址用于保存producer。最后经这个handle为参数,构造SurfaceControl对象。也就是说SurfaceControl的handle是指向一个Layer的handle。在JAVA层,SurfaceControl的构造方法调用nativeCreate之后,也调用了nativeGetHandle方法,就是来获取Layer的handle指针,并保存到JAVA层的mNativeHandle

     mNativeObject = nativeCreate(session, name, w, h, format, flags,
                        parent != null ? parent.mNativeObject : 0, metaParcel);
    
    static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
        SurfaceControl *surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
        return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
    }
    

    接着我们继续看看mClient->createSurface是如何生成Layer的。
    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, 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);
    }
    

    进一步调用mFlinger->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;
    }
    
    

    上层创建一个SurfaceConftrol实质上是在SurfaceFlinger创建一个Layer,这里会根据Layer的flag生成不同的Layer,通常情况传入的flag包含的是eFXSurfaceBufferState(blast)这个位开关。因此将进入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;
    }
    

    这里调用getFactory().createBufferStateLayer()去创建,创建完之后即那个layer的handler赋值给handle,layer赋值为outLayer。
    这样就构造好了Layer,并返回回去。
    frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

    sp<BufferStateLayer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
        return new BufferStateLayer(args);
    }
    
    

    frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp

    BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
    
    BufferQueueLayer::~BufferQueueLayer() {
        mContentsChangedListener->abandon();
        mConsumer->abandon();
    }
    

    继承自BufferLayer, frameworks/native/services/surfaceflinger/BufferLayer.cpp

    
    BufferLayer::BufferLayer(const LayerCreationArgs& args)
          : Layer(args),
            mTextureName(args.textureName),
            mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {
        ALOGV("Creating Layer %s", getDebugName());
    
        mPremultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
    
        mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
        mProtectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
    }
    

    继承自Layer frameworks/native/services/surfaceflinger/Layer.cpp

    Layer::Layer(const LayerCreationArgs& args)
          : mFlinger(args.flinger),
            mName(args.name),
            mClientRef(args.client),
            mWindowType(static_cast<InputWindowInfo::Type>(
                    args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))) {
        
        ...
    }
    
    void Layer::onFirstRef() {
        mFlinger->onLayerFirstRef(this);
    }
    
    

    引用到Layer的时候,会调用mFlinger->onLayerFirstRef(this);

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

    再调用mScheduler->registerLayer(layer)
    frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp

    void Scheduler::registerLayer(Layer* layer) {
        scheduler::LayerHistory::LayerVoteType voteType;
           ...
            voteType = scheduler::LayerHistory::LayerVoteType::Heuristic;
        }
        mLayerHistory->registerLayer(layer, voteType);
    }
    

    frameworks/native/services/surfaceflinger/Scheduler/LayerHistory.cpp

    void LayerHistory::registerLayer(Layer* layer, LayerVoteType type) {
        std::lock_guard lock(mLock);
        for (const auto& info : mLayerInfos) {
            LOG_ALWAYS_FATAL_IF(info.first == layer, "%s already registered", layer->getName().c_str());
        }
        auto info = std::make_unique<LayerInfo>(layer->getName(), layer->getOwnerUid(), type);
        mLayerInfos.emplace_back(layer, std::move(info));
    }
    

    将生成layer记录到历史。

    当Layer创建好了之后,会去获取这个Layer的handle

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

    frameworks/native/services/surfaceflinger/Layer.h

     class Handle : public BBinder, public LayerCleaner {
        public:
            Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
                  : LayerCleaner(flinger, layer, this), owner(layer) {}
            const String16& getInterfaceDescriptor() const override { return kDescriptor; }
    
            static const String16 kDescriptor;
            wp<Layer> owner;
        };
    

    这handle里保存了surface 和 layer的引用,它也是一个IBinder类型的对象。

    到这里SurfaceControl的nativeCreate方法就结束了,它通过SurfaceSession连接SurfaceFlingger,然后远程呼叫SurfaceFlinger创建一个Client连接,之后远程调用这个client的createLayer方法,进而调用到SurfaceFlinger的Factory创建一个BufferQueueLayer对象,然后将这个Layer的handle赋值到surfacecontrol.handle指针,然后将surfacecontrol的指针至返回到JAVA层,保存到SurfaceControl的mNativeObject。

    至此创建有效的SurfaceControl的流程结束,它在SurfaceFlinger端创建了一个Layer,并在surfaceControl中保存了这个Layer的远程句柄。

    6. BLASTBufferQueue

    如果mWindowSession.relayout之后,mSurfaceControl将会变成有效的,此时会判断blast是否开启(blast特性时12新推出的,它默认开启的),所以进入到getOrCreateBLASTSurface,在这里将会生成一个BLASTBufferQueue, 。而原来的 mSurface.copyFrom(mSurfaceControl),我们将在最后来对比分析一下。

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
               ...
            int relayoutResult = mWindowSession.relayout(mWindow, ..., mSurfaceControl, ...);
          
            if (mSurfaceControl.isValid()) {
                if (!useBLAST()) {
                    mSurface.copyFrom(mSurfaceControl);
                } else {
                    final Surface blastSurface = getOrCreateBLASTSurface();
                    ...
                    if (blastSurface != null) {
                        mSurface.transferFrom(blastSurface);
                    }
                }
               ...
        }
    
    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,则传入mSurfaceControl新创建一个mBlastBufferQueue,然后调用这个 BufferQueue.createSurface()来创建一个Surface;如果已经存在了,则进行更新操作mBlastBufferQueue.update(mSurfaceControl,...)。分析一下这个create的逻辑
    frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java

    public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
                @PixelFormat.Format int format) {
            mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format);
        }
    

    构造方法调用nativeCreate创建底层数据,它传入了sc.mNativeObject,,在JNI层就可通过这个指针访问这个SurfaceControl对象
    frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp

    static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
                              jlong width, jlong height, jint format) {
        ...
        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());
    }
    

    nativeCreate函数将surfaceControl指针转换成SurfaceControl*指针,然后以此为参数生成了一个BLASTBufferQueue的对象queue,然后返回这个queue的指针给JAVA层并保存在mNativeObject。所以在JAVA层,BLASTBufferQueue的mNativeObject实质是指向一个BLASTBufferQueue对象,其持有一个SurfaceControl。
    frameworks/native/libs/gui/BLASTBufferQueue.cpp

    BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
                                       int width, int height, int32_t format)
          : mSurfaceControl(surface),
          ...{
        createBufferQueue(&mProducer, &mConsumer);  
         ...
        // safe default, most producers are expected to override this
        mProducer->setMaxDequeuedBufferCount(2);
        ...
    }
    

    createBufferQueue,并且传入了mProducer和mConsumer的地址,表示这个方法在内容生成对应的对象,并将值用这个两个指针指向他们。

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

    首先生成一个BufferQueueCore对象core,然后以这个core分别生成producer和consumer。最后将producer和consumer存入的指针指向他们。
    这个core相当于一个容器,里面管理存放buffer,producer和consuer都持有这个core,这就是一个典型的生产者-消费者模型,core就是缓存仓库

    BBQBufferQueueProducer继承自BufferQueueProducer,间接就继承自BnGraphicBufferProducer 说明它工作在服务端,是真正干活的对象。它是buffer的生产者,它会从core中取空闲的buffer出来绘制,绘制完后再放回去core。即dequeueBuffer 和queueBuffer 两个方法。
    frameworks/native/libs/gui/BLASTBufferQueue.cpp

    class BBQBufferQueueProducer : public BufferQueueProducer {
    public:
        BBQBufferQueueProducer(const sp<BufferQueueCore>& core)
              : BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/) {}
    

    frameworks/native/libs/gui/include/gui/BufferQueueProducer.h

    class BufferQueueProducer : public BnGraphicBufferProducer {
    

    frameworks/native/libs/gui/BufferQueueProducer.cpp

    BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
            bool consumerIsSurfaceFlinger) :
        mCore(core),
        mSlots(core->mSlots),
       ...
    

    再来看看消费者,它是继承自BnGraphicBufferConsumer,因此也是工作的服务端直接干活的对象
    frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h

    class BufferQueueConsumer : public BnGraphicBufferConsumer {
    

    frameworks/native/libs/gui/BufferQueueConsumer.cpp

    BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
       mCore(core),
       mSlots(core->mSlots),
       mConsumerName() {}
    

    这里的producer和consumer同时依赖core这个仓库,并直接操作它的slots。consumer的主要方法就是acquireBuffer和releaseBuffer。

    到这里ViewRootImpl的mBlastBufferQueue就初始化完成了。

    7. BBQSurface

    生成了BLASTBufferQueue之后会调用createSurface或者update来创建或者更新surface。我们来看一下createSurface的流程
    frameworks/base/graphics/java/android/graphics/BLASTBufferQueue.java

    public Surface createSurface() {
            return nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */);
        }
    
    

    直接进入JNI 的nativeGetSurface函数
    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));
    }
    

    通过传入的ptr指针转换成BLASTBufferQueue对象queue,然后调用getSurface方法
    frameworks/native/libs/gui/BLASTBufferQueue.cpp

    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 == flase,所以scHandle为null,然后传入mProducer生成一个BBQSurface

    class BBQSurface : public Surface {
    private:
        std::mutex mMutex;
        sp<BLASTBufferQueue> mBbq;
        bool mDestroyed = false;
    
    public:
        BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
                   const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
              : Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {
              ...
        }
    };
    

    Surface是继承自ANativeWindow,代表一个nativewindow,它的定义在如下,这种继承关系表达有一些费解。

    class Surface : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
    

    构造方法:

    Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp, const sp<IBinder>& surfaceControlHandle)
          : mGraphicBufferProducer(bufferProducer),
           ...{
        ...
        mSurfaceControlHandle = surfaceControlHandle;
    }
    

    可以看到构建的Surface其实是它的子类BBQSurface,这里传入参数controledByApp == true,说明它是由APP自己控制的,surfaceControlHandle == nullptr, 同时接受一个producer,说这Surface的角色是producer,由surface来产生buffer数据。 surface的dequeueBuffer和enqueueBuffer最终会调用到producer对应的方法。

    int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
        ...
        status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,
                                                                dqInput.height, dqInput.format,
                                                                dqInput.usage, &mBufferAge,
                                                                dqInput.getTimestamps ?
                                                                        &frameTimestamps : nullptr);
        ...
    }
    
    
    int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
        ...
        status_t result = mGraphicBufferProducer->dequeueBuffers(dequeueInput, &dequeueOutput);
        ...
    }
    

    具体的逻辑就不在详细展开。我需要记住的是如何生成者个Surface对象,它实质上是一个BBQSurface,代表者生产者。最后通过调用一个JNI函数android_view_Surface_createFromSurface来获构建一个Surface个对象,返回给JAVA层。

    jobject android_view_Surface_createFromSurface(JNIEnv* env, const sp<Surface>& surface) {
        jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz,
                gSurfaceClassInfo.ctor, (jlong)surface.get());
        if (surfaceObj == NULL) {
            if (env->ExceptionCheck()) {
                ALOGE("Could not create instance of Surface from IGraphicBufferProducer.");
                LOGE_EX(env);
                env->ExceptionClear();
            }
            return NULL;
        }
        surface->incStrong(&sRefBaseOwner);
        return surfaceObj;
    }
    
     gSurfaceClassInfo.ctor = GetMethodIDOrDie(env, gSurfaceClassInfo.clazz, "<init>", "(J)V");
    

    这里将反射调用Surface的私有构造方法:并将BBQSurface的指针保存到Surface.mNativeObject.
    frameworks/base/core/java/android/view/Surface.java

    private Surface(long nativeObject) {
            synchronized (mLock) {
                setNativeObjectLocked(nativeObject);
            }
        }
    

    创建好这个Surface之后,需要将它保存到ViewRootImpl的mSurface中去,可以理解为将blastSurface的nativeObject赋值给mSurface

    if (blastSurface != null) {
          mSurface.transferFrom(blastSurface);
    }
    

    8. 不开启Blast的情况.

    虽然现在默认是开始blast的,但是我们也可以分析一下不开始blast的情况,它调用的是一个copyFrom方法,从mSurfaceControl中来创建一个surface。

     if (!useBLAST()) {
              mSurface.copyFrom(mSurfaceControl);
    }
    

    frameworks/base/core/java/android/view/Surface.java

    public void copyFrom(SurfaceControl other) {
            if (other == null) {
                throw new IllegalArgumentException("other must not be null");
            }
    
            long surfaceControlPtr = other.mNativeObject;
            if (surfaceControlPtr == 0) {
                throw new NullPointerException(
                        "null SurfaceControl native object. Are you using a released SurfaceControl?");
            }
            long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
            updateNativeObject(newNativeObject);
        }
    

    这个里通过调用一个native方法nativeGetFromSurfaceControl返回一个surface的指针给上层保存,然后将新的newNativeObject保存到mNativeObject, 从而完成创建。我们看一下这个native方法.

    static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
            jlong nativeObject,
            jlong surfaceControlNativeObj) {
        Surface* self(reinterpret_cast<Surface *>(nativeObject));
        sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
    
        // If the underlying IGBP's are the same, we don't need to do anything.
        if (self != nullptr &&
                IInterface::asBinder(self->getIGraphicBufferProducer()) ==
                IInterface::asBinder(ctrl->getIGraphicBufferProducer())) {
            return nativeObject;
        }
    
        sp<Surface> surface(ctrl->getSurface());
        if (surface != NULL) {
            surface->incStrong(&sRefBaseOwner);
        }
    
        return reinterpret_cast<jlong>(surface.get());
    }
    

    入参有一个surfaceControlNativeObj,获取到它指向的SurfaceControl对象,然后调用它的getSurface方法返回一个surface
    frameworks/native/libs/gui/SurfaceControl.cpp

    sp<Surface> SurfaceControl::getSurface()
    {
        Mutex::Autolock _l(mLock);
        if (mSurfaceData == nullptr) {
            return generateSurfaceLocked();
        }
        return mSurfaceData;
    }
    
    sp<Surface> SurfaceControl::generateSurfaceLocked()
    {
        uint32_t ignore;
        auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
                                     ISurfaceComposerClient::eOpaque);
        mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
                                           flags, mHandle, {}, &ignore);
        mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
    
        // This surface is always consumed by SurfaceFlinger, so the
        // producerControlledByApp value doesn't matter; using false.
        mSurfaceData = mBbq->getSurface(true);
    
        return mSurfaceData;
    }
    

    这个再其次调用了mClient->createSurface,这个mClient是一个SurfaceComposerClient对象,这个前面分析过,它将与SurfaceFlinger的Client进行远程通信。
    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, 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);
    }
    

    但是这里调用的方法直接返回一个对象赋给mBbqChild,而mBbqChild是一个SurfaceControl类型的成员。因此不是单纯的IPC调用。看看定义:

    sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
                                                            PixelFormat format, uint32_t flags,
                                                            const sp<IBinder>& parentHandle,
                                                            LayerMetadata metadata,
                                                            uint32_t* outTransformHint) {
        sp<SurfaceControl> s;
        createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, std::move(metadata),
                             outTransformHint);
        return s;
    }
    

    原来是调用createSurfaceChecked,它内部生成了一个SurfaceControl,保存到s然后返回。

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

    所以又生成了一个新的SurfaceControl返回回去
    然后生成一个BLASTBufferQueue,之后再调用它的getSurface来创建surface,但是传入的参数是true

    mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
    
        // This surface is always consumed by SurfaceFlinger, so the
        // producerControlledByApp value doesn't matter; using false.
        mSurfaceData = mBbq->getSurface(true);
    
    p<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 == true,mSurfaceControl 是上面创建的child。因此scHandle是指向Layer的Handle,然后生成的BBQSurface也将持有该Handle。

    9. 总结

    • 通过分析APP与WMS和SurfaceFlinger的IPC通信,详细介绍了创建SurfaceControl以及Surface的流程
    • SurfaceControl持有SurfaceFlinger进程中创建的Layer的handle
    • Surface是通过BlastBufferQueue生成的一个BBQSurface,它继承自Surface,Surface是ANativeWindow的子类,它持有一个生产者,主要有dequeueBuffer和enqueueBuffer方法。

    相关文章

      网友评论

        本文标题:View绘制原理(04)-生成Surface

        本文链接:https://www.haomeiwen.com/subject/khtcudtx.html