亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于Android10渲染Surface的創(chuàng)建過(guò)程

 更新時(shí)間:2022年08月14日 09:34:36   作者:Avengong???????  
這篇文章主要介紹了基于Android10渲染Surface的創(chuàng)建過(guò)程,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

一、Surface 概述

OpenGL ES/Skia定義了一組繪制接口的規(guī)范,為什么能夠跨平臺(tái)? 本質(zhì)上需要與對(duì)應(yīng)平臺(tái)上的本地窗口建立連接。也就是說(shuō)OpenGL ES負(fù)責(zé)輸入了繪制的命令,但是需要一個(gè) "畫布" 來(lái)承載輸出結(jié)果,最終展示到屏幕。這個(gè)畫布就是本地窗口。

因此,每個(gè)平臺(tái)的有著不一樣的本地窗口的實(shí)現(xiàn)。Android平臺(tái)上是 ANativeWindow。

疑問(wèn):

  • 那么如何將OpenGL本地化? 通過(guò) EGL來(lái)對(duì)OpenGL ES來(lái)進(jìn)行配置。關(guān)鍵點(diǎn)就是提供本地化窗口。
  • 本地化窗口的作用是什么? 本地窗口是OpenGL ES和 物理屏幕之間的橋梁。

1.1 Android本地窗口簡(jiǎn)述

Android圖形系統(tǒng)提供的本地窗口,可以分為兩類:

  • FrameBufferNativeWindow

面對(duì)SF(SurfaceFlinger)。它通過(guò)HAL層的Gralloc系統(tǒng)調(diào)用(alloc/free)來(lái)分配內(nèi)核中的FrameBuffer幀緩沖區(qū)。 這個(gè)幀緩沖區(qū)就代表了物理屏幕(fb*驅(qū)動(dòng)節(jié)點(diǎn),*表示屏幕數(shù)。如fb0主屏幕、fb1等)。 FrameBuffer的數(shù)量一般情況下是2,也就是雙緩沖。當(dāng)然還有三倍緩沖。

  • Surface

面向應(yīng)用程序。對(duì)應(yīng)的是內(nèi)存中一塊緩沖區(qū),稱為:GraphicBuffer。是由SF來(lái)進(jìn)行分配。app從SF中獲取一塊GraphicBuffer, 通過(guò)OpenGL/Skia將圖形數(shù)據(jù)繪制(軟件/硬件)到GraphicBuffer上。最終SF會(huì)把各個(gè)應(yīng)用的GraphicBuffer數(shù)據(jù)進(jìn)行合成,最終 通過(guò) FrameBufferNativeWindow 輸出到屏幕上。

有了一個(gè)整體的概念,接下來(lái)就好理解很多。

二、引出SurfaceSession

2.1 從WindowManagerImpl的addView()說(shuō)起

app:
WindowManagerImpl.addView()
  WindowManagerGlobal.addView()
    ViewRootImpl的setView()
      IWindowSession.addToDisplay()
      
WMS:
      new WindowState
        WindowState.attach()
          session.windowAddedLocked()
            new SurfaceSession()

view添加到window的過(guò)程中, 從WindowManagerImpl 的 addView(),到WindowManagerGlobal(構(gòu)造方法中會(huì)在system server 進(jìn)程中創(chuàng)建一個(gè)Session對(duì)象)的addView()。最后會(huì)調(diào)用 ViewRootImplsetView()方法。 內(nèi)部會(huì)調(diào)用 IWindowSession 的addToDisplay() 方法。IWindowSession是WMS提供的一個(gè)binder服務(wù)(實(shí)現(xiàn)類就是Session)。

2.2 IWindowSession.windowAddedLocked()

內(nèi)部會(huì)創(chuàng)建一個(gè)WindowState 對(duì)象。 調(diào)用 WindowState的 attach()方法。最終調(diào)到Session中的windowAddedLocked(),會(huì)創(chuàng)建 一個(gè)SurfaceSession對(duì)象。這就是我們要找的的跟SurfaceFlinger建立聯(lián)系的地方。

 SurfaceSession mSurfaceSession;
