日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Android的Surface的创建

發布時間:2023/12/19 综合教程 21 生活家
生活随笔 收集整理的這篇文章主要介紹了 Android的Surface的创建 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ViewRootImpl管理著整個view tree。 對于ViewRootImpl.setView(),我們可以簡單的把它當做一個UI渲染操作的入口。

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/WindowManagerImpl.java

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    ...
    //mWindowSession是一個aidl,ViewRootImpl利用它來和WindowManagerService交互
    //mWindow是一個aidl,WindowManagerService可以利用這個對象與服務端交互
    //mAttachInfo可以理解為是一個data bean,可以跨進程傳遞
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
            getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
            mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
    ...
}

ViewRootImpl.setView()方法會向WindowManagerService請求添加一個Window,mWindowSession.addToDisplay()跨進程最終調用到了WindowManagerService.addWindow():
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public int addWindow(Session session, IWindow client...) {
    ...
    //WindowState用來描述一個Window
    final WindowState win = new WindowState(this, session, client, token, parentWindow,
                appOp[0], seq, attrs, viewVisibility, session.mUid,
                session.mCanAddInternalSystemWindow);
    ...
    win.attach();  //會創建一個SurfaceSession

    mWindowMap.put(client.asBinder(), win); //mWindowMap是WindowManagerService用來保存當前所有Window新的的集合
    ...
    win.mToken.addWindow(win); //一個token下會有多個win state。 其實token與PhoneWindow是一一對應的。
    ...
}

http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowState.java

 void attach() {
       if (WindowManagerService.localLOGV) Slog.v(
            TAG, "Attaching " + this + " token=" + mToken
            + ", list=" + mToken.windows);
        mSession.windowAddedLocked();
   }

WindowStateWindowManagerService用來描述應用程序的一個Window的對象。上面注釋我標注了win.attach(),這個方法可以說是WindowSurfaceFlinger鏈接的起點,它最終會調用到Session.windowAddedLocked():
http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/Session.java

void windowAddedLocked(String packageName) {
    ...
    if (mSurfaceSession == null) { 
        ...
        mSurfaceSession = new SurfaceSession();
        ...
    }
}

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/SurfaceSession.java

//SurfaceSession類的構造方法
public final class SurfaceSession {
    private long mNativeClient; // SurfaceComposerClient*

    public SurfaceSession() {
        mNativeClient = nativeCreate(); 
}

這里調用了native方法nativeCreate(),這個方法其實是返回了一個SurfaceComposerClient指針。那這個對象是怎么創建的呢?

SurfaceComposerClient的創建

http://androidxref.com/6.0.1_r10/xref/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);
}

即構造了一個SurfaceComposerClient對象。并返回它的指針。這個對象一個應用程序就有一個,它是應用程序與SurfaceFlinger溝通的橋梁,為什么這么說呢?在SurfaceComposerClient指針第一次使用時會調用下面這個方法:

//這個方法在第一次使用SurfaceComposerClient的指針的時候會調用
void SurfaceComposerClient::onFirstRef() {
    ....
    sp<ISurfaceComposerClient> conn;
    //sf 就是SurfaceFlinger
    conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
            sf->createConnection();
    ...
}

即通過SurfaceFlinger(它本身具有跨進程通信的能力)創建了一個ISurfaceComposerClient對象:

http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    return initClient(new Client(this)); //initClient這個方法其實并沒有做什么,
}

即構造了一個Client對象,Client實現了ISurfaceComposerClient接口。是一個可以跨進程通信的aidl對象。即SurfaceComposerClient可以通過它來和SurfaceFlinger通信。除此之外它還可以創建Surface,并且維護一個應用程序的所有Layer(下文會分析到它是什么)。它是一個十分重要的對象,我們先來看一下它的組成,它所涉及的其他東西在下文分析中都會講到:
http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/Client.h

class Client : public BnSurfaceComposerClient
{
public:
    ...
    void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer);
    void detachLayer(const Layer* layer);
    ...
private:
    // ISurfaceComposerClient interface。   gbp很重要,它維護這一個應用程序的渲染 Buffer隊列
    virtual status_t createSurface(...sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp);

    virtual status_t destroySurface(const sp<IBinder>& handle); 

    //跨進程通信方法
    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
    ...

    // constant
    sp<SurfaceFlinger> mFlinger;

    // protected by mLock
    DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers; // 一個應用程序的所有Layer
    ...
};

