「Android」 Surface分析

 本篇针对Surface模块进行分析,从Java层的Activity建立开始,到ViewRoot、WindowsManagerService,再到JNI层和Native层。java

首先推荐一个Android源码查看的网站:http://androidxref.com/android

Surface的建立涉及三个部分:canvas

  1. App 进程
    App须要将本身的内容显示在屏幕上,因此App负责发起Surface建立请求,建立好Surface后, 就能够直接能够在canvas上画图等,最终都会保存到Surface里的buffer里,最后由SurfaceFlinger合成并显示。数组

  2. System_Server进程
    主要是其中的WindowManagerService, 负责接收APP请求,向SurfaceFlinger发起具体的请求建立Surface, 且WMS须要建立Surface的辅助管理类,如SurfaceControl。session

  3. SurfaceFlinger
    为App进程建立具体的Surface, 在SurfaceFlinger里对应成Layer, 而后负责管理、合成显示。app

 

整体流程(参考《深刻理解Android》,源码较旧):composer

Surface建立过程: ActivityThread.java 调用handleLaunchActivity 调用handleResumeActivity函数 addView调用到LocalWindowManager.java的addView函数 而后调用WindowManagerImpl.java的addView函数 建立ViewRoot(分红两个分支): 1、执行ViewRoot的构造函数,建立mSurface(!实现ViewRoot的Surface建立)(建立IWindow) 2、调用ViewRoot的setView函数(分红两个分支): 1、setView调用WMS的add函数(IWindowSession) 调用WMS的addWindow函数 调用WMS.java::WindowState的attach函数 调用WMS.java::Session的windowAddedLocked函数,建立SurfaceSession(!实现WMS的SurfaceSession建立) 执行SurfaceSession的构造器,调用native函数init JNI层实现init函数,建立一个SurfaceComposerClient(分红两步): 1、SurfaceComposerClient构造函数调用SurfaceFlinger的createConnection(!和SF创建交互通道) 建立Client(建立共享内存)(一个Client最多支持31个显示层) Client构造函数建立SharedClient对象 SharedClient定义SharedBufferStack数组对象(有31个元素) 建立BClient(接受客户端请求,将处理提交给SF) 2、再调用_init(初始化SurfaceComposerClient一些成员变量) 2、调用requestLayout函数,向ViewRoot发送DO_TRAVERSAL消息 调用handleMessage函数 调用performTraversal函数(分红两个分支): 1、调用ViewRoot的relayoutWindow函数(调用IWindowSession的relayout函数) 调用createSurfaceControl建立一个SurfaceControl ?在SurfaceComposerClient的createSurface建立一个SurfaceControl(请求端) ?SurfaceComposerClient调用createSurface建立一个Surface(SurfaceControl类型) ? 调用SurfaceControl的writeToParcel将信息写入Parcel包中 ? 在readFromParcel中经过Parcel信息构造一个Surface对象,保存到mSurface ? ViewRoot得到一个Native的Surface对象 调用WMS.java::Session的relayout函数(!此和上这两步跨进程)(分红三步): 1、在IWindowSession.adil的Bn端调用onTransact,writeToParcel写入信息 2、在IWindowSession.adil的Bp端,relayout中传入outSurface,readFormParcel读取信息填充outSurface 3、调用WMS的relayoutWindow 》》调用WMS.java::WindowState的createSurfaceLocked,建立本地Surface(SurfaceSession) 》》调用copyForm,将本地surface信息拷贝到outSurface(即mSurface) 2、调用draw()函数开始绘制(lockCanvas、调用draw、unlockCanvasAndPost) 调用DecorView的draw函数(!实现UI绘制)

 

概述


 

Surface和APP的关系:tcp

  Surface像是UI的画布,APP就像是在Surface上做画,经过i使用Skia绘制二维图像,或是用OpenGL绘制三维图像,最终APP和Surfacea都要进行交互。ide

SUrface和SurfaceFlinger(SF)的关系:函数

  surface向SF提供数据,SF进行混合数据。

Activity的显示(Java层)


 一、应用程序的显示和surface有关,而应用程序的外表经过Activity展现的,那么Activity如何建立的呢?

  App对应的进程,它的入口函数是ActivityThread类的main函数。

  ActivityThread类中有一个handleLaunchActivity函数(建立Activity),代码以下:

