Android UI結構源碼研究


android經驗相關(android4.3)

        由於之前工作需要,對Android的UI framework做了些許研究,主要針對Android4.3的源碼參考晚上別人的一些流程分析,加上自己打log得出的一些理解和經驗。特意放上CSDN。



*************************************************************************************


一、當setVisibility(View.GONE);時,android所執行的measure、layout和draw相關操作。


********************************   measure & layout   *******************************
-->View.setFlag()
{
    if (changed & GONE) != 0
        requestLayout();
}


-->View.requestLayout()
{
    //表示本View已經接受了本次requestlayout的請求。
    mPrivateFlags |= PFLAG_FORCE_LAYOUT;


    if (mParent != null && !mParent.isLayoutRequested()) {
        mParent.requestLayout();
    }
}


public boolean isLayoutRequested() {
    return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
}




-->一層一層遞歸到最上面ViewRootImpl的requestLayout之後,scheduleTraversals


-->ViewRootImpl.requestLayout()
{
    ...


    //mLayoutRequested爲true則表示接受當前requestLayout請求。
    mLayoutRequested = true;
    scheduleTraversals();
}




-->ViewRootImpl.performTraversals()
{
    // mStopped means whether is in the stopped state(no longer be active)
    boolean layoutRequested = mLayoutRequested && !mStopped;
    if (layoutRequested) {
        performMeasure();
    }


    final boolean didLayout = layoutRequested && !mStopped;
    if (didLayout) {
        performLayout();
    }
}




-->performMeasure & performLayout


-->到達parent(FrameLayout)時候,onMeasure(int, int)
{
    if (child.getVisibility() != GONE)
        跳過調用本View的measure
}


-->同理parent(FrameLayout),onLayout(boolean,int,int,int,int)
{


    if (child.getVisibility() != GONE) 
        跳過調用本View的layout
}


-->由於本View的meauser和layout沒有被調用,也就是從本View開始的View都沒有被重新measure和layout
另外,只有layout的時候會mPivateFlags &= ~PFLAG_FORCE_LAYOUT;(也就是完成了之前的layout請求)
此時,(mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;爲true,也就是isLayoutRequestd()返回true。


-->此時如果本View的child View繼續調用requestLayout的時候,會因爲判斷if(mParent.isLayoutRequested)返回true而跳過回溯到
ViewRootImpl的請求,因此就等於無法重新measure或者layout


********************************   draw   *******************************
/***


  drawSoftware ver.


***/


-->setFlag 
{
    if (changed & GONE) != 0 {
        ...


            mParent.invalidate(true);


        /*PFLAG_DRAWN表示該View已經完成draw操作,通常在invalidate判斷,如果已經設置了該flag,則證明可以invalidate,並
         *把該flag去掉,表示需要重新draw操作。同時在draw操作執行過程中,會把該flag添加上。
         */
        mPrivateFlags |= PFLAG_DRAWN  
    }


    if ((changed & VISIBILITY_MASK) != 0) {
        ...


            mParent.invalidate(true);
    }
}


--->invalidate(boolean invalidateCache)
{
    //不是visibile和沒有運行動畫中的view要跳過invalidate
    if (skipInvalidate()) {
        return;
    }


    // PFLAG_DRAWN表示是否經過draw,PFLAG_HAS_BOUNDS在layout的時候setFrame設置上
    if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) {


        final AttachInfo ai = mAttachInfo;
        final ViewParent p = mParent;


        if (p != null && ai != null) {
            final Rect r = ai.mTmpInvalRect;
            r.set(0, 0, mRight - mLeft, mBottom - mTop);


            //調用parent的invalidateChid
            //同時把本View的區域作爲dirtyRect爲參數傳入
            p.invalidateChild(this, r);
        }
    }
}


-->ViewGroup.invalidateChild(View, Rect)
{


    do {
        parent = parent.invalidateChildInParent(location, dirty);    
    }while(parent != null);


}


-->ViewGroup.invalidateChildInParent(final int[] location, final Rect dirty)
{
    //這裏對dirtyRect進行操作


    //首先進行滑動的位移計算
    dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX,
            location[CHILD_TOP_INDEX] - mScrollY);
    
    //如果沒有設上FLAG_CLIP_CHILDREN(在initViewGroup默認設上),則把dirtyRect和自己的區域進行並集操作
    if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) {
        dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
    }


    final int left = mLeft;
    final int top = mTop;


    //否則就把dirtyRect和自己的區域進行交集操作,另外,如果發現沒有交集,則把當前dirtyRect設爲空。
    if ((mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
        if (!dirty.intersect(0, 0, mRight - left, mBottom - top)) {
            dirty.setEmpty();
        }
    }
}


然後就這樣一直計算dirtyRect,回溯到ViewRootImpl.invalidateChildParent(),並把參數傳遞過去。


