Android Surface理解

結合別人的博客和自己看的代碼,梳理下自己對surface的理解

1.代碼相關文件

/AOSP/frameworks/native/libs/uiwKiom1gK4CeAa6_IAAAezFFSYgQ432.png

主要是bufferqueuecore與surfaceflinger中分配

GraphicBufferAllocator 通過hw_get_module()&gralloc_open與硬件提供的設備交互
ex: /hardware/qcom/display/libgralloc/alloc_controller.cpp etc.


/AOSP/frameworks/native/libs/gui

Android.mk                   IGraphicBufferAlloc.cpp
BitTube.cpp                  IGraphicBufferConsumer.cpp
BufferItemConsumer.cpp       IGraphicBufferProducer.cpp
BufferItem.cpp               IProducerListener.cpp
BufferQueueConsumer.cpp      ISensorEventConnection.cpp
BufferQueueCore.cpp          ISensorServer.cpp
BufferQueue.cpp              ISurfaceComposerClient.cpp
BufferQueueProducer.cpp      ISurfaceComposer.cpp
BufferSlot.cpp               LayerState.cpp
CleanSpec.mk                 Sensor.cpp
ConsumerBase.cpp             SensorEventQueue.cpp
CpuConsumer.cpp              SensorManager.cpp
DisplayEventReceiver.cpp     StreamSplitter.cpp
GLConsumer.cpp               SurfaceComposerClient.cpp
GraphicBufferAlloc.cpp       SurfaceControl.cpp
GuiConfig.cpp                Surface.cpp
IConsumerListener.cpp        SyncFeatures.cpp
IDisplayEventConnection.cpp  tests

SurfaceComposerClient 中成員變量 sp<ISurfaceComposerClient>  mClient;與surface.cpp binder通信

/AOSP/frameworks/native/services/surfaceflinger

Android.mk         EventControlThread.cpp   MODULE_LICENSE_APACHE2
Barrier.h          EventControlThread.h     MonitoredProducer.cpp
Client.cpp         EventLog                 MonitoredProducer.h
Client.h           EventThread.cpp          RenderEngine
clz.h              EventThread.h            SurfaceFlingerConsumer.cpp
Colorizer.h        FrameTracker.cpp         SurfaceFlingerConsumer.h
DdmConnection.cpp  FrameTracker.h           SurfaceFlinger.cpp
DdmConnection.h    Layer.cpp                SurfaceFlinger.h
DisplayDevice.cpp  LayerDim.cpp             surfaceflinger.rc
DisplayDevice.h    LayerDim.h               tests
DisplayHardware    Layer.h                  Transform.cpp
DispSync.cpp       main_surfaceflinger.cpp  Transform.h
DispSync.h         MessageQueue.cpp
Effects            MessageQueue.h

surfaceflinger管理surface及layer

AOSP/frameworks/base/core/java/android/view