經過上面這一頓源碼分析,我們大概知道了ViewRootImpl.setView()所引發的主要操作:

WindowManagerService創建了一個WindowState。用來表示客戶端的一個Window
WindowManagerService創建了一個SurfaceSession,SurfaceSession會與SurfaceFlinger構建鏈接,創建了一個SurfaceComposerClient對象,一個應用程序只具有一個這個對象。
SurfaceComposerClient創建了一個Client, 這個對象十分重要,它維護這應用程序的渲染核心數據,并負責與SurfaceFlinger通信。

經過上面的步驟,應用程序的ViewRootImpl已經被WindowManagerService識別,并且應用程序已經與SurfaceFlinger建立連接。即創建了SurfaceComposerClientClient對象

文章開始就已經說了SurfaceWindow(ViewRootImpl)的UI載體,那Surface是在哪里創建的呢?

Surface的創建

其實一個ViewRootImpl就對應一個Surface。

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/Surface.java

這點可以通過ViewRootImpl的源碼看出:

ViewRootImpl在構造的時候就new 了一個 Surface。但其實這個新new的Surface并沒有什么邏輯,它的構造函數是空的。

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/ViewRootImpl.java

public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
//...
public final Surface mSurface = new Surface();
//...
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    ...
    requestLayout(); //susion 請求layout。先添加到待渲染隊列中  
    ...
    res = mWindowSession.addToDisplay(mWindow, ...); //WindowManagerService會創建mWindow對應的WindowState
    ...
}
 @Override
public void requestLayout() { if (!mHandlingLayoutInLayoutRequest) { checkThread(); mLayoutRequested = true; scheduleTraversals(); } } }

即在向WindowManagerService請求創建WindowState之前,調用了requestLayout(),這個方法會引起ViewRootImpl所管理的整個view tree的重新渲染。它最終會調用到scheduleTraversals():

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/ViewRootImpl.java

void scheduleTraversals() {
    ...
    mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
    ...
}

scheduleTraversals()會通過Choreographer來post一個mTraversalRunnable,Choreographer接收顯示系統的時間脈沖(垂直同步信號-VSync信號,16ms發出一次),在下一個frame渲染時控制執行這個mTraversalRunnable。

但是mTraversalRunnable的執行至少要在應用程序與SurfaceFlinger建立連接之后。這是因為渲染操作是由SurfaceFlinger負責調度了,如果應用程序還沒有與SurfaceFlinger創建連接,那SurfaceFlinger當然不會渲染這個應用程序。所以在執行完mWindowSession.addToDisplay(mWindow, ...)之后,才會執行mTraversalRunnable:

final class TraversalRunnable implements Runnable {
    @Override
    public void run() {
        doTraversal();
    }
}

doTraversal()會調用到ViewRootImpl.performTraversals(),大部分同學可能知道這個方法是一個view treemeasure/layout/draw的控制方法:

private void performTraversals() {
    finalView host = mView; //mView是一個Window的根View,對于Activity來說就是DecorView
    ...
    relayoutWindow(params, viewVisibility, insetsPending);
    ...
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    ...         
    performLayout(lp, mWidth, mHeight);
    ...
    performDraw();
    ...
}

Surface的具體創建就由relayoutWindow(params, viewVisibility, insetsPending)這個方法來完成的。這個方法會通過IPC調用到WindowManagerService.relayoutWindow():

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/ViewRootImpl.java

private int relayoutWindow(WindowManager.LayoutParams params, ...) throws RemoteException {
    ...
    int relayoutResult = mWindowSession.relayout(mWindow,..., mSurface);
    ...
}

mWindowSession.relayout()方法的很多參數,不過有一個十分重要的參數我沒有省略,就是mSurface。前面已經分析了它就是一個空的Surface對象。其實:

真正的Surface創建是由SurfaceControl完成的,應用程序ViewRootImplSurface只是一個指針,指向這個Surface

下面就來看一下SurfaceControl是如何創建Surface的:

mWindowSession.relayout()會調用到WindowManagerService.relayoutWindow():

http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

 //這里的outSurface其實就是ViewRootImpl中的那個Surface