private void handleLaunchActivity(ActivityClientRecord r
    , Intent customIntent
    , String reason) {
    ...
    Activity a = performLaunchActivity(r, customIntent);
    ...
    if (a != null) {
        ...
        handleResumeActivity(r.token
        , false
        , r.isForward
        ,!r.activity.mFinished && !r.startsNotResumed
        , r.lastProcessedSeq, reason);
        //Activity建立成功就往onResume()走了!
        ...
    }
}

 

   这个函数涉及了两个关键函数:

(1)performLaunchActivity
    返回一个activity(即App中的Activity),该方法 建立了Activity:
private Activity performLaunchActivity(ActivityClientRecord r
    , Intent customIntent) {
    ...
 // newActivity函数根据Activity的类名经过Java反射机制建立对应的Activity
    activity = mInstrumentation.newActivity(     
         cl, component.getClassName(), r.intent);
    ...
     Application app = r.packageInfo.makeApplication(false
     , mInstrumentation);
     //在获取Application
    ...
    activity.attach(appContext
        , this
        , getInstrumentation()
        , r.token
        ,.ident
        , app
        , r.intent
        , r.activityInfo
        , title
        , r.parent
        , r.embeddedID
        , r.lastNonConfigurationInstances
        , config
        ,r.referrer
        , r.voiceInteractor
        , window);
    ...
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(
          activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);  //调用Activity的onCreate函数
    }
    ...
}

  所以,performLaunchActivity的做用以下:

  • 根据类名以java反射机制的方法建立一个Activity
  • 调用Activity的onCreate函数,开始Activity 的生命周期
(2)handleResumeActivity
    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
            boolean reallyResume) {
        ...

        // 与调用Activity的onResume相关
        ActivityClientRecord r = performResumeActivity(token, clearHide);

        ...
                // PhoneWindow
                r.window = r.activity.getWindow();
                // 获取Activity的DecorView
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                // WindowManagerImpl,其实就是LocalWindowManager
                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;
                    wm.addView(decor, l);   // 将刚才的dector对象加入到ViewManagerg中
                }

            ...
    }

     

     > 在Activity.java中Activity在onCreate函数中经过setContentView设置UI界面。

  Activity.java部分代码:

public  void  setContentView(View view) {
  getWindow().setContentView(view);   // 传入一个view
}

public Window  getWindow() {
   return mWindow;    //返回一个类型为Window的对象
}

  > 分析出现的两个和UI相关的类:

Window:一个抽象基类,用于控制顶层窗口的外观和行为。职能多是绘制背景、标题栏、默认的按键处理等。

     它将做为一个顶层的view加入到Window  Manager中。 

View:一个基本的UI单元,占据屏幕的一块矩形区域,可用于绘制,能处理事件。(设置的view其实只是DecorView的子view,DecorView还处理了标题栏显示等一系列操做)

 

也能够看作:

  > 分析addView,wm类型其实是LocalWindowManager,查看LocalWindowManager.java的addView函数:

public  final void addView(View view , ViewGroup.LayoutParams params) {
      ..............
      mWindowManager.addView(view, params);  // mWindowManager对象实际是WindowManagerImpl类型
}

  接着查看WindowManagerImpl.java类的addView函数:

