EGL Version 1.4 阅读理解

来源:互联网 发布:中小型企业网络设计 编辑:程序博客网 时间:2024/05/22 16:02

1. 概览

EGL是介于各种粉刷(rendering)API如(OpenGL,OpenVG等)和底层窗口系统平台之间的接口。EGL提供各种机制创建图形context和粉刷surface供客户API使用。同时,EGL也在绘图的过程中为本地绘图平台和客户api提供同步机制。EGL提供远程和间接粉刷机制,而GLX API则有这个机制。

2. EGL操作

2.1本地窗口系统和粉刷API

EGL可以在多个操作系统(塞班/嵌入式linux/unix/windows等)和多种本地窗口(X/MicrosoftWindows)中实现。EGL的实现也可能允许本地其他的粉刷api来粉刷EGL surface,如(Xlib,GDI)。

2.1.1 常数类型

1.EGLBoolean:egl的boolean类型,值可以是EGL_TRUE(1) 和 EGL_FALSE (0).

2.EGLint:类似于int类型。

 

2.1.2 Display

大部分EGL调用都会使用EGLDisplay参数,它代表一个抽象的屏幕。

 

2.2粉刷上下文和绘图平面(Rendering Contexts andDrawing Surfaces)

EGL的一个最主要的目的就是提供粉刷上下文和绘图平面的创建函数供客户端API使用。EGL定义了多种绘图平面类型,统称EGLSurface。主要包括如下三类:

(1)windowsurface:可以将里面的图形缓冲画到屏幕上。

(2)pbufferssurface:数据存在内存缓冲上,不能画在屏幕上。

(3)pixmaps,surface:本地api可以访问的内存数据缓冲。

   

EGLSurface是依照各自的EGLConfig来进行的(其实就是创建EGLSurface的函数需要EGLCongif做参数)。EGLConfig描述了所创建的平面需要的颜色深度,类型,辅助缓冲等一些信息。

辅助缓存是对应于EGLSurface的,而不是context。如果很多context向同一个surface画图,则context之间会共享这些缓冲。Surface和Context之间有一种兼容性的说法,满足兼容性条件后,surface才能被context使用。这些条件是:

(1)支持相同类型的颜色缓冲。(颜色缓冲类型包括RGB/luminance等)

(2)具有相同的颜色缓冲深度和辅助缓冲深度。这里的深度只各个颜色深度都要相同,比如RGB565与RGB4444中,虽然颜色深度总和都是16bit/pixel,但是每个维度的深度不一样。因此,他们是不兼容的。辅助缓冲有一个特例,如果某个辅助缓冲对于某个客户API是没有意义的(不需要的),那么,这种缓冲不考虑兼容性。如,一个surface包含颜色缓冲和stencilbuffer,当OpenVG 粉刷api下的Context包含相同的颜色缓冲时,他们是兼容的。因为,OpenVG不需要stencil buffer。

(3)surface和context需要在相同类型的客户api(都是opengl或都是openVG等)创建函数下创建。

(4)他们的创建函数中使用的display参数是一样的。

满足兼容条件时,一个context可以往多个EGLSurface上作画,一个EGLSurface也可以对应多个context。

 

2.2.1 使用粉刷上下文(Rendering Context)

OpenGL ES定义了客户端状态和服务端状态。因此,OpenGLES的context包含客户和服务端两个状态。OpenVG则没有。OpenGL ES和OpenVG客户API都采用了隐含的context作为粉刷入口点,而不是在绘图函数中传入Context参数。因此,EGL会提供一个函数(makeCurrent(…))来使某个context变成当前使用状态。每个线程最多可以为每个支持的客户端api(opengl/openVG等)创建一个当前粉刷context。另外,同一时刻,一个context只能被一个线程置成当前。

2.2.2 粉刷模式

EGL支持两种粉刷模式:后备缓冲和单缓冲。(back buffered and single buffered)

