2 * EGL Configuration (pixel format) functions.
10 #include "eglconfig.h"
11 #include "egldisplay.h"
12 #include "egldriver.h"
13 #include "eglglobals.h"
17 #define MIN2(A, B) (((A) < (B)) ? (A) : (B))
21 _eglSetConfigAttrib(_EGLConfig
*config
, EGLint attr
, EGLint val
)
23 assert(attr
>= FIRST_ATTRIB
);
24 assert(attr
< FIRST_ATTRIB
+ MAX_ATTRIBS
);
25 config
->Attrib
[attr
- FIRST_ATTRIB
] = val
;
30 * Init the given _EGLconfig to default values.
31 * \param id the configuration's ID.
34 _eglInitConfig(_EGLConfig
*config
, EGLint id
)
36 memset(config
, 0, sizeof(*config
));
37 config
->Handle
= (EGLConfig
) _eglUIntToPointer((unsigned int) id
);
38 _eglSetConfigAttrib(config
, EGL_CONFIG_ID
, id
);
39 _eglSetConfigAttrib(config
, EGL_BIND_TO_TEXTURE_RGB
, EGL_DONT_CARE
);
40 _eglSetConfigAttrib(config
, EGL_BIND_TO_TEXTURE_RGBA
, EGL_DONT_CARE
);
41 _eglSetConfigAttrib(config
, EGL_CONFIG_CAVEAT
, EGL_DONT_CARE
);
42 _eglSetConfigAttrib(config
, EGL_NATIVE_RENDERABLE
, EGL_DONT_CARE
);
43 _eglSetConfigAttrib(config
, EGL_NATIVE_VISUAL_TYPE
, EGL_DONT_CARE
);
44 _eglSetConfigAttrib(config
, EGL_MIN_SWAP_INTERVAL
, EGL_DONT_CARE
);
45 _eglSetConfigAttrib(config
, EGL_MAX_SWAP_INTERVAL
, EGL_DONT_CARE
);
46 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_WINDOW_BIT
);
47 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_TYPE
, EGL_NONE
);
48 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_RED_VALUE
, EGL_DONT_CARE
);
49 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_GREEN_VALUE
, EGL_DONT_CARE
);
50 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_BLUE_VALUE
, EGL_DONT_CARE
);
51 #ifdef EGL_VERSION_1_2
52 _eglSetConfigAttrib(config
, EGL_COLOR_BUFFER_TYPE
, EGL_RGB_BUFFER
);
53 _eglSetConfigAttrib(config
, EGL_RENDERABLE_TYPE
, EGL_OPENGL_ES_BIT
);
54 #endif /* EGL_VERSION_1_2 */
59 * Return the public handle for an internal _EGLConfig.
60 * This is the inverse of _eglLookupConfig().
63 _eglGetConfigHandle(_EGLConfig
*config
)
65 return config
? config
->Handle
: 0;
70 * Given an EGLConfig handle, return the corresponding _EGLConfig object.
71 * This is the inverse of _eglGetConfigHandle().
74 _eglLookupConfig(EGLConfig config
, _EGLDisplay
*disp
)
77 for (i
= 0; i
< disp
->NumConfigs
; i
++) {
78 if (disp
->Configs
[i
]->Handle
== config
) {
79 return disp
->Configs
[i
];
87 * Add the given _EGLConfig to the given display.
88 * Note that we just save the ptr to the config (we don't copy the config).
91 _eglAddConfig(_EGLDisplay
*display
, _EGLConfig
*config
)
93 _EGLConfig
**newConfigs
;
96 /* do some sanity checks on the config's attribs */
97 assert(GET_CONFIG_ATTRIB(config
, EGL_CONFIG_ID
) > 0);
98 assert(GET_CONFIG_ATTRIB(config
, EGL_RENDERABLE_TYPE
) != 0x0);
99 assert(GET_CONFIG_ATTRIB(config
, EGL_SURFACE_TYPE
) != 0x0);
100 assert(GET_CONFIG_ATTRIB(config
, EGL_RED_SIZE
) > 0);
101 assert(GET_CONFIG_ATTRIB(config
, EGL_GREEN_SIZE
) > 0);
102 assert(GET_CONFIG_ATTRIB(config
, EGL_BLUE_SIZE
) > 0);
104 n
= display
->NumConfigs
;
106 /* realloc array of ptrs */
107 newConfigs
= (_EGLConfig
**) realloc(display
->Configs
,
108 (n
+ 1) * sizeof(_EGLConfig
*));
110 display
->Configs
= newConfigs
;
111 display
->Configs
[n
] = config
;
112 display
->NumConfigs
++;
122 * Parse the attrib_list to fill in the fields of the given _eglConfig
123 * Return EGL_FALSE if any errors, EGL_TRUE otherwise.
126 _eglParseConfigAttribs(_EGLConfig
*config
, const EGLint
*attrib_list
)
130 /* set all config attribs to EGL_DONT_CARE */
131 for (i
= 0; i
< MAX_ATTRIBS
; i
++) {
132 config
->Attrib
[i
] = EGL_DONT_CARE
;
135 /* by default choose windows unless otherwise specified */
136 config
->Attrib
[EGL_SURFACE_TYPE
- FIRST_ATTRIB
] = EGL_WINDOW_BIT
;
138 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
139 const EGLint attr
= attrib_list
[i
];
140 if (attr
>= EGL_BUFFER_SIZE
&&
141 attr
<= EGL_MAX_SWAP_INTERVAL
) {
142 EGLint k
= attr
- FIRST_ATTRIB
;
144 assert(k
< MAX_ATTRIBS
);
145 config
->Attrib
[k
] = attrib_list
[++i
];
147 #ifdef EGL_VERSION_1_2
148 else if (attr
== EGL_COLOR_BUFFER_TYPE
) {
149 EGLint bufType
= attrib_list
[++i
];
150 if (bufType
!= EGL_RGB_BUFFER
&& bufType
!= EGL_LUMINANCE_BUFFER
) {
151 _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
154 _eglSetConfigAttrib(config
, EGL_COLOR_BUFFER_TYPE
, bufType
);
156 else if (attr
== EGL_RENDERABLE_TYPE
) {
157 EGLint renType
= attrib_list
[++i
];
158 if (renType
& ~(EGL_OPENGL_ES_BIT
| EGL_OPENGL_ES2_BIT
| EGL_OPENVG_BIT
)) {
159 _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
162 _eglSetConfigAttrib(config
, EGL_RENDERABLE_TYPE
, renType
);
164 else if (attr
== EGL_ALPHA_MASK_SIZE
||
165 attr
== EGL_LUMINANCE_SIZE
) {
166 EGLint value
= attrib_list
[++i
];
167 _eglSetConfigAttrib(config
, attr
, value
);
169 #endif /* EGL_VERSION_1_2 */
171 _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
188 EGLint MatchCriteria
;
192 /* This encodes the info from Table 3.5 of the EGL spec, ordered by
195 * XXX To do: EGL 1.2 attribs
197 static struct sort_info SortInfo
[] = {
198 { EGL_CONFIG_CAVEAT
, EXACT
, SPECIAL
},
199 { EGL_RED_SIZE
, ATLEAST
, SPECIAL
},
200 { EGL_GREEN_SIZE
, ATLEAST
, SPECIAL
},
201 { EGL_BLUE_SIZE
, ATLEAST
, SPECIAL
},
202 { EGL_ALPHA_SIZE
, ATLEAST
, SPECIAL
},
203 { EGL_BUFFER_SIZE
, ATLEAST
, SMALLER
},
204 { EGL_SAMPLE_BUFFERS
, ATLEAST
, SMALLER
},
205 { EGL_SAMPLES
, ATLEAST
, SMALLER
},
206 { EGL_DEPTH_SIZE
, ATLEAST
, SMALLER
},
207 { EGL_STENCIL_SIZE
, ATLEAST
, SMALLER
},
208 { EGL_NATIVE_VISUAL_TYPE
, EXACT
, SPECIAL
},
209 { EGL_CONFIG_ID
, EXACT
, SMALLER
},
210 { EGL_BIND_TO_TEXTURE_RGB
, EXACT
, NONE
},
211 { EGL_BIND_TO_TEXTURE_RGBA
, EXACT
, NONE
},
212 { EGL_LEVEL
, EXACT
, NONE
},
213 { EGL_NATIVE_RENDERABLE
, EXACT
, NONE
},
214 { EGL_MAX_SWAP_INTERVAL
, EXACT
, NONE
},
215 { EGL_MIN_SWAP_INTERVAL
, EXACT
, NONE
},
216 { EGL_SURFACE_TYPE
, MASK
, NONE
},
217 { EGL_TRANSPARENT_TYPE
, EXACT
, NONE
},
218 { EGL_TRANSPARENT_RED_VALUE
, EXACT
, NONE
},
219 { EGL_TRANSPARENT_GREEN_VALUE
, EXACT
, NONE
},
220 { EGL_TRANSPARENT_BLUE_VALUE
, EXACT
, NONE
},
226 * Return EGL_TRUE if the attributes of c meet or exceed the minimums
230 _eglConfigQualifies(const _EGLConfig
*c
, const _EGLConfig
*min
)
233 for (i
= 0; SortInfo
[i
].Attribute
!= 0; i
++) {
234 const EGLint mv
= GET_CONFIG_ATTRIB(min
, SortInfo
[i
].Attribute
);
235 if (mv
!= EGL_DONT_CARE
) {
236 const EGLint cv
= GET_CONFIG_ATTRIB(c
, SortInfo
[i
].Attribute
);
237 if (SortInfo
[i
].MatchCriteria
== EXACT
) {
242 else if (SortInfo
[i
].MatchCriteria
== ATLEAST
) {
248 assert(SortInfo
[i
].MatchCriteria
== MASK
);
249 if ((mv
& cv
) != mv
) {
260 * Compare configs 'a' and 'b' and return -1 if a belongs before b,
261 * 1 if a belongs after b, or 0 if they're equal.
265 _eglCompareConfigs(const void *a
, const void *b
)
267 const _EGLConfig
*aConfig
= (const _EGLConfig
*) a
;
268 const _EGLConfig
*bConfig
= (const _EGLConfig
*) b
;
271 for (i
= 0; SortInfo
[i
].Attribute
!= 0; i
++) {
272 const EGLint aVal
= GET_CONFIG_ATTRIB(aConfig
, SortInfo
[i
].Attribute
);
273 const EGLint bVal
= GET_CONFIG_ATTRIB(bConfig
, SortInfo
[i
].Attribute
);
274 if (SortInfo
[i
].SortOrder
== SMALLER
) {
277 else if (aVal
> bVal
)
279 /* else, continue examining attribute values */
281 else if (SortInfo
[i
].SortOrder
== SPECIAL
) {
282 if (SortInfo
[i
].Attribute
== EGL_CONFIG_CAVEAT
) {
283 /* values are EGL_NONE, SLOW_CONFIG, or NON_CONFORMANT_CONFIG */
286 else if (aVal
> bVal
)
289 else if (SortInfo
[i
].Attribute
== EGL_RED_SIZE
||
290 SortInfo
[i
].Attribute
== EGL_GREEN_SIZE
||
291 SortInfo
[i
].Attribute
== EGL_BLUE_SIZE
||
292 SortInfo
[i
].Attribute
== EGL_ALPHA_SIZE
) {
295 else if (aVal
< bVal
)
299 assert(SortInfo
[i
].Attribute
== EGL_NATIVE_VISUAL_TYPE
);
302 else if (aVal
> bVal
)
307 assert(SortInfo
[i
].SortOrder
== NONE
);
308 /* continue examining attribute values */
312 /* all attributes identical */
318 * Typical fallback routine for eglChooseConfig
321 _eglChooseConfig(_EGLDriver
*drv
, _EGLDisplay
*disp
, const EGLint
*attrib_list
,
322 EGLConfig
*configs
, EGLint config_size
, EGLint
*num_configs
)
324 _EGLConfig
**configList
, criteria
;
327 /* parse the attrib_list to initialize criteria */
328 if (!_eglParseConfigAttribs(&criteria
, attrib_list
)) {
332 /* allocate array of config pointers */
333 configList
= (_EGLConfig
**) malloc(config_size
* sizeof(_EGLConfig
*));
335 _eglError(EGL_BAD_CONFIG
, "eglChooseConfig(out of memory)");
339 /* make array of pointers to qualifying configs */
340 for (i
= count
= 0; i
< disp
->NumConfigs
&& count
< config_size
; i
++) {
341 if (_eglConfigQualifies(disp
->Configs
[i
], &criteria
)) {
342 configList
[count
++] = disp
->Configs
[i
];
346 /* sort array of pointers */
347 qsort(configList
, count
, sizeof(_EGLConfig
*), _eglCompareConfigs
);
349 /* copy config handles to output array */
351 for (i
= 0; i
< count
; i
++) {
352 configs
[i
] = configList
[i
]->Handle
;
358 *num_configs
= count
;
365 * Fallback for eglGetConfigAttrib.
368 _eglGetConfigAttrib(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
369 EGLint attribute
, EGLint
*value
)
371 const EGLint k
= attribute
- FIRST_ATTRIB
;
372 if (k
>= 0 && k
< MAX_ATTRIBS
) {
373 *value
= conf
->Attrib
[k
];
377 _eglError(EGL_BAD_ATTRIBUTE
, "eglGetConfigAttrib");
384 * Fallback for eglGetConfigs.
387 _eglGetConfigs(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLConfig
*configs
,
388 EGLint config_size
, EGLint
*num_config
)
392 *num_config
= MIN2(disp
->NumConfigs
, config_size
);
393 for (i
= 0; i
< *num_config
; i
++) {
394 configs
[i
] = disp
->Configs
[i
]->Handle
;
398 /* just return total number of supported configs */
399 *num_config
= disp
->NumConfigs
;