详解Android SurfaceFinger服务

目录(?)[-]

  1. 概述
  2. 相关类图
  3. 启动
  4. SurfaceFlinger构造
  1. EGL初始化
  2. Hardware Composer初始化
  3. 选择EGLConfig并创建EGLContext
  4. 初始化各个DisplayDevice
  5. 初始化OpenGL ES并绑定到当前进程初始化EGLDisplay
  1. 创建Surface

概述

SurfaceFlinger是android平台的显示服务,为移动互联网时代的内容呈现和交互提供了平台级的基础。本文以Android4.2的源代码和架构为例,详细介绍SurfaceFlinger服务。

相关类图

android surface的数据显示 android window surface_主线程

启动

SurfaceFlinger服务的源代码位于frameworks/native/cmds/surfaceflinger下:

1. int main(int argc, char** argv) {  
2. true);  
3. // When SF is launched in its own process, limit the number of
4. // binder threads to 4.
5.     ProcessState::self()->setThreadPoolMaxThreadCount(4);  
6. return
7. }

为android平台上最常见的native BinderService启动方式。

下边结合binder上层接口粗略分析该段程序。

将"SurfaceFlinger::publishAndJoinThreadPool(true);"

扩展开变为:

1. sp<IServiceManager> sm(defaultServiceManager());  
2. sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); // 向servicemanager注册SurfaceFinger服务,以“SurfaceFlinger”作为名字/标识
3. ProcessState::self()->startThreadPool();  
4. IPCThreadState::self()->joinThreadPool();

ProcessState为每进程的记录binder进程状态的类。主要职责在于:

  1. 打开binder设备并将binder事务内存映射到本进程地址空间的最开始,尺寸为BINDER_VM_SIZE
  2. 记录contextobject(一般为servicemanager代理对象)
  3. 孵化线程/管理线程池
  4. IBinder和handle之间的转换和查询

1. ProcessState::self()->startThreadPool();

通过创建一个额外线程(自动进入looper状态)来启动线程池,

1. IPCThreadState::self()->joinThreadPool();

IPCThreadState为每线程(通过编程本地存储实现)的管理binder thread状态的类,同时负责与binder设备之间的数据交换,其成员:

1. Parcel              mIn;  
2. Parcel              mOut;

承担着binder的flat/unflat、发出请求到binder、从binder设备接收client端的请求等任务。

这样子主线程也进入looper模式,现在进入joinThreadPool方法:

binder通信的主要细节就在此方法中,主要思想便是通过talkWithDriver来取到本进程接收到的binder请求并将其反序列化为mIn身上,读出cmd并执行之,摘取几个重要的cmd如下:

BR_TRANSACTION:代表一次binder事务,最常见的便是RPC调用了

1. binder_transaction_data tr;  
2. ......  
3. if
4.     sp<BBinder> b((BBinder*)tr.cookie);  
5. const
6. if
7.   
8. } else
9. const
10. if
11. }

binder_transaction_data身上带有服务端的BBinder(client端第一次从servicemanager查询到服务端时被告知并由binder driver记录),

当tr.target.ptr非空时,通过该BBinder对象的transact函数来完成RPC。否则意味着对context_object(通常为本进程内的BpServiceManager对象,且对应handle为0 )的请求。

BBinder的子类通过onTransact函数来服务各种RPC调用。在本文中,便是SurfaceFlinger对象的onTransact函数来应对client的请求。

BR_SPAWN_LOOPER:

前边启动过程中,binder thread包括主线程(SurfaceFlinger对象构造过程中也创建了额外辅助进程,但不是binder thread,排除在外,在本文后半部分分析)一共是两个。当有多个client请求时,势必binder thread不够用(binder driver簿记binder thread的各种信息),此时binder driver便post BR_SPAWN_LOOPER类型的cmd,让本进程预先孵化下一个binder thread,且此后孵化的线程不会进入looper模式(主要处理线程),只是登记为looper(目前在driver中未看出来两者明显区别)

另外,当本进程需要其他服务的协助的时候呢,本进程也需要作为client来发起binder请求,此时便用到了BpBinder::transact()函数,BpBinder成员mHandle用来引用远端对象,作为参数传递给IPCThreadState::self()->transact()来完成。其原理与前述接受binder请求的过程相反,不再赘述。

SurfaceFlinger构造

