资源描述
Android显示系统设计框架介绍
[-]
1. 本地窗口
1. 应用程序本地窗口
2. SurfaceFlinger本地窗口
2. Gralloc
1. gpu设备
2. fb设备
3. SurfaceSession建立过程
1. 客户端请求
2. 服务端处理
4. Surface创建过程
1. 客户端请求
2. 服务端处理
1. Layer构造过程
2. BufferQueue构造过程
3. GraphicBufferAlloc构造过程
4. SurfaceTexture构造过程
5. ISurface本地对象创建过程
5. 应用程序本地窗口Surface创建过程
6. Surface的图形buffer申请过程
1. 客户端请求
2. 服务端处理
7. 图形缓冲区创建过程
8. 应用程序获取图形buffer首地址
1. 客户端请求
2. 服务端处理
9. 应用程序释放图形buffer过程
1. 客户端请求
2. 服务端处理
1. Linux内核提供了统一的framebuffer显示驱动,设备节点/dev/graphics/fb*或者/dev/fb*,以fb0表示第一个显示屏,当前实现中只用到了一个显示屏。
2. Android的HAL层提供了Gralloc,分为fb和gralloc两个设备。设备fb负责打开内核中的framebuffer以及提供post、setSwapInterval等操作,设备gralloc则负责管理帧缓冲区的分配和释放。上层只能通过Gralloc访问帧缓冲区,这样一来就实现了有序的封装保护。
3. 由于OpenGL ES是一个通用的函数库,在不同的平台系统上需要被“本地化”——即把它与具体平台上的窗口系统建立起关联,这样才能保证它正常工作。从FramebufferNativeWindow就是将OpenGL ES在Android平台上本地化窗口。
4. OpenGL或者OpenGL ES 更多的只是一个接口协议,实现上既可以采用软件,也能依托于硬件。EGL通过读取egl.cfg配置文件,根据用户的设定来动态加载libagl(软件实现)或者libhgl(硬件实现)。然后上层才可以正常使用各种glXXX接口。
5. SurfaceFlinger中持有一个GraphicPlane成员变量mGraphicPlanes来描述“显示屏”;GraphicPlane类中又包含了一个DisplayHardware对象实例(mHw)。DisplayHardware在初始化时还将调用eglInitialize、eglCreateWindowSurface等接口,并利用EGL完成对OpenGLES环境的搭建。
本地窗口
Android提供了两种本地窗口:
1) 面向SurfaceFlinger的FramebufferNativeWindow;
2) 面向应用程序的SurfaceTextureClient;
使用OpenGL绘制图像前,需要通过EGL创建一个Surface画板:
frameworks\native\opengl\libagl\ Egl.cpp
[cpp] view plaincopy
1. EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
2. NativeWindowType window,
3. const EGLint *attrib_list)
4. {
5. return createWindowSurface(dpy, config, window, attrib_list);
6. }
OpenGL是跨平台的图形库,不同平台上的NativeWindowType窗口类型有不同的定义:
frameworks\native\opengl\include\egl\ Eglplatform.h
[cpp] view plaincopy
1. typedef EGLNativeWindowType NativeWindowType;
2.
3. #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
4. #ifndef WIN32_LEAN_AND_MEAN
5. #define WIN32_LEAN_AND_MEAN 1
6. #endif
7. #include <windows.h>
8.
9. typedef HDC EGLNativeDisplayType;
10. typedef HBITMAP EGLNativePixmapType;
11. typedef HWND EGLNativeWindowType;
12.
13. #elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
14.
15. typedef int EGLNativeDisplayType;
16. typedef void *EGLNativeWindowType;
17. typedef void *EGLNativePixmapType;
18.
19. #elif defined(__ANDROID__) || defined(ANDROID)
20.
21. struct ANativeWindow;
22. struct egl_native_pixmap_t;
23.
24. typedef struct ANativeWindow* EGLNativeWindowType;
25. typedef struct egl_native_pixmap_t* EGLNativePixmapType;
26. typedef void* EGLNativeDisplayType;
27.
28. #elif defined(__unix__)
29.
30. /* X11 (tentative) */
31. #include <X11/Xlib.h>
32. #include <X11/Xutil.h>
33.
34. typedef Display *EGLNativeDisplayType;
35. typedef Pixmap EGLNativePixmapType;
36. typedef Window EGLNativeWindowType;
37.
38. #else
39. #error "Platform not recognized"
40. #endif
可以看出对于Android平台,NativeWindowType的类型为ANativeWindow
[cpp] view plaincopy
1. struct ANativeWindow
2. {
3. #ifdef __cplusplus //C++定义
4. ANativeWindow(): flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
5. {
6. common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
7. common.version = sizeof(ANativeWindow);
8. memset(common.reserved, 0, sizeof(common.reserved));
9. }
10. /* Implement the methods that sp<ANativeWindow> expects so that it
11. can be used to automatically refcount ANativeWindow's. */
12. void incStrong(const void* id) const {
13. common.incRef(const_cast<android_native_base_t*>(&common));
14. }
15. void decStrong(const void* id) const {
16. common.decRef(const_cast<android_native_base_t*>(&common));
17. }
18. #endif
19. struct android_native_base_t common;
20. /* flags describing some attributes of this surface or its updater */
21. const uint32_t flags;
22. /* min swap interval supported by this updated */
23. const int minSwapInterval;
24. /* max swap interval supported by this updated */
25. const int maxSwapInterval;
26. /* horizontal and vertical resolution in DPI */
27. const float xdpi;
28. const float ydpi;
29. /* Some storage reserved for the OEM's driver. */
30. intptr_t oem[4];
31. /* Set the swap interval for this surface. */
32. int (*setSwapInterval)(struct ANativeWindow* window,
33. int interval);
34. /*
35. * Hook called by EGL to acquire a buffer. After this call, the buffer
36. * is not locked, so its content cannot be modified. This call may block if
37. * no buffers are available.
38. */
39. int (*dequeueBuffer)(struct ANativeWindow* window,
40. struct ANativeWindowBuffer** buffer);
41. /*
42. * hook called by EGL to lock a buffer. This MUST be called before modifying
43. * the content of a buffer. The buffer must have been acquired with
44. * dequeueBuffer first.
45. */
46. int (*lockBuffer)(struct ANativeWindow* window,
47. struct ANativeWindowBuffer* buffer);
48. /*
49. * Hook called by EGL when modifications to the render buffer are done.
50. * This unlocks and post the buffer.
51. */
52. int (*queueBuffer)(struct ANativeWindow* window,
53. struct ANativeWindowBuffer* buffer);
54. /*
55. * hook used to retrieve information about the native window.
56. */
57. int (*query)(const struct ANativeWindow* window,
58. int what, int* value);
59. /*
60. * hook used to perform various operations on the surface.
61. * (*perform)() is a generic mechanism to add functionality to
62. * ANativeWindow while keeping backward binary compatibility.
63. * The valid operations are:
64. * NATIVE_WINDOW_SET_USAGE
65. * NATIVE_WINDOW_CONNECT (deprecated)
66. * NATIVE_WINDOW_DISCONNECT (deprecated)
67. * NATIVE_WINDOW_SET_CROP (private)
68. * NATIVE_WINDOW_SET_BUFFER_COUNT
69. * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY (deprecated)
70. * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
71. * NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
72. * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS
73. * NATIVE_WINDOW_SET_BUFFERS_FORMAT
74. * NATIVE_WINDOW_SET_SCALING_MODE (private)
75. * NATIVE_WINDOW_LOCK (private)
76. * NATIVE_WINDOW_UNLOCK_AND_POST (private)
77. * NATIVE_WINDOW_API_CONNECT (private)
78. * NATIVE_WINDOW_API_DISCONNECT (private)
79. * NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS (private)
80. * NATIVE_WINDOW_SET_POST_TRANSFORM_CROP (private)
81. *
82. */
83. int (*perform)(struct ANativeWindow* window,
84. int operation, ... );
85. /*
86. * Hook used to cancel a buffer that has been dequeued.
87. * No synchronization is performed between dequeue() and cancel(), so
88. * either external synchronization is needed, or these functions must be
89. * called from the same thread.
90. */
91. int (*cancelBuffer)(struct ANativeWindow* window,
92. struct ANativeWindowBuffer* buffer);
93. void* reserved_proc[2];
94. };
无论是基于应用程序的本地窗口SurfaceTextureClient还是基于SurfaceFlinger的FramebufferNativeWindow本地窗口,都必须实现ANativeWindow定义的一套窗口协议,这样应用程序和SurfaceFlinger才能使用OpenGL。ANativeWindow就相当于Java中的接口类型,只是用于定义窗口的功能函数,并不去实现这些函数,而是由需要使用OpenGL的对象来实现。
应用程序本地窗口
应用程序端的SurfaceTextureClient实现了ANativeWindow类型中定义的函数,这样应用程序就可以使用OpenGL来绘制图形图像了,当然应用程序可以选择性地使用OpenGL或是Skia。
SurfaceFlinger本地窗口
由于SurfaceFlinger必须要使用OpenGL来混合图像,因此SurfaceFlinger端的FramebufferNativeWindow必须实现ANativeWindow类型。
Gralloc
通过加载gralloc抽象层,可以打开fb设备和gpu设备,fb设备用于操作framebuffer,gpu设备负责图形缓冲区的分配和释放。对于SurfaceFlinger服务端的本地窗口FramebufferNativeWindow将分别打开fb设备和gpu设备,FramebufferNativeWindow通过gpu设备从Framebuffer中分配图形缓冲区,通过fb设备来渲染经SurfaceFlinger混合后的图像。而对于应用程序端的SurfaceTextureClient本地窗口,其需要的图形缓冲区也是由SurfaceFlinger服务端来分配,应用程序进程只需要将服务端分配的图形缓冲区映射到应用程序的虚拟地址空间,图形缓冲区的映射过程也是由Gralloc模块完成。Android图形显示之硬件抽象层Gralloc对Gralloc模块进行了详细介绍,这里只简单带过。
gpu、fb和gralloc模块中定义的数据结构关系如下:
通过加载Gralloc动态库,可以分别打开fb设备和gpu设备。
gpu设备
Gpu打开过程就是创建并初始化一个gralloc_context_t对象,gpu负责图形buffer的分配和释放。
[cpp] view plaincopy
1. int gralloc_device_open(const hw_module_t* module, const char* name,
2. hw_device_t** device)
3. {
4. int status = -EINVAL;
5. if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
6. gralloc_context_t *dev;
7. dev = (gralloc_context_t*)malloc(sizeof(*dev));
8.
9. /* initialize our state here */
10. memset(dev, 0, sizeof(*dev));
11.
12. /* initialize the procs */
13. dev->mon.tag = HARDWARE_DEVICE_TAG;
14. dev->mon.version = 0;
15. dev->mon.module = const_cast<hw_module_t*>(module);
16. dev->mon.close = gralloc_close;
17.
18. dev->device.alloc = gralloc_alloc;
19. dev->device.free = gralloc_free;
20.
21. *device = &dev->mon;
22. status = 0;
23. return status;
24. }
fb设备
Fb设备打开过程就是创建并初始化一个fb_context_t对象,关于屏幕大小、格式、刷新频率等信息都是通过Framebuffer驱动来获取,最后将Framebuffer映射到SurfaceFlinger进程地址空间,并将映射后的首地址保持到private_module_t的framebuffer->base变量中。
[cpp] view plaincopy
1. int fb_device_open(hw_module_t const* module, const char* name,
2. hw_device_t** device)
3. {
4. int status = -EINVAL;
5. if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
6. alloc_device_t* gralloc_device;
7. status = gralloc_open(module, &gralloc_device);
8. if (status < 0)
9. return status;
10.
11. /* initialize our state here */
12. fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
13. memset(dev, 0, sizeof(*dev));
14.
15. /* initialize the procs */
16. dev->mon.tag = HARDWARE_DEVICE_TAG;
17. dev->mon.version = 0;
18. dev->mon.module = const_cast<hw_module_t*>(module);
19. dev->mon.close = fb_close;
20. dev->device.setSwapInterval = fb_setSwapInterval;
21. dev->device.post = fb_post;
22. dev->device.setUpdateRect = 0;
23.
24. private_module_t* m = (private_module_t*)module;
25. status = mapFrameBuffer(m);
26. if (status >= 0) {
27. int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
28. int format = (m->info.bits_per_pixel == 32)
29. ? HAL_PIXEL_FORMAT_RGBX_8888
30. : HAL_PIXEL_FORMAT_RGB_565;
31. const_cast<uint32_t&>(dev->device.flags) = 0;
32. const_cast<uint32_t&>(dev->device.width) = m->info.xres;
33. const_cast<uint32_t&>(dev->device.height) = m->info.yres;
34. const_cast<int&>(dev->device.stride) = stride;
35. const_cast<int&>(dev->device.format) = format;
36. const_cast<float&>(dev->device.xdpi) = m->xdpi;
37. const_cast<float&>(dev->device.ydpi) = m->ydpi;
38. const_cast<float&>(dev->device.fps) = m->fps;
39. const_cast<int&>(dev->device.minSwapInterval) = 1;
40. const_cast<int&>(dev->device.maxSwapInterval) = 1;
41. *device = &dev->mon;
42. }
43. }
44. return status;
45. }
为了方便应用程序及SurfaceFlinger使用Gralloc模块中的fb设备和gpu设备,Android对gpu设备进行了封装。我们知道,SurfaceFlinger不仅负责FramebufferNativeWindow本地窗口的图形buffer的分配,同时也负责应用程序本地窗口SurfaceTextureClient的图形buffer分配,应用程序只需将服务端分配的图形buffer映射到当前进程的虚拟地址空间即可,因此应用程序和SurfaceFlinger都将会使用到Gralloc模块。
SurfaceSession建立过程
SurfaceSession对象承担了应用程序与SurfaceFlinger之间的通信过程,每一个需要与SurfaceFlinger进程交互的应用程序端都需要创建一个SurfaceSession对象。
客户端请求
frameworks\base\core\java\android\view\SurfaceSession.java
[cpp] view plaincopy
1. public SurfaceSession() {
2. init();
3. }
Java层的SurfaceSession对象构造过程会通过JNI在native层创建一个SurfaceComposerClient对象。
frameworks\base\core\jni\android_view_Surface.cpp
[cpp] view plaincopy
1. static void SurfaceSession_init(JNIEnv* env, jobject clazz)
2. {
3. sp<SurfaceComposerClient> client = new SurfaceComposerClient;
4. client->incStrong(clazz);
5. env->SetIntField(clazz, sso.client, (int)client.get());
6. }
Java层的SurfaceSession对象与C++层的SurfaceComposerClient对象之间是一对一关系。
frameworks\native\libs\gui\SurfaceComposerClient.cpp
[cpp] view plaincopy
1. SurfaceComposerClient::SurfaceComposerClient()
2. : mStatus(NO_INIT), mComposer(Composer::getInstance())
3. {
4. }
SurfaceComposerClient继承于RefBase类,当第一次被强引用时,onFirstRef函数被回调,在该函数中SurfaceComposerClient会请求SurfaceFlinger为当前应用程序创建一个Client对象,专门接收该应用程序的请求,在SurfaceFlinger端创建好Client本地Binder对象后,将该Binder代理对象返回给应用程序端,并保存在SurfaceComposerClient的成员变量mClient中。
[cpp] view plaincopy
1. void SurfaceComposerClient::onFirstRef() {
2. //得到SurfaceFlinger的代理对象BpSurfaceComposer
3. sp<ISurfaceComposer> sm(getComposerService());
4. if (sm != 0) {
5. sp<ISurfaceComposerClient> conn = sm->createConnection();
6. if (conn != 0) {
7. mClient = conn;
8. mStatus = NO_ERROR;
9. }
10. }
11. }
服务端处理
在SurfaceFlinger服务端为应用程序创建交互的Client对象
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
[cpp] view plaincopy
1. sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
2. {
3. sp<ISurfaceComposerClient> bclient;
4. sp<Client> client(new Client(this));
5. status_t err = client->initCheck();
6. if (err == NO_ERROR) {
7. bclient = client;
8. }
9. return bclient;
10. }
关于SurfaceFlinger服务代理对象获取的详细过程请查看Android SurfaceFlinger服务代理对象获取过程源码分析。
Surface创建过程
客户端请求
frameworks\base\core\java\android\view\Surface.java
[java] view plaincopy
1. public Surface(SurfaceSession s,int pid, String name, int display, int w, int h, int format, int flags)
2. throws OutOfResourcesException {
3. checkHeadless();
4. if (DEBUG_RELEASE) {
5. mCreationStack = new
展开阅读全文