Android 深入系统完全讲解(22)
Posted 程序员入门进阶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 深入系统完全讲解(22)相关的知识,希望对你有一定的参考价值。
SurfaceFlinger 和 WindowManager
SurfaceFlinger 接受缓冲区,对它们进行合成,然后发送到屏幕。WindowManager 为
SurfaceFlinger 提供缓冲区和窗口元数据,而 SurfaceFlinger 可使用这些信息将 Surface 合
成到屏幕。
SurfaceFlinger 可通过两种方式接受缓冲区:通过 BufferQueue 和 SurfaceControl,或通过
ASurfaceControl。
SurfaceFlinger 接受缓冲区的一种方式是通过 BufferQueue 和 SurfaceControl。当应用进入前
台时,它会从 WindowManager 请求缓冲区。然后,WindowManager 会从 SurfaceFlinger 请
求层。层是 surface(包含 BufferQueue)和 SurfaceControl(包含显示框架等层元数据)的
组合。SurfaceFlinger 创建层并将其发送至 WindowManager。然后,WindowManager 将
Surface 发送至应用,但会保留 SurfaceControl 来操控应用在屏幕上的外观。
android 10 新增了 ASurfaceControl,这是 SurfaceFlinger 接受缓冲区的另一种方式。
ASurfaceControl 将 Surface 和 SurfaceControl 组合到一个事务包中,该包会被发送至
SurfaceFlinger。ASurfaceControl 与层相关联,应用可通过 ASurfaceTransactions 更新该层。
然 后 , 应 用 可 通 过 回 调 ( 用 于 传 递 包 含 锁 定 时 间 、 获 取 时 间 等 信 息 的
ASurfaceTransactionStats)获取有关 ASurfaceTransactions 的信息。
在屏幕处于两次刷新之间时,屏幕会向 SurfaceFlinger 发送 VSYNC 信号。VSYNC 信号表明
可对屏幕进行刷新而不会产生撕裂。当 SurfaceFlinger 接收到 VSYNC 信号后,SurfaceFlinger
会遍历其层列表,以查找新的缓冲区。如果 SurfaceFlinger 找到新的缓冲区,SurfaceFlinger 会
获取缓冲区;否则,SurfaceFlinger 会继续使用上一次获取的那个缓冲区。SurfaceFlinger 必
须始终显示内容,因此它会保留一个缓冲区。如果在某个层上没有提交缓冲区,该层会被忽
略。
SurfaceFlinger 在收集可见层的所有缓冲区之后,便会询问硬件混合渲染器 (HWC) 应如何进
行合成。如果 HWC 将层合成类型标记为客户端合成,则 SurfaceFlinger 将合成这些层。然
后,SurfaceFlinger 会将输出缓冲区传递给 HWC。
WindowManager 会控制窗口对象,它们是用于容纳视图对象的容器。窗口对象始终由
Surface 对象提供支持。WindowManager 会监督生命周期、输入和聚焦事件、屏幕方向、
转换、动画、位置、变形、Z 轴顺序以及窗口的许多其他方面。WindowManager 会将所有
窗口元数据发送到 SurfaceFlinger,以便 SurfaceFlinger 可以使用这些数据在屏幕上合成
Surface。
这段文字,完成了整个的绘制讲解。
下面我们再看一个 GLSurfaceView,就会进入到音视频的相关学习。
GLSurfaceView 这个我们直接看源码,当我们在学习某一个类的时候,一定不要忽略的就是
前面的注释,这块会完整的讲解,关于这个类的一切。
然后讲了特性:代码位置
http://androidxref.cn/android-11.0.0_r21/xref/frameworks/base/opengl/java/android/opengl/GL
SurfaceView.java
43 *
44 * A GLSurfaceView provides the following features:
45 *
46 *
47 *- Manages a surface, which is a special piece of memory that can be
48 * composited into the Android view system. 49 * - Manages an EGL display, which enables OpenGL to render into a surface. 50 *
- Accepts a user-provided Renderer object that does the actual rendering. 51 *
- Renders on a dedicated thread to decouple rendering performance from the
52 * UI thread. 53 * - Supports both on-demand and continuous rendering. 54 *
- Optionally wraps, traces, and/or error-checks the renderer’s OpenGL calls. 55 *
56 * 57 *
58 *
Developer Guides
59 *
For more information about how to use OpenGL, read the
60 * OpenGL developer
guide.
61 *
这里指向的是 doc 目录的相关文件,指导大家使用,同时这个文件也给出了使用方式。这里
就写得很明确,也很详细。
-
Using GLSurfaceView
64 *
65 * Typically you use GLSurfaceView by subclassing it and overriding one or more of the
66 * View system input event methods. If your application does not need to override event
67 * methods then GLSurfaceView can be used as-is. For the most part
68 * GLSurfaceView behavior is customized by calling “set” methods rather than by
subclassing. 69 * For example, unlike a regular View, drawing is delegated to a separate Renderer object
which
70 * is registered with the GLSurfaceView
71 * using the @link #setRenderer(Renderer) call. 72 *
73 *
Initializing GLSurfaceView
74 * All you have to do to initialize a GLSurfaceView is call @link #setRenderer(Renderer). 75 * However, if desired, you can modify the default behavior of GLSurfaceView by calling one
or
76 * more of these methods before calling setRenderer:
77 *
78 *- @link #setDebugFlags(int)
79 * - @link #setEGLConfigChooser(boolean)
80 * - @link #setEGLConfigChooser(EGLConfigChooser)
81 * - @link #setEGLConfigChooser(int, int, int, int, int, int)
82 * - @link #setGLWrapper(GLWrapper)
83 *
85 *
Specifying the android.view.Surface
86 * By default GLSurfaceView will create a PixelFormat.RGB_888 format surface. If a
translucent
87 * surface is required, call getHolder().setFormat(PixelFormat.TRANSLUCENT). 88 * The exact format of a TRANSLUCENT surface is device dependent, but it will be
89 * a 32-bit-per-pixel surface with 8 bits per component. 90 *
91 *
Choosing an EGL Configuration
92 * A given Android device may support multiple EGLConfig rendering configurations. 93 * The available configurations may differ in how many channels of data are present, as
94 * well as how many bits are allocated to each channel. Therefore, the first thing
95 * GLSurfaceView has to do when starting to render is choose what EGLConfig to use. 96 *
97 * By default GLSurfaceView chooses a EGLConfig that has an RGB_888 pixel format, 98 * with at least a 16-bit depth buffer and no stencil. 99 *
100 * If you would prefer a different EGLConfig
101 * you can override the default behavior by calling one of the
102 * setEGLConfigChooser methods. 103 *
104 *
Debug Behavior
105 * You can optionally modify the behavior of GLSurfaceView by calling
106 * one or more of the debugging methods @link #setDebugFlags(int), 107 * and @link #setGLWrapper. These methods may be called before and/or after
setRenderer, but
108 * typically they are called before setRenderer so that they take effect immediately. 109 *
110 *
Setting a Renderer
111 * Finally, you must call @link #setRenderer to register a @link Renderer. 112 * The renderer is
113 * responsible for doing the actual OpenGL rendering. 114 *
115 *
Rendering Mode
116 * Once the renderer is set, you can control whether the renderer draws
117 * continuously or on-demand by calling
118 * @link #setRenderMode. The default is continuous rendering. 119 *
120 *
Activity Life-cycle
121 * A GLSurfaceView must be notified when to pause and resume rendering. GLSurfaceView
clients
122 * are required to call @link #onPause() when the activity stops and
123 * @link #onResume() when the activity starts. These calls allow GLSurfaceView to124 * pause and resume the rendering thread, and also allow GLSurfaceView to release and
recreate
125 * the OpenGL display. 126 *
127 *
Handling events
128 *
129 * To handle an event you will typically subclass GLSurfaceView and override the
130 * appropriate method, just as you would with any other View. However, when handling
131 * the event, you may need to communicate with the Renderer object
132 * that’s running in the rendering thread. You can do this using any
133 * standard Java cross-thread communication mechanism. In addition, 134 * one relatively easy way to communicate with your renderer is
135 * to call
136 * @link #queueEvent(Runnable). For example:
137 *
138 * class MyGLSurfaceView extends GLSurfaceView
139 * 140 * private MyRenderer mMyRenderer;
141 * 142 * public void start()
143 * mMyRenderer = …;
144 * setRenderer(mMyRenderer);
145 *
146 * 147 * public boolean onKeyDown(int keyCode, KeyEvent event)
148 * if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
149 * queueEvent(new Runnable()
150 * // This method will be called on the rendering
151 * // thread:
152 * public void run()
153 * mMyRenderer.handleDpadCenter();
154 * );
155 * return true;
156 *
157 * return super.onKeyDown(keyCode, event);
158 *
159 *
160 *
161 * 162 */
我们来看段示例代码:像市面的 LibGDX 游戏引擎,cocos2dx 引擎,都是使用的 GLSurfaceView 作为桥梁,完成跟安
卓的对接。
在说到这里,我们讲解下 OpenGL 和 OpenGLES:
以上是关于Android 深入系统完全讲解(22)的主要内容,如果未能解决你的问题,请参考以下文章