AbsSavedState.java                       MagnificationSpec.aidl
accessibility                            MagnificationSpec.java
AccessibilityInteractionController.java  MenuInflater.java
AccessibilityIterators.java              MenuItem.java
ActionMode.java                          Menu.java
ActionProvider.java                      MotionEvent.aidl
animation                                MotionEvent.java
AnimationRenderStats.aidl                OrientationEventListener.java
Choreographer.java                       OrientationListener.java
CollapsibleActionView.java               package.html
ContextMenu.java                         PointerIcon.aidl
ContextThemeWrapper.java                 PointerIcon.java
DisplayAdjustments.java                  RemotableViewMethod.java
Display.aidl                             RenderNodeAnimator.java
DisplayEventReceiver.java                RenderNode.java
DisplayInfo.aidl                         ScaleGestureDetector.java
DisplayInfo.java                         SearchEvent.java
Display.java                             SoundEffectConstants.java
DisplayListCanvas.java                   SubMenu.java
DragEvent.aidl                           Surface.aidl
DragEvent.java                           SurfaceControl.java
FallbackEventHandler.java                SurfaceHolder.java
FocusFinderHelper.java                   Surface.java
FocusFinder.java                         SurfaceSession.java
FrameInfo.java                           SurfaceView.java
FrameStats.java                          textservice
GestureDetector.java                     TextureView.java
GhostView.java                           ThreadedRenderer.java
GraphicBuffer.aidl                       TouchDelegate.java
GraphicBuffer.java                       VelocityTracker.java
Gravity.java                             ViewAnimationUtils.java
HapticFeedbackConstants.java             ViewConfiguration.java
HardwareLayer.java                       ViewDebug.java
HardwareRenderer.java                    ViewGroup.java
IApplicationToken.aidl                   ViewGroupOverlay.java
IAssetAtlas.aidl                         ViewHierarchyEncoder.java
IGraphicsStats.aidl                      View.java
IInputFilter.aidl                        ViewManager.java
IInputFilterHost.aidl                    ViewOutlineProvider.java
InflateException.java                    ViewOverlay.java
InputChannel.aidl                        ViewParent.java
InputChannel.java                        ViewPropertyAnimator.java
InputDevice.aidl                         ViewPropertyAnimatorRT.java
InputDevice.java                         ViewRootImpl.java
InputEvent.aidl                          ViewStructure.java
InputEventConsistencyVerifier.java       ViewStub.java
InputEvent.java                          ViewTreeObserver.java
InputEventReceiver.java                  WindowAnimationFrameStats.aidl
InputEventSender.java                    WindowAnimationFrameStats.java
InputFilter.java                         WindowCallbackWrapper.java
inputmethod                              WindowContentFrameStats.aidl
InputQueue.java                          WindowContentFrameStats.java
IOnKeyguardExitResult.aidl               WindowId.java
IRotationWatcher.aidl                    WindowInfo.aidl
IWindow.aidl                             WindowInfo.java
IWindowFocusObserver.aidl                WindowInsets.java
IWindowId.aidl                           Window.java
IWindowManager.aidl                      WindowManager.aidl
IWindowSession.aidl                      WindowManagerGlobal.java
IWindowSessionCallback.aidl              WindowManagerImpl.java
KeyCharacterMap.java                     WindowManagerInternal.java
KeyEvent.aidl                            WindowManager.java
KeyEvent.java                            WindowManagerPolicy.java
LayoutInflater.java


2. Activity顯示

2.1 Activity創建

/base/core/java/android/app/ActivityThread.java

handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...............
    //根據類名以Java反射的方法創建一個Activity 
    Activity a = performLaunchActivity(r, customIntent);
    
    handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
................}

2.2 handleResumeActivity 

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume) {
.....................
if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                //得到一個view對象
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                //獲得viewManager
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    //將view加入viewmanager
                    wm.addView(decor, l);
                }
}
..................................}

2.3 Activity 通過setContentView設置UI

Activity.java

public void setContentView(View view, ViewGroup.LayoutParams params) {
        getWindow().setContentView(view, params);
        initWindowDecorActionBar();
    }
    
 public Window getWindow() {
        return mWindow;
    }

上面出現了兩個和UI有關係的類:View和Window

wKioL1gLCP6A0qLZAAAgcgiJoYY882.png

2.4 Activity Window 與WindowManager
Activity.java

 final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
        //創建window對象    
        mWindow = new PhoneWindow(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        //創建windowManager      
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
         //保存WindowManager對象       
         mWindowManager = mWindow.getWindowManager();


 setWindowManager由PhoneWindow父類window.java實現

Window.java

public void setWindowManager(WindowManager wm, IBinder appToken, String appName,){
 mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }

WindowManagerImpl.java

public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
        return new WindowManagerImpl(mDisplay, parentWindow);
    }
public final class WindowManagerImpl implements WindowManager {}

wKioL1gLEo6RAmwNAAAdowfdt8w811.png

   (2.4)中流程總結

2.5 繼續分析setContentView()

Activity.java

public void setContentView(View view, ViewGroup.LayoutParams params) {
        getWindow().setContentView(view, params);
        initWindowDecorActionBar();
    }

PhoneWindow.java

 private ViewGroup mContentParent;
 public void setContentView(View view) {
        setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
    }
    
  public void setContentView(View view, ViewGroup.LayoutParams params) {
  //mContentParent是一個viewGroup對象
  if (mContentParent == null) {
            installDecor();
        } 
        
  if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            view.setLayoutParams(params);
            final Scene newScene = new Scene(mContentParent, view);
            transitionTo(newScene);
        } else {
            //把view加入到ViewGroup中
            mContentParent.addView(view, params);
        }
  ........}