-->ViewRootImpl.invalidateChildInParent(int[] location, Rect dirty)
{


    //ViewRootImpl則把dirty和自己的dirtyRect進行並集
    final Rect localDirty = mDirty;
    localDirty.union(dirty.left, dirty.top, dirty.right, dirty.bottom);




    //如果dirtyRect和自己的View區域存在交集,或者動畫過程中,
    //同時沒有在performTraversals的執行過程中(!mWillDrawSoon),則會調度一次Traversals
    final boolean intersected = localDirty.intersect(0, 0,
            (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
    if (!intersected) {
        localDirty.setEmpty();
    }
    if (!mWillDrawSoon && (intersected || mIsAnimating)) {
        //調度一次Traversals,讓下次執行performTraversals
        //注意:這裏和requestLayout不同的是,performTraversals一般都要執行performDraw
        //但如果沒有requestLayout過,則不會執行measure和layout(兩者一般都會一起執行)
    
        scheduleTraversals();
    }


}


-->ViewRoomImpl.performTraversals()
-->ViewRootImpl.performDraw()
-->ViewRootImpl.draw()
-->ViewRootImpl.drawSoftware(... Rect dirty)
{
    ...


    //把dirtyRect的值傳入lockCanvas,通過jni調用返回一個clipRect是dirty的canvas
    int left = dirty.left;
    int top = dirty.top;
    int right = dirty.right;
    int bottom = dirty.bottom;


    canvas = mSurface.lockCanvas(dirty);
   


    ...


    //傳入mView的draw(),開始了第一個View的draw調用。
    mView.draw(canvas);
    


}


-->View.draw(canvas) (ViewRootImpl的直接孩子是繼承FrameLayout的DecorView)
{
    /*
     * Draw traversal performs several drawing steps which must be executed
     * in the appropriate order:
     *
     *      1. Draw the background
     *      2. If necessary, save the canvas' layers to prepare for fading
     *      3. Draw view's content
     *      4. Draw children
     *      5. If necessary, draw the fading edges and restore layers
     *      6. Draw decorations (scrollbars for instance)
     */


    ...


    dispatchDraw(canvas);


    ...
    
}


-->ViewGroup.dispatchDraw(canvas)
{
    //從這裏可見,只有VISIBILE或者在執行動畫過程中的View纔會被繪製
    if ((flags & FLAG_USE_CHILD_DRAWING_ORDER) == 0) {
        for (int i = 0; i < count; i++) {
            final View child = children[i];
            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
                more |= drawChild(canvas, child, drawingTime);
            }
        }
    } else  {
        for (int i = 0; i < count; i++) {
            final View child = children[getChildDrawingOrder(count, i)];
            if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
                more |= drawChild(canvas, child, drawingTime);
            }
        }
    }
}


-->ViewGroup.drawChild(canvas, child, drawingTime)
{
    child.draw(canvas, this, drawingTime);
}


-->View.draw(canvas, parent, drawingTime)
{


    // Sets the flag as early as possible to allow draw() implementations
    // to call invalidate() successfully when doing animations
    mPrivateFlags |= PFLAG_DRAWN;


    if (!concatMatrix &&
            (flags & (ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS |
                      ViewGroup.FLAG_CLIP_CHILDREN)) == ViewGroup.FLAG_CLIP_CHILDREN &&


            //這裏通過把自己View的位置傳入canvas來判斷是否和clipRect有交集
            //如果沒有,則可以直接返回不進行下面的draw調用。
            canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
            
            (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) {
        mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED;


        return more;
    }




    //PFLAG_SKIP_DRAW表示不繪製,通常在ViewGrop.initViewGroup裏
    //setFlags(WILL_NOT_DRAW, DRAW_MASK);給默認設上。


    if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
        mPrivateFlags &= ~PFLAG_DIRTY_MASK;
        dispatchDraw(canvas);
    } else {
        draw(canvas);
    }


}


//就這樣繼續返回到最上層的child的繪製了。
//大致情況就是,某個子view進行invalidate調用的時候,通過和parent不斷進行並集dirtyRect
//並最終傳回給ViewRootImpl調度一次繪製操作,然後從最底層的view開始追溯回本View,同時會
//遍歷每個子View,這個時候每個子View會把自己的區域和canvas的裁剪區域進行交集判斷,如果
//沒有交集就不會進行繪製。




*************************************************************************************


二 、mSurface.lockCanvas()


*************************************************************************************


-->Surface.lockCanvas()


-->android_view_Surface.nativeLockCanvas()
{
    sp<Surface> surface;
    surface->lock()
}


-->Surface.lock()   frameworks/native/libs/gui/Surface.cpp
{
    dequeueBuffer();
}


-->Surface.dequeueBuffer()
{
    mGraphicBufferProducer->dequeueBuffer();
}


-->BpGraphicBufferProducer.dequeueBuffer()   frameworks/native/libs/gui/IGraphicBufferProducder
{
    remote()->transact(DEQUEUE_BUFFER, ...)
}


