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
) 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
,
47 EGL_SCREEN_BIT_MESA
| EGL_PBUFFER_BIT
|
48 EGL_PIXMAP_BIT
| EGL_WINDOW_BIT
);
49 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_TYPE
, EGL_NONE
);
50 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_RED_VALUE
, EGL_DONT_CARE
);
51 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_GREEN_VALUE
, EGL_DONT_CARE
);
52 _eglSetConfigAttrib(config
, EGL_TRANSPARENT_BLUE_VALUE
, EGL_DONT_CARE
);
53 #ifdef EGL_VERSION_1_2
54 _eglSetConfigAttrib(config
, EGL_COLOR_BUFFER_TYPE
, EGL_RGB_BUFFER
);
55 _eglSetConfigAttrib(config
, EGL_RENDERABLE_TYPE
, EGL_OPENGL_ES_BIT
);
56 #endif /* EGL_VERSION_1_2 */
61 * Return the public handle for an internal _EGLConfig.
62 * This is the inverse of _eglLookupConfig().
65 _eglGetConfigHandle(_EGLConfig
*config
)
67 return config
? config
->Handle
: 0;
72 * Given an EGLConfig handle, return the corresponding _EGLConfig object.
73 * This is the inverse of _eglGetConfigHandle().
76 _eglLookupConfig(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
)
79 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
80 for (i
= 0; i
< disp
->NumConfigs
; i
++) {
81 if (disp
->Configs
[i
]->Handle
== config
) {
82 return disp
->Configs
[i
];
90 * Add the given _EGLConfig to the given display.
91 * Note that we just save the ptr to the config (we don't copy the config).
94 _eglAddConfig(_EGLDisplay
*display
, _EGLConfig
*config
)
96 _EGLConfig
**newConfigs
;
99 n
= display
->NumConfigs
;
101 /* realloc array of ptrs */
102 newConfigs
= (_EGLConfig
**) realloc(display
->Configs
,
103 (n
+ 1) * sizeof(_EGLConfig
*));
105 display
->Configs
= newConfigs
;
106 display
->Configs
[n
] = config
;
107 display
->NumConfigs
++;
117 * Parse the attrib_list to fill in the fields of the given _eglConfig
118 * Return EGL_FALSE if any errors, EGL_TRUE otherwise.
121 _eglParseConfigAttribs(_EGLConfig
*config
, const EGLint
*attrib_list
)
125 /* set all config attribs to EGL_DONT_CARE */
126 for (i
= 0; i
< MAX_ATTRIBS
; i
++) {
127 config
->Attrib
[i
] = EGL_DONT_CARE
;
130 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
131 const EGLint attr
= attrib_list
[i
];
132 if (attr
>= EGL_BUFFER_SIZE
&&
133 attr
<= EGL_MAX_SWAP_INTERVAL
) {
134 EGLint k
= attr
- FIRST_ATTRIB
;
136 assert(k
< MAX_ATTRIBS
);
137 config
->Attrib
[k
] = attrib_list
[++i
];
139 #ifdef EGL_VERSION_1_2
140 else if (attr
== EGL_COLOR_BUFFER_TYPE
) {
141 EGLint bufType
= attrib_list
[++i
];
142 if (bufType
!= EGL_RGB_BUFFER
&& bufType
!= EGL_LUMINANCE_BUFFER
) {
143 _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
146 _eglSetConfigAttrib(config
, EGL_COLOR_BUFFER_TYPE
, bufType
);
148 else if (attr
== EGL_RENDERABLE_TYPE
) {
149 EGLint renType
= attrib_list
[++i
];
150 if (renType
& ~(EGL_OPENGL_ES_BIT
| EGL_OPENVG_BIT
)) {
151 _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
154 _eglSetConfigAttrib(config
, EGL_RENDERABLE_TYPE
, renType
);
156 else if (attr
== EGL_ALPHA_MASK_SIZE
||
157 attr
== EGL_LUMINANCE_SIZE
) {
158 EGLint value
= attrib_list
[++i
];
159 _eglSetConfigAttrib(config
, attr
, value
);
161 #endif /* EGL_VERSION_1_2 */
163 _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
180 EGLint MatchCriteria
;
184 /* This encodes the info from Table 3.5 of the EGL spec, ordered by
187 * XXX To do: EGL 1.2 attribs
189 static struct sort_info SortInfo
[] = {
190 { EGL_CONFIG_CAVEAT
, EXACT
, SPECIAL
},
191 { EGL_RED_SIZE
, ATLEAST
, SPECIAL
},
192 { EGL_GREEN_SIZE
, ATLEAST
, SPECIAL
},
193 { EGL_BLUE_SIZE
, ATLEAST
, SPECIAL
},
194 { EGL_ALPHA_SIZE
, ATLEAST
, SPECIAL
},
195 { EGL_BUFFER_SIZE
, ATLEAST
, SMALLER
},
196 { EGL_SAMPLE_BUFFERS
, ATLEAST
, SMALLER
},
197 { EGL_SAMPLES
, ATLEAST
, SMALLER
},
198 { EGL_DEPTH_SIZE
, ATLEAST
, SMALLER
},
199 { EGL_STENCIL_SIZE
, ATLEAST
, SMALLER
},
200 { EGL_NATIVE_VISUAL_TYPE
, EXACT
, SPECIAL
},
201 { EGL_CONFIG_ID
, EXACT
, SMALLER
},
202 { EGL_BIND_TO_TEXTURE_RGB
, EXACT
, NONE
},
203 { EGL_BIND_TO_TEXTURE_RGBA
, EXACT
, NONE
},
204 { EGL_LEVEL
, EXACT
, NONE
},
205 { EGL_NATIVE_RENDERABLE
, EXACT
, NONE
},
206 { EGL_MAX_SWAP_INTERVAL
, EXACT
, NONE
},
207 { EGL_MIN_SWAP_INTERVAL
, EXACT
, NONE
},
208 { EGL_SURFACE_TYPE
, MASK
, NONE
},
209 { EGL_TRANSPARENT_TYPE
, EXACT
, NONE
},
210 { EGL_TRANSPARENT_RED_VALUE
, EXACT
, NONE
},
211 { EGL_TRANSPARENT_GREEN_VALUE
, EXACT
, NONE
},
212 { EGL_TRANSPARENT_BLUE_VALUE
, EXACT
, NONE
},
218 * Return EGL_TRUE if the attributes of c meet or exceed the minimums
222 _eglConfigQualifies(const _EGLConfig
*c
, const _EGLConfig
*min
)
225 for (i
= 0; SortInfo
[i
].Attribute
!= 0; i
++) {
226 const EGLint mv
= GET_CONFIG_ATTRIB(min
, SortInfo
[i
].Attribute
);
227 if (mv
!= EGL_DONT_CARE
) {
228 const EGLint cv
= GET_CONFIG_ATTRIB(c
, SortInfo
[i
].Attribute
);
229 if (SortInfo
[i
].MatchCriteria
== EXACT
) {
234 else if (SortInfo
[i
].MatchCriteria
== ATLEAST
) {
240 assert(SortInfo
[i
].MatchCriteria
== MASK
);
241 if ((mv
& cv
) != mv
) {
252 * Compare configs 'a' and 'b' and return -1 if a belongs before b,
253 * 1 if a belongs after b, or 0 if they're equal.
257 _eglCompareConfigs(const void *a
, const void *b
)
259 const _EGLConfig
*aConfig
= (const _EGLConfig
*) a
;
260 const _EGLConfig
*bConfig
= (const _EGLConfig
*) b
;
263 for (i
= 0; SortInfo
[i
].Attribute
!= 0; i
++) {
264 const EGLint aVal
= GET_CONFIG_ATTRIB(aConfig
, SortInfo
[i
].Attribute
);
265 const EGLint bVal
= GET_CONFIG_ATTRIB(bConfig
, SortInfo
[i
].Attribute
);
266 if (SortInfo
[i
].SortOrder
== SMALLER
) {
269 else if (aVal
> bVal
)
271 /* else, continue examining attribute values */
273 else if (SortInfo
[i
].SortOrder
== SPECIAL
) {
274 if (SortInfo
[i
].Attribute
== EGL_CONFIG_CAVEAT
) {
275 /* values are EGL_NONE, SLOW_CONFIG, or NON_CONFORMANT_CONFIG */
278 else if (aVal
> bVal
)
281 else if (SortInfo
[i
].Attribute
== EGL_RED_SIZE
||
282 SortInfo
[i
].Attribute
== EGL_GREEN_SIZE
||
283 SortInfo
[i
].Attribute
== EGL_BLUE_SIZE
||
284 SortInfo
[i
].Attribute
== EGL_ALPHA_SIZE
) {
287 else if (aVal
< bVal
)
291 assert(SortInfo
[i
].Attribute
== EGL_NATIVE_VISUAL_TYPE
);
294 else if (aVal
> bVal
)
299 assert(SortInfo
[i
].SortOrder
== NONE
);
300 /* continue examining attribute values */
304 /* all attributes identical */
310 * Typical fallback routine for eglChooseConfig
313 _eglChooseConfig(_EGLDriver
*drv
, EGLDisplay dpy
, const EGLint
*attrib_list
,
314 EGLConfig
*configs
, EGLint config_size
, EGLint
*num_configs
)
316 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
317 _EGLConfig
**configList
, criteria
;
320 /* parse the attrib_list to initialize criteria */
321 if (!_eglParseConfigAttribs(&criteria
, attrib_list
)) {
325 /* allocate array of config pointers */
326 configList
= (_EGLConfig
**) malloc(config_size
* sizeof(_EGLConfig
*));
328 _eglError(EGL_BAD_CONFIG
, "eglChooseConfig(out of memory)");
332 /* make array of pointers to qualifying configs */
333 for (i
= count
= 0; i
< disp
->NumConfigs
&& count
< config_size
; i
++) {
334 if (_eglConfigQualifies(disp
->Configs
[i
], &criteria
)) {
335 configList
[count
++] = disp
->Configs
[i
];
339 /* sort array of pointers */
340 qsort(configList
, count
, sizeof(_EGLConfig
*), _eglCompareConfigs
);
342 /* copy config handles to output array */
344 for (i
= 0; i
< count
; i
++) {
345 configs
[i
] = configList
[i
]->Handle
;
351 *num_configs
= count
;
358 * Fallback for eglGetConfigAttrib.
361 _eglGetConfigAttrib(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
362 EGLint attribute
, EGLint
*value
)
364 const _EGLConfig
*conf
= _eglLookupConfig(drv
, dpy
, config
);
365 const EGLint k
= attribute
- FIRST_ATTRIB
;
366 if (k
>= 0 && k
< MAX_ATTRIBS
) {
367 *value
= conf
->Attrib
[k
];
371 _eglError(EGL_BAD_ATTRIBUTE
, "eglGetConfigAttrib");
378 * Fallback for eglGetConfigs.
381 _eglGetConfigs(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig
*configs
,
382 EGLint config_size
, EGLint
*num_config
)
384 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
386 if (!drv
->Initialized
) {
387 _eglError(EGL_NOT_INITIALIZED
, "eglGetConfigs");
393 *num_config
= MIN2(disp
->NumConfigs
, config_size
);
394 for (i
= 0; i
< *num_config
; i
++) {
395 configs
[i
] = disp
->Configs
[i
]->Handle
;
399 /* just return total number of supported configs */
400 *num_config
= disp
->NumConfigs
;