mContentParent是一個ViewGroup類型,它從View中派生,所以也是一個UI單元。從它名字中“Group”所表達的意思分析,它還可以包含其他的View元素。這又是什麼意思呢?也就是說,在繪製一個ViewGroup時,它不僅需要把自己的樣子畫出來,還需要把它包含的View元素的樣子也畫出來。讀者可將它想象成一個容器,容器中的元素就是View。
installDecor()函數
主要用來給view繪製icon ,window title,logo, menu等等


2.6 重回handleResumeActivity 

我們之所以分析2.5內容,是爲了弄清楚View, ViewManager(就是WindowManager)這些對象

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume) {
.....................
if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                //得到一個view對象
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                //獲得viewManager
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    //將view加入viewmanager
                    wm.addView(decor, l);
                }
}
..................................}

分析wm.addView(decor,l)

WindowManagerImpl.java

public final class WindowManagerImpl implements WindowManager {
    private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
 public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mDisplay, mParentWindow);
    }

WindowManagerGlobal裏面可以通過AIDL與IWindowManager.Stub.asInterface 及IWindowSessionCallback.Stub() IPC通信

WindowManagerGlobal.java

public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
            root = new ViewRootImpl(view.getContext(), display);
            view.setLayoutParams(wparams);
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);
            
            root.setView(view, wparams, panelParentView);// TAG 1


2.6.1 ViewRootImpl又是什麼東東?


ViewRootImpl.java