void windowAddedLocked(String packageName) {
  mPackageName = packageName;
  mRelayoutTag = "relayoutWindow: " + mPackageName;
  if (mSurfaceSession == null) {
  // 一個(gè)進(jìn)程只有一個(gè)session,因此也只創(chuàng)建一次 SurfaceSession 對(duì)象
      
      // 創(chuàng)建 SurfaceSession 對(duì)象
      mSurfaceSession = new SurfaceSession();
      
      // 每個(gè)session 都存入WMS中的         
      mService.mSessions.add(this);
      
      if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
          mService.dispatchNewAnimatorScaleLocked(this);
      }
  }
  mNumWindow++; // 進(jìn)程中所有窗口的數(shù)量+1
}

一個(gè)應(yīng)用進(jìn)程對(duì)應(yīng)一個(gè)Session對(duì)象,一個(gè)Session對(duì)象對(duì)應(yīng)一個(gè)SurfaceSession。 WMS會(huì)把 這個(gè)Session 存儲(chǔ)起來(lái)。也就是說(shuō)WMS 會(huì)把所有跟SurfaceFlinger保持連接狀態(tài)的應(yīng)用Session存儲(chǔ)起來(lái)。

2.3 SurfaceSession 創(chuàng)建過(guò)程

這個(gè)類的實(shí)例代表了和SurfaceFlinger的一個(gè)連接。我們可以通過(guò)它 創(chuàng)建一個(gè)或多個(gè) Surface 對(duì)象。

2.3.1 構(gòu)造方法

> SurfaceSession.java
private long mNativeClient; // SurfaceComposerClient*

public SurfaceSession() {
    //native 方法
    mNativeClient = nativeCreate();
}

> frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    // 新建一個(gè) SurfaceComposerClient 對(duì)象
    SurfaceComposerClient* client = new SurfaceComposerClient();
    client->incStrong((void*)nativeCreate);
    //返回SurfaceComposerClient對(duì)象的引用到j(luò)ava層。
    return reinterpret_cast<jlong>(client);
}

SurfaceComposerClient 是什么呢?

2.3.2 SurfaceComposerClient

在 SurfaceComposerClient第一次被引用的時(shí)候會(huì)走onFirstRef()方法。

> frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
    //創(chuàng)建sf代理binder對(duì)象sf,類型為 ISurfaceComposer
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        //創(chuàng)建一個(gè) ISurfaceComposerClient 對(duì)象,用來(lái)跨進(jìn)程調(diào)用
        conn = sf->createConnection();
        if (conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}
  • ISurfaceComposer 實(shí)現(xiàn)類就是 SurfaceFlinger對(duì)象。在server進(jìn)程的代理對(duì)象是 ComposerService。This class defines the Binder IPC interface for accessing various SurfaceFlinger features.
  • 通過(guò)SF.createConnection(),創(chuàng)建一個(gè) ISurfaceComposerClient 對(duì)象 mClient,用來(lái)跨進(jìn)程調(diào)用。

那么 ISurfaceComposerClient的實(shí)現(xiàn)類是哪個(gè)呢? 繼續(xù)看看 SF.createConnection()。

2.3.3 SurfaceFlinger.createConnection()

注意,此時(shí)是在SF進(jìn)程。

> frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    // new client對(duì)象。
    return initClient(new Client(this));
}
static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        // 返回該對(duì)象
        return client;
    }
    return nullptr;
}
> frameworks/native/services/surfaceflinger/Client.h
class Client : public BnSurfaceComposerClient{...
  class BnSurfaceComposerClient : public SafeBnInterface<ISurfaceComposerClient> {...

原來(lái),ISurfaceComposerClient的實(shí)現(xiàn)類就是 SF中定義的 Client。也是一個(gè)binder服務(wù)。 我們回到 SurfaceComposerClient 類,它持有 ISurfaceComposerClient的binder引用 mClient。通過(guò) mClient實(shí)現(xiàn)與SF通信。

2.3 小結(jié)