此步骤是前述启动步骤中的一小步,但也是展现出特定service与众不同的最大一步。

如文件第一部分所列类图所示,SurfaceFlinger继承自多个基类:

1. class SurfaceFlinger : public
2. public
3. private
4. private
5. private

构造函数非常轻量级,只获取了几个系统debug设置。

在ServiceManager addservice时第一次引用刚创建的SurfaceFinger对象,其基类RefBase的onFirstRef被调用:

1. void
2. {  
3. this);  
4.   
5. "SurfaceFlinger", PRIORITY_URGENT_DISPLAY);  
6.   
7. // Wait for the main thread to be done with its initialization
8.     mReadyToRunBarrier.wait();  
9. }

初始化EventQueue,并建立Looper/Handler这对好基友。

接下来启动自己(SurfaceFlinger也是Thread对象),

然后主线程阻塞住直到ReadyToRun(Thread真正启动前的一次性初始化函数)被调用。

接下来咱们转到ReadyToRun函数,鉴于该函数如一枚知性的熟女——深有内涵:

1. ALOGI(  "SurfaceFlinger's main thread ready to run. "
2. "Initializing graphics H/W...");  
3.   
4. // initialize EGL for the default display
5. mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);  
6. eglInitialize(mEGLDisplay, NULL, NULL);  
7.   
8. // Initialize the H/W composer object.  There may or may not be an
9. // actual hardware composer underneath.
10. mHwc = new HWComposer(this,  
11. static_cast<HWComposer::EventHandler *>(this));  
12.   
13. // initialize the config and context
14. EGLint format = mHwc->getVisualID();  
15. mEGLConfig  = selectEGLConfig(mEGLDisplay, format);  
16. mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);  
17.   
18. LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,  
19. "couldn't create EGLContext");  
20.   
21. // initialize our non-virtual displays
22. for (size_t
23.     DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);  
24. new
25.     wp<IBinder> token = mDefaultDisplays[i];  
26.   
27. // set-up the displays that are already connected
28. if
29. // All non-virtual displays are currently considered secure.
30. bool isSecure = true;  
31.         mCurrentState.displays.add(token, DisplayDeviceState(type));  
32. new
33. new
34. static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));  
35. new DisplayDevice(this,  
36.                 type, isSecure, token, stc, fbs, mEGLConfig);  
37. if
38. // FIXME: currently we don't get blank/unblank requests
39. // for displays other than the main display, so we always
40. // assume a connected display is unblanked.
41. "marking display %d as acquired/unblanked", i);  
42.             hw->acquireScreen();  
43.         }  
44.         mDisplays.add(token, hw);  
45.     }  
46. }  
47.   
48. //  we need a GL context current in a few places, when initializing
49. //  OpenGL ES (see below), or creating a layer,
50. //  or when a texture is (asynchronously) destroyed, and for that
51. //  we need a valid surface, so it's convenient to use the main display
52. //  for that.
53. sp<const
54.   
55. //  initialize OpenGL ES
56. DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);  
57. initializeGL(mEGLDisplay);  
58.   
59. // start the EventThread
60. mEventThread = new EventThread(this);  
61. mEventQueue.setEventThread(mEventThread);  
62.   
63. // initialize our drawing state
64. mDrawingState = mCurrentState;  
65.   
66.   
67. // We're now ready to accept clients...
68. mReadyToRunBarrier.open();  
69.   
70. // set initial conditions (e.g. unblank default device)
71. initializeDisplays();  
72.   
73. // start boot animation
74. startBootAnim();  
75.   
76. return

我们将其曼妙身段划分为如下:

  1. EGL初始化
  2. Hardware Composer初始化
  3. 选择EGLConfig并创建EGLContext
  4. 初始化各个DisplayDevice
  5. 初始化OpenGL ES并绑定到当前进程,初始化EGLDisplay
  6. 创建EventThread用于为mEventQueue身上的Handler/Looper搞基提供上下文
  7. 通知主线程,让其继续运行
  8. 初始化显示,并显示启动动画(通过“property_set("ctl.start", "bootanim")”)

下边摘取其中一些关键步骤分析:

EGL初始化

EGL初始化主要通过eglGetDisplay()来实现,其参数为EGL_DEFAULT_DISPLAY(一个handle值,意义依赖于具体平台):