private void addView(View view, ViewGroup.LayoutParams params, boolean nest)
    {
       ...
      ViewRoot root;
      ...
      root = new ViewRoot(view.getContext());   // 建立viewRoot
      ...
      root.setView(view, wparams, panelParentView);   // view即刚刚介绍的DectorView

 


 

  二、 viewRoot: viewRoot实现了ViewParent接口,ViewParent不处理绘画,由于它没有onDraw函数(因此和Android基本绘画单元的view不太同样)

//查看ViewRoot.java::ViewRoot定义
public final class ViewRoot extends Handler implements ViewParent, View.AttachInfo.Callbacks    // 从Handler 派生
{
private final Suface mSurface = new Surface(); // 建立了一个Surface 对象
Final W mWindow;
View mView;
}

 

 分析得出ViewRoot的做用:
  • ViewRoot继承Handler类,可以处理消息,重写了handleMessage函数
  • ViewRoot有一个成员变量mSurface,是Surface类型
  • ViewRoot有一个W类型的mWinow和一个View类型的mView变量(W是ViewRoot定义的e静态内部类 static class W extends IWindow.Stub,将参与和Binder的通讯) 

View、DectorView是UI单元,绘画工做在OnDraw函数中完成。若是onDraw是画图过程,那么画布就是Surface。

Surface:有一块Raw Buffer,Surface操做这块Raw Buffer,Screen Compositor(即SurfaceFlinger)管理这块Raw Buffer。

结论:

  • ViewRoot的成员变量mSurface(aSurfce类型),他和一块Raw Buffer有关联
  • ViewRoot是一个ViewParent,他的子View的绘画操做,是在画布Surface上展开的
  • Surface和SurfaceFlinger交互

的setView中,调用的时ViewRoot.java的setView函数:

public void setView(View view, WindowManager.LayoutParams attrs,
            View panelParentView) {
      ...
      ...
    res = sWindowSession.add(mWindow, mWindowAttributes,
                            getHostVisibility(), mAttachInfo.mContentInsets,
                            mInputChannel);
    ...
}

 

 实现了:

  • 保存传入的View(即DectorView,从ActivityThread层层传入)
  • 调用requestLayout(往handler中发送一个消息,由于ViewRoot是从handlera派生的,因此这个消息最后会由ViewRoot本身处理)
  • 调用IWindowSession的add函数(一个跨进程的Binder通讯,第一个参数是mWindow,他是W类型,由IWindow.stub派生)

 


 

三、requestLayout会向ViewRoot发送一个消息,进入ViewRoot.java的handleMessage函数,调用performTraversals函数。

进入 performTraversals函数: 

private void performTraversals() {
    final View host = mView;   //即最初的DectorView
    ...
  try{
    relayoutResult = relayoutWindow(params, viewVisiblity, insetPending);
} ... host.measure(childWidthMeasureSpec, childHeightMeasureSpec); ... host.layout(
0, 0, host.mMeasuredWidth, host.mMeasuredHeight); ... ... draw(fullRedrawNeeded); ... }

 

(1)relayoutWindow函数:会调用IWindowSession的Relayout函数;

(2)draw函数:从mSurface(Surface)中lock一块Canvas(画布),调用DecorView的draw函数,而后交给mView绘画,最后unlockCanvasAndPost释放这块Canvas

 


 

总结:

一、大体涉及的方法、类的大致流程(回车表示前一方法内调用):

ActivityThread.java
    调用handleLaunchActivity
        调用performLaunchActivity函数(建立Activity、调用onCreate)
            onCreate调用setContentView函数设置UI界面,传入view,返回Window
        调用handleResumeActivity函数
            addView调用到LocalWindowManager.java的addView函数
                而后调用WindowManagerImpl.java的addView函数
                    建立ViewRoot,调用ViewRoot的setView函数

ViewRoot.java(继承Handler、实现ViewParent)
    构造函数建立一个Surface对象mSurface
    setView函数实现:
        保存传入的view为mView
        调用requestLayout
        调用IWindowSession的add函数
        WIndowManagerServce.java::session的add函数
          调用WMS.java的addWindow
            调用WMS.java::WIndowState的attach函数
              调用windowAnddedLocked函数并建立一个SurfaceSession对象 
requestLayout(向ViewRoot发送一个消息) 进入ViewRoot.java的handleMessage函数 调用performTraversals函数 调用relayoutWindow函数 调用IWindowSession的Relayout函数 调用draw函数(从mSurface中lock一块Canvas) 调用DecorView的draw函数,交给mView绘画 最后unlockCanvasAndPost释放Canvas

 

二、要点:

(1)整个Activity的绘图流程就是从mSurface中lock一块Canvas,而后交给mView去绘画,最后unlockCanvasAndPost释放这块Canvas ;

(2)Activity的顶层view是DecotView,而onCreate函数中setContentView设置的View是这个DecorView的一部分。DecorView是一个FrameLayout类型的ViewGroup;

(3)Activity和UI有关,包含window(真实类型是phoneWIndow)和一个WindowManger(真实类型是LocalWindowManager)对象。这两个对象控制整个Activity的显示;

(4)LocalWindowManager使用了WindowManagerImpl.java(其中addView有一个ViewRoot对象)做为最终处理对象;

(5)ViewRoot实现了ViewParent接口,有两个变量:

    mView,指向Activity顶层UI单元的DecorView

    mSurface,包含一个Canvas

   此外,ViewRoot还经过Binder系统和dWinowManagerService进行跨进程交互;

(6)ViewRoot可以处理Handler的消息,Activity的显示就是由ViwRoot在他的performTraversals函数中完成;


 

 

Surface(Java层)


经过上面一节的分析可知:

ViewRoot的构造函数里面会建立一个Surface;

而ViewRoot经过IWindowSession和WMS交互时,WMS调用的attach函数会构造一个SurfaceSession;

ViewRoot在prformTransval的处理过程当中会调用IWindowSession的relayout函数。(WMS由SYsytem_server进程启动,SF服务也在这个进程中)

 

  两个部分的Surface看似是毫无关系,可是实际上,在使用createSurfaceLocked() 的时候,会将creaeSurfaceLocked 建立的Surface copy到ViewRoot层的Surface中。也就是这样,将底层的Surface对象传到上层,供Activity的界面部分使用,用来绘图。整个流程大概是:

RootView.relayoutWindow,调用方,调用relayout将mSurface传进去

->  WindowManagerService.Session.relayout调用外部类对象的relayoutWindow

->  WindowManagerService.relayoutWindow,调用createSurfaceLocked

->  WindowManagerService.createSurfaceLocked(),将SurfaceSession拷贝到建立的新对象Surface

->  outSurface.copyFrom(surface),将本地Surface 的信息(即SurfaceSession)拷贝到outSurface中

最后一步是将WindowManagerService的surface与ViewRoot 的outSurface联系起来的关键点,outSurface是做为参数,从RootView传到WindowManagerService的。

ViewRoot实际上是经过Binder与WindowManagerService进行跨进程调用通讯的。

 


 

 

Surface(JNI层)


 

一、在JNI层,首先被调用的时Surface的无参构造函数,代码:

// Surface.java
Public Surface() {
 ...
mCanvas = new CompatibleCanvas();  //   CompatibleCanvaso从Canvas类派生
}

 

 Canvas:

  画图须要:

  • Bitmap,用于存储像素(即画布,能够看成是一块数据存储区域);
  • Canvas,用于记载画图的动做(例如画一个矩形),Canvas提供了这些基本操做的绘图函数;
  • Drawing primitive:绘图基本元素,例如矩形、圆等;
  • Paint:用来描述h绘画时使用的颜色、虚实线等;

通常状况下,Canvas会封装一块Bitmap。

 

二、SurfaceSession的构造

// SurfaceSession.java
public  SurfaceSession(){
       init();   //这是一个native函数       
}

 

init函数的实如今JNI的android_view_Surface.cpp中:

static void SurfaceSession_init(JNIEnv* env,jobject clazz)
{
     //建立一个SurfaceComposerClient对象
   sp<SurfaceComposerClient> client = new SurfaceComposerClient;
client->incStrong(clazz);
//在Java对象中保存这个client对象的指针,类型为SurfaceComposerClient
   env->SetIntField(clazz, sso.client, (int)client.get());
}

 

 

三、Surface的有参构造函数:

//    Surface.java
    publicSurface(SurfaceSession s,//传入一个SurfaceSession对象
           int pid, String name, int display, int w, int h, int format, int flags)
       throws OutOfResourcesException {
        ......
       mCanvas = new CompatibleCanvas();
      //又一个native函数,注意传递的参数:display之后再说,w,h表明绘图区域的宽高值
       init(s,pid,name,display,w,h,format,flags);
       mName = name;
    }

 

Surface的init函数实如今JNI层:

static void Surface_init(

        JNIEnv*env, jobject clazz,
       jobject session,
       jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags)
{
   //从SurfaceSession对象中取出以前建立的那个SurfaceComposerClient对象
SurfaceComposerClient* client =
           (SurfaceComposerClient*)env->GetIntField(session, sso.client);

   sp<SurfaceControl> surface;//注意它的类型是SurfaceControl
if (jname == NULL) {
    /*
调用SurfaceComposerClient的createSurface函数,返回的surface是一个
SurfaceControl类型。
*/
       surface = client->createSurface(pid, dpy, w, h, format, flags);
    } else{
      ......
}
   //把这个surfaceControl对象设置到Java层的Surface对象中,对这个函数就再也不分析了
   setSurfaceControl(env, clazz, surface);
}

 

 

四、copyForm分析 

上一节中,outSurface.copyFrom(surface),将本地Surface 的信息(即SurfaceSession)拷贝到outSurface中

他是一个native函数,代码以下:

static void Surface_copyFrom(JNIEnv* env,jobject clazz, jobject other)
{
   //根据JNI函数的规则,clazz是copyFrom的调用对象,而other是copyFrom的参数。
   //目标对象此时尚未设置SurfaceControl,而源对象在前面已经建立了SurfaceControl
   constsp<SurfaceControl>& surface = getSurfaceControl(env, clazz);
   constsp<SurfaceControl>& rhs = getSurfaceControl(env, other);

if (!SurfaceControl::isSameSurface(surface, rhs)) {
        //把源SurfaceControl对象设置到目标Surface中。
       setSurfaceControl(env, clazz, rhs);
    }
}

 

 

五、writeToParcel和readFromParcel分析

这两个函数调用发生在ViewRoot调用IWindowSession的relayout函数中,它发生在IWindowSession.adil(经过aidl -l ...编译成java文件可查看到relayout方法中和onTransactg中)

//  android_view_Surface.cpp
static void Surface_writeToParcel(JNIEnv* env,jobject clazz,
jobject argParcel, jint flags)
{
   Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel);

//clazz就是Surface对象,从这个Surface对象中取出保存的SurfaceControl对象
const sp<SurfaceControl>&control(getSurfaceControl(env, clazz));
/*
把SurfaceControl中的信息写到Parcel包中,而后利用Binder通讯传递到对端,
对端经过readFromParcel来处理Parcel包。
*/
   SurfaceControl::writeSurfaceToParcel(control, parcel);

if (flags & PARCELABLE_WRITE_RETURN_VALUE) {

       //lags的值就等于PARCELABLE_WRITE_RETURN_VALUE
       //因此本地Surface对象的SurfaceControl值被置空了
       setSurfaceControl(env, clazz, 0);
    }
}
--------------------- 

