5 #include "egldisplay.h"
7 #include "eglglobals.h"
10 #define MIN2(A, B) (((A) < (B)) ? (A) : (B))
14 * Init the given _EGLconfig to default values.
15 * \param id the configuration's ID.
18 _eglInitConfig(_EGLConfig
*config
, EGLint id
)
20 memset(config
, 0, sizeof(*config
));
22 SET_CONFIG_ATTRIB(config
, EGL_CONFIG_ID
, id
);
23 SET_CONFIG_ATTRIB(config
, EGL_BIND_TO_TEXTURE_RGB
, EGL_DONT_CARE
);
24 SET_CONFIG_ATTRIB(config
, EGL_BIND_TO_TEXTURE_RGBA
, EGL_DONT_CARE
);
25 SET_CONFIG_ATTRIB(config
, EGL_CONFIG_CAVEAT
, EGL_DONT_CARE
);
26 SET_CONFIG_ATTRIB(config
, EGL_NATIVE_RENDERABLE
, EGL_DONT_CARE
);
27 SET_CONFIG_ATTRIB(config
, EGL_NATIVE_VISUAL_TYPE
, EGL_DONT_CARE
);
28 SET_CONFIG_ATTRIB(config
, EGL_MIN_SWAP_INTERVAL
, EGL_DONT_CARE
);
29 SET_CONFIG_ATTRIB(config
, EGL_MAX_SWAP_INTERVAL
, EGL_DONT_CARE
);
30 SET_CONFIG_ATTRIB(config
, EGL_SURFACE_TYPE
, EGL_WINDOW_BIT
);
31 SET_CONFIG_ATTRIB(config
, EGL_TRANSPARENT_TYPE
, EGL_NONE
);
32 SET_CONFIG_ATTRIB(config
, EGL_TRANSPARENT_RED_VALUE
, EGL_DONT_CARE
);
33 SET_CONFIG_ATTRIB(config
, EGL_TRANSPARENT_GREEN_VALUE
, EGL_DONT_CARE
);
34 SET_CONFIG_ATTRIB(config
, EGL_TRANSPARENT_BLUE_VALUE
, EGL_DONT_CARE
);
39 * Given an EGLConfig handle, return the corresponding _EGLConfig object.
42 _eglLookupConfig(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
)
45 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
46 for (i
= 0; i
< disp
->NumConfigs
; i
++) {
47 if (disp
->Configs
[i
].Handle
== config
) {
48 return disp
->Configs
+ i
;
56 * Add the given _EGLConifg to the given display.
59 _eglAddConfig(_EGLDisplay
*display
, const _EGLConfig
*config
)
61 _EGLConfig
*newConfigs
;
64 n
= display
->NumConfigs
;
66 newConfigs
= (_EGLConfig
*) realloc(display
->Configs
,
67 (n
+ 1) * sizeof(_EGLConfig
));
69 display
->Configs
= newConfigs
;
70 display
->Configs
[n
] = *config
; /* copy struct */
71 display
->NumConfigs
++;
72 return display
->Configs
+ n
;
82 * Parse the attrib_list to fill in the fields of the given _egl_config
83 * Return EGL_FALSE if any errors, EGL_TRUE otherwise.
86 _eglParseConfigAttribs(_EGLConfig
*config
, const EGLint
*attrib_list
)
90 /* XXX set all config attribs to EGL_DONT_CARE */
92 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
93 EGLint k
= attrib_list
[i
] - FIRST_ATTRIB
;
94 if (k
>= 0 && k
< MAX_ATTRIBS
) {
95 config
->Attrib
[k
] = attrib_list
[++i
];
98 _eglError(EGL_BAD_ATTRIBUTE
, "eglChooseConfig");
115 EGLint MatchCriteria
;
119 /* This encodes the info from Table 3.5 of the EGL spec, ordered by
122 static struct sort_info SortInfo
[] = {
123 { EGL_CONFIG_CAVEAT
, EXACT
, SPECIAL
},
124 { EGL_RED_SIZE
, ATLEAST
, SPECIAL
},
125 { EGL_GREEN_SIZE
, ATLEAST
, SPECIAL
},
126 { EGL_BLUE_SIZE
, ATLEAST
, SPECIAL
},
127 { EGL_ALPHA_SIZE
, ATLEAST
, SPECIAL
},
128 { EGL_BUFFER_SIZE
, ATLEAST
, SMALLER
},
129 { EGL_SAMPLE_BUFFERS
, ATLEAST
, SMALLER
},
130 { EGL_SAMPLES
, ATLEAST
, SMALLER
},
131 { EGL_DEPTH_SIZE
, ATLEAST
, SMALLER
},
132 { EGL_STENCIL_SIZE
, ATLEAST
, SMALLER
},
133 { EGL_NATIVE_VISUAL_TYPE
, EXACT
, SPECIAL
},
134 { EGL_CONFIG_ID
, EXACT
, SMALLER
},
135 { EGL_BIND_TO_TEXTURE_RGB
, EXACT
, NONE
},
136 { EGL_BIND_TO_TEXTURE_RGBA
, EXACT
, NONE
},
137 { EGL_LEVEL
, EXACT
, NONE
},
138 { EGL_NATIVE_RENDERABLE
, EXACT
, NONE
},
139 { EGL_MAX_SWAP_INTERVAL
, EXACT
, NONE
},
140 { EGL_MIN_SWAP_INTERVAL
, EXACT
, NONE
},
141 { EGL_SURFACE_TYPE
, MASK
, NONE
},
142 { EGL_TRANSPARENT_TYPE
, EXACT
, NONE
},
143 { EGL_TRANSPARENT_RED_VALUE
, EXACT
, NONE
},
144 { EGL_TRANSPARENT_GREEN_VALUE
, EXACT
, NONE
},
145 { EGL_TRANSPARENT_BLUE_VALUE
, EXACT
, NONE
},
151 * Return EGL_TRUE if the attributes of c meet or exceed the minimums
155 _eglConfigQualifies(const _EGLConfig
*c
, const _EGLConfig
*min
)
158 for (i
= 0; SortInfo
[i
].Attribute
!= 0; i
++) {
159 const EGLint mv
= GET_CONFIG_ATTRIB(min
, SortInfo
[i
].Attribute
);
160 if (mv
!= EGL_DONT_CARE
) {
161 const EGLint cv
= GET_CONFIG_ATTRIB(c
, SortInfo
[i
].Attribute
);
162 if (SortInfo
[i
].MatchCriteria
== EXACT
) {
167 else if (SortInfo
[i
].MatchCriteria
== ATLEAST
) {
173 assert(SortInfo
[i
].MatchCriteria
== MASK
);
174 if ((mv
& cv
) != mv
) {
185 * Compare configs 'a' and 'b' and return -1 if a belongs before b,
186 * 1 if a belongs after b, or 0 if they're equal.
189 _eglCompareConfigs(const _EGLConfig
*a
, const _EGLConfig
*b
)
192 for (i
= 0; SortInfo
[i
].Attribute
!= 0; i
++) {
193 const EGLint av
= GET_CONFIG_ATTRIB(a
, SortInfo
[i
].Attribute
);
194 const EGLint bv
= GET_CONFIG_ATTRIB(b
, SortInfo
[i
].Attribute
);
195 if (SortInfo
[i
].SortOrder
== SMALLER
) {
200 /* else, continue examining attribute values */
202 else if (SortInfo
[i
].SortOrder
== SPECIAL
) {
203 if (SortInfo
[i
].Attribute
== EGL_CONFIG_CAVEAT
) {
204 /* values are EGL_NONE, SLOW_CONFIG, or NON_CONFORMANT_CONFIG */
210 else if (SortInfo
[i
].Attribute
== EGL_RED_SIZE
||
211 SortInfo
[i
].Attribute
== EGL_GREEN_SIZE
||
212 SortInfo
[i
].Attribute
== EGL_BLUE_SIZE
||
213 SortInfo
[i
].Attribute
== EGL_ALPHA_SIZE
) {
220 assert(SortInfo
[i
].Attribute
== EGL_NATIVE_VISUAL_TYPE
);
228 assert(SortInfo
[i
].SortOrder
== NONE
);
229 /* continue examining attribute values */
237 * Typical fallback routine for eglChooseConfig
240 _eglChooseConfig(_EGLDriver
*drv
, EGLDisplay dpy
, const EGLint
*attrib_list
, EGLConfig
*configs
, EGLint config_size
, EGLint
*num_config
)
242 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
246 /* parse the attrib_list to initialize criteria */
247 if (!_eglParseConfigAttribs(&criteria
, attrib_list
)) {
252 for (i
= 0; i
< disp
->NumConfigs
; i
++) {
253 const _EGLConfig
*conf
= disp
->Configs
+ i
;
254 if (_eglConfigQualifies(conf
, &criteria
)) {
255 if (*num_config
< config_size
) {
257 configs
[*num_config
] = conf
->Handle
;
266 /* XXX sort the list here */
273 * Fallback for eglGetConfigAttrib.
276 _eglGetConfigAttrib(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
, EGLint attribute
, EGLint
*value
)
278 const _EGLConfig
*conf
= _eglLookupConfig(drv
, dpy
, config
);
279 const EGLint k
= attribute
- FIRST_ATTRIB
;
280 if (k
>= 0 && k
< MAX_ATTRIBS
) {
281 *value
= conf
->Attrib
[k
];
285 _eglError(EGL_BAD_ATTRIBUTE
, "eglGetConfigAttrib");
292 * Fallback for eglGetConfigs.
295 _eglGetConfigs(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig
*configs
, EGLint config_size
, EGLint
*num_config
)
297 _EGLDisplay
*disp
= _eglLookupDisplay(dpy
);
299 if (!drv
->Initialized
) {
300 _eglError(EGL_NOT_INITIALIZED
, "eglGetConfigs");
304 *num_config
= MIN2(disp
->NumConfigs
, config_size
);
307 for (i
= 0; i
< *num_config
; i
++) {
308 configs
[i
] = disp
->Configs
[i
].Handle
;