1. EGLDisplay eglGetDisplay(EGLNativeDisplayType display)  
2. {  
3.     clearError();  
4.   
5.     uint32_t index = uint32_t(display);  
6. if
7. return
8.     }  
9.   
10. if
11. return
12.     }  
13.   
14.     EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);  
15. return
16. }

接下来的调用栈为:egl_init_drivers->egl_init_drivers_locked,egl_init_drivers_locked中主要就是根据/system/lib/egl/egl.cfg文件中配置信息(其中便指定了{tag}的值)运行时装载libGLESv1_CM_{tag}.so,libGLESv2_{tag}.so libEGL_{tag}.so,并将egl_entries.in中的egl函数簇的地址全部找到并绑定到egl_connection_t的egl成员上,将entries.in中的gl函数簇的地址全部找到并绑定到egl_connection_t的hooks上,所以最终的egl的一堆东西都保存在了进程全局变量:

1. egl_connection_t gEGLImpl;  
2. gl_hooks_t gHooks[2];

上(gEGLImpl成员含有对gHooks的指针)。

接下来便是拿到EGLDisplay的过程,包含在egl_display_t::getFromNativeDisplay(display)中,其实现是调用上一步中装载的EGL库中的"eglGetDisplay"函数来获得真正实现并设定给egl_display_t::sDisplay[NUM_DISPLAYS].dpy,返回egl_display_t::sDisplay数组中第一个invalid项的索引作为EGLDisplay handle

接下来便是EGL初始化的过程:

1. EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)  
2. {  
3.     clearError();  
4.   
5.     egl_display_ptr dp = get_display(dpy);  
6. if (!dp) return
7.   
8.     EGLBoolean res = dp->initialize(major, minor);  
9.   
10. return
11. }

其中关键步骤体现在dp->initialize中,展开它的实现:

1. EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {  
2.   
3.     Mutex::Autolock _l(lock);  
4.   
5. if
6. if
7.             *major = VERSION_MAJOR;  
8. if
9.             *minor = VERSION_MINOR;  
10.         refs++;  
11. return
12.     }  
13.   
14. #if EGL_TRACE
15.   
16. // Called both at early_init time and at this time. (Early_init is pre-zygote, so
17. // the information from that call may be stale.)
18.     initEglTraceLevel();  
19.     initEglDebugLevel();  
20.   
21. #endif
22.   
23. // 将前边从egl库中取出来的glhooks绑定到thread的TLS上,Note:bionic c为OpenGL预留了专用的TLS,see:<tt><a target="_blank" href="http://10.37.116.53:7080/source/xref/GTV4_2/bionic/libc/private/bionic_tls.h">bionic_tls.h</a></tt>
24.   
25. // initialize each EGL and
26. // build our own extension string first, based on the extension we know
27. // and the extension supported by our client implementation
28.   
29. const
30.     cnx->major = -1;  
31.     cnx->minor = -1;  
32. if
33.   
34. #if defined(ADRENO130)
35. #warning "Adreno-130 eglInitialize() workaround"
36. /*
37.          * The ADRENO 130 driver returns a different EGLDisplay each time
38.          * eglGetDisplay() is called, but also makes the EGLDisplay invalid
39.          * after eglTerminate() has been called, so that eglInitialize()
40.          * cannot be called again. Therefore, we need to make sure to call
41.          * eglGetDisplay() before calling eglInitialize();
42.          */
43. if
44.             disp[i].dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);  
45.         }  
46. #endif
47.   
48.         EGLDisplay idpy = disp.dpy;  
49. if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) { // 调用egl库中的eglInitialize
50. //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
51. //        idpy, cnx->major, cnx->minor, cnx);
52.   
53. // display is now initialized
54.             disp.state = egl_display_t::INITIALIZED;  
55.   
56. // get the query-strings for this display for each implementation
57. // 查询一些meta信息
58.                     EGL_VENDOR);  
59.             disp.queryString.version = cnx->egl.eglQueryString(idpy,  
60.                     EGL_VERSION);  
61.             disp.queryString.extensions = cnx->egl.eglQueryString(idpy,  
62.                     EGL_EXTENSIONS);  
63.             disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,  
64.                     EGL_CLIENT_APIS);  
65.   
66. else
67. "eglInitialize(%p) failed (%s)", idpy,  
68.                     egl_tls_t::egl_strerror(cnx->egl.eglGetError()));  
69.         }  
70.     }  
71.   
72. // the query strings are per-display
73.     mVendorString.setTo(sVendorString);  
74.     mVersionString.setTo(sVersionString);  
75.     mClientApiString.setTo(sClientApiString);  
76.   
77. // we only add extensions that exist in the implementation
78. char const* start = sExtensionString; // 装配扩展信息
79. char const* end;  
80. do
81. // find the space separating this extension for the next one
82. ' ');  
83. if
84. // length of the extension string
85. const size_t
86. if
87. // NOTE: we could avoid the copy if we had strnstr.
88. const
89. // now look for this extension
90. if
91. // if we find it, add this extension string to our list
92. // (and don't forget the space)
93. const char* match = strstr(disp.queryString.extensions, ext.string());  
94. if (match && (match[len] == ' '
95.                         mExtensionString.append(start, len+1);  
96.                     }  
97.                 }  
98.             }  
99. // process the next extension string, and skip the space.
100.             start = end + 1;  
101.         }  
102. while
103.   
104. this); // 初始化egl_cache
105.   
106. char
107. "debug.egl.finish", value, "0");  
108. if
109. true;  
110.     }  
111.   
112. "debug.egl.traceGpuCompletion", value, "0");  
113. if
114. true;  
115.     }  
116.   
117.     refs++;  
118. if
119.         *major = VERSION_MAJOR;  
120. if
121.         *minor = VERSION_MINOR;  
122.   
123. true); // Hibernation相关
124.   
125. return
126. }