//  android_view_Surface.cpp

static void Surface_readFromParcel(
       JNIEnv* env, jobject clazz, jobject argParcel)
{
   Parcel* parcel = (Parcel*)env->GetIntField( argParcel,no.native_parcel);
   //注意下面定义的变量类型是Surface,而不是SurfaceControl
   const sp<Surface>&control(getSurface(env, clazz));

   //根据服务端传递的Parcel包来构造一个新的surface。    sp<Surface> rhs = new Surface(*parcel);

if (!Surface::isSameSurface(control, rhs)) {
//把这个新surface赋给ViewRoot中的mSurface对象
      setSurface(env,clazz, rhs);
    }
}

 

小结

在JNIe层建立了三个对象:SurfaceComposerClient、SurfceControl、Surface 

大体流程:

(1)建立一个SurfaceComposerClient

(2)调用SurfaceComposerClient的createSurface获得一个SurfceControl对象

(3)调用SurfaceControl的writeToParcel,将一些信息写入Parcel包中

(4)根据Parcel包的信息z构造一个Surface对象,将其保存到Java层的mSurface中

(5)所以,ViewRoot获得一个Native的Surface对象

 

 Surface和画图Canvas:

在ViewRoot的draw()函数里面(前面有提到),有两个和Surface相关的函数调用:

  (1)lockCanvas:先得到一块存储区域,而后将它和Canvas绑定到一块儿,这样,UI绘画的结果就记录在这块存储区域里了,如此进Canvas进行UI画图就会有画布了;

  (2)unlockCanvasAndPost:一个native函数,取出Native的Surface对象,调用Surface的unlockAndPost函数。

 

