blob: 76dabba2eb516c6899e2b181ba1f0e72a4ad2acb [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"
Emil Velikov239e7ee2017-05-04 18:55:36 +010091#include "util/macros.h"
Chia-I Wu1e6c10f2010-05-31 11:47:58 +080092
Chad Versace3c58d4c2013-10-11 16:04:55 -070093#include "eglglobals.h"
Brian Pauladbff7e2005-04-22 21:09:39 +000094#include "eglcontext.h"
95#include "egldisplay.h"
96#include "egltypedefs.h"
Chia-I Wu94cb3212010-01-29 09:00:30 +080097#include "eglcurrent.h"
Brian Pauladbff7e2005-04-22 21:09:39 +000098#include "egldriver.h"
99#include "eglsurface.h"
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800100#include "eglconfig.h"
Chia-I Wua1c4a8a2009-08-15 22:58:13 +0800101#include "eglimage.h"
Chia-I Wu4eebea72010-08-14 23:09:12 +0800102#include "eglsync.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000103
Matt Turner4e970842017-07-06 18:40:53 -0700104#include "GL/mesa_glinterop.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000105
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
Eric Engestrom1534fc62017-02-21 23:56:52 +0000160struct _egl_entrypoint {
161 const char *name;
162 _EGLProc function;
163};
164
165
Emil Velikov7bd16932015-02-28 16:35:22 +0000166static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800167_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
168{
169 if (!disp) {
170 _eglError(EGL_BAD_DISPLAY, msg);
171 return NULL;
172 }
173 if (!disp->Initialized) {
174 _eglError(EGL_NOT_INITIALIZED, msg);
175 return NULL;
176 }
177 return disp->Driver;
178}
179
180
Emil Velikov7bd16932015-02-28 16:35:22 +0000181static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800182_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
183{
184 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
185 if (!drv)
186 return NULL;
187 if (!surf) {
188 _eglError(EGL_BAD_SURFACE, msg);
189 return NULL;
190 }
191 return drv;
192}
193
194
Emil Velikov7bd16932015-02-28 16:35:22 +0000195static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800196_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
197{
198 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
199 if (!drv)
200 return NULL;
201 if (!context) {
202 _eglError(EGL_BAD_CONTEXT, msg);
203 return NULL;
204 }
205 return drv;
206}
207
208
Emil Velikov7bd16932015-02-28 16:35:22 +0000209static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800210_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
211{
212 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
213 if (!drv)
214 return NULL;
215 if (!conf) {
216 _eglError(EGL_BAD_CONFIG, msg);
217 return NULL;
218 }
219 return drv;
220}
221
222
Emil Velikov7bd16932015-02-28 16:35:22 +0000223static inline _EGLDriver *
Chia-I Wu4eebea72010-08-14 23:09:12 +0800224_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
225{
226 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
227 if (!drv)
228 return NULL;
229 if (!s) {
230 _eglError(EGL_BAD_PARAMETER, msg);
231 return NULL;
232 }
233 return drv;
234}
235
236
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800237/**
Chia-I Wu655f4652010-02-17 17:30:44 +0800238 * Lookup and lock a display.
239 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000240static inline _EGLDisplay *
Chia-I Wu655f4652010-02-17 17:30:44 +0800241_eglLockDisplay(EGLDisplay display)
242{
243 _EGLDisplay *dpy = _eglLookupDisplay(display);
244 if (dpy)
Emil Velikovefe87f12015-03-06 16:54:55 +0000245 mtx_lock(&dpy->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +0800246 return dpy;
247}
248
249
250/**
251 * Unlock a display.
252 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000253static inline void
Chia-I Wu655f4652010-02-17 17:30:44 +0800254_eglUnlockDisplay(_EGLDisplay *dpy)
255{
Emil Velikovefe87f12015-03-06 16:54:55 +0000256 mtx_unlock(&dpy->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +0800257}
258
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400259static EGLBoolean
260_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
261{
262 _EGLThreadInfo *thr = _eglGetCurrentThread();
263 if (!_eglIsCurrentThreadDummy()) {
264 thr->CurrentFuncName = funcName;
265 thr->CurrentObjectLabel = NULL;
266
267 if (objectType == EGL_OBJECT_THREAD_KHR)
268 thr->CurrentObjectLabel = thr->Label;
269 else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
270 thr->CurrentObjectLabel = disp->Label;
271 else if (object)
272 thr->CurrentObjectLabel = object->Label;
273
274 return EGL_TRUE;
275 }
276
Emil Velikovb94344f2017-09-07 17:03:50 +0100277 _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400278 return EGL_FALSE;
279}
280
281#define _EGL_FUNC_START(disp, objectType, object, ret) \
282 do { \
283 if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
284 if (disp) \
285 _eglUnlockDisplay(disp); \
286 return ret; \
287 } \
288 } while(0)
Chia-I Wu655f4652010-02-17 17:30:44 +0800289
Chad Versace3e0d5752016-09-27 13:27:17 -0700290/**
291 * Convert an attribute list from EGLint[] to EGLAttrib[].
292 *
293 * Return an EGL error code. The output parameter out_attrib_list is modified
294 * only on success.
295 */
Eric Engestrom9e1d35c2016-12-08 00:36:03 +0000296static EGLint
Chad Versace3e0d5752016-09-27 13:27:17 -0700297_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
298{
299 size_t len = 0;
300 EGLAttrib *attrib_list;
301
302 if (int_list) {
303 while (int_list[2*len] != EGL_NONE)
304 ++len;
305 }
306
307 if (len == 0) {
308 *out_attrib_list = NULL;
309 return EGL_SUCCESS;
310 }
311
312 if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
313 return EGL_BAD_ALLOC;
314
315 attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
316 if (!attrib_list)
317 return EGL_BAD_ALLOC;
318
319 for (size_t i = 0; i < len; ++i) {
320 attrib_list[2*i + 0] = int_list[2*i + 0];
321 attrib_list[2*i + 1] = int_list[2*i + 1];
322 }
323
324 attrib_list[2*len] = EGL_NONE;
325
326 *out_attrib_list = attrib_list;
327 return EGL_SUCCESS;
328}
329
330
Marek Olšák515f04e2015-05-12 20:42:05 +0200331static EGLint *
332_eglConvertAttribsToInt(const EGLAttrib *attr_list)
333{
334 EGLint *int_attribs = NULL;
335
336 /* Convert attributes from EGLAttrib[] to EGLint[] */
337 if (attr_list) {
338 int i, size = 0;
339
340 while (attr_list[size] != EGL_NONE)
341 size += 2;
342
343 size += 1; /* add space for EGL_NONE */
344
345 int_attribs = calloc(size, sizeof(int_attribs[0]));
346 if (!int_attribs)
347 return NULL;
348
349 for (i = 0; i < size; i++)
350 int_attribs[i] = attr_list[i];
351 }
352 return int_attribs;
353}
354
355
Chia-I Wu655f4652010-02-17 17:30:44 +0800356/**
Brian Paul6052af12008-05-27 16:48:23 -0600357 * This is typically the first EGL function that an application calls.
Chia-I Wudb5ce8b2010-02-17 18:39:27 +0800358 * It associates a private _EGLDisplay object to the native display.
Brian Pauladbff7e2005-04-22 21:09:39 +0000359 */
Brian Paul1ed10272008-05-27 13:45:41 -0600360EGLDisplay EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +0800361eglGetDisplay(EGLNativeDisplayType nativeDisplay)
Brian Pauladbff7e2005-04-22 21:09:39 +0000362{
Chad Versace6d1f83e2014-01-07 14:54:51 -0800363 _EGLPlatformType plat;
364 _EGLDisplay *dpy;
365 void *native_display_ptr;
366
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400367 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
368
Chad Versace6d1f83e2014-01-07 14:54:51 -0800369 STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
370 native_display_ptr = (void*) nativeDisplay;
371
372 plat = _eglGetNativePlatform(native_display_ptr);
373 dpy = _eglFindDisplay(plat, native_display_ptr);
Brian Paul721ba152008-05-27 14:33:54 -0600374 return _eglGetDisplayHandle(dpy);
Brian Pauladbff7e2005-04-22 21:09:39 +0000375}
376
Kyle Brenneman017946b2016-09-12 16:42:56 -0400377static EGLDisplay
378_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +0100379 const EGLint *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -0800380{
381 _EGLDisplay *dpy;
382
383 switch (platform) {
384#ifdef HAVE_X11_PLATFORM
385 case EGL_PLATFORM_X11_EXT:
386 dpy = _eglGetX11Display((Display*) native_display, attrib_list);
387 break;
388#endif
389#ifdef HAVE_DRM_PLATFORM
390 case EGL_PLATFORM_GBM_MESA:
391 dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
392 attrib_list);
393 break;
394#endif
395#ifdef HAVE_WAYLAND_PLATFORM
396 case EGL_PLATFORM_WAYLAND_EXT:
397 dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
398 attrib_list);
399 break;
400#endif
Chad Versacea597c8a2016-10-12 15:48:15 -0700401#ifdef HAVE_SURFACELESS_PLATFORM
402 case EGL_PLATFORM_SURFACELESS_MESA:
403 dpy = _eglGetSurfacelessDisplay(native_display, attrib_list);
404 break;
405#endif
Chad Versace468cc862014-01-23 07:26:10 -0800406 default:
407 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
408 }
409
410 return _eglGetDisplayHandle(dpy);
411}
Brian Pauladbff7e2005-04-22 21:09:39 +0000412
Kyle Brenneman017946b2016-09-12 16:42:56 -0400413static EGLDisplay EGLAPIENTRY
414eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
415 const EGLint *attrib_list)
416{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400417 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
Kyle Brenneman017946b2016-09-12 16:42:56 -0400418 return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
419}
420
Marek Olšák820a4d42015-05-12 21:06:41 +0200421EGLDisplay EGLAPIENTRY
422eglGetPlatformDisplay(EGLenum platform, void *native_display,
423 const EGLAttrib *attrib_list)
424{
425 EGLDisplay display;
Kyle Brenneman017946b2016-09-12 16:42:56 -0400426 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +0200427
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400428 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
429
Kyle Brenneman017946b2016-09-12 16:42:56 -0400430 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +0200431 if (attrib_list && !int_attribs)
432 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
433
Kyle Brenneman017946b2016-09-12 16:42:56 -0400434 display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +0200435 free(int_attribs);
436 return display;
437}
438
Brian Paul6052af12008-05-27 16:48:23 -0600439/**
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700440 * Copy the extension into the string and update the string pointer.
441 */
442static EGLint
443_eglAppendExtension(char **str, const char *ext)
444{
445 char *s = *str;
446 size_t len = strlen(ext);
447
448 if (s) {
449 memcpy(s, ext, len);
450 s[len++] = ' ';
451 s[len] = '\0';
452
453 *str += len;
454 }
455 else {
456 len++;
457 }
458
459 return (EGLint) len;
460}
461
462/**
463 * Examine the individual extension enable/disable flags and recompute
464 * the driver's Extensions string.
465 */
466static void
467_eglCreateExtensionsString(_EGLDisplay *dpy)
468{
469#define _EGL_CHECK_EXTENSION(ext) \
470 do { \
471 if (dpy->Extensions.ext) { \
472 _eglAppendExtension(&exts, "EGL_" #ext); \
473 assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
474 } \
475 } while (0)
476
477 char *exts = dpy->ExtensionsString;
478
Marek Olšák32aa1d72015-06-09 23:08:57 +0200479 /* Please keep these sorted alphabetically. */
Rob Herring89755272016-02-02 14:23:07 -0600480 _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700481 _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
Rob Clark0201f012016-11-18 08:39:33 -0500482 _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
Rob Herringe21e81a2016-02-02 14:23:08 -0600483 _EGL_CHECK_EXTENSION(ANDROID_recordable);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700484
485 _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
486
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700487 _EGL_CHECK_EXTENSION(EXT_buffer_age);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200488 _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700489 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
Varad Gautam4c412292017-05-30 17:23:40 +0530490 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200491 _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
492
Chris Wilson95ecf3d2016-10-27 19:34:46 +0100493 _EGL_CHECK_EXTENSION(IMG_context_priority);
494
Marek Olšák32aa1d72015-06-09 23:08:57 +0200495 _EGL_CHECK_EXTENSION(KHR_cl_event2);
Emil Velikov26541a12016-12-05 14:42:04 +0000496 _EGL_CHECK_EXTENSION(KHR_config_attribs);
Adam Jacksonc0be3aa2016-09-22 03:47:55 -0400497 _EGL_CHECK_EXTENSION(KHR_context_flush_control);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200498 _EGL_CHECK_EXTENSION(KHR_create_context);
Grigori Goronzy49095192017-06-29 02:44:03 +0200499 _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200500 _EGL_CHECK_EXTENSION(KHR_fence_sync);
501 _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
502 _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
503 _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
504 _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
505 _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
506 _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
507 if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
508 _eglAppendExtension(&exts, "EGL_KHR_image");
509 _EGL_CHECK_EXTENSION(KHR_image_base);
510 _EGL_CHECK_EXTENSION(KHR_image_pixmap);
Adam Jacksond9f5b192016-09-09 12:25:34 -0400511 _EGL_CHECK_EXTENSION(KHR_no_config_context);
Harish Krupo98275472017-06-09 20:13:34 +0530512 _EGL_CHECK_EXTENSION(KHR_partial_update);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200513 _EGL_CHECK_EXTENSION(KHR_reusable_sync);
514 _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
Eric Engestrom0a606a42016-10-10 17:33:17 +0100515 if (dpy->Extensions.EXT_swap_buffers_with_damage)
516 _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
Marek Olšák32aa1d72015-06-09 23:08:57 +0200517 _EGL_CHECK_EXTENSION(KHR_wait_sync);
518
Adam Jacksond9f5b192016-09-09 12:25:34 -0400519 if (dpy->Extensions.KHR_no_config_context)
520 _eglAppendExtension(&exts, "EGL_MESA_configless_context");
Marek Olšák32aa1d72015-06-09 23:08:57 +0200521 _EGL_CHECK_EXTENSION(MESA_drm_image);
522 _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
523
524 _EGL_CHECK_EXTENSION(NOK_swap_region);
525 _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700526
527 _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
Dave Airlie8f7338f2014-03-03 13:57:16 +1000528
Marek Olšák32aa1d72015-06-09 23:08:57 +0200529 _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
530 _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
531
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700532#undef _EGL_CHECK_EXTENSION
533}
534
535static void
536_eglCreateAPIsString(_EGLDisplay *dpy)
537{
538 if (dpy->ClientAPIs & EGL_OPENGL_BIT)
539 strcat(dpy->ClientAPIsString, "OpenGL ");
540
Plamena Manolova21edd242016-05-12 18:21:38 +0100541 if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||
542 dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||
543 dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700544 strcat(dpy->ClientAPIsString, "OpenGL_ES ");
Plamena Manolova21edd242016-05-12 18:21:38 +0100545 }
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700546
547 if (dpy->ClientAPIs & EGL_OPENVG_BIT)
548 strcat(dpy->ClientAPIsString, "OpenVG ");
549
550 assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
551}
552
Marek Olšákefda9c52015-05-11 22:16:52 +0200553static void
554_eglComputeVersion(_EGLDisplay *disp)
555{
Marek Olšák0e4b5642015-05-12 16:40:29 +0200556 disp->Version = 14;
Marek Olšáka1cb4072015-05-11 22:18:04 +0200557
558 if (disp->Extensions.KHR_fence_sync &&
559 disp->Extensions.KHR_cl_event2 &&
560 disp->Extensions.KHR_wait_sync &&
561 disp->Extensions.KHR_image_base &&
562 disp->Extensions.KHR_gl_texture_2D_image &&
563 disp->Extensions.KHR_gl_texture_3D_image &&
564 disp->Extensions.KHR_gl_texture_cubemap_image &&
565 disp->Extensions.KHR_gl_renderbuffer_image &&
566 disp->Extensions.KHR_create_context &&
567 disp->Extensions.EXT_create_context_robustness &&
568 disp->Extensions.KHR_get_all_proc_addresses &&
569 disp->Extensions.KHR_gl_colorspace &&
570 disp->Extensions.KHR_surfaceless_context)
571 disp->Version = 15;
Marek Olšákefda9c52015-05-11 22:16:52 +0200572}
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700573
574/**
Brian Paul6052af12008-05-27 16:48:23 -0600575 * This is typically the second EGL function that an application calls.
576 * Here we load/initialize the actual hardware driver.
577 */
Brian Paul1ed10272008-05-27 13:45:41 -0600578EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000579eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
580{
Chia-I Wu655f4652010-02-17 17:30:44 +0800581 _EGLDisplay *disp = _eglLockDisplay(dpy);
Jonathan White7e2458c2008-08-06 13:40:03 -0600582
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400583 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
584
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800585 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800586 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Brian Paulc56e15b2008-05-28 15:43:41 -0600587
Chia-I Wua9332592010-01-27 23:55:58 +0800588 if (!disp->Initialized) {
Eric Engestromd7e769a2017-10-18 16:31:23 +0100589 if (!_eglMatchDriver(disp))
Chia-I Wuf2aa3612010-07-04 15:55:12 +0800590 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
Chia-I Wu57929ed2010-01-19 18:29:21 +0800591
Chia-I Wu310c7682009-08-17 15:53:54 +0800592 /* limit to APIs supported by core */
Chia-I Wua4a38dc2011-01-13 16:53:13 +0800593 disp->ClientAPIs &= _EGL_API_ALL_BITS;
Chad Versace7e8ba772014-11-20 10:26:38 -0800594
595 /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
596 * classifies it as an EGL display extension, though conceptually it's an
597 * EGL client extension.
598 *
599 * From the EGL_KHR_get_all_proc_addresses spec:
600 *
601 * The EGL implementation must expose the name
602 * EGL_KHR_client_get_all_proc_addresses if and only if it exposes
603 * EGL_KHR_get_all_proc_addresses and supports
604 * EGL_EXT_client_extensions.
605 *
606 * Mesa unconditionally exposes both client extensions mentioned above,
607 * so the spec requires that each EGLDisplay unconditionally expose
608 * EGL_KHR_get_all_proc_addresses also.
609 */
610 disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700611
Emil Velikov26541a12016-12-05 14:42:04 +0000612 /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
613 * programs. It is driver agnostic and handled in the main EGL code.
614 */
615 disp->Extensions.KHR_config_attribs = EGL_TRUE;
616
Marek Olšákefda9c52015-05-11 22:16:52 +0200617 _eglComputeVersion(disp);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700618 _eglCreateExtensionsString(disp);
619 _eglCreateAPIsString(disp);
Emil Velikov3593f372015-07-14 00:19:54 +0100620 snprintf(disp->VersionString, sizeof(disp->VersionString),
Marek Olšák2cb9ab52017-10-18 20:22:58 +0200621 "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
622 disp->Driver->Name);
Brian Pauladbff7e2005-04-22 21:09:39 +0000623 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800624
625 /* Update applications version of major and minor if not NULL */
626 if ((major != NULL) && (minor != NULL)) {
Marek Olšák0e4b5642015-05-12 16:40:29 +0200627 *major = disp->Version / 10;
628 *minor = disp->Version % 10;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800629 }
630
Chia-I Wubef4b472010-02-19 12:08:50 +0800631 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000632}
633
634
Brian Paul1ed10272008-05-27 13:45:41 -0600635EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000636eglTerminate(EGLDisplay dpy)
637{
Chia-I Wu655f4652010-02-17 17:30:44 +0800638 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800639
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400640 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
641
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800642 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800643 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800644
Chia-I Wua9332592010-01-27 23:55:58 +0800645 if (disp->Initialized) {
646 _EGLDriver *drv = disp->Driver;
647
Chia-I Wuccc2b0b2009-08-13 13:39:51 +0800648 drv->API.Terminate(drv, disp);
Chia-I Wua9332592010-01-27 23:55:58 +0800649 /* do not reset disp->Driver */
Dave Airlie37e3a112015-03-16 15:21:55 +1000650 disp->ClientAPIsString[0] = 0;
Chia-I Wua9332592010-01-27 23:55:58 +0800651 disp->Initialized = EGL_FALSE;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800652 }
653
Chia-I Wubef4b472010-02-19 12:08:50 +0800654 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000655}
656
657
Brian Paul1ed10272008-05-27 13:45:41 -0600658const char * EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000659eglQueryString(EGLDisplay dpy, EGLint name)
660{
Chad Versace3c58d4c2013-10-11 16:04:55 -0700661 _EGLDisplay *disp;
Chia-I Wuaed73582010-02-17 15:43:47 +0800662 _EGLDriver *drv;
663
Chad Versace3c58d4c2013-10-11 16:04:55 -0700664 if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
Kyle Brennemance562f92017-01-04 11:31:58 -0700665 const char *ret = _eglGetClientExtensionString();
666 if (ret != NULL)
667 RETURN_EGL_SUCCESS(NULL, ret);
668 else
669 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
Chad Versace3c58d4c2013-10-11 16:04:55 -0700670 }
671
672 disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400673 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
Chia-I Wubef4b472010-02-19 12:08:50 +0800674 _EGL_CHECK_DISPLAY(disp, NULL, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800675
Matt Turner6c6e2a12015-03-13 17:00:26 -0700676 switch (name) {
677 case EGL_VENDOR:
678 RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
679 case EGL_VERSION:
680 RETURN_EGL_SUCCESS(disp, disp->VersionString);
681 case EGL_EXTENSIONS:
682 RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
683 case EGL_CLIENT_APIS:
684 RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
685 default:
686 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
687 }
Brian Pauladbff7e2005-04-22 21:09:39 +0000688}
689
690
Brian Paul1ed10272008-05-27 13:45:41 -0600691EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800692eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
693 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000694{
Chia-I Wu655f4652010-02-17 17:30:44 +0800695 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800696 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800697 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800698
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400699 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
700
Chia-I Wubef4b472010-02-19 12:08:50 +0800701 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800702 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
703
Chia-I Wubef4b472010-02-19 12:08:50 +0800704 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000705}
706
707
Brian Paul1ed10272008-05-27 13:45:41 -0600708EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800709eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
710 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000711{
Chia-I Wu655f4652010-02-17 17:30:44 +0800712 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800713 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800714 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800715
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400716 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
717
Chia-I Wubef4b472010-02-19 12:08:50 +0800718 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800719 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +0100720 config_size, num_config);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800721
Chia-I Wubef4b472010-02-19 12:08:50 +0800722 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000723}
724
725
Brian Paul1ed10272008-05-27 13:45:41 -0600726EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800727eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
728 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000729{
Chia-I Wu655f4652010-02-17 17:30:44 +0800730 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800731 _EGLConfig *conf = _eglLookupConfig(config, disp);
732 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800733 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800734
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400735 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
736
Chia-I Wubef4b472010-02-19 12:08:50 +0800737 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800738 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
739
Chia-I Wubef4b472010-02-19 12:08:50 +0800740 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000741}
742
743
Brian Paul1ed10272008-05-27 13:45:41 -0600744EGLContext EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800745eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
746 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000747{
Chia-I Wu655f4652010-02-17 17:30:44 +0800748 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800749 _EGLConfig *conf = _eglLookupConfig(config, disp);
750 _EGLContext *share = _eglLookupContext(share_list, disp);
751 _EGLDriver *drv;
752 _EGLContext *context;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800753 EGLContext ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800754
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400755 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
756
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800757 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
758
Tapani Pälli5876f3c2016-10-20 14:11:16 +0300759 if (config != EGL_NO_CONFIG_KHR)
760 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
761 else if (!disp->Extensions.KHR_no_config_context)
Neil Roberts4b17dff2014-03-07 18:05:46 +0000762 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
Kristian Høgsbergb90a3e72010-06-02 22:48:06 -0400763
Chia-I Wub3bb1802010-02-17 16:05:27 +0800764 if (!share && share_list != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800765 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800766
767 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +0800768 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800769
Chia-I Wubef4b472010-02-19 12:08:50 +0800770 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000771}
772
773
Brian Paul1ed10272008-05-27 13:45:41 -0600774EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000775eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
776{
Chia-I Wu655f4652010-02-17 17:30:44 +0800777 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800778 _EGLContext *context = _eglLookupContext(ctx, disp);
779 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800780 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800781
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400782 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
783
Chia-I Wubef4b472010-02-19 12:08:50 +0800784 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800785 _eglUnlinkContext(context);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800786 ret = drv->API.DestroyContext(drv, disp, context);
787
Chia-I Wubef4b472010-02-19 12:08:50 +0800788 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000789}
790
791
Brian Paul1ed10272008-05-27 13:45:41 -0600792EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800793eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
794 EGLContext ctx)
Brian Pauladbff7e2005-04-22 21:09:39 +0000795{
Chia-I Wu655f4652010-02-17 17:30:44 +0800796 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800797 _EGLContext *context = _eglLookupContext(ctx, disp);
798 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
799 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
800 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800801 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800802
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400803 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
804
Chia-I Wu17330472010-01-27 23:51:54 +0800805 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800806 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800807 drv = disp->Driver;
808
809 /* display is allowed to be uninitialized under certain condition */
810 if (!disp->Initialized) {
811 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
812 ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800813 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800814 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800815 if (!drv)
Chia-I Wubef4b472010-02-19 12:08:50 +0800816 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Chia-I Wu17330472010-01-27 23:51:54 +0800817
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800818 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800819 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800820 if (!draw_surf || !read_surf) {
Beren Minor0ca0d572014-03-20 08:36:34 +0100821 /* From the EGL 1.4 (20130211) spec:
822 *
823 * To release the current context without assigning a new one, set ctx
824 * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
825 */
826 if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800827 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
828
829 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
830 (!read_surf && read != EGL_NO_SURFACE))
831 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
832 if (draw_surf || read_surf)
833 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
834 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800835
Chad Versace23c86c72017-05-04 17:46:33 -0700836 /* If a native window underlying either draw or read is no longer valid,
837 * an EGL_BAD_NATIVE_WINDOW error is generated.
838 */
839 if (draw_surf && draw_surf->Lost)
840 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
841 if (read_surf && read_surf->Lost)
842 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
843
Chia-I Wub3bb1802010-02-17 16:05:27 +0800844 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
845
Chia-I Wubef4b472010-02-19 12:08:50 +0800846 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000847}
848
849
Brian Paul1ed10272008-05-27 13:45:41 -0600850EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800851eglQueryContext(EGLDisplay dpy, EGLContext ctx,
852 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000853{
Chia-I Wu655f4652010-02-17 17:30:44 +0800854 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800855 _EGLContext *context = _eglLookupContext(ctx, disp);
856 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800857 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800858
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400859 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
860
Chia-I Wubef4b472010-02-19 12:08:50 +0800861 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800862 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
863
Chia-I Wubef4b472010-02-19 12:08:50 +0800864 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000865}
866
867
Chad Versace468cc862014-01-23 07:26:10 -0800868static EGLSurface
869_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
870 void *native_window, const EGLint *attrib_list)
871{
872 _EGLConfig *conf = _eglLookupConfig(config, disp);
873 _EGLDriver *drv;
874 _EGLSurface *surf;
875 EGLSurface ret;
876
Sinclair Yeh91ff0d42014-06-03 14:00:13 -0700877
878 if (native_window == NULL)
879 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
880
Chad Versacea597c8a2016-10-12 15:48:15 -0700881#ifdef HAVE_SURFACELESS_PLATFORM
Chad Versace5e97b8f2016-12-13 14:23:55 -0800882 if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
Chad Versacea597c8a2016-10-12 15:48:15 -0700883 /* From the EGL_MESA_platform_surfaceless spec (v1):
884 *
885 * eglCreatePlatformWindowSurface fails when called with a <display>
886 * that belongs to the surfaceless platform. It returns
887 * EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
888 * justification for this unconditional failure is that the
889 * surfaceless platform has no native windows, and therefore the
890 * <native_window> parameter is always invalid.
891 *
892 * This check must occur before checking the EGLConfig, which emits
893 * EGL_BAD_CONFIG.
894 */
895 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
896 }
897#endif
898
899 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
900
Chad Versacefbb4af92016-12-16 11:00:13 -0800901 if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
902 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
903
Chad Versace468cc862014-01-23 07:26:10 -0800904 surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
905 attrib_list);
906 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
907
908 RETURN_EGL_EVAL(disp, ret);
909}
910
911
Brian Paul1ed10272008-05-27 13:45:41 -0600912EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800913eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +0800914 EGLNativeWindowType window, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000915{
Chia-I Wu655f4652010-02-17 17:30:44 +0800916 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400917
918 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -0800919 STATIC_ASSERT(sizeof(void*) == sizeof(window));
920 return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
921 attrib_list);
922}
923
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400924static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000925_fixupNativeWindow(_EGLDisplay *disp, void *native_window)
Chad Versace468cc862014-01-23 07:26:10 -0800926{
Chad Versace468cc862014-01-23 07:26:10 -0800927#ifdef HAVE_X11_PLATFORM
Emil Velikov26fbb9e2017-08-08 15:55:36 +0100928 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
Chad Versace468cc862014-01-23 07:26:10 -0800929 /* The `native_window` parameter for the X11 platform differs between
930 * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
931 * eglCreateWindowSurface(), the type of `native_window` is an Xlib
932 * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
933 * `Window*`. Convert `Window*` to `Window` because that's what
934 * dri2_x11_create_window_surface() expects.
935 */
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400936 return (void *)(* (Window*) native_window);
Chad Versace468cc862014-01-23 07:26:10 -0800937 }
938#endif
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400939 return native_window;
940}
941
942static EGLSurface EGLAPIENTRY
943eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
944 void *native_window,
945 const EGLint *attrib_list)
946{
947 _EGLDisplay *disp = _eglLockDisplay(dpy);
948
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000949 native_window = _fixupNativeWindow(disp, native_window);
Chad Versace468cc862014-01-23 07:26:10 -0800950
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400951 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -0800952 return _eglCreateWindowSurfaceCommon(disp, config, native_window,
953 attrib_list);
954}
955
956
Marek Olšák820a4d42015-05-12 21:06:41 +0200957EGLSurface EGLAPIENTRY
958eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
959 void *native_window,
960 const EGLAttrib *attrib_list)
961{
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400962 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +0200963 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400964 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +0200965
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400966 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
967
968 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +0200969 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400970 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +0200971
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000972 native_window = _fixupNativeWindow(disp, native_window);
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400973 surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
974 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +0200975 free(int_attribs);
976 return surface;
977}
978
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400979static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000980_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400981{
982#ifdef HAVE_X11_PLATFORM
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +0100983 /* The `native_pixmap` parameter for the X11 platform differs between
984 * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
985 * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
986 * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
987 * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
988 * dri2_x11_create_pixmap_surface() expects.
989 */
Emil Velikov26fbb9e2017-08-08 15:55:36 +0100990 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400991 return (void *)(* (Pixmap*) native_pixmap);
992#endif
993 return native_pixmap;
994}
Marek Olšák820a4d42015-05-12 21:06:41 +0200995
Chad Versace468cc862014-01-23 07:26:10 -0800996static EGLSurface
997_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
998 void *native_pixmap, const EGLint *attrib_list)
999{
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001000 _EGLConfig *conf = _eglLookupConfig(config, disp);
1001 _EGLDriver *drv;
1002 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001003 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001004
Chad Versacea597c8a2016-10-12 15:48:15 -07001005#if HAVE_SURFACELESS_PLATFORM
Chad Versace5e97b8f2016-12-13 14:23:55 -08001006 if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
Chad Versacea597c8a2016-10-12 15:48:15 -07001007 /* From the EGL_MESA_platform_surfaceless spec (v1):
1008 *
1009 * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
1010 * also fails when called with a <display> that belongs to the
1011 * surfaceless platform. It returns EGL_NO_SURFACE and generates
1012 * EGL_BAD_NATIVE_PIXMAP.
1013 *
1014 * This check must occur before checking the EGLConfig, which emits
1015 * EGL_BAD_CONFIG.
1016 */
1017 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1018 }
1019#endif
1020
Chia-I Wubef4b472010-02-19 12:08:50 +08001021 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chad Versacefbb4af92016-12-16 11:00:13 -08001022
1023 if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
1024 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1025
Emil Velikovdf8efd52017-08-05 00:25:48 +01001026 if (native_pixmap == NULL)
1027 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1028
Chad Versace468cc862014-01-23 07:26:10 -08001029 surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
Chad Versace6d1f83e2014-01-07 14:54:51 -08001030 attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001031 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001032
Chia-I Wubef4b472010-02-19 12:08:50 +08001033 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001034}
1035
1036
Brian Paul1ed10272008-05-27 13:45:41 -06001037EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001038eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +08001039 EGLNativePixmapType pixmap, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001040{
Chia-I Wu655f4652010-02-17 17:30:44 +08001041 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001042
1043 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001044 STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
Chad Versace468cc862014-01-23 07:26:10 -08001045 return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001046 attrib_list);
Chad Versace468cc862014-01-23 07:26:10 -08001047}
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001048
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001049static EGLSurface EGLAPIENTRY
Chad Versace468cc862014-01-23 07:26:10 -08001050eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001051 void *native_pixmap,
1052 const EGLint *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -08001053{
1054 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001055
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001056 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001057 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Chad Versace468cc862014-01-23 07:26:10 -08001058 return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1059 attrib_list);
Brian Pauladbff7e2005-04-22 21:09:39 +00001060}
1061
1062
Brian Paul1ed10272008-05-27 13:45:41 -06001063EGLSurface EGLAPIENTRY
Marek Olšák820a4d42015-05-12 21:06:41 +02001064eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
1065 void *native_pixmap,
1066 const EGLAttrib *attrib_list)
1067{
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001068 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +02001069 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001070 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +02001071
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001072 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1073
1074 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +02001075 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001076 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +02001077
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001078 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001079 surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1080 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +02001081 free(int_attribs);
1082 return surface;
1083}
1084
1085
1086EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001087eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
1088 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001089{
Chia-I Wu655f4652010-02-17 17:30:44 +08001090 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001091 _EGLConfig *conf = _eglLookupConfig(config, disp);
1092 _EGLDriver *drv;
1093 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001094 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001095
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001096 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001097 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001098
Chad Versacefbb4af92016-12-16 11:00:13 -08001099 if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
1100 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1101
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001102 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001103 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001104
Chia-I Wubef4b472010-02-19 12:08:50 +08001105 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001106}
1107
1108
Brian Paul1ed10272008-05-27 13:45:41 -06001109EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001110eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
1111{
Chia-I Wu655f4652010-02-17 17:30:44 +08001112 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001113 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1114 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001115 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001116
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001117 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001118 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001119 _eglUnlinkSurface(surf);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001120 ret = drv->API.DestroySurface(drv, disp, surf);
1121
Chia-I Wubef4b472010-02-19 12:08:50 +08001122 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001123}
1124
Brian Paul1ed10272008-05-27 13:45:41 -06001125EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001126eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
1127 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001128{
Chia-I Wu655f4652010-02-17 17:30:44 +08001129 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001130 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1131 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001132 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001133
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001134 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001135 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001136 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
1137
Chia-I Wubef4b472010-02-19 12:08:50 +08001138 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001139}
1140
Brian Paul1ed10272008-05-27 13:45:41 -06001141EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001142eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
1143 EGLint attribute, EGLint value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001144{
Chia-I Wu655f4652010-02-17 17:30:44 +08001145 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001146 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1147 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001148 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001149
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001150 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001151 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001152 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
1153
Chia-I Wubef4b472010-02-19 12:08:50 +08001154 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001155}
1156
1157
Brian Paul1ed10272008-05-27 13:45:41 -06001158EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001159eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1160{
Chia-I Wu655f4652010-02-17 17:30:44 +08001161 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001162 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1163 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001164 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001165
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001166 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001167 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001168 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
1169
Chia-I Wubef4b472010-02-19 12:08:50 +08001170 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001171}
1172
1173
Brian Paul1ed10272008-05-27 13:45:41 -06001174EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001175eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1176{
Chia-I Wu655f4652010-02-17 17:30:44 +08001177 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001178 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1179 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001180 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001181
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001182 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001183 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001184 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
1185
Chia-I Wubef4b472010-02-19 12:08:50 +08001186 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001187}
1188
1189
Brian Paul1ed10272008-05-27 13:45:41 -06001190EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001191eglSwapInterval(EGLDisplay dpy, EGLint interval)
1192{
Chia-I Wu655f4652010-02-17 17:30:44 +08001193 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu57da4992009-10-15 11:08:48 +08001194 _EGLContext *ctx = _eglGetCurrentContext();
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001195 _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
Chia-I Wuaed73582010-02-17 15:43:47 +08001196 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001197 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001198
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001199 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001200 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu57da4992009-10-15 11:08:48 +08001201
Chia-I Wud19afc52010-10-23 12:52:26 +08001202 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1203 ctx->Resource.Display != disp)
Chia-I Wubef4b472010-02-19 12:08:50 +08001204 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001205
Chia-I Wud19afc52010-10-23 12:52:26 +08001206 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001207 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001208
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001209 interval = CLAMP(interval,
1210 surf->Config->MinSwapInterval,
1211 surf->Config->MaxSwapInterval);
1212
Eric Engestromdd9eb8d2017-08-02 17:25:44 +01001213 if (surf->SwapInterval != interval)
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001214 ret = drv->API.SwapInterval(drv, disp, surf, interval);
1215 else
1216 ret = EGL_TRUE;
1217
1218 if (ret)
1219 surf->SwapInterval = interval;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001220
Chia-I Wubef4b472010-02-19 12:08:50 +08001221 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001222}
1223
1224
Brian Paul1ed10272008-05-27 13:45:41 -06001225EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001226eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
Brian Pauladbff7e2005-04-22 21:09:39 +00001227{
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001228 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu655f4652010-02-17 17:30:44 +08001229 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001230 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1231 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001232 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001233
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001234 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001235 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001236
1237 /* surface must be bound to current context in EGL 1.4 */
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001238 #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
Chia-I Wud19afc52010-10-23 12:52:26 +08001239 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1240 surf != ctx->DrawSurface)
Chia-I Wubef4b472010-02-19 12:08:50 +08001241 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001242 #endif
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001243
Chad Versace23c86c72017-05-04 17:46:33 -07001244 /* From the EGL 1.5 spec:
1245 *
1246 * If eglSwapBuffers is called and the native window associated with
1247 * surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
1248 * generated.
1249 */
1250 if (surf->Lost)
1251 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
1252
Chia-I Wub3bb1802010-02-17 16:05:27 +08001253 ret = drv->API.SwapBuffers(drv, disp, surf);
1254
Harish Krupo98275472017-06-09 20:13:34 +05301255 /* EGL_KHR_partial_update
1256 * Frame boundary successfully reached,
1257 * reset damage region and reset BufferAgeRead
1258 */
1259 if (ret) {
1260 surf->SetDamageRegionCalled = EGL_FALSE;
1261 surf->BufferAgeRead = EGL_FALSE;
1262 }
1263
Chia-I Wubef4b472010-02-19 12:08:50 +08001264 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001265}
1266
1267
Eric Engestrom0a606a42016-10-10 17:33:17 +01001268static EGLBoolean
Eric Engestrom9702f912016-11-16 22:29:53 +00001269_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
1270 EGLint *rects, EGLint n_rects)
Robert Bragg6425b142013-04-25 13:41:42 +01001271{
1272 _EGLContext *ctx = _eglGetCurrentContext();
Robert Bragg6425b142013-04-25 13:41:42 +01001273 _EGLDriver *drv;
1274 EGLBoolean ret;
1275
1276 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1277
1278 /* surface must be bound to current context in EGL 1.4 */
1279 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1280 surf != ctx->DrawSurface)
1281 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1282
1283 if ((n_rects > 0 && rects == NULL) || n_rects < 0)
1284 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1285
1286 ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
1287
Harish Krupo98275472017-06-09 20:13:34 +05301288 /* EGL_KHR_partial_update
1289 * Frame boundary successfully reached,
1290 * reset damage region and reset BufferAgeRead
1291 */
1292 if (ret) {
1293 surf->SetDamageRegionCalled = EGL_FALSE;
1294 surf->BufferAgeRead = EGL_FALSE;
1295 }
1296
Robert Bragg6425b142013-04-25 13:41:42 +01001297 RETURN_EGL_EVAL(disp, ret);
1298}
1299
Eric Engestrom0a606a42016-10-10 17:33:17 +01001300static EGLBoolean EGLAPIENTRY
1301eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
1302 EGLint *rects, EGLint n_rects)
1303{
1304 _EGLDisplay *disp = _eglLockDisplay(dpy);
1305 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1306 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001307 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001308}
1309
1310static EGLBoolean EGLAPIENTRY
1311eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
1312 EGLint *rects, EGLint n_rects)
1313{
1314 _EGLDisplay *disp = _eglLockDisplay(dpy);
1315 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1316 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001317 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001318}
1319
Harish Krupo98275472017-06-09 20:13:34 +05301320/**
1321 * If the width of the passed rect is greater than the surface's
1322 * width then it is clamped to the width of the surface. Same with
1323 * height.
1324 */
1325
1326static void
1327_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf,
1328 EGLint *rects, EGLint n_rects)
1329{
1330 EGLint i;
1331 EGLint surf_height = surf->Height;
1332 EGLint surf_width = surf->Width;
1333
1334 for (i = 0; i < (4 * n_rects); i += 4) {
1335 EGLint x, y, rect_width, rect_height;
1336 x = rects[i];
1337 y = rects[i + 1];
1338 rect_width = rects[i + 2];
1339 rect_height = rects[i + 3];
1340
1341 if (rect_width > surf_width - x)
1342 rects[i + 2] = surf_width - x;
1343
1344 if (rect_height > surf_height - y)
1345 rects[i + 3] = surf_height - y;
1346 }
1347}
1348
1349static EGLBoolean EGLAPIENTRY
1350eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
1351 EGLint *rects, EGLint n_rects)
1352{
1353 _EGLDisplay *disp = _eglLockDisplay(dpy);
1354 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1355 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1356 _EGLContext *ctx = _eglGetCurrentContext();
1357 _EGLDriver *drv;
1358 EGLBoolean ret;
1359 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1360
1361 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1362 surf->Type != EGL_WINDOW_BIT ||
1363 ctx->DrawSurface != surf ||
1364 surf->SwapBehavior != EGL_BUFFER_DESTROYED)
1365 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1366
1367 /* If the damage region is already set or
1368 * buffer age is not queried between
1369 * frame boundaries, throw bad access error
1370 */
1371
1372 if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
1373 RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
1374
1375 _eglSetDamageRegionKHRClampRects(disp, surf, rects, n_rects);
1376 ret = drv->API.SetDamageRegion(drv, disp, surf, rects, n_rects);
1377
1378 if (ret)
1379 surf->SetDamageRegionCalled = EGL_TRUE;
1380
1381 RETURN_EGL_EVAL(disp, ret);
1382}
1383
Brian Paul1ed10272008-05-27 13:45:41 -06001384EGLBoolean EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +08001385eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
Brian Pauladbff7e2005-04-22 21:09:39 +00001386{
Chia-I Wu655f4652010-02-17 17:30:44 +08001387 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001388 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1389 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001390 EGLBoolean ret;
Chad Versace6d1f83e2014-01-07 14:54:51 -08001391 void *native_pixmap_ptr;
1392
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001393 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001394 STATIC_ASSERT(sizeof(void*) == sizeof(target));
1395 native_pixmap_ptr = (void*) target;
Chia-I Wuaed73582010-02-17 15:43:47 +08001396
Chia-I Wubef4b472010-02-19 12:08:50 +08001397 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Benjamin Franzke85fe9482011-08-09 14:23:18 +02001398 if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
Chia-I Wuf22665d2010-06-17 17:14:03 +08001399 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001400 ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001401
Chia-I Wubef4b472010-02-19 12:08:50 +08001402 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001403}
1404
1405
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001406static EGLBoolean
1407_eglWaitClientCommon(void)
Brian Pauladbff7e2005-04-22 21:09:39 +00001408{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001409 _EGLContext *ctx = _eglGetCurrentContext();
1410 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001411 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001412 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001413
Chia-I Wu6c21c882009-09-28 14:12:39 +08001414 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001415 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001416
1417 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001418 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001419
1420 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001421 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1422 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001423 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001424
Chia-I Wu6c21c882009-09-28 14:12:39 +08001425 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001426 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001427 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001428 ret = drv->API.WaitClient(drv, disp, ctx);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001429
Chia-I Wubef4b472010-02-19 12:08:50 +08001430 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu6c21c882009-09-28 14:12:39 +08001431}
1432
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001433EGLBoolean EGLAPIENTRY
1434eglWaitClient(void)
1435{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001436 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001437 return _eglWaitClientCommon();
1438}
Chia-I Wu6c21c882009-09-28 14:12:39 +08001439
1440EGLBoolean EGLAPIENTRY
1441eglWaitGL(void)
1442{
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001443 /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001444 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001445 return _eglWaitClientCommon();
Brian Pauladbff7e2005-04-22 21:09:39 +00001446}
1447
1448
Brian Paul1ed10272008-05-27 13:45:41 -06001449EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001450eglWaitNative(EGLint engine)
1451{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001452 _EGLContext *ctx = _eglGetCurrentContext();
1453 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001454 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001455 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001456
Chia-I Wu6c21c882009-09-28 14:12:39 +08001457 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001458 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001459
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001460 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1461
Chia-I Wu655f4652010-02-17 17:30:44 +08001462 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001463 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001464
Chia-I Wu6c21c882009-09-28 14:12:39 +08001465 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001466 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1467 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001468 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001469
Chia-I Wu6c21c882009-09-28 14:12:39 +08001470 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001471 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001472 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001473 ret = drv->API.WaitNative(drv, disp, engine);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001474
Chia-I Wubef4b472010-02-19 12:08:50 +08001475 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001476}
1477
1478
Brian Paul1ed10272008-05-27 13:45:41 -06001479EGLDisplay EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001480eglGetCurrentDisplay(void)
1481{
Chia-I Wua1717972010-01-26 17:13:51 +08001482 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001483 EGLDisplay ret;
1484
1485 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
1486
Chia-I Wubef4b472010-02-19 12:08:50 +08001487 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001488}
1489
1490
Brian Paul1ed10272008-05-27 13:45:41 -06001491EGLContext EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001492eglGetCurrentContext(void)
1493{
1494 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001495 EGLContext ret;
1496
1497 ret = _eglGetContextHandle(ctx);
1498
Chia-I Wubef4b472010-02-19 12:08:50 +08001499 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001500}
1501
1502
Brian Paul1ed10272008-05-27 13:45:41 -06001503EGLSurface EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001504eglGetCurrentSurface(EGLint readdraw)
1505{
Chia-I Wu61906632009-09-30 15:34:45 +08001506 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001507 EGLint err = EGL_SUCCESS;
Chia-I Wu61906632009-09-30 15:34:45 +08001508 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001509 EGLSurface ret;
Chia-I Wu61906632009-09-30 15:34:45 +08001510
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001511 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
1512
Chia-I Wu61906632009-09-30 15:34:45 +08001513 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001514 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
Chia-I Wu61906632009-09-30 15:34:45 +08001515
1516 switch (readdraw) {
1517 case EGL_DRAW:
1518 surf = ctx->DrawSurface;
1519 break;
1520 case EGL_READ:
1521 surf = ctx->ReadSurface;
1522 break;
1523 default:
Chia-I Wu61906632009-09-30 15:34:45 +08001524 surf = NULL;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001525 err = EGL_BAD_PARAMETER;
Chia-I Wu61906632009-09-30 15:34:45 +08001526 break;
1527 }
1528
Chia-I Wub3bb1802010-02-17 16:05:27 +08001529 ret = _eglGetSurfaceHandle(surf);
1530
Chia-I Wubef4b472010-02-19 12:08:50 +08001531 RETURN_EGL_ERROR(NULL, err, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001532}
1533
1534
Brian Paul1ed10272008-05-27 13:45:41 -06001535EGLint EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001536eglGetError(void)
1537{
Brian Paul48822792005-12-10 17:54:00 +00001538 _EGLThreadInfo *t = _eglGetCurrentThread();
1539 EGLint e = t->LastError;
Chia-I Wu75da80b2009-07-17 11:41:02 -06001540 if (!_eglIsCurrentThreadDummy())
1541 t->LastError = EGL_SUCCESS;
Brian Pauladbff7e2005-04-22 21:09:39 +00001542 return e;
1543}
1544
1545
Brian Paulb2006a42006-01-30 00:10:55 +00001546/**
1547 ** EGL 1.2
1548 **/
1549
Brian Pauld5078b92008-05-30 13:45:40 -06001550/**
1551 * Specify the client API to use for subsequent calls including:
1552 * eglCreateContext()
1553 * eglGetCurrentContext()
1554 * eglGetCurrentDisplay()
1555 * eglGetCurrentSurface()
1556 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1557 * eglWaitClient()
1558 * eglWaitNative()
1559 * See section 3.7 "Rendering Context" in the EGL specification for details.
1560 */
nobledc43ab4f2010-07-02 19:38:07 -04001561EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001562eglBindAPI(EGLenum api)
1563{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001564 _EGLThreadInfo *t;
Brian Paulb2006a42006-01-30 00:10:55 +00001565
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001566 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1567
1568 t = _eglGetCurrentThread();
Chia-I Wu75da80b2009-07-17 11:41:02 -06001569 if (_eglIsCurrentThreadDummy())
Chia-I Wubef4b472010-02-19 12:08:50 +08001570 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
Chia-I Wu75da80b2009-07-17 11:41:02 -06001571
Chia-I Wu21b635f2009-07-17 11:42:04 -06001572 if (!_eglIsApiValid(api))
Chia-I Wubef4b472010-02-19 12:08:50 +08001573 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wu21b635f2009-07-17 11:42:04 -06001574
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001575 t->CurrentAPI = api;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001576
Chia-I Wubef4b472010-02-19 12:08:50 +08001577 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001578}
Jon Smirl7012d012005-05-13 18:31:35 +00001579
1580
Brian Pauld5078b92008-05-30 13:45:40 -06001581/**
1582 * Return the last value set with eglBindAPI().
1583 */
nobledc43ab4f2010-07-02 19:38:07 -04001584EGLenum EGLAPIENTRY
Brian Pauld5078b92008-05-30 13:45:40 -06001585eglQueryAPI(void)
1586{
Brian Pauld5078b92008-05-30 13:45:40 -06001587 _EGLThreadInfo *t = _eglGetCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001588 EGLenum ret;
1589
1590 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001591 ret = t->CurrentAPI;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001592
Chia-I Wubef4b472010-02-19 12:08:50 +08001593 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauld5078b92008-05-30 13:45:40 -06001594}
1595
1596
nobledc43ab4f2010-07-02 19:38:07 -04001597EGLSurface EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001598eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1599 EGLClientBuffer buffer, EGLConfig config,
1600 const EGLint *attrib_list)
1601{
Chia-I Wu655f4652010-02-17 17:30:44 +08001602 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001603 _EGLConfig *conf = _eglLookupConfig(config, disp);
1604 _EGLDriver *drv;
1605 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001606 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001607
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001608 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1609
Chia-I Wubef4b472010-02-19 12:08:50 +08001610 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001611
1612 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1613 conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001614 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001615
Chia-I Wubef4b472010-02-19 12:08:50 +08001616 RETURN_EGL_EVAL(disp, ret);
Brian Paulb2006a42006-01-30 00:10:55 +00001617}
Jon Smirl7012d012005-05-13 18:31:35 +00001618
Brian Paulb2006a42006-01-30 00:10:55 +00001619
nobledc43ab4f2010-07-02 19:38:07 -04001620EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001621eglReleaseThread(void)
1622{
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001623 /* unbind current contexts */
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001624 if (!_eglIsCurrentThreadDummy()) {
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001625 _EGLThreadInfo *t = _eglGetCurrentThread();
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001626 _EGLContext *ctx = t->CurrentContext;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001627
1628 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1629
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001630 if (ctx) {
1631 _EGLDisplay *disp = ctx->Resource.Display;
1632 _EGLDriver *drv;
Chia-I Wu655f4652010-02-17 17:30:44 +08001633
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001634 mtx_lock(&disp->Mutex);
1635 drv = disp->Driver;
1636 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1637 mtx_unlock(&disp->Mutex);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001638 }
Brian Paulb2006a42006-01-30 00:10:55 +00001639 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001640
Chia-I Wu75da80b2009-07-17 11:41:02 -06001641 _eglDestroyCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001642
Chia-I Wubef4b472010-02-19 12:08:50 +08001643 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001644}
1645
1646
Kyle Brenneman58338c62016-09-12 17:38:13 -04001647static EGLImage
1648_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001649 EGLClientBuffer buffer, const EGLint *attr_list)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001650{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001651 _EGLContext *context = _eglLookupContext(ctx, disp);
1652 _EGLDriver *drv;
1653 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02001654 EGLImage ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001655
Chia-I Wubef4b472010-02-19 12:08:50 +08001656 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001657 if (!disp->Extensions.KHR_image_base)
1658 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001659 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +08001660 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
Topi Pohjolainen0de013b2013-03-22 14:31:01 +02001661 /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1662 * <ctx> must be EGL_NO_CONTEXT..."
1663 */
1664 if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1665 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001666
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001667 img = drv->API.CreateImageKHR(drv, disp, context, target,
1668 buffer, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001669 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001670
Chia-I Wubef4b472010-02-19 12:08:50 +08001671 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001672}
1673
Kyle Brenneman58338c62016-09-12 17:38:13 -04001674static EGLImage EGLAPIENTRY
1675eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1676 EGLClientBuffer buffer, const EGLint *attr_list)
1677{
1678 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001679 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
Kyle Brenneman58338c62016-09-12 17:38:13 -04001680 return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
1681}
1682
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001683
Marek Olšák515f04e2015-05-12 20:42:05 +02001684EGLImage EGLAPIENTRY
1685eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1686 EGLClientBuffer buffer, const EGLAttrib *attr_list)
1687{
Kyle Brenneman58338c62016-09-12 17:38:13 -04001688 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák515f04e2015-05-12 20:42:05 +02001689 EGLImage image;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001690 EGLint *int_attribs;
Marek Olšák515f04e2015-05-12 20:42:05 +02001691
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001692 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
1693
1694 int_attribs = _eglConvertAttribsToInt(attr_list);
Marek Olšák515f04e2015-05-12 20:42:05 +02001695 if (attr_list && !int_attribs)
Kyle Brenneman58338c62016-09-12 17:38:13 -04001696 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
Marek Olšák515f04e2015-05-12 20:42:05 +02001697
Kyle Brenneman58338c62016-09-12 17:38:13 -04001698 image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
Marek Olšák515f04e2015-05-12 20:42:05 +02001699 free(int_attribs);
1700 return image;
1701}
1702
1703
Eric Engestromdf7fa302017-02-21 23:56:44 +00001704static EGLBoolean
1705_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001706{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001707 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001708 EGLBoolean ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001709
Chia-I Wubef4b472010-02-19 12:08:50 +08001710 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001711 if (!disp->Extensions.KHR_image_base)
1712 RETURN_EGL_EVAL(disp, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001713 if (!img)
Chia-I Wubef4b472010-02-19 12:08:50 +08001714 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001715
1716 _eglUnlinkImage(img);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001717 ret = drv->API.DestroyImageKHR(drv, disp, img);
1718
Chia-I Wubef4b472010-02-19 12:08:50 +08001719 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001720}
1721
Eric Engestromdf7fa302017-02-21 23:56:44 +00001722EGLBoolean EGLAPIENTRY
1723eglDestroyImage(EGLDisplay dpy, EGLImage image)
1724{
1725 _EGLDisplay *disp = _eglLockDisplay(dpy);
1726 _EGLImage *img = _eglLookupImage(image, disp);
1727 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1728 return _eglDestroyImageCommon(disp, img);
1729}
1730
1731static EGLBoolean EGLAPIENTRY
1732eglDestroyImageKHR(EGLDisplay dpy, EGLImage image)
1733{
1734 _EGLDisplay *disp = _eglLockDisplay(dpy);
1735 _EGLImage *img = _eglLookupImage(image, disp);
1736 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1737 return _eglDestroyImageCommon(disp, img);
1738}
1739
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001740
Marek Olšákd333d302015-05-12 17:34:57 +02001741static EGLSync
Chad Versace80448852016-09-27 13:27:21 -07001742_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
1743 EGLBoolean orig_is_EGLAttrib,
Marek Olšák51c8c662015-05-12 21:41:32 +02001744 EGLenum invalid_type_error)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001745{
Marek Olšák9a0bda22015-04-10 10:56:02 +02001746 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu4eebea72010-08-14 23:09:12 +08001747 _EGLDriver *drv;
1748 _EGLSync *sync;
Marek Olšákd333d302015-05-12 17:34:57 +02001749 EGLSync ret;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001750
1751 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001752
Chad Versace80448852016-09-27 13:27:21 -07001753 if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
Chad Versacef2c2f432016-09-27 13:27:12 -07001754 /* There exist two EGLAttrib variants of eglCreateSync*:
1755 * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
1756 * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
1757 * support as a proxy for EGL 1.5 support, even though that's not
1758 * entirely correct (though _eglComputeVersion does the same).
1759 *
1760 * The EGL spec provides no guidance on how to handle unsupported
1761 * functions. EGL_BAD_MATCH seems reasonable.
1762 */
1763 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1764 }
Marek Olšák290a3eb2015-04-10 13:16:30 +02001765
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001766 /* If type is EGL_SYNC_FENCE and no context is current for the bound API
1767 * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH
1768 * error is generated.
1769 */
Rob Clark0201f012016-11-18 08:39:33 -05001770 if (!ctx &&
1771 (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001772 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1773
Marek Olšák9a0bda22015-04-10 10:56:02 +02001774 /* return an error if the client API doesn't support GL_OES_EGL_sync */
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001775 if (ctx && (ctx->Resource.Display != disp ||
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001776 ctx->ClientAPI != EGL_OPENGL_ES_API))
Marek Olšák9a0bda22015-04-10 10:56:02 +02001777 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1778
1779 switch (type) {
1780 case EGL_SYNC_FENCE_KHR:
1781 if (!disp->Extensions.KHR_fence_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001782 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001783 break;
1784 case EGL_SYNC_REUSABLE_KHR:
1785 if (!disp->Extensions.KHR_reusable_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001786 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001787 break;
Marek Olšák290a3eb2015-04-10 13:16:30 +02001788 case EGL_SYNC_CL_EVENT_KHR:
1789 if (!disp->Extensions.KHR_cl_event2)
Marek Olšák51c8c662015-05-12 21:41:32 +02001790 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001791 break;
Rob Clark0201f012016-11-18 08:39:33 -05001792 case EGL_SYNC_NATIVE_FENCE_ANDROID:
1793 if (!disp->Extensions.ANDROID_native_fence_sync)
1794 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1795 break;
Marek Olšák9a0bda22015-04-10 10:56:02 +02001796 default:
Marek Olšák51c8c662015-05-12 21:41:32 +02001797 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001798 }
Chia-I Wu4eebea72010-08-14 23:09:12 +08001799
Chad Versace80448852016-09-27 13:27:21 -07001800 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001801 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001802
1803 RETURN_EGL_EVAL(disp, ret);
1804}
1805
1806
Marek Olšákd333d302015-05-12 17:34:57 +02001807static EGLSync EGLAPIENTRY
Chad Versace80448852016-09-27 13:27:21 -07001808eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001809{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001810 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001811 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001812
1813 EGLSync sync;
1814 EGLAttrib *attrib_list;
1815 EGLint err;
1816
1817 if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
1818 attrib_list = (EGLAttrib *) int_list;
1819 } else {
1820 err = _eglConvertIntsToAttribs(int_list, &attrib_list);
1821 if (err != EGL_SUCCESS)
1822 RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
1823 }
1824
1825 sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001826 EGL_BAD_ATTRIBUTE);
Chad Versace80448852016-09-27 13:27:21 -07001827
1828 if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
1829 free(attrib_list);
1830
1831 /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
1832 return sync;
Marek Olšák51c8c662015-05-12 21:41:32 +02001833}
1834
1835
1836static EGLSync EGLAPIENTRY
1837eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1838{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001839 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001840 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001841 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001842 EGL_BAD_ATTRIBUTE);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001843}
1844
1845
Marek Olšák2885ba02015-05-12 20:54:22 +02001846EGLSync EGLAPIENTRY
1847eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001848{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001849 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001850 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001851 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001852 EGL_BAD_PARAMETER);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001853}
1854
1855
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001856static EGLBoolean
1857_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001858{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001859 _EGLDriver *drv;
1860 EGLBoolean ret;
1861
1862 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001863 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05001864 disp->Extensions.KHR_fence_sync ||
1865 disp->Extensions.ANDROID_native_fence_sync);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001866
Chia-I Wu4eebea72010-08-14 23:09:12 +08001867 _eglUnlinkSync(s);
1868 ret = drv->API.DestroySyncKHR(drv, disp, s);
1869
1870 RETURN_EGL_EVAL(disp, ret);
1871}
1872
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001873EGLBoolean EGLAPIENTRY
1874eglDestroySync(EGLDisplay dpy, EGLSync sync)
1875{
1876 _EGLDisplay *disp = _eglLockDisplay(dpy);
1877 _EGLSync *s = _eglLookupSync(sync, disp);
1878 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1879 return _eglDestroySync(disp, s);
1880}
1881
1882static EGLBoolean EGLAPIENTRY
1883eglDestroySyncKHR(EGLDisplay dpy, EGLSync sync)
1884{
1885 _EGLDisplay *disp = _eglLockDisplay(dpy);
1886 _EGLSync *s = _eglLookupSync(sync, disp);
1887 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1888 return _eglDestroySync(disp, s);
1889}
1890
Chia-I Wu4eebea72010-08-14 23:09:12 +08001891
Eric Engestrom66d5ec52017-02-21 23:56:46 +00001892static EGLint
1893_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
1894 _EGLSync *s, EGLint flags, EGLTime timeout)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001895{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001896 _EGLDriver *drv;
1897 EGLint ret;
1898
1899 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001900 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05001901 disp->Extensions.KHR_fence_sync ||
1902 disp->Extensions.ANDROID_native_fence_sync);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001903
1904 if (s->SyncStatus == EGL_SIGNALED_KHR)
1905 RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
1906
Dongwon Kim70299472016-04-04 17:14:10 -07001907 /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
1908 * unlocked here to allow other threads also to be able to
1909 * go into waiting state.
1910 */
1911
1912 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1913 _eglUnlockDisplay(dpy);
1914
Chia-I Wu4eebea72010-08-14 23:09:12 +08001915 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1916
Dongwon Kim70299472016-04-04 17:14:10 -07001917 /*
1918 * 'disp' is already unlocked for reusable sync type,
1919 * so passing 'NULL' to bypass unlocking display.
1920 */
1921 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1922 RETURN_EGL_EVAL(NULL, ret);
1923 else
1924 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001925}
1926
Eric Engestrom66d5ec52017-02-21 23:56:46 +00001927EGLint EGLAPIENTRY
1928eglClientWaitSync(EGLDisplay dpy, EGLSync sync,
1929 EGLint flags, EGLTime timeout)
1930{
1931 _EGLDisplay *disp = _eglLockDisplay(dpy);
1932 _EGLSync *s = _eglLookupSync(sync, disp);
1933 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1934 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
1935}
1936
1937static EGLint EGLAPIENTRY
1938eglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync,
1939 EGLint flags, EGLTime timeout)
1940{
1941 _EGLDisplay *disp = _eglLockDisplay(dpy);
1942 _EGLSync *s = _eglLookupSync(sync, disp);
1943 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1944 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
1945}
1946
Chia-I Wu4eebea72010-08-14 23:09:12 +08001947
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001948static EGLint
1949_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
Marek Olšáka8617cc2015-04-10 12:04:18 +02001950{
Marek Olšáka8617cc2015-04-10 12:04:18 +02001951 _EGLContext *ctx = _eglGetCurrentContext();
1952 _EGLDriver *drv;
1953 EGLint ret;
1954
1955 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1956 assert(disp->Extensions.KHR_wait_sync);
1957
1958 /* return an error if the client API doesn't support GL_OES_EGL_sync */
1959 if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
1960 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1961
1962 /* the API doesn't allow any flags yet */
1963 if (flags != 0)
1964 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1965
1966 ret = drv->API.WaitSyncKHR(drv, disp, s);
1967
1968 RETURN_EGL_EVAL(disp, ret);
1969}
1970
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001971static EGLint EGLAPIENTRY
1972eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
1973{
1974 _EGLDisplay *disp = _eglLockDisplay(dpy);
1975 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001976 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001977 return _eglWaitSyncCommon(disp, s, flags);
1978}
1979
Marek Olšáka8617cc2015-04-10 12:04:18 +02001980
Marek Olšák75245922015-05-12 18:13:31 +02001981EGLBoolean EGLAPIENTRY
1982eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
1983{
1984 /* The KHR version returns EGLint, while the core version returns
1985 * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
1986 * EGL_TRUE.
1987 */
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001988 _EGLDisplay *disp = _eglLockDisplay(dpy);
1989 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001990 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001991 return _eglWaitSyncCommon(disp, s, flags);
Marek Olšák75245922015-05-12 18:13:31 +02001992}
1993
1994
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001995static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02001996eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001997{
1998 _EGLDisplay *disp = _eglLockDisplay(dpy);
1999 _EGLSync *s = _eglLookupSync(sync, disp);
2000 _EGLDriver *drv;
2001 EGLBoolean ret;
2002
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002003 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2004
Chia-I Wu4eebea72010-08-14 23:09:12 +08002005 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002006 assert(disp->Extensions.KHR_reusable_sync);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002007 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
2008
2009 RETURN_EGL_EVAL(disp, ret);
2010}
2011
2012
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002013static EGLBoolean
2014_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
Chia-I Wu4eebea72010-08-14 23:09:12 +08002015{
Chia-I Wu4eebea72010-08-14 23:09:12 +08002016 _EGLDriver *drv;
2017 EGLBoolean ret;
2018
2019 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02002020 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05002021 disp->Extensions.KHR_fence_sync ||
2022 disp->Extensions.ANDROID_native_fence_sync);
Marek Olšák1e79e052015-05-12 18:14:31 +02002023 ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002024
2025 RETURN_EGL_EVAL(disp, ret);
2026}
2027
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002028EGLBoolean EGLAPIENTRY
2029eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
2030{
2031 _EGLDisplay *disp = _eglLockDisplay(dpy);
2032 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002033 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002034 return _eglGetSyncAttribCommon(disp, s, attribute, value);
2035}
2036
Chia-I Wu4eebea72010-08-14 23:09:12 +08002037
Marek Olšák1e79e052015-05-12 18:14:31 +02002038static EGLBoolean EGLAPIENTRY
2039eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
2040{
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002041 _EGLDisplay *disp = _eglLockDisplay(dpy);
2042 _EGLSync *s = _eglLookupSync(sync, disp);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002043 EGLAttrib attrib;
2044 EGLBoolean result;
2045
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002046 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2047
Dongwon Kimd1e15632016-02-02 15:06:28 -08002048 if (!value)
Chad Versace17084b62016-09-27 23:06:37 -07002049 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002050
2051 attrib = *value;
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002052 result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
Marek Olšák1e79e052015-05-12 18:14:31 +02002053
2054 /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
2055 *
2056 * If any error occurs, <*value> is not modified.
2057 */
2058 if (result == EGL_FALSE)
2059 return result;
2060
2061 *value = attrib;
2062 return result;
2063}
2064
Rob Clark0201f012016-11-18 08:39:33 -05002065static EGLint EGLAPIENTRY
2066eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
2067{
2068 _EGLDisplay *disp = _eglLockDisplay(dpy);
2069 _EGLSync *s = _eglLookupSync(sync, disp);
2070 _EGLDriver *drv;
2071 EGLBoolean ret;
2072
2073 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2074
2075 /* the spec doesn't seem to specify what happens if the fence
2076 * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems
2077 * sensible:
2078 */
2079 if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)))
2080 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID);
2081
2082 _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv);
2083 assert(disp->Extensions.ANDROID_native_fence_sync);
2084 ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s);
2085
2086 RETURN_EGL_EVAL(disp, ret);
2087}
Marek Olšák1e79e052015-05-12 18:14:31 +02002088
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002089static EGLBoolean EGLAPIENTRY
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002090eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002091 EGLint numRects, const EGLint *rects)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002092{
2093 _EGLContext *ctx = _eglGetCurrentContext();
2094 _EGLDisplay *disp = _eglLockDisplay(dpy);
2095 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2096 _EGLDriver *drv;
2097 EGLBoolean ret;
2098
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002099 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2100
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002101 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2102
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002103 if (!disp->Extensions.NOK_swap_region)
2104 RETURN_EGL_EVAL(disp, EGL_FALSE);
2105
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002106 /* surface must be bound to current context in EGL 1.4 */
Chia-I Wud19afc52010-10-23 12:52:26 +08002107 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
2108 surf != ctx->DrawSurface)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002109 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
2110
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002111 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002112
2113 RETURN_EGL_EVAL(disp, ret);
2114}
2115
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002116
Marek Olšákd333d302015-05-12 17:34:57 +02002117static EGLImage EGLAPIENTRY
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002118eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
2119{
2120 _EGLDisplay *disp = _eglLockDisplay(dpy);
2121 _EGLDriver *drv;
2122 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02002123 EGLImage ret;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002124
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002125 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2126
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002127 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002128 if (!disp->Extensions.MESA_drm_image)
2129 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002130
2131 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08002132 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002133
2134 RETURN_EGL_EVAL(disp, ret);
2135}
2136
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002137static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002138eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002139 EGLint *name, EGLint *handle, EGLint *stride)
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002140{
2141 _EGLDisplay *disp = _eglLockDisplay(dpy);
2142 _EGLImage *img = _eglLookupImage(image, disp);
2143 _EGLDriver *drv;
2144 EGLBoolean ret;
2145
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002146 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2147
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002148 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002149 assert(disp->Extensions.MESA_drm_image);
2150
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002151 if (!img)
2152 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2153
2154 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
2155
2156 RETURN_EGL_EVAL(disp, ret);
2157}
2158
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002159
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002160struct wl_display;
2161
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002162static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002163eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2164{
2165 _EGLDisplay *disp = _eglLockDisplay(dpy);
2166 _EGLDriver *drv;
2167 EGLBoolean ret;
2168
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002169 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2170
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002171 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2172 assert(disp->Extensions.WL_bind_wayland_display);
2173
2174 if (!display)
2175 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2176
2177 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
2178
2179 RETURN_EGL_EVAL(disp, ret);
2180}
2181
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002182static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002183eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2184{
2185 _EGLDisplay *disp = _eglLockDisplay(dpy);
2186 _EGLDriver *drv;
2187 EGLBoolean ret;
2188
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002189 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2190
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002191 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2192 assert(disp->Extensions.WL_bind_wayland_display);
2193
2194 if (!display)
2195 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2196
2197 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
2198
2199 RETURN_EGL_EVAL(disp, ret);
2200}
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002201
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002202static EGLBoolean EGLAPIENTRY
Ander Conselvan de Oliveira8d29b522013-07-18 15:11:25 +03002203eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002204 EGLint attribute, EGLint *value)
2205{
2206 _EGLDisplay *disp = _eglLockDisplay(dpy);
2207 _EGLDriver *drv;
2208 EGLBoolean ret;
2209
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002210 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2211
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002212 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2213 assert(disp->Extensions.WL_bind_wayland_display);
2214
2215 if (!buffer)
2216 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2217
2218 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
2219
2220 RETURN_EGL_EVAL(disp, ret);
2221}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002222
Emil Velikov720125f2015-07-10 11:22:13 +01002223
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002224static struct wl_buffer * EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002225eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002226{
2227 _EGLDisplay *disp = _eglLockDisplay(dpy);
2228 _EGLImage *img;
2229 _EGLDriver *drv;
2230 struct wl_buffer *ret;
2231
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002232 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2233
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002234 _EGL_CHECK_DISPLAY(disp, NULL, drv);
Emil Velikov70131142017-05-15 16:14:15 +01002235 if (!disp->Extensions.WL_create_wayland_buffer_from_image)
2236 RETURN_EGL_EVAL(disp, NULL);
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002237
2238 img = _eglLookupImage(image, disp);
2239
2240 if (!img)
2241 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
2242
2243 ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
2244
2245 RETURN_EGL_EVAL(disp, ret);
2246}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002247
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002248static EGLBoolean EGLAPIENTRY
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002249eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
2250 EGLint x, EGLint y, EGLint width, EGLint height)
2251{
2252 _EGLDisplay *disp = _eglLockDisplay(dpy);
2253 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2254 _EGLDriver *drv;
2255 EGLBoolean ret;
2256
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002257 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2258
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002259 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2260
2261 if (!disp->Extensions.NV_post_sub_buffer)
2262 RETURN_EGL_EVAL(disp, EGL_FALSE);
2263
2264 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
2265
2266 RETURN_EGL_EVAL(disp, ret);
2267}
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002268
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002269static EGLBoolean EGLAPIENTRY
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002270eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
2271 EGLuint64KHR *ust, EGLuint64KHR *msc,
2272 EGLuint64KHR *sbc)
2273{
2274 _EGLDisplay *disp = _eglLockDisplay(display);
2275 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2276 _EGLDriver *drv;
2277 EGLBoolean ret;
2278
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002279 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2280
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002281 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2282 if (!disp->Extensions.CHROMIUM_sync_control)
2283 RETURN_EGL_EVAL(disp, EGL_FALSE);
2284
2285 if (!ust || !msc || !sbc)
2286 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2287
2288 ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
2289
2290 RETURN_EGL_EVAL(disp, ret);
2291}
Dave Airlie8f7338f2014-03-03 13:57:16 +10002292
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002293static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002294eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002295 EGLint *fourcc, EGLint *nplanes,
Dave Airlieb5045e22015-05-05 09:10:34 +10002296 EGLuint64KHR *modifiers)
Dave Airlie8f7338f2014-03-03 13:57:16 +10002297{
2298 _EGLDisplay *disp = _eglLockDisplay(dpy);
2299 _EGLImage *img = _eglLookupImage(image, disp);
2300 _EGLDriver *drv;
2301 EGLBoolean ret;
2302
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002303 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2304
Dave Airlie8f7338f2014-03-03 13:57:16 +10002305 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2306 assert(disp->Extensions.MESA_image_dma_buf_export);
2307
2308 if (!img)
2309 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2310
2311 ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
2312 modifiers);
2313
2314 RETURN_EGL_EVAL(disp, ret);
2315}
2316
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002317static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002318eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002319 int *fds, EGLint *strides, EGLint *offsets)
2320{
2321 _EGLDisplay *disp = _eglLockDisplay(dpy);
2322 _EGLImage *img = _eglLookupImage(image, disp);
2323 _EGLDriver *drv;
2324 EGLBoolean ret;
2325
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002326 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2327
Dave Airlie8f7338f2014-03-03 13:57:16 +10002328 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2329 assert(disp->Extensions.MESA_image_dma_buf_export);
2330
2331 if (!img)
2332 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2333
2334 ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
2335
2336 RETURN_EGL_EVAL(disp, ret);
2337}
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002338
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002339static EGLint EGLAPIENTRY
2340eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002341 EGLLabelKHR label)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002342{
2343 _EGLDisplay *disp = NULL;
2344 _EGLResourceType type;
2345
2346 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2347
2348 if (objectType == EGL_OBJECT_THREAD_KHR) {
2349 _EGLThreadInfo *t = _eglGetCurrentThread();
2350
2351 if (!_eglIsCurrentThreadDummy()) {
2352 t->Label = label;
2353 return EGL_SUCCESS;
2354 }
2355
2356 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
2357 }
2358
2359 disp = _eglLockDisplay(dpy);
2360 if (disp == NULL)
2361 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
2362
2363 if (objectType == EGL_OBJECT_DISPLAY_KHR) {
2364 if (dpy != (EGLDisplay) object)
2365 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2366
2367 disp->Label = label;
2368 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2369 }
2370
2371 switch (objectType) {
2372 case EGL_OBJECT_CONTEXT_KHR:
2373 type = _EGL_RESOURCE_CONTEXT;
2374 break;
2375 case EGL_OBJECT_SURFACE_KHR:
2376 type = _EGL_RESOURCE_SURFACE;
2377 break;
2378 case EGL_OBJECT_IMAGE_KHR:
2379 type = _EGL_RESOURCE_IMAGE;
2380 break;
2381 case EGL_OBJECT_SYNC_KHR:
2382 type = _EGL_RESOURCE_SYNC;
2383 break;
2384 case EGL_OBJECT_STREAM_KHR:
2385 default:
2386 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2387 }
2388
2389 if (_eglCheckResource(object, type, disp)) {
2390 _EGLResource *res = (_EGLResource *) object;
2391
2392 res->Label = label;
2393 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2394 }
2395
2396 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2397}
2398
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002399static EGLint EGLAPIENTRY
2400eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002401 const EGLAttrib *attrib_list)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002402{
2403 unsigned int newEnabled;
2404
2405 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2406
2407 mtx_lock(_eglGlobal.Mutex);
2408
2409 newEnabled = _eglGlobal.debugTypesEnabled;
2410 if (attrib_list != NULL) {
2411 int i;
2412
2413 for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
Emil Velikov4df0d502017-09-07 17:03:53 +01002414 switch (attrib_list[i]) {
2415 case EGL_DEBUG_MSG_CRITICAL_KHR:
2416 case EGL_DEBUG_MSG_ERROR_KHR:
2417 case EGL_DEBUG_MSG_WARN_KHR:
2418 case EGL_DEBUG_MSG_INFO_KHR:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002419 if (attrib_list[i + 1])
2420 newEnabled |= DebugBitFromType(attrib_list[i]);
2421 else
2422 newEnabled &= ~DebugBitFromType(attrib_list[i]);
Emil Velikov4df0d502017-09-07 17:03:53 +01002423 break;
2424 default:
2425 // On error, set the last error code, call the current
2426 // debug callback, and return the error code.
2427 mtx_unlock(_eglGlobal.Mutex);
2428 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
2429 "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
2430 return EGL_BAD_ATTRIBUTE;
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002431 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002432 }
2433 }
2434
2435 if (callback != NULL) {
2436 _eglGlobal.debugCallback = callback;
2437 _eglGlobal.debugTypesEnabled = newEnabled;
2438 } else {
2439 _eglGlobal.debugCallback = NULL;
2440 _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
2441 }
2442
2443 mtx_unlock(_eglGlobal.Mutex);
2444 return EGL_SUCCESS;
2445}
2446
2447static EGLBoolean EGLAPIENTRY
2448eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
2449{
2450 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2451
2452 mtx_lock(_eglGlobal.Mutex);
2453
Emil Velikov4df0d502017-09-07 17:03:53 +01002454 switch (attribute) {
2455 case EGL_DEBUG_MSG_CRITICAL_KHR:
2456 case EGL_DEBUG_MSG_ERROR_KHR:
2457 case EGL_DEBUG_MSG_WARN_KHR:
2458 case EGL_DEBUG_MSG_INFO_KHR:
2459 if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
2460 *value = EGL_TRUE;
2461 else
2462 *value = EGL_FALSE;
2463 break;
2464 case EGL_DEBUG_CALLBACK_KHR:
2465 *value = (EGLAttrib) _eglGlobal.debugCallback;
2466 break;
2467 default:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002468 mtx_unlock(_eglGlobal.Mutex);
2469 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002470 "Invalid attribute 0x%04lx", (unsigned long) attribute);
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002471 return EGL_FALSE;
Emil Velikov4df0d502017-09-07 17:03:53 +01002472 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002473
2474 mtx_unlock(_eglGlobal.Mutex);
2475 return EGL_TRUE;
2476}
2477
Eric Engestrom1534fc62017-02-21 23:56:52 +00002478static int
2479_eglFunctionCompare(const void *key, const void *elem)
2480{
2481 const char *procname = key;
2482 const struct _egl_entrypoint *entrypoint = elem;
2483 return strcmp(procname, entrypoint->name);
2484}
2485
Varad Gautam6719e052017-05-30 17:23:38 +05302486static EGLBoolean EGLAPIENTRY
2487eglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats,
2488 EGLint *formats, EGLint *num_formats)
2489{
2490 _EGLDisplay *disp = _eglLockDisplay(dpy);
2491 _EGLDriver *drv;
2492 EGLBoolean ret;
2493
2494 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2495
2496 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2497
2498 ret = drv->API.QueryDmaBufFormatsEXT(drv, disp, max_formats, formats,
2499 num_formats);
2500
2501 RETURN_EGL_EVAL(disp, ret);
2502}
2503
Varad Gautamde3c4592017-05-30 17:23:39 +05302504static EGLBoolean EGLAPIENTRY
2505eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
2506 EGLuint64KHR *modifiers, EGLBoolean *external_only,
2507 EGLint *num_modifiers)
2508{
2509 _EGLDisplay *disp = _eglLockDisplay(dpy);
2510 _EGLDriver *drv;
2511 EGLBoolean ret;
2512
2513 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2514
2515 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2516
2517 ret = drv->API.QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers,
2518 modifiers, external_only,
2519 num_modifiers);
2520
2521 RETURN_EGL_EVAL(disp, ret);
2522}
2523
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002524__eglMustCastToProperFunctionPointerType EGLAPIENTRY
2525eglGetProcAddress(const char *procname)
2526{
Eric Engestrom1534fc62017-02-21 23:56:52 +00002527 static const struct _egl_entrypoint egl_functions[] = {
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002528#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
Eric Engestromf92fd4d2017-02-21 23:56:49 +00002529#include "eglentrypoint.h"
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002530#undef EGL_ENTRYPOINT
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002531 };
Eric Engestrom1534fc62017-02-21 23:56:52 +00002532 _EGLProc ret = NULL;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002533
2534 if (!procname)
2535 RETURN_EGL_SUCCESS(NULL, NULL);
2536
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002537 _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2538
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002539 if (strncmp(procname, "egl", 3) == 0) {
Eric Engestrom1534fc62017-02-21 23:56:52 +00002540 const struct _egl_entrypoint *entrypoint =
2541 bsearch(procname,
2542 egl_functions, ARRAY_SIZE(egl_functions),
2543 sizeof(egl_functions[0]),
2544 _eglFunctionCompare);
2545 if (entrypoint)
2546 ret = entrypoint->function;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002547 }
Eric Engestrom1534fc62017-02-21 23:56:52 +00002548
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002549 if (!ret)
2550 ret = _eglGetDriverProc(procname);
2551
2552 RETURN_EGL_SUCCESS(NULL, ret);
2553}
Marek Olšákb6eda702016-03-03 15:59:48 +01002554
2555static int
2556_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
2557 _EGLDisplay **disp, _EGLDriver **drv,
2558 _EGLContext **ctx)
2559{
2560
2561 *disp = _eglLockDisplay(dpy);
2562 if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
2563 if (*disp)
2564 _eglUnlockDisplay(*disp);
2565 return MESA_GLINTEROP_INVALID_DISPLAY;
2566 }
2567
2568 *drv = (*disp)->Driver;
2569
2570 *ctx = _eglLookupContext(context, *disp);
2571 if (!*ctx ||
2572 ((*ctx)->ClientAPI != EGL_OPENGL_API &&
2573 (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
2574 _eglUnlockDisplay(*disp);
2575 return MESA_GLINTEROP_INVALID_CONTEXT;
2576 }
2577
2578 return MESA_GLINTEROP_SUCCESS;
2579}
2580
Marek Olšákee39d442016-11-02 18:59:22 +01002581PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002582MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002583 struct mesa_glinterop_device_info *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002584{
2585 _EGLDisplay *disp;
2586 _EGLDriver *drv;
2587 _EGLContext *ctx;
2588 int ret;
2589
2590 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2591 if (ret != MESA_GLINTEROP_SUCCESS)
2592 return ret;
2593
2594 if (drv->API.GLInteropQueryDeviceInfo)
2595 ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
2596 else
2597 ret = MESA_GLINTEROP_UNSUPPORTED;
2598
2599 _eglUnlockDisplay(disp);
2600 return ret;
2601}
2602
Marek Olšákee39d442016-11-02 18:59:22 +01002603PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002604MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002605 struct mesa_glinterop_export_in *in,
2606 struct mesa_glinterop_export_out *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002607{
2608 _EGLDisplay *disp;
2609 _EGLDriver *drv;
2610 _EGLContext *ctx;
2611 int ret;
2612
2613 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2614 if (ret != MESA_GLINTEROP_SUCCESS)
2615 return ret;
2616
2617 if (drv->API.GLInteropExportObject)
2618 ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
2619 else
2620 ret = MESA_GLINTEROP_UNSUPPORTED;
2621
2622 _eglUnlockDisplay(disp);
2623 return ret;
2624}