  • Session 類中,創(chuàng)建了一個(gè) SurfaceSession 對(duì)象,內(nèi)部引用c++層的 SurfaceComposerClient 對(duì)象。
  • SurfaceComposerClient 對(duì)象是通過(guò)SF創(chuàng)建的另一個(gè)binder服務(wù)。減輕SF的工作量。
  • SurfaceComposerClient 對(duì)象則通過(guò) mClient成員(ISurfaceComposerClient)代理binder,后續(xù)用來(lái)創(chuàng)建 Surface。

到目前為止,WMS中應(yīng)用進(jìn)程對(duì)應(yīng)的Session對(duì)象已經(jīng)建立了與SF的聯(lián)系。

三、Surface的創(chuàng)建

3.1 Java層的Surface

ViewRootImpl 類成員變量 :

ViewRootImpl.java

// 任何線程都可以訪問(wèn)這個(gè)對(duì)象,只需要加鎖就可以了。
public final Surface mSurface = new Surface();

調(diào)用的是空參構(gòu)造,因此 此時(shí)的Surface只是Java層的空殼而已。

3.2 App端的 relayoutWindow()

當(dāng)SF收到vsync信號(hào)后,通過(guò)Choreographer監(jiān)聽(tīng),分發(fā)到app進(jìn)程。app收到vsync信號(hào)后doFrame(),再到主線程調(diào)用 doTraversal() ->performTraversals():

> ViewRootImpl.java
private void performTraversals() {
    // 調(diào)用 relayoutWindow 
    relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
    //...
    
    // Ask host how big it wants to be
    // 三大流程
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    //...
    performLayout(lp, mWidth, mHeight);
    //```
    performDraw();
    //...
}
    > ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
    boolean insetsPending) throws RemoteException {
    //...
    // 1  mWindowSession是 IWindowSession 對(duì)象,調(diào)用relayout()
     int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
                 // 此處傳入的  mSurfaceControl對(duì)象 
                mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
                
        if (mSurfaceControl.isValid()) {
            // 2 從 mSurfaceControl 中復(fù)制 surface 
            mSurface.copyFrom(mSurfaceControl);
        } else {
            // 無(wú)效,則銷毀
            destroySurface();
        }
        
     //... 
    return relayoutResult;
}
  • relayout() 傳入 mSurfaceControl,跨進(jìn)程調(diào)用到了WMS端。
  • copyFrom() ,從 mSurfaceControl 中獲取 Surface。

SurfaceControl 是啥?

SurfaceControl 可以控制一個(gè)被合成系統(tǒng)管理的、正在屏幕上顯示的surface。它是Buffer數(shù)據(jù)和窗口的metadata的鏈接器。 通過(guò)這個(gè) SurfaceControl構(gòu)造的surface,app可以直接提交buffer數(shù)據(jù)到合成系統(tǒng)進(jìn)行合成。此外還可以通過(guò)SurfaceControl.Transaction 來(lái)修改buffer的被顯示的屬性。如旋轉(zhuǎn)、平移、裁剪。

3.3 SurfaceControl空參構(gòu)造

是 ViewRootImpl 類成員變量:

private final SurfaceControl mSurfaceControl = new SurfaceControl();

SurfaceControl 的空參構(gòu)造方法,啥都沒(méi)干!目前也是個(gè)空殼。

3.4 小結(jié)

目前可以看出,在開(kāi)始繪制時(shí),調(diào)用了WMS的session.relayout(SurfaceControl mSurfaceControl)方法之后。就可以從SurfaceControl中得到 Surface對(duì)象。

那 session.relayout() 內(nèi)部是如何做到的呢? 繼續(xù)看 Session.relayout()。

3.5 WMS端 Session.relayout()

>Session.java
@Override
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
        int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
        Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets,
        Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
        DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
        SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
        
    // 繼續(xù)調(diào)用 WMS的 relayoutWindow()
    int res = mService.relayoutWindow(this, window, seq, attrs,
            requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
            outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
            outStableInsets, outsets, outBackdropFrame, cutout,
            mergedConfiguration, outSurfaceControl, outInsetsState);
    return res;
}
 > WMS.java
outSurfaceControl 從app進(jìn)程傳遞到了WMS進(jìn)程。 表示結(jié)果接收。它實(shí)現(xiàn)了parcelable接口,跨進(jìn)程傳遞到了WMS中。
public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
        int requestedWidth, int requestedHeight, int viewVisibility, int flags,
        long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
        Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
        DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,
        SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
        //...
        try {
            //調(diào)用 createSurfaceControl
            result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
        } catch (Exception e) {
            ...
        }
        //...
        
}           
> WMS.java
private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win,
        WindowStateAnimator winAnimator) {
    if (!win.mHasSurface) {
        result |= RELAYOUT_RES_SURFACE_CHANGED;
    }
    // 聲明一個(gè) WindowSurfaceController
    WindowSurfaceController surfaceController;
    
    try {
        //1  創(chuàng)建 WindowSurfaceController 對(duì)象
        surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
    } finally {
    }
    if (surfaceController != null) {
        // 2 從得到 WindowSurfaceController 對(duì)象中,獲取 SurfaceController
        surfaceController.getSurfaceControl(outSurfaceControl);
    } else {
        // For some reason there isn't a surface.  Clear the
        // caller's object so they see the same state.
        Slog.w(TAG_WM, "Failed to create surface control for " + win);
        outSurfaceControl.release();
    }

    return result;
}

