0%

Android下OpenGL环境的创建

上一篇文章中我向你详细介了从Camera采集的视频帧是如何一步步在Android系统内部通过其显示系统展示出来的,那么今天我们再来聊聊在Android系统下该如何创建OpenGL环境。

OpenGL工作原理

在我们开始之前,咱们先来看一张图,这张图就是Android系统下OpenGL的工作原理图。

咱们首先看一下这张图中都包括也哪些组件,我们按从左到右的顺序一一讲解。

  • Surfaceview,它是View的子类,它自己会管理一个单独的Surface,因此这种类型的View更具有灵活性,尤其可以实现窗口浮动的功能。

  • GLSurfaceview,是Surfaceview的子类。我们使用OpenGL对视频、图像渲染时,一般不直接使用Surfaceview。其原因是,Surfaceview虽然灵活但其内部并没有自动构造OpenGL环境,而开发者自己实现这部分代码还是挺麻烦的,尤其是很多同学对Android的显示系统并不清楚,这种情况下很容易掉入各种“坑”里。而GLSurfaceview则为我们解决了这个问题,在其内部,会自己启动一个新的渲染线程,并在这个渲染线程中构造OpenGL环境,这样就大大减轻了开发者的负担。

  • Surface我们应该都非常清楚了,它是一个视频帧缓况区队列的管理者,用于在不同的进程之间传递视频帧或图像。每当我们创建一个Surfaceview或GLSurfaceview对象时,在其内部就会自动创建一个Surface。

  • EGL,它是OpenGLES的上下文,在我们使用OpenGL之前首先要先创建这个上下文。在创建EGL时,它会做以下几件事儿:

    • 动态加载OpenGL库
    • 初始化OpenGL库,并获得其版本
    • 设置配置参数
    • 创建EGLSurface,并将它与Surfaceview中的Surface进行绑定
  • EGLSurface,它是OpenGL的输出缓冲区,当我们使用OpenGL渲染视频、图像时,会将结果输出到EGLSurface中。其实你也可以认为它是Surfaceview中Surface的外外壳,最终经过OpenGL渲染的数据会交由Surface管理。此时,OpenGL就与Surfaceview或GLSurfaceview建立好了连接。

  • OpenGLES,指是就是OpenGL库,当EGL创建好后,我们就可以使用OpenGL API调用Shader程序了。

  • GPU,它是图形处理器,大家对它应该不陌生,主要用于图形处理和并行计算。OpenGL库就是一种可以访问和控制GPU的接口。我们可以通过OpenGL API 向GPU传送数据,发送指令以及从GPU中获取计算的结果。

  • SurfaceFlinger,它是Android系统的显示服务。当我们通过OpenGL让GPU对图像处理后,会将结果保存到EGLSurface中。而SurfaceFlinger则会为每个View中的Surface创建一个Layer,并让Layer成为Surface的消费者,从Surface中读取数据交由SurfaceFlinger时行合成。

  • Screen,它表示的是显示器,上面SurfaceFline通过Hardware(GPU)合成图层工作后,就会将最终的结果输出给Screen显示出来。

至此上述图片中的每个组件我都向你介绍清楚了。

OpenGL高效渲染的过程

那么大家比较关心的一个问题来了,OpenGL是如何高效渲染视频、图像的呢?

我们还是以从Camera采集到一帧数据,然后经过OpenGL渲染显示出来这个过程为例,看看为什么OpenGL可以高效渲染视频、图像的吧。

当Camera采集到视频帧后,它会在Camera硬件的空间中分配一块缓冲区来存放采集到的视频帧(注意这块缓冲区不是在主内存中分配的)。然后Camera会将这块这空间的地址或叫句柄保存到Surface的BufferQueue中。

如我上面所述,在App中我们会创建一个SurfaceTexture作为该Surface中BufferQueue的消费者,当SurfaceTexture发现BufferQueue中有数据时,就会将其取出转成纹理交给GPU。此时,在系统的底层会通过DMA技术将Camera中存放的数据拷贝到GPU中。

当我们通过OpenGL的Shader程序处理好GPU中的视频帧、图像之后,处理后的数据仍然保留在GPU中,而它的句柄则会输出到EGLSurface中,也就是Surface的BufferQueue中。

同样的道理,当SurfaceFlinger的Layer从BufferQueue中取数据时,它取出的仍然是视频帧或图像的句柄,真正要处理的数据此时仍然在GPU中。当SurfaceFlinger对多个Layer合并时,它会把具体的任务交给GPU,这样GPU就可以从它所管理的内存空间中直接取出数据进行合并工作了。

这样是不是大大提高了渲染的效率呢?这就是OpenGL高效渲染的过程。

小结

在这篇文章中,我向你介绍了Android系统下OpenGL的工作原理,并且向你详细阐述了从Camera采集的视频帧传到GPU中进行渲染的,并如何通过Android的显示服务最终展示到屏幕上的。

通过这篇文章,我想你应该十分清楚OpenGL在Android系统下为什么可以高效工作了。尤其是当我们将上一篇文章与本篇文章放在一起阅读时,你的体会会更加深刻。

参考资料

系统玩转OpenGL+AI,实现各种酷炫视频特效

欢迎关注我的其它发布渠道