blob: 697957eb4691964cd228a684f8177fdec8a030da [file] [log] [blame]
Chia-I Wuf2001df2011-07-02 17:57:30 +09001/**************************************************************************
2 *
José Fonseca87712852014-01-17 16:27:50 +00003 * Copyright 2008 VMware, Inc.
Chia-I Wuf2001df2011-07-02 17:57:30 +09004 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010-2011 LunarG, Inc.
6 * All Rights Reserved.
7 *
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:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
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.
27 *
28 **************************************************************************/
29
30
Brian Pauladbff7e2005-04-22 21:09:39 +000031/**
32 * Public EGL API entrypoints
33 *
34 * Generally, we use the EGLDisplay parameter as a key to lookup the
35 * appropriate device driver handle, then jump though the driver's
36 * dispatch table to handle the function.
37 *
38 * That allows us the option of supporting multiple, simultaneous,
39 * heterogeneous hardware devices in the future.
40 *
41 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
Chia-I Wuaaa12532009-09-30 15:08:34 +080042 * opaque handles. Internal objects are linked to a display to
43 * create the handles.
Brian Pauladbff7e2005-04-22 21:09:39 +000044 *
Chia-I Wuaaa12532009-09-30 15:08:34 +080045 * For each public API entry point, the opaque handles are looked up
46 * before being dispatched to the drivers. When it fails to look up
47 * a handle, one of
48 *
49 * EGL_BAD_DISPLAY
50 * EGL_BAD_CONFIG
51 * EGL_BAD_CONTEXT
52 * EGL_BAD_SURFACE
53 * EGL_BAD_SCREEN_MESA
54 * EGL_BAD_MODE_MESA
55 *
56 * is generated and the driver function is not called. An
57 * uninitialized EGLDisplay has no driver associated with it. When
58 * such display is detected,
59 *
60 * EGL_NOT_INITIALIZED
61 *
62 * is generated.
Brian Pauladbff7e2005-04-22 21:09:39 +000063 *
Chia-I Wubbfd0e22009-10-15 11:08:33 +080064 * Some of the entry points use current display, context, or surface
65 * implicitly. For such entry points, the implicit objects are also
66 * checked before calling the driver function. Other than the
67 * errors listed above,
68 *
69 * EGL_BAD_CURRENT_SURFACE
70 *
71 * may also be generated.
72 *
Brian Pauladbff7e2005-04-22 21:09:39 +000073 * Notes on naming conventions:
74 *
75 * eglFooBar - public EGL function
76 * EGL_FOO_BAR - public EGL token
77 * EGLDatatype - public EGL datatype
78 *
79 * _eglFooBar - private EGL function
80 * _EGLDatatype - private EGL datatype, typedef'd struct
81 * _egl_struct - private EGL struct, non-typedef'd
82 *
83 */
84
85
Brian Pauladbff7e2005-04-22 21:09:39 +000086#include <stdio.h>
Brian Paulb2006a42006-01-30 00:10:55 +000087#include <stdlib.h>
Brian Pauladbff7e2005-04-22 21:09:39 +000088#include <string.h>
Emil Velikov7bd16932015-02-28 16:35:22 +000089#include "c99_compat.h"
Emil Velikovefe87f12015-03-06 16:54:55 +000090#include "c11/threads.h"
Marek Olšákb6eda702016-03-03 15:59:48 +010091#include "GL/mesa_glinterop.h"
Emil Velikovefe87f12015-03-06 16:54:55 +000092#include "eglcompiler.h"
Chia-I Wu1e6c10f2010-05-31 11:47:58 +080093
Chad Versace3c58d4c2013-10-11 16:04:55 -070094#include "eglglobals.h"
Brian Pauladbff7e2005-04-22 21:09:39 +000095#include "eglcontext.h"
96#include "egldisplay.h"
97#include "egltypedefs.h"
Chia-I Wu94cb3212010-01-29 09:00:30 +080098#include "eglcurrent.h"
Brian Pauladbff7e2005-04-22 21:09:39 +000099#include "egldriver.h"
100#include "eglsurface.h"
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800101#include "eglconfig.h"
Chia-I Wua1c4a8a2009-08-15 22:58:13 +0800102#include "eglimage.h"
Chia-I Wu4eebea72010-08-14 23:09:12 +0800103#include "eglsync.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000104
105
106/**
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800107 * Macros to help return an API entrypoint.
Chia-I Wu655f4652010-02-17 17:30:44 +0800108 *
109 * These macros will unlock the display and record the error code.
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800110 */
Chia-I Wubef4b472010-02-19 12:08:50 +0800111#define RETURN_EGL_ERROR(disp, err, ret) \
112 do { \
Chia-I Wu655f4652010-02-17 17:30:44 +0800113 if (disp) \
114 _eglUnlockDisplay(disp); \
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800115 /* EGL error codes are non-zero */ \
116 if (err) \
Emil Velikovd7800122015-02-28 16:39:10 +0000117 _eglError(err, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800118 return ret; \
119 } while (0)
120
121#define RETURN_EGL_SUCCESS(disp, ret) \
122 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
123
Chia-I Wub3bb1802010-02-17 16:05:27 +0800124/* record EGL_SUCCESS only when ret evaluates to true */
Chia-I Wubef4b472010-02-19 12:08:50 +0800125#define RETURN_EGL_EVAL(disp, ret) \
126 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800127
128
Chia-I Wubef4b472010-02-19 12:08:50 +0800129/*
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800130 * A bunch of macros and checks to simplify error checking.
131 */
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800132
Chia-I Wubef4b472010-02-19 12:08:50 +0800133#define _EGL_CHECK_DISPLAY(disp, ret, drv) \
134 do { \
Emil Velikovd7800122015-02-28 16:39:10 +0000135 drv = _eglCheckDisplay(disp, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800136 if (!drv) \
137 RETURN_EGL_ERROR(disp, 0, ret); \
138 } while (0)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800139
Chia-I Wubef4b472010-02-19 12:08:50 +0800140#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
141 do { \
Emil Velikovd7800122015-02-28 16:39:10 +0000142 drv = _eglCheck ## type(disp, obj, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800143 if (!drv) \
144 RETURN_EGL_ERROR(disp, 0, ret); \
145 } while (0)
146
147#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
148 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
149
150#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
151 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
152
153#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
154 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
155
Chia-I Wu4eebea72010-08-14 23:09:12 +0800156#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
157 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800158
159
Emil Velikov7bd16932015-02-28 16:35:22 +0000160static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800161_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
162{
163 if (!disp) {
164 _eglError(EGL_BAD_DISPLAY, msg);
165 return NULL;
166 }
167 if (!disp->Initialized) {
168 _eglError(EGL_NOT_INITIALIZED, msg);
169 return NULL;
170 }
171 return disp->Driver;
172}
173
174
Emil Velikov7bd16932015-02-28 16:35:22 +0000175static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800176_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
177{
178 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
179 if (!drv)
180 return NULL;
181 if (!surf) {
182 _eglError(EGL_BAD_SURFACE, msg);
183 return NULL;
184 }
185 return drv;
186}
187
188
Emil Velikov7bd16932015-02-28 16:35:22 +0000189static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800190_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
191{
192 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
193 if (!drv)
194 return NULL;
195 if (!context) {
196 _eglError(EGL_BAD_CONTEXT, msg);
197 return NULL;
198 }
199 return drv;
200}
201
202
Emil Velikov7bd16932015-02-28 16:35:22 +0000203static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800204_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
205{
206 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
207 if (!drv)
208 return NULL;
209 if (!conf) {
210 _eglError(EGL_BAD_CONFIG, msg);
211 return NULL;
212 }
213 return drv;
214}
215
216
Emil Velikov7bd16932015-02-28 16:35:22 +0000217static inline _EGLDriver *
Chia-I Wu4eebea72010-08-14 23:09:12 +0800218_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
219{
220 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
221 if (!drv)
222 return NULL;
223 if (!s) {
224 _eglError(EGL_BAD_PARAMETER, msg);
225 return NULL;
226 }
227 return drv;
228}
229
230
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800231/**
Chia-I Wu655f4652010-02-17 17:30:44 +0800232 * Lookup and lock a display.
233 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000234static inline _EGLDisplay *
Chia-I Wu655f4652010-02-17 17:30:44 +0800235_eglLockDisplay(EGLDisplay display)
236{
237 _EGLDisplay *dpy = _eglLookupDisplay(display);
238 if (dpy)
Emil Velikovefe87f12015-03-06 16:54:55 +0000239 mtx_lock(&dpy->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +0800240 return dpy;
241}
242
243
244/**
245 * Unlock a display.
246 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000247static inline void
Chia-I Wu655f4652010-02-17 17:30:44 +0800248_eglUnlockDisplay(_EGLDisplay *dpy)
249{
Emil Velikovefe87f12015-03-06 16:54:55 +0000250 mtx_unlock(&dpy->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +0800251}
252
253
Chad Versace3e0d5752016-09-27 13:27:17 -0700254/**
255 * Convert an attribute list from EGLint[] to EGLAttrib[].
256 *
257 * Return an EGL error code. The output parameter out_attrib_list is modified
258 * only on success.
259 */
260EGLint
261_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
262{
263 size_t len = 0;
264 EGLAttrib *attrib_list;
265
266 if (int_list) {
267 while (int_list[2*len] != EGL_NONE)
268 ++len;
269 }
270
271 if (len == 0) {
272 *out_attrib_list = NULL;
273 return EGL_SUCCESS;
274 }
275
276 if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
277 return EGL_BAD_ALLOC;
278
279 attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
280 if (!attrib_list)
281 return EGL_BAD_ALLOC;
282
283 for (size_t i = 0; i < len; ++i) {
284 attrib_list[2*i + 0] = int_list[2*i + 0];
285 attrib_list[2*i + 1] = int_list[2*i + 1];
286 }
287
288 attrib_list[2*len] = EGL_NONE;
289
290 *out_attrib_list = attrib_list;
291 return EGL_SUCCESS;
292}
293
294
Marek Olšák515f04e2015-05-12 20:42:05 +0200295static EGLint *
296_eglConvertAttribsToInt(const EGLAttrib *attr_list)
297{
298 EGLint *int_attribs = NULL;
299
300 /* Convert attributes from EGLAttrib[] to EGLint[] */
301 if (attr_list) {
302 int i, size = 0;
303
304 while (attr_list[size] != EGL_NONE)
305 size += 2;
306
307 size += 1; /* add space for EGL_NONE */
308
309 int_attribs = calloc(size, sizeof(int_attribs[0]));
310 if (!int_attribs)
311 return NULL;
312
313 for (i = 0; i < size; i++)
314 int_attribs[i] = attr_list[i];
315 }
316 return int_attribs;
317}
318
319
Chia-I Wu655f4652010-02-17 17:30:44 +0800320/**
Brian Paul6052af12008-05-27 16:48:23 -0600321 * This is typically the first EGL function that an application calls.
Chia-I Wudb5ce8b2010-02-17 18:39:27 +0800322 * It associates a private _EGLDisplay object to the native display.
Brian Pauladbff7e2005-04-22 21:09:39 +0000323 */
Brian Paul1ed10272008-05-27 13:45:41 -0600324EGLDisplay EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +0800325eglGetDisplay(EGLNativeDisplayType nativeDisplay)
Brian Pauladbff7e2005-04-22 21:09:39 +0000326{
Chad Versace6d1f83e2014-01-07 14:54:51 -0800327 _EGLPlatformType plat;
328 _EGLDisplay *dpy;
329 void *native_display_ptr;
330
331 STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
332 native_display_ptr = (void*) nativeDisplay;
333
334 plat = _eglGetNativePlatform(native_display_ptr);
335 dpy = _eglFindDisplay(plat, native_display_ptr);
Brian Paul721ba152008-05-27 14:33:54 -0600336 return _eglGetDisplayHandle(dpy);
Brian Pauladbff7e2005-04-22 21:09:39 +0000337}
338
Kyle Brenneman017946b2016-09-12 16:42:56 -0400339static EGLDisplay
340_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
341 const EGLint *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -0800342{
343 _EGLDisplay *dpy;
344
345 switch (platform) {
346#ifdef HAVE_X11_PLATFORM
347 case EGL_PLATFORM_X11_EXT:
348 dpy = _eglGetX11Display((Display*) native_display, attrib_list);
349 break;
350#endif
351#ifdef HAVE_DRM_PLATFORM
352 case EGL_PLATFORM_GBM_MESA:
353 dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
354 attrib_list);
355 break;
356#endif
357#ifdef HAVE_WAYLAND_PLATFORM
358 case EGL_PLATFORM_WAYLAND_EXT:
359 dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
360 attrib_list);
361 break;
362#endif
363 default:
364 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
365 }
366
367 return _eglGetDisplayHandle(dpy);
368}
Brian Pauladbff7e2005-04-22 21:09:39 +0000369
Kyle Brenneman017946b2016-09-12 16:42:56 -0400370static EGLDisplay EGLAPIENTRY
371eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
372 const EGLint *attrib_list)
373{
374 return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
375}
376
Marek Olšák820a4d42015-05-12 21:06:41 +0200377EGLDisplay EGLAPIENTRY
378eglGetPlatformDisplay(EGLenum platform, void *native_display,
379 const EGLAttrib *attrib_list)
380{
381 EGLDisplay display;
Kyle Brenneman017946b2016-09-12 16:42:56 -0400382 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +0200383
Kyle Brenneman017946b2016-09-12 16:42:56 -0400384 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +0200385 if (attrib_list && !int_attribs)
386 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
387
Kyle Brenneman017946b2016-09-12 16:42:56 -0400388 display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +0200389 free(int_attribs);
390 return display;
391}
392
Brian Paul6052af12008-05-27 16:48:23 -0600393/**
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700394 * Copy the extension into the string and update the string pointer.
395 */
396static EGLint
397_eglAppendExtension(char **str, const char *ext)
398{
399 char *s = *str;
400 size_t len = strlen(ext);
401
402 if (s) {
403 memcpy(s, ext, len);
404 s[len++] = ' ';
405 s[len] = '\0';
406
407 *str += len;
408 }
409 else {
410 len++;
411 }
412
413 return (EGLint) len;
414}
415
416/**
417 * Examine the individual extension enable/disable flags and recompute
418 * the driver's Extensions string.
419 */
420static void
421_eglCreateExtensionsString(_EGLDisplay *dpy)
422{
423#define _EGL_CHECK_EXTENSION(ext) \
424 do { \
425 if (dpy->Extensions.ext) { \
426 _eglAppendExtension(&exts, "EGL_" #ext); \
427 assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
428 } \
429 } while (0)
430
431 char *exts = dpy->ExtensionsString;
432
Marek Olšák32aa1d72015-06-09 23:08:57 +0200433 /* Please keep these sorted alphabetically. */
Rob Herring89755272016-02-02 14:23:07 -0600434 _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700435 _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
Rob Herringe21e81a2016-02-02 14:23:08 -0600436 _EGL_CHECK_EXTENSION(ANDROID_recordable);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700437
438 _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
439
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700440 _EGL_CHECK_EXTENSION(EXT_buffer_age);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200441 _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700442 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200443 _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
444
445 _EGL_CHECK_EXTENSION(KHR_cl_event2);
446 _EGL_CHECK_EXTENSION(KHR_create_context);
447 _EGL_CHECK_EXTENSION(KHR_fence_sync);
448 _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
449 _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
450 _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
451 _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
452 _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
453 _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
454 if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
455 _eglAppendExtension(&exts, "EGL_KHR_image");
456 _EGL_CHECK_EXTENSION(KHR_image_base);
457 _EGL_CHECK_EXTENSION(KHR_image_pixmap);
Adam Jacksond9f5b192016-09-09 12:25:34 -0400458 _EGL_CHECK_EXTENSION(KHR_no_config_context);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200459 _EGL_CHECK_EXTENSION(KHR_reusable_sync);
460 _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200461 _EGL_CHECK_EXTENSION(KHR_wait_sync);
462
Adam Jacksond9f5b192016-09-09 12:25:34 -0400463 if (dpy->Extensions.KHR_no_config_context)
464 _eglAppendExtension(&exts, "EGL_MESA_configless_context");
Marek Olšák32aa1d72015-06-09 23:08:57 +0200465 _EGL_CHECK_EXTENSION(MESA_drm_image);
466 _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
467
468 _EGL_CHECK_EXTENSION(NOK_swap_region);
469 _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700470
471 _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
Dave Airlie8f7338f2014-03-03 13:57:16 +1000472
Marek Olšák32aa1d72015-06-09 23:08:57 +0200473 _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
474 _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
475
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700476#undef _EGL_CHECK_EXTENSION
477}
478
479static void
480_eglCreateAPIsString(_EGLDisplay *dpy)
481{
482 if (dpy->ClientAPIs & EGL_OPENGL_BIT)
483 strcat(dpy->ClientAPIsString, "OpenGL ");
484
Plamena Manolova21edd242016-05-12 18:21:38 +0100485 if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||
486 dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||
487 dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700488 strcat(dpy->ClientAPIsString, "OpenGL_ES ");
Plamena Manolova21edd242016-05-12 18:21:38 +0100489 }
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700490
491 if (dpy->ClientAPIs & EGL_OPENVG_BIT)
492 strcat(dpy->ClientAPIsString, "OpenVG ");
493
494 assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
495}
496
Marek Olšákefda9c52015-05-11 22:16:52 +0200497static void
498_eglComputeVersion(_EGLDisplay *disp)
499{
Marek Olšák0e4b5642015-05-12 16:40:29 +0200500 disp->Version = 14;
Marek Olšáka1cb4072015-05-11 22:18:04 +0200501
502 if (disp->Extensions.KHR_fence_sync &&
503 disp->Extensions.KHR_cl_event2 &&
504 disp->Extensions.KHR_wait_sync &&
505 disp->Extensions.KHR_image_base &&
506 disp->Extensions.KHR_gl_texture_2D_image &&
507 disp->Extensions.KHR_gl_texture_3D_image &&
508 disp->Extensions.KHR_gl_texture_cubemap_image &&
509 disp->Extensions.KHR_gl_renderbuffer_image &&
510 disp->Extensions.KHR_create_context &&
511 disp->Extensions.EXT_create_context_robustness &&
512 disp->Extensions.KHR_get_all_proc_addresses &&
513 disp->Extensions.KHR_gl_colorspace &&
514 disp->Extensions.KHR_surfaceless_context)
515 disp->Version = 15;
Marek Olšákefda9c52015-05-11 22:16:52 +0200516}
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700517
518/**
Brian Paul6052af12008-05-27 16:48:23 -0600519 * This is typically the second EGL function that an application calls.
520 * Here we load/initialize the actual hardware driver.
521 */
Brian Paul1ed10272008-05-27 13:45:41 -0600522EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000523eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
524{
Chia-I Wu655f4652010-02-17 17:30:44 +0800525 _EGLDisplay *disp = _eglLockDisplay(dpy);
Jonathan White7e2458c2008-08-06 13:40:03 -0600526
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800527 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800528 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Brian Paulc56e15b2008-05-28 15:43:41 -0600529
Chia-I Wua9332592010-01-27 23:55:58 +0800530 if (!disp->Initialized) {
Chia-I Wuf2aa3612010-07-04 15:55:12 +0800531 if (!_eglMatchDriver(disp, EGL_FALSE))
532 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
Chia-I Wu57929ed2010-01-19 18:29:21 +0800533
Chia-I Wu310c7682009-08-17 15:53:54 +0800534 /* limit to APIs supported by core */
Chia-I Wua4a38dc2011-01-13 16:53:13 +0800535 disp->ClientAPIs &= _EGL_API_ALL_BITS;
Chad Versace7e8ba772014-11-20 10:26:38 -0800536
537 /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
538 * classifies it as an EGL display extension, though conceptually it's an
539 * EGL client extension.
540 *
541 * From the EGL_KHR_get_all_proc_addresses spec:
542 *
543 * The EGL implementation must expose the name
544 * EGL_KHR_client_get_all_proc_addresses if and only if it exposes
545 * EGL_KHR_get_all_proc_addresses and supports
546 * EGL_EXT_client_extensions.
547 *
548 * Mesa unconditionally exposes both client extensions mentioned above,
549 * so the spec requires that each EGLDisplay unconditionally expose
550 * EGL_KHR_get_all_proc_addresses also.
551 */
552 disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700553
Marek Olšákefda9c52015-05-11 22:16:52 +0200554 _eglComputeVersion(disp);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700555 _eglCreateExtensionsString(disp);
556 _eglCreateAPIsString(disp);
Emil Velikov3593f372015-07-14 00:19:54 +0100557 snprintf(disp->VersionString, sizeof(disp->VersionString),
Marek Olšák0e4b5642015-05-12 16:40:29 +0200558 "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700559 disp->Driver->Name);
Brian Pauladbff7e2005-04-22 21:09:39 +0000560 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800561
562 /* Update applications version of major and minor if not NULL */
563 if ((major != NULL) && (minor != NULL)) {
Marek Olšák0e4b5642015-05-12 16:40:29 +0200564 *major = disp->Version / 10;
565 *minor = disp->Version % 10;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800566 }
567
Chia-I Wubef4b472010-02-19 12:08:50 +0800568 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000569}
570
571
Brian Paul1ed10272008-05-27 13:45:41 -0600572EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000573eglTerminate(EGLDisplay dpy)
574{
Chia-I Wu655f4652010-02-17 17:30:44 +0800575 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800576
577 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800578 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800579
Chia-I Wua9332592010-01-27 23:55:58 +0800580 if (disp->Initialized) {
581 _EGLDriver *drv = disp->Driver;
582
Chia-I Wuccc2b0b2009-08-13 13:39:51 +0800583 drv->API.Terminate(drv, disp);
Chia-I Wua9332592010-01-27 23:55:58 +0800584 /* do not reset disp->Driver */
Dave Airlie37e3a112015-03-16 15:21:55 +1000585 disp->ClientAPIsString[0] = 0;
Chia-I Wua9332592010-01-27 23:55:58 +0800586 disp->Initialized = EGL_FALSE;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800587 }
588
Chia-I Wubef4b472010-02-19 12:08:50 +0800589 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000590}
591
592
Brian Paul1ed10272008-05-27 13:45:41 -0600593const char * EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000594eglQueryString(EGLDisplay dpy, EGLint name)
595{
Chad Versace3c58d4c2013-10-11 16:04:55 -0700596 _EGLDisplay *disp;
Chia-I Wuaed73582010-02-17 15:43:47 +0800597 _EGLDriver *drv;
598
Chad Versace3c58d4c2013-10-11 16:04:55 -0700599 if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
600 RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
601 }
602
603 disp = _eglLockDisplay(dpy);
Chia-I Wubef4b472010-02-19 12:08:50 +0800604 _EGL_CHECK_DISPLAY(disp, NULL, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800605
Matt Turner6c6e2a12015-03-13 17:00:26 -0700606 switch (name) {
607 case EGL_VENDOR:
608 RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
609 case EGL_VERSION:
610 RETURN_EGL_SUCCESS(disp, disp->VersionString);
611 case EGL_EXTENSIONS:
612 RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
613 case EGL_CLIENT_APIS:
614 RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
615 default:
616 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
617 }
Brian Pauladbff7e2005-04-22 21:09:39 +0000618}
619
620
Brian Paul1ed10272008-05-27 13:45:41 -0600621EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800622eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
623 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000624{
Chia-I Wu655f4652010-02-17 17:30:44 +0800625 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800626 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800627 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800628
Chia-I Wubef4b472010-02-19 12:08:50 +0800629 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800630 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
631
Chia-I Wubef4b472010-02-19 12:08:50 +0800632 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000633}
634
635
Brian Paul1ed10272008-05-27 13:45:41 -0600636EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800637eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
638 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000639{
Chia-I Wu655f4652010-02-17 17:30:44 +0800640 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800641 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800642 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800643
Chia-I Wubef4b472010-02-19 12:08:50 +0800644 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800645 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800646 config_size, num_config);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800647
Chia-I Wubef4b472010-02-19 12:08:50 +0800648 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000649}
650
651
Brian Paul1ed10272008-05-27 13:45:41 -0600652EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800653eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
654 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000655{
Chia-I Wu655f4652010-02-17 17:30:44 +0800656 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800657 _EGLConfig *conf = _eglLookupConfig(config, disp);
658 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800659 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800660
Chia-I Wubef4b472010-02-19 12:08:50 +0800661 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800662 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
663
Chia-I Wubef4b472010-02-19 12:08:50 +0800664 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000665}
666
667
Brian Paul1ed10272008-05-27 13:45:41 -0600668EGLContext EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800669eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
670 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000671{
Chia-I Wu655f4652010-02-17 17:30:44 +0800672 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800673 _EGLConfig *conf = _eglLookupConfig(config, disp);
674 _EGLContext *share = _eglLookupContext(share_list, disp);
675 _EGLDriver *drv;
676 _EGLContext *context;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800677 EGLContext ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800678
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800679 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
680
Adam Jacksond9f5b192016-09-09 12:25:34 -0400681 if (!config && !disp->Extensions.KHR_no_config_context)
Neil Roberts4b17dff2014-03-07 18:05:46 +0000682 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
Kristian Høgsbergb90a3e72010-06-02 22:48:06 -0400683
Chia-I Wub3bb1802010-02-17 16:05:27 +0800684 if (!share && share_list != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800685 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800686
687 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +0800688 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800689
Chia-I Wubef4b472010-02-19 12:08:50 +0800690 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000691}
692
693
Brian Paul1ed10272008-05-27 13:45:41 -0600694EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000695eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
696{
Chia-I Wu655f4652010-02-17 17:30:44 +0800697 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800698 _EGLContext *context = _eglLookupContext(ctx, disp);
699 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800700 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800701
Chia-I Wubef4b472010-02-19 12:08:50 +0800702 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800703 _eglUnlinkContext(context);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800704 ret = drv->API.DestroyContext(drv, disp, context);
705
Chia-I Wubef4b472010-02-19 12:08:50 +0800706 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000707}
708
709
Brian Paul1ed10272008-05-27 13:45:41 -0600710EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800711eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
712 EGLContext ctx)
Brian Pauladbff7e2005-04-22 21:09:39 +0000713{
Chia-I Wu655f4652010-02-17 17:30:44 +0800714 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800715 _EGLContext *context = _eglLookupContext(ctx, disp);
716 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
717 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
718 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800719 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800720
Chia-I Wu17330472010-01-27 23:51:54 +0800721 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800722 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800723 drv = disp->Driver;
724
725 /* display is allowed to be uninitialized under certain condition */
726 if (!disp->Initialized) {
727 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
728 ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800729 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800730 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800731 if (!drv)
Chia-I Wubef4b472010-02-19 12:08:50 +0800732 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Chia-I Wu17330472010-01-27 23:51:54 +0800733
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800734 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800735 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800736 if (!draw_surf || !read_surf) {
Beren Minor0ca0d572014-03-20 08:36:34 +0100737 /* From the EGL 1.4 (20130211) spec:
738 *
739 * To release the current context without assigning a new one, set ctx
740 * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
741 */
742 if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800743 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
744
745 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
746 (!read_surf && read != EGL_NO_SURFACE))
747 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
748 if (draw_surf || read_surf)
749 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
750 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800751
Chia-I Wub3bb1802010-02-17 16:05:27 +0800752 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
753
Chia-I Wubef4b472010-02-19 12:08:50 +0800754 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000755}
756
757
Brian Paul1ed10272008-05-27 13:45:41 -0600758EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800759eglQueryContext(EGLDisplay dpy, EGLContext ctx,
760 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000761{
Chia-I Wu655f4652010-02-17 17:30:44 +0800762 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800763 _EGLContext *context = _eglLookupContext(ctx, disp);
764 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800765 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800766
Chia-I Wubef4b472010-02-19 12:08:50 +0800767 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800768 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
769
Chia-I Wubef4b472010-02-19 12:08:50 +0800770 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000771}
772
773
Chad Versace468cc862014-01-23 07:26:10 -0800774static EGLSurface
775_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
776 void *native_window, const EGLint *attrib_list)
777{
778 _EGLConfig *conf = _eglLookupConfig(config, disp);
779 _EGLDriver *drv;
780 _EGLSurface *surf;
781 EGLSurface ret;
782
783 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Sinclair Yeh91ff0d42014-06-03 14:00:13 -0700784
785 if (native_window == NULL)
786 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
787
Chad Versace468cc862014-01-23 07:26:10 -0800788 surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
789 attrib_list);
790 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
791
792 RETURN_EGL_EVAL(disp, ret);
793}
794
795
Brian Paul1ed10272008-05-27 13:45:41 -0600796EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800797eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +0800798 EGLNativeWindowType window, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000799{
Chia-I Wu655f4652010-02-17 17:30:44 +0800800 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chad Versace468cc862014-01-23 07:26:10 -0800801 STATIC_ASSERT(sizeof(void*) == sizeof(window));
802 return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
803 attrib_list);
804}
805
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400806static void *
807fixupNativeWindow(_EGLDisplay *disp, void *native_window)
Chad Versace468cc862014-01-23 07:26:10 -0800808{
Chad Versace468cc862014-01-23 07:26:10 -0800809#ifdef HAVE_X11_PLATFORM
810 if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
811 /* The `native_window` parameter for the X11 platform differs between
812 * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
813 * eglCreateWindowSurface(), the type of `native_window` is an Xlib
814 * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
815 * `Window*`. Convert `Window*` to `Window` because that's what
816 * dri2_x11_create_window_surface() expects.
817 */
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400818 return (void *)(* (Window*) native_window);
Chad Versace468cc862014-01-23 07:26:10 -0800819 }
820#endif
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400821 return native_window;
822}
823
824static EGLSurface EGLAPIENTRY
825eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
826 void *native_window,
827 const EGLint *attrib_list)
828{
829 _EGLDisplay *disp = _eglLockDisplay(dpy);
830
831 native_window = fixupNativeWindow(disp, native_window);
Chad Versace468cc862014-01-23 07:26:10 -0800832
833 return _eglCreateWindowSurfaceCommon(disp, config, native_window,
834 attrib_list);
835}
836
837
Marek Olšák820a4d42015-05-12 21:06:41 +0200838EGLSurface EGLAPIENTRY
839eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
840 void *native_window,
841 const EGLAttrib *attrib_list)
842{
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400843 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +0200844 EGLSurface surface;
845 EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
846
847 if (attrib_list && !int_attribs)
848 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
849
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400850 native_window = fixupNativeWindow(disp, native_window);
851 surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
852 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +0200853 free(int_attribs);
854 return surface;
855}
856
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400857static void *
858fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
859{
860#ifdef HAVE_X11_PLATFORM
861 /* The `native_pixmap` parameter for the X11 platform differs between
862 * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
863 * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
864 * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
865 * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
866 * dri2_x11_create_pixmap_surface() expects.
867 */
868 if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
869 return (void *)(* (Pixmap*) native_pixmap);
870#endif
871 return native_pixmap;
872}
Marek Olšák820a4d42015-05-12 21:06:41 +0200873
Chad Versace468cc862014-01-23 07:26:10 -0800874static EGLSurface
875_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
876 void *native_pixmap, const EGLint *attrib_list)
877{
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800878 _EGLConfig *conf = _eglLookupConfig(config, disp);
879 _EGLDriver *drv;
880 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800881 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800882
Chia-I Wubef4b472010-02-19 12:08:50 +0800883 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chad Versace468cc862014-01-23 07:26:10 -0800884 surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
Chad Versace6d1f83e2014-01-07 14:54:51 -0800885 attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +0800886 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800887
Chia-I Wubef4b472010-02-19 12:08:50 +0800888 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000889}
890
891
Brian Paul1ed10272008-05-27 13:45:41 -0600892EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800893eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +0800894 EGLNativePixmapType pixmap, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000895{
Chia-I Wu655f4652010-02-17 17:30:44 +0800896 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chad Versace6d1f83e2014-01-07 14:54:51 -0800897 STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
Chad Versace468cc862014-01-23 07:26:10 -0800898 return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
899 attrib_list);
900}
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800901
Emil Velikove3cc5ad2015-05-11 23:43:48 +0100902static EGLSurface EGLAPIENTRY
Chad Versace468cc862014-01-23 07:26:10 -0800903eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
904 void *native_pixmap,
905 const EGLint *attrib_list)
906{
907 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800908
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400909 native_pixmap = fixupNativePixmap(disp, native_pixmap);
Chad Versace468cc862014-01-23 07:26:10 -0800910 return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
911 attrib_list);
Brian Pauladbff7e2005-04-22 21:09:39 +0000912}
913
914
Brian Paul1ed10272008-05-27 13:45:41 -0600915EGLSurface EGLAPIENTRY
Marek Olšák820a4d42015-05-12 21:06:41 +0200916eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
917 void *native_pixmap,
918 const EGLAttrib *attrib_list)
919{
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400920 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +0200921 EGLSurface surface;
922 EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
923
924 if (attrib_list && !int_attribs)
925 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
926
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400927 native_pixmap = fixupNativePixmap(disp, native_pixmap);
928 surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
929 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +0200930 free(int_attribs);
931 return surface;
932}
933
934
935EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800936eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
937 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000938{
Chia-I Wu655f4652010-02-17 17:30:44 +0800939 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800940 _EGLConfig *conf = _eglLookupConfig(config, disp);
941 _EGLDriver *drv;
942 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800943 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800944
Chia-I Wubef4b472010-02-19 12:08:50 +0800945 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800946
947 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +0800948 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800949
Chia-I Wubef4b472010-02-19 12:08:50 +0800950 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000951}
952
953
Brian Paul1ed10272008-05-27 13:45:41 -0600954EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000955eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
956{
Chia-I Wu655f4652010-02-17 17:30:44 +0800957 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800958 _EGLSurface *surf = _eglLookupSurface(surface, disp);
959 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800960 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800961
Chia-I Wubef4b472010-02-19 12:08:50 +0800962 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800963 _eglUnlinkSurface(surf);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800964 ret = drv->API.DestroySurface(drv, disp, surf);
965
Chia-I Wubef4b472010-02-19 12:08:50 +0800966 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000967}
968
Brian Paul1ed10272008-05-27 13:45:41 -0600969EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800970eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
971 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000972{
Chia-I Wu655f4652010-02-17 17:30:44 +0800973 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800974 _EGLSurface *surf = _eglLookupSurface(surface, disp);
975 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800976 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800977
Chia-I Wubef4b472010-02-19 12:08:50 +0800978 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800979 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
980
Chia-I Wubef4b472010-02-19 12:08:50 +0800981 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000982}
983
Brian Paul1ed10272008-05-27 13:45:41 -0600984EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800985eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
986 EGLint attribute, EGLint value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000987{
Chia-I Wu655f4652010-02-17 17:30:44 +0800988 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800989 _EGLSurface *surf = _eglLookupSurface(surface, disp);
990 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800991 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800992
Chia-I Wubef4b472010-02-19 12:08:50 +0800993 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800994 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
995
Chia-I Wubef4b472010-02-19 12:08:50 +0800996 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000997}
998
999
Brian Paul1ed10272008-05-27 13:45:41 -06001000EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001001eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1002{
Chia-I Wu655f4652010-02-17 17:30:44 +08001003 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001004 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1005 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001006 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001007
Chia-I Wubef4b472010-02-19 12:08:50 +08001008 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001009 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
1010
Chia-I Wubef4b472010-02-19 12:08:50 +08001011 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001012}
1013
1014
Brian Paul1ed10272008-05-27 13:45:41 -06001015EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001016eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1017{
Chia-I Wu655f4652010-02-17 17:30:44 +08001018 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001019 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1020 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001021 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001022
Chia-I Wubef4b472010-02-19 12:08:50 +08001023 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001024 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
1025
Chia-I Wubef4b472010-02-19 12:08:50 +08001026 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001027}
1028
1029
Brian Paul1ed10272008-05-27 13:45:41 -06001030EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001031eglSwapInterval(EGLDisplay dpy, EGLint interval)
1032{
Chia-I Wu655f4652010-02-17 17:30:44 +08001033 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu57da4992009-10-15 11:08:48 +08001034 _EGLContext *ctx = _eglGetCurrentContext();
1035 _EGLSurface *surf;
Chia-I Wuaed73582010-02-17 15:43:47 +08001036 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001037 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001038
Chia-I Wubef4b472010-02-19 12:08:50 +08001039 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu57da4992009-10-15 11:08:48 +08001040
Chia-I Wud19afc52010-10-23 12:52:26 +08001041 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1042 ctx->Resource.Display != disp)
Chia-I Wubef4b472010-02-19 12:08:50 +08001043 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001044
1045 surf = ctx->DrawSurface;
Chia-I Wud19afc52010-10-23 12:52:26 +08001046 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001047 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001048
Chia-I Wub3bb1802010-02-17 16:05:27 +08001049 ret = drv->API.SwapInterval(drv, disp, surf, interval);
1050
Chia-I Wubef4b472010-02-19 12:08:50 +08001051 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001052}
1053
1054
Brian Paul1ed10272008-05-27 13:45:41 -06001055EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001056eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
Brian Pauladbff7e2005-04-22 21:09:39 +00001057{
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001058 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu655f4652010-02-17 17:30:44 +08001059 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001060 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1061 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001062 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001063
Chia-I Wubef4b472010-02-19 12:08:50 +08001064 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001065
1066 /* surface must be bound to current context in EGL 1.4 */
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001067 #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
Chia-I Wud19afc52010-10-23 12:52:26 +08001068 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1069 surf != ctx->DrawSurface)
Chia-I Wubef4b472010-02-19 12:08:50 +08001070 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001071 #endif
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001072
Chia-I Wub3bb1802010-02-17 16:05:27 +08001073 ret = drv->API.SwapBuffers(drv, disp, surf);
1074
Chia-I Wubef4b472010-02-19 12:08:50 +08001075 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001076}
1077
1078
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001079static EGLBoolean EGLAPIENTRY
Robert Bragg6425b142013-04-25 13:41:42 +01001080eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
1081 EGLint *rects, EGLint n_rects)
1082{
1083 _EGLContext *ctx = _eglGetCurrentContext();
1084 _EGLDisplay *disp = _eglLockDisplay(dpy);
1085 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1086 _EGLDriver *drv;
1087 EGLBoolean ret;
1088
1089 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1090
1091 /* surface must be bound to current context in EGL 1.4 */
1092 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1093 surf != ctx->DrawSurface)
1094 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1095
1096 if ((n_rects > 0 && rects == NULL) || n_rects < 0)
1097 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1098
1099 ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
1100
1101 RETURN_EGL_EVAL(disp, ret);
1102}
1103
Brian Paul1ed10272008-05-27 13:45:41 -06001104EGLBoolean EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +08001105eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
Brian Pauladbff7e2005-04-22 21:09:39 +00001106{
Chia-I Wu655f4652010-02-17 17:30:44 +08001107 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001108 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1109 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001110 EGLBoolean ret;
Chad Versace6d1f83e2014-01-07 14:54:51 -08001111 void *native_pixmap_ptr;
1112
1113 STATIC_ASSERT(sizeof(void*) == sizeof(target));
1114 native_pixmap_ptr = (void*) target;
Chia-I Wuaed73582010-02-17 15:43:47 +08001115
Chia-I Wubef4b472010-02-19 12:08:50 +08001116 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Benjamin Franzke85fe9482011-08-09 14:23:18 +02001117 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
Chia-I Wuf22665d2010-06-17 17:14:03 +08001118 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001119 ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001120
Chia-I Wubef4b472010-02-19 12:08:50 +08001121 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001122}
1123
1124
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001125static EGLBoolean
1126_eglWaitClientCommon(void)
Brian Pauladbff7e2005-04-22 21:09:39 +00001127{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001128 _EGLContext *ctx = _eglGetCurrentContext();
1129 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001130 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001131 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001132
Chia-I Wu6c21c882009-09-28 14:12:39 +08001133 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001134 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001135
1136 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001137 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001138
1139 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001140 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1141 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001142 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001143
Chia-I Wu6c21c882009-09-28 14:12:39 +08001144 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001145 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001146 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001147 ret = drv->API.WaitClient(drv, disp, ctx);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001148
Chia-I Wubef4b472010-02-19 12:08:50 +08001149 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu6c21c882009-09-28 14:12:39 +08001150}
1151
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001152EGLBoolean EGLAPIENTRY
1153eglWaitClient(void)
1154{
1155 return _eglWaitClientCommon();
1156}
Chia-I Wu6c21c882009-09-28 14:12:39 +08001157
1158EGLBoolean EGLAPIENTRY
1159eglWaitGL(void)
1160{
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001161 /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001162 return _eglWaitClientCommon();
Brian Pauladbff7e2005-04-22 21:09:39 +00001163}
1164
1165
Brian Paul1ed10272008-05-27 13:45:41 -06001166EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001167eglWaitNative(EGLint engine)
1168{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001169 _EGLContext *ctx = _eglGetCurrentContext();
1170 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001171 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001172 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001173
Chia-I Wu6c21c882009-09-28 14:12:39 +08001174 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001175 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001176
Chia-I Wu655f4652010-02-17 17:30:44 +08001177 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001178 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001179
Chia-I Wu6c21c882009-09-28 14:12:39 +08001180 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001181 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1182 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001183 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001184
Chia-I Wu6c21c882009-09-28 14:12:39 +08001185 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001186 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001187 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001188 ret = drv->API.WaitNative(drv, disp, engine);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001189
Chia-I Wubef4b472010-02-19 12:08:50 +08001190 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001191}
1192
1193
Brian Paul1ed10272008-05-27 13:45:41 -06001194EGLDisplay EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001195eglGetCurrentDisplay(void)
1196{
Chia-I Wua1717972010-01-26 17:13:51 +08001197 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001198 EGLDisplay ret;
1199
1200 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
1201
Chia-I Wubef4b472010-02-19 12:08:50 +08001202 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001203}
1204
1205
Brian Paul1ed10272008-05-27 13:45:41 -06001206EGLContext EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001207eglGetCurrentContext(void)
1208{
1209 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001210 EGLContext ret;
1211
1212 ret = _eglGetContextHandle(ctx);
1213
Chia-I Wubef4b472010-02-19 12:08:50 +08001214 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001215}
1216
1217
Brian Paul1ed10272008-05-27 13:45:41 -06001218EGLSurface EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001219eglGetCurrentSurface(EGLint readdraw)
1220{
Chia-I Wu61906632009-09-30 15:34:45 +08001221 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001222 EGLint err = EGL_SUCCESS;
Chia-I Wu61906632009-09-30 15:34:45 +08001223 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001224 EGLSurface ret;
Chia-I Wu61906632009-09-30 15:34:45 +08001225
1226 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001227 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
Chia-I Wu61906632009-09-30 15:34:45 +08001228
1229 switch (readdraw) {
1230 case EGL_DRAW:
1231 surf = ctx->DrawSurface;
1232 break;
1233 case EGL_READ:
1234 surf = ctx->ReadSurface;
1235 break;
1236 default:
Chia-I Wu61906632009-09-30 15:34:45 +08001237 surf = NULL;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001238 err = EGL_BAD_PARAMETER;
Chia-I Wu61906632009-09-30 15:34:45 +08001239 break;
1240 }
1241
Chia-I Wub3bb1802010-02-17 16:05:27 +08001242 ret = _eglGetSurfaceHandle(surf);
1243
Chia-I Wubef4b472010-02-19 12:08:50 +08001244 RETURN_EGL_ERROR(NULL, err, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001245}
1246
1247
Brian Paul1ed10272008-05-27 13:45:41 -06001248EGLint EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001249eglGetError(void)
1250{
Brian Paul48822792005-12-10 17:54:00 +00001251 _EGLThreadInfo *t = _eglGetCurrentThread();
1252 EGLint e = t->LastError;
Chia-I Wu75da80b2009-07-17 11:41:02 -06001253 if (!_eglIsCurrentThreadDummy())
1254 t->LastError = EGL_SUCCESS;
Brian Pauladbff7e2005-04-22 21:09:39 +00001255 return e;
1256}
1257
1258
Brian Paulb2006a42006-01-30 00:10:55 +00001259/**
1260 ** EGL 1.2
1261 **/
1262
Brian Pauld5078b92008-05-30 13:45:40 -06001263/**
1264 * Specify the client API to use for subsequent calls including:
1265 * eglCreateContext()
1266 * eglGetCurrentContext()
1267 * eglGetCurrentDisplay()
1268 * eglGetCurrentSurface()
1269 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1270 * eglWaitClient()
1271 * eglWaitNative()
1272 * See section 3.7 "Rendering Context" in the EGL specification for details.
1273 */
nobledc43ab4f2010-07-02 19:38:07 -04001274EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001275eglBindAPI(EGLenum api)
1276{
1277 _EGLThreadInfo *t = _eglGetCurrentThread();
1278
Chia-I Wu75da80b2009-07-17 11:41:02 -06001279 if (_eglIsCurrentThreadDummy())
Chia-I Wubef4b472010-02-19 12:08:50 +08001280 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
Chia-I Wu75da80b2009-07-17 11:41:02 -06001281
Chia-I Wu21b635f2009-07-17 11:42:04 -06001282 if (!_eglIsApiValid(api))
Chia-I Wubef4b472010-02-19 12:08:50 +08001283 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wu21b635f2009-07-17 11:42:04 -06001284
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001285 t->CurrentAPI = api;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001286
Chia-I Wubef4b472010-02-19 12:08:50 +08001287 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001288}
Jon Smirl7012d012005-05-13 18:31:35 +00001289
1290
Brian Pauld5078b92008-05-30 13:45:40 -06001291/**
1292 * Return the last value set with eglBindAPI().
1293 */
nobledc43ab4f2010-07-02 19:38:07 -04001294EGLenum EGLAPIENTRY
Brian Pauld5078b92008-05-30 13:45:40 -06001295eglQueryAPI(void)
1296{
Brian Pauld5078b92008-05-30 13:45:40 -06001297 _EGLThreadInfo *t = _eglGetCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001298 EGLenum ret;
1299
1300 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001301 ret = t->CurrentAPI;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001302
Chia-I Wubef4b472010-02-19 12:08:50 +08001303 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauld5078b92008-05-30 13:45:40 -06001304}
1305
1306
nobledc43ab4f2010-07-02 19:38:07 -04001307EGLSurface EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001308eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1309 EGLClientBuffer buffer, EGLConfig config,
1310 const EGLint *attrib_list)
1311{
Chia-I Wu655f4652010-02-17 17:30:44 +08001312 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001313 _EGLConfig *conf = _eglLookupConfig(config, disp);
1314 _EGLDriver *drv;
1315 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001316 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001317
Chia-I Wubef4b472010-02-19 12:08:50 +08001318 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001319
1320 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1321 conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001322 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001323
Chia-I Wubef4b472010-02-19 12:08:50 +08001324 RETURN_EGL_EVAL(disp, ret);
Brian Paulb2006a42006-01-30 00:10:55 +00001325}
Jon Smirl7012d012005-05-13 18:31:35 +00001326
Brian Paulb2006a42006-01-30 00:10:55 +00001327
nobledc43ab4f2010-07-02 19:38:07 -04001328EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001329eglReleaseThread(void)
1330{
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001331 /* unbind current contexts */
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001332 if (!_eglIsCurrentThreadDummy()) {
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001333 _EGLThreadInfo *t = _eglGetCurrentThread();
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001334
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001335 _EGLContext *ctx = t->CurrentContext;
1336 if (ctx) {
1337 _EGLDisplay *disp = ctx->Resource.Display;
1338 _EGLDriver *drv;
Chia-I Wu655f4652010-02-17 17:30:44 +08001339
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001340 mtx_lock(&disp->Mutex);
1341 drv = disp->Driver;
1342 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1343 mtx_unlock(&disp->Mutex);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001344 }
Brian Paulb2006a42006-01-30 00:10:55 +00001345 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001346
Chia-I Wu75da80b2009-07-17 11:41:02 -06001347 _eglDestroyCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001348
Chia-I Wubef4b472010-02-19 12:08:50 +08001349 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001350}
1351
1352
Kyle Brenneman58338c62016-09-12 17:38:13 -04001353static EGLImage
1354_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001355 EGLClientBuffer buffer, const EGLint *attr_list)
1356{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001357 _EGLContext *context = _eglLookupContext(ctx, disp);
1358 _EGLDriver *drv;
1359 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02001360 EGLImage ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001361
Chia-I Wubef4b472010-02-19 12:08:50 +08001362 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001363 if (!disp->Extensions.KHR_image_base)
1364 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001365 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +08001366 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
Topi Pohjolainen0de013b2013-03-22 14:31:01 +02001367 /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1368 * <ctx> must be EGL_NO_CONTEXT..."
1369 */
1370 if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1371 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001372
1373 img = drv->API.CreateImageKHR(drv,
1374 disp, context, target, buffer, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001375 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001376
Chia-I Wubef4b472010-02-19 12:08:50 +08001377 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001378}
1379
Kyle Brenneman58338c62016-09-12 17:38:13 -04001380static EGLImage EGLAPIENTRY
1381eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1382 EGLClientBuffer buffer, const EGLint *attr_list)
1383{
1384 _EGLDisplay *disp = _eglLockDisplay(dpy);
1385 return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
1386}
1387
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001388
Marek Olšák515f04e2015-05-12 20:42:05 +02001389EGLImage EGLAPIENTRY
1390eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1391 EGLClientBuffer buffer, const EGLAttrib *attr_list)
1392{
Kyle Brenneman58338c62016-09-12 17:38:13 -04001393 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák515f04e2015-05-12 20:42:05 +02001394 EGLImage image;
1395 EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
1396
1397 if (attr_list && !int_attribs)
Kyle Brenneman58338c62016-09-12 17:38:13 -04001398 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
Marek Olšák515f04e2015-05-12 20:42:05 +02001399
Kyle Brenneman58338c62016-09-12 17:38:13 -04001400 image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
Marek Olšák515f04e2015-05-12 20:42:05 +02001401 free(int_attribs);
1402 return image;
1403}
1404
1405
Marek Olšák2885ba02015-05-12 20:54:22 +02001406EGLBoolean EGLAPIENTRY
1407eglDestroyImage(EGLDisplay dpy, EGLImage image)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001408{
Chia-I Wu655f4652010-02-17 17:30:44 +08001409 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001410 _EGLImage *img = _eglLookupImage(image, disp);
1411 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001412 EGLBoolean ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001413
Chia-I Wubef4b472010-02-19 12:08:50 +08001414 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001415 if (!disp->Extensions.KHR_image_base)
1416 RETURN_EGL_EVAL(disp, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001417 if (!img)
Chia-I Wubef4b472010-02-19 12:08:50 +08001418 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001419
1420 _eglUnlinkImage(img);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001421 ret = drv->API.DestroyImageKHR(drv, disp, img);
1422
Chia-I Wubef4b472010-02-19 12:08:50 +08001423 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001424}
1425
1426
Marek Olšákd333d302015-05-12 17:34:57 +02001427static EGLSync
Kyle Brenneman9a992032016-09-12 17:40:29 -04001428_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLint *attrib_list,
Marek Olšák51c8c662015-05-12 21:41:32 +02001429 const EGLAttrib *attrib_list64, EGLBoolean is64,
1430 EGLenum invalid_type_error)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001431{
Marek Olšák9a0bda22015-04-10 10:56:02 +02001432 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu4eebea72010-08-14 23:09:12 +08001433 _EGLDriver *drv;
1434 _EGLSync *sync;
Marek Olšákd333d302015-05-12 17:34:57 +02001435 EGLSync ret;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001436
1437 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001438
Chad Versacef2c2f432016-09-27 13:27:12 -07001439 if (!disp->Extensions.KHR_cl_event2 && is64) {
1440 /* There exist two EGLAttrib variants of eglCreateSync*:
1441 * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
1442 * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
1443 * support as a proxy for EGL 1.5 support, even though that's not
1444 * entirely correct (though _eglComputeVersion does the same).
1445 *
1446 * The EGL spec provides no guidance on how to handle unsupported
1447 * functions. EGL_BAD_MATCH seems reasonable.
1448 */
1449 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1450 }
Marek Olšák290a3eb2015-04-10 13:16:30 +02001451
Marek Olšák9a0bda22015-04-10 10:56:02 +02001452 /* return an error if the client API doesn't support GL_OES_EGL_sync */
Kyle Brenneman9a992032016-09-12 17:40:29 -04001453 if (!ctx || ctx->Resource.Display != disp ||
Marek Olšák9a0bda22015-04-10 10:56:02 +02001454 ctx->ClientAPI != EGL_OPENGL_ES_API)
1455 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1456
1457 switch (type) {
1458 case EGL_SYNC_FENCE_KHR:
1459 if (!disp->Extensions.KHR_fence_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001460 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001461 break;
1462 case EGL_SYNC_REUSABLE_KHR:
1463 if (!disp->Extensions.KHR_reusable_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001464 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001465 break;
Marek Olšák290a3eb2015-04-10 13:16:30 +02001466 case EGL_SYNC_CL_EVENT_KHR:
1467 if (!disp->Extensions.KHR_cl_event2)
Marek Olšák51c8c662015-05-12 21:41:32 +02001468 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001469 break;
Marek Olšák9a0bda22015-04-10 10:56:02 +02001470 default:
Marek Olšák51c8c662015-05-12 21:41:32 +02001471 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001472 }
Chia-I Wu4eebea72010-08-14 23:09:12 +08001473
Marek Olšák290a3eb2015-04-10 13:16:30 +02001474 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001475 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001476
1477 RETURN_EGL_EVAL(disp, ret);
1478}
1479
1480
Marek Olšákd333d302015-05-12 17:34:57 +02001481static EGLSync EGLAPIENTRY
Marek Olšák290a3eb2015-04-10 13:16:30 +02001482eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1483{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001484 _EGLDisplay *disp = _eglLockDisplay(dpy);
1485 return _eglCreateSync(disp, type, attrib_list, NULL, EGL_FALSE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001486 EGL_BAD_ATTRIBUTE);
1487}
1488
1489
1490static EGLSync EGLAPIENTRY
1491eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1492{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001493 _EGLDisplay *disp = _eglLockDisplay(dpy);
1494 return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001495 EGL_BAD_ATTRIBUTE);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001496}
1497
1498
Marek Olšák2885ba02015-05-12 20:54:22 +02001499EGLSync EGLAPIENTRY
1500eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001501{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001502 _EGLDisplay *disp = _eglLockDisplay(dpy);
1503 return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001504 EGL_BAD_PARAMETER);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001505}
1506
1507
Marek Olšák2885ba02015-05-12 20:54:22 +02001508EGLBoolean EGLAPIENTRY
1509eglDestroySync(EGLDisplay dpy, EGLSync sync)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001510{
1511 _EGLDisplay *disp = _eglLockDisplay(dpy);
1512 _EGLSync *s = _eglLookupSync(sync, disp);
1513 _EGLDriver *drv;
1514 EGLBoolean ret;
1515
1516 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001517 assert(disp->Extensions.KHR_reusable_sync ||
1518 disp->Extensions.KHR_fence_sync);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001519
Chia-I Wu4eebea72010-08-14 23:09:12 +08001520 _eglUnlinkSync(s);
1521 ret = drv->API.DestroySyncKHR(drv, disp, s);
1522
1523 RETURN_EGL_EVAL(disp, ret);
1524}
1525
1526
Marek Olšák2885ba02015-05-12 20:54:22 +02001527EGLint EGLAPIENTRY
1528eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001529{
1530 _EGLDisplay *disp = _eglLockDisplay(dpy);
1531 _EGLSync *s = _eglLookupSync(sync, disp);
1532 _EGLDriver *drv;
1533 EGLint ret;
1534
1535 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001536 assert(disp->Extensions.KHR_reusable_sync ||
1537 disp->Extensions.KHR_fence_sync);
1538
1539 if (s->SyncStatus == EGL_SIGNALED_KHR)
1540 RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
1541
Dongwon Kim70299472016-04-04 17:14:10 -07001542 /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
1543 * unlocked here to allow other threads also to be able to
1544 * go into waiting state.
1545 */
1546
1547 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1548 _eglUnlockDisplay(dpy);
1549
Chia-I Wu4eebea72010-08-14 23:09:12 +08001550 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1551
Dongwon Kim70299472016-04-04 17:14:10 -07001552 /*
1553 * 'disp' is already unlocked for reusable sync type,
1554 * so passing 'NULL' to bypass unlocking display.
1555 */
1556 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1557 RETURN_EGL_EVAL(NULL, ret);
1558 else
1559 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001560}
1561
1562
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001563static EGLint
1564_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
Marek Olšáka8617cc2015-04-10 12:04:18 +02001565{
Marek Olšáka8617cc2015-04-10 12:04:18 +02001566 _EGLContext *ctx = _eglGetCurrentContext();
1567 _EGLDriver *drv;
1568 EGLint ret;
1569
1570 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1571 assert(disp->Extensions.KHR_wait_sync);
1572
1573 /* return an error if the client API doesn't support GL_OES_EGL_sync */
1574 if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
1575 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1576
1577 /* the API doesn't allow any flags yet */
1578 if (flags != 0)
1579 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1580
1581 ret = drv->API.WaitSyncKHR(drv, disp, s);
1582
1583 RETURN_EGL_EVAL(disp, ret);
1584}
1585
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001586static EGLint EGLAPIENTRY
1587eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
1588{
1589 _EGLDisplay *disp = _eglLockDisplay(dpy);
1590 _EGLSync *s = _eglLookupSync(sync, disp);
1591 return _eglWaitSyncCommon(disp, s, flags);
1592}
1593
Marek Olšáka8617cc2015-04-10 12:04:18 +02001594
Marek Olšák75245922015-05-12 18:13:31 +02001595EGLBoolean EGLAPIENTRY
1596eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
1597{
1598 /* The KHR version returns EGLint, while the core version returns
1599 * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
1600 * EGL_TRUE.
1601 */
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001602 _EGLDisplay *disp = _eglLockDisplay(dpy);
1603 _EGLSync *s = _eglLookupSync(sync, disp);
1604 return _eglWaitSyncCommon(disp, s, flags);
Marek Olšák75245922015-05-12 18:13:31 +02001605}
1606
1607
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001608static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02001609eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001610{
1611 _EGLDisplay *disp = _eglLockDisplay(dpy);
1612 _EGLSync *s = _eglLookupSync(sync, disp);
1613 _EGLDriver *drv;
1614 EGLBoolean ret;
1615
1616 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001617 assert(disp->Extensions.KHR_reusable_sync);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001618 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1619
1620 RETURN_EGL_EVAL(disp, ret);
1621}
1622
1623
Kyle Brenneman1d535c12016-09-12 17:46:04 -04001624static EGLBoolean
1625_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001626{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001627 _EGLDriver *drv;
1628 EGLBoolean ret;
1629
1630 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001631 assert(disp->Extensions.KHR_reusable_sync ||
1632 disp->Extensions.KHR_fence_sync);
Marek Olšák1e79e052015-05-12 18:14:31 +02001633 ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001634
1635 RETURN_EGL_EVAL(disp, ret);
1636}
1637
Kyle Brenneman1d535c12016-09-12 17:46:04 -04001638EGLBoolean EGLAPIENTRY
1639eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
1640{
1641 _EGLDisplay *disp = _eglLockDisplay(dpy);
1642 _EGLSync *s = _eglLookupSync(sync, disp);
1643 return _eglGetSyncAttribCommon(disp, s, attribute, value);
1644}
1645
Chia-I Wu4eebea72010-08-14 23:09:12 +08001646
Marek Olšák1e79e052015-05-12 18:14:31 +02001647static EGLBoolean EGLAPIENTRY
1648eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
1649{
Kyle Brenneman1d535c12016-09-12 17:46:04 -04001650 _EGLDisplay *disp = _eglLockDisplay(dpy);
1651 _EGLSync *s = _eglLookupSync(sync, disp);
Dongwon Kimd1e15632016-02-02 15:06:28 -08001652 EGLAttrib attrib;
1653 EGLBoolean result;
1654
1655 if (!value)
Chad Versace17084b62016-09-27 23:06:37 -07001656 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Dongwon Kimd1e15632016-02-02 15:06:28 -08001657
1658 attrib = *value;
Kyle Brenneman1d535c12016-09-12 17:46:04 -04001659 result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
Marek Olšák1e79e052015-05-12 18:14:31 +02001660
1661 /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
1662 *
1663 * If any error occurs, <*value> is not modified.
1664 */
1665 if (result == EGL_FALSE)
1666 return result;
1667
1668 *value = attrib;
1669 return result;
1670}
1671
1672
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001673static EGLBoolean EGLAPIENTRY
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04001674eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1675 EGLint numRects, const EGLint *rects)
1676{
1677 _EGLContext *ctx = _eglGetCurrentContext();
1678 _EGLDisplay *disp = _eglLockDisplay(dpy);
1679 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1680 _EGLDriver *drv;
1681 EGLBoolean ret;
1682
1683 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1684
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001685 if (!disp->Extensions.NOK_swap_region)
1686 RETURN_EGL_EVAL(disp, EGL_FALSE);
1687
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04001688 /* surface must be bound to current context in EGL 1.4 */
Chia-I Wud19afc52010-10-23 12:52:26 +08001689 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1690 surf != ctx->DrawSurface)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04001691 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1692
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001693 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04001694
1695 RETURN_EGL_EVAL(disp, ret);
1696}
1697
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04001698
Marek Olšákd333d302015-05-12 17:34:57 +02001699static EGLImage EGLAPIENTRY
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04001700eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1701{
1702 _EGLDisplay *disp = _eglLockDisplay(dpy);
1703 _EGLDriver *drv;
1704 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02001705 EGLImage ret;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04001706
1707 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001708 if (!disp->Extensions.MESA_drm_image)
1709 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04001710
1711 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001712 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04001713
1714 RETURN_EGL_EVAL(disp, ret);
1715}
1716
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001717static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02001718eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04001719 EGLint *name, EGLint *handle, EGLint *stride)
1720{
1721 _EGLDisplay *disp = _eglLockDisplay(dpy);
1722 _EGLImage *img = _eglLookupImage(image, disp);
1723 _EGLDriver *drv;
1724 EGLBoolean ret;
1725
1726 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001727 assert(disp->Extensions.MESA_drm_image);
1728
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04001729 if (!img)
1730 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1731
1732 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1733
1734 RETURN_EGL_EVAL(disp, ret);
1735}
1736
Benjamin Franzke6b369c42011-02-21 16:22:34 +01001737
Benjamin Franzke6b369c42011-02-21 16:22:34 +01001738struct wl_display;
1739
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001740static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01001741eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1742{
1743 _EGLDisplay *disp = _eglLockDisplay(dpy);
1744 _EGLDriver *drv;
1745 EGLBoolean ret;
1746
1747 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1748 assert(disp->Extensions.WL_bind_wayland_display);
1749
1750 if (!display)
1751 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1752
1753 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
1754
1755 RETURN_EGL_EVAL(disp, ret);
1756}
1757
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001758static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01001759eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1760{
1761 _EGLDisplay *disp = _eglLockDisplay(dpy);
1762 _EGLDriver *drv;
1763 EGLBoolean ret;
1764
1765 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1766 assert(disp->Extensions.WL_bind_wayland_display);
1767
1768 if (!display)
1769 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1770
1771 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
1772
1773 RETURN_EGL_EVAL(disp, ret);
1774}
Kristian Høgsberge6a33572012-07-05 16:43:04 -04001775
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001776static EGLBoolean EGLAPIENTRY
Ander Conselvan de Oliveira8d29b522013-07-18 15:11:25 +03001777eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
Kristian Høgsberge6a33572012-07-05 16:43:04 -04001778 EGLint attribute, EGLint *value)
1779{
1780 _EGLDisplay *disp = _eglLockDisplay(dpy);
1781 _EGLDriver *drv;
1782 EGLBoolean ret;
1783
1784 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1785 assert(disp->Extensions.WL_bind_wayland_display);
1786
1787 if (!buffer)
1788 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1789
1790 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
1791
1792 RETURN_EGL_EVAL(disp, ret);
1793}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01001794
Emil Velikov720125f2015-07-10 11:22:13 +01001795
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001796static struct wl_buffer * EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02001797eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
Neil Roberts5cddb1c2013-10-28 15:07:03 +00001798{
1799 _EGLDisplay *disp = _eglLockDisplay(dpy);
1800 _EGLImage *img;
1801 _EGLDriver *drv;
1802 struct wl_buffer *ret;
1803
1804 _EGL_CHECK_DISPLAY(disp, NULL, drv);
1805 assert(disp->Extensions.WL_create_wayland_buffer_from_image);
1806
1807 img = _eglLookupImage(image, disp);
1808
1809 if (!img)
1810 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
1811
1812 ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
1813
1814 RETURN_EGL_EVAL(disp, ret);
1815}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01001816
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001817static EGLBoolean EGLAPIENTRY
Fredrik Höglund7d46b452011-12-14 21:24:09 +01001818eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
1819 EGLint x, EGLint y, EGLint width, EGLint height)
1820{
1821 _EGLDisplay *disp = _eglLockDisplay(dpy);
1822 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1823 _EGLDriver *drv;
1824 EGLBoolean ret;
1825
1826 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1827
1828 if (!disp->Extensions.NV_post_sub_buffer)
1829 RETURN_EGL_EVAL(disp, EGL_FALSE);
1830
1831 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
1832
1833 RETURN_EGL_EVAL(disp, ret);
1834}
Sarah Sharpc524f3e2014-05-06 12:10:57 -07001835
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001836static EGLBoolean EGLAPIENTRY
Sarah Sharpc524f3e2014-05-06 12:10:57 -07001837eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
1838 EGLuint64KHR *ust, EGLuint64KHR *msc,
1839 EGLuint64KHR *sbc)
1840{
1841 _EGLDisplay *disp = _eglLockDisplay(display);
1842 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1843 _EGLDriver *drv;
1844 EGLBoolean ret;
1845
1846 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1847 if (!disp->Extensions.CHROMIUM_sync_control)
1848 RETURN_EGL_EVAL(disp, EGL_FALSE);
1849
1850 if (!ust || !msc || !sbc)
1851 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1852
1853 ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
1854
1855 RETURN_EGL_EVAL(disp, ret);
1856}
Dave Airlie8f7338f2014-03-03 13:57:16 +10001857
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001858static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02001859eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10001860 EGLint *fourcc, EGLint *nplanes,
Dave Airlieb5045e22015-05-05 09:10:34 +10001861 EGLuint64KHR *modifiers)
Dave Airlie8f7338f2014-03-03 13:57:16 +10001862{
1863 _EGLDisplay *disp = _eglLockDisplay(dpy);
1864 _EGLImage *img = _eglLookupImage(image, disp);
1865 _EGLDriver *drv;
1866 EGLBoolean ret;
1867
1868 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1869 assert(disp->Extensions.MESA_image_dma_buf_export);
1870
1871 if (!img)
1872 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1873
1874 ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
1875 modifiers);
1876
1877 RETURN_EGL_EVAL(disp, ret);
1878}
1879
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001880static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02001881eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10001882 int *fds, EGLint *strides, EGLint *offsets)
1883{
1884 _EGLDisplay *disp = _eglLockDisplay(dpy);
1885 _EGLImage *img = _eglLookupImage(image, disp);
1886 _EGLDriver *drv;
1887 EGLBoolean ret;
1888
1889 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1890 assert(disp->Extensions.MESA_image_dma_buf_export);
1891
1892 if (!img)
1893 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1894
1895 ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
1896
1897 RETURN_EGL_EVAL(disp, ret);
1898}
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001899
1900__eglMustCastToProperFunctionPointerType EGLAPIENTRY
1901eglGetProcAddress(const char *procname)
1902{
1903 static const struct {
1904 const char *name;
1905 _EGLProc function;
1906 } egl_functions[] = {
Emil Velikov448e01b2015-05-12 00:30:16 +01001907 /* core functions queryable in the presence of
1908 * EGL_KHR_get_all_proc_addresses or EGL 1.5
1909 */
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001910 /* alphabetical order */
1911 { "eglBindAPI", (_EGLProc) eglBindAPI },
1912 { "eglBindTexImage", (_EGLProc) eglBindTexImage },
1913 { "eglChooseConfig", (_EGLProc) eglChooseConfig },
1914 { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
1915 { "eglCreateContext", (_EGLProc) eglCreateContext },
1916 { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
1917 { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
1918 { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
1919 { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
1920 { "eglDestroyContext", (_EGLProc) eglDestroyContext },
1921 { "eglDestroySurface", (_EGLProc) eglDestroySurface },
1922 { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
1923 { "eglGetConfigs", (_EGLProc) eglGetConfigs },
1924 { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
1925 { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
1926 { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
1927 { "eglGetDisplay", (_EGLProc) eglGetDisplay },
1928 { "eglGetError", (_EGLProc) eglGetError },
1929 { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
1930 { "eglInitialize", (_EGLProc) eglInitialize },
1931 { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
1932 { "eglQueryAPI", (_EGLProc) eglQueryAPI },
1933 { "eglQueryContext", (_EGLProc) eglQueryContext },
1934 { "eglQueryString", (_EGLProc) eglQueryString },
1935 { "eglQuerySurface", (_EGLProc) eglQuerySurface },
1936 { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
1937 { "eglReleaseThread", (_EGLProc) eglReleaseThread },
1938 { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
1939 { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
1940 { "eglSwapInterval", (_EGLProc) eglSwapInterval },
1941 { "eglTerminate", (_EGLProc) eglTerminate },
1942 { "eglWaitClient", (_EGLProc) eglWaitClient },
1943 { "eglWaitGL", (_EGLProc) eglWaitGL },
1944 { "eglWaitNative", (_EGLProc) eglWaitNative },
Marek Olšák2885ba02015-05-12 20:54:22 +02001945 { "eglCreateSync", (_EGLProc) eglCreateSync },
1946 { "eglDestroySync", (_EGLProc) eglDestroySync },
1947 { "eglClientWaitSync", (_EGLProc) eglClientWaitSync },
Marek Olšák1e79e052015-05-12 18:14:31 +02001948 { "eglGetSyncAttrib", (_EGLProc) eglGetSyncAttrib },
Marek Olšák75245922015-05-12 18:13:31 +02001949 { "eglWaitSync", (_EGLProc) eglWaitSync },
Marek Olšák515f04e2015-05-12 20:42:05 +02001950 { "eglCreateImage", (_EGLProc) eglCreateImage },
Marek Olšák2885ba02015-05-12 20:54:22 +02001951 { "eglDestroyImage", (_EGLProc) eglDestroyImage },
Marek Olšák820a4d42015-05-12 21:06:41 +02001952 { "eglGetPlatformDisplay", (_EGLProc) eglGetPlatformDisplay },
1953 { "eglCreatePlatformWindowSurface", (_EGLProc) eglCreatePlatformWindowSurface },
1954 { "eglCreatePlatformPixmapSurface", (_EGLProc) eglCreatePlatformPixmapSurface },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001955 { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
Marek Olšák2885ba02015-05-12 20:54:22 +02001956 { "eglDestroyImageKHR", (_EGLProc) eglDestroyImage },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001957 { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
Marek Olšák51c8c662015-05-12 21:41:32 +02001958 { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR },
Marek Olšák2885ba02015-05-12 20:54:22 +02001959 { "eglDestroySyncKHR", (_EGLProc) eglDestroySync },
1960 { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSync },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001961 { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR },
1962 { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
1963 { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001964 { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001965 { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
1966 { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001967 { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
1968 { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
1969 { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001970 { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001971 { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001972 { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001973 { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
1974 { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
1975 { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
1976 { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001977 { "eglExportDMABUFImageQueryMESA", (_EGLProc) eglExportDMABUFImageQueryMESA },
1978 { "eglExportDMABUFImageMESA", (_EGLProc) eglExportDMABUFImageMESA },
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001979 { NULL, NULL }
1980 };
1981 EGLint i;
1982 _EGLProc ret;
1983
1984 if (!procname)
1985 RETURN_EGL_SUCCESS(NULL, NULL);
1986
1987 ret = NULL;
1988 if (strncmp(procname, "egl", 3) == 0) {
1989 for (i = 0; egl_functions[i].name; i++) {
1990 if (strcmp(egl_functions[i].name, procname) == 0) {
1991 ret = egl_functions[i].function;
1992 break;
1993 }
1994 }
1995 }
1996 if (!ret)
1997 ret = _eglGetDriverProc(procname);
1998
1999 RETURN_EGL_SUCCESS(NULL, ret);
2000}
Marek Olšákb6eda702016-03-03 15:59:48 +01002001
2002static int
2003_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
2004 _EGLDisplay **disp, _EGLDriver **drv,
2005 _EGLContext **ctx)
2006{
2007
2008 *disp = _eglLockDisplay(dpy);
2009 if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
2010 if (*disp)
2011 _eglUnlockDisplay(*disp);
2012 return MESA_GLINTEROP_INVALID_DISPLAY;
2013 }
2014
2015 *drv = (*disp)->Driver;
2016
2017 *ctx = _eglLookupContext(context, *disp);
2018 if (!*ctx ||
2019 ((*ctx)->ClientAPI != EGL_OPENGL_API &&
2020 (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
2021 _eglUnlockDisplay(*disp);
2022 return MESA_GLINTEROP_INVALID_CONTEXT;
2023 }
2024
2025 return MESA_GLINTEROP_SUCCESS;
2026}
2027
Emil Velikovb5f98202016-05-03 12:14:26 +01002028int
Marek Olšákb6eda702016-03-03 15:59:48 +01002029MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002030 struct mesa_glinterop_device_info *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002031{
2032 _EGLDisplay *disp;
2033 _EGLDriver *drv;
2034 _EGLContext *ctx;
2035 int ret;
2036
2037 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2038 if (ret != MESA_GLINTEROP_SUCCESS)
2039 return ret;
2040
2041 if (drv->API.GLInteropQueryDeviceInfo)
2042 ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
2043 else
2044 ret = MESA_GLINTEROP_UNSUPPORTED;
2045
2046 _eglUnlockDisplay(disp);
2047 return ret;
2048}
2049
Emil Velikovb5f98202016-05-03 12:14:26 +01002050int
Marek Olšákb6eda702016-03-03 15:59:48 +01002051MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002052 struct mesa_glinterop_export_in *in,
2053 struct mesa_glinterop_export_out *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002054{
2055 _EGLDisplay *disp;
2056 _EGLDriver *drv;
2057 _EGLContext *ctx;
2058 int ret;
2059
2060 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2061 if (ret != MESA_GLINTEROP_SUCCESS)
2062 return ret;
2063
2064 if (drv->API.GLInteropExportObject)
2065 ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
2066 else
2067 ret = MESA_GLINTEROP_UNSUPPORTED;
2068
2069 _eglUnlockDisplay(disp);
2070 return ret;
2071}