GUI系统之SurfaceFlinger(3)Android中的本地窗口FramebufferNativewindow

本文深入探讨了Android系统中的本地窗口,尤其是FramebufferNativeWindow。文章介绍了Android为何需要两种本地窗口,分别是面向管理者(SurfaceFlinger)的FramebufferNativeWindow和面向应用程序的SurfaceTextureClient。通过分析源码,揭示了EGL创建窗口Surface的过程,并详细解释了ANativeWindow的结构和作用,以及FramebufferNativeWindow如何履行这份“协议”。文章还阐述了双缓冲技术在提高用户体验中的关键作用,并展示了如何通过dequeueBuffer分配渲染缓冲区。
摘要由CSDN通过智能技术生成

文章都是通过阅读源码分析出来的,还在不断完善与改进中,其中难免有些地方理解得不对,欢迎大家批评指正
转载请注明:From LXS. http://blog.csdn.net/uiop78uiop78/



1.1 Android中的本地窗口

在OpenGL的学习过程中,我们不断提及“本地窗口”(NativeWindow)这一概念。那么对于Android系统来说,它是如何将OpenGL ES本地化的呢,或者说,它提供了什么样的本地窗口?

根据整个Android系统的GUI设计理念,我们不难猜想到至少需要两种本地窗口:

Ø  面向管理者(SurfaceFlinger)

既然SurfaceFlinger扮演了系统中所有UI界面的管理者,那么它无可厚非地需要直接或间接地持有“本地窗口”。从前一小节我们已经知道,这个窗口就是FramebufferNativeWindow

Ø  面向应用程序

我们先给出答案,这类窗口是SurfaceTextureClient

 

有不少读者可能会觉得困惑,为什么需要两种窗口,同一个系统不是应该只有一种窗口吗?比如这样子:

 


图 11‑4理想的窗口系统

 

这个图中,由Window来管理Framebuffer。我们打个比方来说,OpenGL就像是一台通用的打印机一样,只要输入正确的指令,它就能按照要求输出结果;而Window则是“纸”,它是用来承载OpenGL的输出结果的。OpenGL并不介意Window是A4纸或者是A6,甚至是塑料纸也没有关系,对它来说都只是“本地窗口”。

理解了这个图后,我们再来思考下,这样的模型是否能符合Android的要求?假如整个系统仅有一个需要显示UI的程序,我们有理由相信它是可以胜任的。但是如果有N个UI程序的情况呢?Framebuffer显然只有一个,不可能让各个应用程序自己单独管理。

这样子问题就来了,该如何改进呢?下面这个方法如何?

 


图 11‑5 改进的窗口系统

 

在这个改进的窗口系统中,我们有了两类本地窗口,即Window-1和Window-2。第一种窗口是能直接显示在终端屏幕上的——它使用了帧缓冲区,而后一种Window实际上是从内存缓冲区分配的空间。当系统中存在多个应用程序时,这能保证它们都可以获得一个“本地窗口”,并且这些窗口最终也能显示到屏幕上——SurfaceFlinger会收集所有程序的显示需求,对它们做统一的图像混合操作(有点类似于AudioFlinger),然后输出到自己的Window-1上。

当然,这个改进的窗口系统有一个前提,即应用程序与SurfaceFlinger都是基于OpenGL ES来实现的。有没有其它选择呢?答案是肯定的,比如应用程序端完全可以采用Skia等第三方的图形库,只要保持它们与SurfaceFlinger间的“协议”不变就可以了,如下所示:


图 11‑6 另一种改进的窗口系统

 

理论上来说,采用哪一种方式都是可行的。不过对于开发人员,特别是没有OpenGLES项目经验的人而言,前一种系统的门槛相对较高。事实上,Android系统同时提供了这两种实现来供上层选择。正常情况下我们按照SDK向导生成的apk应用,就属于后面的情况;而对于希望使用OpenGLES来完成复杂的界面渲染的应用开发者,也可以使用GLSurfaceView来达到目标。

在接下来的源码分析中,我们将对上面所提出的假设做进一步验证。

1.1.1 FramebufferNativeWindow

 

先把EGL创建一个Window Surface的函数原型列出如下:

EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,

                          NativeWindowType  window, const EGLint *attrib_list);

显然不论是哪一种本地窗口,它都必须要与NativeWindowType保持一致,否则就无法正常使用EGL了。先从数据类型的定义来看下这个window参数有什么特别之处:

/*frameworks/native/opengl/include/egl/Eglplatform.h*/

typedef  EGLNativeWindowType  NativeWindowType;//注意这两种类型其实是一样的

#if defined(_WIN32) || defined(__VC32__) &&!defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)

                /* Win32 和WinCE系统下的定义 */

    …

    typedef  HWND    EGLNativeWindowType;

#elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian系统*/

    …

     t

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值