Hardware Composer初始化

Hardware Composer的构造函数如下:

1. HWComposer::HWComposer(  
2. const
3.         EventHandler& handler)  
4.     : mFlinger(flinger),  
5.       mFbDev(0), mHwc(0), mNumDisplays(1),  
6. new
7.       mEventHandler(handler),  
8. false)  
9. {  
10. for (size_t
11.         mLists[i] = 0;  
12.     }  
13.   
14. char
15. "debug.sf.no_hw_vsync", value, "0");  
16.     mDebugForceFakeVSync = atoi(value);  
17.   
18. bool needVSyncThread = true;  
19.   
20. // Note: some devices may insist that the FB HAL be opened before HWC.
21. // load gralloc HAL模块
22. // load hwcomposer HAL模块
23.   
24. if
25. // close FB HAL if we don't needed it.
26. // FIXME: this is temporary until we're not forced to open FB HAL
27. // before HWC.
28.         framebuffer_close(mFbDev);  
29.         mFbDev = NULL;  
30.     }  
31.   
32. // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
33. if
34.             && !mFbDev) {  
35. "ERROR: failed to open framebuffer, aborting");  
36.         abort();  
37.     }  
38.   
39. // these display IDs are always reserved
40. for (size_t
41.         mAllocatedDisplayIDs.markBit(i);  
42.     }  
43.   
44. if
45. "Using %s version %u.%u", HWC_HARDWARE_COMPOSER,  
46.               (hwcApiVersion(mHwc) >> 24) & 0xff,  
47.               (hwcApiVersion(mHwc) >> 16) & 0xff);  
48. if (mHwc->registerProcs) { // 有hardware composer的情形下,需要注册一些callback函数给它,来接受通知
49. this;  
50. // invalidate hook
51. // vsync hook
52. if
53. // hotplug hook
54. else
55.                 mCBContext->procs.hotplug = NULL;  
56. sizeof(mCBContext->procs.zero));  
57. // 真正注册
58.         }  
59.   
60. // don't need a vsync thread if we have a hardware composer
61. false; // 因为hardware composer存在,VSync由它来trigger,在SurfaceFlinger服务进程无需自己创建Vsync线程
62. // always turn vsync off when we start
63.         eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);  
64.   
65. // the number of displays we actually have depends on the
66. // hw composer version
67. if
68. // 1.2 adds support for virtual displays
69.             mNumDisplays = MAX_DISPLAYS;  
70. else if
71. // 1.1 adds support for multiple displays
72.             mNumDisplays = HWC_NUM_DISPLAY_TYPES;  
73. else
74.             mNumDisplays = 1;  
75.         }  
76.     }  
77. // 从gralloc模块获取一些显示输出相关信息
78. if
79.         ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),  
80. "should only have fbdev if no hwc or hwc is 1.0");  
81.   
82.         DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);  
83. true;  
84.         disp.width = mFbDev->width;  
85.         disp.height = mFbDev->height;  
86.         disp.format = mFbDev->format;  
87.         disp.xdpi = mFbDev->xdpi;  
88.         disp.ydpi = mFbDev->ydpi;  
89. if
90.             disp.refresh = nsecs_t(1e9 / mFbDev->fps);  
91. "getting VSYNC period from fb HAL: %lld", disp.refresh);  
92.         }  
93. if
94.             disp.refresh = nsecs_t(1e9 / 60.0);  
95. "getting VSYNC period from thin air: %lld",  
96.                     mDisplayData[HWC_DISPLAY_PRIMARY].refresh);  
97.         }  
98. else if
99. // here we're guaranteed to have at least HWC 1.1
100. for (size_t
101.             queryDisplayProperties(i);  
102.         }  
103.     }  
104.   
105. if (needVSyncThread) { // 如果Hardware composer不存在,则需要在SurfaceFlinger进程中创建VSync线程
106. // we don't have VSYNC support, we need to fake it
107. new VSyncThread(*this);  
108.     }  
109. }