调用流程总结:

   

总结

一、一个Activity通常都会对应到一个Window, 对应了一个DecorView, ViewRoot 
二、ViewRoot中有一个Surface, 就是App能够用于绘制UI的Surface了,在Native层也对应了一个Surface, 在SurfaceFlinger对应的是一个Layer,经过Layer中的Producer能够真正的申请Buffer用于绘制。App中经过Surface中的Canvas的相似lockcanvas接口触发dequeue buffer流程。 
三、 一个ViewRoot在WMS端对应了一个WindowState, WindowState又经过一系列引用关联到一个SurfaceControl, Native层也有一个SurfaceControl。这个能够用于控制窗口的一些属性。 
四、 WMS native层的SurfaceComposerClient与SurfaceFlinger之间经过ISurfaceComposerClient创建联系。一个App在SurfaceFlinger端对应了一个Client,用于处理该App layer的建立等请求。

五、当ViewRootImpl请求WMS relayout时,会将ViewSurface中的Surface交给WMS初始化。在WMS中,对应每一个WindowState对象,在relayout窗口时,一样会建立一个Surface,wms中的这个Surface会真正的初始化,而后再将这个WMS Surface复制给ViewRootImpl中的Surface。这么实现的目的就是保证ViewRootImpl和WMS共享同一个Surface。ViewRootImpl对Surface进行绘制,WMS对这个Surface进行初始化及管理。 

