blob: 4585540437b72518ae280f3790f6acc1b801d417 [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 "eglapi.h"
100#include "egldefines.h"
Chad Versace3c58d4c2013-10-11 16:04:55 -0700101#include "eglglobals.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000102#include "eglcontext.h"
103#include "egldisplay.h"
104#include "egltypedefs.h"
Chia-I Wu94cb3212010-01-29 09:00:30 +0800105#include "eglcurrent.h"
Emil Velikov7552fcb2015-07-24 16:19:55 +0200106#include "egldevice.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000107#include "egldriver.h"
108#include "eglsurface.h"
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800109#include "eglconfig.h"
Chia-I Wua1c4a8a2009-08-15 22:58:13 +0800110#include "eglimage.h"
Chia-I Wu4eebea72010-08-14 23:09:12 +0800111#include "eglsync.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000112
Matt Turner4e970842017-07-06 18:40:53 -0700113#include "GL/mesa_glinterop.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000114
115/**
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800116 * Macros to help return an API entrypoint.
Chia-I Wu655f4652010-02-17 17:30:44 +0800117 *
118 * These macros will unlock the display and record the error code.
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800119 */
Chia-I Wubef4b472010-02-19 12:08:50 +0800120#define RETURN_EGL_ERROR(disp, err, ret) \
121 do { \
Chia-I Wu655f4652010-02-17 17:30:44 +0800122 if (disp) \
123 _eglUnlockDisplay(disp); \
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800124 /* EGL error codes are non-zero */ \
125 if (err) \
Emil Velikovd7800122015-02-28 16:39:10 +0000126 _eglError(err, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800127 return ret; \
128 } while (0)
129
130#define RETURN_EGL_SUCCESS(disp, ret) \
131 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
132
Chia-I Wub3bb1802010-02-17 16:05:27 +0800133/* record EGL_SUCCESS only when ret evaluates to true */
Chia-I Wubef4b472010-02-19 12:08:50 +0800134#define RETURN_EGL_EVAL(disp, ret) \
135 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800136
137
Chia-I Wubef4b472010-02-19 12:08:50 +0800138/*
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800139 * A bunch of macros and checks to simplify error checking.
140 */
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800141
Chia-I Wubef4b472010-02-19 12:08:50 +0800142#define _EGL_CHECK_DISPLAY(disp, ret, drv) \
143 do { \
Emil Velikovd7800122015-02-28 16:39:10 +0000144 drv = _eglCheckDisplay(disp, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800145 if (!drv) \
146 RETURN_EGL_ERROR(disp, 0, ret); \
147 } while (0)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800148
Chia-I Wubef4b472010-02-19 12:08:50 +0800149#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
150 do { \
Emil Velikovd7800122015-02-28 16:39:10 +0000151 drv = _eglCheck ## type(disp, obj, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800152 if (!drv) \
153 RETURN_EGL_ERROR(disp, 0, ret); \
154 } while (0)
155
156#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
157 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
158
159#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
160 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
161
162#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
163 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
164
Chia-I Wu4eebea72010-08-14 23:09:12 +0800165#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
166 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800167
168
Eric Engestrom1534fc62017-02-21 23:56:52 +0000169struct _egl_entrypoint {
170 const char *name;
171 _EGLProc function;
172};
173
174
Emil Velikov7bd16932015-02-28 16:35:22 +0000175static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800176_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
177{
178 if (!disp) {
179 _eglError(EGL_BAD_DISPLAY, msg);
180 return NULL;
181 }
182 if (!disp->Initialized) {
183 _eglError(EGL_NOT_INITIALIZED, msg);
184 return NULL;
185 }
186 return disp->Driver;
187}
188
189
Emil Velikov7bd16932015-02-28 16:35:22 +0000190static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800191_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
192{
193 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
194 if (!drv)
195 return NULL;
196 if (!surf) {
197 _eglError(EGL_BAD_SURFACE, msg);
198 return NULL;
199 }
200 return drv;
201}
202
203
Emil Velikov7bd16932015-02-28 16:35:22 +0000204static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800205_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
206{
207 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
208 if (!drv)
209 return NULL;
210 if (!context) {
211 _eglError(EGL_BAD_CONTEXT, msg);
212 return NULL;
213 }
214 return drv;
215}
216
217
Emil Velikov7bd16932015-02-28 16:35:22 +0000218static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800219_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
220{
221 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
222 if (!drv)
223 return NULL;
224 if (!conf) {
225 _eglError(EGL_BAD_CONFIG, msg);
226 return NULL;
227 }
228 return drv;
229}
230
231
Emil Velikov7bd16932015-02-28 16:35:22 +0000232static inline _EGLDriver *
Chia-I Wu4eebea72010-08-14 23:09:12 +0800233_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
234{
235 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
236 if (!drv)
237 return NULL;
238 if (!s) {
239 _eglError(EGL_BAD_PARAMETER, msg);
240 return NULL;
241 }
242 return drv;
243}
244
245
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800246/**
Chia-I Wu655f4652010-02-17 17:30:44 +0800247 * Lookup and lock a display.
248 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000249static inline _EGLDisplay *
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000250_eglLockDisplay(EGLDisplay dpy)
Chia-I Wu655f4652010-02-17 17:30:44 +0800251{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000252 _EGLDisplay *disp = _eglLookupDisplay(dpy);
253 if (disp)
254 mtx_lock(&disp->Mutex);
255 return disp;
Chia-I Wu655f4652010-02-17 17:30:44 +0800256}
257
258
259/**
260 * Unlock a display.
261 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000262static inline void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000263_eglUnlockDisplay(_EGLDisplay *disp)
Chia-I Wu655f4652010-02-17 17:30:44 +0800264{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000265 mtx_unlock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +0800266}
267
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400268static EGLBoolean
269_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
270{
271 _EGLThreadInfo *thr = _eglGetCurrentThread();
272 if (!_eglIsCurrentThreadDummy()) {
273 thr->CurrentFuncName = funcName;
274 thr->CurrentObjectLabel = NULL;
275
276 if (objectType == EGL_OBJECT_THREAD_KHR)
277 thr->CurrentObjectLabel = thr->Label;
278 else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
279 thr->CurrentObjectLabel = disp->Label;
280 else if (object)
281 thr->CurrentObjectLabel = object->Label;
282
283 return EGL_TRUE;
284 }
285
Emil Velikovb94344f2017-09-07 17:03:50 +0100286 _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400287 return EGL_FALSE;
288}
289
290#define _EGL_FUNC_START(disp, objectType, object, ret) \
291 do { \
292 if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
293 if (disp) \
294 _eglUnlockDisplay(disp); \
295 return ret; \
296 } \
297 } while(0)
Chia-I Wu655f4652010-02-17 17:30:44 +0800298
Chad Versace3e0d5752016-09-27 13:27:17 -0700299/**
300 * Convert an attribute list from EGLint[] to EGLAttrib[].
301 *
302 * Return an EGL error code. The output parameter out_attrib_list is modified
303 * only on success.
304 */
Eric Engestrom9e1d35c2016-12-08 00:36:03 +0000305static EGLint
Chad Versace3e0d5752016-09-27 13:27:17 -0700306_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
307{
308 size_t len = 0;
309 EGLAttrib *attrib_list;
310
311 if (int_list) {
312 while (int_list[2*len] != EGL_NONE)
313 ++len;
314 }
315
316 if (len == 0) {
317 *out_attrib_list = NULL;
318 return EGL_SUCCESS;
319 }
320
321 if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
322 return EGL_BAD_ALLOC;
323
324 attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
325 if (!attrib_list)
326 return EGL_BAD_ALLOC;
327
328 for (size_t i = 0; i < len; ++i) {
329 attrib_list[2*i + 0] = int_list[2*i + 0];
330 attrib_list[2*i + 1] = int_list[2*i + 1];
331 }
332
333 attrib_list[2*len] = EGL_NONE;
334
335 *out_attrib_list = attrib_list;
336 return EGL_SUCCESS;
337}
338
339
Marek Olšák515f04e2015-05-12 20:42:05 +0200340static EGLint *
341_eglConvertAttribsToInt(const EGLAttrib *attr_list)
342{
Emil Velikov72b9aa92019-05-16 18:01:33 +0100343 size_t size = _eglNumAttribs(attr_list);
Marek Olšák515f04e2015-05-12 20:42:05 +0200344 EGLint *int_attribs = NULL;
345
346 /* Convert attributes from EGLAttrib[] to EGLint[] */
Emil Velikov72b9aa92019-05-16 18:01:33 +0100347 if (size) {
Marek Olšák515f04e2015-05-12 20:42:05 +0200348 int_attribs = calloc(size, sizeof(int_attribs[0]));
349 if (!int_attribs)
350 return NULL;
351
Emil Velikov72b9aa92019-05-16 18:01:33 +0100352 for (size_t i = 0; i < size; i++)
Marek Olšák515f04e2015-05-12 20:42:05 +0200353 int_attribs[i] = attr_list[i];
354 }
355 return int_attribs;
356}
357
358
Chia-I Wu655f4652010-02-17 17:30:44 +0800359/**
Brian Paul6052af12008-05-27 16:48:23 -0600360 * This is typically the first EGL function that an application calls.
Chia-I Wudb5ce8b2010-02-17 18:39:27 +0800361 * It associates a private _EGLDisplay object to the native display.
Brian Pauladbff7e2005-04-22 21:09:39 +0000362 */
Brian Paul1ed10272008-05-27 13:45:41 -0600363EGLDisplay EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +0800364eglGetDisplay(EGLNativeDisplayType nativeDisplay)
Brian Pauladbff7e2005-04-22 21:09:39 +0000365{
Chad Versace6d1f83e2014-01-07 14:54:51 -0800366 _EGLPlatformType plat;
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000367 _EGLDisplay *disp;
Chad Versace6d1f83e2014-01-07 14:54:51 -0800368 void *native_display_ptr;
369
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400370 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
371
Chad Versace6d1f83e2014-01-07 14:54:51 -0800372 STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
373 native_display_ptr = (void*) nativeDisplay;
374
375 plat = _eglGetNativePlatform(native_display_ptr);
Adam Jackson8e991ce2019-05-16 18:01:34 +0100376 disp = _eglFindDisplay(plat, native_display_ptr, NULL);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000377 return _eglGetDisplayHandle(disp);
Brian Pauladbff7e2005-04-22 21:09:39 +0000378}
379
Kyle Brenneman017946b2016-09-12 16:42:56 -0400380static EGLDisplay
381_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500382 const EGLAttrib *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -0800383{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000384 _EGLDisplay *disp;
Chad Versace468cc862014-01-23 07:26:10 -0800385
386 switch (platform) {
387#ifdef HAVE_X11_PLATFORM
388 case EGL_PLATFORM_X11_EXT:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000389 disp = _eglGetX11Display((Display*) native_display, attrib_list);
Chad Versace468cc862014-01-23 07:26:10 -0800390 break;
391#endif
392#ifdef HAVE_DRM_PLATFORM
393 case EGL_PLATFORM_GBM_MESA:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000394 disp = _eglGetGbmDisplay((struct gbm_device*) native_display,
Chad Versace468cc862014-01-23 07:26:10 -0800395 attrib_list);
396 break;
397#endif
398#ifdef HAVE_WAYLAND_PLATFORM
399 case EGL_PLATFORM_WAYLAND_EXT:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000400 disp = _eglGetWaylandDisplay((struct wl_display*) native_display,
Chad Versace468cc862014-01-23 07:26:10 -0800401 attrib_list);
402 break;
403#endif
Chad Versacea597c8a2016-10-12 15:48:15 -0700404#ifdef HAVE_SURFACELESS_PLATFORM
405 case EGL_PLATFORM_SURFACELESS_MESA:
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000406 disp = _eglGetSurfacelessDisplay(native_display, attrib_list);
Chad Versacea597c8a2016-10-12 15:48:15 -0700407 break;
408#endif
Emil Velikovd6edcce2019-05-16 18:01:40 +0100409 case EGL_PLATFORM_DEVICE_EXT:
410 disp = _eglGetDeviceDisplay(native_display, attrib_list);
411 break;
Chad Versace468cc862014-01-23 07:26:10 -0800412 default:
413 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
414 }
415
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000416 return _eglGetDisplayHandle(disp);
Chad Versace468cc862014-01-23 07:26:10 -0800417}
Brian Pauladbff7e2005-04-22 21:09:39 +0000418
Kyle Brenneman017946b2016-09-12 16:42:56 -0400419static EGLDisplay EGLAPIENTRY
420eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500421 const EGLint *int_attribs)
Kyle Brenneman017946b2016-09-12 16:42:56 -0400422{
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500423 EGLAttrib *attrib_list;
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000424 EGLDisplay disp;
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500425
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400426 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500427
428 if (_eglConvertIntsToAttribs(int_attribs, &attrib_list) != EGL_SUCCESS)
429 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
430
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000431 disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500432 free(attrib_list);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000433 return disp;
Kyle Brenneman017946b2016-09-12 16:42:56 -0400434}
435
Marek Olšák820a4d42015-05-12 21:06:41 +0200436EGLDisplay EGLAPIENTRY
437eglGetPlatformDisplay(EGLenum platform, void *native_display,
438 const EGLAttrib *attrib_list)
439{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400440 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500441 return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +0200442}
443
Brian Paul6052af12008-05-27 16:48:23 -0600444/**
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700445 * Copy the extension into the string and update the string pointer.
446 */
447static EGLint
448_eglAppendExtension(char **str, const char *ext)
449{
450 char *s = *str;
451 size_t len = strlen(ext);
452
453 if (s) {
454 memcpy(s, ext, len);
455 s[len++] = ' ';
456 s[len] = '\0';
457
458 *str += len;
459 }
460 else {
461 len++;
462 }
463
464 return (EGLint) len;
465}
466
467/**
468 * Examine the individual extension enable/disable flags and recompute
469 * the driver's Extensions string.
470 */
471static void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000472_eglCreateExtensionsString(_EGLDisplay *disp)
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700473{
474#define _EGL_CHECK_EXTENSION(ext) \
475 do { \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000476 if (disp->Extensions.ext) { \
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700477 _eglAppendExtension(&exts, "EGL_" #ext); \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000478 assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700479 } \
480 } while (0)
481
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000482 char *exts = disp->ExtensionsString;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700483
Marek Olšák32aa1d72015-06-09 23:08:57 +0200484 /* Please keep these sorted alphabetically. */
Tapani Pälli6f5b5702017-12-28 10:51:11 +0200485 _EGL_CHECK_EXTENSION(ANDROID_blob_cache);
Rob Herring89755272016-02-02 14:23:07 -0600486 _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700487 _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
Rob Clark0201f012016-11-18 08:39:33 -0500488 _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
Rob Herringe21e81a2016-02-02 14:23:08 -0600489 _EGL_CHECK_EXTENSION(ANDROID_recordable);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700490
491 _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
492
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700493 _EGL_CHECK_EXTENSION(EXT_buffer_age);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200494 _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700495 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
Varad Gautam4c412292017-05-30 17:23:40 +0530496 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
Tapani Pälli799b3d12018-04-05 13:02:36 +0300497 _EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
498 _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200499 _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
500
Chris Wilson95ecf3d2016-10-27 19:34:46 +0100501 _EGL_CHECK_EXTENSION(IMG_context_priority);
502
Marek Olšák32aa1d72015-06-09 23:08:57 +0200503 _EGL_CHECK_EXTENSION(KHR_cl_event2);
Emil Velikov26541a12016-12-05 14:42:04 +0000504 _EGL_CHECK_EXTENSION(KHR_config_attribs);
Adam Jacksonc0be3aa2016-09-22 03:47:55 -0400505 _EGL_CHECK_EXTENSION(KHR_context_flush_control);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200506 _EGL_CHECK_EXTENSION(KHR_create_context);
Grigori Goronzy49095192017-06-29 02:44:03 +0200507 _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200508 _EGL_CHECK_EXTENSION(KHR_fence_sync);
509 _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
510 _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
511 _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
512 _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
513 _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
514 _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000515 if (disp->Extensions.KHR_image_base && disp->Extensions.KHR_image_pixmap)
516 disp->Extensions.KHR_image = EGL_TRUE;
Harish Krupo96fc5fb2017-12-08 21:29:39 +0530517 _EGL_CHECK_EXTENSION(KHR_image);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200518 _EGL_CHECK_EXTENSION(KHR_image_base);
519 _EGL_CHECK_EXTENSION(KHR_image_pixmap);
Chad Versace3dc22382018-04-30 22:32:25 -0700520 _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
Adam Jacksond9f5b192016-09-09 12:25:34 -0400521 _EGL_CHECK_EXTENSION(KHR_no_config_context);
Harish Krupo98275472017-06-09 20:13:34 +0530522 _EGL_CHECK_EXTENSION(KHR_partial_update);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200523 _EGL_CHECK_EXTENSION(KHR_reusable_sync);
524 _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000525 if (disp->Extensions.EXT_swap_buffers_with_damage)
Eric Engestrom0a606a42016-10-10 17:33:17 +0100526 _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
Tapani Pälli41f7de42017-10-31 10:57:42 +0200527 _EGL_CHECK_EXTENSION(EXT_pixel_format_float);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200528 _EGL_CHECK_EXTENSION(KHR_wait_sync);
529
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000530 if (disp->Extensions.KHR_no_config_context)
Adam Jacksond9f5b192016-09-09 12:25:34 -0400531 _eglAppendExtension(&exts, "EGL_MESA_configless_context");
Marek Olšák32aa1d72015-06-09 23:08:57 +0200532 _EGL_CHECK_EXTENSION(MESA_drm_image);
533 _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
Veluri Mithun6afce782019-01-23 22:44:25 +0530534 _EGL_CHECK_EXTENSION(MESA_query_driver);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200535
536 _EGL_CHECK_EXTENSION(NOK_swap_region);
537 _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700538
539 _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
Dave Airlie8f7338f2014-03-03 13:57:16 +1000540
Marek Olšák32aa1d72015-06-09 23:08:57 +0200541 _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
542 _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
543
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700544#undef _EGL_CHECK_EXTENSION
545}
546
547static void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000548_eglCreateAPIsString(_EGLDisplay *disp)
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700549{
Eric Engestromaa78b292018-08-16 15:31:55 +0100550#define addstr(str) \
551 { \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000552 const size_t old_len = strlen(disp->ClientAPIsString); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100553 const size_t add_len = sizeof(str); \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000554 const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \
Eric Engestromaa78b292018-08-16 15:31:55 +0100555 if (old_len + add_len <= max_len) \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000556 strcat(disp->ClientAPIsString, str " "); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100557 else \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000558 assert(!"disp->ClientAPIsString is not large enough"); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100559 }
560
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000561 if (disp->ClientAPIs & EGL_OPENGL_BIT)
Eric Engestromaa78b292018-08-16 15:31:55 +0100562 addstr("OpenGL");
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700563
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000564 if (disp->ClientAPIs & EGL_OPENGL_ES_BIT ||
565 disp->ClientAPIs & EGL_OPENGL_ES2_BIT ||
566 disp->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
Eric Engestromaa78b292018-08-16 15:31:55 +0100567 addstr("OpenGL_ES");
Plamena Manolova21edd242016-05-12 18:21:38 +0100568 }
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700569
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000570 if (disp->ClientAPIs & EGL_OPENVG_BIT)
Eric Engestromaa78b292018-08-16 15:31:55 +0100571 addstr("OpenVG");
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700572
Eric Engestromaa78b292018-08-16 15:31:55 +0100573#undef addstr
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700574}
575
Marek Olšákefda9c52015-05-11 22:16:52 +0200576static void
577_eglComputeVersion(_EGLDisplay *disp)
578{
Marek Olšák0e4b5642015-05-12 16:40:29 +0200579 disp->Version = 14;
Marek Olšáka1cb4072015-05-11 22:18:04 +0200580
581 if (disp->Extensions.KHR_fence_sync &&
582 disp->Extensions.KHR_cl_event2 &&
583 disp->Extensions.KHR_wait_sync &&
584 disp->Extensions.KHR_image_base &&
585 disp->Extensions.KHR_gl_texture_2D_image &&
586 disp->Extensions.KHR_gl_texture_3D_image &&
587 disp->Extensions.KHR_gl_texture_cubemap_image &&
588 disp->Extensions.KHR_gl_renderbuffer_image &&
589 disp->Extensions.KHR_create_context &&
590 disp->Extensions.EXT_create_context_robustness &&
591 disp->Extensions.KHR_get_all_proc_addresses &&
592 disp->Extensions.KHR_gl_colorspace &&
593 disp->Extensions.KHR_surfaceless_context)
594 disp->Version = 15;
Marek Olšákefda9c52015-05-11 22:16:52 +0200595}
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700596
597/**
Brian Paul6052af12008-05-27 16:48:23 -0600598 * This is typically the second EGL function that an application calls.
599 * Here we load/initialize the actual hardware driver.
600 */
Brian Paul1ed10272008-05-27 13:45:41 -0600601EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000602eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
603{
Chia-I Wu655f4652010-02-17 17:30:44 +0800604 _EGLDisplay *disp = _eglLockDisplay(dpy);
Jonathan White7e2458c2008-08-06 13:40:03 -0600605
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400606 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
607
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800608 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800609 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Brian Paulc56e15b2008-05-28 15:43:41 -0600610
Chia-I Wua9332592010-01-27 23:55:58 +0800611 if (!disp->Initialized) {
Eric Engestromd7e769a2017-10-18 16:31:23 +0100612 if (!_eglMatchDriver(disp))
Chia-I Wuf2aa3612010-07-04 15:55:12 +0800613 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
Chia-I Wu57929ed2010-01-19 18:29:21 +0800614
Chia-I Wu310c7682009-08-17 15:53:54 +0800615 /* limit to APIs supported by core */
Chia-I Wua4a38dc2011-01-13 16:53:13 +0800616 disp->ClientAPIs &= _EGL_API_ALL_BITS;
Chad Versace7e8ba772014-11-20 10:26:38 -0800617
618 /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
619 * classifies it as an EGL display extension, though conceptually it's an
620 * EGL client extension.
621 *
622 * From the EGL_KHR_get_all_proc_addresses spec:
623 *
624 * The EGL implementation must expose the name
625 * EGL_KHR_client_get_all_proc_addresses if and only if it exposes
626 * EGL_KHR_get_all_proc_addresses and supports
627 * EGL_EXT_client_extensions.
628 *
629 * Mesa unconditionally exposes both client extensions mentioned above,
630 * so the spec requires that each EGLDisplay unconditionally expose
631 * EGL_KHR_get_all_proc_addresses also.
632 */
633 disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700634
Emil Velikov26541a12016-12-05 14:42:04 +0000635 /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
636 * programs. It is driver agnostic and handled in the main EGL code.
637 */
638 disp->Extensions.KHR_config_attribs = EGL_TRUE;
639
Marek Olšákefda9c52015-05-11 22:16:52 +0200640 _eglComputeVersion(disp);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700641 _eglCreateExtensionsString(disp);
642 _eglCreateAPIsString(disp);
Emil Velikov3593f372015-07-14 00:19:54 +0100643 snprintf(disp->VersionString, sizeof(disp->VersionString),
Eric Engestroma96749b2017-10-18 16:32:33 +0100644 "%d.%d", disp->Version / 10, disp->Version % 10);
Brian Pauladbff7e2005-04-22 21:09:39 +0000645 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800646
647 /* Update applications version of major and minor if not NULL */
648 if ((major != NULL) && (minor != NULL)) {
Marek Olšák0e4b5642015-05-12 16:40:29 +0200649 *major = disp->Version / 10;
650 *minor = disp->Version % 10;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800651 }
652
Chia-I Wubef4b472010-02-19 12:08:50 +0800653 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000654}
655
656
Brian Paul1ed10272008-05-27 13:45:41 -0600657EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000658eglTerminate(EGLDisplay dpy)
659{
Chia-I Wu655f4652010-02-17 17:30:44 +0800660 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800661
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400662 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
663
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800664 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800665 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800666
Chia-I Wua9332592010-01-27 23:55:58 +0800667 if (disp->Initialized) {
668 _EGLDriver *drv = disp->Driver;
669
Chia-I Wuccc2b0b2009-08-13 13:39:51 +0800670 drv->API.Terminate(drv, disp);
Chia-I Wua9332592010-01-27 23:55:58 +0800671 /* do not reset disp->Driver */
Dave Airlie37e3a112015-03-16 15:21:55 +1000672 disp->ClientAPIsString[0] = 0;
Chia-I Wua9332592010-01-27 23:55:58 +0800673 disp->Initialized = EGL_FALSE;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800674 }
675
Chia-I Wubef4b472010-02-19 12:08:50 +0800676 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000677}
678
679
Brian Paul1ed10272008-05-27 13:45:41 -0600680const char * EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000681eglQueryString(EGLDisplay dpy, EGLint name)
682{
Chad Versace3c58d4c2013-10-11 16:04:55 -0700683 _EGLDisplay *disp;
Chia-I Wuaed73582010-02-17 15:43:47 +0800684 _EGLDriver *drv;
685
Chad Versace3c58d4c2013-10-11 16:04:55 -0700686 if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
Kyle Brennemance562f92017-01-04 11:31:58 -0700687 const char *ret = _eglGetClientExtensionString();
688 if (ret != NULL)
689 RETURN_EGL_SUCCESS(NULL, ret);
690 else
691 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
Chad Versace3c58d4c2013-10-11 16:04:55 -0700692 }
693
694 disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400695 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
Chia-I Wubef4b472010-02-19 12:08:50 +0800696 _EGL_CHECK_DISPLAY(disp, NULL, drv);
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 Wuaed73582010-02-17 15:43:47 +0800718 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800719 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800720
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400721 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
722
Chia-I Wubef4b472010-02-19 12:08:50 +0800723 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Eric Engestrom64c7c052019-01-08 11:14:35 +0000724
725 if (!num_config)
726 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
727
Eric Engestromb883d7f2019-06-22 22:29:46 +0100728 if (drv->API.GetConfigs)
729 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
730 else
731 ret = _eglGetConfigs(drv, disp, configs, config_size, num_config);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800732
Chia-I Wubef4b472010-02-19 12:08:50 +0800733 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000734}
735
736
Brian Paul1ed10272008-05-27 13:45:41 -0600737EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800738eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
739 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000740{
Chia-I Wu655f4652010-02-17 17:30:44 +0800741 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800742 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800743 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800744
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400745 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
746
Chia-I Wubef4b472010-02-19 12:08:50 +0800747 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Eric Engestrom64c7c052019-01-08 11:14:35 +0000748
749 if (!num_config)
750 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
751
Eric Engestrom1b76cca2019-06-22 22:30:23 +0100752 if (drv->API.ChooseConfig)
753 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
754 config_size, num_config);
755 else
756 ret = _eglChooseConfig(drv, disp, attrib_list, configs,
757 config_size, num_config);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800758
Chia-I Wubef4b472010-02-19 12:08:50 +0800759 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000760}
761
762
Brian Paul1ed10272008-05-27 13:45:41 -0600763EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800764eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
765 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000766{
Chia-I Wu655f4652010-02-17 17:30:44 +0800767 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800768 _EGLConfig *conf = _eglLookupConfig(config, disp);
769 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800770 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800771
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400772 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
773
Chia-I Wubef4b472010-02-19 12:08:50 +0800774 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
Eric Engestrom7f848f92019-06-22 22:31:00 +0100775
776 if (drv->API.GetConfigAttrib)
777 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
778 else
779 ret = _eglGetConfigAttrib(drv, disp, conf, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800780
Chia-I Wubef4b472010-02-19 12:08:50 +0800781 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000782}
783
784
Brian Paul1ed10272008-05-27 13:45:41 -0600785EGLContext EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800786eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
787 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000788{
Chia-I Wu655f4652010-02-17 17:30:44 +0800789 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800790 _EGLConfig *conf = _eglLookupConfig(config, disp);
791 _EGLContext *share = _eglLookupContext(share_list, disp);
792 _EGLDriver *drv;
793 _EGLContext *context;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800794 EGLContext ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800795
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400796 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
797
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800798 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
799
Tapani Pälli5876f3c2016-10-20 14:11:16 +0300800 if (config != EGL_NO_CONFIG_KHR)
801 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
802 else if (!disp->Extensions.KHR_no_config_context)
Neil Roberts4b17dff2014-03-07 18:05:46 +0000803 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
Kristian Høgsbergb90a3e72010-06-02 22:48:06 -0400804
Chia-I Wub3bb1802010-02-17 16:05:27 +0800805 if (!share && share_list != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800806 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800807
808 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +0800809 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800810
Chia-I Wubef4b472010-02-19 12:08:50 +0800811 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000812}
813
814
Brian Paul1ed10272008-05-27 13:45:41 -0600815EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000816eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
817{
Chia-I Wu655f4652010-02-17 17:30:44 +0800818 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800819 _EGLContext *context = _eglLookupContext(ctx, disp);
820 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800821 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800822
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400823 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
824
Chia-I Wubef4b472010-02-19 12:08:50 +0800825 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800826 _eglUnlinkContext(context);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800827 ret = drv->API.DestroyContext(drv, disp, context);
828
Chia-I Wubef4b472010-02-19 12:08:50 +0800829 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000830}
831
832
Brian Paul1ed10272008-05-27 13:45:41 -0600833EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800834eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
835 EGLContext ctx)
Brian Pauladbff7e2005-04-22 21:09:39 +0000836{
Chia-I Wu655f4652010-02-17 17:30:44 +0800837 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800838 _EGLContext *context = _eglLookupContext(ctx, disp);
839 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
840 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
841 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800842 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800843
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400844 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
845
Chia-I Wu17330472010-01-27 23:51:54 +0800846 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800847 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800848 drv = disp->Driver;
849
850 /* display is allowed to be uninitialized under certain condition */
851 if (!disp->Initialized) {
852 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
853 ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800854 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800855 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800856 if (!drv)
Chia-I Wubef4b472010-02-19 12:08:50 +0800857 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Chia-I Wu17330472010-01-27 23:51:54 +0800858
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800859 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800860 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800861 if (!draw_surf || !read_surf) {
Beren Minor0ca0d572014-03-20 08:36:34 +0100862 /* From the EGL 1.4 (20130211) spec:
863 *
864 * To release the current context without assigning a new one, set ctx
865 * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
866 */
867 if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800868 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
869
870 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
871 (!read_surf && read != EGL_NO_SURFACE))
872 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
873 if (draw_surf || read_surf)
874 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
875 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800876
Chad Versace23c86c72017-05-04 17:46:33 -0700877 /* If a native window underlying either draw or read is no longer valid,
878 * an EGL_BAD_NATIVE_WINDOW error is generated.
879 */
880 if (draw_surf && draw_surf->Lost)
881 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
882 if (read_surf && read_surf->Lost)
883 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
884
Chia-I Wub3bb1802010-02-17 16:05:27 +0800885 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
886
Chia-I Wubef4b472010-02-19 12:08:50 +0800887 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000888}
889
890
Brian Paul1ed10272008-05-27 13:45:41 -0600891EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800892eglQueryContext(EGLDisplay dpy, EGLContext ctx,
893 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000894{
Chia-I Wu655f4652010-02-17 17:30:44 +0800895 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800896 _EGLContext *context = _eglLookupContext(ctx, disp);
897 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800898 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800899
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400900 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
901
Chia-I Wubef4b472010-02-19 12:08:50 +0800902 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Eric Engestromb792b3e2019-06-22 22:31:26 +0100903
904 if (drv->API.QueryContext)
905 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
906 else
907 ret = _eglQueryContext(drv, disp, context, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800908
Chia-I Wubef4b472010-02-19 12:08:50 +0800909 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000910}
911
912
Paulo Zanoni73055ae2019-05-01 16:26:47 -0700913/* In EGL specs 1.4 and 1.5, at the end of sections 3.5.1 and 3.5.4, it says
914 * that if native_surface was already used to create a window or pixmap, we
915 * can't create a new one. This is what this function checks for.
916 */
917static bool
918_eglNativeSurfaceAlreadyUsed(_EGLDisplay *disp, void *native_surface)
919{
920 _EGLResource *list;
921
922 list = disp->ResourceLists[_EGL_RESOURCE_SURFACE];
923 while (list) {
924 _EGLSurface *surf = (_EGLSurface *) list;
925
926 list = list->Next;
927
928 if (surf->Type == EGL_PBUFFER_BIT)
929 continue;
930
931 if (surf->NativeSurface == native_surface)
932 return true;
933 }
934
935 return false;
936}
937
938
Chad Versace468cc862014-01-23 07:26:10 -0800939static EGLSurface
940_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
941 void *native_window, const EGLint *attrib_list)
942{
943 _EGLConfig *conf = _eglLookupConfig(config, disp);
944 _EGLDriver *drv;
945 _EGLSurface *surf;
946 EGLSurface ret;
947
Sinclair Yeh91ff0d42014-06-03 14:00:13 -0700948
949 if (native_window == NULL)
950 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
951
Emil Velikovd6edcce2019-05-16 18:01:40 +0100952 if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
953 disp->Platform == _EGL_PLATFORM_DEVICE)) {
Chad Versacea597c8a2016-10-12 15:48:15 -0700954 /* From the EGL_MESA_platform_surfaceless spec (v1):
955 *
956 * eglCreatePlatformWindowSurface fails when called with a <display>
957 * that belongs to the surfaceless platform. It returns
958 * EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
959 * justification for this unconditional failure is that the
960 * surfaceless platform has no native windows, and therefore the
961 * <native_window> parameter is always invalid.
962 *
963 * This check must occur before checking the EGLConfig, which emits
964 * EGL_BAD_CONFIG.
965 */
966 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
967 }
Chad Versacea597c8a2016-10-12 15:48:15 -0700968
969 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
970
Chad Versacefbb4af92016-12-16 11:00:13 -0800971 if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
972 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
973
Paulo Zanoni73055ae2019-05-01 16:26:47 -0700974 if (_eglNativeSurfaceAlreadyUsed(disp, native_window))
975 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
976
Chad Versace468cc862014-01-23 07:26:10 -0800977 surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
978 attrib_list);
979 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
980
981 RETURN_EGL_EVAL(disp, ret);
982}
983
984
Brian Paul1ed10272008-05-27 13:45:41 -0600985EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800986eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +0800987 EGLNativeWindowType window, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000988{
Chia-I Wu655f4652010-02-17 17:30:44 +0800989 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400990
991 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -0800992 STATIC_ASSERT(sizeof(void*) == sizeof(window));
993 return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
994 attrib_list);
995}
996
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400997static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000998_fixupNativeWindow(_EGLDisplay *disp, void *native_window)
Chad Versace468cc862014-01-23 07:26:10 -0800999{
Chad Versace468cc862014-01-23 07:26:10 -08001000#ifdef HAVE_X11_PLATFORM
Emil Velikov26fbb9e2017-08-08 15:55:36 +01001001 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
Chad Versace468cc862014-01-23 07:26:10 -08001002 /* The `native_window` parameter for the X11 platform differs between
1003 * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
1004 * eglCreateWindowSurface(), the type of `native_window` is an Xlib
1005 * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
1006 * `Window*`. Convert `Window*` to `Window` because that's what
1007 * dri2_x11_create_window_surface() expects.
1008 */
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -04001009 return (void *)(* (Window*) native_window);
Chad Versace468cc862014-01-23 07:26:10 -08001010 }
1011#endif
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -04001012 return native_window;
1013}
1014
1015static EGLSurface EGLAPIENTRY
1016eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
1017 void *native_window,
1018 const EGLint *attrib_list)
1019{
1020 _EGLDisplay *disp = _eglLockDisplay(dpy);
1021
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001022 native_window = _fixupNativeWindow(disp, native_window);
Chad Versace468cc862014-01-23 07:26:10 -08001023
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001024 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -08001025 return _eglCreateWindowSurfaceCommon(disp, config, native_window,
1026 attrib_list);
1027}
1028
1029
Marek Olšák820a4d42015-05-12 21:06:41 +02001030EGLSurface EGLAPIENTRY
1031eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
1032 void *native_window,
1033 const EGLAttrib *attrib_list)
1034{
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -04001035 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +02001036 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001037 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +02001038
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001039 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1040
1041 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +02001042 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001043 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +02001044
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001045 native_window = _fixupNativeWindow(disp, native_window);
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -04001046 surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
1047 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +02001048 free(int_attribs);
1049 return surface;
1050}
1051
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001052static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001053_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001054{
1055#ifdef HAVE_X11_PLATFORM
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001056 /* The `native_pixmap` parameter for the X11 platform differs between
1057 * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
1058 * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
1059 * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
1060 * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
1061 * dri2_x11_create_pixmap_surface() expects.
1062 */
Emil Velikov26fbb9e2017-08-08 15:55:36 +01001063 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001064 return (void *)(* (Pixmap*) native_pixmap);
1065#endif
1066 return native_pixmap;
1067}
Marek Olšák820a4d42015-05-12 21:06:41 +02001068
Chad Versace468cc862014-01-23 07:26:10 -08001069static EGLSurface
1070_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
1071 void *native_pixmap, const EGLint *attrib_list)
1072{
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001073 _EGLConfig *conf = _eglLookupConfig(config, disp);
1074 _EGLDriver *drv;
1075 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001076 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001077
Emil Velikovd6edcce2019-05-16 18:01:40 +01001078 if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
1079 disp->Platform == _EGL_PLATFORM_DEVICE)) {
Chad Versacea597c8a2016-10-12 15:48:15 -07001080 /* From the EGL_MESA_platform_surfaceless spec (v1):
1081 *
1082 * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
1083 * also fails when called with a <display> that belongs to the
1084 * surfaceless platform. It returns EGL_NO_SURFACE and generates
1085 * EGL_BAD_NATIVE_PIXMAP.
1086 *
1087 * This check must occur before checking the EGLConfig, which emits
1088 * EGL_BAD_CONFIG.
1089 */
1090 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1091 }
Chad Versacea597c8a2016-10-12 15:48:15 -07001092
Chia-I Wubef4b472010-02-19 12:08:50 +08001093 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chad Versacefbb4af92016-12-16 11:00:13 -08001094
1095 if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
1096 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1097
Emil Velikovdf8efd52017-08-05 00:25:48 +01001098 if (native_pixmap == NULL)
1099 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1100
Paulo Zanoni73055ae2019-05-01 16:26:47 -07001101 if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap))
1102 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
1103
Chad Versace468cc862014-01-23 07:26:10 -08001104 surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
Chad Versace6d1f83e2014-01-07 14:54:51 -08001105 attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001106 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001107
Chia-I Wubef4b472010-02-19 12:08:50 +08001108 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001109}
1110
1111
Brian Paul1ed10272008-05-27 13:45:41 -06001112EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001113eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +08001114 EGLNativePixmapType pixmap, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001115{
Chia-I Wu655f4652010-02-17 17:30:44 +08001116 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001117
1118 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001119 STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
Chad Versace468cc862014-01-23 07:26:10 -08001120 return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001121 attrib_list);
Chad Versace468cc862014-01-23 07:26:10 -08001122}
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001123
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001124static EGLSurface EGLAPIENTRY
Chad Versace468cc862014-01-23 07:26:10 -08001125eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001126 void *native_pixmap,
1127 const EGLint *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -08001128{
1129 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001130
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001131 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001132 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Chad Versace468cc862014-01-23 07:26:10 -08001133 return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1134 attrib_list);
Brian Pauladbff7e2005-04-22 21:09:39 +00001135}
1136
1137
Brian Paul1ed10272008-05-27 13:45:41 -06001138EGLSurface EGLAPIENTRY
Marek Olšák820a4d42015-05-12 21:06:41 +02001139eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
1140 void *native_pixmap,
1141 const EGLAttrib *attrib_list)
1142{
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001143 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +02001144 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001145 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +02001146
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001147 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1148
1149 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +02001150 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001151 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +02001152
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001153 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001154 surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1155 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +02001156 free(int_attribs);
1157 return surface;
1158}
1159
1160
1161EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001162eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
1163 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001164{
Chia-I Wu655f4652010-02-17 17:30:44 +08001165 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001166 _EGLConfig *conf = _eglLookupConfig(config, disp);
1167 _EGLDriver *drv;
1168 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001169 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001170
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001171 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001172 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001173
Chad Versacefbb4af92016-12-16 11:00:13 -08001174 if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
1175 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1176
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001177 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001178 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001179
Chia-I Wubef4b472010-02-19 12:08:50 +08001180 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001181}
1182
1183
Brian Paul1ed10272008-05-27 13:45:41 -06001184EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001185eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
1186{
Chia-I Wu655f4652010-02-17 17:30:44 +08001187 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001188 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1189 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001190 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001191
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001192 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001193 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001194 _eglUnlinkSurface(surf);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001195 ret = drv->API.DestroySurface(drv, disp, surf);
1196
Chia-I Wubef4b472010-02-19 12:08:50 +08001197 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001198}
1199
Brian Paul1ed10272008-05-27 13:45:41 -06001200EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001201eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
1202 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001203{
Chia-I Wu655f4652010-02-17 17:30:44 +08001204 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001205 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1206 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001207 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001208
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001209 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001210 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Eric Engestrom58be9d52019-06-22 22:31:53 +01001211
1212 if (drv->API.QuerySurface)
1213 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
1214 else
1215 ret = _eglQuerySurface(drv, disp, surf, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001216
Chia-I Wubef4b472010-02-19 12:08:50 +08001217 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001218}
1219
Brian Paul1ed10272008-05-27 13:45:41 -06001220EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001221eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
1222 EGLint attribute, EGLint value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001223{
Chia-I Wu655f4652010-02-17 17:30:44 +08001224 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001225 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1226 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001227 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001228
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001229 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001230 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Eric Engestrom188dbb12019-06-22 21:55:03 +01001231 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001232
Chia-I Wubef4b472010-02-19 12:08:50 +08001233 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001234}
1235
1236
Brian Paul1ed10272008-05-27 13:45:41 -06001237EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001238eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1239{
Chia-I Wu655f4652010-02-17 17:30:44 +08001240 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001241 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1242 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001243 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001244
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001245 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001246 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001247 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
1248
Chia-I Wubef4b472010-02-19 12:08:50 +08001249 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001250}
1251
1252
Brian Paul1ed10272008-05-27 13:45:41 -06001253EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001254eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1255{
Chia-I Wu655f4652010-02-17 17:30:44 +08001256 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001257 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1258 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001259 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001260
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001261 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001262 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001263 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
1264
Chia-I Wubef4b472010-02-19 12:08:50 +08001265 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001266}
1267
1268
Brian Paul1ed10272008-05-27 13:45:41 -06001269EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001270eglSwapInterval(EGLDisplay dpy, EGLint interval)
1271{
Chia-I Wu655f4652010-02-17 17:30:44 +08001272 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu57da4992009-10-15 11:08:48 +08001273 _EGLContext *ctx = _eglGetCurrentContext();
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001274 _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
Chia-I Wuaed73582010-02-17 15:43:47 +08001275 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001276 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001277
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001278 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001279 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu57da4992009-10-15 11:08:48 +08001280
Chia-I Wud19afc52010-10-23 12:52:26 +08001281 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1282 ctx->Resource.Display != disp)
Chia-I Wubef4b472010-02-19 12:08:50 +08001283 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001284
Chia-I Wud19afc52010-10-23 12:52:26 +08001285 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001286 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001287
Emil Velikov64b4ccd2018-09-03 13:05:22 +01001288 if (surf->Type != EGL_WINDOW_BIT)
1289 RETURN_EGL_EVAL(disp, EGL_TRUE);
1290
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001291 interval = CLAMP(interval,
1292 surf->Config->MinSwapInterval,
1293 surf->Config->MaxSwapInterval);
1294
Eric Engestrom188dbb12019-06-22 21:55:03 +01001295 if (surf->SwapInterval != interval)
1296 ret = drv->API.SwapInterval(drv, disp, surf, interval);
1297 else
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001298 ret = EGL_TRUE;
1299
1300 if (ret)
1301 surf->SwapInterval = interval;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001302
Chia-I Wubef4b472010-02-19 12:08:50 +08001303 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001304}
1305
1306
Brian Paul1ed10272008-05-27 13:45:41 -06001307EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001308eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
Brian Pauladbff7e2005-04-22 21:09:39 +00001309{
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001310 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu655f4652010-02-17 17:30:44 +08001311 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001312 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1313 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001314 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001315
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001316 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001317 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001318
1319 /* surface must be bound to current context in EGL 1.4 */
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001320 #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
Chia-I Wud19afc52010-10-23 12:52:26 +08001321 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1322 surf != ctx->DrawSurface)
Chia-I Wubef4b472010-02-19 12:08:50 +08001323 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001324 #endif
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001325
Emil Velikov8f667432018-09-03 13:05:23 +01001326 if (surf->Type != EGL_WINDOW_BIT)
1327 RETURN_EGL_EVAL(disp, EGL_TRUE);
1328
Chad Versace23c86c72017-05-04 17:46:33 -07001329 /* From the EGL 1.5 spec:
1330 *
1331 * If eglSwapBuffers is called and the native window associated with
1332 * surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
1333 * generated.
1334 */
1335 if (surf->Lost)
1336 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
1337
Chia-I Wub3bb1802010-02-17 16:05:27 +08001338 ret = drv->API.SwapBuffers(drv, disp, surf);
1339
Harish Krupo98275472017-06-09 20:13:34 +05301340 /* EGL_KHR_partial_update
1341 * Frame boundary successfully reached,
1342 * reset damage region and reset BufferAgeRead
1343 */
1344 if (ret) {
1345 surf->SetDamageRegionCalled = EGL_FALSE;
1346 surf->BufferAgeRead = EGL_FALSE;
1347 }
1348
Chia-I Wubef4b472010-02-19 12:08:50 +08001349 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001350}
1351
1352
Eric Engestrom0a606a42016-10-10 17:33:17 +01001353static EGLBoolean
Eric Engestrom9702f912016-11-16 22:29:53 +00001354_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
1355 EGLint *rects, EGLint n_rects)
Robert Bragg6425b142013-04-25 13:41:42 +01001356{
1357 _EGLContext *ctx = _eglGetCurrentContext();
Robert Bragg6425b142013-04-25 13:41:42 +01001358 _EGLDriver *drv;
1359 EGLBoolean ret;
1360
1361 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1362
1363 /* surface must be bound to current context in EGL 1.4 */
1364 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1365 surf != ctx->DrawSurface)
1366 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1367
Emil Velikov8f667432018-09-03 13:05:23 +01001368 if (surf->Type != EGL_WINDOW_BIT)
1369 RETURN_EGL_EVAL(disp, EGL_TRUE);
1370
Robert Bragg6425b142013-04-25 13:41:42 +01001371 if ((n_rects > 0 && rects == NULL) || n_rects < 0)
1372 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1373
1374 ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
1375
Harish Krupo98275472017-06-09 20:13:34 +05301376 /* EGL_KHR_partial_update
1377 * Frame boundary successfully reached,
1378 * reset damage region and reset BufferAgeRead
1379 */
1380 if (ret) {
1381 surf->SetDamageRegionCalled = EGL_FALSE;
1382 surf->BufferAgeRead = EGL_FALSE;
1383 }
1384
Robert Bragg6425b142013-04-25 13:41:42 +01001385 RETURN_EGL_EVAL(disp, ret);
1386}
1387
Eric Engestrom0a606a42016-10-10 17:33:17 +01001388static EGLBoolean EGLAPIENTRY
1389eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
1390 EGLint *rects, EGLint n_rects)
1391{
1392 _EGLDisplay *disp = _eglLockDisplay(dpy);
1393 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1394 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001395 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001396}
1397
1398static EGLBoolean EGLAPIENTRY
1399eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
1400 EGLint *rects, EGLint n_rects)
1401{
1402 _EGLDisplay *disp = _eglLockDisplay(dpy);
1403 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1404 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001405 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001406}
1407
Harish Krupo98275472017-06-09 20:13:34 +05301408/**
Harish Krupofd734602018-07-08 12:53:00 +05301409 * Clamp the rectangles so that they lie within the surface.
Harish Krupo98275472017-06-09 20:13:34 +05301410 */
1411
1412static void
1413_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf,
1414 EGLint *rects, EGLint n_rects)
1415{
1416 EGLint i;
1417 EGLint surf_height = surf->Height;
1418 EGLint surf_width = surf->Width;
1419
1420 for (i = 0; i < (4 * n_rects); i += 4) {
Harish Krupofd734602018-07-08 12:53:00 +05301421 EGLint x1, y1, x2, y2;
1422 x1 = rects[i];
1423 y1 = rects[i + 1];
1424 x2 = rects[i + 2] + x1;
1425 y2 = rects[i + 3] + y1;
Harish Krupo98275472017-06-09 20:13:34 +05301426
Harish Krupofd734602018-07-08 12:53:00 +05301427 rects[i] = CLAMP(x1, 0, surf_width);
1428 rects[i + 1] = CLAMP(y1, 0, surf_height);
1429 rects[i + 2] = CLAMP(x2, 0, surf_width) - rects[i];
1430 rects[i + 3] = CLAMP(y2, 0, surf_height) - rects[i + 1];
Harish Krupo98275472017-06-09 20:13:34 +05301431 }
1432}
1433
1434static EGLBoolean EGLAPIENTRY
1435eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
1436 EGLint *rects, EGLint n_rects)
1437{
1438 _EGLDisplay *disp = _eglLockDisplay(dpy);
1439 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1440 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1441 _EGLContext *ctx = _eglGetCurrentContext();
1442 _EGLDriver *drv;
1443 EGLBoolean ret;
1444 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1445
1446 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1447 surf->Type != EGL_WINDOW_BIT ||
1448 ctx->DrawSurface != surf ||
1449 surf->SwapBehavior != EGL_BUFFER_DESTROYED)
1450 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1451
1452 /* If the damage region is already set or
1453 * buffer age is not queried between
1454 * frame boundaries, throw bad access error
1455 */
1456
1457 if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
1458 RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
1459
1460 _eglSetDamageRegionKHRClampRects(disp, surf, rects, n_rects);
1461 ret = drv->API.SetDamageRegion(drv, disp, surf, rects, n_rects);
1462
1463 if (ret)
1464 surf->SetDamageRegionCalled = EGL_TRUE;
1465
1466 RETURN_EGL_EVAL(disp, ret);
1467}
1468
Brian Paul1ed10272008-05-27 13:45:41 -06001469EGLBoolean EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +08001470eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
Brian Pauladbff7e2005-04-22 21:09:39 +00001471{
Chia-I Wu655f4652010-02-17 17:30:44 +08001472 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001473 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1474 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001475 EGLBoolean ret;
Chad Versace6d1f83e2014-01-07 14:54:51 -08001476 void *native_pixmap_ptr;
1477
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001478 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001479 STATIC_ASSERT(sizeof(void*) == sizeof(target));
1480 native_pixmap_ptr = (void*) target;
Chia-I Wuaed73582010-02-17 15:43:47 +08001481
Chia-I Wubef4b472010-02-19 12:08:50 +08001482 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001483 ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001484
Chia-I Wubef4b472010-02-19 12:08:50 +08001485 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001486}
1487
1488
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001489static EGLBoolean
1490_eglWaitClientCommon(void)
Brian Pauladbff7e2005-04-22 21:09:39 +00001491{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001492 _EGLContext *ctx = _eglGetCurrentContext();
1493 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001494 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001495 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001496
Chia-I Wu6c21c882009-09-28 14:12:39 +08001497 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001498 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001499
1500 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001501 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001502
1503 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001504 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1505 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001506 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001507
Chia-I Wu6c21c882009-09-28 14:12:39 +08001508 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001509 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001510 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001511 ret = drv->API.WaitClient(drv, disp, ctx);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001512
Chia-I Wubef4b472010-02-19 12:08:50 +08001513 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu6c21c882009-09-28 14:12:39 +08001514}
1515
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001516EGLBoolean EGLAPIENTRY
1517eglWaitClient(void)
1518{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001519 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001520 return _eglWaitClientCommon();
1521}
Chia-I Wu6c21c882009-09-28 14:12:39 +08001522
1523EGLBoolean EGLAPIENTRY
1524eglWaitGL(void)
1525{
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001526 /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001527 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001528 return _eglWaitClientCommon();
Brian Pauladbff7e2005-04-22 21:09:39 +00001529}
1530
1531
Brian Paul1ed10272008-05-27 13:45:41 -06001532EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001533eglWaitNative(EGLint engine)
1534{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001535 _EGLContext *ctx = _eglGetCurrentContext();
1536 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001537 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001538 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001539
Chia-I Wu6c21c882009-09-28 14:12:39 +08001540 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001541 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001542
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001543 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1544
Chia-I Wu655f4652010-02-17 17:30:44 +08001545 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001546 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001547
Chia-I Wu6c21c882009-09-28 14:12:39 +08001548 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001549 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1550 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001551 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001552
Chia-I Wu6c21c882009-09-28 14:12:39 +08001553 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001554 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001555 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001556 ret = drv->API.WaitNative(drv, disp, engine);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001557
Chia-I Wubef4b472010-02-19 12:08:50 +08001558 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001559}
1560
1561
Brian Paul1ed10272008-05-27 13:45:41 -06001562EGLDisplay EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001563eglGetCurrentDisplay(void)
1564{
Chia-I Wua1717972010-01-26 17:13:51 +08001565 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001566 EGLDisplay ret;
1567
1568 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
1569
Chia-I Wubef4b472010-02-19 12:08:50 +08001570 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001571}
1572
1573
Brian Paul1ed10272008-05-27 13:45:41 -06001574EGLContext EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001575eglGetCurrentContext(void)
1576{
1577 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001578 EGLContext ret;
1579
1580 ret = _eglGetContextHandle(ctx);
1581
Chia-I Wubef4b472010-02-19 12:08:50 +08001582 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001583}
1584
1585
Brian Paul1ed10272008-05-27 13:45:41 -06001586EGLSurface EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001587eglGetCurrentSurface(EGLint readdraw)
1588{
Chia-I Wu61906632009-09-30 15:34:45 +08001589 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001590 EGLint err = EGL_SUCCESS;
Chia-I Wu61906632009-09-30 15:34:45 +08001591 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001592 EGLSurface ret;
Chia-I Wu61906632009-09-30 15:34:45 +08001593
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001594 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
1595
Chia-I Wu61906632009-09-30 15:34:45 +08001596 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001597 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
Chia-I Wu61906632009-09-30 15:34:45 +08001598
1599 switch (readdraw) {
1600 case EGL_DRAW:
1601 surf = ctx->DrawSurface;
1602 break;
1603 case EGL_READ:
1604 surf = ctx->ReadSurface;
1605 break;
1606 default:
Chia-I Wu61906632009-09-30 15:34:45 +08001607 surf = NULL;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001608 err = EGL_BAD_PARAMETER;
Chia-I Wu61906632009-09-30 15:34:45 +08001609 break;
1610 }
1611
Chia-I Wub3bb1802010-02-17 16:05:27 +08001612 ret = _eglGetSurfaceHandle(surf);
1613
Chia-I Wubef4b472010-02-19 12:08:50 +08001614 RETURN_EGL_ERROR(NULL, err, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001615}
1616
1617
Brian Paul1ed10272008-05-27 13:45:41 -06001618EGLint EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001619eglGetError(void)
1620{
Brian Paul48822792005-12-10 17:54:00 +00001621 _EGLThreadInfo *t = _eglGetCurrentThread();
1622 EGLint e = t->LastError;
Chia-I Wu75da80b2009-07-17 11:41:02 -06001623 if (!_eglIsCurrentThreadDummy())
1624 t->LastError = EGL_SUCCESS;
Brian Pauladbff7e2005-04-22 21:09:39 +00001625 return e;
1626}
1627
1628
Brian Paulb2006a42006-01-30 00:10:55 +00001629/**
1630 ** EGL 1.2
1631 **/
1632
Brian Pauld5078b92008-05-30 13:45:40 -06001633/**
1634 * Specify the client API to use for subsequent calls including:
1635 * eglCreateContext()
1636 * eglGetCurrentContext()
1637 * eglGetCurrentDisplay()
1638 * eglGetCurrentSurface()
1639 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1640 * eglWaitClient()
1641 * eglWaitNative()
1642 * See section 3.7 "Rendering Context" in the EGL specification for details.
1643 */
nobledc43ab4f2010-07-02 19:38:07 -04001644EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001645eglBindAPI(EGLenum api)
1646{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001647 _EGLThreadInfo *t;
Brian Paulb2006a42006-01-30 00:10:55 +00001648
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001649 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1650
1651 t = _eglGetCurrentThread();
Chia-I Wu75da80b2009-07-17 11:41:02 -06001652 if (_eglIsCurrentThreadDummy())
Chia-I Wubef4b472010-02-19 12:08:50 +08001653 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
Chia-I Wu75da80b2009-07-17 11:41:02 -06001654
Chia-I Wu21b635f2009-07-17 11:42:04 -06001655 if (!_eglIsApiValid(api))
Chia-I Wubef4b472010-02-19 12:08:50 +08001656 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wu21b635f2009-07-17 11:42:04 -06001657
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001658 t->CurrentAPI = api;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001659
Chia-I Wubef4b472010-02-19 12:08:50 +08001660 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001661}
Jon Smirl7012d012005-05-13 18:31:35 +00001662
1663
Brian Pauld5078b92008-05-30 13:45:40 -06001664/**
1665 * Return the last value set with eglBindAPI().
1666 */
nobledc43ab4f2010-07-02 19:38:07 -04001667EGLenum EGLAPIENTRY
Brian Pauld5078b92008-05-30 13:45:40 -06001668eglQueryAPI(void)
1669{
Brian Pauld5078b92008-05-30 13:45:40 -06001670 _EGLThreadInfo *t = _eglGetCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001671 EGLenum ret;
1672
1673 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001674 ret = t->CurrentAPI;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001675
Chia-I Wubef4b472010-02-19 12:08:50 +08001676 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauld5078b92008-05-30 13:45:40 -06001677}
1678
1679
nobledc43ab4f2010-07-02 19:38:07 -04001680EGLSurface EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001681eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1682 EGLClientBuffer buffer, EGLConfig config,
1683 const EGLint *attrib_list)
1684{
Chia-I Wu655f4652010-02-17 17:30:44 +08001685 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001686 _EGLConfig *conf = _eglLookupConfig(config, disp);
1687 _EGLDriver *drv;
1688 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001689 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001690
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001691 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1692
Chia-I Wubef4b472010-02-19 12:08:50 +08001693 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001694
1695 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1696 conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001697 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001698
Chia-I Wubef4b472010-02-19 12:08:50 +08001699 RETURN_EGL_EVAL(disp, ret);
Brian Paulb2006a42006-01-30 00:10:55 +00001700}
Jon Smirl7012d012005-05-13 18:31:35 +00001701
Brian Paulb2006a42006-01-30 00:10:55 +00001702
nobledc43ab4f2010-07-02 19:38:07 -04001703EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001704eglReleaseThread(void)
1705{
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001706 /* unbind current contexts */
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001707 if (!_eglIsCurrentThreadDummy()) {
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001708 _EGLThreadInfo *t = _eglGetCurrentThread();
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001709 _EGLContext *ctx = t->CurrentContext;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001710
1711 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1712
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001713 if (ctx) {
1714 _EGLDisplay *disp = ctx->Resource.Display;
1715 _EGLDriver *drv;
Chia-I Wu655f4652010-02-17 17:30:44 +08001716
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001717 mtx_lock(&disp->Mutex);
1718 drv = disp->Driver;
1719 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1720 mtx_unlock(&disp->Mutex);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001721 }
Brian Paulb2006a42006-01-30 00:10:55 +00001722 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001723
Chia-I Wu75da80b2009-07-17 11:41:02 -06001724 _eglDestroyCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001725
Chia-I Wubef4b472010-02-19 12:08:50 +08001726 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001727}
1728
1729
Kyle Brenneman58338c62016-09-12 17:38:13 -04001730static EGLImage
1731_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001732 EGLClientBuffer buffer, const EGLint *attr_list)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001733{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001734 _EGLContext *context = _eglLookupContext(ctx, disp);
1735 _EGLDriver *drv;
1736 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02001737 EGLImage ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001738
Chia-I Wubef4b472010-02-19 12:08:50 +08001739 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001740 if (!disp->Extensions.KHR_image_base)
1741 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001742 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +08001743 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
Topi Pohjolainen0de013b2013-03-22 14:31:01 +02001744 /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1745 * <ctx> must be EGL_NO_CONTEXT..."
1746 */
1747 if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1748 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001749
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001750 img = drv->API.CreateImageKHR(drv, disp, context, target,
1751 buffer, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001752 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001753
Chia-I Wubef4b472010-02-19 12:08:50 +08001754 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001755}
1756
Kyle Brenneman58338c62016-09-12 17:38:13 -04001757static EGLImage EGLAPIENTRY
1758eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1759 EGLClientBuffer buffer, const EGLint *attr_list)
1760{
1761 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001762 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
Kyle Brenneman58338c62016-09-12 17:38:13 -04001763 return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
1764}
1765
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001766
Marek Olšák515f04e2015-05-12 20:42:05 +02001767EGLImage EGLAPIENTRY
1768eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1769 EGLClientBuffer buffer, const EGLAttrib *attr_list)
1770{
Kyle Brenneman58338c62016-09-12 17:38:13 -04001771 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák515f04e2015-05-12 20:42:05 +02001772 EGLImage image;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001773 EGLint *int_attribs;
Marek Olšák515f04e2015-05-12 20:42:05 +02001774
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001775 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
1776
1777 int_attribs = _eglConvertAttribsToInt(attr_list);
Marek Olšák515f04e2015-05-12 20:42:05 +02001778 if (attr_list && !int_attribs)
Kyle Brenneman58338c62016-09-12 17:38:13 -04001779 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
Marek Olšák515f04e2015-05-12 20:42:05 +02001780
Kyle Brenneman58338c62016-09-12 17:38:13 -04001781 image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
Marek Olšák515f04e2015-05-12 20:42:05 +02001782 free(int_attribs);
1783 return image;
1784}
1785
1786
Eric Engestromdf7fa302017-02-21 23:56:44 +00001787static EGLBoolean
1788_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001789{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001790 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001791 EGLBoolean ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001792
Chia-I Wubef4b472010-02-19 12:08:50 +08001793 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001794 if (!disp->Extensions.KHR_image_base)
1795 RETURN_EGL_EVAL(disp, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001796 if (!img)
Chia-I Wubef4b472010-02-19 12:08:50 +08001797 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001798
1799 _eglUnlinkImage(img);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001800 ret = drv->API.DestroyImageKHR(drv, disp, img);
1801
Chia-I Wubef4b472010-02-19 12:08:50 +08001802 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001803}
1804
Eric Engestromdf7fa302017-02-21 23:56:44 +00001805EGLBoolean EGLAPIENTRY
1806eglDestroyImage(EGLDisplay dpy, EGLImage image)
1807{
1808 _EGLDisplay *disp = _eglLockDisplay(dpy);
1809 _EGLImage *img = _eglLookupImage(image, disp);
1810 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1811 return _eglDestroyImageCommon(disp, img);
1812}
1813
1814static EGLBoolean EGLAPIENTRY
1815eglDestroyImageKHR(EGLDisplay dpy, EGLImage image)
1816{
1817 _EGLDisplay *disp = _eglLockDisplay(dpy);
1818 _EGLImage *img = _eglLookupImage(image, disp);
1819 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1820 return _eglDestroyImageCommon(disp, img);
1821}
1822
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001823
Marek Olšákd333d302015-05-12 17:34:57 +02001824static EGLSync
Chad Versace80448852016-09-27 13:27:21 -07001825_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
1826 EGLBoolean orig_is_EGLAttrib,
Marek Olšák51c8c662015-05-12 21:41:32 +02001827 EGLenum invalid_type_error)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001828{
Marek Olšák9a0bda22015-04-10 10:56:02 +02001829 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu4eebea72010-08-14 23:09:12 +08001830 _EGLDriver *drv;
1831 _EGLSync *sync;
Marek Olšákd333d302015-05-12 17:34:57 +02001832 EGLSync ret;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001833
1834 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001835
Chad Versace80448852016-09-27 13:27:21 -07001836 if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
Chad Versacef2c2f432016-09-27 13:27:12 -07001837 /* There exist two EGLAttrib variants of eglCreateSync*:
1838 * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
1839 * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
1840 * support as a proxy for EGL 1.5 support, even though that's not
1841 * entirely correct (though _eglComputeVersion does the same).
1842 *
1843 * The EGL spec provides no guidance on how to handle unsupported
1844 * functions. EGL_BAD_MATCH seems reasonable.
1845 */
1846 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1847 }
Marek Olšák290a3eb2015-04-10 13:16:30 +02001848
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001849 /* If type is EGL_SYNC_FENCE and no context is current for the bound API
1850 * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH
1851 * error is generated.
1852 */
Rob Clark0201f012016-11-18 08:39:33 -05001853 if (!ctx &&
1854 (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001855 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1856
Marek Olšák9a0bda22015-04-10 10:56:02 +02001857 /* return an error if the client API doesn't support GL_OES_EGL_sync */
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001858 if (ctx && (ctx->Resource.Display != disp ||
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001859 ctx->ClientAPI != EGL_OPENGL_ES_API))
Marek Olšák9a0bda22015-04-10 10:56:02 +02001860 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1861
1862 switch (type) {
1863 case EGL_SYNC_FENCE_KHR:
1864 if (!disp->Extensions.KHR_fence_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001865 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001866 break;
1867 case EGL_SYNC_REUSABLE_KHR:
1868 if (!disp->Extensions.KHR_reusable_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001869 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001870 break;
Marek Olšák290a3eb2015-04-10 13:16:30 +02001871 case EGL_SYNC_CL_EVENT_KHR:
1872 if (!disp->Extensions.KHR_cl_event2)
Marek Olšák51c8c662015-05-12 21:41:32 +02001873 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001874 break;
Rob Clark0201f012016-11-18 08:39:33 -05001875 case EGL_SYNC_NATIVE_FENCE_ANDROID:
1876 if (!disp->Extensions.ANDROID_native_fence_sync)
1877 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1878 break;
Marek Olšák9a0bda22015-04-10 10:56:02 +02001879 default:
Marek Olšák51c8c662015-05-12 21:41:32 +02001880 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001881 }
Chia-I Wu4eebea72010-08-14 23:09:12 +08001882
Chad Versace80448852016-09-27 13:27:21 -07001883 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001884 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001885
1886 RETURN_EGL_EVAL(disp, ret);
1887}
1888
1889
Marek Olšákd333d302015-05-12 17:34:57 +02001890static EGLSync EGLAPIENTRY
Chad Versace80448852016-09-27 13:27:21 -07001891eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001892{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001893 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001894 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001895
1896 EGLSync sync;
1897 EGLAttrib *attrib_list;
1898 EGLint err;
1899
1900 if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
1901 attrib_list = (EGLAttrib *) int_list;
1902 } else {
1903 err = _eglConvertIntsToAttribs(int_list, &attrib_list);
1904 if (err != EGL_SUCCESS)
1905 RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
1906 }
1907
1908 sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001909 EGL_BAD_ATTRIBUTE);
Chad Versace80448852016-09-27 13:27:21 -07001910
1911 if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
1912 free(attrib_list);
1913
1914 /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
1915 return sync;
Marek Olšák51c8c662015-05-12 21:41:32 +02001916}
1917
1918
1919static EGLSync EGLAPIENTRY
1920eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1921{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001922 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001923 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001924 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001925 EGL_BAD_ATTRIBUTE);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001926}
1927
1928
Marek Olšák2885ba02015-05-12 20:54:22 +02001929EGLSync EGLAPIENTRY
1930eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001931{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001932 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001933 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001934 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001935 EGL_BAD_PARAMETER);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001936}
1937
1938
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001939static EGLBoolean
1940_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001941{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001942 _EGLDriver *drv;
1943 EGLBoolean ret;
1944
1945 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001946 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05001947 disp->Extensions.KHR_fence_sync ||
1948 disp->Extensions.ANDROID_native_fence_sync);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001949
Chia-I Wu4eebea72010-08-14 23:09:12 +08001950 _eglUnlinkSync(s);
1951 ret = drv->API.DestroySyncKHR(drv, disp, s);
1952
1953 RETURN_EGL_EVAL(disp, ret);
1954}
1955
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001956EGLBoolean EGLAPIENTRY
1957eglDestroySync(EGLDisplay dpy, EGLSync sync)
1958{
1959 _EGLDisplay *disp = _eglLockDisplay(dpy);
1960 _EGLSync *s = _eglLookupSync(sync, disp);
1961 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1962 return _eglDestroySync(disp, s);
1963}
1964
1965static EGLBoolean EGLAPIENTRY
1966eglDestroySyncKHR(EGLDisplay dpy, EGLSync sync)
1967{
1968 _EGLDisplay *disp = _eglLockDisplay(dpy);
1969 _EGLSync *s = _eglLookupSync(sync, disp);
1970 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1971 return _eglDestroySync(disp, s);
1972}
1973
Chia-I Wu4eebea72010-08-14 23:09:12 +08001974
Eric Engestrom66d5ec52017-02-21 23:56:46 +00001975static EGLint
1976_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
1977 _EGLSync *s, EGLint flags, EGLTime timeout)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001978{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001979 _EGLDriver *drv;
1980 EGLint ret;
1981
1982 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001983 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05001984 disp->Extensions.KHR_fence_sync ||
1985 disp->Extensions.ANDROID_native_fence_sync);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001986
1987 if (s->SyncStatus == EGL_SIGNALED_KHR)
1988 RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
1989
Dongwon Kim70299472016-04-04 17:14:10 -07001990 /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
1991 * unlocked here to allow other threads also to be able to
1992 * go into waiting state.
1993 */
1994
1995 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1996 _eglUnlockDisplay(dpy);
1997
Chia-I Wu4eebea72010-08-14 23:09:12 +08001998 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1999
Dongwon Kim70299472016-04-04 17:14:10 -07002000 /*
2001 * 'disp' is already unlocked for reusable sync type,
2002 * so passing 'NULL' to bypass unlocking display.
2003 */
2004 if (s->Type == EGL_SYNC_REUSABLE_KHR)
2005 RETURN_EGL_EVAL(NULL, ret);
2006 else
2007 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002008}
2009
Eric Engestrom66d5ec52017-02-21 23:56:46 +00002010EGLint EGLAPIENTRY
2011eglClientWaitSync(EGLDisplay dpy, EGLSync sync,
2012 EGLint flags, EGLTime timeout)
2013{
2014 _EGLDisplay *disp = _eglLockDisplay(dpy);
2015 _EGLSync *s = _eglLookupSync(sync, disp);
2016 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2017 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
2018}
2019
2020static EGLint EGLAPIENTRY
2021eglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync,
2022 EGLint flags, EGLTime timeout)
2023{
2024 _EGLDisplay *disp = _eglLockDisplay(dpy);
2025 _EGLSync *s = _eglLookupSync(sync, disp);
2026 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2027 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
2028}
2029
Chia-I Wu4eebea72010-08-14 23:09:12 +08002030
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002031static EGLint
2032_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
Marek Olšáka8617cc2015-04-10 12:04:18 +02002033{
Marek Olšáka8617cc2015-04-10 12:04:18 +02002034 _EGLContext *ctx = _eglGetCurrentContext();
2035 _EGLDriver *drv;
2036 EGLint ret;
2037
2038 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
2039 assert(disp->Extensions.KHR_wait_sync);
2040
2041 /* return an error if the client API doesn't support GL_OES_EGL_sync */
2042 if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
2043 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
2044
2045 /* the API doesn't allow any flags yet */
2046 if (flags != 0)
2047 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2048
2049 ret = drv->API.WaitSyncKHR(drv, disp, s);
2050
2051 RETURN_EGL_EVAL(disp, ret);
2052}
2053
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002054static EGLint EGLAPIENTRY
2055eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
2056{
2057 _EGLDisplay *disp = _eglLockDisplay(dpy);
2058 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002059 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002060 return _eglWaitSyncCommon(disp, s, flags);
2061}
2062
Marek Olšáka8617cc2015-04-10 12:04:18 +02002063
Marek Olšák75245922015-05-12 18:13:31 +02002064EGLBoolean EGLAPIENTRY
2065eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
2066{
2067 /* The KHR version returns EGLint, while the core version returns
2068 * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
2069 * EGL_TRUE.
2070 */
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002071 _EGLDisplay *disp = _eglLockDisplay(dpy);
2072 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002073 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002074 return _eglWaitSyncCommon(disp, s, flags);
Marek Olšák75245922015-05-12 18:13:31 +02002075}
2076
2077
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002078static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002079eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
Chia-I Wu4eebea72010-08-14 23:09:12 +08002080{
2081 _EGLDisplay *disp = _eglLockDisplay(dpy);
2082 _EGLSync *s = _eglLookupSync(sync, disp);
2083 _EGLDriver *drv;
2084 EGLBoolean ret;
2085
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002086 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2087
Chia-I Wu4eebea72010-08-14 23:09:12 +08002088 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002089 assert(disp->Extensions.KHR_reusable_sync);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002090 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
2091
2092 RETURN_EGL_EVAL(disp, ret);
2093}
2094
2095
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002096static EGLBoolean
2097_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
Chia-I Wu4eebea72010-08-14 23:09:12 +08002098{
Chia-I Wu4eebea72010-08-14 23:09:12 +08002099 _EGLDriver *drv;
2100 EGLBoolean ret;
2101
2102 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02002103 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05002104 disp->Extensions.KHR_fence_sync ||
2105 disp->Extensions.ANDROID_native_fence_sync);
Marek Olšák1e79e052015-05-12 18:14:31 +02002106 ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002107
2108 RETURN_EGL_EVAL(disp, ret);
2109}
2110
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002111EGLBoolean EGLAPIENTRY
2112eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
2113{
2114 _EGLDisplay *disp = _eglLockDisplay(dpy);
2115 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002116 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002117 return _eglGetSyncAttribCommon(disp, s, attribute, value);
2118}
2119
Chia-I Wu4eebea72010-08-14 23:09:12 +08002120
Marek Olšák1e79e052015-05-12 18:14:31 +02002121static EGLBoolean EGLAPIENTRY
2122eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
2123{
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002124 _EGLDisplay *disp = _eglLockDisplay(dpy);
2125 _EGLSync *s = _eglLookupSync(sync, disp);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002126 EGLAttrib attrib;
2127 EGLBoolean result;
2128
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002129 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2130
Dongwon Kimd1e15632016-02-02 15:06:28 -08002131 if (!value)
Chad Versace17084b62016-09-27 23:06:37 -07002132 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002133
2134 attrib = *value;
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002135 result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
Marek Olšák1e79e052015-05-12 18:14:31 +02002136
2137 /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
2138 *
2139 * If any error occurs, <*value> is not modified.
2140 */
2141 if (result == EGL_FALSE)
2142 return result;
2143
2144 *value = attrib;
2145 return result;
2146}
2147
Rob Clark0201f012016-11-18 08:39:33 -05002148static EGLint EGLAPIENTRY
2149eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
2150{
2151 _EGLDisplay *disp = _eglLockDisplay(dpy);
2152 _EGLSync *s = _eglLookupSync(sync, disp);
2153 _EGLDriver *drv;
2154 EGLBoolean ret;
2155
2156 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2157
2158 /* the spec doesn't seem to specify what happens if the fence
2159 * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems
2160 * sensible:
2161 */
2162 if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)))
2163 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID);
2164
2165 _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv);
2166 assert(disp->Extensions.ANDROID_native_fence_sync);
2167 ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s);
2168
2169 RETURN_EGL_EVAL(disp, ret);
2170}
Marek Olšák1e79e052015-05-12 18:14:31 +02002171
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002172static EGLBoolean EGLAPIENTRY
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002173eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002174 EGLint numRects, const EGLint *rects)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002175{
2176 _EGLContext *ctx = _eglGetCurrentContext();
2177 _EGLDisplay *disp = _eglLockDisplay(dpy);
2178 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2179 _EGLDriver *drv;
2180 EGLBoolean ret;
2181
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002182 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2183
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002184 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2185
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002186 if (!disp->Extensions.NOK_swap_region)
2187 RETURN_EGL_EVAL(disp, EGL_FALSE);
2188
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002189 /* surface must be bound to current context in EGL 1.4 */
Chia-I Wud19afc52010-10-23 12:52:26 +08002190 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
2191 surf != ctx->DrawSurface)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002192 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
2193
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002194 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002195
2196 RETURN_EGL_EVAL(disp, ret);
2197}
2198
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002199
Marek Olšákd333d302015-05-12 17:34:57 +02002200static EGLImage EGLAPIENTRY
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002201eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
2202{
2203 _EGLDisplay *disp = _eglLockDisplay(dpy);
2204 _EGLDriver *drv;
2205 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02002206 EGLImage ret;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002207
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002208 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2209
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002210 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002211 if (!disp->Extensions.MESA_drm_image)
2212 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002213
2214 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08002215 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002216
2217 RETURN_EGL_EVAL(disp, ret);
2218}
2219
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002220static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002221eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002222 EGLint *name, EGLint *handle, EGLint *stride)
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002223{
2224 _EGLDisplay *disp = _eglLockDisplay(dpy);
2225 _EGLImage *img = _eglLookupImage(image, disp);
2226 _EGLDriver *drv;
2227 EGLBoolean ret;
2228
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002229 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2230
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002231 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002232 assert(disp->Extensions.MESA_drm_image);
2233
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002234 if (!img)
2235 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2236
2237 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
2238
2239 RETURN_EGL_EVAL(disp, ret);
2240}
2241
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002242
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002243struct wl_display;
2244
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002245static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002246eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2247{
2248 _EGLDisplay *disp = _eglLockDisplay(dpy);
2249 _EGLDriver *drv;
2250 EGLBoolean ret;
2251
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002252 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2253
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002254 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2255 assert(disp->Extensions.WL_bind_wayland_display);
2256
2257 if (!display)
2258 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2259
2260 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
2261
2262 RETURN_EGL_EVAL(disp, ret);
2263}
2264
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002265static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002266eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2267{
2268 _EGLDisplay *disp = _eglLockDisplay(dpy);
2269 _EGLDriver *drv;
2270 EGLBoolean ret;
2271
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002272 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2273
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002274 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2275 assert(disp->Extensions.WL_bind_wayland_display);
2276
2277 if (!display)
2278 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2279
2280 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
2281
2282 RETURN_EGL_EVAL(disp, ret);
2283}
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002284
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002285static EGLBoolean EGLAPIENTRY
Ander Conselvan de Oliveira8d29b522013-07-18 15:11:25 +03002286eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002287 EGLint attribute, EGLint *value)
2288{
2289 _EGLDisplay *disp = _eglLockDisplay(dpy);
2290 _EGLDriver *drv;
2291 EGLBoolean ret;
2292
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002293 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2294
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002295 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2296 assert(disp->Extensions.WL_bind_wayland_display);
2297
2298 if (!buffer)
2299 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2300
2301 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
2302
2303 RETURN_EGL_EVAL(disp, ret);
2304}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002305
Emil Velikov720125f2015-07-10 11:22:13 +01002306
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002307static struct wl_buffer * EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002308eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002309{
2310 _EGLDisplay *disp = _eglLockDisplay(dpy);
2311 _EGLImage *img;
2312 _EGLDriver *drv;
2313 struct wl_buffer *ret;
2314
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002315 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2316
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002317 _EGL_CHECK_DISPLAY(disp, NULL, drv);
Emil Velikov70131142017-05-15 16:14:15 +01002318 if (!disp->Extensions.WL_create_wayland_buffer_from_image)
2319 RETURN_EGL_EVAL(disp, NULL);
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002320
2321 img = _eglLookupImage(image, disp);
2322
2323 if (!img)
2324 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
2325
2326 ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
2327
2328 RETURN_EGL_EVAL(disp, ret);
2329}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002330
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002331static EGLBoolean EGLAPIENTRY
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002332eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
2333 EGLint x, EGLint y, EGLint width, EGLint height)
2334{
2335 _EGLDisplay *disp = _eglLockDisplay(dpy);
2336 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2337 _EGLDriver *drv;
2338 EGLBoolean ret;
2339
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002340 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2341
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002342 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2343
2344 if (!disp->Extensions.NV_post_sub_buffer)
2345 RETURN_EGL_EVAL(disp, EGL_FALSE);
2346
2347 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
2348
2349 RETURN_EGL_EVAL(disp, ret);
2350}
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002351
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002352static EGLBoolean EGLAPIENTRY
Eric Engestrom54fa5ec2019-02-02 11:38:45 +00002353eglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface,
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002354 EGLuint64KHR *ust, EGLuint64KHR *msc,
2355 EGLuint64KHR *sbc)
2356{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +00002357 _EGLDisplay *disp = _eglLockDisplay(dpy);
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002358 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2359 _EGLDriver *drv;
2360 EGLBoolean ret;
2361
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002362 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2363
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002364 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2365 if (!disp->Extensions.CHROMIUM_sync_control)
2366 RETURN_EGL_EVAL(disp, EGL_FALSE);
2367
2368 if (!ust || !msc || !sbc)
2369 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2370
2371 ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
2372
2373 RETURN_EGL_EVAL(disp, ret);
2374}
Dave Airlie8f7338f2014-03-03 13:57:16 +10002375
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002376static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002377eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002378 EGLint *fourcc, EGLint *nplanes,
Dave Airlieb5045e22015-05-05 09:10:34 +10002379 EGLuint64KHR *modifiers)
Dave Airlie8f7338f2014-03-03 13:57:16 +10002380{
2381 _EGLDisplay *disp = _eglLockDisplay(dpy);
2382 _EGLImage *img = _eglLookupImage(image, disp);
2383 _EGLDriver *drv;
2384 EGLBoolean ret;
2385
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002386 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2387
Dave Airlie8f7338f2014-03-03 13:57:16 +10002388 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2389 assert(disp->Extensions.MESA_image_dma_buf_export);
2390
2391 if (!img)
2392 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2393
2394 ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
2395 modifiers);
2396
2397 RETURN_EGL_EVAL(disp, ret);
2398}
2399
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002400static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002401eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002402 int *fds, EGLint *strides, EGLint *offsets)
2403{
2404 _EGLDisplay *disp = _eglLockDisplay(dpy);
2405 _EGLImage *img = _eglLookupImage(image, disp);
2406 _EGLDriver *drv;
2407 EGLBoolean ret;
2408
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002409 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2410
Dave Airlie8f7338f2014-03-03 13:57:16 +10002411 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2412 assert(disp->Extensions.MESA_image_dma_buf_export);
2413
2414 if (!img)
2415 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2416
2417 ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
2418
2419 RETURN_EGL_EVAL(disp, ret);
2420}
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002421
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002422static EGLint EGLAPIENTRY
2423eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002424 EGLLabelKHR label)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002425{
2426 _EGLDisplay *disp = NULL;
2427 _EGLResourceType type;
2428
2429 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2430
2431 if (objectType == EGL_OBJECT_THREAD_KHR) {
2432 _EGLThreadInfo *t = _eglGetCurrentThread();
2433
2434 if (!_eglIsCurrentThreadDummy()) {
2435 t->Label = label;
2436 return EGL_SUCCESS;
2437 }
2438
2439 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
2440 }
2441
2442 disp = _eglLockDisplay(dpy);
2443 if (disp == NULL)
2444 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
2445
2446 if (objectType == EGL_OBJECT_DISPLAY_KHR) {
2447 if (dpy != (EGLDisplay) object)
2448 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2449
2450 disp->Label = label;
2451 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2452 }
2453
2454 switch (objectType) {
2455 case EGL_OBJECT_CONTEXT_KHR:
2456 type = _EGL_RESOURCE_CONTEXT;
2457 break;
2458 case EGL_OBJECT_SURFACE_KHR:
2459 type = _EGL_RESOURCE_SURFACE;
2460 break;
2461 case EGL_OBJECT_IMAGE_KHR:
2462 type = _EGL_RESOURCE_IMAGE;
2463 break;
2464 case EGL_OBJECT_SYNC_KHR:
2465 type = _EGL_RESOURCE_SYNC;
2466 break;
2467 case EGL_OBJECT_STREAM_KHR:
2468 default:
2469 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2470 }
2471
2472 if (_eglCheckResource(object, type, disp)) {
2473 _EGLResource *res = (_EGLResource *) object;
2474
2475 res->Label = label;
2476 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2477 }
2478
2479 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2480}
2481
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002482static EGLint EGLAPIENTRY
2483eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002484 const EGLAttrib *attrib_list)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002485{
2486 unsigned int newEnabled;
2487
2488 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2489
2490 mtx_lock(_eglGlobal.Mutex);
2491
2492 newEnabled = _eglGlobal.debugTypesEnabled;
2493 if (attrib_list != NULL) {
2494 int i;
2495
2496 for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
Emil Velikov4df0d502017-09-07 17:03:53 +01002497 switch (attrib_list[i]) {
2498 case EGL_DEBUG_MSG_CRITICAL_KHR:
2499 case EGL_DEBUG_MSG_ERROR_KHR:
2500 case EGL_DEBUG_MSG_WARN_KHR:
2501 case EGL_DEBUG_MSG_INFO_KHR:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002502 if (attrib_list[i + 1])
2503 newEnabled |= DebugBitFromType(attrib_list[i]);
2504 else
2505 newEnabled &= ~DebugBitFromType(attrib_list[i]);
Emil Velikov4df0d502017-09-07 17:03:53 +01002506 break;
2507 default:
2508 // On error, set the last error code, call the current
2509 // debug callback, and return the error code.
2510 mtx_unlock(_eglGlobal.Mutex);
2511 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
2512 "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
2513 return EGL_BAD_ATTRIBUTE;
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002514 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002515 }
2516 }
2517
2518 if (callback != NULL) {
2519 _eglGlobal.debugCallback = callback;
2520 _eglGlobal.debugTypesEnabled = newEnabled;
2521 } else {
2522 _eglGlobal.debugCallback = NULL;
2523 _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
2524 }
2525
2526 mtx_unlock(_eglGlobal.Mutex);
2527 return EGL_SUCCESS;
2528}
2529
2530static EGLBoolean EGLAPIENTRY
2531eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
2532{
2533 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2534
2535 mtx_lock(_eglGlobal.Mutex);
2536
Emil Velikov4df0d502017-09-07 17:03:53 +01002537 switch (attribute) {
2538 case EGL_DEBUG_MSG_CRITICAL_KHR:
2539 case EGL_DEBUG_MSG_ERROR_KHR:
2540 case EGL_DEBUG_MSG_WARN_KHR:
2541 case EGL_DEBUG_MSG_INFO_KHR:
2542 if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
2543 *value = EGL_TRUE;
2544 else
2545 *value = EGL_FALSE;
2546 break;
2547 case EGL_DEBUG_CALLBACK_KHR:
2548 *value = (EGLAttrib) _eglGlobal.debugCallback;
2549 break;
2550 default:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002551 mtx_unlock(_eglGlobal.Mutex);
2552 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002553 "Invalid attribute 0x%04lx", (unsigned long) attribute);
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002554 return EGL_FALSE;
Emil Velikov4df0d502017-09-07 17:03:53 +01002555 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002556
2557 mtx_unlock(_eglGlobal.Mutex);
2558 return EGL_TRUE;
2559}
2560
Eric Engestrom1534fc62017-02-21 23:56:52 +00002561static int
2562_eglFunctionCompare(const void *key, const void *elem)
2563{
2564 const char *procname = key;
2565 const struct _egl_entrypoint *entrypoint = elem;
2566 return strcmp(procname, entrypoint->name);
2567}
2568
Varad Gautam6719e052017-05-30 17:23:38 +05302569static EGLBoolean EGLAPIENTRY
2570eglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats,
2571 EGLint *formats, EGLint *num_formats)
2572{
2573 _EGLDisplay *disp = _eglLockDisplay(dpy);
2574 _EGLDriver *drv;
2575 EGLBoolean ret;
2576
2577 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2578
2579 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2580
2581 ret = drv->API.QueryDmaBufFormatsEXT(drv, disp, max_formats, formats,
2582 num_formats);
2583
2584 RETURN_EGL_EVAL(disp, ret);
2585}
2586
Varad Gautamde3c4592017-05-30 17:23:39 +05302587static EGLBoolean EGLAPIENTRY
2588eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
2589 EGLuint64KHR *modifiers, EGLBoolean *external_only,
2590 EGLint *num_modifiers)
2591{
2592 _EGLDisplay *disp = _eglLockDisplay(dpy);
2593 _EGLDriver *drv;
2594 EGLBoolean ret;
2595
2596 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2597
2598 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2599
2600 ret = drv->API.QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers,
2601 modifiers, external_only,
2602 num_modifiers);
2603
2604 RETURN_EGL_EVAL(disp, ret);
2605}
2606
Tapani Pälli6f5b5702017-12-28 10:51:11 +02002607static void EGLAPIENTRY
2608eglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
2609 EGLGetBlobFuncANDROID get)
2610{
2611 /* This function does not return anything so we cannot
2612 * utilize the helper macros _EGL_FUNC_START or _EGL_CHECK_DISPLAY.
2613 */
2614 _EGLDisplay *disp = _eglLockDisplay(dpy);
2615 if (!_eglSetFuncName(__func__, disp, EGL_OBJECT_DISPLAY_KHR, NULL)) {
2616 if (disp)
2617 _eglUnlockDisplay(disp);
2618 return;
2619 }
2620
2621 _EGLDriver *drv = _eglCheckDisplay(disp, __func__);
2622 if (!drv) {
2623 if (disp)
2624 _eglUnlockDisplay(disp);
2625 return;
2626 }
2627
2628 if (!set || !get) {
2629 _eglError(EGL_BAD_PARAMETER,
2630 "eglSetBlobCacheFuncsANDROID: NULL handler given");
2631 _eglUnlockDisplay(disp);
2632 return;
2633 }
2634
2635 if (disp->BlobCacheSet) {
2636 _eglError(EGL_BAD_PARAMETER,
2637 "eglSetBlobCacheFuncsANDROID: functions already set");
2638 _eglUnlockDisplay(disp);
2639 return;
2640 }
2641
2642 disp->BlobCacheSet = set;
2643 disp->BlobCacheGet = get;
2644
2645 drv->API.SetBlobCacheFuncsANDROID(drv, disp, set, get);
2646
2647 _eglUnlockDisplay(disp);
2648}
2649
Emil Velikov7552fcb2015-07-24 16:19:55 +02002650static EGLBoolean EGLAPIENTRY
2651eglQueryDeviceAttribEXT(EGLDeviceEXT device,
2652 EGLint attribute,
2653 EGLAttrib *value)
2654{
2655 _EGLDevice *dev = _eglLookupDevice(device);
2656 EGLBoolean ret;
2657
2658 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2659 if (!dev)
2660 RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, EGL_FALSE);
2661
2662 ret = _eglQueryDeviceAttribEXT(dev, attribute, value);
2663 RETURN_EGL_EVAL(NULL, ret);
2664}
2665
2666static const char * EGLAPIENTRY
2667eglQueryDeviceStringEXT(EGLDeviceEXT device,
2668 EGLint name)
2669{
2670 _EGLDevice *dev = _eglLookupDevice(device);
2671
2672 _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2673 if (!dev)
2674 RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, NULL);
2675
2676 RETURN_EGL_EVAL(NULL, _eglQueryDeviceStringEXT(dev, name));
2677}
2678
2679static EGLBoolean EGLAPIENTRY
2680eglQueryDevicesEXT(EGLint max_devices,
2681 EGLDeviceEXT *devices,
2682 EGLint *num_devices)
2683{
2684 EGLBoolean ret;
2685
2686 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2687 ret = _eglQueryDevicesEXT(max_devices, (_EGLDevice **) devices,
2688 num_devices);
2689 RETURN_EGL_EVAL(NULL, ret);
2690}
2691
2692static EGLBoolean EGLAPIENTRY
2693eglQueryDisplayAttribEXT(EGLDisplay dpy,
2694 EGLint attribute,
2695 EGLAttrib *value)
2696{
2697 _EGLDisplay *disp = _eglLockDisplay(dpy);
2698 _EGLDriver *drv;
2699
2700 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2701 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2702
2703 switch (attribute) {
2704 case EGL_DEVICE_EXT:
2705 *value = (EGLAttrib) disp->Device;
2706 break;
2707 default:
2708 RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_FALSE);
2709 }
2710 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
2711}
2712
Veluri Mithun6afce782019-01-23 22:44:25 +05302713static char * EGLAPIENTRY
2714eglGetDisplayDriverConfig(EGLDisplay dpy)
2715{
2716 _EGLDisplay *disp = _eglLockDisplay(dpy);
2717 _EGLDriver *drv;
2718 char *ret;
2719
2720 _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
2721 _EGL_CHECK_DISPLAY(disp, NULL, drv);
2722
2723 assert(disp->Extensions.MESA_query_driver);
2724
2725 ret = drv->API.QueryDriverConfig(disp);
2726 RETURN_EGL_EVAL(disp, ret);
2727}
2728
2729static const char * EGLAPIENTRY
2730eglGetDisplayDriverName(EGLDisplay dpy)
2731{
2732 _EGLDisplay *disp = _eglLockDisplay(dpy);
2733 _EGLDriver *drv;
2734 const char *ret;
2735
2736 _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
2737 _EGL_CHECK_DISPLAY(disp, NULL, drv);
2738
2739 assert(disp->Extensions.MESA_query_driver);
2740
2741 ret = drv->API.QueryDriverName(disp);
2742 RETURN_EGL_EVAL(disp, ret);
2743}
2744
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002745__eglMustCastToProperFunctionPointerType EGLAPIENTRY
2746eglGetProcAddress(const char *procname)
2747{
Eric Engestrom1534fc62017-02-21 23:56:52 +00002748 static const struct _egl_entrypoint egl_functions[] = {
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002749#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
Eric Engestromf92fd4d2017-02-21 23:56:49 +00002750#include "eglentrypoint.h"
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002751#undef EGL_ENTRYPOINT
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002752 };
Eric Engestrom1534fc62017-02-21 23:56:52 +00002753 _EGLProc ret = NULL;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002754
2755 if (!procname)
2756 RETURN_EGL_SUCCESS(NULL, NULL);
2757
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002758 _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2759
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002760 if (strncmp(procname, "egl", 3) == 0) {
Eric Engestrom1534fc62017-02-21 23:56:52 +00002761 const struct _egl_entrypoint *entrypoint =
2762 bsearch(procname,
2763 egl_functions, ARRAY_SIZE(egl_functions),
2764 sizeof(egl_functions[0]),
2765 _eglFunctionCompare);
2766 if (entrypoint)
2767 ret = entrypoint->function;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002768 }
Eric Engestrom1534fc62017-02-21 23:56:52 +00002769
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002770 if (!ret)
2771 ret = _eglGetDriverProc(procname);
2772
2773 RETURN_EGL_SUCCESS(NULL, ret);
2774}
Marek Olšákb6eda702016-03-03 15:59:48 +01002775
2776static int
2777_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
2778 _EGLDisplay **disp, _EGLDriver **drv,
2779 _EGLContext **ctx)
2780{
2781
2782 *disp = _eglLockDisplay(dpy);
2783 if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
2784 if (*disp)
2785 _eglUnlockDisplay(*disp);
2786 return MESA_GLINTEROP_INVALID_DISPLAY;
2787 }
2788
2789 *drv = (*disp)->Driver;
2790
2791 *ctx = _eglLookupContext(context, *disp);
2792 if (!*ctx ||
2793 ((*ctx)->ClientAPI != EGL_OPENGL_API &&
2794 (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
2795 _eglUnlockDisplay(*disp);
2796 return MESA_GLINTEROP_INVALID_CONTEXT;
2797 }
2798
2799 return MESA_GLINTEROP_SUCCESS;
2800}
2801
Marek Olšákee39d442016-11-02 18:59:22 +01002802PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002803MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002804 struct mesa_glinterop_device_info *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002805{
2806 _EGLDisplay *disp;
2807 _EGLDriver *drv;
2808 _EGLContext *ctx;
2809 int ret;
2810
2811 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2812 if (ret != MESA_GLINTEROP_SUCCESS)
2813 return ret;
2814
2815 if (drv->API.GLInteropQueryDeviceInfo)
2816 ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
2817 else
2818 ret = MESA_GLINTEROP_UNSUPPORTED;
2819
2820 _eglUnlockDisplay(disp);
2821 return ret;
2822}
2823
Marek Olšákee39d442016-11-02 18:59:22 +01002824PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002825MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002826 struct mesa_glinterop_export_in *in,
2827 struct mesa_glinterop_export_out *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002828{
2829 _EGLDisplay *disp;
2830 _EGLDriver *drv;
2831 _EGLContext *ctx;
2832 int ret;
2833
2834 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2835 if (ret != MESA_GLINTEROP_SUCCESS)
2836 return ret;
2837
2838 if (drv->API.GLInteropExportObject)
2839 ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
2840 else
2841 ret = MESA_GLINTEROP_UNSUPPORTED;
2842
2843 _eglUnlockDisplay(disp);
2844 return ret;
2845}