public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks{
        final IWindowSession mWindowSession;
        final Display mDisplay;
        final DisplayManager mDisplayManager;
        final W mWindow;
        final Surface mSurface = new Surface();
        
        static class W extends IWindow.Stub {
        private final WeakReference<ViewRootImpl> mViewAncestor;
        private final IWindowSession mWindowSession;}


ViewRootImpl繼承了Handler類,看來它能處理消息。ViewRootImpl果真重寫了handleMessage函數

一個成員變量叫mSurface,它是Surface類型

surface.java
public class Surface implements Parcelable {

一個W類型的mWindow和一個View類型的mView變量

ViewRootImpl有一個成員變量mSurface,它是Surface類型,它和一塊Raw Buffer有關聯。

ViewRootImpl是一個ViewParent,它的子View的繪畫操作,是在畫布Surface上展開的

ViewRootImpl的構造

public ViewRootImpl(Context context, Display display) {
    mDisplay = display;//Display.java Provides information about the size and density of a logical display.
    mWindowSession = WindowManagerGlobal.getWindowSession(); // IWindowSession AIDLmWindo    w = new W(this); //內部W對象,實際是與window通信的AIDL static class W extends IWindow.Stub
    mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);

WindowManagerGlobal.getWindowSession()將建立Activity的ViewRoot和WindowManagerService的關係

WindowManagerGlobal.java

 public static IWindowSession getWindowSession() {
 
     IWindowManager windowManager = getWindowManagerService();//得到Iwindowmanager對象,
     //IWindowManager 的AIDL Bn端是WindowManagerService class WindowManagerService extends IWindowManager.Stub
     sWindowSession = windowManager.openSession( //然後通過AIDL得到windowsession aidl 對象 不清楚爲啥已經有了windowmanager的aidl 幹嘛還需要windowsession aidl
     new IWindowSessionCallback.Stub() { })
 }  
 public static IWindowManager getWindowManagerService() {
     sWindowManagerService = IWindowManager.Stub.asInterface(
               ServiceManager.getService("window")); //得到WindowManager AIDL BP對象
         try {
                  sWindowManagerService = getWindowManagerService();
                  ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());                
              } catch (RemoteException e) {}

ViewRootImpl和WMS的關係

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

public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {}
        
        public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
            IInputContext inputContext) {
        Session session = new Session(this, callback, client, inputContext);
        return session;
    }

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

    final class Session extends IWindowSession.Stub
        implements IBinder.DeathRecipient {
        final WindowManagerService mService;
        final IWindowSessionCallback mCallback;
        final IInputMethodClient mClient;


分析完ViewRootImpl創建過程後,現在返回TAG 1處繼續分析ViewRootImpl.setView()
2.6.2 ViewRootImpl.setView()

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

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {

    // Compute surface insets required to draw at specified Z value.
    // TODO: Use real shadow insets for a constant max Z.
           if (!attrs.hasManualSurfaceInsets) {
                final int surfaceInset = (int) Math.ceil(view.getZ() * 2);
                attrs.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);} //計算Z軸座標
                
    requestLayout();
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
              getHostVisibility(), mDisplay.getDisplayId(),
              mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
              mAttachInfo.mOutsets, mInputChannel);
//requestLayout()流程  TAG2

public void requestLayout() {        scheduleTraversals();}

void scheduleTraversals() {
        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
        mChoreographer.postCallback(
             Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        notifyRendererOfFramePending();
        pokeDrawLockIfNeeded();}
        
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
//Runnable實現多線程,避免點繼承的侷限,一個類可以繼承多個接口.適合於資源的共享
final class TraversalRunnable implements Runnable {
        @Override
        public void run() {
            doTraversal();
        }
    }
    
void doTraversal() {
    performTraversals();}

private void performTraversals() {
     //mSurface是 surface.java 對象, final Surface mSurface = new Surface();
    // surface.java 通過jni 可以操作Surface.cpp 中surface對象 Surface::Surface(
    //    const sp<IGraphicBufferProducer>& bufferProducer,
    //    bool controlledByApp)
    if (mSurface.isValid()) { 
        if (mAttachInfo.mHardwareRenderer != null) {
            try {
                hwInitialized = mAttachInfo.mHardwareRenderer.initialize(mSurface);
                if (hwInitialized && (host.mPrivateFlags
                     & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
                    // Don't pre-allocate if transparent regions
                    // are requested as they may not be needed
                       mSurface.allocateBuffers();
                }
        }
     //Interface for rendering a view hierarchy using hardware acceleration.
     final HardwareRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer;
     hardwareRenderer.setup(mWidth, mHeight, mAttachInfo,
                            mWindowAttributes.surfaceInsets); 
}
mWindowSession.addToDisplay流程

//mWindowSession(IWindowSession) 通過AIDL 與Session.java交互 final class Session extends IWindowSession.Stub
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInset    s,Rect outOutsets, InputChannel outInputChannel) {
        return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
                outContentInsets, outStableInsets, outOutsets, outInputChannel);
    }
final WindowManagerService mService;
WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq,
       WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
       Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
       InputChannel outInputChannel) {
            //windowstate A window in the window manager.class WindowState implements WindowManagerPolicy.WindowState 
            WindowState win = new WindowState(this, session, client, token,
                attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
            win.attach();
}
WindowState.java
void attach() {
        mSession.windowAddedLocked();}
Session.java
void windowAddedLocked() {   
    mSurfaceSession = new SurfaceSession();
    mService.mSessions.add(this);
    mNumWindow++;
}

ViewRootImpl 與WMS關係總結

wKiom1gQkyPTB3qzAADJr2y68mc375.jpgViewRootImpl通過IWindowSession和WMS進程進行跨進程通信。
ViewRootImpl內部有一個W類型的對象,它也是一個基於Binder通信的類,W是IWindow的Bn端,用於響應請求。IWindow定義在另一個aidl文件IWindow.aidl中
IWindowSession

System private per-application interface to the window manager.

IWindow 

API back to a client window that the Window Manager uses to inform it of interesting things happening.


IWindow.aidl
void dispatchAppVisibility(boolean visible);
void dispatchWallpaperCommand(

void dispatchDragEvent(in DragEvent event);
void dispatchWindowShown();

這裏的事件指的就是按鍵、觸屏等事件。那麼,一個按鍵事件是如何被分發的呢?下面是它大致的流程:WMS所在的SystemServer進程接收到按鍵事件。WMS找到UI位於屏幕頂端的進程所對應的IWindow對象,調用這個IWindow對象的dispatchKey。IWindow對象的Bn端位於ViewRoot中,ViewRoot再根據內部View的位置信息找到真正處理這個事件的View,最後調用dispatchKey函數完成按鍵的處理。(這段過程沒有去跟代碼)

2.7 Activity的UI繪製

    在TAG2處分析過requestLayout。根據前面的分析可知,最終調用到performTraversals()

ViewRootImpl.java

private void performTraversals() {
    relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);//TAG3
    performDraw();//開始繪製
    }
     
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
    boolean insetsPending) throws RemoteException {
        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,
                mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface);
    }//這個函數通過AIDL調用到WMS relayoutWindow().暫時不繼續分析
    
private void performDraw() {
     draw(fullRedrawNeeded);}
     
private void draw(boolean fullRedrawNeeded){
     mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);//hw render完成draw
     //HardwareRenderer.java abstract void draw() }

2.8 Activity 總結

    Activity的頂層View是DecorView,而我們在onCreate函數中通過setContentView設置的View只不過是這個DecorView中的一部分罷了。DecorView是一個FrameLayout類型的ViewGroup。
     Activity和UI有關,它包含一個Window(真實類型是PhoneWindow)和一個WindowManager(真實類型是LocalWindowManager)對象。這兩個對象將控制整個Activity的顯示。
    LocalWindowManager使用了WindowManagerImpl做爲最終的處理對象(Proxy模式),這個WindowManagerImpl中有一個ViewRootImpl對象。ViewRootImpl實現了ViewParent接口,它有兩個重要的成員變量,一個是mView,它指向Activity頂層UI單元的DecorView,另外有一個mSurface,這個Surface包含了一個Canvas(畫布)(這個surface java對象可以通過JNI 與 surface.cpp中對象交互)。除此之外,ViewRooImplt還通過Binder系統和WindowManagerService進行了跨進程交互。
     ViewRoot能處理Handler的消息,Activity的顯示就是由ViewRoot在它的performTraversals函數中完成的。

3. Surface對象

    終於可以分析java與C++處surface對象了,先回憶下surface是如何創建的

    ViewRootImpl.java
    final Surface mSurface = new Surface();

     ViewRootImpl通過IWindowSession和WMS交互,而WMS中會調用的一個attach函數,會構造一個SurfaceSession,前面遇到過但沒有繼續分析

WindowState.java
void attach() {
        mSession.windowAddedLocked();}
Session.java
void windowAddedLocked() {   
    mSurfaceSession = new SurfaceSession();
    mService.mSessions.add(this);
    mNumWindow++;
}
SurfaceSession.java
 //* An instance of this class represents a connection to the surface
 //* flinger, from which you can create one or more Surface instances that will
 //* be composited to the screen.
public final class SurfaceSession {
    private static native long nativeCreate();
    private static native void nativeDestroy(long ptr);
    private static native void nativeKill(long ptr);}

 由註釋可見,surfacesession負責與SF的連接

  在2.7處Activity UI 繪製時,遇到過relayoutWindow(),現在繼續看該函數

   ViewRootImpl.java

private void performTraversals() {
    relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);//TAG3
    performDraw();//開始繪製
    }
     
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
    boolean insetsPending) throws RemoteException {
        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,
                mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface);
    }//這個函數通過AIDL調用到WMS relayoutWindow()
