yjguo的个人博客分享 http://blog.sciencenet.cn/u/yjguo

博文

EGL资源的数据共享应用和底层驱动实现

已有 8816 次阅读 2015-8-12 19:22 |个人分类:OpenGL|系统分类:科研笔记

为了某个原因成文于2013年,本文最有意义的是在最后揭示了如何实现免拷贝的数据共享(non-copy,zero-copy),我还没有在之前的书籍教材中有看到过介绍的。通过CPU和GPU直接的数据直接共享,GPU之上各API之间的数据直接共享,可以大幅度的提高性能。这是个普遍的思路,在各种应用背景下都可以实现并使用。



    随着移动设备的广泛应用,如何以更低的功耗提供更佳的用户体验成为一个非常重要的课题。EGL通过定义EGLSurface和EGL Image等资源,使得不同renderingAPI间以及和原生平台间的数据可以实现直接共享,从而降低功耗提高性能。本文整合分散在各种规范中的概念介绍了如何在应用层使用EGL资源进行数据共享,并解释了在驱动程序中是如何支持的思路,以深入理解,不仅知其然,而且知其所以然。

关键词    EGL, OpenGL ES, 低功耗, 数据共享


1.引言

EGL是由Khronos组织维护的、连接OpenGL ES[[1]]和OpenVG[[2]]等rendering API与原生平台系统(native platformwindow system)的一套API接口,由核心规范[[3]]和扩展规范[[4]]组成。随着移动设备的广泛应用,如何以更低的功耗提供更佳的用户体验成为一个非常重要的课题。EGL通过定义EGL Surface和EGL Image等资源,使得不同rendering API间以及和原生平台间的数据可以实现直接共享,而无需拷贝。这种无拷贝机制不仅减少了内存读写从而降低功耗,而且提高了性能从而改善用户的体验。

由于不同的EGL资源在概念上相近,却在核心规范和多个扩展规范中被分别定义,容易混淆,因此,很有必要总结成文厘清概念,并解释其驱动程序的底层实现思路,以加深理解,从而更好的在移动设备上的应用程序中用好EGL资源。

2.EGL资源在应用层的数据共享

EGL Surface和EGLImage等EGL资源在应用程序中的创建和使用是类似的,具体函数名不同,但是形式上是类似的。而且两者最终都是通过成为绘制目标(RenderingTarget)或者纹理资源(Texture)来实现的,很容易造成函数的误用。

2.1 EGL Surface的创建和使用

1 EGL Surface的创建和使用

EGL Surface的创建和使用在EGL核心规范中定义。EGL Surface分成 WindowSurface、PixmapSurface和PbufferSurface三种类型,分别由函数eglCreateWindowSurface、eglCreatePixmapSurface和eglCreatePbufferSurface/eglCreatePbufferFromClientBuffer创建,如图1所示,箭头上的注释是函数名。其中,WindowSurface来自窗口系统,是最终在屏幕可见的Surface;PixmapSurface和PbufferSurface则是不可见的,两者区别在于PbufferSurface属于EGL创建,而PixmapSurface则是来自原生平台系统。随着函数eglCreatePbufferFromClientBuffer的出现,使得PbufferSurface也可以来自原生平台系统。由于PixmapSurface的概念相对简单,而且和窗口系统的不可见资源具有对应关系,因此,一般来说,我们会倾向使用PixmapSurface而不是PbufferSurface。

在图1中,指向椭圆形EGL Surface的箭头表示Surface的被创建,而源自EGL Surface的箭头则表示Surface的被使用。箭头起始端的矩形中的变量是该箭头函数的主要参数,其中,EGLNativeWindowType win和EGLNativePixmapType pixmap一般都在原生平台中被定义,所以可以被原生平台中支持的函数所直接访问。例如X11系统中由Xlib库创建的Window和Pixmap。

无论哪种EGL Surface,都可以通过eglMakeCurrent函数成为Render Target,但是,由于eglMakeCurrent会导致graphics context的切换从而影响性能,所以,在可能的情况下,不可见的RenderTarget一般不使用EGL Surface,而使用FBO技术(FrameBuffer Object[[5]])。PBufferSurface还可以通过eglBindTexImage函数成为纹理资源(Texture),以作为graphicspipeline的数据来源;一般来说,原生平台提供商还会增加一个扩展规范,使得PixmapSurface也可以通过eglBindTexImage函数成为Texture。

2.2 EGL Image的创建和使用

EGL Image最初在扩展规范EGL_KHR_image中定义,为了进一步扩展的需要,在2008年11月19号被分成为两个扩展规范,如图2的椭圆形EGLImage向上部分所示,其中,EGL_KHR_image_base定义了EGLImage的相关概念和相应的eglCreateImageKHR函数,该函数的两个关键参数是target和buffer,另一个扩展规范是EGL_KHR_image_pixmap,使得原生平台的pixmap可以被创建为EGL Image。在此基础上,Android平台提出了EGL_Android_image_native_buffer使得android平台定义的ANativeWindowBuffer可以被创建为EGL Image;还有EGL_KHR_gl_texture_2D_image,EGL_KHR_gl_texture_3D_image,EGL_KHR_gl_renderbuffer_image和EGL_KHR_gl_texture_cubemap_image等扩展规范使得OpenGLES中的资源可以被创建为EGL Image。一般的,每个原生平台提供者都会提供其私有的扩展规范来创建相应的EGLImage。

EGL Image的使用在OpenGLES的扩展规范中被定义,如图2的椭圆形EGL Surface部分向下所示,首先,EGL Image被重新定义(typedef)为GLeglImageOES,然后,扩展规范GL_OES_EGL_image定义了两个函数,使得EGL Image可以被当做2D Texture或者Renderbuffer使用,可分别作为graphicspipeline的数据来源和绘制目标。另一个扩展规范GL_OES_EGL_image_external定义了一个新的Texture类型GL_TEXTURE_EXTERNAL_OES,使得诸如YUV等以前不被OpenGL ES支持的格式的EGL Image,可以被直接作为一个Texture从而被OpenGL ES所支持,当然,其背后离不开驱动程序内部增加shader指令进行格式转换,假以时日,可能会出现直接支持YUV等格式的texture采样硬件。

2EGL Image的创建和使用

3.EGL资源在驱动底层的实现

EGL Surface和EGLImage数据结构的c语言定义都是void *,它们可以从多种来源被创建,也有多个使用场合,那么,在驱动底层是如何光凭void *就能知道当前情况呢,一个参考实现是使用基础struct和magic number,其中,magic number在基础struct中被定义,所有相关资源数据结构的最开始部分就是基础struct。这样,在创建时返回对应资源数据结构(struct)的指针作为void *的handle,在使用时则将此handle强制转回基础struct指针,然后根据struct中magic number数据成员的值来得知原始资源是什么从而将其用好。

之前提到,有些资源还可以被原生平台提供的函数读写,那么,是怎么实现CPU和GPU对同一资源的访问呢?抛开表象看本质,我们知道所有资源最终都是由物理存储器中的内存页面组成,CPU通过其内存管理单元(MMU)进行地址映射从而访问到真实存储,有了这些信息,内核态的驱动程序就可以通过配置GPU的类MMU单元,从而使得GPU也可以访问这些资源,这也就意味着graphicspipeline可以读写这些资源。在此,需要特别关注并解决好CPU和GPU对同一资源的并发访问和cache刷新的技术问题。

4.结语

知其然,也知其所以然。通过以上对EGL Surface和EGLImage的介绍,包括如何创建和使用,也包括在驱动底层的支持思路,可以深入理解这些EGL资源的无需拷贝的数据共享机制是如何降低功耗和提高性能。特别地,将所有相关重要概念都在文中的两幅图中表现出来,做到一目了然,这对用好EGL资源具有重要意义。限于篇幅所限,无法对EGL Surface和EGLImage进行更多细节上的介绍,需要用户在使用细节上参考相应的EGL和OpenGLES的核心规范和扩展规范。

 

参考文献


[1]OpenGL ES - The Standard for Embedded Accelerated 3D Graphics, http://www.khronos.org/opengles/

[2]OpenVG - The Standard for Vector Graphics Acceleration, http://www.khronos.org/openvg/

[3]Jon Leech, Khronos Native Platform Graphics Interface (EGL Version 1.4 – April6, 2011) http://www.khronos.org/registry/egl/specs/eglspec.1.4.20110406.pdf

[4]Khronos EGL API Registry, http://www.khronos.org/registry/egl/

[5]Aaftab Munshi, GL_OES_framebuffer_object, http://www.khronos.org/registry/gles/extensions/OES/OES_framebuffer_object.txt





https://blog.sciencenet.cn/blog-1420268-912560.html

上一篇:基于OpenGL Shader的颜色空间转换
收藏 IP: 116.233.97.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-11-22 23:35

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部