2 * EGL Configuration (pixel format) functions.
10 #include "egldisplay.h"
11 #include "eglcurrent.h"
15 #define MIN2(A, B) (((A) < (B)) ? (A) : (B))
19 * Init the given _EGLconfig to default values.
20 * \param id the configuration's ID.
22 * Note that id must be positive for the config to be valid.
23 * It is also recommended that when there are N configs, their
24 * IDs are from 1 to N respectively.
27 _eglInitConfig(_EGLConfig
*config
, _EGLDisplay
*dpy
, EGLint id
)
29 memset(config
, 0, sizeof(*config
));
31 config
->Display
= dpy
;
33 /* some attributes take non-zero default values */
34 SET_CONFIG_ATTRIB(config
, EGL_CONFIG_ID
, id
);
35 SET_CONFIG_ATTRIB(config
, EGL_CONFIG_CAVEAT
, EGL_NONE
);
36 SET_CONFIG_ATTRIB(config
, EGL_TRANSPARENT_TYPE
, EGL_NONE
);
37 SET_CONFIG_ATTRIB(config
, EGL_NATIVE_VISUAL_TYPE
, EGL_NONE
);
38 #ifdef EGL_VERSION_1_2
39 SET_CONFIG_ATTRIB(config
, EGL_COLOR_BUFFER_TYPE
, EGL_RGB_BUFFER
);
40 #endif /* EGL_VERSION_1_2 */
45 * Link a config to a display and return the handle of the link.
46 * The handle can be passed to client directly.
48 * Note that we just save the ptr to the config (we don't copy the config).
51 _eglAddConfig(_EGLDisplay
*dpy
, _EGLConfig
*conf
)
54 assert(GET_CONFIG_ATTRIB(conf
, EGL_CONFIG_ID
) > 0);
57 dpy
->Configs
= _eglCreateArray("Config", 16);
59 return (EGLConfig
) NULL
;
63 _eglAppendArray(dpy
->Configs
, (void *) conf
);
65 return (EGLConfig
) conf
;
70 _eglCheckConfigHandle(EGLConfig config
, _EGLDisplay
*dpy
)
74 conf
= (_EGLConfig
*) _eglFindArray(dpy
->Configs
, (void *) config
);
76 assert(conf
->Display
== dpy
);
78 return (conf
!= NULL
);
88 ATTRIB_TYPE_PSEUDO
, /* non-queryable */
89 ATTRIB_TYPE_PLATFORM
, /* platform-dependent */
91 ATTRIB_CRITERION_EXACT
,
92 ATTRIB_CRITERION_ATLEAST
,
93 ATTRIB_CRITERION_MASK
,
94 ATTRIB_CRITERION_SPECIAL
,
95 ATTRIB_CRITERION_IGNORE
99 /* EGL spec Table 3.1 and 3.4 */
100 static const struct {
104 EGLint default_value
;
105 } _eglValidationTable
[] =
107 { EGL_BUFFER_SIZE
, ATTRIB_TYPE_INTEGER
,
108 ATTRIB_CRITERION_ATLEAST
,
110 { EGL_RED_SIZE
, ATTRIB_TYPE_INTEGER
,
111 ATTRIB_CRITERION_ATLEAST
,
113 { EGL_GREEN_SIZE
, ATTRIB_TYPE_INTEGER
,
114 ATTRIB_CRITERION_ATLEAST
,
116 { EGL_BLUE_SIZE
, ATTRIB_TYPE_INTEGER
,
117 ATTRIB_CRITERION_ATLEAST
,
119 { EGL_LUMINANCE_SIZE
, ATTRIB_TYPE_INTEGER
,
120 ATTRIB_CRITERION_ATLEAST
,
122 { EGL_ALPHA_SIZE
, ATTRIB_TYPE_INTEGER
,
123 ATTRIB_CRITERION_ATLEAST
,
125 { EGL_ALPHA_MASK_SIZE
, ATTRIB_TYPE_INTEGER
,
126 ATTRIB_CRITERION_ATLEAST
,
128 { EGL_BIND_TO_TEXTURE_RGB
, ATTRIB_TYPE_BOOLEAN
,
129 ATTRIB_CRITERION_EXACT
,
131 { EGL_BIND_TO_TEXTURE_RGBA
, ATTRIB_TYPE_BOOLEAN
,
132 ATTRIB_CRITERION_EXACT
,
134 { EGL_COLOR_BUFFER_TYPE
, ATTRIB_TYPE_ENUM
,
135 ATTRIB_CRITERION_EXACT
,
137 { EGL_CONFIG_CAVEAT
, ATTRIB_TYPE_ENUM
,
138 ATTRIB_CRITERION_EXACT
,
140 { EGL_CONFIG_ID
, ATTRIB_TYPE_INTEGER
,
141 ATTRIB_CRITERION_EXACT
,
143 { EGL_CONFORMANT
, ATTRIB_TYPE_BITMASK
,
144 ATTRIB_CRITERION_MASK
,
146 { EGL_DEPTH_SIZE
, ATTRIB_TYPE_INTEGER
,
147 ATTRIB_CRITERION_ATLEAST
,
149 { EGL_LEVEL
, ATTRIB_TYPE_PLATFORM
,
150 ATTRIB_CRITERION_EXACT
,
152 { EGL_MAX_PBUFFER_WIDTH
, ATTRIB_TYPE_INTEGER
,
153 ATTRIB_CRITERION_IGNORE
,
155 { EGL_MAX_PBUFFER_HEIGHT
, ATTRIB_TYPE_INTEGER
,
156 ATTRIB_CRITERION_IGNORE
,
158 { EGL_MAX_PBUFFER_PIXELS
, ATTRIB_TYPE_INTEGER
,
159 ATTRIB_CRITERION_IGNORE
,
161 { EGL_MAX_SWAP_INTERVAL
, ATTRIB_TYPE_INTEGER
,
162 ATTRIB_CRITERION_EXACT
,
164 { EGL_MIN_SWAP_INTERVAL
, ATTRIB_TYPE_INTEGER
,
165 ATTRIB_CRITERION_EXACT
,
167 { EGL_NATIVE_RENDERABLE
, ATTRIB_TYPE_BOOLEAN
,
168 ATTRIB_CRITERION_EXACT
,
170 { EGL_NATIVE_VISUAL_ID
, ATTRIB_TYPE_PLATFORM
,
171 ATTRIB_CRITERION_IGNORE
,
173 { EGL_NATIVE_VISUAL_TYPE
, ATTRIB_TYPE_PLATFORM
,
174 ATTRIB_CRITERION_EXACT
,
176 { EGL_RENDERABLE_TYPE
, ATTRIB_TYPE_BITMASK
,
177 ATTRIB_CRITERION_MASK
,
179 { EGL_SAMPLE_BUFFERS
, ATTRIB_TYPE_INTEGER
,
180 ATTRIB_CRITERION_ATLEAST
,
182 { EGL_SAMPLES
, ATTRIB_TYPE_INTEGER
,
183 ATTRIB_CRITERION_ATLEAST
,
185 { EGL_STENCIL_SIZE
, ATTRIB_TYPE_INTEGER
,
186 ATTRIB_CRITERION_ATLEAST
,
188 { EGL_SURFACE_TYPE
, ATTRIB_TYPE_BITMASK
,
189 ATTRIB_CRITERION_MASK
,
191 { EGL_TRANSPARENT_TYPE
, ATTRIB_TYPE_ENUM
,
192 ATTRIB_CRITERION_EXACT
,
194 { EGL_TRANSPARENT_RED_VALUE
, ATTRIB_TYPE_INTEGER
,
195 ATTRIB_CRITERION_EXACT
,
197 { EGL_TRANSPARENT_GREEN_VALUE
, ATTRIB_TYPE_INTEGER
,
198 ATTRIB_CRITERION_EXACT
,
200 { EGL_TRANSPARENT_BLUE_VALUE
, ATTRIB_TYPE_INTEGER
,
201 ATTRIB_CRITERION_EXACT
,
203 /* these are not real attributes */
204 { EGL_MATCH_NATIVE_PIXMAP
, ATTRIB_TYPE_PSEUDO
,
205 ATTRIB_CRITERION_SPECIAL
,
207 /* there is a gap before EGL_SAMPLES */
208 { 0x3030, ATTRIB_TYPE_PSEUDO
,
209 ATTRIB_CRITERION_IGNORE
,
211 { EGL_NONE
, ATTRIB_TYPE_PSEUDO
,
212 ATTRIB_CRITERION_IGNORE
,
215 { EGL_Y_INVERTED_NOK
, ATTRIB_TYPE_BOOLEAN
,
216 ATTRIB_CRITERION_EXACT
,
223 * Return true if a config is valid. When for_matching is true,
224 * EGL_DONT_CARE is accepted as a valid attribute value, and checks
225 * for conflicting attribute values are skipped.
227 * Note that some attributes are platform-dependent and are not
231 _eglValidateConfig(const _EGLConfig
*conf
, EGLBoolean for_matching
)
234 EGLBoolean valid
= EGL_TRUE
;
235 EGLint red_size
= 0, green_size
= 0, blue_size
= 0, luminance_size
= 0;
236 EGLint alpha_size
= 0, buffer_size
= 0;
238 /* all attributes should have been listed */
239 assert(ARRAY_SIZE(_eglValidationTable
) == _EGL_CONFIG_NUM_ATTRIBS
);
241 /* check attributes by their types */
242 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
245 attr
= _eglValidationTable
[i
].attr
;
246 val
= GET_CONFIG_ATTRIB(conf
, attr
);
248 switch (_eglValidationTable
[i
].type
) {
249 case ATTRIB_TYPE_INTEGER
:
252 /* config id must be positive */
256 case EGL_SAMPLE_BUFFERS
:
257 /* there can be at most 1 sample buffer */
270 case EGL_LUMINANCE_SIZE
:
271 luminance_size
= val
;
276 case EGL_BUFFER_SIZE
:
283 case ATTRIB_TYPE_BOOLEAN
:
284 if (val
!= EGL_TRUE
&& val
!= EGL_FALSE
)
287 case ATTRIB_TYPE_ENUM
:
289 case EGL_CONFIG_CAVEAT
:
290 if (val
!= EGL_NONE
&& val
!= EGL_SLOW_CONFIG
&&
291 val
!= EGL_NON_CONFORMANT_CONFIG
)
294 case EGL_TRANSPARENT_TYPE
:
295 if (val
!= EGL_NONE
&& val
!= EGL_TRANSPARENT_RGB
)
298 case EGL_COLOR_BUFFER_TYPE
:
299 if (val
!= EGL_RGB_BUFFER
&& val
!= EGL_LUMINANCE_BUFFER
)
307 case ATTRIB_TYPE_BITMASK
:
309 case EGL_SURFACE_TYPE
:
310 mask
= EGL_PBUFFER_BIT
|
313 EGL_VG_COLORSPACE_LINEAR_BIT
|
314 EGL_VG_ALPHA_FORMAT_PRE_BIT
|
315 EGL_MULTISAMPLE_RESOLVE_BOX_BIT
|
316 EGL_SWAP_BEHAVIOR_PRESERVED_BIT
;
317 #ifdef EGL_MESA_screen_surface
318 if (conf
->Display
->Extensions
.MESA_screen_surface
)
319 mask
|= EGL_SCREEN_BIT_MESA
;
322 case EGL_RENDERABLE_TYPE
:
324 mask
= EGL_OPENGL_ES_BIT
|
336 case ATTRIB_TYPE_PLATFORM
:
337 /* unable to check platform-dependent attributes here */
339 case ATTRIB_TYPE_PSEUDO
:
340 /* pseudo attributes should not be set */
349 if (!valid
&& for_matching
) {
350 /* accept EGL_DONT_CARE as a valid value */
351 if (val
== EGL_DONT_CARE
)
353 if (_eglValidationTable
[i
].criterion
== ATTRIB_CRITERION_SPECIAL
)
358 "attribute 0x%04x has an invalid value 0x%x", attr
, val
);
363 /* any invalid attribute value should have been catched */
364 if (!valid
|| for_matching
)
367 /* now check for conflicting attribute values */
369 switch (GET_CONFIG_ATTRIB(conf
, EGL_COLOR_BUFFER_TYPE
)) {
373 if (red_size
+ green_size
+ blue_size
+ alpha_size
!= buffer_size
)
376 case EGL_LUMINANCE_BUFFER
:
377 if (red_size
|| green_size
|| blue_size
)
379 if (luminance_size
+ alpha_size
!= buffer_size
)
384 _eglLog(_EGL_DEBUG
, "conflicting color buffer type and channel sizes");
388 val
= GET_CONFIG_ATTRIB(conf
, EGL_SAMPLE_BUFFERS
);
389 if (!val
&& GET_CONFIG_ATTRIB(conf
, EGL_SAMPLES
))
392 _eglLog(_EGL_DEBUG
, "conflicting samples and sample buffers");
396 val
= GET_CONFIG_ATTRIB(conf
, EGL_SURFACE_TYPE
);
397 if (!(val
& EGL_WINDOW_BIT
)) {
398 if (GET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_ID
) != 0 ||
399 GET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_TYPE
) != EGL_NONE
)
402 if (!(val
& EGL_PBUFFER_BIT
)) {
403 if (GET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGB
) ||
404 GET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGBA
))
408 _eglLog(_EGL_DEBUG
, "conflicting surface type and native visual/texture binding");
417 * Return true if a config matches the criteria. This and
418 * _eglParseConfigAttribList together implement the algorithm
419 * described in "Selection of EGLConfigs".
421 * Note that attributes that are special (currently, only
422 * EGL_MATCH_NATIVE_PIXMAP) are ignored.
425 _eglMatchConfig(const _EGLConfig
*conf
, const _EGLConfig
*criteria
)
428 EGLBoolean matched
= EGL_TRUE
;
430 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
432 if (_eglValidationTable
[i
].criterion
== ATTRIB_CRITERION_IGNORE
)
435 attr
= _eglValidationTable
[i
].attr
;
436 cmp
= GET_CONFIG_ATTRIB(criteria
, attr
);
437 if (cmp
== EGL_DONT_CARE
)
440 val
= GET_CONFIG_ATTRIB(conf
, attr
);
441 switch (_eglValidationTable
[i
].criterion
) {
442 case ATTRIB_CRITERION_EXACT
:
446 case ATTRIB_CRITERION_ATLEAST
:
450 case ATTRIB_CRITERION_MASK
:
451 if ((val
& cmp
) != cmp
)
454 case ATTRIB_CRITERION_SPECIAL
:
464 /* only print the common errors when DEBUG is not defined */
465 if (attr
!= EGL_RENDERABLE_TYPE
)
469 "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)",
478 static INLINE EGLBoolean
479 _eglIsConfigAttribValid(_EGLConfig
*conf
, EGLint attr
)
481 if (_eglIndexConfig(conf
, attr
) < 0)
484 /* there are some holes in the range */
486 case 0x3030 /* a gap before EGL_SAMPLES */:
488 #ifdef EGL_VERSION_1_4
489 case EGL_MATCH_NATIVE_PIXMAP
:
492 case EGL_Y_INVERTED_NOK
:
493 return conf
->Display
->Extensions
.NOK_texture_from_pixmap
;
502 * Initialize a criteria config from the given attribute list.
503 * Return EGL_FALSE if any of the attribute is invalid.
506 _eglParseConfigAttribList(_EGLConfig
*conf
, const EGLint
*attrib_list
)
509 EGLint config_id
= 0, level
= 0;
510 EGLBoolean has_native_visual_type
= EGL_FALSE
;
511 EGLBoolean has_transparent_color
= EGL_FALSE
;
513 /* reset to default values */
514 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
515 attr
= _eglValidationTable
[i
].attr
;
516 val
= _eglValidationTable
[i
].default_value
;
517 SET_CONFIG_ATTRIB(conf
, attr
, val
);
521 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
+= 2) {
522 attr
= attrib_list
[i
];
523 val
= attrib_list
[i
+ 1];
525 if (!_eglIsConfigAttribValid(conf
, attr
))
528 SET_CONFIG_ATTRIB(conf
, attr
, val
);
530 /* rememeber some attributes for post-processing */
538 case EGL_NATIVE_VISUAL_TYPE
:
539 has_native_visual_type
= EGL_TRUE
;
541 case EGL_TRANSPARENT_RED_VALUE
:
542 case EGL_TRANSPARENT_GREEN_VALUE
:
543 case EGL_TRANSPARENT_BLUE_VALUE
:
544 has_transparent_color
= EGL_TRUE
;
551 if (!_eglValidateConfig(conf
, EGL_TRUE
))
554 /* the spec says that EGL_LEVEL cannot be EGL_DONT_CARE */
555 if (level
== EGL_DONT_CARE
)
558 /* ignore other attributes when EGL_CONFIG_ID is given */
560 _eglResetConfigKeys(conf
, EGL_DONT_CARE
);
561 SET_CONFIG_ATTRIB(conf
, EGL_CONFIG_ID
, config_id
);
564 if (has_native_visual_type
) {
565 val
= GET_CONFIG_ATTRIB(conf
, EGL_SURFACE_TYPE
);
566 if (!(val
& EGL_WINDOW_BIT
))
567 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_TYPE
, EGL_DONT_CARE
);
570 if (has_transparent_color
) {
571 val
= GET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_TYPE
);
572 if (val
== EGL_NONE
) {
573 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_RED_VALUE
,
575 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_GREEN_VALUE
,
577 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_BLUE_VALUE
,
588 * Decide the ordering of conf1 and conf2, under the given criteria.
589 * When compare_id is true, this implements the algorithm described
590 * in "Sorting of EGLConfigs". When compare_id is false,
591 * EGL_CONFIG_ID is not compared.
593 * It returns a negative integer if conf1 is considered to come
594 * before conf2; a positive integer if conf2 is considered to come
595 * before conf1; zero if the ordering cannot be decided.
597 * Note that EGL_NATIVE_VISUAL_TYPE is platform-dependent and is
601 _eglCompareConfigs(const _EGLConfig
*conf1
, const _EGLConfig
*conf2
,
602 const _EGLConfig
*criteria
, EGLBoolean compare_id
)
604 const EGLint compare_attribs
[] = {
613 EGLBoolean rgb_buffer
;
619 /* the enum values have the desired ordering */
620 assert(EGL_NONE
< EGL_SLOW_CONFIG
);
621 assert(EGL_SLOW_CONFIG
< EGL_NON_CONFORMANT_CONFIG
);
622 val1
= GET_CONFIG_ATTRIB(conf1
, EGL_CONFIG_CAVEAT
);
623 val2
= GET_CONFIG_ATTRIB(conf2
, EGL_CONFIG_CAVEAT
);
625 return (val1
- val2
);
627 /* the enum values have the desired ordering */
628 assert(EGL_RGB_BUFFER
< EGL_LUMINANCE_BUFFER
);
629 val1
= GET_CONFIG_ATTRIB(conf1
, EGL_COLOR_BUFFER_TYPE
);
630 val2
= GET_CONFIG_ATTRIB(conf2
, EGL_COLOR_BUFFER_TYPE
);
632 return (val1
- val2
);
633 rgb_buffer
= (val1
== EGL_RGB_BUFFER
);
638 if (GET_CONFIG_ATTRIB(criteria
, EGL_RED_SIZE
) > 0) {
639 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_RED_SIZE
);
640 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_RED_SIZE
);
642 if (GET_CONFIG_ATTRIB(criteria
, EGL_GREEN_SIZE
) > 0) {
643 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_GREEN_SIZE
);
644 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_GREEN_SIZE
);
646 if (GET_CONFIG_ATTRIB(criteria
, EGL_BLUE_SIZE
) > 0) {
647 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_BLUE_SIZE
);
648 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_BLUE_SIZE
);
652 if (GET_CONFIG_ATTRIB(criteria
, EGL_LUMINANCE_SIZE
) > 0) {
653 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_LUMINANCE_SIZE
);
654 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_LUMINANCE_SIZE
);
657 if (GET_CONFIG_ATTRIB(criteria
, EGL_ALPHA_SIZE
) > 0) {
658 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_ALPHA_SIZE
);
659 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_ALPHA_SIZE
);
663 /* assume the default criteria, which gives no specific ordering */
667 /* for color bits, larger one is preferred */
669 return (val2
- val1
);
671 for (i
= 0; i
< ARRAY_SIZE(compare_attribs
); i
++) {
672 val1
= GET_CONFIG_ATTRIB(conf1
, compare_attribs
[i
]);
673 val2
= GET_CONFIG_ATTRIB(conf2
, compare_attribs
[i
]);
675 return (val1
- val2
);
678 /* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
681 val1
= GET_CONFIG_ATTRIB(conf1
, EGL_CONFIG_ID
);
682 val2
= GET_CONFIG_ATTRIB(conf2
, EGL_CONFIG_ID
);
683 assert(val1
!= val2
);
689 return (val1
- val2
);
694 void _eglSwapConfigs(const _EGLConfig
**conf1
, const _EGLConfig
**conf2
)
696 const _EGLConfig
*tmp
= *conf1
;
703 * Quick sort an array of configs. This differs from the standard
704 * qsort() in that the compare function accepts an additional
708 _eglSortConfigs(const _EGLConfig
**configs
, EGLint count
,
709 EGLint (*compare
)(const _EGLConfig
*, const _EGLConfig
*,
713 const EGLint pivot
= 0;
719 _eglSwapConfigs(&configs
[pivot
], &configs
[count
/ 2]);
723 while (i
< count
&& compare(configs
[i
], configs
[pivot
], priv_data
) < 0)
725 while (compare(configs
[j
], configs
[pivot
], priv_data
) > 0)
728 _eglSwapConfigs(&configs
[i
], &configs
[j
]);
738 _eglSwapConfigs(&configs
[pivot
], &configs
[j
]);
740 _eglSortConfigs(configs
, j
, compare
, priv_data
);
741 _eglSortConfigs(configs
+ i
, count
- i
, compare
, priv_data
);
746 _eglFallbackCompare(const _EGLConfig
*conf1
, const _EGLConfig
*conf2
,
749 const _EGLConfig
*criteria
= (const _EGLConfig
*) priv_data
;
750 return _eglCompareConfigs(conf1
, conf2
, criteria
, EGL_TRUE
);
755 * Typical fallback routine for eglChooseConfig
758 _eglChooseConfig(_EGLDriver
*drv
, _EGLDisplay
*disp
, const EGLint
*attrib_list
,
759 EGLConfig
*configs
, EGLint config_size
, EGLint
*num_configs
)
761 _EGLConfig
**configList
, criteria
;
765 return _eglError(EGL_BAD_PARAMETER
, "eglChooseConfigs");
767 _eglInitConfig(&criteria
, disp
, 0);
768 if (!_eglParseConfigAttribList(&criteria
, attrib_list
))
769 return _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
771 configList
= (_EGLConfig
**) _eglFilterArray(disp
->Configs
, &count
,
772 (_EGLArrayForEach
) _eglMatchConfig
, (void *) &criteria
);
774 return _eglError(EGL_BAD_ALLOC
, "eglChooseConfig(out of memory)");
776 /* perform sorting of configs */
777 if (configs
&& count
) {
778 _eglSortConfigs((const _EGLConfig
**) configList
, count
,
779 _eglFallbackCompare
, (void *) &criteria
);
780 count
= MIN2(count
, config_size
);
781 for (i
= 0; i
< count
; i
++)
782 configs
[i
] = _eglGetConfigHandle(configList
[i
]);
787 *num_configs
= count
;
794 * Fallback for eglGetConfigAttrib.
797 _eglGetConfigAttrib(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
798 EGLint attribute
, EGLint
*value
)
800 if (!_eglIsConfigAttribValid(conf
, attribute
))
801 return _eglError(EGL_BAD_ATTRIBUTE
, "eglGetConfigAttrib");
803 return _eglError(EGL_BAD_PARAMETER
, "eglGetConfigAttrib");
805 *value
= GET_CONFIG_ATTRIB(conf
, attribute
);
811 _eglFlattenConfig(void *elem
, void *buffer
)
813 _EGLConfig
*conf
= (_EGLConfig
*) elem
;
814 EGLConfig
*handle
= (EGLConfig
*) buffer
;
815 *handle
= _eglGetConfigHandle(conf
);
820 * Fallback for eglGetConfigs.
823 _eglGetConfigs(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLConfig
*configs
,
824 EGLint config_size
, EGLint
*num_config
)
827 return _eglError(EGL_BAD_PARAMETER
, "eglGetConfigs");
829 *num_config
= _eglFlattenArray(disp
->Configs
, (void *) configs
,
830 sizeof(configs
[0]), config_size
, _eglFlattenConfig
);