1 /**************************************************************************
3 * Copyright 2008 VMware, Inc.
4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010-2011 LunarG, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * EGL Configuration (pixel format) functions.
39 #include "c99_compat.h"
40 #include "util/macros.h"
42 #include "eglconfig.h"
43 #include "egldisplay.h"
44 #include "eglcurrent.h"
51 * Init the given _EGLconfig to default values.
52 * \param id the configuration's ID.
54 * Note that id must be positive for the config to be valid.
55 * It is also recommended that when there are N configs, their
56 * IDs are from 1 to N respectively.
59 _eglInitConfig(_EGLConfig
*conf
, _EGLDisplay
*disp
, EGLint id
)
61 memset(conf
, 0, sizeof(*conf
));
65 /* some attributes take non-zero default values */
67 conf
->ConfigCaveat
= EGL_NONE
;
68 conf
->TransparentType
= EGL_NONE
;
69 conf
->NativeVisualType
= EGL_NONE
;
70 conf
->ColorBufferType
= EGL_RGB_BUFFER
;
71 conf
->ComponentType
= EGL_COLOR_COMPONENT_TYPE_FIXED_EXT
;
75 * Wipe the configs list and return the old list
78 _eglWipeConfigs(_EGLDisplay
*disp
)
80 _EGLArray
*configs
= disp
->Configs
;
86 * Link a config to its display and return the handle of the link.
87 * The handle can be passed to client directly.
89 * Note that we just save the ptr to the config (we don't copy the config).
92 _eglLinkConfig(_EGLConfig
*conf
)
94 _EGLDisplay
*disp
= conf
->Display
;
98 assert(conf
->ConfigID
> 0);
100 if (!disp
->Configs
) {
101 disp
->Configs
= _eglCreateArray("Config", 16);
103 return (EGLConfig
) NULL
;
106 _eglAppendArray(disp
->Configs
, (void *) conf
);
108 return (EGLConfig
) conf
;
113 * Lookup a handle to find the linked config.
114 * Return NULL if the handle has no corresponding linked config.
117 _eglLookupConfig(EGLConfig config
, _EGLDisplay
*disp
)
124 conf
= (_EGLConfig
*) _eglFindArray(disp
->Configs
, (void *) config
);
126 assert(conf
->Display
== disp
);
137 ATTRIB_TYPE_PSEUDO
, /* non-queryable */
138 ATTRIB_TYPE_PLATFORM
, /* platform-dependent */
142 ATTRIB_CRITERION_EXACT
,
143 ATTRIB_CRITERION_ATLEAST
,
144 ATTRIB_CRITERION_MASK
,
145 ATTRIB_CRITERION_SPECIAL
,
146 ATTRIB_CRITERION_IGNORE
150 /* EGL spec Table 3.1 and 3.4 */
151 static const struct {
154 enum criterion criterion
;
155 EGLint default_value
;
156 } _eglValidationTable
[] =
159 { EGL_BUFFER_SIZE
, ATTRIB_TYPE_INTEGER
,
160 ATTRIB_CRITERION_ATLEAST
,
162 { EGL_RED_SIZE
, ATTRIB_TYPE_INTEGER
,
163 ATTRIB_CRITERION_ATLEAST
,
165 { EGL_GREEN_SIZE
, ATTRIB_TYPE_INTEGER
,
166 ATTRIB_CRITERION_ATLEAST
,
168 { EGL_BLUE_SIZE
, ATTRIB_TYPE_INTEGER
,
169 ATTRIB_CRITERION_ATLEAST
,
171 { EGL_LUMINANCE_SIZE
, ATTRIB_TYPE_INTEGER
,
172 ATTRIB_CRITERION_ATLEAST
,
174 { EGL_ALPHA_SIZE
, ATTRIB_TYPE_INTEGER
,
175 ATTRIB_CRITERION_ATLEAST
,
177 { EGL_ALPHA_MASK_SIZE
, ATTRIB_TYPE_INTEGER
,
178 ATTRIB_CRITERION_ATLEAST
,
180 { EGL_BIND_TO_TEXTURE_RGB
, ATTRIB_TYPE_BOOLEAN
,
181 ATTRIB_CRITERION_EXACT
,
183 { EGL_BIND_TO_TEXTURE_RGBA
, ATTRIB_TYPE_BOOLEAN
,
184 ATTRIB_CRITERION_EXACT
,
186 { EGL_COLOR_BUFFER_TYPE
, ATTRIB_TYPE_ENUM
,
187 ATTRIB_CRITERION_EXACT
,
189 { EGL_CONFIG_CAVEAT
, ATTRIB_TYPE_ENUM
,
190 ATTRIB_CRITERION_EXACT
,
192 { EGL_CONFIG_ID
, ATTRIB_TYPE_INTEGER
,
193 ATTRIB_CRITERION_EXACT
,
195 { EGL_CONFORMANT
, ATTRIB_TYPE_BITMASK
,
196 ATTRIB_CRITERION_MASK
,
198 { EGL_DEPTH_SIZE
, ATTRIB_TYPE_INTEGER
,
199 ATTRIB_CRITERION_ATLEAST
,
201 { EGL_LEVEL
, ATTRIB_TYPE_PLATFORM
,
202 ATTRIB_CRITERION_EXACT
,
204 { EGL_MAX_PBUFFER_WIDTH
, ATTRIB_TYPE_INTEGER
,
205 ATTRIB_CRITERION_IGNORE
,
207 { EGL_MAX_PBUFFER_HEIGHT
, ATTRIB_TYPE_INTEGER
,
208 ATTRIB_CRITERION_IGNORE
,
210 { EGL_MAX_PBUFFER_PIXELS
, ATTRIB_TYPE_INTEGER
,
211 ATTRIB_CRITERION_IGNORE
,
213 { EGL_MAX_SWAP_INTERVAL
, ATTRIB_TYPE_INTEGER
,
214 ATTRIB_CRITERION_EXACT
,
216 { EGL_MIN_SWAP_INTERVAL
, ATTRIB_TYPE_INTEGER
,
217 ATTRIB_CRITERION_EXACT
,
219 { EGL_NATIVE_RENDERABLE
, ATTRIB_TYPE_BOOLEAN
,
220 ATTRIB_CRITERION_EXACT
,
222 { EGL_NATIVE_VISUAL_ID
, ATTRIB_TYPE_PLATFORM
,
223 ATTRIB_CRITERION_IGNORE
,
225 { EGL_NATIVE_VISUAL_TYPE
, ATTRIB_TYPE_PLATFORM
,
226 ATTRIB_CRITERION_EXACT
,
228 { EGL_RENDERABLE_TYPE
, ATTRIB_TYPE_BITMASK
,
229 ATTRIB_CRITERION_MASK
,
231 { EGL_SAMPLE_BUFFERS
, ATTRIB_TYPE_INTEGER
,
232 ATTRIB_CRITERION_ATLEAST
,
234 { EGL_SAMPLES
, ATTRIB_TYPE_INTEGER
,
235 ATTRIB_CRITERION_ATLEAST
,
237 { EGL_STENCIL_SIZE
, ATTRIB_TYPE_INTEGER
,
238 ATTRIB_CRITERION_ATLEAST
,
240 { EGL_SURFACE_TYPE
, ATTRIB_TYPE_BITMASK
,
241 ATTRIB_CRITERION_MASK
,
243 { EGL_TRANSPARENT_TYPE
, ATTRIB_TYPE_ENUM
,
244 ATTRIB_CRITERION_EXACT
,
246 { EGL_TRANSPARENT_RED_VALUE
, ATTRIB_TYPE_INTEGER
,
247 ATTRIB_CRITERION_EXACT
,
249 { EGL_TRANSPARENT_GREEN_VALUE
, ATTRIB_TYPE_INTEGER
,
250 ATTRIB_CRITERION_EXACT
,
252 { EGL_TRANSPARENT_BLUE_VALUE
, ATTRIB_TYPE_INTEGER
,
253 ATTRIB_CRITERION_EXACT
,
255 { EGL_MATCH_NATIVE_PIXMAP
, ATTRIB_TYPE_PSEUDO
,
256 ATTRIB_CRITERION_SPECIAL
,
259 { EGL_Y_INVERTED_NOK
, ATTRIB_TYPE_BOOLEAN
,
260 ATTRIB_CRITERION_EXACT
,
262 { EGL_FRAMEBUFFER_TARGET_ANDROID
, ATTRIB_TYPE_BOOLEAN
,
263 ATTRIB_CRITERION_EXACT
,
265 { EGL_RECORDABLE_ANDROID
, ATTRIB_TYPE_BOOLEAN
,
266 ATTRIB_CRITERION_EXACT
,
268 { EGL_COLOR_COMPONENT_TYPE_EXT
, ATTRIB_TYPE_ENUM
,
269 ATTRIB_CRITERION_EXACT
,
270 EGL_COLOR_COMPONENT_TYPE_FIXED_EXT
},
271 { EGL_CONFIG_SELECT_GROUP_MESA
, ATTRIB_TYPE_INTEGER
,
272 ATTRIB_CRITERION_IGNORE
,
278 * Return true if a config is valid. When for_matching is true,
279 * EGL_DONT_CARE is accepted as a valid attribute value, and checks
280 * for conflicting attribute values are skipped.
282 * Note that some attributes are platform-dependent and are not
286 _eglValidateConfig(const _EGLConfig
*conf
, EGLBoolean for_matching
)
288 _EGLDisplay
*disp
= conf
->Display
;
290 EGLBoolean valid
= EGL_TRUE
;
292 /* check attributes by their types */
293 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
296 attr
= _eglValidationTable
[i
].attr
;
297 val
= _eglGetConfigKey(conf
, attr
);
299 switch (_eglValidationTable
[i
].type
) {
300 case ATTRIB_TYPE_INTEGER
:
303 /* config id must be positive */
307 case EGL_SAMPLE_BUFFERS
:
308 /* there can be at most 1 sample buffer */
309 if (val
> 1 || val
< 0)
312 case EGL_CONFIG_SELECT_GROUP_MESA
:
320 case ATTRIB_TYPE_BOOLEAN
:
321 if (val
!= EGL_TRUE
&& val
!= EGL_FALSE
)
324 case ATTRIB_TYPE_ENUM
:
326 case EGL_CONFIG_CAVEAT
:
327 if (val
!= EGL_NONE
&& val
!= EGL_SLOW_CONFIG
&&
328 val
!= EGL_NON_CONFORMANT_CONFIG
)
331 case EGL_TRANSPARENT_TYPE
:
332 if (val
!= EGL_NONE
&& val
!= EGL_TRANSPARENT_RGB
)
335 case EGL_COLOR_BUFFER_TYPE
:
336 if (val
!= EGL_RGB_BUFFER
&& val
!= EGL_LUMINANCE_BUFFER
)
339 case EGL_COLOR_COMPONENT_TYPE_EXT
:
340 if (val
!= EGL_COLOR_COMPONENT_TYPE_FIXED_EXT
&&
341 val
!= EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT
)
345 unreachable("check _eglValidationTable[]");
349 case ATTRIB_TYPE_BITMASK
:
351 case EGL_SURFACE_TYPE
:
352 mask
= EGL_PBUFFER_BIT
|
355 EGL_VG_COLORSPACE_LINEAR_BIT
|
356 EGL_VG_ALPHA_FORMAT_PRE_BIT
|
357 EGL_MULTISAMPLE_RESOLVE_BOX_BIT
|
358 EGL_SWAP_BEHAVIOR_PRESERVED_BIT
;
359 if (disp
->Extensions
.KHR_mutable_render_buffer
)
360 mask
|= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR
;
362 case EGL_RENDERABLE_TYPE
:
364 mask
= EGL_OPENGL_ES_BIT
|
367 EGL_OPENGL_ES3_BIT_KHR
|
371 unreachable("check _eglValidationTable[]");
378 case ATTRIB_TYPE_PLATFORM
:
379 /* unable to check platform-dependent attributes here */
381 case ATTRIB_TYPE_PSEUDO
:
382 /* pseudo attributes should not be set */
388 if (!valid
&& for_matching
) {
389 /* accept EGL_DONT_CARE as a valid value */
390 if (val
== EGL_DONT_CARE
)
392 if (_eglValidationTable
[i
].criterion
== ATTRIB_CRITERION_SPECIAL
)
397 "attribute 0x%04x has an invalid value 0x%x", attr
, val
);
402 /* any invalid attribute value should have been catched */
403 if (!valid
|| for_matching
)
406 /* now check for conflicting attribute values */
408 switch (conf
->ColorBufferType
) {
410 if (conf
->LuminanceSize
)
412 if (conf
->RedSize
+ conf
->GreenSize
+
413 conf
->BlueSize
+ conf
->AlphaSize
!= conf
->BufferSize
)
416 case EGL_LUMINANCE_BUFFER
:
417 if (conf
->RedSize
|| conf
->GreenSize
|| conf
->BlueSize
)
419 if (conf
->LuminanceSize
+ conf
->AlphaSize
!= conf
->BufferSize
)
424 _eglLog(_EGL_DEBUG
, "conflicting color buffer type and channel sizes");
428 if (!conf
->SampleBuffers
&& conf
->Samples
)
431 _eglLog(_EGL_DEBUG
, "conflicting samples and sample buffers");
435 if (!(conf
->SurfaceType
& EGL_WINDOW_BIT
)) {
436 if (conf
->NativeVisualID
!= 0 || conf
->NativeVisualType
!= EGL_NONE
)
439 if (!(conf
->SurfaceType
& EGL_PBUFFER_BIT
)) {
440 if (conf
->BindToTextureRGB
|| conf
->BindToTextureRGBA
)
444 _eglLog(_EGL_DEBUG
, "conflicting surface type and native visual/texture binding");
453 * Return true if a config matches the criteria. This and
454 * _eglParseConfigAttribList together implement the algorithm
455 * described in "Selection of EGLConfigs".
457 * Note that attributes that are special (currently, only
458 * EGL_MATCH_NATIVE_PIXMAP) are ignored.
461 _eglMatchConfig(const _EGLConfig
*conf
, const _EGLConfig
*criteria
)
464 EGLBoolean matched
= EGL_TRUE
;
466 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
468 if (_eglValidationTable
[i
].criterion
== ATTRIB_CRITERION_IGNORE
)
471 attr
= _eglValidationTable
[i
].attr
;
472 cmp
= _eglGetConfigKey(criteria
, attr
);
473 if (cmp
== EGL_DONT_CARE
)
476 val
= _eglGetConfigKey(conf
, attr
);
477 switch (_eglValidationTable
[i
].criterion
) {
478 case ATTRIB_CRITERION_EXACT
:
482 case ATTRIB_CRITERION_ATLEAST
:
486 case ATTRIB_CRITERION_MASK
:
487 if ((val
& cmp
) != cmp
)
490 case ATTRIB_CRITERION_SPECIAL
:
493 case ATTRIB_CRITERION_IGNORE
:
494 unreachable("already handled above");
500 /* only print the common errors when DEBUG is not defined */
501 if (attr
!= EGL_RENDERABLE_TYPE
)
505 "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)",
514 static inline EGLBoolean
515 _eglIsConfigAttribValid(_EGLConfig
*conf
, EGLint attr
)
517 if (_eglOffsetOfConfig(attr
) < 0)
521 case EGL_Y_INVERTED_NOK
:
522 return conf
->Display
->Extensions
.NOK_texture_from_pixmap
;
523 case EGL_FRAMEBUFFER_TARGET_ANDROID
:
524 return conf
->Display
->Extensions
.ANDROID_framebuffer_target
;
525 case EGL_RECORDABLE_ANDROID
:
526 return conf
->Display
->Extensions
.ANDROID_recordable
;
535 * Initialize a criteria config from the given attribute list.
536 * Return EGL_FALSE if any of the attribute is invalid.
539 _eglParseConfigAttribList(_EGLConfig
*conf
, _EGLDisplay
*disp
,
540 const EGLint
*attrib_list
)
544 _eglInitConfig(conf
, disp
, EGL_DONT_CARE
);
546 /* reset to default values */
547 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
548 attr
= _eglValidationTable
[i
].attr
;
549 val
= _eglValidationTable
[i
].default_value
;
550 _eglSetConfigKey(conf
, attr
, val
);
554 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
+= 2) {
555 attr
= attrib_list
[i
];
556 val
= attrib_list
[i
+ 1];
558 if (!_eglIsConfigAttribValid(conf
, attr
))
561 _eglSetConfigKey(conf
, attr
, val
);
564 if (!_eglValidateConfig(conf
, EGL_TRUE
))
567 /* EGL_LEVEL and EGL_MATCH_NATIVE_PIXMAP cannot be EGL_DONT_CARE */
568 if (conf
->Level
== EGL_DONT_CARE
||
569 conf
->MatchNativePixmap
== EGL_DONT_CARE
)
572 /* ignore other attributes when EGL_CONFIG_ID is given */
573 if (conf
->ConfigID
!= EGL_DONT_CARE
) {
574 for (i
= 0; i
< ARRAY_SIZE(_eglValidationTable
); i
++) {
575 attr
= _eglValidationTable
[i
].attr
;
576 if (attr
!= EGL_CONFIG_ID
)
577 _eglSetConfigKey(conf
, attr
, EGL_DONT_CARE
);
581 if (!(conf
->SurfaceType
& EGL_WINDOW_BIT
))
582 conf
->NativeVisualType
= EGL_DONT_CARE
;
584 if (conf
->TransparentType
== EGL_NONE
) {
585 conf
->TransparentRedValue
= EGL_DONT_CARE
;
586 conf
->TransparentGreenValue
= EGL_DONT_CARE
;
587 conf
->TransparentBlueValue
= EGL_DONT_CARE
;
596 * Decide the ordering of conf1 and conf2, under the given criteria.
597 * When compare_id is true, this implements the algorithm described
598 * in "Sorting of EGLConfigs". When compare_id is false,
599 * EGL_CONFIG_ID is not compared.
601 * It returns a negative integer if conf1 is considered to come
602 * before conf2; a positive integer if conf2 is considered to come
603 * before conf1; zero if the ordering cannot be decided.
605 * Note that EGL_NATIVE_VISUAL_TYPE is platform-dependent and is
609 _eglCompareConfigs(const _EGLConfig
*conf1
, const _EGLConfig
*conf2
,
610 const _EGLConfig
*criteria
, EGLBoolean compare_id
)
612 const EGLint compare_attribs
[] = {
626 val1
= conf1
->ConfigSelectGroup
- conf2
->ConfigSelectGroup
;
630 /* the enum values have the desired ordering */
631 STATIC_ASSERT(EGL_NONE
< EGL_SLOW_CONFIG
);
632 STATIC_ASSERT(EGL_SLOW_CONFIG
< EGL_NON_CONFORMANT_CONFIG
);
633 val1
= conf1
->ConfigCaveat
- conf2
->ConfigCaveat
;
637 /* the enum values have the desired ordering */
638 STATIC_ASSERT(EGL_RGB_BUFFER
< EGL_LUMINANCE_BUFFER
);
639 val1
= conf1
->ColorBufferType
- conf2
->ColorBufferType
;
645 if (conf1
->ColorBufferType
== EGL_RGB_BUFFER
) {
646 if (criteria
->RedSize
> 0) {
647 val1
+= conf1
->RedSize
;
648 val2
+= conf2
->RedSize
;
650 if (criteria
->GreenSize
> 0) {
651 val1
+= conf1
->GreenSize
;
652 val2
+= conf2
->GreenSize
;
654 if (criteria
->BlueSize
> 0) {
655 val1
+= conf1
->BlueSize
;
656 val2
+= conf2
->BlueSize
;
660 if (criteria
->LuminanceSize
> 0) {
661 val1
+= conf1
->LuminanceSize
;
662 val2
+= conf2
->LuminanceSize
;
665 if (criteria
->AlphaSize
> 0) {
666 val1
+= conf1
->AlphaSize
;
667 val2
+= conf2
->AlphaSize
;
671 /* assume the default criteria, which gives no specific ordering */
675 /* for color bits, larger one is preferred */
677 return (val2
- val1
);
679 for (i
= 0; i
< ARRAY_SIZE(compare_attribs
); i
++) {
680 val1
= _eglGetConfigKey(conf1
, compare_attribs
[i
]);
681 val2
= _eglGetConfigKey(conf2
, compare_attribs
[i
]);
683 return (val1
- val2
);
686 /* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
688 return (compare_id
) ? (conf1
->ConfigID
- conf2
->ConfigID
) : 0;
693 void _eglSwapConfigs(const _EGLConfig
**conf1
, const _EGLConfig
**conf2
)
695 const _EGLConfig
*tmp
= *conf1
;
702 * Quick sort an array of configs. This differs from the standard
703 * qsort() in that the compare function accepts an additional
707 _eglSortConfigs(const _EGLConfig
**configs
, EGLint count
,
708 EGLint (*compare
)(const _EGLConfig
*, const _EGLConfig
*,
712 const EGLint pivot
= 0;
718 _eglSwapConfigs(&configs
[pivot
], &configs
[count
/ 2]);
722 while (i
< count
&& compare(configs
[i
], configs
[pivot
], priv_data
) < 0)
724 while (compare(configs
[j
], configs
[pivot
], priv_data
) > 0)
727 _eglSwapConfigs(&configs
[i
], &configs
[j
]);
737 _eglSwapConfigs(&configs
[pivot
], &configs
[j
]);
739 _eglSortConfigs(configs
, j
, compare
, priv_data
);
740 _eglSortConfigs(configs
+ i
, count
- i
, compare
, priv_data
);
745 * A helper function for implementing eglChooseConfig. See _eglFilterArray and
746 * _eglSortConfigs for the meanings of match and compare.
749 _eglFilterConfigArray(_EGLArray
*array
, EGLConfig
*configs
,
750 EGLint config_size
, EGLint
*num_configs
,
751 EGLBoolean (*match
)(const _EGLConfig
*, void *),
752 EGLint (*compare
)(const _EGLConfig
*, const _EGLConfig
*,
756 _EGLConfig
**configList
;
759 /* get the number of matched configs */
760 count
= _eglFilterArray(array
, NULL
, 0,
761 (_EGLArrayForEach
) match
, priv_data
);
763 *num_configs
= count
;
767 configList
= malloc(sizeof(*configList
) * count
);
769 return _eglError(EGL_BAD_ALLOC
, "eglChooseConfig(out of memory)");
771 /* get the matched configs */
772 _eglFilterArray(array
, (void **) configList
, count
,
773 (_EGLArrayForEach
) match
, priv_data
);
775 /* perform sorting of configs */
776 if (configs
&& count
) {
777 _eglSortConfigs((const _EGLConfig
**) configList
, count
,
779 count
= MIN2(count
, config_size
);
780 for (i
= 0; i
< count
; i
++)
781 configs
[i
] = _eglGetConfigHandle(configList
[i
]);
786 *num_configs
= count
;
793 _eglFallbackMatch(const _EGLConfig
*conf
, void *priv_data
)
795 return _eglMatchConfig(conf
, (const _EGLConfig
*) priv_data
);
800 _eglFallbackCompare(const _EGLConfig
*conf1
, const _EGLConfig
*conf2
,
803 return _eglCompareConfigs(conf1
, conf2
,
804 (const _EGLConfig
*) priv_data
, EGL_TRUE
);
809 * Typical fallback routine for eglChooseConfig
812 _eglChooseConfig(_EGLDriver
*drv
, _EGLDisplay
*disp
, const EGLint
*attrib_list
,
813 EGLConfig
*configs
, EGLint config_size
, EGLint
*num_configs
)
817 if (!_eglParseConfigAttribList(&criteria
, disp
, attrib_list
))
818 return _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
820 return _eglFilterConfigArray(disp
->Configs
,
821 configs
, config_size
, num_configs
,
822 _eglFallbackMatch
, _eglFallbackCompare
,
828 * Fallback for eglGetConfigAttrib.
831 _eglGetConfigAttrib(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLConfig
*conf
,
832 EGLint attribute
, EGLint
*value
)
834 if (!_eglIsConfigAttribValid(conf
, attribute
))
835 return _eglError(EGL_BAD_ATTRIBUTE
, "eglGetConfigAttrib");
837 /* nonqueryable attributes */
839 case EGL_MATCH_NATIVE_PIXMAP
:
840 return _eglError(EGL_BAD_ATTRIBUTE
, "eglGetConfigAttrib");
847 return _eglError(EGL_BAD_PARAMETER
, "eglGetConfigAttrib");
849 *value
= _eglGetConfigKey(conf
, attribute
);
855 _eglFlattenConfig(void *elem
, void *buffer
)
857 _EGLConfig
*conf
= (_EGLConfig
*) elem
;
858 EGLConfig
*handle
= (EGLConfig
*) buffer
;
859 *handle
= _eglGetConfigHandle(conf
);
864 * Fallback for eglGetConfigs.
867 _eglGetConfigs(_EGLDriver
*drv
, _EGLDisplay
*disp
, EGLConfig
*configs
,
868 EGLint config_size
, EGLint
*num_config
)
870 *num_config
= _eglFlattenArray(disp
->Configs
, (void *) configs
,
871 sizeof(configs
[0]), config_size
, _eglFlattenConfig
);