EGLConfigs是一个用来描述EGL surface配置信息的数据类型。要获取正确的渲染结果,Surface的格式是非常重要的。根据平台的不同,surface配置可能会有限制,比如某个设备只支持16位色深显示,或是不支持stencil buffer,还有其他的功能限制或精度的差异。
下面是获取系统可用的EGL配置信息的函数原型:
EGLBoolean eglGetConfigs (EGLDisplay dpy, EGLConfig *configs,EGLint config_size, EGLint *num_config);
参数configs将包含在你的平台上有效的所有EGL framebuffer配置列表。支持的配置总数将通过num_config返回。实际返回的configs的配置个数依赖于程序传入的config_size。如果config_size < num_config,则不是所有的配置信息都将被返回。如果想获取系统支持的所有配置信息,最好的办法就是先给eglGetConfig传一个NULL的configs参数,num_config将得到系统所支持的配置总数,然后用它来给configs分配合适的内存大小,再用得到的configs来调用eglGetConfig。
下面是如果使用eglGetConfig()函数的例子:
EGLConfig *configs_list;
EGLint num_configs;
// Main Display
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if( m_eglDisplay == EGL_NO_DISPLAY || eglGetError() != EGL_SUCCESS )
return FALSE;
if( eglInitialize( m_eglDisplay, NULL, NULL ) == EGL_FALSE || eglGetError() != EGL_SUCCESS )
return FALSE;
// find out how many configurations are supported
if ( eglGetConfigs( m_eglDisplay, NULL, 0, &num_configs)
== EGL_FALSE || eglGetError() != EGL_SUCCESS )
return FALSE;
configs_list = malloc(num_configs * sizeof(EGLConfig));
if (configs_list == (EGLConfig *)0)
return FALSE;
// Get Configurations
if( eglGetConfigs( m_eglDisplay, configs_list, num_configs, &num_configs)
== EGL_FALSE || eglGetError() != EGL_SUCCESS )
return FALSE;
由于当前平台的限制,通常只有很少的配置可用。系统支持的配置通常是利用系统硬件提供最好的性能。当你移植游戏到多个平台,它们的EGL配置可能会有细微的差别,我们希望作为通用的移植问题来直接处理这些问题。
选择一个EGL Configuration
基于EGL的属性,你可以定义一个希望从系统获得的配置,它将返回一个最接近你的需求的配置。选择一个你特有的配置是有点不合适的,因为只是在你的平台上使用有效。eglChooseConfig()函数将适配一个你所期望的配置,并且尽可能接近一个有效的系统配置。
下面是选择一个EGL配置的函数原型:
EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size, EGLint * num_config);
参数attrib_list指定了选择配置时需要参照的属性。参数configs将返回一个按照attrib_list排序的平台有效的所有EGL framebuffer配置列表。参数config_size指定了可以返回到configs的总配置个数。参数num_config返回了实际匹配的配置总数。
下面是如果使用eglChoosetConfig()函数的例子:
EGLint attrs[3] = { EGL_DEPTH_SIZE, 16, EGL_NONE };
EGLint num_configs;
EGLConfigs *configs_list;
// Get the display device
if ((eglDisplay = eglGetDisplay(EGL_NO_DISPLAY)) == EGL_NO_DISPLAY)
{
return eglGetError();
}
// Initialize the display
if (eglInitialize(eglDisplay, NULL, NULL) == EGL_FALSE)
{
return eglGetError();
}
// Obtain the total number of configurations that match
if (eglChooseConfig(eglDisplay, attrs, NULL, 0, &num_configs) == EGL_FALSE)
{
return eglGetError();
}
configs_list = malloc(num_configs * sizeof(EGLConfig));
if (configs_list == (EGLConfig *)0)
return eglGetError();
// Obtain the first configuration with a depth buffer of 16 bits
if (!eglChooseConfig(eglDisplay, attrs, &configs_list, num_configs, &num_configs))
{
return eglGetError();
}
如果找到多个合适的配置,有一个简单的排序算法用来匹配最接近你所查询的配置。表2-2显示了基于属性值的用来选择和排序的顺序,也包括了EGL规范中所有EGL配置属性及其默认值。
表2.1 EGL 配置属性默认值和匹配法则
属性 |
数据类型 |
默认值 |
排序优先级 |
选择顺序 |
EGL_BUFFER_SIZE |
int |
0 |
3 |
Smaller value |
EGL_RED_SIZE |
int |
0 |
2 |
Larger value |
EGL_GREEN_SIZE |
int |
0 |
2 |
Larger value |
EGL_BLUE_SIZE |
int |
0 |
2 |
Larger value |
EGL_ALPHA_SIZE |
int |
0 |
2 |
Larger value |
EGL_CONFIG_CAVET |
enum |
EGL_DONT_CARE |
1(first) |
Exact value |
EGL_CONFIG_ID |
int |
EGL_DONT_CARE |
9 |
Exact value |
EGL_DEPTH_SIZE |
int |
0 |
6 |
Smaller value |
EGL_LEVEL |
int |
0 |
- |
Equal value |
EGL_NATIVE_RENDERABLE |
Boolean |
EGL_DONT_CARE |
- |
Exact value |
EGL_NATIVE_VISUAL_TYPE |
int |
EGL_DONT_CARE |
8 |
Exact value |
EGL_SAMPLE_BUFFERS |
int |
0 |
4 |
Smaller value |
EGL_SAMPLES |
int |
0 |
5 |
Smaller value |
EGL_STENCIL_SIZE |
int |
0 |
7 |
Smaller value |
EGL_SURFACE_TYPE |
bitmask |
EGL_WINDOW_BIT |
- |
Mask value |
EGL_TRANSPARENT_TYPE |
enum |
EGL_NONE |
- |
Exact value |
EGL_TRANSPARENT_RED_VALUE |
int |
EGL_DONT_CARE |
- |
Exact value |
EGL_TRANSPARENT_GREEN_VALUE |
int |
EGL_DONT_CARE |
- |
Exact value |
EGL_TRANSPARENT_BLUE_VALUE |
int |
EGL_DONT_CARE |
- |
Exact value |