ActivityThread.java
    调用handleLaunchActivity
        调用performLaunchActivity函数(建立Activity、调用onCreate)
            onCreate调用setContentView函数设置UI界面,传入view,返回Window
        调用handleResumeActivity函数
            addView调用到LocalWindowManager.java的addView函数
                而后调用WindowManagerImpl.java的addView函数
                    建立ViewRoot,调用ViewRoot的setView函数

ViewRoot.java(继承Handler、实现ViewParent)
    构造函数建立一个Surface对象mSurface
    setView函数实现:
        保存传入的view为mView
        调用requestLayout
        调用IWindowSession的add函数
        WIndowManagerServce.java::session的add函数
          调用WMS.java的addWindow
            调用WMS.java::WIndowState的attach函数
              调用windowAnddedLocked函数并建立一个SurfaceSession对象 

requestLayout(向ViewRoot发送一个消息)
    进入ViewRoot.java的handleMessage函数
        调用performTraversals函数
            调用relayoutWindow函数
                调用IWindowSession的Relayout函数
            调用draw函数(从mSurface中lock一块Canvas)
                调用DecorView的draw函数,交给mView绘画
                最后unlockCanvasAndPost释放Canvas

 

建立Surface的总体流程:

1.1 viewrootImpl.java

在应用启动时,会经过WindowManagerGlobal去添加view,添加view时会去建立viewRootImpl,而后进行设置view。

viewRootImpl.setView() —> requestLayout()申请布局—>scheduleTraversals()—>doTraversal()–>performTraversals()

利用IWindowSession和Session通讯,调用relayout,注意,这里mSurface是ViewRootImpl的成员变量,开始调用了无参的构造函数,IWindowSession.aidl文件中,参数mSurface是被out修饰,用来接受在server端建立Surface,而后再binder返回给ViewRootImpl。

1.2 Session.java

 public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewFlags,
            int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
            Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
        int res = mService.relayoutWindow(this, window, seq, attrs,
                requestedWidth, requestedHeight, viewFlags, flags,
                outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
                outConfig, outSurface);
        return res;
    }

 