SurfaceFlinger实现了HWComposer::EventHandler接口,所以最终的

VSync和Hotplug处理在SurfaceFlinger::onVSyncReceived()和SurfaceFlinger::onHotplugReceived()中。

选择EGLConfig并创建EGLContext

// initialize the config and context
     EGLint format = mHwc->getVisualID(); // 从hardware composer取到颜色空间
     mEGLConfig  = selectEGLConfig(mEGLDisplay, format); // 生成EGLConfig
     mEGLContext = createGLContext(mEGLDisplay, mEGLConfig); //生成EGLContext(通过调用egl库的eglCreateContext函数,然后封装成egl_context_t对象)

初始化各个DisplayDevice

1. // initialize our non-virtual displays
2. for (size_t
3.     DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);  
4. new
5.     wp<IBinder> token = mDefaultDisplays[i];  
6.   
7. // set-up the displays that are already connected
8. if
9. // All non-virtual displays are currently considered secure.
10. bool isSecure = true;  
11.         mCurrentState.displays.add(token, DisplayDeviceState(type));  
12. new
13. new
14. static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));  
15. new DisplayDevice(this,  
16.                 type, isSecure, token, stc, fbs, mEGLConfig);  
17. if
18. // FIXME: currently we don't get blank/unblank requests
19. // for displays other than the main display, so we always
20. // assume a connected display is unblanked.
21. "marking display %d as acquired/unblanked", i);  
22.             hw->acquireScreen();  
23.         }  
24.         mDisplays.add(token, hw);  
25.     }  
26. }

DisplayDevice封装了一个显示设备,组合了之前分析过的hardware composer, framebuffer surface, SurfaceTextureClient, EGLConfig.在SurfaceFlinger的合成和显示的每个点上都会遍历这个DisplayDevice集合。

初始化OpenGL ES并绑定到当前进程,初始化EGLDisplay

1. //  initialize OpenGL ES
2. DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);  
3. initializeGL(mEGLDisplay);

ReadyToRun终于运行完了,接下来便进入真正的threadloop:

1. bool
2. // 通过Looper等待事件
3. return true;  
4. }

创建Surface

Android中创建创建一个Activity时创建Surface的流程:

● Activity Thread calls on attach() and makeVisible()
 ● makeVisible does wm.addView()
 ● vm.addView() - this also called by StatusBar to display itself
 ● Creates a new ViewRootImpl
 ● Call on its setView()
 ● setView() calls on sWindowSession.add(...)
 ● This results in call to WM's addWindow()
 ● ViewRootImpl's performTraversals()
 ● Calls on relayoutWindow()
 ● Calls to WM session's relayout()
 ● Call to WM's relayoutWindow()
 ● Call to createSurfaceLocked()
 ● new Surface(...)  // Surface Object @java-layer

Surface构造函数调用了一个nativeCreate的native方法,其实现位于frameworks/base/core/jni/android_view_Surface.cpp:

