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
)
56 assert(GET_CONFIG_ATTRIB(conf
, EGL_CONFIG_ID
) > 0);
58 configs
= dpy
->Configs
;
59 if (dpy
->NumConfigs
>= dpy
->MaxConfigs
) {
60 EGLint new_size
= dpy
->MaxConfigs
+ 16;
61 assert(dpy
->NumConfigs
< new_size
);
63 configs
= realloc(dpy
->Configs
, new_size
* sizeof(dpy
->Configs
[0]));
65 return (EGLConfig
) NULL
;
67 dpy
->Configs
= configs
;
68 dpy
->MaxConfigs
= new_size
;
72 dpy
->Configs
[dpy
->NumConfigs
++] = conf
;
74 return (EGLConfig
) conf
;
79 _eglCheckConfigHandle(EGLConfig config
, _EGLDisplay
*dpy
)
81 EGLint num_configs
= (dpy
) ? dpy
->NumConfigs
: 0;
84 for (i
= 0; i
< num_configs
; i
++) {
85 _EGLConfig
*conf
= dpy
->Configs
[i
];
86 if (conf
== (_EGLConfig
*) config
) {
87 assert(conf
->Display
== dpy
);
91 return (i
< num_configs
);
101 ATTRIB_TYPE_PSEUDO
, /* non-queryable */
102 ATTRIB_TYPE_PLATFORM
, /* platform-dependent */
104 ATTRIB_CRITERION_EXACT
,
105 ATTRIB_CRITERION_ATLEAST
,
106 ATTRIB_CRITERION_MASK
,
107 ATTRIB_CRITERION_SPECIAL
,
108 ATTRIB_CRITERION_IGNORE
112 /* EGL spec Table 3.1 and 3.4 */
113 static const struct {
117 EGLint default_value
;
118 } _eglValidationTable
[] =
120 { EGL_BUFFER_SIZE
, ATTRIB_TYPE_INTEGER
,
121 ATTRIB_CRITERION_ATLEAST
,
123 { EGL_RED_SIZE
, ATTRIB_TYPE_INTEGER
,
124 ATTRIB_CRITERION_ATLEAST
,
126 { EGL_GREEN_SIZE
, ATTRIB_TYPE_INTEGER
,
127 ATTRIB_CRITERION_ATLEAST
,
129 { EGL_BLUE_SIZE
, ATTRIB_TYPE_INTEGER
,
130 ATTRIB_CRITERION_ATLEAST
,
132 { EGL_LUMINANCE_SIZE
, ATTRIB_TYPE_INTEGER
,
133 ATTRIB_CRITERION_ATLEAST
,
135 { EGL_ALPHA_SIZE
, ATTRIB_TYPE_INTEGER
,
136 ATTRIB_CRITERION_ATLEAST
,
138 { EGL_ALPHA_MASK_SIZE
, ATTRIB_TYPE_INTEGER
,
139 ATTRIB_CRITERION_ATLEAST
,
141 { EGL_BIND_TO_TEXTURE_RGB
, ATTRIB_TYPE_BOOLEAN
,
142 ATTRIB_CRITERION_EXACT
,
144 { EGL_BIND_TO_TEXTURE_RGBA
, ATTRIB_TYPE_BOOLEAN
,
145 ATTRIB_CRITERION_EXACT
,
147 { EGL_COLOR_BUFFER_TYPE
, ATTRIB_TYPE_ENUM
,
148 ATTRIB_CRITERION_EXACT
,
150 { EGL_CONFIG_CAVEAT
, ATTRIB_TYPE_ENUM
,
151 ATTRIB_CRITERION_EXACT
,
153 { EGL_CONFIG_ID
, ATTRIB_TYPE_INTEGER
,
154 ATTRIB_CRITERION_EXACT
,
156 { EGL_CONFORMANT
, ATTRIB_TYPE_BITMASK
,
157 ATTRIB_CRITERION_MASK
,
159 { EGL_DEPTH_SIZE
, ATTRIB_TYPE_INTEGER
,
160 ATTRIB_CRITERION_ATLEAST
,
162 { EGL_LEVEL
, ATTRIB_TYPE_PLATFORM
,
163 ATTRIB_CRITERION_EXACT
,
165 { EGL_MAX_PBUFFER_WIDTH
, ATTRIB_TYPE_INTEGER
,
166 ATTRIB_CRITERION_IGNORE
,
168 { EGL_MAX_PBUFFER_HEIGHT
, ATTRIB_TYPE_INTEGER
,
169 ATTRIB_CRITERION_IGNORE
,
171 { EGL_MAX_PBUFFER_PIXELS
, ATTRIB_TYPE_INTEGER
,
172 ATTRIB_CRITERION_IGNORE
,
174 { EGL_MAX_SWAP_INTERVAL
, ATTRIB_TYPE_INTEGER
,
175 ATTRIB_CRITERION_EXACT
,
177 { EGL_MIN_SWAP_INTERVAL
, ATTRIB_TYPE_INTEGER
,
178 ATTRIB_CRITERION_EXACT
,
180 { EGL_NATIVE_RENDERABLE
, ATTRIB_TYPE_BOOLEAN
,
181 ATTRIB_CRITERION_EXACT
,
183 { EGL_NATIVE_VISUAL_ID
, ATTRIB_TYPE_PLATFORM
,
184 ATTRIB_CRITERION_IGNORE
,
186 { EGL_NATIVE_VISUAL_TYPE
, ATTRIB_TYPE_PLATFORM
,
187 ATTRIB_CRITERION_EXACT
,
189 { EGL_RENDERABLE_TYPE
, ATTRIB_TYPE_BITMASK
,
190 ATTRIB_CRITERION_MASK
,
192 { EGL_SAMPLE_BUFFERS
, ATTRIB_TYPE_INTEGER
,
193 ATTRIB_CRITERION_ATLEAST
,
195 { EGL_SAMPLES
, ATTRIB_TYPE_INTEGER
,
196 ATTRIB_CRITERION_ATLEAST
,
198 { EGL_STENCIL_SIZE
, ATTRIB_TYPE_INTEGER
,
199 ATTRIB_CRITERION_ATLEAST
,
201 { EGL_SURFACE_TYPE
, ATTRIB_TYPE_BITMASK
,
202 ATTRIB_CRITERION_MASK
,
204 { EGL_TRANSPARENT_TYPE
, ATTRIB_TYPE_ENUM
,
205 ATTRIB_CRITERION_EXACT
,
207 { EGL_TRANSPARENT_RED_VALUE
, ATTRIB_TYPE_INTEGER
,
208 ATTRIB_CRITERION_EXACT
,
210 { EGL_TRANSPARENT_GREEN_VALUE
, ATTRIB_TYPE_INTEGER
,
211 ATTRIB_CRITERION_EXACT
,
213 { EGL_TRANSPARENT_BLUE_VALUE
, ATTRIB_TYPE_INTEGER
,
214 ATTRIB_CRITERION_EXACT
,
216 /* these are not real attributes */
217 { EGL_MATCH_NATIVE_PIXMAP
, ATTRIB_TYPE_PSEUDO
,
218 ATTRIB_CRITERION_SPECIAL
,
220 /* there is a gap before EGL_SAMPLES */
221 { 0x3030, ATTRIB_TYPE_PSEUDO
,
222 ATTRIB_CRITERION_IGNORE
,
224 { EGL_NONE
, ATTRIB_TYPE_PSEUDO
,
225 ATTRIB_CRITERION_IGNORE
,
231 * Return true if a config is valid. When for_matching is true,
232 * EGL_DONT_CARE is accepted as a valid attribute value, and checks
233 * for conflicting attribute values are skipped.
235 * Note that some attributes are platform-dependent and are not
239 _eglValidateConfig(const _EGLConfig
*conf
, EGLBoolean for_matching
)
242 EGLBoolean valid
= EGL_TRUE
;
243 EGLint red_size
= 0, green_size
= 0, blue_size
= 0, luminance_size
= 0;
244 EGLint alpha_size
= 0, buffer_size
= 0;
246 /* all attributes should have been listed */
247 assert(ARRAY_SIZE(_eglValidationTable
) == _EGL_CONFIG_NUM_ATTRIBS
);
249 /* check attributes by their types */
250 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
253 attr
= _eglValidationTable
[i
].attr
;
254 val
= GET_CONFIG_ATTRIB(conf
, attr
);
256 switch (_eglValidationTable
[i
].type
) {
257 case ATTRIB_TYPE_INTEGER
:
260 /* config id must be positive */
264 case EGL_SAMPLE_BUFFERS
:
265 /* there can be at most 1 sample buffer */
278 case EGL_LUMINANCE_SIZE
:
279 luminance_size
= val
;
284 case EGL_BUFFER_SIZE
:
291 case ATTRIB_TYPE_BOOLEAN
:
292 if (val
!= EGL_TRUE
&& val
!= EGL_FALSE
)
295 case ATTRIB_TYPE_ENUM
:
297 case EGL_CONFIG_CAVEAT
:
298 if (val
!= EGL_NONE
&& val
!= EGL_SLOW_CONFIG
&&
299 val
!= EGL_NON_CONFORMANT_CONFIG
)
302 case EGL_TRANSPARENT_TYPE
:
303 if (val
!= EGL_NONE
&& val
!= EGL_TRANSPARENT_RGB
)
306 case EGL_COLOR_BUFFER_TYPE
:
307 if (val
!= EGL_RGB_BUFFER
&& val
!= EGL_LUMINANCE_BUFFER
)
315 case ATTRIB_TYPE_BITMASK
:
317 case EGL_SURFACE_TYPE
:
318 mask
= EGL_PBUFFER_BIT
|
321 EGL_VG_COLORSPACE_LINEAR_BIT
|
322 EGL_VG_ALPHA_FORMAT_PRE_BIT
|
323 EGL_MULTISAMPLE_RESOLVE_BOX_BIT
|
324 EGL_SWAP_BEHAVIOR_PRESERVED_BIT
;
325 if (conf
->Display
->Extensions
.MESA_screen_surface
)
326 mask
|= EGL_SCREEN_BIT_MESA
;
328 case EGL_RENDERABLE_TYPE
:
330 mask
= EGL_OPENGL_ES_BIT
|
342 case ATTRIB_TYPE_PLATFORM
:
343 /* unable to check platform-dependent attributes here */
345 case ATTRIB_TYPE_PSEUDO
:
346 /* pseudo attributes should not be set */
355 if (!valid
&& for_matching
) {
356 /* accept EGL_DONT_CARE as a valid value */
357 if (val
== EGL_DONT_CARE
)
359 if (_eglValidationTable
[i
].criterion
== ATTRIB_CRITERION_SPECIAL
)
364 "attribute 0x%04x has an invalid value 0x%x", attr
, val
);
369 /* any invalid attribute value should have been catched */
370 if (!valid
|| for_matching
)
373 /* now check for conflicting attribute values */
375 switch (GET_CONFIG_ATTRIB(conf
, EGL_COLOR_BUFFER_TYPE
)) {
379 if (red_size
+ green_size
+ blue_size
+ alpha_size
!= buffer_size
)
382 case EGL_LUMINANCE_BUFFER
:
383 if (red_size
|| green_size
|| blue_size
)
385 if (luminance_size
+ alpha_size
!= buffer_size
)
390 _eglLog(_EGL_DEBUG
, "conflicting color buffer type and channel sizes");
394 val
= GET_CONFIG_ATTRIB(conf
, EGL_SAMPLE_BUFFERS
);
395 if (!val
&& GET_CONFIG_ATTRIB(conf
, EGL_SAMPLES
))
398 _eglLog(_EGL_DEBUG
, "conflicting samples and sample buffers");
402 val
= GET_CONFIG_ATTRIB(conf
, EGL_SURFACE_TYPE
);
403 if (!(val
& EGL_WINDOW_BIT
)) {
404 if (GET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_ID
) != 0 ||
405 GET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_TYPE
) != EGL_NONE
)
408 if (!(val
& EGL_PBUFFER_BIT
)) {
409 if (GET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGB
) ||
410 GET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGBA
))
414 _eglLog(_EGL_DEBUG
, "conflicting surface type and native visual/texture binding");
423 * Return true if a config matches the criteria. This and
424 * _eglParseConfigAttribList together implement the algorithm
425 * described in "Selection of EGLConfigs".
427 * Note that attributes that are special (currently, only
428 * EGL_MATCH_NATIVE_PIXMAP) are ignored.
431 _eglMatchConfig(const _EGLConfig
*conf
, const _EGLConfig
*criteria
)
434 EGLBoolean matched
= EGL_TRUE
;
436 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
438 if (_eglValidationTable
[i
].criterion
== ATTRIB_CRITERION_IGNORE
)
441 attr
= _eglValidationTable
[i
].attr
;
442 cmp
= GET_CONFIG_ATTRIB(criteria
, attr
);
443 if (cmp
== EGL_DONT_CARE
)
446 val
= GET_CONFIG_ATTRIB(conf
, attr
);
447 switch (_eglValidationTable
[i
].criterion
) {
448 case ATTRIB_CRITERION_EXACT
:
452 case ATTRIB_CRITERION_ATLEAST
:
456 case ATTRIB_CRITERION_MASK
:
457 if ((val
& cmp
) != cmp
)
460 case ATTRIB_CRITERION_SPECIAL
:
471 "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)",
483 * Initialize a criteria config from the given attribute list.
484 * Return EGL_FALSE if any of the attribute is invalid.
487 _eglParseConfigAttribList(_EGLConfig
*conf
, const EGLint
*attrib_list
)
490 EGLint config_id
= 0, level
= 0;
491 EGLBoolean has_native_visual_type
= EGL_FALSE
;
492 EGLBoolean has_transparent_color
= EGL_FALSE
;
494 /* reset to default values */
495 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
496 attr
= _eglValidationTable
[i
].attr
;
497 val
= _eglValidationTable
[i
].default_value
;
498 SET_CONFIG_ATTRIB(conf
, attr
, val
);
502 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
+= 2) {
505 attr
= attrib_list
[i
];
506 val
= attrib_list
[i
+ 1];
508 idx
= _eglIndexConfig(conf
, attr
);
511 conf
->Storage
[idx
] = val
;
513 /* rememeber some attributes for post-processing */
521 case EGL_NATIVE_VISUAL_TYPE
:
522 has_native_visual_type
= EGL_TRUE
;
524 case EGL_TRANSPARENT_RED_VALUE
:
525 case EGL_TRANSPARENT_GREEN_VALUE
:
526 case EGL_TRANSPARENT_BLUE_VALUE
:
527 has_transparent_color
= EGL_TRUE
;
534 if (!_eglValidateConfig(conf
, EGL_TRUE
))
537 /* the spec says that EGL_LEVEL cannot be EGL_DONT_CARE */
538 if (level
== EGL_DONT_CARE
)
541 /* ignore other attributes when EGL_CONFIG_ID is given */
543 _eglResetConfigKeys(conf
, EGL_DONT_CARE
);
544 SET_CONFIG_ATTRIB(conf
, EGL_CONFIG_ID
, config_id
);
547 if (has_native_visual_type
) {
548 val
= GET_CONFIG_ATTRIB(conf
, EGL_SURFACE_TYPE
);
549 if (!(val
& EGL_WINDOW_BIT
))
550 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_TYPE
, EGL_DONT_CARE
);
553 if (has_transparent_color
) {
554 val
= GET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_TYPE
);
555 if (val
== EGL_NONE
) {
556 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_RED_VALUE
,
558 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_GREEN_VALUE
,
560 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_BLUE_VALUE
,
571 * Decide the ordering of conf1 and conf2, under the given criteria.
572 * When compare_id is true, this implements the algorithm described
573 * in "Sorting of EGLConfigs". When compare_id is false,
574 * EGL_CONFIG_ID is not compared.
576 * It returns a negative integer if conf1 is considered to come
577 * before conf2; a positive integer if conf2 is considered to come
578 * before conf1; zero if the ordering cannot be decided.
580 * Note that EGL_NATIVE_VISUAL_TYPE is platform-dependent and is
584 _eglCompareConfigs(const _EGLConfig
*conf1
, const _EGLConfig
*conf2
,
585 const _EGLConfig
*criteria
, EGLBoolean compare_id
)
587 const EGLint compare_attribs
[] = {
596 EGLBoolean rgb_buffer
;
602 /* the enum values have the desired ordering */
603 assert(EGL_NONE
< EGL_SLOW_CONFIG
);
604 assert(EGL_SLOW_CONFIG
< EGL_NON_CONFORMANT_CONFIG
);
605 val1
= GET_CONFIG_ATTRIB(conf1
, EGL_CONFIG_CAVEAT
);
606 val2
= GET_CONFIG_ATTRIB(conf2
, EGL_CONFIG_CAVEAT
);
608 return (val1
- val2
);
610 /* the enum values have the desired ordering */
611 assert(EGL_RGB_BUFFER
< EGL_LUMINANCE_BUFFER
);
612 val1
= GET_CONFIG_ATTRIB(conf1
, EGL_COLOR_BUFFER_TYPE
);
613 val2
= GET_CONFIG_ATTRIB(conf2
, EGL_COLOR_BUFFER_TYPE
);
615 return (val1
- val2
);
616 rgb_buffer
= (val1
== EGL_RGB_BUFFER
);
621 if (GET_CONFIG_ATTRIB(criteria
, EGL_RED_SIZE
) > 0) {
622 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_RED_SIZE
);
623 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_RED_SIZE
);
625 if (GET_CONFIG_ATTRIB(criteria
, EGL_GREEN_SIZE
) > 0) {
626 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_GREEN_SIZE
);
627 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_GREEN_SIZE
);
629 if (GET_CONFIG_ATTRIB(criteria
, EGL_BLUE_SIZE
) > 0) {
630 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_BLUE_SIZE
);
631 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_BLUE_SIZE
);
635 if (GET_CONFIG_ATTRIB(criteria
, EGL_LUMINANCE_SIZE
) > 0) {
636 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_LUMINANCE_SIZE
);
637 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_LUMINANCE_SIZE
);
640 if (GET_CONFIG_ATTRIB(criteria
, EGL_ALPHA_SIZE
) > 0) {
641 val1
+= GET_CONFIG_ATTRIB(conf1
, EGL_ALPHA_SIZE
);
642 val2
+= GET_CONFIG_ATTRIB(conf2
, EGL_ALPHA_SIZE
);
646 /* assume the default criteria, which gives no specific ordering */
650 /* for color bits, larger one is preferred */
652 return (val2
- val1
);
654 for (i
= 0; i
< ARRAY_SIZE(compare_attribs
); i
++) {
655 val1
= GET_CONFIG_ATTRIB(conf1
, compare_attribs
[i
]);
656 val2
= GET_CONFIG_ATTRIB(conf2
, compare_attribs
[i
]);
658 return (val1
- val2
);
661 /* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
664 val1
= GET_CONFIG_ATTRIB(conf1
, EGL_CONFIG_ID
);
665 val2
= GET_CONFIG_ATTRIB(conf2
, EGL_CONFIG_ID
);
666 assert(val1
!= val2
);
672 return (val1
- val2
);
677 void _eglSwapConfigs(const _EGLConfig
**conf1
, const _EGLConfig
**conf2
)
679 const _EGLConfig
*tmp
= *conf1
;
686 * Quick sort an array of configs. This differs from the standard
687 * qsort() in that the compare function accepts an additional
691 _eglSortConfigs(const _EGLConfig
**configs
, EGLint count
,
692 EGLint (*compare
)(const _EGLConfig
*, const _EGLConfig
*,
696 const EGLint pivot
= 0;
702 _eglSwapConfigs(&configs
[pivot
], &configs
[count
/ 2]);
706 while (i
< count
&& compare(configs
[i
], configs
[pivot
], priv_data
) < 0)
708 while (compare(configs
[j
], configs
[pivot
], priv_data
) > 0)
711 _eglSwapConfigs(&configs
[i
], &configs
[j
]);
721 _eglSwapConfigs(&configs
[pivot
], &configs
[j
]);
723 _eglSortConfigs(configs
, j
, compare
, priv_data
);
724 _eglSortConfigs(configs
+ i
, count
- i
, compare
, priv_data
);
729 _eglFallbackCompare(const _EGLConfig
*conf1
, const _EGLConfig
*conf2
,
732 const _EGLConfig
*criteria
= (const _EGLConfig
*) priv_data
;
733 return _eglCompareConfigs(conf1
, conf2
, criteria
, EGL_TRUE
);
738 * Typical fallback routine for eglChooseConfig
741 _eglChooseConfig(_EGLDriver
*drv
, _EGLDisplay
*disp
, const EGLint
*attrib_list
,
742 EGLConfig
*configs
, EGLint config_size
, EGLint
*num_configs
)
744 _EGLConfig
**configList
, criteria
;
748 return _eglError(EGL_BAD_PARAMETER
, "eglChooseConfigs");
750 _eglInitConfig(&criteria
, disp
, 0);
751 if (!_eglParseConfigAttribList(&criteria
, attrib_list
))
752 return _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
754 /* allocate array of config pointers */
755 configList
= (_EGLConfig
**)
756 malloc(disp
->NumConfigs
* sizeof(_EGLConfig
*));
758 return _eglError(EGL_BAD_ALLOC
, "eglChooseConfig(out of memory)");
760 /* perform selection of configs */
762 for (i
= 0; i
< disp
->NumConfigs
; i
++) {
763 if (_eglMatchConfig(disp
->Configs
[i
], &criteria
))
764 configList
[count
++] = disp
->Configs
[i
];
767 /* perform sorting of configs */
768 if (configs
&& count
) {
769 _eglSortConfigs((const _EGLConfig
**) configList
, count
,
770 _eglFallbackCompare
, (void *) &criteria
);
771 count
= MIN2(count
, config_size
);
772 for (i
= 0; i
< count
; i
++)
773 configs
[i
] = _eglGetConfigHandle(configList
[i
]);
778 *num_configs
= count
;
784 static INLINE EGLBoolean
785 _eglIsConfigAttribValid(_EGLConfig
*conf
, EGLint attr
)
787 if (_eglIndexConfig(conf
, attr
) < 0)
790 /* there are some holes in the range */
792 case 0x3030 /* a gap before EGL_SAMPLES */:
794 #ifdef EGL_VERSION_1_4
795 case EGL_MATCH_NATIVE_PIXMAP
:
807 * Fallback for eglGetConfigAttrib.
810 _eglGetConfigAttrib(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
811 EGLint attribute
, EGLint
*value
)
813 if (!_eglIsConfigAttribValid(conf
, attribute
))
814 return _eglError(EGL_BAD_ATTRIBUTE
, "eglGetConfigAttrib");
816 return _eglError(EGL_BAD_PARAMETER
, "eglGetConfigAttrib");
818 *value
= GET_CONFIG_ATTRIB(conf
, attribute
);
824 * Fallback for eglGetConfigs.
827 _eglGetConfigs(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLConfig
*configs
,
828 EGLint config_size
, EGLint
*num_config
)
831 return _eglError(EGL_BAD_PARAMETER
, "eglGetConfigs");
835 *num_config
= MIN2(disp
->NumConfigs
, config_size
);
836 for (i
= 0; i
< *num_config
; i
++)
837 configs
[i
] = _eglGetConfigHandle(disp
->Configs
[i
]);
840 /* just return total number of supported configs */
841 *num_config
= disp
->NumConfigs
;