最終:

  • winAnimator.createSurfaceLocked()得到WindowSurfaceController對(duì)象
  • 從得到 WindowSurfaceController 對(duì)象中,獲取 SurfaceController,返回給outSurfaceControl

winAnimator 是 WindowStateAnimator類型。

3.5.1 winAnimator.createSurfaceLocked()

> WindowStateAnimator.java
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
    final WindowState w = mWin;

    if (mSurfaceController != null) {
        // 如果有,則返回
        return mSurfaceController;
    }
    //...
    // Set up surface control with initial size.
    try {
        // 否則創(chuàng)建一個(gè) WindowSurfaceController
        mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
                attrs.getTitle().toString(), width, height, format, flags, this,
                windowType, ownerUid);
        // ...
    } catch (OutOfResourcesException e) {
     //...
     }
    return mSurfaceController;
}

createSurfaceLocked() 就是創(chuàng)建了一個(gè) WindowSurfaceController 對(duì)象。WindowSurfaceController的構(gòu)造方法中會(huì)創(chuàng)建一個(gè)SurfaceControl對(duì)象。

3.5.2 WindowSurfaceController構(gòu)造方法

> WindowSurfaceController.java
public WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format,
        int flags, WindowStateAnimator animator, int windowType, int ownerUid) {
    mAnimator = animator;
    mSurfaceW = w;
    mSurfaceH = h;

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

    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
    // 1 調(diào)用的是 WindowState的 makeSurface()方法
    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, ownerUid);
            // 2 創(chuàng)建SurfaceControl對(duì)象 
    mSurfaceControl = b.build();
    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
  >SurfaceControl.java 
  public SurfaceControl build() {
            if (mWidth < 0 || mHeight < 0) {
                throw new IllegalStateException(
                        "width and height must be positive or unset");
            }
            if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) {
                throw new IllegalStateException(
                        "Only buffer layers can set a valid buffer size.");
            }
            // 創(chuàng)建對(duì)象 ,調(diào)用了 SurfaceControl的有參構(gòu)造方法。
            return new SurfaceControl(
                    mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata);
        }

調(diào)用SurfaceControl的有參構(gòu)造方法,構(gòu)造了一個(gè)SurfaceControl對(duì)象。 還記得在3. 3,ViewRootImpl的成員變量mSurfaceControl,調(diào)用的是空參構(gòu)造,啥都沒(méi)做。

但是,現(xiàn)在SurfaceControl的有參構(gòu)造做了什么呢? 我們深入看看。

SurfaceControl的有參構(gòu)造:

long mNativeObject; // package visibility only for Surface.java access
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
        SurfaceControl parent, SparseIntArray metadata)
                throws OutOfResourcesException, IllegalArgumentException {
                //... 
                
                //注意這里第一個(gè)參數(shù)是  SurfaceSession
        mNativeObject = nativeCreate(session, name, w, h, format, flags,
                            parent != null ? parent.mNativeObject : 0, metaParcel);
}

>frameworks/base/core/jni/android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
        jobject metadataParcel) {
    ScopedUtfChars name(env, nameStr);
    //這個(gè)就是之前創(chuàng)建 SurfaceSession創(chuàng)建時(shí)候的 SurfaceComposerClient對(duì)象。SF的代理服務(wù)。
    sp<SurfaceComposerClient> client;
    if (sessionObj != NULL) {
        // 之前創(chuàng)建的 mClient
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
        
        client = SurfaceComposerClient::getDefault();
    }
    // 父 SurfaceControl
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
    // 聲明 SurfaceControl
    sp<SurfaceControl> surface;
    // 窗口的 metadata。 因?yàn)镾urfaceControl 本身就是 surface和 metadata的接合器。
    LayerMetadata metadata;
    
    Parcel* parcel = parcelForJavaObject(env, metadataParcel);
    if (parcel && !parcel->objectsCount()) {
        status_t err = metadata.readFromParcel(parcel);
        if (err != NO_ERROR) {
          jniThrowException(env, "java/lang/IllegalArgumentException",
                            "Metadata parcel has wrong format");
        }
    }
    // 調(diào)用SF進(jìn)程的 createSurfaceChecked(),創(chuàng)建surface對(duì)象 
    status_t err = client->createSurfaceChecked(
            String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));
    if (err == NAME_NOT_FOUND) {
        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
        return 0;
    } else if (err != NO_ERROR) {
        jniThrowException(env, OutOfResourcesException, NULL);
        return 0;
    }

    surface->incStrong((void *)nativeCreate);
    // 返回 SurfaceControl的 jlong 引用 
    return reinterpret_cast<jlong>(surface.get());
}