1. static void
2.         jstring nameStr, jint w, jint h, jint format, jint flags) {  
3.     ScopedUtfChars name(env, nameStr);  
4.     sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));  
5.   
6.     sp<SurfaceControl> surface = client->createSurface(  
7.             String8(name.c_str()), w, h, format, flags);  
8. if
9.         jniThrowException(env, OutOfResourcesException, NULL);  
10. return;  
11.     }  
12.   
13.     setSurfaceControl(env, surfaceObj, surface);  
14. }

与此类似,接下来粘贴一段Native层创建Surface的Sample代码:

    1. new
    2.         ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());  
    3.   
    4.         sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(  
    5.                 ISurfaceComposer::eDisplayIdMain));  
    6.         DisplayInfo info;  
    7. // 获取显示参数
    8.   
    9.         ssize_t displayWidth = info.w;  
    10.         ssize_t displayHeight = info.h;  
    11.   
    12. // Background surface
    13. // 创建Surface,后文将详细分析其squence
    14. "BG Test Surface"), displayWidth, displayHeight,  
    15.                 PIXEL_FORMAT_RGBA_8888, 0);  
    16.         ASSERT_TRUE(mBGSurfaceControl != NULL);  
    17.         ASSERT_TRUE(mBGSurfaceControl->isValid());  
    18.         fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);   
    19.   
    20. // Fill an RGBA_8888 formatted surface with a single color.
    21. static void fillSurfaceRGBA8(const
    22.         uint8_t r, uint8_t g, uint8_t b) {  
    23.     Surface::SurfaceInfo info;  
    24.     sp<Surface> s = sc->getSurface();  
    25.     ASSERT_TRUE(s != NULL);  
    26.     ASSERT_EQ(NO_ERROR, s->lock(&info));  
    27. reinterpret_cast<uint8_t*>(info.bits);  
    28. for
    29. for
    30.             uint8_t* pixel = img + (4 * (y*info.s + x));  
    31.             pixel[0] = r;  
    32.             pixel[1] = g;  
    33.             pixel[2] = b;  
    34.             pixel[3] = 255;  
    35.         }  
    36.     }  
    37.     ASSERT_EQ(NO_ERROR, s->unlockAndPost());  
    38. }

    其中CreateSurface过程的时序图如下:

    android surface的数据显示 android window surface_EGL_02

    queueBuffer的过程时序图如下:

    android surface的数据显示 android window surface_EGL_03

    VSync的时序图:


    android surface的数据显示 android window surface_主线程_04

    在dequeue了新的GraphicBuffer之后,SurfaceFlinger就需要对它管理的layer进行合成。合成的过程主要包含了以下几个重要的步骤:
    handleMessageTransaction:处理系统显示屏以及应用程序窗口的属性变化。并把SurfaceFlinger::mDrawingStat更新为SurfaceFlinger::mCurrentState,新创建的layer(surface)都是保存在mCurrentState中的。
    handlePageFlip:更新每个layer的active buffer。
    rebuildLayerStacks:为每个DisplayDevice设置可见、按Z-order排序的layers
    setUpHWComposer:根据在step3设置的SurfaceFlinger的DisplayDevice中的active layers来设置HWComposer的DisplayData数据,然后调用hwc模块的prepare函数
    doComposition:使用OpenGL ES或者hwc模块来合成

    在合成完后,就需要推送到屏幕上显示。有3个重要的类用来管理显示设备:

    DisplayDevice
    FramebufferSurface
    SurfaceTextureClient

    Android系统支持多个显示设备,每一个显示设备在SurfaceFlinger进程中都有一个DisplayDevice对象来管理它。

    FramebufferSurface继承于ConsumerBase,当其连接的BufferQueue有新帧时,其onFrameAvailable方法会被调用,来处理这个新帧。

    SurfaceTextureClient继承于ANativeWindow,在SurfaceFlinger进程中,它引用了FramebufferSurface的BufferQueue;同时又因为它是一个ANativeWindow,它被EGL封装为EGLSurface保存在DisplayDevice 中,用来显示改设备的新帧。

    DisplayDevice的初始化过程在SurfaceFlinger::readyToRun()里实现。

    下面重点介绍两种不同情况下的显示流程:

    在没有 hwc 模块时的显示流程

    在有 hwc 模块并且使用 hwc 模块来进行合成的显示流程

    没有HWC模块时:

    android surface的数据显示 android window surface_EGL_05


    有HWC模块时:

    android surface的数据显示 android window surface_初始化_06