public int relayoutWindow(Session session, IWindow client....Surface outSurface){ 
    ...
    result = createSurfaceControl(outSurface, result, win, winAnimator);  
    ...
}

private int createSurfaceControl(Surface outSurface, int result, WindowState win,WindowStateAnimator winAnimator) {
    ...
    surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
    ...
    surfaceController.getSurface(outSurface);
}

winAnimator.createSurfaceLocked實際上是創建了一個SurfaceControl。即上面是先構造SurfaceControl,然后在構造Surface

http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java

 SurfaceControl createSurfaceLocked() {
        final WindowState w = mWin;
        if (mSurfaceControl == null) {
           //...
             mSurfaceFormat = format;
                if (DEBUG_SURFACE_TRACE) {
                    mSurfaceControl = new SurfaceTrace(
                            mSession.mSurfaceSession,
                            attrs.getTitle().toString(),
                            width, height, format, flags);
                } else {
                    mSurfaceControl = new SurfaceControl(
                        mSession.mSurfaceSession,
                        attrs.getTitle().toString(),
                        width, height, format, flags);
                }
             //...
        }
        return mSurfaceControl;
    }        

SurfaceControl的創建

winAnimator.createSurfaceLocked其實是通過SurfaceControl的構造函數創建了一個SurfaceControl對象,這個對象的作用其實就是負責維護Surface,Surface其實也是由這個對象負責創建的,我們看一下這個對象的構造方法:

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/SurfaceControl.java

long mNativeObject; //成員指針變量,指向native創建的SurfaceControl

private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,
            SurfaceControl parent, int windowType, int ownerUid){
    ...
    mNativeObject = nativeCreate(session, name, w, h, format, flags,
        parent != null ? parent.mNativeObject : 0, windowType, ownerUid);
    ...
}

即調用了nativeCreate()并返回一個SurfaceControl指針:

http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceControl.cpp

static jlong nativeCreate(JNIEnv* env, ...) {
    //這個client其實就是前面創建的SurfaceComposerClinent
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); 
    sp<SurfaceControl> surface; //創建成功之后,這個指針會指向新創建的SurfaceControl
    status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface, flags, parent, windowType, ownerUid);
    ...
    return reinterpret_cast<jlong>(surface.get()); //返回這個SurfaceControl的地址
}

即調用到SurfaceComposerClient.createSurfaceChecked():

http://androidxref.com/6.0.1_r10/xref/frameworks/native/libs/gui/SurfaceComposerClient.cpp

//outSurface會指向新創建的SurfaceControl
status_t SurfaceComposerClient::createSurfaceChecked(...sp<SurfaceControl>* outSurface..) 
{
    sp<IGraphicBufferProducer> gbp; //這個對象很重要
    ...
    err = mClient->createSurface(name, w, h, format, flags, parentHandle, windowType, ownerUid, &handle, &gbp);
    if (err == NO_ERROR) {
        //SurfaceControl創建成功, 指針賦值
        *outSurface = new SurfaceControl(this, handle, gbp, true);
    }
    return err;
}

上面這個方法實際上是調用Client.createSurface()來創建一個Surface。在創建時有一個很重要的參數sp<IGraphicBufferProducer> gbp,在下面源碼分析中我們也要重點注意它。這是因為應用所渲染的每一幀,實際上都會添加到IGraphicBufferProducer中,來等待SurfaceFlinger的渲染。
http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/Client.cpp

status_t Client::createSurface(...)
{
    ...
    //gbp 直接透傳到了SurfaceFlinger
    return mFlinger->createLayer(name, this, w, h, format, flags, windowType, ownerUid, handle, gbp, &parent);
}

SurfaceSurfaceFlinger中對應的實體其實是Layer

我們繼續看一下mFlinger->createLayer()

http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::createLayer(const String8& name,const sp<Client>& client...)
{
    status_t result = NO_ERROR;
    sp<Layer> layer; //將要創建的layer
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createBufferLayer(client,
                    uniqueName, w, h, flags, format,
                    handle, gbp, &layer); // 注意gbp,這時候還沒有構造呢!
            break;
            ... //Layer 分為好幾種,這里不全部列出
    }
    ...
    result = addClientLayer(client, *handle, *gbp, layer, *parent);  //這個layer和client相關聯, 添加到Client的mLayers集合中。
    ...
    return result;
}