>frameworks/native/libs/gui/SurfaceComposerClient.cpp
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;
        // gpb,buffer數(shù)據(jù)的生產(chǎn)者
        sp<IGraphicBufferProducer> gbp;

        uint32_t transformHint = 0;
        int32_t id = -1;
        // mClient 具體實(shí)現(xiàn)類是 SF的Client服務(wù) 。來(lái)創(chuàng)建surface
        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) {
            // 終于創(chuàng)建了一個(gè)native層的 SurfaceControl對(duì)象。注意,此時(shí)是native層的有參構(gòu)造??!
            *outSurface =
                    new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
        }
    }
    return err;
}
繼續(xù)看native層的有參構(gòu)造: 
>frameworks/native/libs/gui/SurfaceControl.cpp
SurfaceControl::SurfaceControl(
        const sp<SurfaceComposerClient>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbp,
        bool owned)
    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)
    //賦值了一些成員變量
{
}

總結(jié):

  • WMS 的relayout() 通過(guò) WindowSurfaceControl對(duì)象來(lái)創(chuàng)建 SurfaceControl 對(duì)象。此時(shí)的 SurfaceControl對(duì)象,不僅僅存在java層,也會(huì)在native層創(chuàng)建一個(gè)SurfaceControl對(duì)象。
  • native層中,內(nèi)部會(huì)通過(guò)之前建立連接surfaceSession來(lái)向SF請(qǐng)求buffer、metadata等信息,給SurfaceControl對(duì)象賦值。

注意,以上的邏輯還是在WMS的native層。 而跨進(jìn)程的 createSurface()調(diào)用到底干了啥?

3.6 SF端 ISurfaceComposerClient.createSurface()

此時(shí)進(jìn)入SF進(jìn)程。 Client 就是 ISurfaceComposerClient 的實(shí)現(xiàn)類。

frameworks/native/services/surfaceflinger/Client.cpp
status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                               uint32_t flags, const sp<IBinder>& parentHandle,
                               LayerMetadata metadata, sp<IBinder>* handle,
                               sp<IGraphicBufferProducer>* gbp) {
    // We rely on createLayer to check permissions.
    // 終于調(diào)用了SF。 創(chuàng)建一個(gè)layer
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle);
}
> frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 
status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                     uint32_t h, PixelFormat format, uint32_t flags,
                                     LayerMetadata metadata, sp<IBinder>* handle,
                                     sp<IGraphicBufferProducer>* gbp,
                                     const sp<IBinder>& parentHandle,
                                     const sp<Layer>& parentLayer) {
    if (int32_t(w|h) < 0) {
       // 寬高不能為負(fù)數(shù)
        return BAD_VALUE;
    }
    status_t result = NO_ERROR;
    // 聲明一個(gè) layer對(duì)象
    sp<Layer> layer; 

    String8 uniqueName = getUniqueLayerName(name);
    // metadata
    if (metadata.has(METADATA_WINDOW_TYPE)) {
        int32_t windowType = metadata.getInt32(METADATA_WINDOW_TYPE, 0);
        if (windowType == 441731) {
            metadata.setInt32(METADATA_WINDOW_TYPE, InputWindowInfo::TYPE_NAVIGATION_BAR_PANEL);
            primaryDisplayOnly = true;
        }
    }
    // 根據(jù)flag 創(chuàng)建不同的layer對(duì)象。
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
            // 1 創(chuàng)建bufferQueue,只看這一種
            result = createBufferQueueLayer(client, uniqueName, w, h, flags, std::move(metadata),
                                            format, handle, gbp, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceBufferState:
            result = createBufferStateLayer(client, uniqueName, w, h, flags, std::move(metadata),
                                            handle, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceColor:
        case ISurfaceComposerClient::eFXSurfaceContainer:
           ...
        default:
            result = BAD_VALUE;
            break;
    }
   ...
    // 2 繼續(xù)調(diào)用 addClientLayer
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                            addToCurrentState);
    ...
    return result;
}
  • 創(chuàng)建了 BufferQueueLayer 對(duì)象,里面持有 sp<BufferLayerConsumer> mConsumer和 sp<IGraphicBufferProducer> mProducer,也就是GraphicBuffer的生產(chǎn)者和消費(fèi)者對(duì)象。
  • 加入到 layers 全局的集合中。

