blob: 9c78e9c343e7e78fd3d7be667d9c751d171bc1c8 [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
Eric Engestrom8d9c2042018-11-15 18:07:33 +000086#ifdef USE_LIBGLVND
87#define EGLAPI
88#undef PUBLIC
89#define PUBLIC
90#endif
91
Brian Pauladbff7e2005-04-22 21:09:39 +000092#include <stdio.h>
Brian Paulb2006a42006-01-30 00:10:55 +000093#include <stdlib.h>
Brian Pauladbff7e2005-04-22 21:09:39 +000094#include <string.h>
Emil Velikov7bd16932015-02-28 16:35:22 +000095#include "c99_compat.h"
Emil Velikovefe87f12015-03-06 16:54:55 +000096#include "c11/threads.h"
Emil Velikov239e7ee2017-05-04 18:55:36 +010097#include "util/macros.h"
Chia-I Wu1e6c10f2010-05-31 11:47:58 +080098
Eric Engestromd75fbff2018-05-16 14:17:30 +010099#include "egldefines.h"
Chad Versace3c58d4c2013-10-11 16:04:55 -0700100#include "eglglobals.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000101#include "eglcontext.h"
102#include "egldisplay.h"
103#include "egltypedefs.h"
Chia-I Wu94cb3212010-01-29 09:00:30 +0800104#include "eglcurrent.h"
Emil Velikov7552fcb2015-07-24 16:19:55 +0200105#include "egldevice.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000106#include "egldriver.h"
107#include "eglsurface.h"
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800108#include "eglconfig.h"
Chia-I Wua1c4a8a2009-08-15 22:58:13 +0800109#include "eglimage.h"
Chia-I Wu4eebea72010-08-14 23:09:12 +0800110#include "eglsync.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000111
Matt Turner4e970842017-07-06 18:40:53 -0700112#include "GL/mesa_glinterop.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000113
114/**
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800115 * Macros to help return an API entrypoint.
Chia-I Wu655f4652010-02-17 17:30:44 +0800116 *
117 * These macros will unlock the display and record the error code.
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800118 */
Chia-I Wubef4b472010-02-19 12:08:50 +0800119#define RETURN_EGL_ERROR(disp, err, ret) \
120 do { \
Chia-I Wu655f4652010-02-17 17:30:44 +0800121 if (disp) \
122 _eglUnlockDisplay(disp); \
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800123 /* EGL error codes are non-zero */ \
124 if (err) \
Emil Velikovd7800122015-02-28 16:39:10 +0000125 _eglError(err, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800126 return ret; \
127 } while (0)
128
129#define RETURN_EGL_SUCCESS(disp, ret) \
130 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
131
Chia-I Wub3bb1802010-02-17 16:05:27 +0800132/* record EGL_SUCCESS only when ret evaluates to true */
Chia-I Wubef4b472010-02-19 12:08:50 +0800133#define RETURN_EGL_EVAL(disp, ret) \
134 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800135
136
Chia-I Wubef4b472010-02-19 12:08:50 +0800137/*
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800138 * A bunch of macros and checks to simplify error checking.
139 */
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800140
Eric Engestromc74628f2020-08-03 22:50:42 +0200141#define _EGL_CHECK_DISPLAY(disp, ret) \
Chia-I Wubef4b472010-02-19 12:08:50 +0800142 do { \
Eric Engestromc74628f2020-08-03 22:50:42 +0200143 if (!_eglCheckDisplay(disp, __func__)) \
Chia-I Wubef4b472010-02-19 12:08:50 +0800144 RETURN_EGL_ERROR(disp, 0, ret); \
145 } while (0)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800146
Eric Engestromc74628f2020-08-03 22:50:42 +0200147#define _EGL_CHECK_OBJECT(disp, type, obj, ret) \
Chia-I Wubef4b472010-02-19 12:08:50 +0800148 do { \
Eric Engestromc74628f2020-08-03 22:50:42 +0200149 if (!_eglCheck ## type(disp, obj, __func__)) \
Chia-I Wubef4b472010-02-19 12:08:50 +0800150 RETURN_EGL_ERROR(disp, 0, ret); \
151 } while (0)
152
Eric Engestromc74628f2020-08-03 22:50:42 +0200153#define _EGL_CHECK_SURFACE(disp, surf, ret) \
154 _EGL_CHECK_OBJECT(disp, Surface, surf, ret)
Chia-I Wubef4b472010-02-19 12:08:50 +0800155
Eric Engestromc74628f2020-08-03 22:50:42 +0200156#define _EGL_CHECK_CONTEXT(disp, context, ret) \
157 _EGL_CHECK_OBJECT(disp, Context, context, ret)
Chia-I Wubef4b472010-02-19 12:08:50 +0800158
Eric Engestromc74628f2020-08-03 22:50:42 +0200159#define _EGL_CHECK_CONFIG(disp, conf, ret) \
160 _EGL_CHECK_OBJECT(disp, Config, conf, ret)
Chia-I Wubef4b472010-02-19 12:08:50 +0800161
Eric Engestromc74628f2020-08-03 22:50:42 +0200162#define _EGL_CHECK_SYNC(disp, s, ret) \
163 _EGL_CHECK_OBJECT(disp, Sync, s, ret)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800164
165
Eric Engestrom1534fc62017-02-21 23:56:52 +0000166struct _egl_entrypoint {
167 const char *name;
168 _EGLProc function;
169};
170
171
Eric Engestromc74628f2020-08-03 22:50:42 +0200172static inline bool
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800173_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
174{
175 if (!disp) {
176 _eglError(EGL_BAD_DISPLAY, msg);
Eric Engestromc74628f2020-08-03 22:50:42 +0200177 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800178 }
179 if (!disp->Initialized) {
180 _eglError(EGL_NOT_INITIALIZED, msg);
Eric Engestromc74628f2020-08-03 22:50:42 +0200181 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800182 }
Eric Engestromc74628f2020-08-03 22:50:42 +0200183 return true;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800184}
185
186
Eric Engestromc74628f2020-08-03 22:50:42 +0200187static inline bool
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800188_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
189{
Eric Engestromc74628f2020-08-03 22:50:42 +0200190 if (!_eglCheckDisplay(disp, msg))
191 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800192 if (!surf) {
193 _eglError(EGL_BAD_SURFACE, msg);
Eric Engestromc74628f2020-08-03 22:50:42 +0200194 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800195 }
Eric Engestromc74628f2020-08-03 22:50:42 +0200196 return true;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800197}
198
199
Eric Engestromc74628f2020-08-03 22:50:42 +0200200static inline bool
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800201_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
202{
Eric Engestromc74628f2020-08-03 22:50:42 +0200203 if (!_eglCheckDisplay(disp, msg))
204 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800205 if (!context) {
206 _eglError(EGL_BAD_CONTEXT, msg);
Eric Engestromc74628f2020-08-03 22:50:42 +0200207 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800208 }
Eric Engestromc74628f2020-08-03 22:50:42 +0200209 return true;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800210}
211
212
Eric Engestromc74628f2020-08-03 22:50:42 +0200213static inline bool
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800214_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
215{
Eric Engestromc74628f2020-08-03 22:50:42 +0200216 if (!_eglCheckDisplay(disp, msg))
217 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800218 if (!conf) {
219 _eglError(EGL_BAD_CONFIG, msg);
Eric Engestromc74628f2020-08-03 22:50:42 +0200220 return false;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800221 }
Eric Engestromc74628f2020-08-03 22:50:42 +0200222 return true;
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800223}
224
225
Eric Engestromc74628f2020-08-03 22:50:42 +0200226static inline bool
Chia-I Wu4eebea72010-08-14 23:09:12 +0800227_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
228{
Eric Engestromc74628f2020-08-03 22:50:42 +0200229 if (!_eglCheckDisplay(disp, msg))
230 return false;
Chia-I Wu4eebea72010-08-14 23:09:12 +0800231 if (!s) {
232 _eglError(EGL_BAD_PARAMETER, msg);
Eric Engestromc74628f2020-08-03 22:50:42 +0200233 return false;
Chia-I Wu4eebea72010-08-14 23:09:12 +0800234 }
Eric Engestromc74628f2020-08-03 22:50:42 +0200235 return true;
Chia-I Wu4eebea72010-08-14 23:09:12 +0800236}
237
238
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800239/**
Chia-I Wu655f4652010-02-17 17:30:44 +0800240 * Lookup and lock a display.
241 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000242static inline _EGLDisplay *
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000243_eglLockDisplay(EGLDisplay dpy)
Chia-I Wu655f4652010-02-17 17:30:44 +0800244{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000245 _EGLDisplay *disp = _eglLookupDisplay(dpy);
246 if (disp)
247 mtx_lock(&disp->Mutex);
248 return disp;
Chia-I Wu655f4652010-02-17 17:30:44 +0800249}
250
251
252/**
253 * Unlock a display.
254 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000255static inline void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000256_eglUnlockDisplay(_EGLDisplay *disp)
Chia-I Wu655f4652010-02-17 17:30:44 +0800257{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000258 mtx_unlock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +0800259}
260
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400261static EGLBoolean
262_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
263{
264 _EGLThreadInfo *thr = _eglGetCurrentThread();
265 if (!_eglIsCurrentThreadDummy()) {
266 thr->CurrentFuncName = funcName;
267 thr->CurrentObjectLabel = NULL;
268
269 if (objectType == EGL_OBJECT_THREAD_KHR)
270 thr->CurrentObjectLabel = thr->Label;
271 else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
272 thr->CurrentObjectLabel = disp->Label;
273 else if (object)
274 thr->CurrentObjectLabel = object->Label;
275
276 return EGL_TRUE;
277 }
278
Emil Velikovb94344f2017-09-07 17:03:50 +0100279 _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400280 return EGL_FALSE;
281}
282
283#define _EGL_FUNC_START(disp, objectType, object, ret) \
284 do { \
285 if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
286 if (disp) \
287 _eglUnlockDisplay(disp); \
288 return ret; \
289 } \
290 } while(0)
Chia-I Wu655f4652010-02-17 17:30:44 +0800291
Chad Versace3e0d5752016-09-27 13:27:17 -0700292/**
293 * Convert an attribute list from EGLint[] to EGLAttrib[].
294 *
295 * Return an EGL error code. The output parameter out_attrib_list is modified
296 * only on success.
297 */
Eric Engestrom9e1d35c2016-12-08 00:36:03 +0000298static EGLint
Chad Versace3e0d5752016-09-27 13:27:17 -0700299_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
300{
301 size_t len = 0;
302 EGLAttrib *attrib_list;
303
304 if (int_list) {
305 while (int_list[2*len] != EGL_NONE)
306 ++len;
307 }
308
309 if (len == 0) {
310 *out_attrib_list = NULL;
311 return EGL_SUCCESS;
312 }
313
314 if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
315 return EGL_BAD_ALLOC;
316
317 attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
318 if (!attrib_list)
319 return EGL_BAD_ALLOC;
320
321 for (size_t i = 0; i < len; ++i) {
322 attrib_list[2*i + 0] = int_list[2*i + 0];
323 attrib_list[2*i + 1] = int_list[2*i + 1];
324 }
325
326 attrib_list[2*len] = EGL_NONE;
327
328 *out_attrib_list = attrib_list;
329 return EGL_SUCCESS;
330}
331
332
Marek Olšák515f04e2015-05-12 20:42:05 +0200333static EGLint *
334_eglConvertAttribsToInt(const EGLAttrib *attr_list)
335{
Emil Velikov72b9aa92019-05-16 18:01:33 +0100336 size_t size = _eglNumAttribs(attr_list);
Marek Olšák515f04e2015-05-12 20:42:05 +0200337 EGLint *int_attribs = NULL;
338
339 /* Convert attributes from EGLAttrib[] to EGLint[] */
Emil Velikov72b9aa92019-05-16 18:01:33 +0100340 if (size) {
Marek Olšák515f04e2015-05-12 20:42:05 +0200341 int_attribs = calloc(size, sizeof(int_attribs[0]));
342 if (!int_attribs)
343 return NULL;
344
Emil Velikov72b9aa92019-05-16 18:01:33 +0100345 for (size_t i = 0; i < size; i++)
Marek Olšák515f04e2015-05-12 20:42:05 +0200346 int_attribs[i] = attr_list[i];
347 }
348 return int_attribs;
349}
350
351
Chia-I Wu655f4652010-02-17 17:30:44 +0800352/**
Brian Paul6052af12008-05-27 16:48:23 -0600353 * This is typically the first EGL function that an application calls.
Chia-I Wudb5ce8b2010-02-17 18:39:27 +0800354 * It associates a private _EGLDisplay object to the native display.
Brian Pauladbff7e2005-04-22 21:09:39 +0000355 */
Brian Paul1ed10272008-05-27 13:45:41 -0600356EGLDisplay EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +0800357eglGetDisplay(EGLNativeDisplayType nativeDisplay)
Brian Pauladbff7e2005-04-22 21:09:39 +0000358{
Chad Versace6d1f83e2014-01-07 14:54:51 -0800359 _EGLPlatformType plat;
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000360 _EGLDisplay *disp;
Chad Versace6d1f83e2014-01-07 14:54:51 -0800361 void *native_display_ptr;
362
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400363 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
364
Chad Versace6d1f83e2014-01-07 14:54:51 -0800365 STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
366 native_display_ptr = (void*) nativeDisplay;
367
368 plat = _eglGetNativePlatform(native_display_ptr);
Adam Jackson8e991ce2019-05-16 18:01:34 +0100369 disp = _eglFindDisplay(plat, native_display_ptr, NULL);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000370 return _eglGetDisplayHandle(disp);
Brian Pauladbff7e2005-04-22 21:09:39 +0000371}
372
Kyle Brenneman017946b2016-09-12 16:42:56 -0400373static EGLDisplay
374_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500375 const EGLAttrib *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -0800376{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000377 _EGLDisplay *disp;
Chad Versace468cc862014-01-23 07:26:10 -0800378
379 switch (platform) {
380#ifdef HAVE_X11_PLATFORM
381 case EGL_PLATFORM_X11_EXT:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000382 disp = _eglGetX11Display((Display*) native_display, attrib_list);
Chad Versace468cc862014-01-23 07:26:10 -0800383 break;
384#endif
385#ifdef HAVE_DRM_PLATFORM
386 case EGL_PLATFORM_GBM_MESA:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000387 disp = _eglGetGbmDisplay((struct gbm_device*) native_display,
Chad Versace468cc862014-01-23 07:26:10 -0800388 attrib_list);
389 break;
390#endif
391#ifdef HAVE_WAYLAND_PLATFORM
392 case EGL_PLATFORM_WAYLAND_EXT:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000393 disp = _eglGetWaylandDisplay((struct wl_display*) native_display,
Chad Versace468cc862014-01-23 07:26:10 -0800394 attrib_list);
395 break;
396#endif
Chad Versacea597c8a2016-10-12 15:48:15 -0700397 case EGL_PLATFORM_SURFACELESS_MESA:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000398 disp = _eglGetSurfacelessDisplay(native_display, attrib_list);
Chad Versacea597c8a2016-10-12 15:48:15 -0700399 break;
renchenglei500b45a2019-06-28 15:21:08 +0800400#ifdef HAVE_ANDROID_PLATFORM
401 case EGL_PLATFORM_ANDROID_KHR:
402 disp = _eglGetAndroidDisplay(native_display, attrib_list);
403 break;
404#endif
Emil Velikovd6edcce2019-05-16 18:01:40 +0100405 case EGL_PLATFORM_DEVICE_EXT:
406 disp = _eglGetDeviceDisplay(native_display, attrib_list);
407 break;
Chad Versace468cc862014-01-23 07:26:10 -0800408 default:
409 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
410 }
411
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000412 return _eglGetDisplayHandle(disp);
Chad Versace468cc862014-01-23 07:26:10 -0800413}
Brian Pauladbff7e2005-04-22 21:09:39 +0000414
Kyle Brenneman017946b2016-09-12 16:42:56 -0400415static EGLDisplay EGLAPIENTRY
416eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500417 const EGLint *int_attribs)
Kyle Brenneman017946b2016-09-12 16:42:56 -0400418{
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500419 EGLAttrib *attrib_list;
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000420 EGLDisplay disp;
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500421
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400422 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500423
424 if (_eglConvertIntsToAttribs(int_attribs, &attrib_list) != EGL_SUCCESS)
425 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
426
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000427 disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500428 free(attrib_list);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000429 return disp;
Kyle Brenneman017946b2016-09-12 16:42:56 -0400430}
431
Marek Olšák820a4d42015-05-12 21:06:41 +0200432EGLDisplay EGLAPIENTRY
433eglGetPlatformDisplay(EGLenum platform, void *native_display,
434 const EGLAttrib *attrib_list)
435{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400436 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500437 return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +0200438}
439
Brian Paul6052af12008-05-27 16:48:23 -0600440/**
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700441 * Copy the extension into the string and update the string pointer.
442 */
443static EGLint
444_eglAppendExtension(char **str, const char *ext)
445{
446 char *s = *str;
447 size_t len = strlen(ext);
448
449 if (s) {
450 memcpy(s, ext, len);
451 s[len++] = ' ';
452 s[len] = '\0';
453
454 *str += len;
455 }
456 else {
457 len++;
458 }
459
460 return (EGLint) len;
461}
462
463/**
464 * Examine the individual extension enable/disable flags and recompute
465 * the driver's Extensions string.
466 */
467static void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000468_eglCreateExtensionsString(_EGLDisplay *disp)
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700469{
470#define _EGL_CHECK_EXTENSION(ext) \
471 do { \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000472 if (disp->Extensions.ext) { \
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700473 _eglAppendExtension(&exts, "EGL_" #ext); \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000474 assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700475 } \
476 } while (0)
477
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000478 char *exts = disp->ExtensionsString;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700479
Marek Olšák32aa1d72015-06-09 23:08:57 +0200480 /* Please keep these sorted alphabetically. */
Tapani Pälli6f5b5702017-12-28 10:51:11 +0200481 _EGL_CHECK_EXTENSION(ANDROID_blob_cache);
Rob Herring89755272016-02-02 14:23:07 -0600482 _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700483 _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
Rob Clark0201f012016-11-18 08:39:33 -0500484 _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
Rob Herringe21e81a2016-02-02 14:23:08 -0600485 _EGL_CHECK_EXTENSION(ANDROID_recordable);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700486
487 _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
488
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700489 _EGL_CHECK_EXTENSION(EXT_buffer_age);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200490 _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700491 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
Varad Gautam4c412292017-05-30 17:23:40 +0530492 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
Tapani Pälli799b3d12018-04-05 13:02:36 +0300493 _EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
494 _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200495 _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
496
Chris Wilson95ecf3d2016-10-27 19:34:46 +0100497 _EGL_CHECK_EXTENSION(IMG_context_priority);
498
Marek Olšák32aa1d72015-06-09 23:08:57 +0200499 _EGL_CHECK_EXTENSION(KHR_cl_event2);
Emil Velikov26541a12016-12-05 14:42:04 +0000500 _EGL_CHECK_EXTENSION(KHR_config_attribs);
Adam Jacksonc0be3aa2016-09-22 03:47:55 -0400501 _EGL_CHECK_EXTENSION(KHR_context_flush_control);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200502 _EGL_CHECK_EXTENSION(KHR_create_context);
Grigori Goronzy49095192017-06-29 02:44:03 +0200503 _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200504 _EGL_CHECK_EXTENSION(KHR_fence_sync);
505 _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
506 _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
507 _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
508 _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
509 _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
510 _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000511 if (disp->Extensions.KHR_image_base && disp->Extensions.KHR_image_pixmap)
512 disp->Extensions.KHR_image = EGL_TRUE;
Harish Krupo96fc5fb2017-12-08 21:29:39 +0530513 _EGL_CHECK_EXTENSION(KHR_image);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200514 _EGL_CHECK_EXTENSION(KHR_image_base);
515 _EGL_CHECK_EXTENSION(KHR_image_pixmap);
Chad Versace3dc22382018-04-30 22:32:25 -0700516 _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
Adam Jacksond9f5b192016-09-09 12:25:34 -0400517 _EGL_CHECK_EXTENSION(KHR_no_config_context);
Harish Krupo98275472017-06-09 20:13:34 +0530518 _EGL_CHECK_EXTENSION(KHR_partial_update);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200519 _EGL_CHECK_EXTENSION(KHR_reusable_sync);
520 _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000521 if (disp->Extensions.EXT_swap_buffers_with_damage)
Eric Engestrom0a606a42016-10-10 17:33:17 +0100522 _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
Tapani Pälli41f7de42017-10-31 10:57:42 +0200523 _EGL_CHECK_EXTENSION(EXT_pixel_format_float);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200524 _EGL_CHECK_EXTENSION(KHR_wait_sync);
525
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000526 if (disp->Extensions.KHR_no_config_context)
Adam Jacksond9f5b192016-09-09 12:25:34 -0400527 _eglAppendExtension(&exts, "EGL_MESA_configless_context");
Marek Olšák32aa1d72015-06-09 23:08:57 +0200528 _EGL_CHECK_EXTENSION(MESA_drm_image);
529 _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
Veluri Mithun6afce782019-01-23 22:44:25 +0530530 _EGL_CHECK_EXTENSION(MESA_query_driver);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200531
532 _EGL_CHECK_EXTENSION(NOK_swap_region);
533 _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700534
535 _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
Dave Airlie8f7338f2014-03-03 13:57:16 +1000536
Marek Olšák32aa1d72015-06-09 23:08:57 +0200537 _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
538 _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
539
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700540#undef _EGL_CHECK_EXTENSION
541}
542
543static void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000544_eglCreateAPIsString(_EGLDisplay *disp)
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700545{
Eric Engestromaa78b292018-08-16 15:31:55 +0100546#define addstr(str) \
547 { \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000548 const size_t old_len = strlen(disp->ClientAPIsString); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100549 const size_t add_len = sizeof(str); \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000550 const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \
Eric Engestromaa78b292018-08-16 15:31:55 +0100551 if (old_len + add_len <= max_len) \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000552 strcat(disp->ClientAPIsString, str " "); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100553 else \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000554 assert(!"disp->ClientAPIsString is not large enough"); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100555 }
556
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000557 if (disp->ClientAPIs & EGL_OPENGL_BIT)
Eric Engestromaa78b292018-08-16 15:31:55 +0100558 addstr("OpenGL");
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700559
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000560 if (disp->ClientAPIs & EGL_OPENGL_ES_BIT ||
561 disp->ClientAPIs & EGL_OPENGL_ES2_BIT ||
562 disp->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
Eric Engestromaa78b292018-08-16 15:31:55 +0100563 addstr("OpenGL_ES");
Plamena Manolova21edd242016-05-12 18:21:38 +0100564 }
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700565
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000566 if (disp->ClientAPIs & EGL_OPENVG_BIT)
Eric Engestromaa78b292018-08-16 15:31:55 +0100567 addstr("OpenVG");
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700568
Eric Engestromaa78b292018-08-16 15:31:55 +0100569#undef addstr
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700570}
571
Marek Olšákefda9c52015-05-11 22:16:52 +0200572static void
573_eglComputeVersion(_EGLDisplay *disp)
574{
Marek Olšák0e4b5642015-05-12 16:40:29 +0200575 disp->Version = 14;
Marek Olšáka1cb4072015-05-11 22:18:04 +0200576
577 if (disp->Extensions.KHR_fence_sync &&
578 disp->Extensions.KHR_cl_event2 &&
579 disp->Extensions.KHR_wait_sync &&
580 disp->Extensions.KHR_image_base &&
581 disp->Extensions.KHR_gl_texture_2D_image &&
582 disp->Extensions.KHR_gl_texture_3D_image &&
583 disp->Extensions.KHR_gl_texture_cubemap_image &&
584 disp->Extensions.KHR_gl_renderbuffer_image &&
585 disp->Extensions.KHR_create_context &&
586 disp->Extensions.EXT_create_context_robustness &&
587 disp->Extensions.KHR_get_all_proc_addresses &&
588 disp->Extensions.KHR_gl_colorspace &&
589 disp->Extensions.KHR_surfaceless_context)
590 disp->Version = 15;
Abhishek Kumar0bea2a12020-05-07 22:02:02 +0530591
592 /* For Android P and below limit the EGL version to 1.4 */
593#if defined(ANDROID) && ANDROID_API_LEVEL <= 28
594 disp->Version = 14;
595#endif
Marek Olšákefda9c52015-05-11 22:16:52 +0200596}
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700597
598/**
Brian Paul6052af12008-05-27 16:48:23 -0600599 * This is typically the second EGL function that an application calls.
600 * Here we load/initialize the actual hardware driver.
601 */
Brian Paul1ed10272008-05-27 13:45:41 -0600602EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000603eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
604{
Chia-I Wu655f4652010-02-17 17:30:44 +0800605 _EGLDisplay *disp = _eglLockDisplay(dpy);
Jonathan White7e2458c2008-08-06 13:40:03 -0600606
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400607 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
608
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800609 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800610 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Brian Paulc56e15b2008-05-28 15:43:41 -0600611
Chia-I Wua9332592010-01-27 23:55:58 +0800612 if (!disp->Initialized) {
Eric Engestromed3f1e02020-07-22 01:19:03 +0200613 if (!_eglInitializeDisplay(disp))
Chia-I Wuf2aa3612010-07-04 15:55:12 +0800614 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
Chia-I Wu57929ed2010-01-19 18:29:21 +0800615
Chia-I Wu310c7682009-08-17 15:53:54 +0800616 /* limit to APIs supported by core */
Chia-I Wua4a38dc2011-01-13 16:53:13 +0800617 disp->ClientAPIs &= _EGL_API_ALL_BITS;
Chad Versace7e8ba772014-11-20 10:26:38 -0800618
619 /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
620 * classifies it as an EGL display extension, though conceptually it's an
621 * EGL client extension.
622 *
623 * From the EGL_KHR_get_all_proc_addresses spec:
624 *
625 * The EGL implementation must expose the name
626 * EGL_KHR_client_get_all_proc_addresses if and only if it exposes
627 * EGL_KHR_get_all_proc_addresses and supports
628 * EGL_EXT_client_extensions.
629 *
630 * Mesa unconditionally exposes both client extensions mentioned above,
631 * so the spec requires that each EGLDisplay unconditionally expose
632 * EGL_KHR_get_all_proc_addresses also.
633 */
634 disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700635
Emil Velikov26541a12016-12-05 14:42:04 +0000636 /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
637 * programs. It is driver agnostic and handled in the main EGL code.
638 */
639 disp->Extensions.KHR_config_attribs = EGL_TRUE;
640
Marek Olšákefda9c52015-05-11 22:16:52 +0200641 _eglComputeVersion(disp);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700642 _eglCreateExtensionsString(disp);
643 _eglCreateAPIsString(disp);
Emil Velikov3593f372015-07-14 00:19:54 +0100644 snprintf(disp->VersionString, sizeof(disp->VersionString),
Eric Engestroma96749b2017-10-18 16:32:33 +0100645 "%d.%d", disp->Version / 10, disp->Version % 10);
Brian Pauladbff7e2005-04-22 21:09:39 +0000646 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800647
648 /* Update applications version of major and minor if not NULL */
649 if ((major != NULL) && (minor != NULL)) {
Marek Olšák0e4b5642015-05-12 16:40:29 +0200650 *major = disp->Version / 10;
651 *minor = disp->Version % 10;
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 -0600658EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000659eglTerminate(EGLDisplay dpy)
660{
Chia-I Wu655f4652010-02-17 17:30:44 +0800661 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800662
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400663 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
664
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800665 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800666 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800667
Chia-I Wua9332592010-01-27 23:55:58 +0800668 if (disp->Initialized) {
Eric Engestrom435ad512018-04-22 16:48:15 +0200669 disp->Driver->Terminate(disp);
Chia-I Wua9332592010-01-27 23:55:58 +0800670 /* do not reset disp->Driver */
Dave Airlie37e3a112015-03-16 15:21:55 +1000671 disp->ClientAPIsString[0] = 0;
Chia-I Wua9332592010-01-27 23:55:58 +0800672 disp->Initialized = EGL_FALSE;
Tapani Pälli3e03a3f2019-08-22 10:49:36 +0300673
674 /* Reset blob cache funcs on terminate. */
675 disp->BlobCacheSet = NULL;
676 disp->BlobCacheGet = NULL;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800677 }
678
Chia-I Wubef4b472010-02-19 12:08:50 +0800679 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000680}
681
682
Brian Paul1ed10272008-05-27 13:45:41 -0600683const char * EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000684eglQueryString(EGLDisplay dpy, EGLint name)
685{
Chad Versace3c58d4c2013-10-11 16:04:55 -0700686 _EGLDisplay *disp;
Chia-I Wuaed73582010-02-17 15:43:47 +0800687
Emil Velikov0a884d72020-04-08 11:46:47 +0100688#if !USE_LIBGLVND
Chad Versace3c58d4c2013-10-11 16:04:55 -0700689 if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
Emil Velikov0a884d72020-04-08 11:46:47 +0100690 RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
Chad Versace3c58d4c2013-10-11 16:04:55 -0700691 }
Emil Velikov0a884d72020-04-08 11:46:47 +0100692#endif
Chad Versace3c58d4c2013-10-11 16:04:55 -0700693
694 disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400695 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
Eric Engestromc74628f2020-08-03 22:50:42 +0200696 _EGL_CHECK_DISPLAY(disp, NULL);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800697
Matt Turner6c6e2a12015-03-13 17:00:26 -0700698 switch (name) {
699 case EGL_VENDOR:
700 RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
701 case EGL_VERSION:
702 RETURN_EGL_SUCCESS(disp, disp->VersionString);
703 case EGL_EXTENSIONS:
704 RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
705 case EGL_CLIENT_APIS:
706 RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
707 default:
708 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
709 }
Brian Pauladbff7e2005-04-22 21:09:39 +0000710}
711
712
Brian Paul1ed10272008-05-27 13:45:41 -0600713EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800714eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
715 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000716{
Chia-I Wu655f4652010-02-17 17:30:44 +0800717 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800718 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800719
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400720 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
721
Eric Engestromc74628f2020-08-03 22:50:42 +0200722 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Eric Engestrom64c7c052019-01-08 11:14:35 +0000723
724 if (!num_config)
725 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
726
Eric Engestrom0345a612018-05-21 19:48:13 +0100727 ret = _eglGetConfigs(disp, configs, config_size, num_config);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800728
Chia-I Wubef4b472010-02-19 12:08:50 +0800729 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000730}
731
732
Brian Paul1ed10272008-05-27 13:45:41 -0600733EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800734eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
735 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000736{
Chia-I Wu655f4652010-02-17 17:30:44 +0800737 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800738 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800739
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400740 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
741
Eric Engestromc74628f2020-08-03 22:50:42 +0200742 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Eric Engestrom64c7c052019-01-08 11:14:35 +0000743
744 if (!num_config)
745 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
746
Eric Engestrom0345a612018-05-21 19:48:13 +0100747 ret = _eglChooseConfig(disp, attrib_list, configs,
Eric Engestromeeacd662019-06-14 16:08:44 +0100748 config_size, num_config);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800749
Chia-I Wubef4b472010-02-19 12:08:50 +0800750 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000751}
752
753
Brian Paul1ed10272008-05-27 13:45:41 -0600754EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800755eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
756 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000757{
Chia-I Wu655f4652010-02-17 17:30:44 +0800758 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800759 _EGLConfig *conf = _eglLookupConfig(config, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800760 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800761
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400762 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
763
Eric Engestromc74628f2020-08-03 22:50:42 +0200764 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE);
Eric Engestrom7f848f92019-06-22 22:31:00 +0100765
Eric Engestrom0345a612018-05-21 19:48:13 +0100766 ret = _eglGetConfigAttrib(disp, conf, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800767
Chia-I Wubef4b472010-02-19 12:08:50 +0800768 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000769}
770
771
Brian Paul1ed10272008-05-27 13:45:41 -0600772EGLContext EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800773eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
774 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000775{
Chia-I Wu655f4652010-02-17 17:30:44 +0800776 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800777 _EGLConfig *conf = _eglLookupConfig(config, disp);
778 _EGLContext *share = _eglLookupContext(share_list, disp);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800779 _EGLContext *context;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800780 EGLContext ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800781
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400782 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
783
Eric Engestromc74628f2020-08-03 22:50:42 +0200784 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT);
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800785
Tapani Pälli5876f3c2016-10-20 14:11:16 +0300786 if (config != EGL_NO_CONFIG_KHR)
Eric Engestromc74628f2020-08-03 22:50:42 +0200787 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT);
Tapani Pälli5876f3c2016-10-20 14:11:16 +0300788 else if (!disp->Extensions.KHR_no_config_context)
Neil Roberts4b17dff2014-03-07 18:05:46 +0000789 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
Kristian Høgsbergb90a3e72010-06-02 22:48:06 -0400790
Chia-I Wub3bb1802010-02-17 16:05:27 +0800791 if (!share && share_list != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800792 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800793
Eric Engestrom5eb58472020-08-03 22:19:42 +0200794 context = disp->Driver->CreateContext(disp, conf, share, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +0800795 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800796
Chia-I Wubef4b472010-02-19 12:08:50 +0800797 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000798}
799
800
Brian Paul1ed10272008-05-27 13:45:41 -0600801EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000802eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
803{
Chia-I Wu655f4652010-02-17 17:30:44 +0800804 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800805 _EGLContext *context = _eglLookupContext(ctx, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800806 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800807
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400808 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
809
Eric Engestromc74628f2020-08-03 22:50:42 +0200810 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800811 _eglUnlinkContext(context);
Eric Engestrom5eb58472020-08-03 22:19:42 +0200812 ret = disp->Driver->DestroyContext(disp, context);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800813
Chia-I Wubef4b472010-02-19 12:08:50 +0800814 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000815}
816
817
Brian Paul1ed10272008-05-27 13:45:41 -0600818EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800819eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
820 EGLContext ctx)
Brian Pauladbff7e2005-04-22 21:09:39 +0000821{
Chia-I Wu655f4652010-02-17 17:30:44 +0800822 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800823 _EGLContext *context = _eglLookupContext(ctx, disp);
824 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
825 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800826 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800827
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400828 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
829
Chia-I Wu17330472010-01-27 23:51:54 +0800830 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800831 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800832
833 /* display is allowed to be uninitialized under certain condition */
834 if (!disp->Initialized) {
835 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
836 ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800837 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800838 }
Eric Engestrom5eb58472020-08-03 22:19:42 +0200839 if (!disp->Driver)
Chia-I Wubef4b472010-02-19 12:08:50 +0800840 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Chia-I Wu17330472010-01-27 23:51:54 +0800841
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800842 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800843 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800844 if (!draw_surf || !read_surf) {
Beren Minor0ca0d572014-03-20 08:36:34 +0100845 /* From the EGL 1.4 (20130211) spec:
846 *
847 * To release the current context without assigning a new one, set ctx
848 * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
849 */
850 if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800851 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
852
853 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
854 (!read_surf && read != EGL_NO_SURFACE))
855 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
856 if (draw_surf || read_surf)
857 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
858 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800859
Chad Versace23c86c72017-05-04 17:46:33 -0700860 /* If a native window underlying either draw or read is no longer valid,
861 * an EGL_BAD_NATIVE_WINDOW error is generated.
862 */
863 if (draw_surf && draw_surf->Lost)
864 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
865 if (read_surf && read_surf->Lost)
866 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
867
Eric Engestrom5eb58472020-08-03 22:19:42 +0200868 ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800869
Chia-I Wubef4b472010-02-19 12:08:50 +0800870 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000871}
872
873
Brian Paul1ed10272008-05-27 13:45:41 -0600874EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800875eglQueryContext(EGLDisplay dpy, EGLContext ctx,
876 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000877{
Chia-I Wu655f4652010-02-17 17:30:44 +0800878 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800879 _EGLContext *context = _eglLookupContext(ctx, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800880 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800881
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400882 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
883
Eric Engestromc74628f2020-08-03 22:50:42 +0200884 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
Eric Engestromb792b3e2019-06-22 22:31:26 +0100885
Eric Engestromb981bab2020-08-03 17:03:44 +0200886 ret = _eglQueryContext(context, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800887
Chia-I Wubef4b472010-02-19 12:08:50 +0800888 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000889}
890
891
Paulo Zanoni73055ae2019-05-01 16:26:47 -0700892/* In EGL specs 1.4 and 1.5, at the end of sections 3.5.1 and 3.5.4, it says
893 * that if native_surface was already used to create a window or pixmap, we
894 * can't create a new one. This is what this function checks for.
895 */
896static bool
897_eglNativeSurfaceAlreadyUsed(_EGLDisplay *disp, void *native_surface)
898{
899 _EGLResource *list;
900
901 list = disp->ResourceLists[_EGL_RESOURCE_SURFACE];
902 while (list) {
903 _EGLSurface *surf = (_EGLSurface *) list;
904
905 list = list->Next;
906
907 if (surf->Type == EGL_PBUFFER_BIT)
908 continue;
909
910 if (surf->NativeSurface == native_surface)
911 return true;
912 }
913
914 return false;
915}
916
917
Chad Versace468cc862014-01-23 07:26:10 -0800918static EGLSurface
919_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
920 void *native_window, const EGLint *attrib_list)
921{
922 _EGLConfig *conf = _eglLookupConfig(config, disp);
Chad Versace468cc862014-01-23 07:26:10 -0800923 _EGLSurface *surf;
924 EGLSurface ret;
925
Sinclair Yeh91ff0d42014-06-03 14:00:13 -0700926
927 if (native_window == NULL)
928 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
929
Emil Velikovd6edcce2019-05-16 18:01:40 +0100930 if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
931 disp->Platform == _EGL_PLATFORM_DEVICE)) {
Chad Versacea597c8a2016-10-12 15:48:15 -0700932 /* From the EGL_MESA_platform_surfaceless spec (v1):
933 *
934 * eglCreatePlatformWindowSurface fails when called with a <display>
935 * that belongs to the surfaceless platform. It returns
936 * EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
937 * justification for this unconditional failure is that the
938 * surfaceless platform has no native windows, and therefore the
939 * <native_window> parameter is always invalid.
940 *
941 * This check must occur before checking the EGLConfig, which emits
942 * EGL_BAD_CONFIG.
943 */
944 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
945 }
Chad Versacea597c8a2016-10-12 15:48:15 -0700946
Eric Engestromc74628f2020-08-03 22:50:42 +0200947 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
Chad Versacea597c8a2016-10-12 15:48:15 -0700948
Chad Versacefbb4af92016-12-16 11:00:13 -0800949 if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
950 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
951
Paulo Zanoni73055ae2019-05-01 16:26:47 -0700952 if (_eglNativeSurfaceAlreadyUsed(disp, native_window))
953 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
954
Eric Engestrom5eb58472020-08-03 22:19:42 +0200955 surf = disp->Driver->CreateWindowSurface(disp, conf, native_window, attrib_list);
Chad Versace468cc862014-01-23 07:26:10 -0800956 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
957
958 RETURN_EGL_EVAL(disp, ret);
959}
960
961
Brian Paul1ed10272008-05-27 13:45:41 -0600962EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800963eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +0800964 EGLNativeWindowType window, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000965{
Chia-I Wu655f4652010-02-17 17:30:44 +0800966 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400967
968 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -0800969 STATIC_ASSERT(sizeof(void*) == sizeof(window));
970 return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
971 attrib_list);
972}
973
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400974static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000975_fixupNativeWindow(_EGLDisplay *disp, void *native_window)
Chad Versace468cc862014-01-23 07:26:10 -0800976{
Chad Versace468cc862014-01-23 07:26:10 -0800977#ifdef HAVE_X11_PLATFORM
Emil Velikov26fbb9e2017-08-08 15:55:36 +0100978 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
Chad Versace468cc862014-01-23 07:26:10 -0800979 /* The `native_window` parameter for the X11 platform differs between
980 * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
981 * eglCreateWindowSurface(), the type of `native_window` is an Xlib
982 * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
983 * `Window*`. Convert `Window*` to `Window` because that's what
984 * dri2_x11_create_window_surface() expects.
985 */
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400986 return (void *)(* (Window*) native_window);
Chad Versace468cc862014-01-23 07:26:10 -0800987 }
988#endif
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400989 return native_window;
990}
991
992static EGLSurface EGLAPIENTRY
993eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
994 void *native_window,
995 const EGLint *attrib_list)
996{
997 _EGLDisplay *disp = _eglLockDisplay(dpy);
998
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000999 native_window = _fixupNativeWindow(disp, native_window);
Chad Versace468cc862014-01-23 07:26:10 -08001000
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001001 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -08001002 return _eglCreateWindowSurfaceCommon(disp, config, native_window,
1003 attrib_list);
1004}
1005
1006
Marek Olšák820a4d42015-05-12 21:06:41 +02001007EGLSurface EGLAPIENTRY
1008eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
1009 void *native_window,
1010 const EGLAttrib *attrib_list)
1011{
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -04001012 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +02001013 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001014 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +02001015
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001016 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1017
1018 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +02001019 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001020 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +02001021
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001022 native_window = _fixupNativeWindow(disp, native_window);
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -04001023 surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
1024 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +02001025 free(int_attribs);
1026 return surface;
1027}
1028
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001029static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001030_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001031{
1032#ifdef HAVE_X11_PLATFORM
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001033 /* The `native_pixmap` parameter for the X11 platform differs between
1034 * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
1035 * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
1036 * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
1037 * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
1038 * dri2_x11_create_pixmap_surface() expects.
1039 */
Emil Velikov26fbb9e2017-08-08 15:55:36 +01001040 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001041 return (void *)(* (Pixmap*) native_pixmap);
1042#endif
1043 return native_pixmap;
1044}
Marek Olšák820a4d42015-05-12 21:06:41 +02001045
Chad Versace468cc862014-01-23 07:26:10 -08001046static EGLSurface
1047_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
1048 void *native_pixmap, const EGLint *attrib_list)
1049{
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001050 _EGLConfig *conf = _eglLookupConfig(config, disp);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001051 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001052 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001053
Emil Velikovd6edcce2019-05-16 18:01:40 +01001054 if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
1055 disp->Platform == _EGL_PLATFORM_DEVICE)) {
Chad Versacea597c8a2016-10-12 15:48:15 -07001056 /* From the EGL_MESA_platform_surfaceless spec (v1):
1057 *
1058 * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
1059 * also fails when called with a <display> that belongs to the
1060 * surfaceless platform. It returns EGL_NO_SURFACE and generates
1061 * EGL_BAD_NATIVE_PIXMAP.
1062 *
1063 * This check must occur before checking the EGLConfig, which emits
1064 * EGL_BAD_CONFIG.
1065 */
1066 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1067 }
Chad Versacea597c8a2016-10-12 15:48:15 -07001068
Eric Engestromc74628f2020-08-03 22:50:42 +02001069 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
Chad Versacefbb4af92016-12-16 11:00:13 -08001070
1071 if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
1072 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1073
Emil Velikovdf8efd52017-08-05 00:25:48 +01001074 if (native_pixmap == NULL)
1075 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1076
Paulo Zanoni73055ae2019-05-01 16:26:47 -07001077 if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap))
1078 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
1079
Eric Engestrom5eb58472020-08-03 22:19:42 +02001080 surf = disp->Driver->CreatePixmapSurface(disp, conf, native_pixmap, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001081 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001082
Chia-I Wubef4b472010-02-19 12:08:50 +08001083 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001084}
1085
1086
Brian Paul1ed10272008-05-27 13:45:41 -06001087EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001088eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +08001089 EGLNativePixmapType pixmap, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001090{
Chia-I Wu655f4652010-02-17 17:30:44 +08001091 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001092
1093 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001094 STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
Chad Versace468cc862014-01-23 07:26:10 -08001095 return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001096 attrib_list);
Chad Versace468cc862014-01-23 07:26:10 -08001097}
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001098
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001099static EGLSurface EGLAPIENTRY
Chad Versace468cc862014-01-23 07:26:10 -08001100eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001101 void *native_pixmap,
1102 const EGLint *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -08001103{
1104 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001105
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001106 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001107 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Chad Versace468cc862014-01-23 07:26:10 -08001108 return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1109 attrib_list);
Brian Pauladbff7e2005-04-22 21:09:39 +00001110}
1111
1112
Brian Paul1ed10272008-05-27 13:45:41 -06001113EGLSurface EGLAPIENTRY
Marek Olšák820a4d42015-05-12 21:06:41 +02001114eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
1115 void *native_pixmap,
1116 const EGLAttrib *attrib_list)
1117{
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001118 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +02001119 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001120 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +02001121
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001122 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1123
1124 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +02001125 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001126 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +02001127
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001128 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001129 surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1130 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +02001131 free(int_attribs);
1132 return surface;
1133}
1134
1135
1136EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001137eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
1138 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001139{
Chia-I Wu655f4652010-02-17 17:30:44 +08001140 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001141 _EGLConfig *conf = _eglLookupConfig(config, disp);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001142 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001143 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001144
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001145 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001146 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001147
Chad Versacefbb4af92016-12-16 11:00:13 -08001148 if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
1149 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1150
Eric Engestrom5eb58472020-08-03 22:19:42 +02001151 surf = disp->Driver->CreatePbufferSurface(disp, conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001152 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001153
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 +00001159eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
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);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001163 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001164
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001165 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001166 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001167 _eglUnlinkSurface(surf);
Eric Engestrom5eb58472020-08-03 22:19:42 +02001168 ret = disp->Driver->DestroySurface(disp, surf);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001169
Chia-I Wubef4b472010-02-19 12:08:50 +08001170 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001171}
1172
Brian Paul1ed10272008-05-27 13:45:41 -06001173EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001174eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
1175 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001176{
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);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001179 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001180
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001181 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001182 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Eric Engestrom58be9d52019-06-22 22:31:53 +01001183
Eric Engestrom5eb58472020-08-03 22:19:42 +02001184 if (disp->Driver->QuerySurface)
1185 ret = disp->Driver->QuerySurface(disp, surf, attribute, value);
Eric Engestrom58be9d52019-06-22 22:31:53 +01001186 else
Eric Engestrom982ac692018-04-22 16:48:15 +02001187 ret = _eglQuerySurface(disp, surf, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001188
Chia-I Wubef4b472010-02-19 12:08:50 +08001189 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001190}
1191
Brian Paul1ed10272008-05-27 13:45:41 -06001192EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001193eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
1194 EGLint attribute, EGLint value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001195{
Chia-I Wu655f4652010-02-17 17:30:44 +08001196 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001197 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001198 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001199
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001200 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001201 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Eric Engestrom9dc00c82019-06-22 22:32:26 +01001202
Eric Engestromb9fb63a2020-08-03 17:08:27 +02001203 ret = _eglSurfaceAttrib(disp, surf, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001204
Chia-I Wubef4b472010-02-19 12:08:50 +08001205 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001206}
1207
1208
Brian Paul1ed10272008-05-27 13:45:41 -06001209EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001210eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1211{
Chia-I Wu655f4652010-02-17 17:30:44 +08001212 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001213 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001214 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001215
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001216 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001217 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Eric Engestrom5eb58472020-08-03 22:19:42 +02001218 ret = disp->Driver->BindTexImage(disp, surf, buffer);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001219
Chia-I Wubef4b472010-02-19 12:08:50 +08001220 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001221}
1222
1223
Brian Paul1ed10272008-05-27 13:45:41 -06001224EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001225eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1226{
Chia-I Wu655f4652010-02-17 17:30:44 +08001227 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001228 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001229 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001230
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001231 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001232 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Eric Engestrom5eb58472020-08-03 22:19:42 +02001233 ret = disp->Driver->ReleaseTexImage(disp, surf, buffer);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001234
Chia-I Wubef4b472010-02-19 12:08:50 +08001235 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001236}
1237
1238
Brian Paul1ed10272008-05-27 13:45:41 -06001239EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001240eglSwapInterval(EGLDisplay dpy, EGLint interval)
1241{
Chia-I Wu655f4652010-02-17 17:30:44 +08001242 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu57da4992009-10-15 11:08:48 +08001243 _EGLContext *ctx = _eglGetCurrentContext();
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001244 _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001245 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001246
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001247 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001248 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001249
Chia-I Wud19afc52010-10-23 12:52:26 +08001250 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1251 ctx->Resource.Display != disp)
Chia-I Wubef4b472010-02-19 12:08:50 +08001252 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001253
Chia-I Wud19afc52010-10-23 12:52:26 +08001254 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001255 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001256
Emil Velikov64b4ccd2018-09-03 13:05:22 +01001257 if (surf->Type != EGL_WINDOW_BIT)
1258 RETURN_EGL_EVAL(disp, EGL_TRUE);
1259
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001260 interval = CLAMP(interval,
1261 surf->Config->MinSwapInterval,
1262 surf->Config->MaxSwapInterval);
1263
Eric Engestrom26d5ca42019-06-22 22:32:50 +01001264 if (surf->SwapInterval != interval) {
Eric Engestrom5eb58472020-08-03 22:19:42 +02001265 if (disp->Driver->SwapInterval)
1266 ret = disp->Driver->SwapInterval(disp, surf, interval);
Eric Engestrom26d5ca42019-06-22 22:32:50 +01001267 else
Eric Engestrom347840c2018-04-22 16:48:15 +02001268 ret = _eglSwapInterval(disp, surf, interval);
Eric Engestrom26d5ca42019-06-22 22:32:50 +01001269 }
1270 else {
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001271 ret = EGL_TRUE;
Eric Engestrom26d5ca42019-06-22 22:32:50 +01001272 }
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001273
1274 if (ret)
1275 surf->SwapInterval = interval;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001276
Chia-I Wubef4b472010-02-19 12:08:50 +08001277 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001278}
1279
1280
Brian Paul1ed10272008-05-27 13:45:41 -06001281EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001282eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
Brian Pauladbff7e2005-04-22 21:09:39 +00001283{
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001284 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu655f4652010-02-17 17:30:44 +08001285 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001286 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001287 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001288
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001289 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02001290 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001291
1292 /* surface must be bound to current context in EGL 1.4 */
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001293 #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
Chia-I Wud19afc52010-10-23 12:52:26 +08001294 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1295 surf != ctx->DrawSurface)
Chia-I Wubef4b472010-02-19 12:08:50 +08001296 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001297 #endif
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001298
Emil Velikov8f667432018-09-03 13:05:23 +01001299 if (surf->Type != EGL_WINDOW_BIT)
1300 RETURN_EGL_EVAL(disp, EGL_TRUE);
1301
Chad Versace23c86c72017-05-04 17:46:33 -07001302 /* From the EGL 1.5 spec:
1303 *
1304 * If eglSwapBuffers is called and the native window associated with
1305 * surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
1306 * generated.
1307 */
1308 if (surf->Lost)
1309 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
1310
Eric Engestrom5eb58472020-08-03 22:19:42 +02001311 ret = disp->Driver->SwapBuffers(disp, surf);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001312
Harish Krupo98275472017-06-09 20:13:34 +05301313 /* EGL_KHR_partial_update
1314 * Frame boundary successfully reached,
1315 * reset damage region and reset BufferAgeRead
1316 */
1317 if (ret) {
1318 surf->SetDamageRegionCalled = EGL_FALSE;
1319 surf->BufferAgeRead = EGL_FALSE;
1320 }
1321
Chia-I Wubef4b472010-02-19 12:08:50 +08001322 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001323}
1324
1325
Eric Engestrom0a606a42016-10-10 17:33:17 +01001326static EGLBoolean
Eric Engestrom9702f912016-11-16 22:29:53 +00001327_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
Simon Ser9a747462020-05-07 21:49:25 +02001328 const EGLint *rects, EGLint n_rects)
Robert Bragg6425b142013-04-25 13:41:42 +01001329{
1330 _EGLContext *ctx = _eglGetCurrentContext();
Robert Bragg6425b142013-04-25 13:41:42 +01001331 EGLBoolean ret;
1332
Eric Engestromc74628f2020-08-03 22:50:42 +02001333 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Robert Bragg6425b142013-04-25 13:41:42 +01001334
1335 /* surface must be bound to current context in EGL 1.4 */
1336 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1337 surf != ctx->DrawSurface)
1338 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1339
Emil Velikov8f667432018-09-03 13:05:23 +01001340 if (surf->Type != EGL_WINDOW_BIT)
1341 RETURN_EGL_EVAL(disp, EGL_TRUE);
1342
Robert Bragg6425b142013-04-25 13:41:42 +01001343 if ((n_rects > 0 && rects == NULL) || n_rects < 0)
1344 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1345
Eric Engestrom5eb58472020-08-03 22:19:42 +02001346 ret = disp->Driver->SwapBuffersWithDamageEXT(disp, surf, rects, n_rects);
Robert Bragg6425b142013-04-25 13:41:42 +01001347
Harish Krupo98275472017-06-09 20:13:34 +05301348 /* EGL_KHR_partial_update
1349 * Frame boundary successfully reached,
1350 * reset damage region and reset BufferAgeRead
1351 */
1352 if (ret) {
1353 surf->SetDamageRegionCalled = EGL_FALSE;
1354 surf->BufferAgeRead = EGL_FALSE;
1355 }
1356
Robert Bragg6425b142013-04-25 13:41:42 +01001357 RETURN_EGL_EVAL(disp, ret);
1358}
1359
Eric Engestrom0a606a42016-10-10 17:33:17 +01001360static EGLBoolean EGLAPIENTRY
1361eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
Simon Ser9a747462020-05-07 21:49:25 +02001362 const EGLint *rects, EGLint n_rects)
Eric Engestrom0a606a42016-10-10 17:33:17 +01001363{
1364 _EGLDisplay *disp = _eglLockDisplay(dpy);
1365 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1366 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001367 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001368}
1369
1370static EGLBoolean EGLAPIENTRY
1371eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
Simon Ser9a747462020-05-07 21:49:25 +02001372 const EGLint *rects, EGLint n_rects)
Eric Engestrom0a606a42016-10-10 17:33:17 +01001373{
1374 _EGLDisplay *disp = _eglLockDisplay(dpy);
1375 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1376 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001377 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001378}
1379
Harish Krupo98275472017-06-09 20:13:34 +05301380/**
Harish Krupofd734602018-07-08 12:53:00 +05301381 * Clamp the rectangles so that they lie within the surface.
Harish Krupo98275472017-06-09 20:13:34 +05301382 */
1383
1384static void
Eric Engestrom3ef8aac2018-05-21 10:42:10 +01001385_eglSetDamageRegionKHRClampRects(_EGLSurface* surf,
Harish Krupo98275472017-06-09 20:13:34 +05301386 EGLint *rects, EGLint n_rects)
1387{
1388 EGLint i;
1389 EGLint surf_height = surf->Height;
1390 EGLint surf_width = surf->Width;
1391
1392 for (i = 0; i < (4 * n_rects); i += 4) {
Harish Krupofd734602018-07-08 12:53:00 +05301393 EGLint x1, y1, x2, y2;
1394 x1 = rects[i];
1395 y1 = rects[i + 1];
1396 x2 = rects[i + 2] + x1;
1397 y2 = rects[i + 3] + y1;
Harish Krupo98275472017-06-09 20:13:34 +05301398
Harish Krupofd734602018-07-08 12:53:00 +05301399 rects[i] = CLAMP(x1, 0, surf_width);
1400 rects[i + 1] = CLAMP(y1, 0, surf_height);
1401 rects[i + 2] = CLAMP(x2, 0, surf_width) - rects[i];
1402 rects[i + 3] = CLAMP(y2, 0, surf_height) - rects[i + 1];
Harish Krupo98275472017-06-09 20:13:34 +05301403 }
1404}
1405
1406static EGLBoolean EGLAPIENTRY
1407eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
1408 EGLint *rects, EGLint n_rects)
1409{
1410 _EGLDisplay *disp = _eglLockDisplay(dpy);
1411 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1412 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1413 _EGLContext *ctx = _eglGetCurrentContext();
Harish Krupo98275472017-06-09 20:13:34 +05301414 EGLBoolean ret;
Eric Engestromc74628f2020-08-03 22:50:42 +02001415 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Harish Krupo98275472017-06-09 20:13:34 +05301416
1417 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1418 surf->Type != EGL_WINDOW_BIT ||
1419 ctx->DrawSurface != surf ||
1420 surf->SwapBehavior != EGL_BUFFER_DESTROYED)
1421 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1422
1423 /* If the damage region is already set or
1424 * buffer age is not queried between
1425 * frame boundaries, throw bad access error
1426 */
1427
1428 if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
1429 RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
1430
Eric Engestrom3ef8aac2018-05-21 10:42:10 +01001431 _eglSetDamageRegionKHRClampRects(surf, rects, n_rects);
Eric Engestrom5eb58472020-08-03 22:19:42 +02001432 ret = disp->Driver->SetDamageRegion(disp, surf, rects, n_rects);
Harish Krupo98275472017-06-09 20:13:34 +05301433
1434 if (ret)
1435 surf->SetDamageRegionCalled = EGL_TRUE;
1436
1437 RETURN_EGL_EVAL(disp, ret);
1438}
1439
Brian Paul1ed10272008-05-27 13:45:41 -06001440EGLBoolean EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +08001441eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
Brian Pauladbff7e2005-04-22 21:09:39 +00001442{
Chia-I Wu655f4652010-02-17 17:30:44 +08001443 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001444 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001445 EGLBoolean ret;
Chad Versace6d1f83e2014-01-07 14:54:51 -08001446 void *native_pixmap_ptr;
1447
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001448 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001449 STATIC_ASSERT(sizeof(void*) == sizeof(target));
1450 native_pixmap_ptr = (void*) target;
Chia-I Wuaed73582010-02-17 15:43:47 +08001451
Eric Engestromc74628f2020-08-03 22:50:42 +02001452 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Eric Engestrom5eb58472020-08-03 22:19:42 +02001453 ret = disp->Driver->CopyBuffers(disp, surf, native_pixmap_ptr);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001454
Chia-I Wubef4b472010-02-19 12:08:50 +08001455 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001456}
1457
1458
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001459static EGLBoolean
1460_eglWaitClientCommon(void)
Brian Pauladbff7e2005-04-22 21:09:39 +00001461{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001462 _EGLContext *ctx = _eglGetCurrentContext();
1463 _EGLDisplay *disp;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001464 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001465
Chia-I Wu6c21c882009-09-28 14:12:39 +08001466 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001467 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001468
1469 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001470 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001471
1472 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001473 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1474 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001475 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001476
Chia-I Wu6c21c882009-09-28 14:12:39 +08001477 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001478 assert(disp->Initialized);
Eric Engestrom4e654692018-04-22 16:48:15 +02001479 ret = disp->Driver->WaitClient(disp, ctx);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001480
Chia-I Wubef4b472010-02-19 12:08:50 +08001481 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu6c21c882009-09-28 14:12:39 +08001482}
1483
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001484EGLBoolean EGLAPIENTRY
1485eglWaitClient(void)
1486{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001487 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001488 return _eglWaitClientCommon();
1489}
Chia-I Wu6c21c882009-09-28 14:12:39 +08001490
1491EGLBoolean EGLAPIENTRY
1492eglWaitGL(void)
1493{
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001494 /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001495 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001496 return _eglWaitClientCommon();
Brian Pauladbff7e2005-04-22 21:09:39 +00001497}
1498
1499
Brian Paul1ed10272008-05-27 13:45:41 -06001500EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001501eglWaitNative(EGLint engine)
1502{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001503 _EGLContext *ctx = _eglGetCurrentContext();
1504 _EGLDisplay *disp;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001505 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001506
Chia-I Wu6c21c882009-09-28 14:12:39 +08001507 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001508 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001509
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001510 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1511
Chia-I Wu655f4652010-02-17 17:30:44 +08001512 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001513 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001514
Chia-I Wu6c21c882009-09-28 14:12:39 +08001515 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001516 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1517 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001518 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001519
Chia-I Wu6c21c882009-09-28 14:12:39 +08001520 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001521 assert(disp->Initialized);
Eric Engestromb8d1c462018-04-22 16:48:15 +02001522 ret = disp->Driver->WaitNative(engine);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001523
Chia-I Wubef4b472010-02-19 12:08:50 +08001524 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001525}
1526
1527
Brian Paul1ed10272008-05-27 13:45:41 -06001528EGLDisplay EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001529eglGetCurrentDisplay(void)
1530{
Chia-I Wua1717972010-01-26 17:13:51 +08001531 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001532 EGLDisplay ret;
1533
1534 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
1535
Chia-I Wubef4b472010-02-19 12:08:50 +08001536 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001537}
1538
1539
Brian Paul1ed10272008-05-27 13:45:41 -06001540EGLContext EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001541eglGetCurrentContext(void)
1542{
1543 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001544 EGLContext ret;
1545
1546 ret = _eglGetContextHandle(ctx);
1547
Chia-I Wubef4b472010-02-19 12:08:50 +08001548 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001549}
1550
1551
Brian Paul1ed10272008-05-27 13:45:41 -06001552EGLSurface EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001553eglGetCurrentSurface(EGLint readdraw)
1554{
Chia-I Wu61906632009-09-30 15:34:45 +08001555 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001556 EGLint err = EGL_SUCCESS;
Chia-I Wu61906632009-09-30 15:34:45 +08001557 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001558 EGLSurface ret;
Chia-I Wu61906632009-09-30 15:34:45 +08001559
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001560 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
1561
Chia-I Wu61906632009-09-30 15:34:45 +08001562 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001563 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
Chia-I Wu61906632009-09-30 15:34:45 +08001564
1565 switch (readdraw) {
1566 case EGL_DRAW:
1567 surf = ctx->DrawSurface;
1568 break;
1569 case EGL_READ:
1570 surf = ctx->ReadSurface;
1571 break;
1572 default:
Chia-I Wu61906632009-09-30 15:34:45 +08001573 surf = NULL;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001574 err = EGL_BAD_PARAMETER;
Chia-I Wu61906632009-09-30 15:34:45 +08001575 break;
1576 }
1577
Chia-I Wub3bb1802010-02-17 16:05:27 +08001578 ret = _eglGetSurfaceHandle(surf);
1579
Chia-I Wubef4b472010-02-19 12:08:50 +08001580 RETURN_EGL_ERROR(NULL, err, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001581}
1582
1583
Brian Paul1ed10272008-05-27 13:45:41 -06001584EGLint EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001585eglGetError(void)
1586{
Brian Paul48822792005-12-10 17:54:00 +00001587 _EGLThreadInfo *t = _eglGetCurrentThread();
1588 EGLint e = t->LastError;
Chia-I Wu75da80b2009-07-17 11:41:02 -06001589 if (!_eglIsCurrentThreadDummy())
1590 t->LastError = EGL_SUCCESS;
Brian Pauladbff7e2005-04-22 21:09:39 +00001591 return e;
1592}
1593
1594
Brian Paulb2006a42006-01-30 00:10:55 +00001595/**
1596 ** EGL 1.2
1597 **/
1598
Brian Pauld5078b92008-05-30 13:45:40 -06001599/**
1600 * Specify the client API to use for subsequent calls including:
1601 * eglCreateContext()
1602 * eglGetCurrentContext()
1603 * eglGetCurrentDisplay()
1604 * eglGetCurrentSurface()
1605 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1606 * eglWaitClient()
1607 * eglWaitNative()
1608 * See section 3.7 "Rendering Context" in the EGL specification for details.
1609 */
nobledc43ab4f2010-07-02 19:38:07 -04001610EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001611eglBindAPI(EGLenum api)
1612{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001613 _EGLThreadInfo *t;
Brian Paulb2006a42006-01-30 00:10:55 +00001614
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001615 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1616
1617 t = _eglGetCurrentThread();
Chia-I Wu75da80b2009-07-17 11:41:02 -06001618 if (_eglIsCurrentThreadDummy())
Chia-I Wubef4b472010-02-19 12:08:50 +08001619 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
Chia-I Wu75da80b2009-07-17 11:41:02 -06001620
Chia-I Wu21b635f2009-07-17 11:42:04 -06001621 if (!_eglIsApiValid(api))
Chia-I Wubef4b472010-02-19 12:08:50 +08001622 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wu21b635f2009-07-17 11:42:04 -06001623
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001624 t->CurrentAPI = api;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001625
Chia-I Wubef4b472010-02-19 12:08:50 +08001626 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001627}
Jon Smirl7012d012005-05-13 18:31:35 +00001628
1629
Brian Pauld5078b92008-05-30 13:45:40 -06001630/**
1631 * Return the last value set with eglBindAPI().
1632 */
nobledc43ab4f2010-07-02 19:38:07 -04001633EGLenum EGLAPIENTRY
Brian Pauld5078b92008-05-30 13:45:40 -06001634eglQueryAPI(void)
1635{
Brian Pauld5078b92008-05-30 13:45:40 -06001636 _EGLThreadInfo *t = _eglGetCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001637 EGLenum ret;
1638
1639 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001640 ret = t->CurrentAPI;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001641
Chia-I Wubef4b472010-02-19 12:08:50 +08001642 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauld5078b92008-05-30 13:45:40 -06001643}
1644
1645
nobledc43ab4f2010-07-02 19:38:07 -04001646EGLSurface EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001647eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1648 EGLClientBuffer buffer, EGLConfig config,
1649 const EGLint *attrib_list)
1650{
Chia-I Wu655f4652010-02-17 17:30:44 +08001651 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001652 _EGLConfig *conf = _eglLookupConfig(config, disp);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001653
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001654 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1655
Eric Engestromc74628f2020-08-03 22:50:42 +02001656 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001657
Eric Engestrome9286eb2019-06-22 15:53:36 +01001658 /* OpenVG is not supported */
1659 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Brian Paulb2006a42006-01-30 00:10:55 +00001660}
Jon Smirl7012d012005-05-13 18:31:35 +00001661
Brian Paulb2006a42006-01-30 00:10:55 +00001662
nobledc43ab4f2010-07-02 19:38:07 -04001663EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001664eglReleaseThread(void)
1665{
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001666 /* unbind current contexts */
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001667 if (!_eglIsCurrentThreadDummy()) {
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001668 _EGLThreadInfo *t = _eglGetCurrentThread();
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001669 _EGLContext *ctx = t->CurrentContext;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001670
1671 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1672
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001673 if (ctx) {
1674 _EGLDisplay *disp = ctx->Resource.Display;
Chia-I Wu655f4652010-02-17 17:30:44 +08001675
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001676 mtx_lock(&disp->Mutex);
Eric Engestrom1a17f1d2018-04-22 16:48:15 +02001677 (void) disp->Driver->MakeCurrent(disp, NULL, NULL, NULL);
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001678 mtx_unlock(&disp->Mutex);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001679 }
Brian Paulb2006a42006-01-30 00:10:55 +00001680 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001681
Chia-I Wu75da80b2009-07-17 11:41:02 -06001682 _eglDestroyCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001683
Chia-I Wubef4b472010-02-19 12:08:50 +08001684 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001685}
1686
1687
Kyle Brenneman58338c62016-09-12 17:38:13 -04001688static EGLImage
1689_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001690 EGLClientBuffer buffer, const EGLint *attr_list)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001691{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001692 _EGLContext *context = _eglLookupContext(ctx, disp);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001693 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02001694 EGLImage ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001695
Eric Engestromc74628f2020-08-03 22:50:42 +02001696 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001697 if (!disp->Extensions.KHR_image_base)
1698 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001699 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +08001700 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
Topi Pohjolainen0de013b2013-03-22 14:31:01 +02001701 /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1702 * <ctx> must be EGL_NO_CONTEXT..."
1703 */
1704 if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1705 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001706
Eric Engestrom5eb58472020-08-03 22:19:42 +02001707 img = disp->Driver->CreateImageKHR(disp, context, target, buffer, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001708 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001709
Chia-I Wubef4b472010-02-19 12:08:50 +08001710 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001711}
1712
Kyle Brenneman58338c62016-09-12 17:38:13 -04001713static EGLImage EGLAPIENTRY
1714eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1715 EGLClientBuffer buffer, const EGLint *attr_list)
1716{
1717 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001718 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
Kyle Brenneman58338c62016-09-12 17:38:13 -04001719 return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
1720}
1721
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001722
Marek Olšák515f04e2015-05-12 20:42:05 +02001723EGLImage EGLAPIENTRY
1724eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1725 EGLClientBuffer buffer, const EGLAttrib *attr_list)
1726{
Kyle Brenneman58338c62016-09-12 17:38:13 -04001727 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák515f04e2015-05-12 20:42:05 +02001728 EGLImage image;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001729 EGLint *int_attribs;
Marek Olšák515f04e2015-05-12 20:42:05 +02001730
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001731 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
1732
1733 int_attribs = _eglConvertAttribsToInt(attr_list);
Marek Olšák515f04e2015-05-12 20:42:05 +02001734 if (attr_list && !int_attribs)
Kyle Brenneman58338c62016-09-12 17:38:13 -04001735 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
Marek Olšák515f04e2015-05-12 20:42:05 +02001736
Kyle Brenneman58338c62016-09-12 17:38:13 -04001737 image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
Marek Olšák515f04e2015-05-12 20:42:05 +02001738 free(int_attribs);
1739 return image;
1740}
1741
1742
Eric Engestromdf7fa302017-02-21 23:56:44 +00001743static EGLBoolean
1744_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001745{
Chia-I Wub3bb1802010-02-17 16:05:27 +08001746 EGLBoolean ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001747
Eric Engestromc74628f2020-08-03 22:50:42 +02001748 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001749 if (!disp->Extensions.KHR_image_base)
1750 RETURN_EGL_EVAL(disp, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001751 if (!img)
Chia-I Wubef4b472010-02-19 12:08:50 +08001752 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001753
1754 _eglUnlinkImage(img);
Eric Engestrom5eb58472020-08-03 22:19:42 +02001755 ret = disp->Driver->DestroyImageKHR(disp, img);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001756
Chia-I Wubef4b472010-02-19 12:08:50 +08001757 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001758}
1759
Eric Engestromdf7fa302017-02-21 23:56:44 +00001760EGLBoolean EGLAPIENTRY
1761eglDestroyImage(EGLDisplay dpy, EGLImage image)
1762{
1763 _EGLDisplay *disp = _eglLockDisplay(dpy);
1764 _EGLImage *img = _eglLookupImage(image, disp);
1765 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1766 return _eglDestroyImageCommon(disp, img);
1767}
1768
1769static EGLBoolean EGLAPIENTRY
1770eglDestroyImageKHR(EGLDisplay dpy, EGLImage image)
1771{
1772 _EGLDisplay *disp = _eglLockDisplay(dpy);
1773 _EGLImage *img = _eglLookupImage(image, disp);
1774 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1775 return _eglDestroyImageCommon(disp, img);
1776}
1777
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001778
Marek Olšákd333d302015-05-12 17:34:57 +02001779static EGLSync
Chad Versace80448852016-09-27 13:27:21 -07001780_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
1781 EGLBoolean orig_is_EGLAttrib,
Marek Olšák51c8c662015-05-12 21:41:32 +02001782 EGLenum invalid_type_error)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001783{
Marek Olšák9a0bda22015-04-10 10:56:02 +02001784 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu4eebea72010-08-14 23:09:12 +08001785 _EGLSync *sync;
Marek Olšákd333d302015-05-12 17:34:57 +02001786 EGLSync ret;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001787
Eric Engestromc74628f2020-08-03 22:50:42 +02001788 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001789
Chad Versace80448852016-09-27 13:27:21 -07001790 if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
Chad Versacef2c2f432016-09-27 13:27:12 -07001791 /* There exist two EGLAttrib variants of eglCreateSync*:
1792 * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
1793 * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
1794 * support as a proxy for EGL 1.5 support, even though that's not
1795 * entirely correct (though _eglComputeVersion does the same).
1796 *
1797 * The EGL spec provides no guidance on how to handle unsupported
1798 * functions. EGL_BAD_MATCH seems reasonable.
1799 */
1800 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1801 }
Marek Olšák290a3eb2015-04-10 13:16:30 +02001802
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001803 /* If type is EGL_SYNC_FENCE and no context is current for the bound API
1804 * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH
1805 * error is generated.
1806 */
Rob Clark0201f012016-11-18 08:39:33 -05001807 if (!ctx &&
1808 (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001809 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1810
Heinrich Fink3aa4f3a2019-07-30 15:58:20 +02001811 /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001812 if (ctx && (ctx->Resource.Display != disp ||
Heinrich Fink3aa4f3a2019-07-30 15:58:20 +02001813 (ctx->ClientAPI != EGL_OPENGL_ES_API &&
1814 ctx->ClientAPI != EGL_OPENGL_API)))
Marek Olšák9a0bda22015-04-10 10:56:02 +02001815 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1816
1817 switch (type) {
1818 case EGL_SYNC_FENCE_KHR:
1819 if (!disp->Extensions.KHR_fence_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001820 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001821 break;
1822 case EGL_SYNC_REUSABLE_KHR:
1823 if (!disp->Extensions.KHR_reusable_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001824 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001825 break;
Marek Olšák290a3eb2015-04-10 13:16:30 +02001826 case EGL_SYNC_CL_EVENT_KHR:
1827 if (!disp->Extensions.KHR_cl_event2)
Marek Olšák51c8c662015-05-12 21:41:32 +02001828 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001829 break;
Rob Clark0201f012016-11-18 08:39:33 -05001830 case EGL_SYNC_NATIVE_FENCE_ANDROID:
1831 if (!disp->Extensions.ANDROID_native_fence_sync)
1832 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1833 break;
Marek Olšák9a0bda22015-04-10 10:56:02 +02001834 default:
Marek Olšák51c8c662015-05-12 21:41:32 +02001835 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001836 }
Chia-I Wu4eebea72010-08-14 23:09:12 +08001837
Eric Engestrom5eb58472020-08-03 22:19:42 +02001838 sync = disp->Driver->CreateSyncKHR(disp, type, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001839 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001840
1841 RETURN_EGL_EVAL(disp, ret);
1842}
1843
1844
Marek Olšákd333d302015-05-12 17:34:57 +02001845static EGLSync EGLAPIENTRY
Chad Versace80448852016-09-27 13:27:21 -07001846eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001847{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001848 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001849 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001850
1851 EGLSync sync;
1852 EGLAttrib *attrib_list;
1853 EGLint err;
1854
1855 if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
1856 attrib_list = (EGLAttrib *) int_list;
1857 } else {
1858 err = _eglConvertIntsToAttribs(int_list, &attrib_list);
1859 if (err != EGL_SUCCESS)
1860 RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
1861 }
1862
1863 sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001864 EGL_BAD_ATTRIBUTE);
Chad Versace80448852016-09-27 13:27:21 -07001865
1866 if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
1867 free(attrib_list);
1868
1869 /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
1870 return sync;
Marek Olšák51c8c662015-05-12 21:41:32 +02001871}
1872
1873
1874static EGLSync EGLAPIENTRY
1875eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1876{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001877 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001878 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001879 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001880 EGL_BAD_ATTRIBUTE);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001881}
1882
1883
Marek Olšák2885ba02015-05-12 20:54:22 +02001884EGLSync EGLAPIENTRY
1885eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001886{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001887 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001888 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001889 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001890 EGL_BAD_PARAMETER);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001891}
1892
1893
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001894static EGLBoolean
1895_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001896{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001897 EGLBoolean ret;
1898
Eric Engestromc74628f2020-08-03 22:50:42 +02001899 _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
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);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001903
Chia-I Wu4eebea72010-08-14 23:09:12 +08001904 _eglUnlinkSync(s);
Eric Engestrom5eb58472020-08-03 22:19:42 +02001905 ret = disp->Driver->DestroySyncKHR(disp, s);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001906
1907 RETURN_EGL_EVAL(disp, ret);
1908}
1909
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001910EGLBoolean EGLAPIENTRY
1911eglDestroySync(EGLDisplay dpy, EGLSync sync)
1912{
1913 _EGLDisplay *disp = _eglLockDisplay(dpy);
1914 _EGLSync *s = _eglLookupSync(sync, disp);
1915 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1916 return _eglDestroySync(disp, s);
1917}
1918
1919static EGLBoolean EGLAPIENTRY
1920eglDestroySyncKHR(EGLDisplay dpy, EGLSync sync)
1921{
1922 _EGLDisplay *disp = _eglLockDisplay(dpy);
1923 _EGLSync *s = _eglLookupSync(sync, disp);
1924 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1925 return _eglDestroySync(disp, s);
1926}
1927
Chia-I Wu4eebea72010-08-14 23:09:12 +08001928
Eric Engestrom66d5ec52017-02-21 23:56:46 +00001929static EGLint
1930_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
1931 _EGLSync *s, EGLint flags, EGLTime timeout)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001932{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001933 EGLint ret;
1934
Eric Engestromc74628f2020-08-03 22:50:42 +02001935 _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001936 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05001937 disp->Extensions.KHR_fence_sync ||
1938 disp->Extensions.ANDROID_native_fence_sync);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001939
1940 if (s->SyncStatus == EGL_SIGNALED_KHR)
1941 RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
1942
Dongwon Kim70299472016-04-04 17:14:10 -07001943 /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
1944 * unlocked here to allow other threads also to be able to
1945 * go into waiting state.
1946 */
1947
1948 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1949 _eglUnlockDisplay(dpy);
1950
Eric Engestrom5eb58472020-08-03 22:19:42 +02001951 ret = disp->Driver->ClientWaitSyncKHR(disp, s, flags, timeout);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001952
Dongwon Kim70299472016-04-04 17:14:10 -07001953 /*
1954 * 'disp' is already unlocked for reusable sync type,
1955 * so passing 'NULL' to bypass unlocking display.
1956 */
1957 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1958 RETURN_EGL_EVAL(NULL, ret);
1959 else
1960 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001961}
1962
Eric Engestrom66d5ec52017-02-21 23:56:46 +00001963EGLint EGLAPIENTRY
1964eglClientWaitSync(EGLDisplay dpy, EGLSync sync,
1965 EGLint flags, EGLTime timeout)
1966{
1967 _EGLDisplay *disp = _eglLockDisplay(dpy);
1968 _EGLSync *s = _eglLookupSync(sync, disp);
1969 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1970 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
1971}
1972
1973static EGLint EGLAPIENTRY
1974eglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync,
1975 EGLint flags, EGLTime timeout)
1976{
1977 _EGLDisplay *disp = _eglLockDisplay(dpy);
1978 _EGLSync *s = _eglLookupSync(sync, disp);
1979 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1980 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
1981}
1982
Chia-I Wu4eebea72010-08-14 23:09:12 +08001983
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001984static EGLint
1985_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
Marek Olšáka8617cc2015-04-10 12:04:18 +02001986{
Marek Olšáka8617cc2015-04-10 12:04:18 +02001987 _EGLContext *ctx = _eglGetCurrentContext();
Marek Olšáka8617cc2015-04-10 12:04:18 +02001988 EGLint ret;
1989
Eric Engestromc74628f2020-08-03 22:50:42 +02001990 _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
Marek Olšáka8617cc2015-04-10 12:04:18 +02001991 assert(disp->Extensions.KHR_wait_sync);
1992
Heinrich Fink3aa4f3a2019-07-30 15:58:20 +02001993 /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
1994 if (ctx == EGL_NO_CONTEXT ||
1995 (ctx->ClientAPI != EGL_OPENGL_ES_API &&
1996 ctx->ClientAPI != EGL_OPENGL_API))
Marek Olšáka8617cc2015-04-10 12:04:18 +02001997 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1998
1999 /* the API doesn't allow any flags yet */
2000 if (flags != 0)
2001 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2002
Eric Engestrom5eb58472020-08-03 22:19:42 +02002003 ret = disp->Driver->WaitSyncKHR(disp, s);
Marek Olšáka8617cc2015-04-10 12:04:18 +02002004
2005 RETURN_EGL_EVAL(disp, ret);
2006}
2007
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002008static EGLint EGLAPIENTRY
2009eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
2010{
2011 _EGLDisplay *disp = _eglLockDisplay(dpy);
2012 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002013 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002014 return _eglWaitSyncCommon(disp, s, flags);
2015}
2016
Marek Olšáka8617cc2015-04-10 12:04:18 +02002017
Marek Olšák75245922015-05-12 18:13:31 +02002018EGLBoolean EGLAPIENTRY
2019eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
2020{
2021 /* The KHR version returns EGLint, while the core version returns
2022 * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
2023 * EGL_TRUE.
2024 */
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002025 _EGLDisplay *disp = _eglLockDisplay(dpy);
2026 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002027 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002028 return _eglWaitSyncCommon(disp, s, flags);
Marek Olšák75245922015-05-12 18:13:31 +02002029}
2030
2031
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002032static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002033eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
Chia-I Wu4eebea72010-08-14 23:09:12 +08002034{
2035 _EGLDisplay *disp = _eglLockDisplay(dpy);
2036 _EGLSync *s = _eglLookupSync(sync, disp);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002037 EGLBoolean ret;
2038
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002039 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2040
Eric Engestromc74628f2020-08-03 22:50:42 +02002041 _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002042 assert(disp->Extensions.KHR_reusable_sync);
Eric Engestrom5eb58472020-08-03 22:19:42 +02002043 ret = disp->Driver->SignalSyncKHR(disp, s, mode);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002044
2045 RETURN_EGL_EVAL(disp, ret);
2046}
2047
2048
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002049static EGLBoolean
2050_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
Chia-I Wu4eebea72010-08-14 23:09:12 +08002051{
Chia-I Wu4eebea72010-08-14 23:09:12 +08002052 EGLBoolean ret;
2053
Eric Engestromc74628f2020-08-03 22:50:42 +02002054 _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
Marek Olšák9a0bda22015-04-10 10:56:02 +02002055 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05002056 disp->Extensions.KHR_fence_sync ||
2057 disp->Extensions.ANDROID_native_fence_sync);
Eric Engestrom757d2fb2019-06-22 22:33:00 +01002058
Eric Engestrom372c6c42020-08-03 17:19:30 +02002059 ret = _eglGetSyncAttrib(disp, s, attribute, value);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002060
2061 RETURN_EGL_EVAL(disp, ret);
2062}
2063
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002064EGLBoolean EGLAPIENTRY
2065eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
2066{
2067 _EGLDisplay *disp = _eglLockDisplay(dpy);
2068 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002069 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Tapani Pälli99cbec02019-06-10 13:06:05 +03002070
2071 if (!value)
2072 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2073
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002074 return _eglGetSyncAttribCommon(disp, s, attribute, value);
2075}
2076
Chia-I Wu4eebea72010-08-14 23:09:12 +08002077
Marek Olšák1e79e052015-05-12 18:14:31 +02002078static EGLBoolean EGLAPIENTRY
2079eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
2080{
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002081 _EGLDisplay *disp = _eglLockDisplay(dpy);
2082 _EGLSync *s = _eglLookupSync(sync, disp);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002083 EGLAttrib attrib;
2084 EGLBoolean result;
2085
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002086 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2087
Dongwon Kimd1e15632016-02-02 15:06:28 -08002088 if (!value)
Chad Versace17084b62016-09-27 23:06:37 -07002089 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002090
2091 attrib = *value;
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002092 result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
Marek Olšák1e79e052015-05-12 18:14:31 +02002093
2094 /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
2095 *
2096 * If any error occurs, <*value> is not modified.
2097 */
2098 if (result == EGL_FALSE)
2099 return result;
2100
2101 *value = attrib;
2102 return result;
2103}
2104
Rob Clark0201f012016-11-18 08:39:33 -05002105static EGLint EGLAPIENTRY
2106eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
2107{
2108 _EGLDisplay *disp = _eglLockDisplay(dpy);
2109 _EGLSync *s = _eglLookupSync(sync, disp);
Rob Clark0201f012016-11-18 08:39:33 -05002110 EGLBoolean ret;
2111
2112 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2113
2114 /* the spec doesn't seem to specify what happens if the fence
2115 * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems
2116 * sensible:
2117 */
2118 if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)))
2119 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID);
2120
Eric Engestromc74628f2020-08-03 22:50:42 +02002121 _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID);
Rob Clark0201f012016-11-18 08:39:33 -05002122 assert(disp->Extensions.ANDROID_native_fence_sync);
Eric Engestrom5eb58472020-08-03 22:19:42 +02002123 ret = disp->Driver->DupNativeFenceFDANDROID(disp, s);
Rob Clark0201f012016-11-18 08:39:33 -05002124
2125 RETURN_EGL_EVAL(disp, ret);
2126}
Marek Olšák1e79e052015-05-12 18:14:31 +02002127
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002128static EGLBoolean EGLAPIENTRY
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002129eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002130 EGLint numRects, const EGLint *rects)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002131{
2132 _EGLContext *ctx = _eglGetCurrentContext();
2133 _EGLDisplay *disp = _eglLockDisplay(dpy);
2134 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002135 EGLBoolean ret;
2136
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002137 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2138
Eric Engestromc74628f2020-08-03 22:50:42 +02002139 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002140
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002141 if (!disp->Extensions.NOK_swap_region)
2142 RETURN_EGL_EVAL(disp, EGL_FALSE);
2143
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002144 /* surface must be bound to current context in EGL 1.4 */
Chia-I Wud19afc52010-10-23 12:52:26 +08002145 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
2146 surf != ctx->DrawSurface)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002147 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
2148
Eric Engestrom5eb58472020-08-03 22:19:42 +02002149 ret = disp->Driver->SwapBuffersRegionNOK(disp, surf, numRects, rects);
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002150
2151 RETURN_EGL_EVAL(disp, ret);
2152}
2153
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002154
Marek Olšákd333d302015-05-12 17:34:57 +02002155static EGLImage EGLAPIENTRY
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002156eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
2157{
2158 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002159 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02002160 EGLImage ret;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002161
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002162 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2163
Eric Engestromc74628f2020-08-03 22:50:42 +02002164 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002165 if (!disp->Extensions.MESA_drm_image)
2166 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002167
Eric Engestrom5eb58472020-08-03 22:19:42 +02002168 img = disp->Driver->CreateDRMImageMESA(disp, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08002169 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002170
2171 RETURN_EGL_EVAL(disp, ret);
2172}
2173
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002174static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002175eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002176 EGLint *name, EGLint *handle, EGLint *stride)
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002177{
2178 _EGLDisplay *disp = _eglLockDisplay(dpy);
2179 _EGLImage *img = _eglLookupImage(image, disp);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002180 EGLBoolean ret;
2181
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002182 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2183
Eric Engestromc74628f2020-08-03 22:50:42 +02002184 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002185 assert(disp->Extensions.MESA_drm_image);
2186
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002187 if (!img)
2188 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2189
Eric Engestrom5eb58472020-08-03 22:19:42 +02002190 ret = disp->Driver->ExportDRMImageMESA(disp, img, name, handle, stride);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002191
2192 RETURN_EGL_EVAL(disp, ret);
2193}
2194
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002195
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002196struct wl_display;
2197
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002198static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002199eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2200{
2201 _EGLDisplay *disp = _eglLockDisplay(dpy);
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002202 EGLBoolean ret;
2203
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002204 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2205
Eric Engestromc74628f2020-08-03 22:50:42 +02002206 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002207 assert(disp->Extensions.WL_bind_wayland_display);
2208
2209 if (!display)
2210 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2211
Eric Engestrom5eb58472020-08-03 22:19:42 +02002212 ret = disp->Driver->BindWaylandDisplayWL(disp, display);
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002213
2214 RETURN_EGL_EVAL(disp, ret);
2215}
2216
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002217static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002218eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2219{
2220 _EGLDisplay *disp = _eglLockDisplay(dpy);
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002221 EGLBoolean ret;
2222
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002223 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2224
Eric Engestromc74628f2020-08-03 22:50:42 +02002225 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002226 assert(disp->Extensions.WL_bind_wayland_display);
2227
2228 if (!display)
2229 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2230
Eric Engestrom5eb58472020-08-03 22:19:42 +02002231 ret = disp->Driver->UnbindWaylandDisplayWL(disp, display);
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002232
2233 RETURN_EGL_EVAL(disp, ret);
2234}
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002235
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002236static EGLBoolean EGLAPIENTRY
Ander Conselvan de Oliveira8d29b522013-07-18 15:11:25 +03002237eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002238 EGLint attribute, EGLint *value)
2239{
2240 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002241 EGLBoolean ret;
2242
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002243 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2244
Eric Engestromc74628f2020-08-03 22:50:42 +02002245 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002246 assert(disp->Extensions.WL_bind_wayland_display);
2247
2248 if (!buffer)
2249 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2250
Eric Engestrom5eb58472020-08-03 22:19:42 +02002251 ret = disp->Driver->QueryWaylandBufferWL(disp, buffer, attribute, value);
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002252
2253 RETURN_EGL_EVAL(disp, ret);
2254}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002255
Emil Velikov720125f2015-07-10 11:22:13 +01002256
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002257static struct wl_buffer * EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002258eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002259{
2260 _EGLDisplay *disp = _eglLockDisplay(dpy);
2261 _EGLImage *img;
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002262 struct wl_buffer *ret;
2263
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002264 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2265
Eric Engestromc74628f2020-08-03 22:50:42 +02002266 _EGL_CHECK_DISPLAY(disp, NULL);
Emil Velikov70131142017-05-15 16:14:15 +01002267 if (!disp->Extensions.WL_create_wayland_buffer_from_image)
2268 RETURN_EGL_EVAL(disp, NULL);
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002269
2270 img = _eglLookupImage(image, disp);
2271
2272 if (!img)
2273 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
2274
Eric Engestrom5eb58472020-08-03 22:19:42 +02002275 ret = disp->Driver->CreateWaylandBufferFromImageWL(disp, img);
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002276
2277 RETURN_EGL_EVAL(disp, ret);
2278}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002279
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002280static EGLBoolean EGLAPIENTRY
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002281eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
2282 EGLint x, EGLint y, EGLint width, EGLint height)
2283{
2284 _EGLDisplay *disp = _eglLockDisplay(dpy);
2285 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002286 EGLBoolean ret;
2287
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002288 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2289
Eric Engestromc74628f2020-08-03 22:50:42 +02002290 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002291
2292 if (!disp->Extensions.NV_post_sub_buffer)
2293 RETURN_EGL_EVAL(disp, EGL_FALSE);
2294
Eric Engestrom5eb58472020-08-03 22:19:42 +02002295 ret = disp->Driver->PostSubBufferNV(disp, surf, x, y, width, height);
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002296
2297 RETURN_EGL_EVAL(disp, ret);
2298}
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002299
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002300static EGLBoolean EGLAPIENTRY
Eric Engestrom54fa5ec2019-02-02 11:38:45 +00002301eglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface,
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002302 EGLuint64KHR *ust, EGLuint64KHR *msc,
2303 EGLuint64KHR *sbc)
2304{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +00002305 _EGLDisplay *disp = _eglLockDisplay(dpy);
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002306 _EGLSurface *surf = _eglLookupSurface(surface, disp);
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002307 EGLBoolean ret;
2308
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002309 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2310
Eric Engestromc74628f2020-08-03 22:50:42 +02002311 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002312 if (!disp->Extensions.CHROMIUM_sync_control)
2313 RETURN_EGL_EVAL(disp, EGL_FALSE);
2314
2315 if (!ust || !msc || !sbc)
2316 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2317
Eric Engestrom5eb58472020-08-03 22:19:42 +02002318 ret = disp->Driver->GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002319
2320 RETURN_EGL_EVAL(disp, ret);
2321}
Dave Airlie8f7338f2014-03-03 13:57:16 +10002322
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002323static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002324eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002325 EGLint *fourcc, EGLint *nplanes,
Dave Airlieb5045e22015-05-05 09:10:34 +10002326 EGLuint64KHR *modifiers)
Dave Airlie8f7338f2014-03-03 13:57:16 +10002327{
2328 _EGLDisplay *disp = _eglLockDisplay(dpy);
2329 _EGLImage *img = _eglLookupImage(image, disp);
Dave Airlie8f7338f2014-03-03 13:57:16 +10002330 EGLBoolean ret;
2331
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002332 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2333
Eric Engestromc74628f2020-08-03 22:50:42 +02002334 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Dave Airlie8f7338f2014-03-03 13:57:16 +10002335 assert(disp->Extensions.MESA_image_dma_buf_export);
2336
2337 if (!img)
2338 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2339
Eric Engestrom5eb58472020-08-03 22:19:42 +02002340 ret = disp->Driver->ExportDMABUFImageQueryMESA(disp, img, fourcc, nplanes, modifiers);
Dave Airlie8f7338f2014-03-03 13:57:16 +10002341
2342 RETURN_EGL_EVAL(disp, ret);
2343}
2344
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002345static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002346eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002347 int *fds, EGLint *strides, EGLint *offsets)
2348{
2349 _EGLDisplay *disp = _eglLockDisplay(dpy);
2350 _EGLImage *img = _eglLookupImage(image, disp);
Dave Airlie8f7338f2014-03-03 13:57:16 +10002351 EGLBoolean ret;
2352
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002353 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2354
Eric Engestromc74628f2020-08-03 22:50:42 +02002355 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Dave Airlie8f7338f2014-03-03 13:57:16 +10002356 assert(disp->Extensions.MESA_image_dma_buf_export);
2357
2358 if (!img)
2359 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2360
Eric Engestrom5eb58472020-08-03 22:19:42 +02002361 ret = disp->Driver->ExportDMABUFImageMESA(disp, img, fds, strides, offsets);
Dave Airlie8f7338f2014-03-03 13:57:16 +10002362
2363 RETURN_EGL_EVAL(disp, ret);
2364}
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002365
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002366static EGLint EGLAPIENTRY
2367eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002368 EGLLabelKHR label)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002369{
2370 _EGLDisplay *disp = NULL;
2371 _EGLResourceType type;
2372
2373 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2374
2375 if (objectType == EGL_OBJECT_THREAD_KHR) {
2376 _EGLThreadInfo *t = _eglGetCurrentThread();
2377
2378 if (!_eglIsCurrentThreadDummy()) {
2379 t->Label = label;
2380 return EGL_SUCCESS;
2381 }
2382
2383 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
2384 }
2385
2386 disp = _eglLockDisplay(dpy);
2387 if (disp == NULL)
2388 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
2389
2390 if (objectType == EGL_OBJECT_DISPLAY_KHR) {
2391 if (dpy != (EGLDisplay) object)
2392 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2393
2394 disp->Label = label;
2395 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2396 }
2397
2398 switch (objectType) {
2399 case EGL_OBJECT_CONTEXT_KHR:
2400 type = _EGL_RESOURCE_CONTEXT;
2401 break;
2402 case EGL_OBJECT_SURFACE_KHR:
2403 type = _EGL_RESOURCE_SURFACE;
2404 break;
2405 case EGL_OBJECT_IMAGE_KHR:
2406 type = _EGL_RESOURCE_IMAGE;
2407 break;
2408 case EGL_OBJECT_SYNC_KHR:
2409 type = _EGL_RESOURCE_SYNC;
2410 break;
2411 case EGL_OBJECT_STREAM_KHR:
2412 default:
2413 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2414 }
2415
2416 if (_eglCheckResource(object, type, disp)) {
2417 _EGLResource *res = (_EGLResource *) object;
2418
2419 res->Label = label;
2420 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2421 }
2422
2423 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2424}
2425
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002426static EGLint EGLAPIENTRY
2427eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002428 const EGLAttrib *attrib_list)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002429{
2430 unsigned int newEnabled;
2431
2432 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2433
2434 mtx_lock(_eglGlobal.Mutex);
2435
2436 newEnabled = _eglGlobal.debugTypesEnabled;
2437 if (attrib_list != NULL) {
2438 int i;
2439
2440 for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
Emil Velikov4df0d502017-09-07 17:03:53 +01002441 switch (attrib_list[i]) {
2442 case EGL_DEBUG_MSG_CRITICAL_KHR:
2443 case EGL_DEBUG_MSG_ERROR_KHR:
2444 case EGL_DEBUG_MSG_WARN_KHR:
2445 case EGL_DEBUG_MSG_INFO_KHR:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002446 if (attrib_list[i + 1])
2447 newEnabled |= DebugBitFromType(attrib_list[i]);
2448 else
2449 newEnabled &= ~DebugBitFromType(attrib_list[i]);
Emil Velikov4df0d502017-09-07 17:03:53 +01002450 break;
2451 default:
2452 // On error, set the last error code, call the current
2453 // debug callback, and return the error code.
2454 mtx_unlock(_eglGlobal.Mutex);
2455 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
2456 "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
2457 return EGL_BAD_ATTRIBUTE;
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002458 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002459 }
2460 }
2461
2462 if (callback != NULL) {
2463 _eglGlobal.debugCallback = callback;
2464 _eglGlobal.debugTypesEnabled = newEnabled;
2465 } else {
2466 _eglGlobal.debugCallback = NULL;
2467 _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
2468 }
2469
2470 mtx_unlock(_eglGlobal.Mutex);
2471 return EGL_SUCCESS;
2472}
2473
2474static EGLBoolean EGLAPIENTRY
2475eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
2476{
2477 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2478
2479 mtx_lock(_eglGlobal.Mutex);
2480
Emil Velikov4df0d502017-09-07 17:03:53 +01002481 switch (attribute) {
2482 case EGL_DEBUG_MSG_CRITICAL_KHR:
2483 case EGL_DEBUG_MSG_ERROR_KHR:
2484 case EGL_DEBUG_MSG_WARN_KHR:
2485 case EGL_DEBUG_MSG_INFO_KHR:
2486 if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
2487 *value = EGL_TRUE;
2488 else
2489 *value = EGL_FALSE;
2490 break;
2491 case EGL_DEBUG_CALLBACK_KHR:
2492 *value = (EGLAttrib) _eglGlobal.debugCallback;
2493 break;
2494 default:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002495 mtx_unlock(_eglGlobal.Mutex);
2496 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002497 "Invalid attribute 0x%04lx", (unsigned long) attribute);
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002498 return EGL_FALSE;
Emil Velikov4df0d502017-09-07 17:03:53 +01002499 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002500
2501 mtx_unlock(_eglGlobal.Mutex);
2502 return EGL_TRUE;
2503}
2504
Eric Engestrom1534fc62017-02-21 23:56:52 +00002505static int
2506_eglFunctionCompare(const void *key, const void *elem)
2507{
2508 const char *procname = key;
2509 const struct _egl_entrypoint *entrypoint = elem;
2510 return strcmp(procname, entrypoint->name);
2511}
2512
Varad Gautam6719e052017-05-30 17:23:38 +05302513static EGLBoolean EGLAPIENTRY
2514eglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats,
2515 EGLint *formats, EGLint *num_formats)
2516{
2517 _EGLDisplay *disp = _eglLockDisplay(dpy);
Varad Gautam6719e052017-05-30 17:23:38 +05302518 EGLBoolean ret;
2519
2520 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2521
Eric Engestromc74628f2020-08-03 22:50:42 +02002522 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Varad Gautam6719e052017-05-30 17:23:38 +05302523
Eric Engestrom5eb58472020-08-03 22:19:42 +02002524 ret = disp->Driver->QueryDmaBufFormatsEXT(disp, max_formats, formats, num_formats);
Varad Gautam6719e052017-05-30 17:23:38 +05302525
2526 RETURN_EGL_EVAL(disp, ret);
2527}
2528
Varad Gautamde3c4592017-05-30 17:23:39 +05302529static EGLBoolean EGLAPIENTRY
2530eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
2531 EGLuint64KHR *modifiers, EGLBoolean *external_only,
2532 EGLint *num_modifiers)
2533{
2534 _EGLDisplay *disp = _eglLockDisplay(dpy);
Varad Gautamde3c4592017-05-30 17:23:39 +05302535 EGLBoolean ret;
2536
2537 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2538
Eric Engestromc74628f2020-08-03 22:50:42 +02002539 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Varad Gautamde3c4592017-05-30 17:23:39 +05302540
Eric Engestrom5eb58472020-08-03 22:19:42 +02002541 ret = disp->Driver->QueryDmaBufModifiersEXT(disp, format, max_modifiers, modifiers,
Eric Engestrom1bbb0c72018-04-22 16:48:15 +02002542 external_only, num_modifiers);
Varad Gautamde3c4592017-05-30 17:23:39 +05302543
2544 RETURN_EGL_EVAL(disp, ret);
2545}
2546
Tapani Pälli6f5b5702017-12-28 10:51:11 +02002547static void EGLAPIENTRY
2548eglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
2549 EGLGetBlobFuncANDROID get)
2550{
2551 /* This function does not return anything so we cannot
2552 * utilize the helper macros _EGL_FUNC_START or _EGL_CHECK_DISPLAY.
2553 */
2554 _EGLDisplay *disp = _eglLockDisplay(dpy);
2555 if (!_eglSetFuncName(__func__, disp, EGL_OBJECT_DISPLAY_KHR, NULL)) {
2556 if (disp)
2557 _eglUnlockDisplay(disp);
2558 return;
2559 }
2560
Eric Engestromc74628f2020-08-03 22:50:42 +02002561 if (!_eglCheckDisplay(disp, __func__)) {
Tapani Pälli6f5b5702017-12-28 10:51:11 +02002562 if (disp)
2563 _eglUnlockDisplay(disp);
2564 return;
2565 }
2566
2567 if (!set || !get) {
2568 _eglError(EGL_BAD_PARAMETER,
2569 "eglSetBlobCacheFuncsANDROID: NULL handler given");
2570 _eglUnlockDisplay(disp);
2571 return;
2572 }
2573
2574 if (disp->BlobCacheSet) {
2575 _eglError(EGL_BAD_PARAMETER,
2576 "eglSetBlobCacheFuncsANDROID: functions already set");
2577 _eglUnlockDisplay(disp);
2578 return;
2579 }
2580
2581 disp->BlobCacheSet = set;
2582 disp->BlobCacheGet = get;
2583
Eric Engestrom5eb58472020-08-03 22:19:42 +02002584 disp->Driver->SetBlobCacheFuncsANDROID(disp, set, get);
Tapani Pälli6f5b5702017-12-28 10:51:11 +02002585
2586 _eglUnlockDisplay(disp);
2587}
2588
Emil Velikov7552fcb2015-07-24 16:19:55 +02002589static EGLBoolean EGLAPIENTRY
2590eglQueryDeviceAttribEXT(EGLDeviceEXT device,
2591 EGLint attribute,
2592 EGLAttrib *value)
2593{
2594 _EGLDevice *dev = _eglLookupDevice(device);
2595 EGLBoolean ret;
2596
2597 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2598 if (!dev)
2599 RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, EGL_FALSE);
2600
2601 ret = _eglQueryDeviceAttribEXT(dev, attribute, value);
2602 RETURN_EGL_EVAL(NULL, ret);
2603}
2604
2605static const char * EGLAPIENTRY
2606eglQueryDeviceStringEXT(EGLDeviceEXT device,
2607 EGLint name)
2608{
2609 _EGLDevice *dev = _eglLookupDevice(device);
2610
2611 _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2612 if (!dev)
2613 RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, NULL);
2614
2615 RETURN_EGL_EVAL(NULL, _eglQueryDeviceStringEXT(dev, name));
2616}
2617
2618static EGLBoolean EGLAPIENTRY
2619eglQueryDevicesEXT(EGLint max_devices,
2620 EGLDeviceEXT *devices,
2621 EGLint *num_devices)
2622{
2623 EGLBoolean ret;
2624
2625 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2626 ret = _eglQueryDevicesEXT(max_devices, (_EGLDevice **) devices,
2627 num_devices);
2628 RETURN_EGL_EVAL(NULL, ret);
2629}
2630
2631static EGLBoolean EGLAPIENTRY
2632eglQueryDisplayAttribEXT(EGLDisplay dpy,
2633 EGLint attribute,
2634 EGLAttrib *value)
2635{
2636 _EGLDisplay *disp = _eglLockDisplay(dpy);
Emil Velikov7552fcb2015-07-24 16:19:55 +02002637
2638 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
Eric Engestromc74628f2020-08-03 22:50:42 +02002639 _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
Emil Velikov7552fcb2015-07-24 16:19:55 +02002640
2641 switch (attribute) {
2642 case EGL_DEVICE_EXT:
2643 *value = (EGLAttrib) disp->Device;
2644 break;
2645 default:
2646 RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_FALSE);
2647 }
2648 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
2649}
2650
Veluri Mithun6afce782019-01-23 22:44:25 +05302651static char * EGLAPIENTRY
2652eglGetDisplayDriverConfig(EGLDisplay dpy)
2653{
2654 _EGLDisplay *disp = _eglLockDisplay(dpy);
Veluri Mithun6afce782019-01-23 22:44:25 +05302655 char *ret;
2656
2657 _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
Eric Engestromc74628f2020-08-03 22:50:42 +02002658 _EGL_CHECK_DISPLAY(disp, NULL);
Veluri Mithun6afce782019-01-23 22:44:25 +05302659
2660 assert(disp->Extensions.MESA_query_driver);
2661
Eric Engestrom5eb58472020-08-03 22:19:42 +02002662 ret = disp->Driver->QueryDriverConfig(disp);
Veluri Mithun6afce782019-01-23 22:44:25 +05302663 RETURN_EGL_EVAL(disp, ret);
2664}
2665
2666static const char * EGLAPIENTRY
2667eglGetDisplayDriverName(EGLDisplay dpy)
2668{
2669 _EGLDisplay *disp = _eglLockDisplay(dpy);
Veluri Mithun6afce782019-01-23 22:44:25 +05302670 const char *ret;
2671
2672 _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
Eric Engestromc74628f2020-08-03 22:50:42 +02002673 _EGL_CHECK_DISPLAY(disp, NULL);
Veluri Mithun6afce782019-01-23 22:44:25 +05302674
2675 assert(disp->Extensions.MESA_query_driver);
2676
Eric Engestrom5eb58472020-08-03 22:19:42 +02002677 ret = disp->Driver->QueryDriverName(disp);
Veluri Mithun6afce782019-01-23 22:44:25 +05302678 RETURN_EGL_EVAL(disp, ret);
2679}
2680
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002681__eglMustCastToProperFunctionPointerType EGLAPIENTRY
2682eglGetProcAddress(const char *procname)
2683{
Eric Engestrom1534fc62017-02-21 23:56:52 +00002684 static const struct _egl_entrypoint egl_functions[] = {
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002685#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
Eric Engestromf92fd4d2017-02-21 23:56:49 +00002686#include "eglentrypoint.h"
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002687#undef EGL_ENTRYPOINT
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002688 };
Eric Engestrom1534fc62017-02-21 23:56:52 +00002689 _EGLProc ret = NULL;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002690
2691 if (!procname)
2692 RETURN_EGL_SUCCESS(NULL, NULL);
2693
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002694 _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2695
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002696 if (strncmp(procname, "egl", 3) == 0) {
Eric Engestrom1534fc62017-02-21 23:56:52 +00002697 const struct _egl_entrypoint *entrypoint =
2698 bsearch(procname,
2699 egl_functions, ARRAY_SIZE(egl_functions),
2700 sizeof(egl_functions[0]),
2701 _eglFunctionCompare);
2702 if (entrypoint)
2703 ret = entrypoint->function;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002704 }
Eric Engestrom1534fc62017-02-21 23:56:52 +00002705
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002706 if (!ret)
2707 ret = _eglGetDriverProc(procname);
2708
2709 RETURN_EGL_SUCCESS(NULL, ret);
2710}
Marek Olšákb6eda702016-03-03 15:59:48 +01002711
2712static int
2713_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
Eric Engestrom37be01b2020-08-03 22:48:10 +02002714 _EGLDisplay **disp, _EGLContext **ctx)
Marek Olšákb6eda702016-03-03 15:59:48 +01002715{
2716
2717 *disp = _eglLockDisplay(dpy);
2718 if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
2719 if (*disp)
2720 _eglUnlockDisplay(*disp);
2721 return MESA_GLINTEROP_INVALID_DISPLAY;
2722 }
2723
Marek Olšákb6eda702016-03-03 15:59:48 +01002724 *ctx = _eglLookupContext(context, *disp);
2725 if (!*ctx ||
2726 ((*ctx)->ClientAPI != EGL_OPENGL_API &&
2727 (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
2728 _eglUnlockDisplay(*disp);
2729 return MESA_GLINTEROP_INVALID_CONTEXT;
2730 }
2731
2732 return MESA_GLINTEROP_SUCCESS;
2733}
2734
Marek Olšákee39d442016-11-02 18:59:22 +01002735PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002736MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002737 struct mesa_glinterop_device_info *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002738{
2739 _EGLDisplay *disp;
Marek Olšákb6eda702016-03-03 15:59:48 +01002740 _EGLContext *ctx;
2741 int ret;
2742
Eric Engestrom37be01b2020-08-03 22:48:10 +02002743 ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx);
Marek Olšákb6eda702016-03-03 15:59:48 +01002744 if (ret != MESA_GLINTEROP_SUCCESS)
2745 return ret;
2746
Eric Engestrom5eb58472020-08-03 22:19:42 +02002747 if (disp->Driver->GLInteropQueryDeviceInfo)
2748 ret = disp->Driver->GLInteropQueryDeviceInfo(disp, ctx, out);
Marek Olšákb6eda702016-03-03 15:59:48 +01002749 else
2750 ret = MESA_GLINTEROP_UNSUPPORTED;
2751
2752 _eglUnlockDisplay(disp);
2753 return ret;
2754}
2755
Marek Olšákee39d442016-11-02 18:59:22 +01002756PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002757MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002758 struct mesa_glinterop_export_in *in,
2759 struct mesa_glinterop_export_out *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002760{
2761 _EGLDisplay *disp;
Marek Olšákb6eda702016-03-03 15:59:48 +01002762 _EGLContext *ctx;
2763 int ret;
2764
Eric Engestrom37be01b2020-08-03 22:48:10 +02002765 ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx);
Marek Olšákb6eda702016-03-03 15:59:48 +01002766 if (ret != MESA_GLINTEROP_SUCCESS)
2767 return ret;
2768
Eric Engestrom5eb58472020-08-03 22:19:42 +02002769 if (disp->Driver->GLInteropExportObject)
2770 ret = disp->Driver->GLInteropExportObject(disp, ctx, in, out);
Marek Olšákb6eda702016-03-03 15:59:48 +01002771 else
2772 ret = MESA_GLINTEROP_UNSUPPORTED;
2773
2774 _eglUnlockDisplay(disp);
2775 return ret;
2776}