SurfaceFlinger.createLayer()方法可以看出Layer分為好幾種。我們這里只對普通的BufferLayer的創建做一下分析,看createBufferLayer():

http://androidxref.com/6.0.1_r10/xref/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::createBufferLayer(const sp<Client>& client... sp<Layer>* outLayer)
{
    ...
    sp<BufferLayer> layer = new BufferLayer(this, client, name, w, h, flags);
    status_t err = layer->setBuffers(w, h, format, flags);  //設置layer的寬高
    if (err == NO_ERROR) {
        *handle = layer->getHandle(); //創建handle
        *gbp = layer->getProducer(); //創建 gbp IGraphicBufferProducer
        *outLayer = layer; //把新建的layer的指針拷貝給outLayer,這樣outLayer就指向了新建的BufferLayer
    }
    return err;
}

前面我說過IGraphicBufferProducer(gbp)是一個很重要的對象,它涉及到SurfaceFlinger的渲染邏輯,下面我們就看一下這個對象的創建邏輯:

IGraphicBufferProducer(gbp)的創建

sp<IGraphicBufferProducer> BufferLayer::getProducer() const {
    return mProducer;
}

mProducer其實是Layer的成員變量,它的創建時機是Layer第一次被使用時:

void BufferLayer::onFirstRef() {
    ...
    BufferQueue::createBufferQueue(&producer, &consumer, true); 
    mProducer = new MonitoredProducer(producer, mFlinger, this);
    ...
}

所以mProducer的實例是MonitoredProducer,但其實它只是一個裝飾類,它實際功能都委托給構造它的參數producer:

BufferQueue.cpp

void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
    ...
    sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
    sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core)); //注意這個consumer
    ...
    *outProducer = producer;
    *outConsumer = consumer;
}

所以實際實現mProducer的工作的queueProducerBufferQueueProducer。

所以構造一個SurfaceControl所做的工作就是創建了一個SurfaceControl,并讓SurfaceFlinger創建了一個對應的LayerLayer中有一個IGraphicBufferProducer,它的實例是BufferQueueProducer

可以用下面這個圖來描述SurfaceControl的創建過程:

從SurfaceControl中獲取Surface

我們回看WindowManagerService.createSurfaceControl(), 來看一下java層的Surface對象到底是個什么:

http://androidxref.com/6.0.1_r10/xref/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private int createSurfaceControl(Surface outSurface, int result, WindowState win,WindowStateAnimator winAnimator) {
    ...
    surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
    ...
    surfaceController.getSurface(outSurface);
}

上面我們已經了解了winAnimator.createSurfaceLocked的整個過程,我們看一下surfaceController.getSurface(outSurface), surfaceControllerWindowSurfaceController的實例:

//WindowSurfaceController.java
void getSurface(Surface outSurface) {
    outSurface.copyFrom(mSurfaceControl);
}

//Surface.java
public void copyFrom(SurfaceControl other) {
    ...
    long surfaceControlPtr = other.mNativeObject;
    ...
    long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);
    ...
    mNativeObject = ptr; // mNativeObject指向native創建的Surface
}

Surface.copyFrom()方法調用nativeGetFromSurfaceControl()來獲取一個指針,這個指針是根據前面創建的SurfaceControl的指針來尋找的,即傳入的參數surfaceControlPtr:

android_view_Surface.cpp

static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj) {
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj)); //把java指針轉化內native指針
    sp<Surface> surface(ctrl->getSurface()); //直接構造一個Surface,指向 ctrl->getSurface()
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner); //強引用
    }
    return reinterpret_cast<jlong>(surface.get());
}

這里的ctrl指向前面創建的SurfaceControl,繼續追溯ctrl->getSurface():

sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) {
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}

sp<Surface> SurfaceControl::generateSurfaceLocked() const
{
    //這個mGraphicBufferProducer其實就是上面分析的BufferQueueProducer
    mSurfaceData = new Surface(mGraphicBufferProducer, false); 
    return mSurfaceData;
}

即直接new了一個nativie的Surface返回給java層,java層的Surface指向的就是native層的Surface。

所以Surface的實際創建可以用下圖表示:

經過上面這個圖,也可以理解SurfaceControl為什么叫SurfaceControl了。

總結

以上是生活随笔為你收集整理的Android的Surface的创建的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。