Session.java
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,..){
    int res = mService.relayoutWindow(this,....);}
WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int requestedWidth,....){
    SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();//TAG4 創建本地surfacecontrol 通過JNI會調用C++最終創建layer, java層保存的surfacecontrol對象是一個surfaceControl.cpp 中對象
    //JNI處返回的surfacecontrol
    //surface->incStrong((void *)nativeCreate);
    //return reinterpret_cast<jlong>(surface.get()); 
   
    outSurface.copyFrom(surfaceControl);//將本地surface拷貝到outSurface }
WindowStateAnimator.java
SurfaceControl createSurfaceLocked() {
    final WindowState w = mWin;
    mSurfaceControl = new SurfaceControl(
               mSession.mSurfaceSession,
               attrs.getTitle().toString(),
               width, height, format, flags);
   // Start a new transaction and apply position & offset.
   SurfaceControl.openTransaction();
   mSurfaceControl.setLayer(mAnimLayer);
   mSurfaceControl.setAlpha(0);
   SurfaceControl.closeTransaction();
   return mSurfaceControl;
}

SurfaceControl是個什麼對象?與Surface有何關係
/frameworks/base/core/java/android/view/SurfaceControl.java
看SurfaceControl構造函數說明,surfacecontrol根據name創建surface

/**
* Create a surface with a name.
* <p>
* The surface creation flags specify what kind of surface to create and
* certain options such as whether the surface can be assumed to be opaque
* and whether it should be initially hidden.  Surfaces should always be
* created with the {@link #HIDDEN} flag set to ensure that they are not
* made visible prematurely before all of the surface's properties have been
* configured.
* <p>
* Good practice is to first create the surface with the {@link #HIDDEN} flag
* specified, open a transaction, set the surface layer, layer stack, alpha,
* and position, call {@link #show} if appropriate, and close the transaction.
*
* @param session The surface session, must not be null.
* @param name The surface name, must not be null.
* @param w The surface initial width.
* @param h The surface initial height.
* @param flags The surface creation flags.  Should always include {@link #HIDDEN}
* in the creation flags.
*
* @throws throws OutOfResourcesException If the SurfaceControl cannot be created.
*/
public SurfaceControl(SurfaceSession session,
            String name, int w, int h, int format, int flags){
       mNativeObject = nativeCreate(session, name, w, h, format, flags);
 }
通過JNI android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags) {
    ScopedUtfChars name(env, nameStr);
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
    sp<SurfaceControl> surface = client->createSurface(
            String8(name.c_str()), w, h, format, flags); }