3.6.1 SF.createBufferQueueLayer()

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, const String8& name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, PixelFormat& format,
                                                sp<IBinder>* handle,
                                                sp<IGraphicBufferProducer>* gbp,
                                                sp<Layer>* outLayer) {
    // initialize the surfaces
    // 格式
    switch (format) {
    case PIXEL_FORMAT_TRANSPARENT:
    case PIXEL_FORMAT_TRANSLUCENT:
        format = PIXEL_FORMAT_RGBA_8888;
        break;
    case PIXEL_FORMAT_OPAQUE:
        format = PIXEL_FORMAT_RGBX_8888;
        break;
    }
    // 創(chuàng)建layer
    sp<BufferQueueLayer> layer = getFactory().createBufferQueueLayer(
            LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));
    status_t err = layer->setDefaultBufferProperties(w, h, format);
    if (err == NO_ERROR) {
        // 賦值 gbp生產(chǎn)者 
        *handle = layer->getHandle();
        *gbp = layer->getProducer();
        *outLayer = layer;
    }
    ALOGE_IF(err, "createBufferQueueLayer() failed (%s)", strerror(-err));
    return err;
}

3.6.2 SurfaceFlingerFactory.createBufferQueueLayer

frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) override {
            return new BufferQueueLayer(args);
        }

3.6.3 BufferQueueLayer 構(gòu)造方法

繼承關(guān)系:

class BufferQueueLayer : public BufferLayer, public BufferLayerConsumer::ContentsChangedListener 
{...
class BufferLayer : public Layer {...

3.6.4 BufferQueueLayer.onFirstRef()

void BufferQueueLayer::onFirstRef() {
    BufferLayer::onFirstRef();

    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    // 聲明生產(chǎn)者和消費(fèi)者 
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    // BufferQueue 初始化
    BufferQueue::createBufferQueue(&producer, &consumer, true);
    // MonitoredProducer分裝了 producer,方便SF監(jiān)聽(tīng)
    mProducer = new MonitoredProducer(producer, mFlinger, this);
    {
        // Grab the SF state lock during this since it's the only safe way to access RenderEngine
        Mutex::Autolock lock(mFlinger->mStateLock);
        // 封裝了BufferLayerConsumer封裝了 consumer
        mConsumer =
           new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);
    }
    mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mConsumer->setContentsChangedListener(this);
    mConsumer->setName(mName);

    // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
    if (!mFlinger->isLayerTripleBufferingDisabled()) {
      //設(shè)置為2
        mProducer->setMaxDequeuedBufferCount(2);
    }

    if (const auto display = mFlinger->getDefaultDisplayDevice()) {
        updateTransformHint(display);
    }
}

重點(diǎn):

  • 聲明了 sp<IGraphicBufferProducer> producersp<IGraphicBufferConsumer> consumer;
  • 調(diào)用 BufferQueue::createBufferQueue(&producer, &consumer, true);來(lái)創(chuàng)建這兩個(gè)對(duì)象。

3.6.5 BufferQueue::createBufferQueue()

frameworks/native/libs/gui/BufferQueue.cpp

void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
        sp<IGraphicBufferConsumer>* outConsumer,
        bool consumerIsSurfaceFlinger) {
    // BufferQueueCore 對(duì)象
    sp<BufferQueueCore> core(new BufferQueueCore());
    //BufferQueueProducer 生產(chǎn)對(duì)象
    sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
    // BufferQueueConsumer 消費(fèi)對(duì)象
    sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));

    *outProducer = producer;
    *outConsumer = consumer;
}
 static constexpr int NUM_BUFFER_SLOTS = 64;

因此,producer和consumer 真正的實(shí)現(xiàn)者就是 BufferQueueProducer 和 BufferQueueConsumer。

3.7 Client.attachLayer()

最終,加入全局的mLayers中。

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

至此,SF創(chuàng)建了 layer 對(duì)象,并且加入了Client服務(wù)的 mLayers列表中。layer中持有 sp<IGraphicBufferProducer> producer和 sp<IGraphicBufferConsumer> consumer;兩個(gè)對(duì)象。具體的實(shí)現(xiàn)者就是 BufferQueueProducer 和 BufferQueueConsumer