-->BnGraphicBufferProducer::onTransact() frameworks/native/libs/gui/IGraphicBufferProducder
{
        case DEQUEUE_BUFFER: {
            int result = dequeueBuffer(&buf, &fence, w, h, format, usage);
            return NO_ERROR;
        } break;
}


-->BufferQueue.dequeueBuffer()  frameworks/native/libs/gui/BufferQueue //同一進程不同線程處理不同請求
{
}


*************************************************************************************


三 、應用程序App的Activity初始化過程(包括和SurfaceFlinger進行連接,申請創建Surface,申請繪圖數據)(java+cpp)


*************************************************************************************


(步驟1,2,3均在調用onCreate之前)
1、ActivityThread通過Instrumentation創建出Activity之後,調用其attach方法,把之前創建的ContextImpl作爲參數賦值(4.3版本待驗證)
2、Activity.attach裏,把ContextImpl通過attachBaseContext給保存起來(4.3待驗證)
3、Activity.attach裏調用PolicyManager.makeNewWindow(this);創建PhoneWindow保存到mWindow裏,然後調用mWindow.setWindowManager(),
    這樣在Window.setWindowManager()裏,會通過mContext.getSystemService獲取WindowManagerImpl,然後調用
    WindowManagerImpl.createLocalWindowManager來創建一個屬於自己的WindowManagerImpl,保存到mWindowManager
(1、2、3步表示保存了ContextImpl,創建了PhoneWindow,WindowManagerImpl)




4、Activity.onCreate中,調用了setContentView(),然後調用getWindow().setContentView(),調用到PhoneWindow.setContentView(),然後PhoneWindow
   就會調用installDecor創建DecorView,令DecorView成爲自定義View的父親。




(步驟5在onResume之後)
5、ActivityThread.handleResumeActivity會調用WindowManager.addView(),也即WindowManagerImpl.addView(),其會調用mGlobal.addView,mGlobal是
    全局靜態單例WindowManagerGlobal(主要負責封裝不與任何Context關聯的系統window manager的交互),WindowManagerGlobal.addView,負責創建
    ViewRootImpl,並且把其與decorView,WindowManager.LayoutParams對象關聯,分別放到三個數組mRoots,mViews,mParams,最後會調用
    ViewRootImpl.setView(view, wparams, panelParentView); 然後會調用view.assignParent(this);把ViewRootImpl作爲自己的ViewParent


創建Session,用於應用程序進程與WindowManagerService進行通信
6、在ViewRootImpl的構造函數裏,調用WindowManagerGlobal.getWindowSession,在getWindowSession裏(涉及Binder跨進程通信,底層利用C++的Binder機制)
    ,會通過IWindowManager.Stub.asInterface(ServiceManager.getService("window"));獲取WindowManagerService的Binder代理對象,然後調用
    IWindowManager.openSession獲取Session,也即調用到WindowManagerServcie.openSession()。(WindowManagerService extends IWindowManager.Stub)


7、WindowManagerService.openSession只是簡單的new Session(this, xxx, xxx);然後返回,要注意,返回到應用程序進程端時,獲得的對象就是
    IWindowSession.Proxy


創建WindowState,表示window狀態,包含了一個IWindow的binder對象,可以與應用程序進程端的Activity組件通信。
8、注意之前在ViewRootImpl的構造函數中,會創建一個W對象,(W extentds IWindow.Stub),保存到mWindow。然後在RootViewImpl.setView()中,會調用
    mWindowSession.addToDisplay(mWindow, xxx);,同理,這是一個Binder的ipc調用,會到Session.addToDisplay(),而addToDisplay只是簡單調用
    mService.addWindow(this, window, xxx);,mServices是之前構造Session賦值的WindowManagerService的引用。
9、WindowManager.addWindow,addWindow裏有一個簡單判斷mWindowMap.containsKey(client.asBinder())的來以(client是RootViewImpl傳過來的
    IWindow對象)來判斷是否已經添加過此window,然後就會構造WindowState(this,session, client, xxx);,然後會調用WindowState.attach來增加
    一個連接SurfaceFlinger的SurfaceSession對象。然後addWindow還做了一大堆調整窗口z軸和位置還有focus的邏輯,略過。


WindowState對象與SurfaceFlinger連接
10、在WindowState對象的構造函數裏,把IWindow對象(ViewRootImpl傳遞過來)保存到mClient中,並且調用c.asBinder().linkToDeath(deatchRecipinet,0)
    來監聽該對象銷燬的信號。另外,這裏創建了一個WindowStateAnimator對象,負責創建並管理SurfaceControl。
11、WindowState.attach,只是簡單調用了mSession.windowAddedLocked()。在windowAddedLocked中,mSurfaceSession = new SurfaceSession(),然後添加到
    WindowManagerServices中,mService.mSessions.add(this)。在SurfaceSession的構造函數裏,通過nativeCreate的jni調用到c++層,會構造一個
    SurfaceComposerClient(),然後返回到SurfaceSession中。


Activity創建Surface
12、當ViewRootImpl.setView調用時會requestLayout,然後就會進行第一次的traversals,經過VSYNC同步之後調用performTraversals,然後會調用relayoutWindow
    在relayoutWindow中,會調用mWindowSession.relayout(mWindow, ... ,  mSurface),注意mSurface在構造ViewRootImpl中已經初始化new Surface,但內部
    的native對象是無效,這裏會調用到Session.relayout,注意這裏的Surface對象傳遞過程是通過在服務進程側new Surface構造另外一個Surface,然後通過
    readFromParcel/WriteToParcel來實現對象的序列化。
13、Sessioin.relayout()只是簡單的調用mService.relayoutWindow(this, window, xxx, outSurface);也就是WindowManagerService.relayoutWindow,其中,
    通過windowForClientLocked(session, client, flase)獲取WindowState win,然後獲取win.mWinAnimator對象,調用WindowStateAnimator.createSurfaceLocked
14、在WindowStateAnimator.createSurfaceLocked中,會構造mSurfaceControl = new SurfaceControl(mSession.mSurfaceSession, xxx);


15、在SurfaceControl的構造中,會接收SurfaceSession作爲參數,內部調用nativeCreate(session,xxx);通過jni調用到c++層,然後會獲取SurfaceSession
    之前獲取的SurfaceComposerClient,然後調用SurfaceComposerClient::createSurface來想SurfaceFlinger申請一個Layer,同時返回SurfaceControl對象


16、繼續在WindowStateAnimator.createSurfaceLocked中,運行了以下代碼來設置SurfaceFlinger進程端對應的Layer的值。具體流程見bootanimation例子。
            SurfaceControl.openTransaction();
            mSurfaceControl.setPosition(mSurfaceX, mSurfaceY);
            mSurfaceControl.setLayerStack(mLayerStack);
            mSurfaceControl.setLayer(mAnimLayer);
            mSurfaceControl.setAlpha(0);
            SurfaceControl.closeTransaction();


17、經過以上步驟完成SurfaceControl的初始化後,返回到WindowStateAnimator.createSurfaceLocked中,會調用outSurface.copyFrom(surfaceControl),
    複製一個Surface,Surface.copyFrom會調用jni方法,nativeCreateFromSurfaceControl,而這個方法內部調用SurfaceControl::getSurface獲取Surface,然後
    返回到Surface裏。


    這樣就完成了Surface的初始化。




總結:
1、Activity組件包含了以下內容
(1)PhoneWindow對象,負責構造並管理DecorView,以及窗口外觀屬性
(2)ViewRootImpl對象,負責創建Surface,與WindowManagerService對象通信,並且負責應用程序View層次的measure,layout,draw
    1)ViewRootImpl對象通過Session(IWindowSession)對象與WindowManagerService通信
    2)WindowManagerService對象通過W(IWindow)對象與ViewRootImpl對象通信
    3) 每個ViewRootImpl對象都有一個屬於自己的W對象


2、WindowManagerService對於每個Activity組件(注意:WindowManagerService與SurfaceFlinger不同進程!)
(1)對於所有屬於同一個應用程序進程都是同一個Session對象
(2)對於不同的ViewRootImpl都有不同的WindowState對象
(3)WindowState對象內部享有相同的Session,因此只有一個SurfaceSession對象,也就是確保只會連接到SurfaceFlinger一次
(4)由於WindowState對象不同,所以會另外創建SurfaceControl和Surface






////////////////////////////////
Java的Binder接口(與C++類似)


以ActivityManager例子(利用aidl可以依靠工具自動生成以下三個步驟,之後Service端只要extends IActivityManager.Stub實現)


1、接口定義
frameworks/base/core/java/android/app/IActivityManager.java
public interface IActivityManager extends android.os.IInterface {


//declare interface
    public int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
            int requestCode, int flags, String profileFile,
            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException;


....
}


2、本地對象定義(Service端)
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    //實現asBinder、onTranscat、、asInterface
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
            switch (code) {
                case START_ACTIVITY_TRANSACTION:
                    {
                        data.enforceInterface(IActivityManager.descriptor);
                        IBinder b = data.readStrongBinder();
                        IApplicationThread app = ApplicationThreadNative.asInterface(b);
                        String callingPackage = data.readString();
                        Intent intent = Intent.CREATOR.createFromParcel(data);
                        String resolvedType = data.readString();
                        IBinder resultTo = data.readStrongBinder();
                        String resultWho = data.readString();
                        int requestCode = data.readInt();
                        int startFlags = data.readInt();
                        String profileFile = data.readString();
                        ParcelFileDescriptor profileFd = data.readInt() != 0
                            ? data.readFileDescriptor() : null;
                        Bundle options = data.readInt() != 0
                            ? Bundle.CREATOR.createFromParcel(data) : null;
                        int result = startActivity(app, callingPackage, intent, resolvedType,
                                resultTo, resultWho, requestCode, startFlags,
                                profileFile, profileFd, options);
                        reply.writeNoException();
                        reply.writeInt(result);
                        return true;
                    }


                    ....
            }
        }


    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }


        return new ActivityManagerProxy(obj);
    }


    public IBinder asBinder() {
        return this;
    }
}


3、代理對象定義(client端)
class ActivityManagerProxy implements IActivityManager
{
    //通過Parcel實現所有接口
   public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, String profileFile,
            ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        data.writeString(profileFile);
        if (profileFd != null) {
            data.writeInt(1);
            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }


   ......
}




*************************************************************************************


四、bootanimation與SurfaceFlinger進行通信(純cpp層)


*************************************************************************************




/////////////////////////////////////////////////


(1)bootanimation與SurfaceFlinger進行連接


/////////////////////////////////////////////////


SurfaceFlinger運行在Android的系統進程內,一般的應用程序需要通過Binder進行跨進程通信。
其中主要SurfaceComposerClient具體封裝了連接的過程。


class SurfaceComposerClient : public RefBase


因此,SurfaceComposerClient通過第一次構造時,通過


sp<SurfaceComposerClient>  session = new SurfaceComposerClient()


時會調用
-->SurfaceComposerClient::onFirstRef() //frameworks/native/libs/gui/SurfaceComposerClient.cpp
{
    //這裏獲取的sp<ISurfaceComposer>是BpSurfaceComposer的子類
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    
    if (sm != 0) {
        
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
    
}


然後就獲取了sp<ISurfaceComposerClient>  mClient; 也就是通過Binder與SurfaceFlinger通信


展開分析
sp<ISurfaceComposer> sm(ComposerService::getComposerService());


-->/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() //frameworks/native/libs/gui/SurfaceComposerClient.cpp
{
    //ComposerService的ctor會調用connectLocked()
    ComposerService& instance = ComposerService::getInstance();
    Mutex::Autolock _l(instance.mLock);


    if (instance.mComposerService == NULL) {
        //嘗試重新連接
        ComposerService::getInstance().connectLocked();
    }
    return instance.mComposerService;
}


-->void ComposerService::connectLocked() //frameworks/native/libs/gui/SurfaceComposerClient.cpp
{
    //嘗試獲取SurfaceFlinger服務,另外
    //sp<ISurfaceComposer> mComposerService;
    //SurfaceFlinger繼承於BnSurfaceComposer,BnSurfaceComposer繼承於BnInterface<ISurfaceComposer>


    /*
    *
    *注意:Bnxxx, Bpxxx是利用Binder機制派生出來的類,n表示native也就是服務端的,p表示proxy
    *一般Bnxxx類負責重載onTransact, Bp負責調用remote()->transact(....)進行跨進程通信。
    *
    */


    //這裏獲取到的mComposerService屬於BpSurfaceComposer。
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != NULL);


    ...
}


getService展開:
-->template<typename INTERFACE>
status_t getService(const String16& name, sp<INTERFACE>* outService)  //frameworks/native/include/binder/IServiceManager.h
{
    //defaultServiceManager()大概爲
    // if(gDefaultServiceManager != NULL ) return gDefaultServiceManager;
    // gDefaultServiceManager = new BpServiceManager(new BpBinder(0));  其中0表示遠程接口句柄值爲0
    //return gDefaultServiceManager;
    
    const sp<IServiceManager> sm = defaultServiceManager();
    if (sm != NULL) {
        //暫時忽略sm->gerService...
        *outService = interface_cast<INTERFACE>(sm->getService(name));
        
        if ((*outService) != NULL) return NO_ERROR;
    }
    return NAME_NOT_FOUND;
}


-->template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    //INTERFACE::asInterface由宏IMPLEMENT_META_INTERFACE實現
    //並最終調用new Bp##INTERFACE(obj)生成Bpxxx的類返回。
    return INTERFACE::asInterface(obj);
}




sp<ISurfaceComposerClient> conn = sm->createConnection();展開
-->virtual sp<ISurfaceComposerClient> BpSurfaceComposer::createConnection()  //frameworks/native/libs/gui/ISurfaceComposer.cpp
{
    uint32_t n;
    Parcel data, reply;
    data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
    
    //這裏向BnSurfaceComposerClient發送消息。
    remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
   
    //同理,這裏的interface_cast生成BpSurfaceComposerClient
    return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}


-->status_t BnSurfaceComposer::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  //frameworks/native/libs/gui/ISurfaceComposer.cpp
{
    switch(code) {
        case CREATE_CONNECTION: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            
            //這裏會調用會SurfaceFlinger的createConnection
            //其中返回的參數爲Client : public BnSurfaceComposerClient
            sp<IBinder> b = createConnection()->asBinder();
            
            reply->writeStrongBinder(b);
        } break;
      
    ...
    
    }


    ...
}


-->sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()    //frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
{
    //這裏創建了Client並返回
    //class Client : public BnSurfaceComposerClient


    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));
    status_t err = client->initCheck();
    if (err == NO_ERROR) {
        bclient = client;
    }
    return bclient;
}




//簡單來說,就是通過SurfaceComposerClient的onFirstRef,也就是第一次增加引用計數時,
//通過Binder機制和SurfaceFlinger建立連接,獲取BpSurfaceComposerClient指針。




/////////////////////////////////////////////////


(2)bootanimation請求SurfaceFlinger創建Surface


/////////////////////////////////////////////////


    通常,一個應用程序可以擁有多個窗口(通常是Acitivity),每個窗口都要請求SurfaceFlinger創建對應的
Surface, 簡單來說,就是通過SurfaceComposerClient請求SurfaceFlinger服務創建Surface,在此過程中,
在SurfaceFlinger服務進程側創建了Layer對象,並且Layer對象內部創建了SurfaceFlingerConsumer以及
爲其使用的SurfaceTextureLayer(繼承於BufferQueue),並且也創建了對應的id對象Handle(同時會在析構時調用
mFlinger->onLayerDestoryed),並且Handle和SurfaceTexturelayer作爲Binder的代理對象返回給應用程序
進程側。同時,應用程序進程側會以Handle和SurfaceTextureLayer兩個對象來構造SurfaceControl對象,並且
同時請求SurfaceControl對象創建Surface對象。


具體調用過程:


-->sp<SurfaceControl> SurfaceComposerClient::createSurface(         //frameworks/native/libs/gui/SurfaceComposerClient.cpp
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags)
{
    sp<SurfaceControl> sur;
    sp<IBinder> handle;
    sp<IGraphicBufferProducer> gbp;


    ...
    //通過mClient(Client)代理Binder對象,請求SurfaceFlinger服務進程側創建Surface
    mClient->createSurface(name, w, h, format, flags,
            &handle, &gbp);


    ...


    //獲取了代理Binder對象handle、gbp(SurfaceTextureLayer),構造SurfaceControl對象並返回。
    sur = new SurfaceControl(this, handle, gbp);


    return sur;
}


//////////////////////////////////
mClient->createSurface()展開


//服務進程側的Client
-->status_t Client::createSurface(                              //frameworks/native/services/surfaceflinger/Client.cpp
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{


    //Client和SurfaceFlinger處於同一進程不同線程,
    //因此這裏進行一個同步操作,效果等同於同一線程調用
    //flinger->createLayer()
    
    class MessageCreateLayer : public MessageBase {
        SurfaceFlinger* flinger;
        Client* client;
        sp<IBinder>* handle;
        sp<IGraphicBufferProducer>* gbp;
        status_t result;
        const String8& name;
        uint32_t w, h;
        PixelFormat format;
        uint32_t flags;
    public:
        MessageCreateLayer(SurfaceFlinger* flinger,
                const String8& name, Client* client,
                uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
                sp<IBinder>* handle,
                sp<IGraphicBufferProducer>* gbp)
            : flinger(flinger), client(client),
              handle(handle), gbp(gbp),
              name(name), w(w), h(h), format(format), flags(flags) {
        }
        status_t getResult() const { return result; }
        virtual bool handler() {
            result = flinger->createLayer(name, client, w, h, format, flags,
                    handle, gbp);
            return true;
        }
    };


    sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
            name, this, w, h, format, flags, handle, gbp);


    mFlinger->postMessageSync(msg);


    return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}




-->status_t SurfaceFlinger::createLayer(                    //frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
        const String8& name,
        const sp<Client>& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
{


    ...


    status_t result = NO_ERROR;


    sp<Layer> layer;


    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createNormalLayer(client,
                    name, w, h, flags, format,
                    handle, gbp, &layer);
            break;
    ...
    
    }


    if (result == NO_ERROR) {
        //創建成功後,添加到把對象添加到Client端,並請求一次調度。
        addClientLayer(client, *handle, *gbp, layer);
        setTransactionFlags(eTransactionNeeded);
    }


    return result;
}




-->status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
    ...


    //創建Layer對象,Layer對象內部創建SurfaceTextureLayer和SurfaceFlingerConsumer
    *outLayer = new Layer(this, client, name, w, h, flags);
    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
    if (err == NO_ERROR) {


        //獲取id對象Handle和BufferQueue對象(也就是Layer內部創建的SurfaceTextureLayer對象)
        *handle = (*outLayer)->getHandle();
        *gbp = (*outLayer)->getBufferQueue();
    }


    ...


    return err;
}


-->void Layer::onFirstRef()                 //frameworks/native/services/surfaceflinger/Layer.cpp
{
    //Layer對象第一次引用時進行初始化
    //創建SurfaceTextureLayer和SurfaceFlingerConsumer,並進行必要的初始化。
    
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);


    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
            GL_TEXTURE_EXTERNAL_OES, false, bq);


    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    mSurfaceFlingerConsumer->setSynchronousMode(true);
    mSurfaceFlingerConsumer->setName(mName);


    ...


    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);


    ...
}


-->status_t Layer::setBuffers( uint32_t w, uint32_t h,             //frameworks/native/services/surfaceflinger/Layer.cpp
                            PixelFormat format, uint32_t flags)
{


    //對mSurfaceFlingerConsumer進行初始化


    // this surfaces pixel format
    PixelFormatInfo info;
    status_t err = getPixelFormatInfo(format, &info);


    uint32_t const maxSurfaceDims = min(
            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());


    mFormat = format;


    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
    mCurrentOpacity = getOpacityForFormat(format);


    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));


    return NO_ERROR;
}


-->sp<IBinder> Layer::getHandle() {


    //返回一個Handle對象(Binder代理)作爲id用途,
    //LayerCleaner確保在析構的時候調用flinger->onLayerDestroyed(mLayer)


    class Handle : public BBinder, public LayerCleaner {
        wp<const Layer> mOwner;
    public:
        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
            : LayerCleaner(flinger, layer), mOwner(layer) {
        }
    };


    return new Handle(mFlinger, this);
}


-->sp<BufferQueue> Layer::getBufferQueue() const {
    //這裏返回的是Layer.onFirstRef裏構造的SurfaceTextureLayer對象.


    return mSurfaceFlingerConsumer->getBufferQueue();
}


-->void SurfaceFlinger::addClientLayer(const sp<Client>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbc,
        const sp<Layer>& lbc)
{
    // attach this layer to the client
    client->attachLayer(handle, lbc);


    // add this layer to the current state list
    Mutex::Autolock _l(mStateLock);


    //這裏添加到一個Vector對象裏,方便以後繪製按照Z軸順序
    mCurrentState.layersSortedByZ.add(lbc);
    mGraphicBufferProducerList.add(gbc->asBinder());
}


-->void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
{
    Mutex::Autolock _l(mLock);
    //添加到一個Key-value的vector對象內
    mLayers.add(handle, layer);
}
//////////////////////////////////


//////////////////////////////////
new SurfaceControl
應用程序進程側的構造


-->SurfaceControl::SurfaceControl(                  //frameworks/native/libs/gui/SurfaceControl.cpp
        const sp<SurfaceComposerClient>& client, 
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbp)
    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
{
}


-->sp<Surface> SurfaceControl::getSurface() const    //frameworks/native/libs/gui/SurfaceControl.cpp
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) {
        mSurfaceData = new Surface(mGraphicBufferProducer);
    }
    return mSurfaceData;
}


-->Surface::Surface(                                //frameworks/native/libs/gui/Surface.cpp
        const sp<IGraphicBufferProducer>& bufferProducer)
    : mGraphicBufferProducer(bufferProducer)
{


    //初始化OpenGl回調的函數指針
    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
    ANativeWindow::queueBuffer      = hook_queueBuffer;
    ANativeWindow::query            = hook_query;
    ANativeWindow::perform          = hook_perform;


    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;


    //初始化OpenGl的值
    const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;


    //其他成員變量初始化
    ...
}




/////////////////////////////////////////////////


BootAnimation創建Surface過程總結(純cpp):


/////////////////////////////////////////////////


應用程序進程對象:
1、SurfaceComposerClient
創建:
    直接new SurfaceComposerClient
作用:
(1)負責與SurfaceFlinger連接,
    通過getService獲取SurfaceFlinger的ISurfaceComposer的binder指針,然後createConnection(),獲得ISurfaceComposerClient(mClient)
(2)負責創建SurfaceControl
    調用mClient->createSurface(),獲取handle(IBinder)、gbp(IGraphicBufferProducer),然後new SurfaceControl(this,handle,gbp)
(3)提供靜態方法,可以在對於整個應用程序進程提供同一的提交Surface變更操作。
    如openGlobalTransaction/closeGlobalTransaction,用來提交Surface的setAlpha/setLayer/setMatrix等操作到服務進程端。
    內部實現是依靠一個靜態類Composer,通過獲取服務SurfaceFlinger的Binder指針,調用ISurfaceComposer::setTransactionState實現,參數裏包含
    Client來區別每個應用程序進程。




2、SurfaceControl
創建:
    由SurfaceComposerClient.createSurface中直接new SurfaceControl
作用:
(1)配合SurfaceComposerClient,利用ISurfaceComposerClient設置窗口的屬性
    setLayer,setAlpha,set**等
    例:
    SurfaceComposerClient::openGlobalTransaction();
    control->setLayer(0x40000000);
    SurfaceComposerClient::closeGlobalTransaction();
    ---最終通過ISurfaceComposer::setTransactionState,調用到SurfaceFlinger服務端,找到對應的Layer,然後調用Layer.setLayer
(2)負責創建Surface
    mSurfaceData = new Surface(mGraphicBufferProducer); (mGraphicBufferProducer即SurfaceTextureLayer : public BufferQueue)


3、Surface
創建:
    由SurfaceControl.getSurface中直接new Surface
作用:
(1)真正的繪製類,通過dequeueBuffer/queueBuffer來獲取/提交圖形數據(pixel)