調用SurfaceComposiClient.cpp
sp<SurfaceControl> SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags){
        sp<SurfaceControl> sur;
        sp<IGraphicBufferProducer> gbp;
        status_t err = mClient->createSurface(name, w, h, format, flags,
                &handle, &gbp);//mClient 是一個sp<ISurfaceComposerClient>對象,由class Client : public BnSurfaceComposerClient來接收IPC交互,
        sur = new SurfaceControl(this, handle, gbp);// 最終通過JNI返回到TAG4處
        return sur;
}
Client.cpp
// ISurfaceComposerClient interface
/* Client是用來與surfaceflinger交互的橋樑,在sf中被創建 
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{
    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));
*/
status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp){
        result = flinger->createLayer(name, client, w, h, format, flags,
                    handle, gbp);}//這裏面的flinger是由Client::Client(const sp<SurfaceFlinger>& flinger)在創建時保存起來的
    : mFlinger(flinger)
}
Surfaceflinger.cpp
status_t SurfaceFlinger::createLayer(
        const String8& name,
        const sp<Client>& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp){
        sp<Layer> layer;

        switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createNormalLayer(client,//創建普通layer gbp是在layer中進行賦值
                    name, w, h, flags, format,
                    handle, gbp, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceDim:
            result = createDimLayer(client,//創建磨砂layer gbp是在layer中進行賦值
                    name, w, h, flags,
                    handle, gbp, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
            
        result = addClientLayer(client, *handle, *gbp, layer);//attach this layer to the client
    }
 //Client中createSurface函數,調用的是SF中createLayer
 //與前面ViewrootImpl.java中 final Surface mSurface = new Surface();有何區分?Layer與surface是如何區分?  前面遇到java surface用於drawSoftware或hwRender時 ex drawsoftware() canvas = mSurface.lockCanvas(dirty);mView.draw(canvas);

wKioL1gTJd-h3fZ-AAHMXAne67Q329.jpg上述流程的小結

3.1 Surface與畫圖

  lockCanvas 

 Surface.java
 * Gets a {@link Canvas} for drawing into this surface.
        public Canvas lockCanvas(Rect inOutDirty){
            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
            return mCanvas;
        }

   調用JNI
   android_view_Surface.cpp

static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
    sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
    
    Rect dirtyRect;
    Rect* dirtyRectPtr = NULL;

    if (dirtyRectObj) {
        dirtyRect.left   = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
        dirtyRect.top    = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
        dirtyRect.right  = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
        dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
        dirtyRectPtr = &dirtyRect;
    }
    
    ANativeWindow_Buffer outBuffer;
    status_t err = surface->lock(&outBuffer, dirtyRectPtr);//一塊表示髒區域的dirtyRectPtr
    //從surface.cpp 中dequeueBuffer()獲得一個GraphicBuffer, 然後將buffer的長寬,format 等賦制給outBuffer,
    
    //
    SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
                                         convertPixelFormat(outBuffer.format),
                                         kPremul_SkAlphaType);
                                         
    SkBitmap bitmap;
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    bitmap.setInfo(info, bpr);
    
     if (outBuffer.width > 0 && outBuffer.height > 0) {
        bitmap.setPixels(outBuffer.bits); // bitmap 指向一片存儲區域
    } else {
        // be safe with an empty bitmap.
        bitmap.setPixels(NULL);
    }
    
    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(bitmap);//將Bitmap設置到這個Canvas中,這樣進UI繪畫時就有畫布了
    // Create another reference to the surface and return it.  This reference
    // should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,
    // because the latter could be replaced while the surface is locked.
    sp<Surface> lockedSurface(surface);
    lockedSurface->incStrong(&sRefBaseOwner);
    return (jlong) lockedSurface.get();
 }

   lockCanvas獲得一塊存儲區域,然後將它和Canvas綁定到一起,這樣,UI繪畫的結果就記錄在這塊存儲區域裏了

  再看unlockCanvas
 Surface.java

  private void unlockSwCanvasAndPost(Canvas canvas) { // 只有sw 渲染的才走這邊?
      try {
            nativeUnlockCanvasAndPost(mLockedObject, canvas);
          } finally {
            nativeRelease(mLockedObject);
            mLockedObject = 0;
        }
  }

