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是一一對應的。
    ...
}
 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()所引發的主要操作:

  1. WindowManagerService創建了一個WindowState。用來表示客戶端的一個Window
  2. WindowManagerService創建了一個SurfaceSession,SurfaceSession會與SurfaceFlinger構建鏈接,創建了一個SurfaceComposerClient對象,一個應用程序只具有一個這個對象。
  3. 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一個mTraversalRunnableChoreographer接收顯示系統的時間脈沖(垂直同步信號-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了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM