深刻学习EGL


 以前在Broadcom7413/Broadcom7213平台上学习过如何设置EGL(http://blog.sina.com.cn/s/blog_602f87700100h4jh.html)。但理解并非很深。此次再做进一步研究。html

 

1.获取Display:
Display表明显示器,在有些系统上能够有多个显示器,也就会有多个Display。(Sam以为这个观点有点牵强,Sam以为Display理解为显存Framebuffer比较合适一些)。得到Display要调用EGLbooleaneglGetDisplay(NativeDisplay dpy),参数通常为EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的,在X-Window下是XDisplay ID,在MSWindows下是Window DC。EGL(Boardcom)为NativeDisplayType。数组

Sam: 因此在不一样平台开发时,第一件须要确认的就是:这个平台上的display概念是的实现是什么?函数

 

如今分Broadcom和Hi3716平台作分别的分析:学习

Broadcom:spa

GLAPI EGLDisplay APIENTRY eglGetDisplay( NativeDisplay display)3d

Hi3716:指针

EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayTypedisplay_id);code

请注意参数类型,全部用到本地窗口系统的地方都用屏蔽指针来处理.这样保证了它可移植性. 返回值EGLDisplay也只是个指针。xml

 

其语义以下:htm

eglGetDisplay()经过nativeDisplay获得Display,Dispaly为EGLDisplay类型的值,是一个关联系统物理屏幕的通用数据类型。

1.1 : Broadcom平台中eglGetDisplay()动做以下:

首先它作了一些硬件方面的准备工做。并返回了类型为EGL_P_Display的一个struct 地址。

typedef struct
{
 NativeDisplay nativeDisplay;

 BMEM_Handle hMem;
 BP3D_Handle hP3d;

 EGLint iError;
 EGL_P_Context *pContext;
 EGL_P_Surface *pDrawSurface;
 EGL_P_Surface *pReadSurface;
 GLboolean bGenerateMipmaps;
}
EGL_P_Display;

 

其中NativeDisplay就是参数1--NativeDisplay display

BP3D_Handle则为3D句柄。

 

 

1.2: Hi3716平台使用GC800 芯片。因此实现被放在_vdkEGL中了。暂时无法看到。

 

 

 

2.EGL初始化:

 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint*minor);

每一个 EGLDisplay在使用前都须要初始化。初始化 EGLDisplay的同时,你能够获得系统中 EGL 的实现版本号。

 

2.1Broadcom平台的eglInitialize ()

GLAPIEGLBoolean APIENTRY eglInitialize( EGLDisplay dpy, EGLint *major,EGLint *minor )

它只是很是简单的返回了主次版本号。

 

eglQueryString() 函数是另一个获取版本信息和其余信息的途径。经过 eglQueryString()获取版本信息须要解析版本字符串。

GLAPI const char * APIENTRY eglQueryString(EGLDisplay dpy, EGLint name )

支持的name有:EGL_VENDOR,EGL_VERSION。 分别返回:"Broadcom","1.0"

 

 

 

2.2 Hi3716平台:

 

 

3. 获得平台可用EGL配置:
EGLConfigs 是一个用来描述 EGL surface 配置信息的数据类型。要获取正确的渲染结果, Surface的格式是很是重要的。根据平台的不一样, surface 配置可能会有限制,好比某个设备只支持 16 位色深显示,或是不支持stencil buffer ,还有其余的功能限制或精度的差别。

      下面是获取系统可用的 EGL 配置信息的函数原型:

EGLBooleaneglGetConfigs (EGLDisplay dpy, EGLConfig *configs,EGLintconfig_size, EGLint *num_config);

 

3.1Broadcom 平台:

GLAPIEGLBoolean APIENTRY eglGetConfigs(
 EGLDisplay dpy,
 EGLConfig *configs,
 EGLint config_size,
 EGLint *num_config )

 

EGLboolean eglGetConfigs(EGLDisplay dpy,EGLConfig * config, EGLint config_size, EGLint *num_config)来得到全部config。

参数1:dpy, display.

参数2:输出参数,会在其中放置config.

参数3:config_size: 取config的个数。

参数4:num_config: 当参数2为空时,返回所有config个数。当参数2不为空时,返回读取config的个数。

 

注意:参数4num_config不能为空。

当参数2为空时,返回可支持的EGL Surface的个数。

当参数2不为空时,则返回参数4num_config个支持的EGL Surface 配置到参数2中。

 

4.察看选定EGL配置的具体特性:

GLAPIEGLBoolean APIENTRY eglGetConfigAttrib(
 EGLDisplay dpy,
 EGLConfig config,
 EGLint attribute,
 EGLint *value )

参数1:dpy, display.

参数2:config:指定config.

参数3:attribute:输入参数,想要知道的特性号。

参数4:value:输出参数,输入参数号的值。

 

 

5.选择一个配置:

以上获得了全部配置,能够经过一个相似filter的机制选择一个尽量有效的配置。

EGLBoolean eglChooseConfig(EGLDisplay dpy,const EGLint *attrib_list, EGLConfig *configs, EGLint config_size,EGLint * num_config);

 

5.1: Broadcom平台:

EGLboolean eglChooseConfig(EGLDisplay dpy,const EGLint * attr_list, EGLConfig * config, EGLint config_size,EGLint *num_config);

参数1:dpy: display.

参数2:attr_list: 使用这个参数,来选中符合的config.

参数3:config: 将符合的config,放到这里。

参数4:想要选中符合的config的最大个数。

参数5:真正选中的符合的config的个数。

其中attr_list是以EGL_NONE结束的参数数组,一般以id,value依次存放,对于个别标识性的属性能够只有id,没有value。

 

 

6.创建Context

GLAPI EGLContext APIENTRY eglCreateContext(
 EGLDisplay dpy,
 EGLConfig config,
 EGLContext share_list,
 const EGLint *attrib_list ) 

 

创建display的EGL 配置为参数2config的Context.

主要是硬件作动做。

注意: 此处能够选择OpenGLES版本。

attrib_list[1]:为版本号。

1为1.0.

2为2.0

 

7.建立Display Window:

注意,这里是EGL的第二个输入概念点-NativeWindow.与以前的NativeDisplay对应。

因此在设置EGL时,要首先知道此平台NativeDisaplay和NativeWindow对应为何概念。

GLAPI EGLSurface APIENTRY eglCreateWindowSurface(
 EGLDisplay dpy,
 EGLConfig config,
 NativeWindow window,
 const EGLint *attrib_list )

 参数1:dpy: display.

 参数2:要创建Surface的config.

 参数3:本地window概念。

 

8.设置Display的当前Sruface.

GLAPI EGLBoolean APIENTRY eglMakeCurrent(
 EGLDisplaydpy,   //参数1:dpy:display.
 EGLSurfacedraw,  //参数2:正在绘制的surface. 由eglCreateWindowSurface建立
 EGLSurface read,
 EGLContext ctx )

 

 

9.交换current Surface来绘制。

应用程序经过OpenGL API进行绘制,一帧完成以后,调用eglSwapBuffers(EGLDisplay dpy,EGLContext ctx)来显示。 

eglCreateContext