android_view_Surface.cpp

static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj) {
            sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));        
// detach the canvas from the surface
    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(SkBitmap());
    // unlock surface
    status_t err = surface->unlockAndPost();
}

Surface.cpp

status_t Surface::unlockAndPost()
{
    status_t err = mLockedBuffer->unlockAsync(&fd);
    //通過mGraphicBufferProducer->queueBuffer
    err = queueBuffer(mLockedBuffer.get(), fd);
}

直接使用別人的圖片surface畫圖過程

wKioL1gywGWTMr_bAAB0cVC9Ksw723.jpg


    

    回憶下上文surface 是如何創建的

sp<SurfaceControl> SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags){
        sp<IGraphicBufferProducer> gbp;
        status_t err = mClient->createSurface(name, w, h, format, flags,
                &handle, &gbp);
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);
        }
}

 

mClient  sp<ISurfaceComposerClient>  mClient;

  class Client : public BnSurfaceComposerClient

  Client 中mFlinger  sp<SurfaceFlinger> mFlinger;  這樣SurfaceComposerClient 就通過IPC 與surfaceflinger 交互起來了

status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{    
    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();
}



Client::createSurface() 與 android_view_Surface.cpp 中nativeReadFromParcel

surfacecontrol.cpp
status_t SurfaceControl::writeSurfaceToParcel(
        const sp<SurfaceControl>& control, Parcel* parcel)
{
    sp<IGraphicBufferProducer> bp;
    if (control != NULL) {
        bp = control->mGraphicBufferProducer;
    }
    return parcel->writeStrongBinder(IInterface::asBinder(bp));//Surface 核心是不是就是IGraphicBufferProducer 指針
}
android_view_Surface.cpp
static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject parcelObj) {
    Parcel* parcel = parcelForJavaObject(env, parcelObj);
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
    sp<IBinder> binder(parcel->readStrongBinder());
    // update the Surface only if the underlying IGraphicBufferProducer
    // has changed.
    if (self != NULL
            && (IInterface::asBinder(self->getIGraphicBufferProducer()) == binder)) {
        // same IGraphicBufferProducer, return ourselves
        return jlong(self.get());// 直接返回surface sp
    }
    //當GraphicBufferProducer改變時,新建一個surface,並將原先surface decStrong 釋放,返回新surface指針
    sp<Surface> sur;
    sp<IGraphicBufferProducer> gbp(interface_cast<IGraphicBufferProducer>(binder));
    if (gbp != NULL) {
        // we have a new IGraphicBufferProducer, create a new Surface for it
        sur = new Surface(gbp, true);
        // and keep a reference before passing to java
        sur->incStrong(&sRefBaseOwner);
    }
    if (self != NULL) {
        // and loose the java reference to ourselves
        self->decStrong(&sRefBaseOwner);
    }
    return jlong(sur.get());


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