3.6 小結(jié)

在回顧下總體流程:

  • App端 調(diào)用WMS的 relayoutWindow(MSurfaceControl),傳入的是一個(gè)空SurfaceControl對(duì)象-A(空參構(gòu)造)。
  • WMS端生成了java層的另一個(gè)SurfaceControl對(duì)象-B(有參構(gòu)造)。同時(shí)在native層也生成了一個(gè)SurfaceControl對(duì)象。 內(nèi)部通過(guò)IComposerClient對(duì)象,調(diào)用了SF的createSurface()方法。同時(shí)持有 IGraphicBufferProducer gbp的引用。
  • SF端生成了Layer對(duì)象,同時(shí)生成了buffer生產(chǎn)者sp<IGraphicBufferProducer>和buffer消費(fèi)者的sp<IGraphicBufferConsumer>。

接下來(lái),從app端傳過(guò)來(lái)的 SurfaceControl-A如何跟 SurfaceControl-B關(guān)聯(lián)起來(lái)呢?當(dāng)然是通過(guò)getSurfaceControl()方法了。

3.7 WindowSurfaceController.getSurfaceControl()

WindowSurfaceController.java

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

mSurfaceControl 就是 WindowSurfaceController 中持有之前創(chuàng)建的 SurfaceControl-B對(duì)象。 當(dāng)前的 outSurfaceControl 是app傳遞過(guò)來(lái)的。 繼續(xù)看 copyFrom():

3.8 SurfaceControl.copyFrom()

>SurfaceControl.java
public void copyFrom(SurfaceControl other) {
    mName = other.mName;
    mWidth = other.mWidth;
    mHeight = other.mHeight;
    assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject));
}

3.8.1 nativeCopyFromSurfaceControl()

>frameworks/base/core/jni/android_view_SurfaceControl.cpp
static jlong nativeCopyFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
    // 根據(jù)引用值,得到native層的 SurfaceControl。此時(shí)是WMS的SurfaceControl對(duì)象-B
    sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
    if (surface == nullptr) {
        return 0;
    }
    // 創(chuàng)建一個(gè)新的native的SurfaceControl對(duì)象C,調(diào)用的是有參構(gòu)造方法
    sp<SurfaceControl> newSurface = new SurfaceControl(surface);
    newSurface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(newSurface.get());
}

// 有參構(gòu)造
SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
    mClient = other->mClient;
    mHandle = other->mHandle;
    mGraphicBufferProducer = other->mGraphicBufferProducer;
    mTransformHint = other->mTransformHint;
    mLayerId = other->mLayerId;
    mWidth = other->mWidth;
    mHeight = other->mHeight;
    mCreateFlags = other->mCreateFlags;
}

native層創(chuàng)建了一個(gè)新的SurfaceControl對(duì)象。

3.8.2 assignNativeObject()

SurfaceControl.java

private void assignNativeObject(long nativeObject) {
// 傳入的是 上一步新創(chuàng)建的native層的 SurfaceControl對(duì)象C。
    if (mNativeObject != 0) {
        // 釋放之前的 
        release();
    }
    // 持有引用。
    mNativeObject = nativeObject;
}

至此,app端的Java層的SurfaceControl對(duì)象就與native層的SurfaceControl對(duì)象聯(lián)系了起來(lái)。創(chuàng)建完成后,返回到app端 ViewRootImpl 的relayoutWindow()方法中。

3.9 mSurface.copyFrom()

Surface.java

public void copyFrom(SurfaceControl other) {
    // 從surfaceControl 拷貝
    if (other == null) {
        throw new IllegalArgumentException("other must not be null");
    }
    // 獲取 SurfaceControl的 native對(duì)象引用
    long surfaceControlPtr = other.mNativeObject;
    if (surfaceControlPtr == 0) {
        throw new NullPointerException(
                "null SurfaceControl native object. Are you using a released SurfaceControl?");
    }
    // 從native層獲取surface對(duì)象的引用 
    long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
    
    //上鎖
    synchronized (mLock) {
        // 同一個(gè)對(duì)象,則不做操作
        if (newNativeObject == mNativeObject) {
            return;
        }
        if (mNativeObject != 0) {
            // 釋放之前的
            nativeRelease(mNativeObject);
        }
        // 設(shè)置新的引用
        setNativeObjectLocked(newNativeObject);
    }
}

