1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/*
29 EGLAPI EGLint EGLAPIENTRY eglGetError(void)
30
31 Khronos documentation:
32
33 3.1 Errors
34 Where possible, when an EGL function fails it has no side effects.
35 EGL functions usually return an indicator of success or failure; either an
36 EGLBoolean EGL TRUE or EGL FALSE value, or in the form of an out-of-band
37 return value indicating failure, such as returning EGL NO CONTEXT instead of a requested
38 context handle. Additional information about the success or failure of the
39 most recent EGL function called in a specific thread, in the form of an error code,
40 can be obtained by calling
41 EGLint eglGetError();
42 The error codes that may be returned from eglGetError, and their meanings,
43 are:
44 EGL SUCCESS
45 Function succeeded.
46 EGL NOT INITIALIZED
47 EGL is not initialized, or could not be initialized, for the specified display.
48 EGL BAD ACCESS
49 EGL cannot access a requested resource (for example, a context is bound in
50 another thread).
51 EGL BAD ALLOC
52 EGL failed to allocate resources for the requested operation.
53 9
54 10 CHAPTER 3. EGL FUNCTIONS AND ERRORS
55 EGL BAD ATTRIBUTE
56 An unrecognized attribute or attribute value was passed in an attribute list.
57 EGL BAD CONTEXT
58 An EGLContext argument does not name a valid EGLContext.
59 EGL BAD CONFIG
60 An EGLConfig argument does not name a valid EGLConfig.
61 EGL BAD CURRENT SURFACE
62 The current surface of the calling thread is a window, pbuffer, or pixmap that
63 is no longer valid.
64 EGL BAD DISPLAY
65 An EGLDisplay argument does not name a valid EGLDisplay; or, EGL
66 is not initialized on the specified EGLDisplay.
67 EGL BAD SURFACE
68 An EGLSurface argument does not name a valid surface (window, pbuffer,
69 or pixmap) configured for rendering.
70 EGL BAD MATCH
71 Arguments are inconsistent; for example, an otherwise valid context requires
72 buffers (e.g. depth or stencil) not allocated by an otherwise valid surface.
73 EGL BAD PARAMETER
74 One or more argument values are invalid.
75 EGL BAD NATIVE PIXMAP
76 An EGLNativePixmapType argument does not refer to a valid native
77 pixmap.
78 EGL BAD NATIVE WINDOW
79 An EGLNativeWindowType argument does not refer to a valid native
80 window.
81 EGL CONTEXT LOST
82 A power management event has occurred. The application must destroy all
83 contexts and reinitialise client API state and objects to continue rendering,
84 as described in section 2.6.
85 When there is no status to return (in other words, when eglGetError is called
86 as the first EGL call in a thread, or immediately after calling eglReleaseThread),
87 EGL SUCCESS will be returned.
88
89 Implementation notes:
90
91 What should we do if eglGetError is called twice? Currently we reset the error to EGL_SUCCESS.
92
93 Preconditions:
94
95 -
96
97 Postconditions:
98
99 Result is in the list (CLIENT_THREAD_STATE_ERROR)
100
101 Invariants preserved:
102
103 -
104
105 Invariants used:
106
107 (CLIENT_THREAD_STATE_ERROR)
108*/
109
110EGLAPI EGLint EGLAPIENTRY eglGetError(void)
111{
112 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_CHECK_THREAD_STATE();
113
114 if (thread)
115 {
116 EGLint result;
117
118 vcos_assert( thread != NULL );
119
120 result = thread->error;
121 thread->error = EGL_SUCCESS;
122
123 return result;
124 }
125 else
126 return EGL_SUCCESS;
127}
128
129/*
130 EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
131
132 Khronos documentation:
133
134 3.2 Initialization
135Initialization must be performed once for each display prior to calling most other
136EGL or client API functions. A display can be obtained by calling
137EGLDisplay eglGetDisplay(EGLNativeDisplayType
138display id);
139The type and format of display id are implementation-specific, and it describes a
140specific display provided by the system EGL is running on. For example, an EGL
141implementation under X windows would require display id to be an X Display,
142while an implementation under Microsoft Windows would require display id to be
143a Windows Device Context. If display id is EGL DEFAULT DISPLAY, a default
144display is returned.
145If no display matching display id is available, EGL NO DISPLAY is returned;
146no error condition is raised in this case.
147
148 Implementation notes:
149
150 We only support one display. This is assumed to have a native display_id
151 of 0 (==EGL_DEFAULT_DISPLAY) and an EGLDisplay id of 1
152
153 Preconditions:
154
155 -
156
157 Postconditions:
158
159 -
160
161 Invariants preserved:
162
163 -
164
165 Invariants used:
166
167 -
168*/
169
170EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
171{
172 CLIENT_THREAD_STATE_T *thread = CLIENT_GET_CHECK_THREAD_STATE();
173 if (thread)
174 thread->error = EGL_SUCCESS;
175
176 return khrn_platform_set_display_id(display_id);
177}
178
179
180//eglInitialize
181//eglTerminate
182//eglQueryString
183
184/*
185 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
186
187 Khronos documentation:
188
1893.4.1 Querying Configurations
190Use
191EGLBoolean eglGetConfigs(EGLDisplay dpy,
192EGLConfig *configs, EGLint config size,
193EGLint *num config);
194to get the list of all EGLConfigs that are available on the specified display. configs
195is a pointer to a buffer containing config size elements. On success, EGL TRUE is
196returned. The number of configurations is returned in num config, and elements 0
197through num config - 1 of configs are filled in with the valid EGLConfigs. No
198more than config size EGLConfigs will be returned even if more are available on
199the specified display. However, if eglGetConfigs is called with configs = NULL,
200then no configurations are returned, but the total number of configurations available
201will be returned in num config.
202On failure, EGL FALSE is returned. An EGL NOT INITIALIZED error is generated
203if EGL is not initialized on dpy. An EGL BAD PARAMETER error is generated
204if num config is NULL.
205
206 Implementation notes:
207
208 -
209
210 Preconditions:
211
212 configs is NULL or a valid pointer to config_size elements
213 num_config is NULL or a valid pointer
214
215 Postconditions:
216
217 The following conditions cause error to assume the specified value
218
219 EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
220 EGL_NOT_INITIALIZED EGL is not initialized for the specified display.
221 EGL_BAD_PARAMETER num_config is null
222 EGL_SUCCESS Function succeeded.
223
224 if more than one condition holds, the first error is generated.
225
226 Invariants preserved:
227
228 -
229
230 Invariants used:
231
232 -
233*/
234
235EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
236{
237 CLIENT_THREAD_STATE_T *thread;
238 CLIENT_PROCESS_STATE_T *process;
239 EGLBoolean result;
240
241 if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
242 {
243 if (!num_config) {
244 thread->error = EGL_BAD_PARAMETER;
245 result = EGL_FALSE;
246 } else if (!configs) {
247 thread->error = EGL_SUCCESS;
248 *num_config = EGL_MAX_CONFIGS;
249 result = EGL_TRUE;
250 } else {
251 int i;
252 for (i = 0; i < EGL_MAX_CONFIGS && i < config_size; i++)
253 configs[i] = egl_config_from_id(i);
254
255 thread->error = EGL_SUCCESS;
256 *num_config = i;
257 result = EGL_TRUE;
258 }
259 CLIENT_UNLOCK();
260 }
261 else
262 result = EGL_FALSE;
263
264 return result;
265}
266
267/*
268 EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
269
270 Khronos documentation:
271
272 Use
273EGLBoolean eglChooseConfig(EGLDisplay dpy, const
274EGLint *attrib list, EGLConfig *configs,
275EGLint config size, EGLint *num config);
276to get EGLConfigs that match a list of attributes. The return value and the meaning
277of configs, config size, and num config are the same as for eglGetConfigs.
278However, only configurations matching attrib list, as discussed below, will be returned.
279On failure, EGL FALSE is returned. An EGL BAD ATTRIBUTE error is generated
280if attrib list contains an undefined EGL attribute or an attribute value that is
281unrecognized or out of range.
282All attribute names in attrib list are immediately followed by the corresponding
283desired value. The list is terminated with EGL NONE. If an attribute is not specified
284in attrib list, then the default value (listed in Table 3.4) is used (it is said to be
285specified implicitly). If EGL_DONT_CARE is specified as an attribute value, then the
286attribute will not be checked. EGL_DONT_CARE may be specified for all attributes
287except EGL LEVEL. If attrib list is NULL or empty (first attribute is EGL NONE),
288then selection and sorting of EGLConfigs is done according to the default criteria
289in Tables 3.4 and 3.1, as described below under Selection and Sorting.
290Selection of EGLConfigs
291Attributes are matched in an attribute-specific manner, as shown in the ”Selection
292Critera” column of table 3.4. The criteria listed in the table have the following
293meanings:
294AtLeast Only EGLConfigs with an attribute value that meets or exceeds the
295specified value are selected.
296Exact Only EGLConfigs whose attribute value equals the specified value are
297matched.
298Mask Only EGLConfigs for which the bits set in the attribute value include all
299the bits that are set in the specified value are selected (additional bits might
300be set in the attribute value).
301Special As described for the specific attribute.
302Some of the attributes must match the specified value exactly; others, such as
303EGL RED SIZE, must meet or exceed the specified minimum values.
304To retrieve an EGLConfig given its unique integer ID, use the
305EGL CONFIG ID attribute. When EGL CONFIG ID is specified, all other attributes
306are ignored, and only the EGLConfig with the given ID is returned.
307If EGL MAX PBUFFER WIDTH, EGL MAX PBUFFER HEIGHT,
308EGL MAX PBUFFER PIXELS, or EGL NATIVE VISUAL ID are specified in
309attrib list, then they are ignored (however, if present, these attributes must still be
310Version 1.3 - December 4, 2006
3113.4. CONFIGURATION MANAGEMENT 21
312followed by an attribute value in attrib list). If EGL SURFACE TYPE is specified
313in attrib list and the mask that follows does not have EGL WINDOW BIT set, or if
314there are no native visual types, then the EGL NATIVE VISUAL TYPE attribute is
315ignored.
316If EGL TRANSPARENT TYPE is set to EGL NONE in attrib list, then
317the EGL TRANSPARENT RED VALUE, EGL TRANSPARENT GREEN VALUE, and
318EGL TRANSPARENT BLUE VALUE attributes are ignored.
319If EGL MATCH NATIVE PIXMAP is specified in attrib list, it must be followed
320by an attribute value which is the handle of a valid native pixmap. Only
321EGLConfigs which support rendering to that pixmap will match this attribute2.
322If no EGLConfig matching the attribute list exists, then the call succeeds, but
323num config is set to 0.
324
325Attribute Default Selection Sort Sort
326 Criteria Order Priority
327EGL_BUFFER_SIZE 0 AtLeast Smaller 4
328EGL_RED_SIZE 0 AtLeast Special 3
329EGL_GREEN_SIZE 0 AtLeast Special 3
330EGL_BLUE_SIZE 0 AtLeast Special 3
331EGL_LUMINANCE_SIZE 0 AtLeast Special 3
332EGL_ALPHA_SIZE 0 AtLeast Special 3
333EGL_ALPHA_MASK_SIZE 0 AtLeast Smaller 9
334EGL_BIND_TO_TEXTURE_RGB EGL_DONT_CARE Exact None
335EGL_BIND_TO_TEXTURE_RGBA EGL_DONT_CARE Exact None
336EGL_COLOR_BUFFER_TYPE EGL_RGB BUFFER Exact None 2
337EGL_CONFIG_CAVEAT EGL_DONT_CARE Exact Special 1
338EGL_CONFIG_ID EGL_DONT_CARE Exact Smaller 11 (last)
339EGL_CONFORMANT 0 Mask None
340EGL_DEPTH_SIZE 0 AtLeast Smaller 7
341EGL_LEVEL 0 Exact None
342EGL_MATCH_NATIVE_PIXMAP EGL_NONE Special None
343EGL_MAX_SWAP_INTERVAL EGL_DONT_CARE Exact None
344EGL_MIN_SWAP_INTERVAL EGL_DONT_CARE Exact None
345EGL_NATIVE_RENDERABLE EGL_DONT_CARE Exact None
346EGL_NATIVE_VISUAL_TYPE EGL_DONT_CARE Exact Special 10
347EGL_RENDERABLE_TYPE EGL_OPENGL_ES_BIT Mask None
348EGL_SAMPLE_BUFFERS 0 AtLeast Smaller 5
349EGL_SAMPLES 0 AtLeast Smaller 6
350EGL_STENCIL_SIZE 0 AtLeast Smaller 8
351EGL_SURFACE_TYPE EGL_WINDOW_BIT Mask None
352EGL_TRANSPARENT_TYPE EGL_NONE Exact None
353EGL_TRANSPARENT_RED_VALUE EGL_DONT_CARE Exact None
354EGL_TRANSPARENT_GREEN_VALUE EGL_DONT_CARE Exact None
355EGL_TRANSPARENT_BLUE_VALUE EGL_DONT_CARE Exact None
356Table 3.4: Default values and match criteria for EGLConfig attributes.
357
358
3592 The special match criteria for EGL MATCH NATIVE PIXMAP was introduced due to the
360difficulty of determining an EGLConfig equivalent to a native pixmap using only color component
361depths.
3623This rule places configs with deeper color buffers first in the list returned by eglChooseConfig.
363Applications may find this counterintuitive, and need to perform additional processing on the list of
364configs to find one best matching their requirements. For example, specifying RGBA depths of 5651
365could return a list whose first config has a depth of 8888.
366
367 Implementation notes:
368
369 Configurations are not always returned in the same order; the sort order depends on
370 whether we care about EGL_RED_SIZE, EGL_GREEN_SIZE, etc. So we need to extract the information
371 about which of these we care about, then pass this to a sorting function.
372
373 Preconditions:
374
375 configs is NULL or a valid pointer to config_size elements
376 num_config is NULL or a valid pointer
377 attrib_list is NULL or a pointer to an EGL_NONE-terminated list of attribute/value pairs
378
379 Postconditions:
380
381 The following conditions cause error to assume the specified value
382
383 EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
384 EGL_NOT_INITIALIZED EGL is not initialized for dpy
385 EGL_BAD_PARAMETER num_config is null
386 EGL_BAD_ATTRIBUTE attrib_list contains an undefined EGL attribute
387 EGL_BAD_ATTRIBUTE attrib_list contains an attribute value that is unrecognized or out of range.
388 EGL_SUCCESS Function succeeded.
389
390 if more than one condition holds, the first error is generated.
391
392 Invariants preserved:
393
394 -
395
396 Invariants used:
397
398 -
399*/
400
401static EGLBoolean choose_config(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config, bool sane)
402{
403 CLIENT_THREAD_STATE_T *thread;
404 CLIENT_PROCESS_STATE_T *process;
405 EGLBoolean result;
406
407 if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
408 {
409 if (!num_config) {
410 thread->error = EGL_BAD_PARAMETER;
411 result = EGL_FALSE;
412 } else {
413 /*
414 check for invalid attributes, and find color components for which
415 we have expressed a preference
416 */
417
418 bool use_red = false;
419 bool use_green = false;
420 bool use_blue = false;
421 bool use_alpha = false;
422
423 if (!egl_config_check_attribs(attrib_list, &use_red, &use_green, &use_blue, &use_alpha)) {
424 thread->error = EGL_BAD_ATTRIBUTE;
425 result = EGL_FALSE;
426 } else {
427
428 /*
429 sort configs
430 */
431
432 int ids[EGL_MAX_CONFIGS];
433 int i, j;
434
435 for (i = 0; i < EGL_MAX_CONFIGS; i++)
436 ids[i] = i;
437
438 egl_config_sort(ids,
439 !sane && use_red, !sane && use_green,
440 !sane && use_blue, !sane && use_alpha);
441
442 /*
443 return configs
444 */
445
446 j = 0;
447 for (i = 0; i < EGL_MAX_CONFIGS; i++) {
448 if (egl_config_filter(ids[i], attrib_list)) {
449 if (configs && j < config_size) {
450 configs[j] = egl_config_from_id(ids[i]);
451 j++;
452 } else if (!configs) {
453 // If configs==NULL then we count all configs
454 // Otherwise we only count the configs we return
455 j++;
456 }
457 }
458 }
459
460 thread->error = EGL_SUCCESS;
461 *num_config = j;
462 result = EGL_TRUE;
463 }
464 }
465
466 CLIENT_UNLOCK();
467 }
468 else
469 result = EGL_FALSE;
470
471 return result;
472}
473
474EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
475{
476 return choose_config(dpy, attrib_list, configs, config_size, num_config, false);
477}
478
479#if EGL_BRCM_sane_choose_config
480EGLAPI EGLBoolean EGLAPIENTRY eglSaneChooseConfigBRCM(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
481{
482 return choose_config(dpy, attrib_list, configs, config_size, num_config, true);
483}
484#endif
485
486/*
487 EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
488
489 Khronos documentation:
490 3.4.3 Querying Configuration Attributes
491 To get the value of an EGLConfig attribute, use
492 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy,
493 EGLConfig config, EGLint attribute, EGLint
494 *value);
495 If eglGetConfigAttrib succeeds then it returns EGL_TRUE and the value for the
496 specified attribute is returned in value. Otherwise it returns EGL_FALSE. If attribute
497 is not a valid attribute then EGL_BAD_ATTRIBUTE is generated.
498 Refer to Table 3.1 and Table 3.4 for a list of valid EGL attributes.
499
500EGL_BUFFER_SIZE integer depth of the color buffer
501EGL_RED_SIZE integer bits of Red in the color buffer
502EGL_GREEN_SIZE integer bits of Green in the color buffer
503EGL_BLUE_SIZE integer bits of Blue in the color buffer
504EGL_LUMINANCE_SIZE integer bits of Luminance in the color buffer
505EGL_ALPHA_SIZE integer bits of Alpha in the color buffer
506EGL_ALPHA_MASK_SIZE integer bits of Alpha Mask in the mask buffer
507EGL_BIND_TO_TEXTURE_RGB boolean True if bindable to RGB textures.
508EGL_BIND_TO_TEXTURE_RGBA boolean True if bindable to RGBA textures.
509EGL_COLOR_BUFFER_TYPE enum color buffer type
510EGL_CONFIG_CAVEAT enum any caveats for the configuration
511EGL_CONFIG_ID integer unique EGLConfig identifier
512EGL_CONFORMANT bitmask whether contexts created with this config are conformant
513EGL_DEPTH_SIZE integer bits of Z in the depth buffer
514EGL_LEVEL integer frame buffer level
515EGL_MAX_PBUFFER_WIDTH integer maximum width of pbuffer
516EGL_MAX_PBUFFER_HEIGHT integer maximum height of pbuffer
517EGL_MAX_PBUFFER_PIXELS integer maximum size of pbuffer
518EGL_MAX_SWAP_INTERVAL integer maximum swap interval
519EGL_MIN_SWAP_INTERVAL integer minimum swap interval
520EGL_NATIVE_RENDERABLE boolean EGL_TRUE if native rendering APIs can render to surface
521EGL_NATIVE_VISUAL_ID integer handle of corresponding native visual
522EGL_NATIVE_VISUAL_TYPE integer native visual type of the associated visual
523EGL_RENDERABLE_TYPE bitmask which client APIs are supported
524EGL_SAMPLE_BUFFERS integer number of multisample buffers
525EGL_SAMPLES integer number of samples per pixel
526EGL_STENCIL_SIZE integer bits of Stencil in the stencil buffer
527EGL_SURFACE_TYPE bitmask which types of EGL surfaces are supported.
528EGL_TRANSPARENT_TYPE enum type of transparency supported
529EGL_TRANSPARENT_RED_VALUE integer transparent red value
530EGL_TRANSPARENT_GREEN_VALUE integer transparent green value
531EGL_TRANSPARENT_BLUE_VALUE integer transparent blue value
532
533 Preconditions:
534
535 value is null or a valid pointer
536
537 Postconditions:
538
539 The following conditions cause error to assume the specified value
540
541 EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
542 EGL_NOT_INITIALIZED EGL is not initialized for the specified display.
543 EGL_BAD_PARAMETER value is null
544 EGL_BAD_CONFIG config does not name a valid EGLConfig
545 EGL_BAD_ATTRIBUTE attribute is not a valid attribute
546 EGL_SUCCESS Function succeeded.
547
548 if more than one condition holds, the first error is generated.
549
550*/
551
552EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
553{
554 CLIENT_THREAD_STATE_T *thread;
555 CLIENT_PROCESS_STATE_T *process;
556 EGLBoolean result;
557
558 if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
559 {
560 if (!value) {
561 thread->error = EGL_BAD_PARAMETER;
562 result = EGL_FALSE;
563 } else if (egl_config_to_id(config) < 0 || egl_config_to_id(config) >= EGL_MAX_CONFIGS) {
564 thread->error = EGL_BAD_CONFIG;
565 result = EGL_FALSE;
566 } else if (!egl_config_get_attrib(egl_config_to_id(config), attribute, value)) {
567 thread->error = EGL_BAD_ATTRIBUTE;
568 result = EGL_FALSE;
569 } else {
570 thread->error = EGL_SUCCESS;
571 result = EGL_TRUE;
572 }
573 CLIENT_UNLOCK();
574 }
575 else
576 result = EGL_FALSE;
577
578 return result;
579}
580