后备缓冲可以用在window和pbuffer两种surface中,EGL负责相关的内存申请和使用。单缓冲则用在pixmapsurface中,其内存格式和本地系统使用的pixmap格式一样,可供本地窗口系统函数访问。当然,某些些客户api比如Opengl 和OpenVG,也支持单缓冲的windowsurface。

不管是单缓冲还是后备缓冲的surface都可以通过eglCopyBuffers()函数,拷贝到指定的本地pixmap中。

EGL surface对应的本地窗口缩放时,EGL的window surface也需要跟着缩放。一般的实现过程是,本地操作系统和窗口系统执行一个的回调函数通知EGL改变窗口大小,这个改变对客户端api是透明的。也有一些EGL实现,是通过surface大小改变的函数调用来实现。对于没有实现窗口改变功能的EGL实现,需要通过调用eglSwapBuffers函数调用来回本地窗口改变。

2.4状态共享

    大部分客户端api的context状态是很小的。但是,一些有时候我们希望context之间可以共享一些状态,省得各个context都拥有一些相同的内部状态数据。只有相同客户api创建(如都是OpenGL创建的)的context才能共享内部一些状态。

OpenGLcontexts 可以共享texture objects, shader和programobjects, display list objects, pixel和 vertex bufferobjects.

OpenGLES contexts 可以共享texture objects, shader 和program objects, vertex buffer objects.

    OpenVG contexts 可以共享images,paint objects, paths.

 

2.5多线程

EGL和它的客户端api函数必须是线程安全的。客户端api和本地绘图api可以通过一些同步原语来实现同步。

 

3. EGL函数与错误

3.1错误

要检测当前egl调用的详细错误信息,可以调用:EGLint eglGetError(void);

 

3.2初始化

(1)EGLDisplayeglGetDisplay(EGLNativeDisplayType display_id);

需要先初始化Display后,才能调用EGL其他函数和客户端API函数。这里EGLNativeDisplayType是依不同本地平台而不同的。如,X windows窗口系统下,它对应于XDisplay;对于微软系统下,它对应于Windows Device Context。

(2)EGLBoolean eglInitialize(EGLDisplaydpy, EGLint *major, EGLint *minor);初始化刚才得到的display。

(3)EGLBoolean eglTerminate(EGLDisplaydpy););释放刚才得到的display。

 

3.3EGL信息

(1)const char *eglQueryString(EGLDisplaydpy,EGLint name);查询当前display下的EGL信息。name参数可以是如下几个:EGL_CLIENT_APIS, EGL_EXTENSIONS, EGL_VENDOR,或者EGL_VERSION.返回值为查询结果。

 

3.4EGL Configuration管理

    EGLConfig描述了一个EGLSurface所包含的像数格式,类型,颜色缓冲大小,辅助缓存大小等信息。如果EGLSurface是属于windowsurface,那么这个surface的EGLConfig还包含相关的本地视窗类型。表3-1描述了EGLConfig的属性值,他们可以作为eglChooseConfig的参数。EGL_CONFIG_ID是一个唯一指定不同EGLConfig的整数值。他们是『1---N』的正整数。


(1)EGLBoolean eglGetConfigs(EGLDisplaydpy, EGLConfig *configs, EGLint config_size,EGLint *num_config);

查询所有指定display下的EGLCongifs,num_config返回了可用的数目。

(2)EGLBoolean eglChooseConfig(EGLDisplaydpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint*num_config);传入需求的属性列表,看是否有合适的config。

(3)EGLBoolean eglGetConfigAttrib(EGLDisplaydpy, EGLConfig config, EGLint attribute, EGLint *value);查询某个config的某些属性值。

 

3.5粉刷表面(Rendering Surface)

(1)EGLSurface eglCreateWindowSurface(EGLDisplay dpy,  EGLConfig config, EGLNativeWindowType win,

const EGLint *attrib_list);创建windowsurface。

 

(2)EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, constEGLint *attrib_list);创建pbuffer surface.

 

(3)EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBufferbuffer, EGLConfig config, const EGLint *attrib_list);绑定surface到客户端api的buffer里。

 