3.9.1 nativeGetFromSurfaceControl()

frameworks/base/core/jni/android_view_Surface.cpp

static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
        jlong nativeObject,
        jlong surfaceControlNativeObj) {
    //拿到 java層引用的c++ surface對(duì)象
    Surface* self(reinterpret_cast<Surface *>(nativeObject));
    // 獲取c++層的 SurfaceControl對(duì)象
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));

    // If the underlying IGBP's are the same, we don't need to do anything.
    // 如果 surface對(duì)象和 SurfaceControl對(duì)象的 gbp一樣,則不需要重新設(shè)值。
    if (self != nullptr &&
            IInterface::asBinder(self->getIGraphicBufferProducer()) ==
            IInterface::asBinder(ctrl->getIGraphicBufferProducer())) {
            // 返回即可
        return nativeObject;
    }
    // 如果gbp不一樣,在重新構(gòu)造一個(gè)
    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }
    // 返回引用
    return reinterpret_cast<jlong>(surface.get());
}

邏輯已經(jīng)注釋清楚了。問(wèn)題是 SurfaceControl 的getSurface()如何工作的?

3.9.2 native層 SurfaceControl::getSurface()

frameworks/native/libs/gui/SurfaceControl.cpp

sp<Surface> SurfaceControl::getSurface()
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == nullptr) {
        // 創(chuàng)建一個(gè)Surface
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}
mutable sp<SurfaceControl> mBbqChild;
sp<Surface> SurfaceControl::generateSurfaceLocked()
{
    uint32_t ignore;
    auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
                                 ISurfaceComposerClient::eOpaque);
     // 通過(guò) ISurfaceComposerClient,調(diào)用到SF進(jìn)程中                            
    mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
                                       flags, mHandle, {}, &ignore);
     // mbbq是 SurfaceControl                                  
    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.
    // 創(chuàng)建 surface
    mSurfaceData = mBbq->getSurface(true);
    return mSurfaceData;
}

3.9.3 Surface.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);
}

3.9.4 BBQSurface

// 繼承了surface 
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) {}

    void allocateBuffers() override {
        uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
        uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
        auto gbp = getIGraphicBufferProducer();
        std::thread ([reqWidth, reqHeight, gbp=getIGraphicBufferProducer(),
                      reqFormat=mReqFormat, reqUsage=mReqUsage] () {
            // 請(qǐng)求 allocateBuffers          
            gbp->allocateBuffers(reqWidth, reqHeight,
                                 reqFormat, reqUsage);

        }).detach();
    }

3.10 小結(jié)

在app端的SurfaceControl與native層的 SurfaceControl對(duì)象建立聯(lián)系后。 app端Java層的Surface通過(guò) copyFrom()方法,從native層的 SurfaceControl中拿到了 native層的 Surface對(duì)象,內(nèi)部持有 IGraphicProducer gbp對(duì)象??梢院蚐F通信。

四、總結(jié)

  • App端 調(diào)用WMS的 relayoutWindow(MSurfaceControl),傳入的是一個(gè)空SurfaceControl對(duì)象-A(空參構(gòu)造)。
  • WMS端生成了java層的另一個(gè)SurfaceControl對(duì)象-B(有參構(gòu)造)。同時(shí)在native層也生成了一個(gè) SurfaceControl 對(duì)象。內(nèi)部通過(guò)IComposerClient對(duì)象,調(diào)用了SF的createSurface()方法。同時(shí)持有 IGraphicBufferProducer gbp的引用
  • SF端生成了Layer對(duì)象,同時(shí)生成了buffer生產(chǎn)者sp<IGraphicBufferProducer>和buffer消費(fèi)者的sp<IGraphicBufferConsumer>
  • WMS端通過(guò)copy()方法讓 App端傳遞過(guò)來(lái)的 SurfaceControl-A對(duì)象也引用到了SF的 IGraphicBufferProducer。
  • 在App端的 SurfaceControl-A對(duì)象唄賦值后,再通過(guò)Surface對(duì)象的copyFrom()方法,讓 JavaSurfaceNative層的Surface建立聯(lián)系。最終,也就是和SFIGraphicBufferProducer 建立了聯(lián)系。

到此這篇關(guān)于基于Android10渲染Surface的創(chuàng)建過(guò)程的文章就介紹到這了,更多相關(guān)Android Surface內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論