ViewRootImpl的drawSoftware就是通過Surafce::lock以及Surface::unlockAndPost來獲取/提交圖形數據


//////////////////////////////////////
服務(SurfaceFlinger)進程對象:
1、Client(ISurfaceComposerClient)
創建:
    由SurfaceFlinger.createConnection直接new Client(this)
作用:
(1)返回應用程序側對象之一,主要負責Surface的構造和管理
    應用程序端通過Binder調用到SurfaceFlinger的方法,createSurface等


2、Layer
創建:
    由SurfaceFlinger.createNormalLayer直接new Layer(this, client, name, w, h, flags);
作用:
(1)創建SurfaceTextureLayer(BufferQueue),以及SurfaceFlingerConsumer
    在Layer.onFirstRef()中,
    sp<BufferQueue>bq = new SurfaceTextureLayer(mFlinger); 
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, ..., .., bq);
    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    這樣,consumer裏包含一個bufferqueue,並且Layer監聽着可用圖像數據的消息。


(2)負責通知SurfaceFlinger更新屏幕
    當應用程序通過Skia完成Rasterazation(光柵化)後,則會調用Surface::queueBuffer把圖像數據提交。這時候會調用到BufferQueue::queueBuffer,
    然後會調用onFrameAvailabel通知Layer,
    Layer就會調用mFlinger->signalLayerUpdate();SurfaceFlinger等待VSYNC同步好後,就會把圖像數據composite到屏幕上


3、SurfaceTextureLayer(BufferQueue)
創建:
    由Layer::onFirstRef()中直接new SurfaceTextLayer(mFlinger);
作用:
(1)負責管理GraphicBuffer隊列,GraphicBuffer就是圖像數據的封裝類
    BufferSlot mSlots[NUM_BUFFER_SLOTS]; //Surface內部有保存一份類似的bufferslot,紀錄已經分配的buffer
    根據數組裏每個buffer的狀態管理和分配出對應的buffer
(2)分配Buffer
    分配Buffer是通過gralloc模塊進行分配,具體通過GraphicsBufferAlloc來new GraphicBuffer


4、SurfaceFlingerConsumer(GLConsumer)
創建:
    由Layer::onFirstRef()中直接new SurfaceFlingerConsumer
作用:
 * GLConsumer consumes buffers of graphics data from a BufferQueue,
 * and makes them available to OpenGL as a texture.
 *
 * A typical usage pattern is to set up the GLConsumer with the
 * desired options, and call updateTexImage() when a new frame is desired.
 * If a new frame is available, the texture will be updated.  If not,
 * the previous contents are retained.
 *
 * By default, the texture is attached to the GL_TEXTURE_EXTERNAL_OES
 * texture target, in the EGL context of the first thread that calls
 * updateTexImage().
 *
 * This class was previously called SurfaceTexture.


    當SurfaceFlinger::handlePageFlip調用時(VSYNC後通知SurfaceFlinger更新),Layer::latchBuffer會調用
    SurfaceFlingerConsumer::updateTexImage利用GL合成圖層。而updateTexImage會調用內部的BufferQueue::acquireBuffer獲得對應的
    等待合成的GraphicBuffer進行合成。


5、GraphicBuffer
創建:
    由GraphicBufferAlloc來直接new GraphicBuffer
作用:
(1)可以跨進程返回給應用進程側
    這是通過public Flattenable來繼承Flattenable,然後重載flatten和unflatten來在Binder的onTranscation和transcat方法調用,
    flatten和unflatten主要通過GraphicMapper把內存映射到應用進程側。
(2)可以申請對應的寬度w,高度h和像素格式format所需要的圖像數據內存
    這是通過GraphicBufferAllocator分配,其中GraphicBufferAllocator是利用gralloc模塊進行分配


//mGraphicBufferAlloc通過ComposerService::getComposerService()獲得SurfaceFlinger的binder接口
//然後調用createGBraphicBufferAlloc在服務進程側創建了GraphicBufferAlloc對象,
//然後,這裏同樣通過binder機制,在進程服務側創建了GrahpicBuffer對象,並且此時利用了gralloc模塊分配了匿名內存
//然後binder對象返回的時候,BpGraphicBufferAlloc(應用進程側)創建了size爲0的GraphicBuffer對象,然後通過Pracel::read方法
//把進程服務側創建的內存複製到應用進程側的這個對象上
mGraphicBufferAlloc->createGraphicBuffer();






另外,關於VSYNC(Vertical Sync)垂直同步:
Android 4.1裏對於CPU、GPU處理完圖層後合成到Display的過程中的優化,嚴格按照Display的刷新頻率進行同步的優化。
主要在SurfaceFlinger裏成員HWComposer *mHwc;封裝了部分邏輯。SurfaceFlinger通過private繼承了HWComposer::EventHandler來接收來自HWComposer的
回調onVSyncReceived,此時SurfaceFlinger內部通過EventThread::onVSyncReceived與自身的Thread Loop進行同步(not very clear..)。


*************************************************************************************************************************************








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章