为了接下来的学习,需要先了解一下 EGL,什么是 EGL 呢?
EGL 是 Khronos 渲染 API(如OpenGL ES 或 OpenVG)和底层本机平台窗口系统(the underlying native platform window system)之间的一个中间接口层。它处理图形上下文管理、表面/缓冲区( surface/buffer )绑定和渲染同步,并使用其他 Khronos api 实现高性能、加速、混合模式的2D和3D渲染。EGL 还提供了 Khronos 之间的互操作功能,以实现 api 之间的有效数据传输。例如,运行 OpenMAX AL 的视频子系统和运行 OpenGL ES 的 GPU 之间的数据传输。
到这里,你可能会对 Khronos 产生疑问,
Khronos Group 团队成立于 2000 年 1 月,由包括 3Dlabs, ATI, Discreet, Evans & Sutherland, Intel, Nvidia, SGI 和 Sun Microsystems 在内的多家国际知名多媒体行业领导者创立,致力于发展开放标准的应用程序接口 API ,以实现在多种平台和终端设备上的富媒体创作、加速和回放。
好了,下面就通过在android开发中对EGL的使用过程,来说一下相关的函数及功能(注意,下面所列代码,非可直接用于生产环境)
首先,准备 EGL display 和 context,代码如下:
// 声明并初始化对象
private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
private EGLConfig mEGLConfig = null;
// 选取一个合适的 EGLConfig 对象,
int[] attribList = {
EGL14.EGL_RED_SIZE, 8,
EGL14.EGL_GREEN_SIZE, 8,
EGL14.EGL_BLUE_SIZE, 8,
EGL14.EGL_ALPHA_SIZE, 8,
EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
EGL14.EGL_NONE, 0, // placeholder for recordable
EGL14.EGL_NONE
};
EGLConfig[] configs = new EGLConfig[1];
int[] numConfigs = new int[1];
EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.length, numConfigs, 0);
mEGLConfig = configs[0];
// 获取 EGLDisplay 对象
mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
// 此处仅给出一个 GLES2 的 EGLContext 对象的获取方式
int[] attrib2_list = {
EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
EGL14.EGL_NONE
};
// 设置函数参数为 EGL14.EGL_NO_CONTEXT ,表示创建非共享的 EGLContext 对象
mEGLContext = EGL14.eglCreateContext(mEGLDisplay, mEGLConfig, EGL14.EGL_NO_CONTEXT, attrib2_list, 0);
然后,创建一个与 android 窗口 Surface 相关联的 EGLSurface 对象,代码如下:
int[ ] surfaceAttribs = {
EGL14.EGL_NONE
};
EGLSurface eglsurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0);
将 EGLContext 对象与 EGLSurface 对象相结合,一个 EGLSurface 对象可同时用作 "draw" and "read" ,或者使用两个不同的 EGLSurface 对象,分别用作 "draw" and "read",代码如下:
EGL14.eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext);
// 亦或
EGL14.eglMakeCurrent(mEGLDisplay, drawSurface, readSurface, mEGLContext);
显示对应的操作帧 EGLSurface 对象,代码如下:
EGL14.eglSwapBuffers(mEGLDisplay, eglSurface);
最后,完成显示后释放资源,代码如下:
EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
EGL14.eglReleaseThread();
// EGL14.eglTerminate(mEGLDisplay);
注意,EGL 在 android 开发中,EGLDisplay 是引用计数的,所以你每调用 eglInitialize() 时,最终需要对应调用 eglTerminate() 以减少引用计数。
以上就是 EGL 在 android 开发中大致的使用过程,希望通过上文的解释,有助于大家对 EGL 的认识理解。