1.3 WindowManagerService.java

 public int relayoutWindow(Session session, IWindow client, int seq,
          WindowManager.LayoutParams attrs, int requestedWidth,
          int requestedHeight, int viewVisibility, int flags,
          Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
          Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {

          //新建一个SurfaceControl 
          SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
                  if (surfaceControl != null) {
                      outSurface.copyFrom(surfaceControl);
                      if (SHOW_TRANSACTIONS) Slog.i(TAG,
                              "  OUT SURFACE " + outSurface + ": copied");
                  } else {
                      // For some reason there isn't a surface.  Clear the
                      // caller's object so they see the same state.
                      outSurface.release();
                  }
          }

 


 1.4 WindowStateAnimator.java

首先建立一个SurfaceControl:

SurfaceControl createSurfaceLocked() {

            mSurfaceControl = new SurfaceControl(
                        mSession.mSurfaceSession,
                        attrs.getTitle().toString(),
                        w, h, format, flags);
             }

    public SurfaceControl(SurfaceSession session,
            String name, int w, int h, int format, int flags)
                    throws OutOfResourcesException {
              //session就是SurfaceComposerClient在java层的表明
              //mNativeObject是native层SurfaceControl的指针
    mNativeObject = nativeCreate(session, name, w, h, format, flags);
    }

1.5 android_view_SurfaceControl.cpp

static jint nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags) {
    ScopedUtfChars name(env, nameStr);
    //从上层取到SurfaceComposerClient的指针,还原一个SurfaceComposerClient
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
    //调用createSurface,返回的是一个SurfaceControl对象,注意不是surface
    sp<SurfaceControl> surface = client->createSurface(
            String8(name.c_str()), w, h, format, flags);
    if (surface == NULL) {
        jniThrowException(env, OutOfResourcesException, NULL);
        return 0;
    }
    surface->incStrong((void *)nativeCreate);
    //返回给java层SurfaceControl的指针
    return int(surface.get());
}

 

1.6 SurfaceComposerClient.cpp

sp<SurfaceControl> SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags)
{
    sp<SurfaceControl> sur;
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;
        status_t err = mClient->createSurface(name, w, h, format, flags,
                &handle, &gbp);
        //gbp就是surfacefligner中Layer的mBufferQueue的client端(IGraphicBufferProducer) 
        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);
        }
    }
    return sur;
}

 

1.7 Client.cpp

经过ISurfaceComposerClient的binder通讯,调用服务端对应client对象的方法createSurface()

status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{
    /*
     * createSurface must be called from the GL thread so that it can
     * have access to the GL context.
     */

    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; }
        //MessageQueue.cpp 中方法回调MessageBase::handleMessage
        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();
}

 

 上述可看出,将建立layer消息放入队列,以下所示:

status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
        nsecs_t reltime, uint32_t /* flags */) {
    status_t res = mEventQueue.postMessage(msg, reltime);
    if (res == NO_ERROR) {
        //阻塞等待消息处理完成
        msg->wait();
    }
    return res;
}

1.8 Layer.cpp

建立layer的消息被处理时,就会回调上述MessageCreateLayer类中的handler方法。handler方法中调用flinger.createLayer(),第一次还会执行Layer.onFirstRef()

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)
{
    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
    if (int32_t(w|h) < 0) {
        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
                int(w), int(h));
        return BAD_VALUE;
    }

    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;
        case ISurfaceComposerClient::eFXSurfaceDim:
            result = createDimLayer(client,
                    name, w, h, flags,
                    handle, gbp, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }

    if (result != NO_ERROR) {
        return result;
    }

    result = addClientLayer(client, *handle, *gbp, layer);
    if (result != NO_ERROR) {
        return result;
    }

    setTransactionFlags(eTransactionNeeded);
    return result;
}

 

 在执行Layer::onFirstRef()会新建一个缓冲区队列的消费者与客户端APP的生产者对应:

void Layer::onFirstRef()
{
    //surfaceflinger中新建一个缓冲区队列的消费者
    mBufferQueue = new SurfaceTextureLayer(mFlinger);
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    mSurfaceFlingerConsumer->setName(mName);

#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
#warning "disabling triple buffering"
    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
#else
    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
#endif

    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
} 

 

Surface(Native层)


(1)FrameBuffer(帧缓冲,存储图形、图像的缓冲):

  Frame:帧,就是指一幅图像。在屏幕a上看到的一幅图像就是一帧。

  Buffer:缓冲,就是一段存储区域(存储的是帧) 。

(2) PageFlipping(画面交换),用于图像、图形数据的生产和消费

  操做过程:

    一、分配一个能容纳两帧数据的缓冲Buffer,前面一个缓冲叫FrontBuffer,后一个叫BackBuffer;

    二、消费者使用FontBuffer中的旧数据,而生产者使用新数据填充BackBuffer,两者互不干扰;

    三、当须要更新显示时,BackBuffer变成oFrontBuffer,FrontBuffer变成BackBuffer。如此循环。

相关文章
相关标签/搜索