(4)EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,EGLNativePixmapType pixmap, const EGLint *attrib_list);创建nativepixmap粉刷surface。

 

(5)EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface);销毁surface。

 

(6)EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLintattribute, EGLint value);设定surface的属性值。

 

(7)EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLintattribute, EGLint *value);查询surface的属性值。

相关属性值见下表:


3.6粉刷纹理(Rendering to Textures)

使用如下一些api可以实现把pbuffersurface里面像数数据粉刷到OpenGL ES纹理(texture)中。

(1)EGLBoolean eglBindTexImage(EGLDisplaydpy, EGLSurface surface, EGLint buffer);这个命令定义了一个两维的纹理图像。纹理图像包含了指定图像的buffer缓冲区。当前,EGL只支持EGL_BACK_BUFFER。也就是说,函数中,buffer只能等于EGL_BACK_BUFFER。

 

(2)EGLBooleaneglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);释放被texture使用的surface缓冲。

 

3.7粉刷上下文(Rendering Context)

(1)EGLBoolean eglBindAPI(EGLenum api);绑定客户端api,参数可以是:EGL_OPENGL_API,

EGL_OPENGL_ES_API,或者 EGL_OPENVG_API。

 

(2)EGLenum eglQueryAPI(void);查询当前支持的客户端api。

 

(3)EGLContexteglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, constEGLint *attrib_list);创建context。

 

(4)EGLBooleaneglDestroyContext(EGLDisplay dpy, EGLContext ctx);销毁一个context

 

(5)EGLBoolean eglMakeCurrent(EGLDisplaydpy, EGLSurface draw, EGLSurface read, EGLContext ctx);这个函数就是前面所说的makecurrent功能。指定当前使用的context,之后的一些api调用都是基于这个context状态下的。draw参数指定的surface可以用来做所有的操作除了读像数,read则是用来读的。read和draw可以指定同一个surface,这样该surface可以用来读,也可以写。

 

(6)EGLContexteglGetCurrentContext(void); 返回当前客户端api的当前context。

 

(7)EGLSurfaceeglGetCurrentSurface(EGLint readdraw);返回read/draw的surface。

 

(8)EGLDisplayeglGetCurrentDisplay(void);返回当前display。

 

(9)EGLBoolean eglQueryContext(EGLDisplaydpy, EGLContext ctx, EGLint attribute, EGLint *value);

获取当前context的属性值。

 

3.8同步原语

(1)EGLBoolean eglWaitClient(void);

 

(2)EGLBoolean eglWaitGL(void);

 

(3)EGLBoolean eglWaitNative(EGLintengine);

 

 

3.9提交颜色缓冲

(1)EGLBoolean eglSwapBuffers(EGLDisplaydpy, GLSurface surface);如果是后备缓冲的window surface,那么它的颜色缓冲就会被拷贝到本地窗口,如果是单缓冲的surface,那么这个函数就没有用了。

(2)EGLBoolean eglCopyBuffers(EGLDisplaydpy, EGLSurface surface, EGLNativePixmapType target);拷贝surface的颜色缓冲到本地pixmap中。

 

关于提交,如果函数中display和surface参数是当前线程的current context的display和surface,那么eglSwapBuffers和eglCopyBuffers会在当前的context下执行一个显式的flush操作(对于opengl或者opengl es是glFlush函数,对于OpenVG则是vgFlush函数)。后来的客户端api命令也可以马上发送,但是在这次提交操作完成前(flush),不会被执行。

 

(3)EGLBoolean eglSwapInterval(EGLDisplaydpy, EGLint interval);用于指定最小的帧发送间隔(一般指video)。

 

3.10获取扩展函数指针

void (*eglGetProcAddress(const char *procname))(void);

 

3.11释放线程状态

EGLBoolean eglReleaseThread(void);EGL保存一些线程状态供类似elgGetError等函数查询,调用这个函数可以使他们恢复到初始状态。

 


原创粉丝点击