blob: f99078febb3958f13c5e97127fb8cbf2e4eed4da [file] [log] [blame]
Chia-I Wuf2001df2011-07-02 17:57:30 +09001/**************************************************************************
2 *
José Fonseca87712852014-01-17 16:27:50 +00003 * Copyright 2008 VMware, Inc.
Chia-I Wuf2001df2011-07-02 17:57:30 +09004 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010-2011 LunarG, Inc.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 **************************************************************************/
29
30
Brian Pauladbff7e2005-04-22 21:09:39 +000031/**
32 * Public EGL API entrypoints
33 *
34 * Generally, we use the EGLDisplay parameter as a key to lookup the
35 * appropriate device driver handle, then jump though the driver's
36 * dispatch table to handle the function.
37 *
38 * That allows us the option of supporting multiple, simultaneous,
39 * heterogeneous hardware devices in the future.
40 *
41 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
Chia-I Wuaaa12532009-09-30 15:08:34 +080042 * opaque handles. Internal objects are linked to a display to
43 * create the handles.
Brian Pauladbff7e2005-04-22 21:09:39 +000044 *
Chia-I Wuaaa12532009-09-30 15:08:34 +080045 * For each public API entry point, the opaque handles are looked up
46 * before being dispatched to the drivers. When it fails to look up
47 * a handle, one of
48 *
49 * EGL_BAD_DISPLAY
50 * EGL_BAD_CONFIG
51 * EGL_BAD_CONTEXT
52 * EGL_BAD_SURFACE
53 * EGL_BAD_SCREEN_MESA
54 * EGL_BAD_MODE_MESA
55 *
56 * is generated and the driver function is not called. An
57 * uninitialized EGLDisplay has no driver associated with it. When
58 * such display is detected,
59 *
60 * EGL_NOT_INITIALIZED
61 *
62 * is generated.
Brian Pauladbff7e2005-04-22 21:09:39 +000063 *
Chia-I Wubbfd0e22009-10-15 11:08:33 +080064 * Some of the entry points use current display, context, or surface
65 * implicitly. For such entry points, the implicit objects are also
66 * checked before calling the driver function. Other than the
67 * errors listed above,
68 *
69 * EGL_BAD_CURRENT_SURFACE
70 *
71 * may also be generated.
72 *
Brian Pauladbff7e2005-04-22 21:09:39 +000073 * Notes on naming conventions:
74 *
75 * eglFooBar - public EGL function
76 * EGL_FOO_BAR - public EGL token
77 * EGLDatatype - public EGL datatype
78 *
79 * _eglFooBar - private EGL function
80 * _EGLDatatype - private EGL datatype, typedef'd struct
81 * _egl_struct - private EGL struct, non-typedef'd
82 *
83 */
84
85
Brian Pauladbff7e2005-04-22 21:09:39 +000086#include <stdio.h>
Brian Paulb2006a42006-01-30 00:10:55 +000087#include <stdlib.h>
Brian Pauladbff7e2005-04-22 21:09:39 +000088#include <string.h>
Emil Velikov7bd16932015-02-28 16:35:22 +000089#include "c99_compat.h"
Emil Velikovefe87f12015-03-06 16:54:55 +000090#include "c11/threads.h"
Emil Velikov239e7ee2017-05-04 18:55:36 +010091#include "util/macros.h"
Chia-I Wu1e6c10f2010-05-31 11:47:58 +080092
Eric Engestromd75fbff2018-05-16 14:17:30 +010093#include "eglapi.h"
94#include "egldefines.h"
Chad Versace3c58d4c2013-10-11 16:04:55 -070095#include "eglglobals.h"
Brian Pauladbff7e2005-04-22 21:09:39 +000096#include "eglcontext.h"
97#include "egldisplay.h"
98#include "egltypedefs.h"
Chia-I Wu94cb3212010-01-29 09:00:30 +080099#include "eglcurrent.h"
Emil Velikov7552fcb2015-07-24 16:19:55 +0200100#include "egldevice.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000101#include "egldriver.h"
102#include "eglsurface.h"
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800103#include "eglconfig.h"
Chia-I Wua1c4a8a2009-08-15 22:58:13 +0800104#include "eglimage.h"
Chia-I Wu4eebea72010-08-14 23:09:12 +0800105#include "eglsync.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000106
Matt Turner4e970842017-07-06 18:40:53 -0700107#include "GL/mesa_glinterop.h"
Brian Pauladbff7e2005-04-22 21:09:39 +0000108
109/**
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800110 * Macros to help return an API entrypoint.
Chia-I Wu655f4652010-02-17 17:30:44 +0800111 *
112 * These macros will unlock the display and record the error code.
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800113 */
Chia-I Wubef4b472010-02-19 12:08:50 +0800114#define RETURN_EGL_ERROR(disp, err, ret) \
115 do { \
Chia-I Wu655f4652010-02-17 17:30:44 +0800116 if (disp) \
117 _eglUnlockDisplay(disp); \
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800118 /* EGL error codes are non-zero */ \
119 if (err) \
Emil Velikovd7800122015-02-28 16:39:10 +0000120 _eglError(err, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800121 return ret; \
122 } while (0)
123
124#define RETURN_EGL_SUCCESS(disp, ret) \
125 RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
126
Chia-I Wub3bb1802010-02-17 16:05:27 +0800127/* record EGL_SUCCESS only when ret evaluates to true */
Chia-I Wubef4b472010-02-19 12:08:50 +0800128#define RETURN_EGL_EVAL(disp, ret) \
129 RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800130
131
Chia-I Wubef4b472010-02-19 12:08:50 +0800132/*
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800133 * A bunch of macros and checks to simplify error checking.
134 */
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800135
Chia-I Wubef4b472010-02-19 12:08:50 +0800136#define _EGL_CHECK_DISPLAY(disp, ret, drv) \
137 do { \
Emil Velikovd7800122015-02-28 16:39:10 +0000138 drv = _eglCheckDisplay(disp, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800139 if (!drv) \
140 RETURN_EGL_ERROR(disp, 0, ret); \
141 } while (0)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800142
Chia-I Wubef4b472010-02-19 12:08:50 +0800143#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
144 do { \
Emil Velikovd7800122015-02-28 16:39:10 +0000145 drv = _eglCheck ## type(disp, obj, __func__); \
Chia-I Wubef4b472010-02-19 12:08:50 +0800146 if (!drv) \
147 RETURN_EGL_ERROR(disp, 0, ret); \
148 } while (0)
149
150#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
151 _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
152
153#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
154 _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
155
156#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
157 _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
158
Chia-I Wu4eebea72010-08-14 23:09:12 +0800159#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
160 _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800161
162
Eric Engestrom1534fc62017-02-21 23:56:52 +0000163struct _egl_entrypoint {
164 const char *name;
165 _EGLProc function;
166};
167
168
Emil Velikov7bd16932015-02-28 16:35:22 +0000169static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800170_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
171{
172 if (!disp) {
173 _eglError(EGL_BAD_DISPLAY, msg);
174 return NULL;
175 }
176 if (!disp->Initialized) {
177 _eglError(EGL_NOT_INITIALIZED, msg);
178 return NULL;
179 }
180 return disp->Driver;
181}
182
183
Emil Velikov7bd16932015-02-28 16:35:22 +0000184static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800185_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
186{
187 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
188 if (!drv)
189 return NULL;
190 if (!surf) {
191 _eglError(EGL_BAD_SURFACE, msg);
192 return NULL;
193 }
194 return drv;
195}
196
197
Emil Velikov7bd16932015-02-28 16:35:22 +0000198static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800199_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
200{
201 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
202 if (!drv)
203 return NULL;
204 if (!context) {
205 _eglError(EGL_BAD_CONTEXT, msg);
206 return NULL;
207 }
208 return drv;
209}
210
211
Emil Velikov7bd16932015-02-28 16:35:22 +0000212static inline _EGLDriver *
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800213_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
214{
215 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
216 if (!drv)
217 return NULL;
218 if (!conf) {
219 _eglError(EGL_BAD_CONFIG, msg);
220 return NULL;
221 }
222 return drv;
223}
224
225
Emil Velikov7bd16932015-02-28 16:35:22 +0000226static inline _EGLDriver *
Chia-I Wu4eebea72010-08-14 23:09:12 +0800227_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
228{
229 _EGLDriver *drv = _eglCheckDisplay(disp, msg);
230 if (!drv)
231 return NULL;
232 if (!s) {
233 _eglError(EGL_BAD_PARAMETER, msg);
234 return NULL;
235 }
236 return drv;
237}
238
239
Chia-I Wuf3e03e12010-02-17 15:22:03 +0800240/**
Chia-I Wu655f4652010-02-17 17:30:44 +0800241 * Lookup and lock a display.
242 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000243static inline _EGLDisplay *
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000244_eglLockDisplay(EGLDisplay dpy)
Chia-I Wu655f4652010-02-17 17:30:44 +0800245{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000246 _EGLDisplay *disp = _eglLookupDisplay(dpy);
247 if (disp)
248 mtx_lock(&disp->Mutex);
249 return disp;
Chia-I Wu655f4652010-02-17 17:30:44 +0800250}
251
252
253/**
254 * Unlock a display.
255 */
Emil Velikov7bd16932015-02-28 16:35:22 +0000256static inline void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000257_eglUnlockDisplay(_EGLDisplay *disp)
Chia-I Wu655f4652010-02-17 17:30:44 +0800258{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000259 mtx_unlock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +0800260}
261
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400262static EGLBoolean
263_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
264{
265 _EGLThreadInfo *thr = _eglGetCurrentThread();
266 if (!_eglIsCurrentThreadDummy()) {
267 thr->CurrentFuncName = funcName;
268 thr->CurrentObjectLabel = NULL;
269
270 if (objectType == EGL_OBJECT_THREAD_KHR)
271 thr->CurrentObjectLabel = thr->Label;
272 else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
273 thr->CurrentObjectLabel = disp->Label;
274 else if (object)
275 thr->CurrentObjectLabel = object->Label;
276
277 return EGL_TRUE;
278 }
279
Emil Velikovb94344f2017-09-07 17:03:50 +0100280 _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400281 return EGL_FALSE;
282}
283
284#define _EGL_FUNC_START(disp, objectType, object, ret) \
285 do { \
286 if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
287 if (disp) \
288 _eglUnlockDisplay(disp); \
289 return ret; \
290 } \
291 } while(0)
Chia-I Wu655f4652010-02-17 17:30:44 +0800292
Chad Versace3e0d5752016-09-27 13:27:17 -0700293/**
294 * Convert an attribute list from EGLint[] to EGLAttrib[].
295 *
296 * Return an EGL error code. The output parameter out_attrib_list is modified
297 * only on success.
298 */
Eric Engestrom9e1d35c2016-12-08 00:36:03 +0000299static EGLint
Chad Versace3e0d5752016-09-27 13:27:17 -0700300_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
301{
302 size_t len = 0;
303 EGLAttrib *attrib_list;
304
305 if (int_list) {
306 while (int_list[2*len] != EGL_NONE)
307 ++len;
308 }
309
310 if (len == 0) {
311 *out_attrib_list = NULL;
312 return EGL_SUCCESS;
313 }
314
315 if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
316 return EGL_BAD_ALLOC;
317
318 attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
319 if (!attrib_list)
320 return EGL_BAD_ALLOC;
321
322 for (size_t i = 0; i < len; ++i) {
323 attrib_list[2*i + 0] = int_list[2*i + 0];
324 attrib_list[2*i + 1] = int_list[2*i + 1];
325 }
326
327 attrib_list[2*len] = EGL_NONE;
328
329 *out_attrib_list = attrib_list;
330 return EGL_SUCCESS;
331}
332
333
Marek Olšák515f04e2015-05-12 20:42:05 +0200334static EGLint *
335_eglConvertAttribsToInt(const EGLAttrib *attr_list)
336{
337 EGLint *int_attribs = NULL;
338
339 /* Convert attributes from EGLAttrib[] to EGLint[] */
340 if (attr_list) {
341 int i, size = 0;
342
343 while (attr_list[size] != EGL_NONE)
344 size += 2;
345
346 size += 1; /* add space for EGL_NONE */
347
348 int_attribs = calloc(size, sizeof(int_attribs[0]));
349 if (!int_attribs)
350 return NULL;
351
352 for (i = 0; i < size; i++)
353 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);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000376 disp = _eglFindDisplay(plat, native_display_ptr);
377 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
Chad Versace468cc862014-01-23 07:26:10 -0800409 default:
410 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
411 }
412
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000413 return _eglGetDisplayHandle(disp);
Chad Versace468cc862014-01-23 07:26:10 -0800414}
Brian Pauladbff7e2005-04-22 21:09:39 +0000415
Kyle Brenneman017946b2016-09-12 16:42:56 -0400416static EGLDisplay EGLAPIENTRY
417eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500418 const EGLint *int_attribs)
Kyle Brenneman017946b2016-09-12 16:42:56 -0400419{
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500420 EGLAttrib *attrib_list;
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000421 EGLDisplay disp;
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500422
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400423 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500424
425 if (_eglConvertIntsToAttribs(int_attribs, &attrib_list) != EGL_SUCCESS)
426 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
427
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000428 disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500429 free(attrib_list);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000430 return disp;
Kyle Brenneman017946b2016-09-12 16:42:56 -0400431}
432
Marek Olšák820a4d42015-05-12 21:06:41 +0200433EGLDisplay EGLAPIENTRY
434eglGetPlatformDisplay(EGLenum platform, void *native_display,
435 const EGLAttrib *attrib_list)
436{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400437 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
Adam Jacksonddcd4b02017-11-16 13:27:27 -0500438 return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +0200439}
440
Brian Paul6052af12008-05-27 16:48:23 -0600441/**
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700442 * Copy the extension into the string and update the string pointer.
443 */
444static EGLint
445_eglAppendExtension(char **str, const char *ext)
446{
447 char *s = *str;
448 size_t len = strlen(ext);
449
450 if (s) {
451 memcpy(s, ext, len);
452 s[len++] = ' ';
453 s[len] = '\0';
454
455 *str += len;
456 }
457 else {
458 len++;
459 }
460
461 return (EGLint) len;
462}
463
464/**
465 * Examine the individual extension enable/disable flags and recompute
466 * the driver's Extensions string.
467 */
468static void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000469_eglCreateExtensionsString(_EGLDisplay *disp)
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700470{
471#define _EGL_CHECK_EXTENSION(ext) \
472 do { \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000473 if (disp->Extensions.ext) { \
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700474 _eglAppendExtension(&exts, "EGL_" #ext); \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000475 assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700476 } \
477 } while (0)
478
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000479 char *exts = disp->ExtensionsString;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700480
Marek Olšák32aa1d72015-06-09 23:08:57 +0200481 /* Please keep these sorted alphabetically. */
Tapani Pälli6f5b5702017-12-28 10:51:11 +0200482 _EGL_CHECK_EXTENSION(ANDROID_blob_cache);
Rob Herring89755272016-02-02 14:23:07 -0600483 _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700484 _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
Rob Clark0201f012016-11-18 08:39:33 -0500485 _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
Rob Herringe21e81a2016-02-02 14:23:08 -0600486 _EGL_CHECK_EXTENSION(ANDROID_recordable);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700487
488 _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
489
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700490 _EGL_CHECK_EXTENSION(EXT_buffer_age);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200491 _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700492 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
Varad Gautam4c412292017-05-30 17:23:40 +0530493 _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
Tapani Pälli799b3d12018-04-05 13:02:36 +0300494 _EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
495 _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200496 _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
497
Chris Wilson95ecf3d2016-10-27 19:34:46 +0100498 _EGL_CHECK_EXTENSION(IMG_context_priority);
499
Marek Olšák32aa1d72015-06-09 23:08:57 +0200500 _EGL_CHECK_EXTENSION(KHR_cl_event2);
Emil Velikov26541a12016-12-05 14:42:04 +0000501 _EGL_CHECK_EXTENSION(KHR_config_attribs);
Adam Jacksonc0be3aa2016-09-22 03:47:55 -0400502 _EGL_CHECK_EXTENSION(KHR_context_flush_control);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200503 _EGL_CHECK_EXTENSION(KHR_create_context);
Grigori Goronzy49095192017-06-29 02:44:03 +0200504 _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200505 _EGL_CHECK_EXTENSION(KHR_fence_sync);
506 _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
507 _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
508 _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
509 _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
510 _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
511 _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000512 if (disp->Extensions.KHR_image_base && disp->Extensions.KHR_image_pixmap)
513 disp->Extensions.KHR_image = EGL_TRUE;
Harish Krupo96fc5fb2017-12-08 21:29:39 +0530514 _EGL_CHECK_EXTENSION(KHR_image);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200515 _EGL_CHECK_EXTENSION(KHR_image_base);
516 _EGL_CHECK_EXTENSION(KHR_image_pixmap);
Chad Versace3dc22382018-04-30 22:32:25 -0700517 _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
Adam Jacksond9f5b192016-09-09 12:25:34 -0400518 _EGL_CHECK_EXTENSION(KHR_no_config_context);
Harish Krupo98275472017-06-09 20:13:34 +0530519 _EGL_CHECK_EXTENSION(KHR_partial_update);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200520 _EGL_CHECK_EXTENSION(KHR_reusable_sync);
521 _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000522 if (disp->Extensions.EXT_swap_buffers_with_damage)
Eric Engestrom0a606a42016-10-10 17:33:17 +0100523 _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
Tapani Pälli41f7de42017-10-31 10:57:42 +0200524 _EGL_CHECK_EXTENSION(EXT_pixel_format_float);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200525 _EGL_CHECK_EXTENSION(KHR_wait_sync);
526
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000527 if (disp->Extensions.KHR_no_config_context)
Adam Jacksond9f5b192016-09-09 12:25:34 -0400528 _eglAppendExtension(&exts, "EGL_MESA_configless_context");
Marek Olšák32aa1d72015-06-09 23:08:57 +0200529 _EGL_CHECK_EXTENSION(MESA_drm_image);
530 _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
Veluri Mithun6afce782019-01-23 22:44:25 +0530531 _EGL_CHECK_EXTENSION(MESA_query_driver);
Marek Olšák32aa1d72015-06-09 23:08:57 +0200532
533 _EGL_CHECK_EXTENSION(NOK_swap_region);
534 _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700535
536 _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
Dave Airlie8f7338f2014-03-03 13:57:16 +1000537
Marek Olšák32aa1d72015-06-09 23:08:57 +0200538 _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
539 _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
540
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700541#undef _EGL_CHECK_EXTENSION
542}
543
544static void
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000545_eglCreateAPIsString(_EGLDisplay *disp)
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700546{
Eric Engestromaa78b292018-08-16 15:31:55 +0100547#define addstr(str) \
548 { \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000549 const size_t old_len = strlen(disp->ClientAPIsString); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100550 const size_t add_len = sizeof(str); \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000551 const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \
Eric Engestromaa78b292018-08-16 15:31:55 +0100552 if (old_len + add_len <= max_len) \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000553 strcat(disp->ClientAPIsString, str " "); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100554 else \
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000555 assert(!"disp->ClientAPIsString is not large enough"); \
Eric Engestromaa78b292018-08-16 15:31:55 +0100556 }
557
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000558 if (disp->ClientAPIs & EGL_OPENGL_BIT)
Eric Engestromaa78b292018-08-16 15:31:55 +0100559 addstr("OpenGL");
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700560
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000561 if (disp->ClientAPIs & EGL_OPENGL_ES_BIT ||
562 disp->ClientAPIs & EGL_OPENGL_ES2_BIT ||
563 disp->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
Eric Engestromaa78b292018-08-16 15:31:55 +0100564 addstr("OpenGL_ES");
Plamena Manolova21edd242016-05-12 18:21:38 +0100565 }
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700566
Eric Engestrom54fa5ec2019-02-02 11:38:45 +0000567 if (disp->ClientAPIs & EGL_OPENVG_BIT)
Eric Engestromaa78b292018-08-16 15:31:55 +0100568 addstr("OpenVG");
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700569
Eric Engestromaa78b292018-08-16 15:31:55 +0100570#undef addstr
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700571}
572
Marek Olšákefda9c52015-05-11 22:16:52 +0200573static void
574_eglComputeVersion(_EGLDisplay *disp)
575{
Marek Olšák0e4b5642015-05-12 16:40:29 +0200576 disp->Version = 14;
Marek Olšáka1cb4072015-05-11 22:18:04 +0200577
578 if (disp->Extensions.KHR_fence_sync &&
579 disp->Extensions.KHR_cl_event2 &&
580 disp->Extensions.KHR_wait_sync &&
581 disp->Extensions.KHR_image_base &&
582 disp->Extensions.KHR_gl_texture_2D_image &&
583 disp->Extensions.KHR_gl_texture_3D_image &&
584 disp->Extensions.KHR_gl_texture_cubemap_image &&
585 disp->Extensions.KHR_gl_renderbuffer_image &&
586 disp->Extensions.KHR_create_context &&
587 disp->Extensions.EXT_create_context_robustness &&
588 disp->Extensions.KHR_get_all_proc_addresses &&
589 disp->Extensions.KHR_gl_colorspace &&
590 disp->Extensions.KHR_surfaceless_context)
591 disp->Version = 15;
Marek Olšákefda9c52015-05-11 22:16:52 +0200592}
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700593
594/**
Brian Paul6052af12008-05-27 16:48:23 -0600595 * This is typically the second EGL function that an application calls.
596 * Here we load/initialize the actual hardware driver.
597 */
Brian Paul1ed10272008-05-27 13:45:41 -0600598EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000599eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
600{
Chia-I Wu655f4652010-02-17 17:30:44 +0800601 _EGLDisplay *disp = _eglLockDisplay(dpy);
Jonathan White7e2458c2008-08-06 13:40:03 -0600602
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400603 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
604
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800605 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800606 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Brian Paulc56e15b2008-05-28 15:43:41 -0600607
Chia-I Wua9332592010-01-27 23:55:58 +0800608 if (!disp->Initialized) {
Eric Engestromd7e769a2017-10-18 16:31:23 +0100609 if (!_eglMatchDriver(disp))
Chia-I Wuf2aa3612010-07-04 15:55:12 +0800610 RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
Chia-I Wu57929ed2010-01-19 18:29:21 +0800611
Chia-I Wu310c7682009-08-17 15:53:54 +0800612 /* limit to APIs supported by core */
Chia-I Wua4a38dc2011-01-13 16:53:13 +0800613 disp->ClientAPIs &= _EGL_API_ALL_BITS;
Chad Versace7e8ba772014-11-20 10:26:38 -0800614
615 /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
616 * classifies it as an EGL display extension, though conceptually it's an
617 * EGL client extension.
618 *
619 * From the EGL_KHR_get_all_proc_addresses spec:
620 *
621 * The EGL implementation must expose the name
622 * EGL_KHR_client_get_all_proc_addresses if and only if it exposes
623 * EGL_KHR_get_all_proc_addresses and supports
624 * EGL_EXT_client_extensions.
625 *
626 * Mesa unconditionally exposes both client extensions mentioned above,
627 * so the spec requires that each EGLDisplay unconditionally expose
628 * EGL_KHR_get_all_proc_addresses also.
629 */
630 disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700631
Emil Velikov26541a12016-12-05 14:42:04 +0000632 /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
633 * programs. It is driver agnostic and handled in the main EGL code.
634 */
635 disp->Extensions.KHR_config_attribs = EGL_TRUE;
636
Marek Olšákefda9c52015-05-11 22:16:52 +0200637 _eglComputeVersion(disp);
Matt Turnerdac2e7d2015-03-10 11:41:57 -0700638 _eglCreateExtensionsString(disp);
639 _eglCreateAPIsString(disp);
Emil Velikov3593f372015-07-14 00:19:54 +0100640 snprintf(disp->VersionString, sizeof(disp->VersionString),
Eric Engestroma96749b2017-10-18 16:32:33 +0100641 "%d.%d", disp->Version / 10, disp->Version % 10);
Brian Pauladbff7e2005-04-22 21:09:39 +0000642 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800643
644 /* Update applications version of major and minor if not NULL */
645 if ((major != NULL) && (minor != NULL)) {
Marek Olšák0e4b5642015-05-12 16:40:29 +0200646 *major = disp->Version / 10;
647 *minor = disp->Version % 10;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800648 }
649
Chia-I Wubef4b472010-02-19 12:08:50 +0800650 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000651}
652
653
Brian Paul1ed10272008-05-27 13:45:41 -0600654EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000655eglTerminate(EGLDisplay dpy)
656{
Chia-I Wu655f4652010-02-17 17:30:44 +0800657 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800658
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400659 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
660
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800661 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800662 RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800663
Chia-I Wua9332592010-01-27 23:55:58 +0800664 if (disp->Initialized) {
665 _EGLDriver *drv = disp->Driver;
666
Chia-I Wuccc2b0b2009-08-13 13:39:51 +0800667 drv->API.Terminate(drv, disp);
Chia-I Wua9332592010-01-27 23:55:58 +0800668 /* do not reset disp->Driver */
Dave Airlie37e3a112015-03-16 15:21:55 +1000669 disp->ClientAPIsString[0] = 0;
Chia-I Wua9332592010-01-27 23:55:58 +0800670 disp->Initialized = EGL_FALSE;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800671 }
672
Chia-I Wubef4b472010-02-19 12:08:50 +0800673 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Brian Pauladbff7e2005-04-22 21:09:39 +0000674}
675
676
Brian Paul1ed10272008-05-27 13:45:41 -0600677const char * EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000678eglQueryString(EGLDisplay dpy, EGLint name)
679{
Chad Versace3c58d4c2013-10-11 16:04:55 -0700680 _EGLDisplay *disp;
Chia-I Wuaed73582010-02-17 15:43:47 +0800681 _EGLDriver *drv;
682
Chad Versace3c58d4c2013-10-11 16:04:55 -0700683 if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
Kyle Brennemance562f92017-01-04 11:31:58 -0700684 const char *ret = _eglGetClientExtensionString();
685 if (ret != NULL)
686 RETURN_EGL_SUCCESS(NULL, ret);
687 else
688 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
Chad Versace3c58d4c2013-10-11 16:04:55 -0700689 }
690
691 disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400692 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
Chia-I Wubef4b472010-02-19 12:08:50 +0800693 _EGL_CHECK_DISPLAY(disp, NULL, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800694
Matt Turner6c6e2a12015-03-13 17:00:26 -0700695 switch (name) {
696 case EGL_VENDOR:
697 RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
698 case EGL_VERSION:
699 RETURN_EGL_SUCCESS(disp, disp->VersionString);
700 case EGL_EXTENSIONS:
701 RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
702 case EGL_CLIENT_APIS:
703 RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
704 default:
705 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
706 }
Brian Pauladbff7e2005-04-22 21:09:39 +0000707}
708
709
Brian Paul1ed10272008-05-27 13:45:41 -0600710EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800711eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
712 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000713{
Chia-I Wu655f4652010-02-17 17:30:44 +0800714 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800715 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800716 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800717
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400718 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
719
Chia-I Wubef4b472010-02-19 12:08:50 +0800720 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800721 ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
722
Chia-I Wubef4b472010-02-19 12:08:50 +0800723 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000724}
725
726
Brian Paul1ed10272008-05-27 13:45:41 -0600727EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800728eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
729 EGLint config_size, EGLint *num_config)
Brian Pauladbff7e2005-04-22 21:09:39 +0000730{
Chia-I Wu655f4652010-02-17 17:30:44 +0800731 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800732 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800733 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800734
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400735 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
736
Chia-I Wubef4b472010-02-19 12:08:50 +0800737 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800738 ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +0100739 config_size, num_config);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800740
Chia-I Wubef4b472010-02-19 12:08:50 +0800741 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000742}
743
744
Brian Paul1ed10272008-05-27 13:45:41 -0600745EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800746eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
747 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000748{
Chia-I Wu655f4652010-02-17 17:30:44 +0800749 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800750 _EGLConfig *conf = _eglLookupConfig(config, disp);
751 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800752 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800753
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400754 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
755
Chia-I Wubef4b472010-02-19 12:08:50 +0800756 _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800757 ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
758
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 -0600763EGLContext EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800764eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
765 const EGLint *attrib_list)
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 _EGLContext *share = _eglLookupContext(share_list, disp);
770 _EGLDriver *drv;
771 _EGLContext *context;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800772 EGLContext ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800773
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400774 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
775
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800776 _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
777
Tapani Pälli5876f3c2016-10-20 14:11:16 +0300778 if (config != EGL_NO_CONFIG_KHR)
779 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
780 else if (!disp->Extensions.KHR_no_config_context)
Neil Roberts4b17dff2014-03-07 18:05:46 +0000781 RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
Kristian Høgsbergb90a3e72010-06-02 22:48:06 -0400782
Chia-I Wub3bb1802010-02-17 16:05:27 +0800783 if (!share && share_list != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800784 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800785
786 context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +0800787 ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800788
Chia-I Wubef4b472010-02-19 12:08:50 +0800789 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000790}
791
792
Brian Paul1ed10272008-05-27 13:45:41 -0600793EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +0000794eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
795{
Chia-I Wu655f4652010-02-17 17:30:44 +0800796 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800797 _EGLContext *context = _eglLookupContext(ctx, disp);
798 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800799 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800800
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400801 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
802
Chia-I Wubef4b472010-02-19 12:08:50 +0800803 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800804 _eglUnlinkContext(context);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800805 ret = drv->API.DestroyContext(drv, disp, context);
806
Chia-I Wubef4b472010-02-19 12:08:50 +0800807 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000808}
809
810
Brian Paul1ed10272008-05-27 13:45:41 -0600811EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800812eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
813 EGLContext ctx)
Brian Pauladbff7e2005-04-22 21:09:39 +0000814{
Chia-I Wu655f4652010-02-17 17:30:44 +0800815 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800816 _EGLContext *context = _eglLookupContext(ctx, disp);
817 _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
818 _EGLSurface *read_surf = _eglLookupSurface(read, disp);
819 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800820 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800821
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400822 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
823
Chia-I Wu17330472010-01-27 23:51:54 +0800824 if (!disp)
Chia-I Wubef4b472010-02-19 12:08:50 +0800825 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800826 drv = disp->Driver;
827
828 /* display is allowed to be uninitialized under certain condition */
829 if (!disp->Initialized) {
830 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
831 ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800832 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
Chia-I Wu17330472010-01-27 23:51:54 +0800833 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800834 if (!drv)
Chia-I Wubef4b472010-02-19 12:08:50 +0800835 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
Chia-I Wu17330472010-01-27 23:51:54 +0800836
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800837 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +0800838 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800839 if (!draw_surf || !read_surf) {
Beren Minor0ca0d572014-03-20 08:36:34 +0100840 /* From the EGL 1.4 (20130211) spec:
841 *
842 * To release the current context without assigning a new one, set ctx
843 * to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
844 */
845 if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
Chia-I Wu6b2f1562010-09-24 02:42:15 +0800846 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
847
848 if ((!draw_surf && draw != EGL_NO_SURFACE) ||
849 (!read_surf && read != EGL_NO_SURFACE))
850 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
851 if (draw_surf || read_surf)
852 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
853 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800854
Chad Versace23c86c72017-05-04 17:46:33 -0700855 /* If a native window underlying either draw or read is no longer valid,
856 * an EGL_BAD_NATIVE_WINDOW error is generated.
857 */
858 if (draw_surf && draw_surf->Lost)
859 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
860 if (read_surf && read_surf->Lost)
861 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
862
Chia-I Wub3bb1802010-02-17 16:05:27 +0800863 ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
864
Chia-I Wubef4b472010-02-19 12:08:50 +0800865 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000866}
867
868
Brian Paul1ed10272008-05-27 13:45:41 -0600869EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800870eglQueryContext(EGLDisplay dpy, EGLContext ctx,
871 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +0000872{
Chia-I Wu655f4652010-02-17 17:30:44 +0800873 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +0800874 _EGLContext *context = _eglLookupContext(ctx, disp);
875 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +0800876 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +0800877
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400878 _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
879
Chia-I Wubef4b472010-02-19 12:08:50 +0800880 _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +0800881 ret = drv->API.QueryContext(drv, disp, context, attribute, value);
882
Chia-I Wubef4b472010-02-19 12:08:50 +0800883 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +0000884}
885
886
Chad Versace468cc862014-01-23 07:26:10 -0800887static EGLSurface
888_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
889 void *native_window, const EGLint *attrib_list)
890{
891 _EGLConfig *conf = _eglLookupConfig(config, disp);
892 _EGLDriver *drv;
893 _EGLSurface *surf;
894 EGLSurface ret;
895
Sinclair Yeh91ff0d42014-06-03 14:00:13 -0700896
897 if (native_window == NULL)
898 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
899
Chad Versacea597c8a2016-10-12 15:48:15 -0700900#ifdef HAVE_SURFACELESS_PLATFORM
Chad Versace5e97b8f2016-12-13 14:23:55 -0800901 if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
Chad Versacea597c8a2016-10-12 15:48:15 -0700902 /* From the EGL_MESA_platform_surfaceless spec (v1):
903 *
904 * eglCreatePlatformWindowSurface fails when called with a <display>
905 * that belongs to the surfaceless platform. It returns
906 * EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
907 * justification for this unconditional failure is that the
908 * surfaceless platform has no native windows, and therefore the
909 * <native_window> parameter is always invalid.
910 *
911 * This check must occur before checking the EGLConfig, which emits
912 * EGL_BAD_CONFIG.
913 */
914 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
915 }
916#endif
917
918 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
919
Chad Versacefbb4af92016-12-16 11:00:13 -0800920 if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
921 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
922
Chad Versace468cc862014-01-23 07:26:10 -0800923 surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
924 attrib_list);
925 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
926
927 RETURN_EGL_EVAL(disp, ret);
928}
929
930
Brian Paul1ed10272008-05-27 13:45:41 -0600931EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +0800932eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +0800933 EGLNativeWindowType window, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +0000934{
Chia-I Wu655f4652010-02-17 17:30:44 +0800935 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400936
937 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -0800938 STATIC_ASSERT(sizeof(void*) == sizeof(window));
939 return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
940 attrib_list);
941}
942
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400943static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000944_fixupNativeWindow(_EGLDisplay *disp, void *native_window)
Chad Versace468cc862014-01-23 07:26:10 -0800945{
Chad Versace468cc862014-01-23 07:26:10 -0800946#ifdef HAVE_X11_PLATFORM
Emil Velikov26fbb9e2017-08-08 15:55:36 +0100947 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
Chad Versace468cc862014-01-23 07:26:10 -0800948 /* The `native_window` parameter for the X11 platform differs between
949 * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
950 * eglCreateWindowSurface(), the type of `native_window` is an Xlib
951 * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
952 * `Window*`. Convert `Window*` to `Window` because that's what
953 * dri2_x11_create_window_surface() expects.
954 */
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400955 return (void *)(* (Window*) native_window);
Chad Versace468cc862014-01-23 07:26:10 -0800956 }
957#endif
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400958 return native_window;
959}
960
961static EGLSurface EGLAPIENTRY
962eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
963 void *native_window,
964 const EGLint *attrib_list)
965{
966 _EGLDisplay *disp = _eglLockDisplay(dpy);
967
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000968 native_window = _fixupNativeWindow(disp, native_window);
Chad Versace468cc862014-01-23 07:26:10 -0800969
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400970 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace468cc862014-01-23 07:26:10 -0800971 return _eglCreateWindowSurfaceCommon(disp, config, native_window,
972 attrib_list);
973}
974
975
Marek Olšák820a4d42015-05-12 21:06:41 +0200976EGLSurface EGLAPIENTRY
977eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
978 void *native_window,
979 const EGLAttrib *attrib_list)
980{
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400981 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +0200982 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400983 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +0200984
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400985 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
986
987 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +0200988 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -0400989 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +0200990
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000991 native_window = _fixupNativeWindow(disp, native_window);
Kyle Brenneman7d7ae5e2016-09-12 17:04:38 -0400992 surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
993 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +0200994 free(int_attribs);
995 return surface;
996}
997
Kyle Brenneman8cc3d982016-09-12 17:25:56 -0400998static void *
Eric Engestrom4729e1b2016-12-08 00:36:02 +0000999_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001000{
1001#ifdef HAVE_X11_PLATFORM
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001002 /* The `native_pixmap` parameter for the X11 platform differs between
1003 * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
1004 * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
1005 * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
1006 * `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
1007 * dri2_x11_create_pixmap_surface() expects.
1008 */
Emil Velikov26fbb9e2017-08-08 15:55:36 +01001009 if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001010 return (void *)(* (Pixmap*) native_pixmap);
1011#endif
1012 return native_pixmap;
1013}
Marek Olšák820a4d42015-05-12 21:06:41 +02001014
Chad Versace468cc862014-01-23 07:26:10 -08001015static EGLSurface
1016_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
1017 void *native_pixmap, const EGLint *attrib_list)
1018{
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001019 _EGLConfig *conf = _eglLookupConfig(config, disp);
1020 _EGLDriver *drv;
1021 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001022 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001023
Chad Versacea597c8a2016-10-12 15:48:15 -07001024#if HAVE_SURFACELESS_PLATFORM
Chad Versace5e97b8f2016-12-13 14:23:55 -08001025 if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
Chad Versacea597c8a2016-10-12 15:48:15 -07001026 /* From the EGL_MESA_platform_surfaceless spec (v1):
1027 *
1028 * [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
1029 * also fails when called with a <display> that belongs to the
1030 * surfaceless platform. It returns EGL_NO_SURFACE and generates
1031 * EGL_BAD_NATIVE_PIXMAP.
1032 *
1033 * This check must occur before checking the EGLConfig, which emits
1034 * EGL_BAD_CONFIG.
1035 */
1036 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1037 }
1038#endif
1039
Chia-I Wubef4b472010-02-19 12:08:50 +08001040 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chad Versacefbb4af92016-12-16 11:00:13 -08001041
1042 if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
1043 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1044
Emil Velikovdf8efd52017-08-05 00:25:48 +01001045 if (native_pixmap == NULL)
1046 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1047
Chad Versace468cc862014-01-23 07:26:10 -08001048 surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
Chad Versace6d1f83e2014-01-07 14:54:51 -08001049 attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001050 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001051
Chia-I Wubef4b472010-02-19 12:08:50 +08001052 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001053}
1054
1055
Brian Paul1ed10272008-05-27 13:45:41 -06001056EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001057eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
Chia-I Wu4aed0942010-01-25 11:55:48 +08001058 EGLNativePixmapType pixmap, const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001059{
Chia-I Wu655f4652010-02-17 17:30:44 +08001060 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001061
1062 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001063 STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
Chad Versace468cc862014-01-23 07:26:10 -08001064 return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001065 attrib_list);
Chad Versace468cc862014-01-23 07:26:10 -08001066}
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001067
Emil Velikove3cc5ad2015-05-11 23:43:48 +01001068static EGLSurface EGLAPIENTRY
Chad Versace468cc862014-01-23 07:26:10 -08001069eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001070 void *native_pixmap,
1071 const EGLint *attrib_list)
Chad Versace468cc862014-01-23 07:26:10 -08001072{
1073 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001074
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001075 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001076 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Chad Versace468cc862014-01-23 07:26:10 -08001077 return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1078 attrib_list);
Brian Pauladbff7e2005-04-22 21:09:39 +00001079}
1080
1081
Brian Paul1ed10272008-05-27 13:45:41 -06001082EGLSurface EGLAPIENTRY
Marek Olšák820a4d42015-05-12 21:06:41 +02001083eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
1084 void *native_pixmap,
1085 const EGLAttrib *attrib_list)
1086{
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001087 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák820a4d42015-05-12 21:06:41 +02001088 EGLSurface surface;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001089 EGLint *int_attribs;
Marek Olšák820a4d42015-05-12 21:06:41 +02001090
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001091 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1092
1093 int_attribs = _eglConvertAttribsToInt(attrib_list);
Marek Olšák820a4d42015-05-12 21:06:41 +02001094 if (attrib_list && !int_attribs)
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001095 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
Marek Olšák820a4d42015-05-12 21:06:41 +02001096
Eric Engestrom4729e1b2016-12-08 00:36:02 +00001097 native_pixmap = _fixupNativePixmap(disp, native_pixmap);
Kyle Brenneman8cc3d982016-09-12 17:25:56 -04001098 surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1099 int_attribs);
Marek Olšák820a4d42015-05-12 21:06:41 +02001100 free(int_attribs);
1101 return surface;
1102}
1103
1104
1105EGLSurface EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001106eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
1107 const EGLint *attrib_list)
Brian Pauladbff7e2005-04-22 21:09:39 +00001108{
Chia-I Wu655f4652010-02-17 17:30:44 +08001109 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001110 _EGLConfig *conf = _eglLookupConfig(config, disp);
1111 _EGLDriver *drv;
1112 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001113 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001114
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001115 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001116 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001117
Chad Versacefbb4af92016-12-16 11:00:13 -08001118 if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
1119 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1120
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001121 surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001122 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001123
Chia-I Wubef4b472010-02-19 12:08:50 +08001124 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001125}
1126
1127
Brian Paul1ed10272008-05-27 13:45:41 -06001128EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001129eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
1130{
Chia-I Wu655f4652010-02-17 17:30:44 +08001131 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001132 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1133 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001134 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001135
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001136 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001137 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001138 _eglUnlinkSurface(surf);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001139 ret = drv->API.DestroySurface(drv, disp, surf);
1140
Chia-I Wubef4b472010-02-19 12:08:50 +08001141 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001142}
1143
Brian Paul1ed10272008-05-27 13:45:41 -06001144EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001145eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
1146 EGLint attribute, EGLint *value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001147{
Chia-I Wu655f4652010-02-17 17:30:44 +08001148 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001149 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1150 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001151 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001152
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001153 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001154 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001155 ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
1156
Chia-I Wubef4b472010-02-19 12:08:50 +08001157 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001158}
1159
Brian Paul1ed10272008-05-27 13:45:41 -06001160EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001161eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
1162 EGLint attribute, EGLint value)
Brian Pauladbff7e2005-04-22 21:09:39 +00001163{
Chia-I Wu655f4652010-02-17 17:30:44 +08001164 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001165 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1166 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001167 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001168
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001169 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001170 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001171 ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
1172
Chia-I Wubef4b472010-02-19 12:08:50 +08001173 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001174}
1175
1176
Brian Paul1ed10272008-05-27 13:45:41 -06001177EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001178eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1179{
Chia-I Wu655f4652010-02-17 17:30:44 +08001180 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001181 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1182 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001183 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001184
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001185 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001186 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001187 ret = drv->API.BindTexImage(drv, disp, surf, buffer);
1188
Chia-I Wubef4b472010-02-19 12:08:50 +08001189 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001190}
1191
1192
Brian Paul1ed10272008-05-27 13:45:41 -06001193EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001194eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1195{
Chia-I Wu655f4652010-02-17 17:30:44 +08001196 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001197 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1198 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001199 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001200
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001201 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001202 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001203 ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
1204
Chia-I Wubef4b472010-02-19 12:08:50 +08001205 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001206}
1207
1208
Brian Paul1ed10272008-05-27 13:45:41 -06001209EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001210eglSwapInterval(EGLDisplay dpy, EGLint interval)
1211{
Chia-I Wu655f4652010-02-17 17:30:44 +08001212 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu57da4992009-10-15 11:08:48 +08001213 _EGLContext *ctx = _eglGetCurrentContext();
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001214 _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
Chia-I Wuaed73582010-02-17 15:43:47 +08001215 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001216 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001217
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001218 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001219 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu57da4992009-10-15 11:08:48 +08001220
Chia-I Wud19afc52010-10-23 12:52:26 +08001221 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1222 ctx->Resource.Display != disp)
Chia-I Wubef4b472010-02-19 12:08:50 +08001223 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001224
Chia-I Wud19afc52010-10-23 12:52:26 +08001225 if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001226 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Chia-I Wu57da4992009-10-15 11:08:48 +08001227
Emil Velikov64b4ccd2018-09-03 13:05:22 +01001228 if (surf->Type != EGL_WINDOW_BIT)
1229 RETURN_EGL_EVAL(disp, EGL_TRUE);
1230
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001231 interval = CLAMP(interval,
1232 surf->Config->MinSwapInterval,
1233 surf->Config->MaxSwapInterval);
1234
Eric Engestromdd9eb8d2017-08-02 17:25:44 +01001235 if (surf->SwapInterval != interval)
Eric Engestrom2714a8f2017-07-31 14:49:31 +01001236 ret = drv->API.SwapInterval(drv, disp, surf, interval);
1237 else
1238 ret = EGL_TRUE;
1239
1240 if (ret)
1241 surf->SwapInterval = interval;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001242
Chia-I Wubef4b472010-02-19 12:08:50 +08001243 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001244}
1245
1246
Brian Paul1ed10272008-05-27 13:45:41 -06001247EGLBoolean EGLAPIENTRY
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001248eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
Brian Pauladbff7e2005-04-22 21:09:39 +00001249{
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001250 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu655f4652010-02-17 17:30:44 +08001251 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001252 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1253 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001254 EGLBoolean ret;
Chia-I Wuaed73582010-02-17 15:43:47 +08001255
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001256 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chia-I Wubef4b472010-02-19 12:08:50 +08001257 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001258
1259 /* surface must be bound to current context in EGL 1.4 */
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001260 #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
Chia-I Wud19afc52010-10-23 12:52:26 +08001261 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1262 surf != ctx->DrawSurface)
Chia-I Wubef4b472010-02-19 12:08:50 +08001263 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
Alexander von Gluck IV400b8332014-12-22 10:10:13 -05001264 #endif
Chia-I Wubbfd0e22009-10-15 11:08:33 +08001265
Emil Velikov8f667432018-09-03 13:05:23 +01001266 if (surf->Type != EGL_WINDOW_BIT)
1267 RETURN_EGL_EVAL(disp, EGL_TRUE);
1268
Chad Versace23c86c72017-05-04 17:46:33 -07001269 /* From the EGL 1.5 spec:
1270 *
1271 * If eglSwapBuffers is called and the native window associated with
1272 * surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
1273 * generated.
1274 */
1275 if (surf->Lost)
1276 RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
1277
Chia-I Wub3bb1802010-02-17 16:05:27 +08001278 ret = drv->API.SwapBuffers(drv, disp, surf);
1279
Harish Krupo98275472017-06-09 20:13:34 +05301280 /* EGL_KHR_partial_update
1281 * Frame boundary successfully reached,
1282 * reset damage region and reset BufferAgeRead
1283 */
1284 if (ret) {
1285 surf->SetDamageRegionCalled = EGL_FALSE;
1286 surf->BufferAgeRead = EGL_FALSE;
1287 }
1288
Chia-I Wubef4b472010-02-19 12:08:50 +08001289 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001290}
1291
1292
Eric Engestrom0a606a42016-10-10 17:33:17 +01001293static EGLBoolean
Eric Engestrom9702f912016-11-16 22:29:53 +00001294_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
1295 EGLint *rects, EGLint n_rects)
Robert Bragg6425b142013-04-25 13:41:42 +01001296{
1297 _EGLContext *ctx = _eglGetCurrentContext();
Robert Bragg6425b142013-04-25 13:41:42 +01001298 _EGLDriver *drv;
1299 EGLBoolean ret;
1300
1301 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1302
1303 /* surface must be bound to current context in EGL 1.4 */
1304 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1305 surf != ctx->DrawSurface)
1306 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1307
Emil Velikov8f667432018-09-03 13:05:23 +01001308 if (surf->Type != EGL_WINDOW_BIT)
1309 RETURN_EGL_EVAL(disp, EGL_TRUE);
1310
Robert Bragg6425b142013-04-25 13:41:42 +01001311 if ((n_rects > 0 && rects == NULL) || n_rects < 0)
1312 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1313
1314 ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
1315
Harish Krupo98275472017-06-09 20:13:34 +05301316 /* EGL_KHR_partial_update
1317 * Frame boundary successfully reached,
1318 * reset damage region and reset BufferAgeRead
1319 */
1320 if (ret) {
1321 surf->SetDamageRegionCalled = EGL_FALSE;
1322 surf->BufferAgeRead = EGL_FALSE;
1323 }
1324
Robert Bragg6425b142013-04-25 13:41:42 +01001325 RETURN_EGL_EVAL(disp, ret);
1326}
1327
Eric Engestrom0a606a42016-10-10 17:33:17 +01001328static EGLBoolean EGLAPIENTRY
1329eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
1330 EGLint *rects, EGLint n_rects)
1331{
1332 _EGLDisplay *disp = _eglLockDisplay(dpy);
1333 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1334 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001335 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001336}
1337
1338static EGLBoolean EGLAPIENTRY
1339eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
1340 EGLint *rects, EGLint n_rects)
1341{
1342 _EGLDisplay *disp = _eglLockDisplay(dpy);
1343 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1344 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Eric Engestrom9702f912016-11-16 22:29:53 +00001345 return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
Eric Engestrom0a606a42016-10-10 17:33:17 +01001346}
1347
Harish Krupo98275472017-06-09 20:13:34 +05301348/**
Harish Krupofd734602018-07-08 12:53:00 +05301349 * Clamp the rectangles so that they lie within the surface.
Harish Krupo98275472017-06-09 20:13:34 +05301350 */
1351
1352static void
1353_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf,
1354 EGLint *rects, EGLint n_rects)
1355{
1356 EGLint i;
1357 EGLint surf_height = surf->Height;
1358 EGLint surf_width = surf->Width;
1359
1360 for (i = 0; i < (4 * n_rects); i += 4) {
Harish Krupofd734602018-07-08 12:53:00 +05301361 EGLint x1, y1, x2, y2;
1362 x1 = rects[i];
1363 y1 = rects[i + 1];
1364 x2 = rects[i + 2] + x1;
1365 y2 = rects[i + 3] + y1;
Harish Krupo98275472017-06-09 20:13:34 +05301366
Harish Krupofd734602018-07-08 12:53:00 +05301367 rects[i] = CLAMP(x1, 0, surf_width);
1368 rects[i + 1] = CLAMP(y1, 0, surf_height);
1369 rects[i + 2] = CLAMP(x2, 0, surf_width) - rects[i];
1370 rects[i + 3] = CLAMP(y2, 0, surf_height) - rects[i + 1];
Harish Krupo98275472017-06-09 20:13:34 +05301371 }
1372}
1373
1374static EGLBoolean EGLAPIENTRY
1375eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
1376 EGLint *rects, EGLint n_rects)
1377{
1378 _EGLDisplay *disp = _eglLockDisplay(dpy);
1379 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1380 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1381 _EGLContext *ctx = _eglGetCurrentContext();
1382 _EGLDriver *drv;
1383 EGLBoolean ret;
1384 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1385
1386 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1387 surf->Type != EGL_WINDOW_BIT ||
1388 ctx->DrawSurface != surf ||
1389 surf->SwapBehavior != EGL_BUFFER_DESTROYED)
1390 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1391
1392 /* If the damage region is already set or
1393 * buffer age is not queried between
1394 * frame boundaries, throw bad access error
1395 */
1396
1397 if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
1398 RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
1399
1400 _eglSetDamageRegionKHRClampRects(disp, surf, rects, n_rects);
1401 ret = drv->API.SetDamageRegion(drv, disp, surf, rects, n_rects);
1402
1403 if (ret)
1404 surf->SetDamageRegionCalled = EGL_TRUE;
1405
1406 RETURN_EGL_EVAL(disp, ret);
1407}
1408
Brian Paul1ed10272008-05-27 13:45:41 -06001409EGLBoolean EGLAPIENTRY
Chia-I Wu4aed0942010-01-25 11:55:48 +08001410eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
Brian Pauladbff7e2005-04-22 21:09:39 +00001411{
Chia-I Wu655f4652010-02-17 17:30:44 +08001412 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wuaed73582010-02-17 15:43:47 +08001413 _EGLSurface *surf = _eglLookupSurface(surface, disp);
1414 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001415 EGLBoolean ret;
Chad Versace6d1f83e2014-01-07 14:54:51 -08001416 void *native_pixmap_ptr;
1417
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001418 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001419 STATIC_ASSERT(sizeof(void*) == sizeof(target));
1420 native_pixmap_ptr = (void*) target;
Chia-I Wuaed73582010-02-17 15:43:47 +08001421
Chia-I Wubef4b472010-02-19 12:08:50 +08001422 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
Chad Versace6d1f83e2014-01-07 14:54:51 -08001423 ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001424
Chia-I Wubef4b472010-02-19 12:08:50 +08001425 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001426}
1427
1428
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001429static EGLBoolean
1430_eglWaitClientCommon(void)
Brian Pauladbff7e2005-04-22 21:09:39 +00001431{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001432 _EGLContext *ctx = _eglGetCurrentContext();
1433 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001434 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001435 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001436
Chia-I Wu6c21c882009-09-28 14:12:39 +08001437 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001438 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001439
1440 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001441 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001442
1443 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001444 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1445 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001446 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001447
Chia-I Wu6c21c882009-09-28 14:12:39 +08001448 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001449 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001450 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001451 ret = drv->API.WaitClient(drv, disp, ctx);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001452
Chia-I Wubef4b472010-02-19 12:08:50 +08001453 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu6c21c882009-09-28 14:12:39 +08001454}
1455
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001456EGLBoolean EGLAPIENTRY
1457eglWaitClient(void)
1458{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001459 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001460 return _eglWaitClientCommon();
1461}
Chia-I Wu6c21c882009-09-28 14:12:39 +08001462
1463EGLBoolean EGLAPIENTRY
1464eglWaitGL(void)
1465{
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001466 /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001467 _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
Kyle Brenneman82a2e2c2016-09-12 17:35:22 -04001468 return _eglWaitClientCommon();
Brian Pauladbff7e2005-04-22 21:09:39 +00001469}
1470
1471
Brian Paul1ed10272008-05-27 13:45:41 -06001472EGLBoolean EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001473eglWaitNative(EGLint engine)
1474{
Chia-I Wu6c21c882009-09-28 14:12:39 +08001475 _EGLContext *ctx = _eglGetCurrentContext();
1476 _EGLDisplay *disp;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001477 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001478 EGLBoolean ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001479
Chia-I Wu6c21c882009-09-28 14:12:39 +08001480 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001481 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001482
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001483 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1484
Chia-I Wu655f4652010-02-17 17:30:44 +08001485 disp = ctx->Resource.Display;
Emil Velikovefe87f12015-03-06 16:54:55 +00001486 mtx_lock(&disp->Mutex);
Chia-I Wu655f4652010-02-17 17:30:44 +08001487
Chia-I Wu6c21c882009-09-28 14:12:39 +08001488 /* let bad current context imply bad current surface */
Chia-I Wud19afc52010-10-23 12:52:26 +08001489 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1490 _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
Chia-I Wubef4b472010-02-19 12:08:50 +08001491 RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001492
Chia-I Wu6c21c882009-09-28 14:12:39 +08001493 /* a valid current context implies an initialized current display */
Chia-I Wua9332592010-01-27 23:55:58 +08001494 assert(disp->Initialized);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001495 drv = disp->Driver;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001496 ret = drv->API.WaitNative(drv, disp, engine);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001497
Chia-I Wubef4b472010-02-19 12:08:50 +08001498 RETURN_EGL_EVAL(disp, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001499}
1500
1501
Brian Paul1ed10272008-05-27 13:45:41 -06001502EGLDisplay EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001503eglGetCurrentDisplay(void)
1504{
Chia-I Wua1717972010-01-26 17:13:51 +08001505 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001506 EGLDisplay ret;
1507
1508 ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
1509
Chia-I Wubef4b472010-02-19 12:08:50 +08001510 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001511}
1512
1513
Brian Paul1ed10272008-05-27 13:45:41 -06001514EGLContext EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001515eglGetCurrentContext(void)
1516{
1517 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001518 EGLContext ret;
1519
1520 ret = _eglGetContextHandle(ctx);
1521
Chia-I Wubef4b472010-02-19 12:08:50 +08001522 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001523}
1524
1525
Brian Paul1ed10272008-05-27 13:45:41 -06001526EGLSurface EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001527eglGetCurrentSurface(EGLint readdraw)
1528{
Chia-I Wu61906632009-09-30 15:34:45 +08001529 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001530 EGLint err = EGL_SUCCESS;
Chia-I Wu61906632009-09-30 15:34:45 +08001531 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001532 EGLSurface ret;
Chia-I Wu61906632009-09-30 15:34:45 +08001533
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001534 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
1535
Chia-I Wu61906632009-09-30 15:34:45 +08001536 if (!ctx)
Chia-I Wubef4b472010-02-19 12:08:50 +08001537 RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
Chia-I Wu61906632009-09-30 15:34:45 +08001538
1539 switch (readdraw) {
1540 case EGL_DRAW:
1541 surf = ctx->DrawSurface;
1542 break;
1543 case EGL_READ:
1544 surf = ctx->ReadSurface;
1545 break;
1546 default:
Chia-I Wu61906632009-09-30 15:34:45 +08001547 surf = NULL;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001548 err = EGL_BAD_PARAMETER;
Chia-I Wu61906632009-09-30 15:34:45 +08001549 break;
1550 }
1551
Chia-I Wub3bb1802010-02-17 16:05:27 +08001552 ret = _eglGetSurfaceHandle(surf);
1553
Chia-I Wubef4b472010-02-19 12:08:50 +08001554 RETURN_EGL_ERROR(NULL, err, ret);
Brian Pauladbff7e2005-04-22 21:09:39 +00001555}
1556
1557
Brian Paul1ed10272008-05-27 13:45:41 -06001558EGLint EGLAPIENTRY
Brian Pauladbff7e2005-04-22 21:09:39 +00001559eglGetError(void)
1560{
Brian Paul48822792005-12-10 17:54:00 +00001561 _EGLThreadInfo *t = _eglGetCurrentThread();
1562 EGLint e = t->LastError;
Chia-I Wu75da80b2009-07-17 11:41:02 -06001563 if (!_eglIsCurrentThreadDummy())
1564 t->LastError = EGL_SUCCESS;
Brian Pauladbff7e2005-04-22 21:09:39 +00001565 return e;
1566}
1567
1568
Brian Paulb2006a42006-01-30 00:10:55 +00001569/**
1570 ** EGL 1.2
1571 **/
1572
Brian Pauld5078b92008-05-30 13:45:40 -06001573/**
1574 * Specify the client API to use for subsequent calls including:
1575 * eglCreateContext()
1576 * eglGetCurrentContext()
1577 * eglGetCurrentDisplay()
1578 * eglGetCurrentSurface()
1579 * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1580 * eglWaitClient()
1581 * eglWaitNative()
1582 * See section 3.7 "Rendering Context" in the EGL specification for details.
1583 */
nobledc43ab4f2010-07-02 19:38:07 -04001584EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001585eglBindAPI(EGLenum api)
1586{
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001587 _EGLThreadInfo *t;
Brian Paulb2006a42006-01-30 00:10:55 +00001588
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001589 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1590
1591 t = _eglGetCurrentThread();
Chia-I Wu75da80b2009-07-17 11:41:02 -06001592 if (_eglIsCurrentThreadDummy())
Chia-I Wubef4b472010-02-19 12:08:50 +08001593 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
Chia-I Wu75da80b2009-07-17 11:41:02 -06001594
Chia-I Wu21b635f2009-07-17 11:42:04 -06001595 if (!_eglIsApiValid(api))
Chia-I Wubef4b472010-02-19 12:08:50 +08001596 RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wu21b635f2009-07-17 11:42:04 -06001597
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001598 t->CurrentAPI = api;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001599
Chia-I Wubef4b472010-02-19 12:08:50 +08001600 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001601}
Jon Smirl7012d012005-05-13 18:31:35 +00001602
1603
Brian Pauld5078b92008-05-30 13:45:40 -06001604/**
1605 * Return the last value set with eglBindAPI().
1606 */
nobledc43ab4f2010-07-02 19:38:07 -04001607EGLenum EGLAPIENTRY
Brian Pauld5078b92008-05-30 13:45:40 -06001608eglQueryAPI(void)
1609{
Brian Pauld5078b92008-05-30 13:45:40 -06001610 _EGLThreadInfo *t = _eglGetCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001611 EGLenum ret;
1612
1613 /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001614 ret = t->CurrentAPI;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001615
Chia-I Wubef4b472010-02-19 12:08:50 +08001616 RETURN_EGL_SUCCESS(NULL, ret);
Brian Pauld5078b92008-05-30 13:45:40 -06001617}
1618
1619
nobledc43ab4f2010-07-02 19:38:07 -04001620EGLSurface EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001621eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1622 EGLClientBuffer buffer, EGLConfig config,
1623 const EGLint *attrib_list)
1624{
Chia-I Wu655f4652010-02-17 17:30:44 +08001625 _EGLDisplay *disp = _eglLockDisplay(dpy);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001626 _EGLConfig *conf = _eglLookupConfig(config, disp);
1627 _EGLDriver *drv;
1628 _EGLSurface *surf;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001629 EGLSurface ret;
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001630
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001631 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1632
Chia-I Wubef4b472010-02-19 12:08:50 +08001633 _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001634
1635 surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1636 conf, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001637 ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001638
Chia-I Wubef4b472010-02-19 12:08:50 +08001639 RETURN_EGL_EVAL(disp, ret);
Brian Paulb2006a42006-01-30 00:10:55 +00001640}
Jon Smirl7012d012005-05-13 18:31:35 +00001641
Brian Paulb2006a42006-01-30 00:10:55 +00001642
nobledc43ab4f2010-07-02 19:38:07 -04001643EGLBoolean EGLAPIENTRY
Brian Paulb2006a42006-01-30 00:10:55 +00001644eglReleaseThread(void)
1645{
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001646 /* unbind current contexts */
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001647 if (!_eglIsCurrentThreadDummy()) {
Chia-I Wu11cf3cb2010-01-26 17:22:21 +08001648 _EGLThreadInfo *t = _eglGetCurrentThread();
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001649 _EGLContext *ctx = t->CurrentContext;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001650
1651 _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1652
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001653 if (ctx) {
1654 _EGLDisplay *disp = ctx->Resource.Display;
1655 _EGLDriver *drv;
Chia-I Wu655f4652010-02-17 17:30:44 +08001656
Kyle Brenneman6e066f72016-07-08 15:21:17 -06001657 mtx_lock(&disp->Mutex);
1658 drv = disp->Driver;
1659 (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1660 mtx_unlock(&disp->Mutex);
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001661 }
Brian Paulb2006a42006-01-30 00:10:55 +00001662 }
Chia-I Wu2f2cf462009-08-11 17:09:39 +08001663
Chia-I Wu75da80b2009-07-17 11:41:02 -06001664 _eglDestroyCurrentThread();
Chia-I Wub3bb1802010-02-17 16:05:27 +08001665
Chia-I Wubef4b472010-02-19 12:08:50 +08001666 RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
Brian Paulb2006a42006-01-30 00:10:55 +00001667}
1668
1669
Kyle Brenneman58338c62016-09-12 17:38:13 -04001670static EGLImage
1671_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001672 EGLClientBuffer buffer, const EGLint *attr_list)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001673{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001674 _EGLContext *context = _eglLookupContext(ctx, disp);
1675 _EGLDriver *drv;
1676 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02001677 EGLImage ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001678
Chia-I Wubef4b472010-02-19 12:08:50 +08001679 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001680 if (!disp->Extensions.KHR_image_base)
1681 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001682 if (!context && ctx != EGL_NO_CONTEXT)
Chia-I Wubef4b472010-02-19 12:08:50 +08001683 RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
Topi Pohjolainen0de013b2013-03-22 14:31:01 +02001684 /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1685 * <ctx> must be EGL_NO_CONTEXT..."
1686 */
1687 if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1688 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001689
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001690 img = drv->API.CreateImageKHR(drv, disp, context, target,
1691 buffer, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001692 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001693
Chia-I Wubef4b472010-02-19 12:08:50 +08001694 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001695}
1696
Kyle Brenneman58338c62016-09-12 17:38:13 -04001697static EGLImage EGLAPIENTRY
1698eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1699 EGLClientBuffer buffer, const EGLint *attr_list)
1700{
1701 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001702 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
Kyle Brenneman58338c62016-09-12 17:38:13 -04001703 return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
1704}
1705
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001706
Marek Olšák515f04e2015-05-12 20:42:05 +02001707EGLImage EGLAPIENTRY
1708eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1709 EGLClientBuffer buffer, const EGLAttrib *attr_list)
1710{
Kyle Brenneman58338c62016-09-12 17:38:13 -04001711 _EGLDisplay *disp = _eglLockDisplay(dpy);
Marek Olšák515f04e2015-05-12 20:42:05 +02001712 EGLImage image;
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001713 EGLint *int_attribs;
Marek Olšák515f04e2015-05-12 20:42:05 +02001714
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001715 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
1716
1717 int_attribs = _eglConvertAttribsToInt(attr_list);
Marek Olšák515f04e2015-05-12 20:42:05 +02001718 if (attr_list && !int_attribs)
Kyle Brenneman58338c62016-09-12 17:38:13 -04001719 RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
Marek Olšák515f04e2015-05-12 20:42:05 +02001720
Kyle Brenneman58338c62016-09-12 17:38:13 -04001721 image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
Marek Olšák515f04e2015-05-12 20:42:05 +02001722 free(int_attribs);
1723 return image;
1724}
1725
1726
Eric Engestromdf7fa302017-02-21 23:56:44 +00001727static EGLBoolean
1728_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001729{
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001730 _EGLDriver *drv;
Chia-I Wub3bb1802010-02-17 16:05:27 +08001731 EGLBoolean ret;
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001732
Chia-I Wubef4b472010-02-19 12:08:50 +08001733 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001734 if (!disp->Extensions.KHR_image_base)
1735 RETURN_EGL_EVAL(disp, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001736 if (!img)
Chia-I Wubef4b472010-02-19 12:08:50 +08001737 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001738
1739 _eglUnlinkImage(img);
Chia-I Wub3bb1802010-02-17 16:05:27 +08001740 ret = drv->API.DestroyImageKHR(drv, disp, img);
1741
Chia-I Wubef4b472010-02-19 12:08:50 +08001742 RETURN_EGL_EVAL(disp, ret);
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001743}
1744
Eric Engestromdf7fa302017-02-21 23:56:44 +00001745EGLBoolean EGLAPIENTRY
1746eglDestroyImage(EGLDisplay dpy, EGLImage image)
1747{
1748 _EGLDisplay *disp = _eglLockDisplay(dpy);
1749 _EGLImage *img = _eglLookupImage(image, disp);
1750 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1751 return _eglDestroyImageCommon(disp, img);
1752}
1753
1754static EGLBoolean EGLAPIENTRY
1755eglDestroyImageKHR(EGLDisplay dpy, EGLImage image)
1756{
1757 _EGLDisplay *disp = _eglLockDisplay(dpy);
1758 _EGLImage *img = _eglLookupImage(image, disp);
1759 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1760 return _eglDestroyImageCommon(disp, img);
1761}
1762
Chia-I Wua1c4a8a2009-08-15 22:58:13 +08001763
Marek Olšákd333d302015-05-12 17:34:57 +02001764static EGLSync
Chad Versace80448852016-09-27 13:27:21 -07001765_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
1766 EGLBoolean orig_is_EGLAttrib,
Marek Olšák51c8c662015-05-12 21:41:32 +02001767 EGLenum invalid_type_error)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001768{
Marek Olšák9a0bda22015-04-10 10:56:02 +02001769 _EGLContext *ctx = _eglGetCurrentContext();
Chia-I Wu4eebea72010-08-14 23:09:12 +08001770 _EGLDriver *drv;
1771 _EGLSync *sync;
Marek Olšákd333d302015-05-12 17:34:57 +02001772 EGLSync ret;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001773
1774 _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001775
Chad Versace80448852016-09-27 13:27:21 -07001776 if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
Chad Versacef2c2f432016-09-27 13:27:12 -07001777 /* There exist two EGLAttrib variants of eglCreateSync*:
1778 * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
1779 * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
1780 * support as a proxy for EGL 1.5 support, even though that's not
1781 * entirely correct (though _eglComputeVersion does the same).
1782 *
1783 * The EGL spec provides no guidance on how to handle unsupported
1784 * functions. EGL_BAD_MATCH seems reasonable.
1785 */
1786 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1787 }
Marek Olšák290a3eb2015-04-10 13:16:30 +02001788
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001789 /* If type is EGL_SYNC_FENCE and no context is current for the bound API
1790 * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH
1791 * error is generated.
1792 */
Rob Clark0201f012016-11-18 08:39:33 -05001793 if (!ctx &&
1794 (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001795 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1796
Marek Olšák9a0bda22015-04-10 10:56:02 +02001797 /* return an error if the client API doesn't support GL_OES_EGL_sync */
Tapani Pälli6bf6fcf2016-10-25 11:29:53 +03001798 if (ctx && (ctx->Resource.Display != disp ||
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01001799 ctx->ClientAPI != EGL_OPENGL_ES_API))
Marek Olšák9a0bda22015-04-10 10:56:02 +02001800 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1801
1802 switch (type) {
1803 case EGL_SYNC_FENCE_KHR:
1804 if (!disp->Extensions.KHR_fence_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001805 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001806 break;
1807 case EGL_SYNC_REUSABLE_KHR:
1808 if (!disp->Extensions.KHR_reusable_sync)
Marek Olšák51c8c662015-05-12 21:41:32 +02001809 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001810 break;
Marek Olšák290a3eb2015-04-10 13:16:30 +02001811 case EGL_SYNC_CL_EVENT_KHR:
1812 if (!disp->Extensions.KHR_cl_event2)
Marek Olšák51c8c662015-05-12 21:41:32 +02001813 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001814 break;
Rob Clark0201f012016-11-18 08:39:33 -05001815 case EGL_SYNC_NATIVE_FENCE_ANDROID:
1816 if (!disp->Extensions.ANDROID_native_fence_sync)
1817 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1818 break;
Marek Olšák9a0bda22015-04-10 10:56:02 +02001819 default:
Marek Olšák51c8c662015-05-12 21:41:32 +02001820 RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001821 }
Chia-I Wu4eebea72010-08-14 23:09:12 +08001822
Chad Versace80448852016-09-27 13:27:21 -07001823 sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08001824 ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
Chia-I Wu4eebea72010-08-14 23:09:12 +08001825
1826 RETURN_EGL_EVAL(disp, ret);
1827}
1828
1829
Marek Olšákd333d302015-05-12 17:34:57 +02001830static EGLSync EGLAPIENTRY
Chad Versace80448852016-09-27 13:27:21 -07001831eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001832{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001833 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001834 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001835
1836 EGLSync sync;
1837 EGLAttrib *attrib_list;
1838 EGLint err;
1839
1840 if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
1841 attrib_list = (EGLAttrib *) int_list;
1842 } else {
1843 err = _eglConvertIntsToAttribs(int_list, &attrib_list);
1844 if (err != EGL_SUCCESS)
1845 RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
1846 }
1847
1848 sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001849 EGL_BAD_ATTRIBUTE);
Chad Versace80448852016-09-27 13:27:21 -07001850
1851 if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
1852 free(attrib_list);
1853
1854 /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
1855 return sync;
Marek Olšák51c8c662015-05-12 21:41:32 +02001856}
1857
1858
1859static EGLSync EGLAPIENTRY
1860eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1861{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001862 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001863 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001864 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001865 EGL_BAD_ATTRIBUTE);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001866}
1867
1868
Marek Olšák2885ba02015-05-12 20:54:22 +02001869EGLSync EGLAPIENTRY
1870eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
Marek Olšák290a3eb2015-04-10 13:16:30 +02001871{
Kyle Brenneman9a992032016-09-12 17:40:29 -04001872 _EGLDisplay *disp = _eglLockDisplay(dpy);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001873 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
Chad Versace80448852016-09-27 13:27:21 -07001874 return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
Marek Olšák51c8c662015-05-12 21:41:32 +02001875 EGL_BAD_PARAMETER);
Marek Olšák290a3eb2015-04-10 13:16:30 +02001876}
1877
1878
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001879static EGLBoolean
1880_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001881{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001882 _EGLDriver *drv;
1883 EGLBoolean ret;
1884
1885 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001886 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05001887 disp->Extensions.KHR_fence_sync ||
1888 disp->Extensions.ANDROID_native_fence_sync);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08001889
Chia-I Wu4eebea72010-08-14 23:09:12 +08001890 _eglUnlinkSync(s);
1891 ret = drv->API.DestroySyncKHR(drv, disp, s);
1892
1893 RETURN_EGL_EVAL(disp, ret);
1894}
1895
Eric Engestromb7f6f3b2017-02-21 23:56:45 +00001896EGLBoolean EGLAPIENTRY
1897eglDestroySync(EGLDisplay dpy, EGLSync sync)
1898{
1899 _EGLDisplay *disp = _eglLockDisplay(dpy);
1900 _EGLSync *s = _eglLookupSync(sync, disp);
1901 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1902 return _eglDestroySync(disp, s);
1903}
1904
1905static EGLBoolean EGLAPIENTRY
1906eglDestroySyncKHR(EGLDisplay dpy, EGLSync sync)
1907{
1908 _EGLDisplay *disp = _eglLockDisplay(dpy);
1909 _EGLSync *s = _eglLookupSync(sync, disp);
1910 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1911 return _eglDestroySync(disp, s);
1912}
1913
Chia-I Wu4eebea72010-08-14 23:09:12 +08001914
Eric Engestrom66d5ec52017-02-21 23:56:46 +00001915static EGLint
1916_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
1917 _EGLSync *s, EGLint flags, EGLTime timeout)
Chia-I Wu4eebea72010-08-14 23:09:12 +08001918{
Chia-I Wu4eebea72010-08-14 23:09:12 +08001919 _EGLDriver *drv;
1920 EGLint ret;
1921
1922 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001923 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05001924 disp->Extensions.KHR_fence_sync ||
1925 disp->Extensions.ANDROID_native_fence_sync);
Marek Olšák9a0bda22015-04-10 10:56:02 +02001926
1927 if (s->SyncStatus == EGL_SIGNALED_KHR)
1928 RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
1929
Dongwon Kim70299472016-04-04 17:14:10 -07001930 /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
1931 * unlocked here to allow other threads also to be able to
1932 * go into waiting state.
1933 */
1934
1935 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1936 _eglUnlockDisplay(dpy);
1937
Chia-I Wu4eebea72010-08-14 23:09:12 +08001938 ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1939
Dongwon Kim70299472016-04-04 17:14:10 -07001940 /*
1941 * 'disp' is already unlocked for reusable sync type,
1942 * so passing 'NULL' to bypass unlocking display.
1943 */
1944 if (s->Type == EGL_SYNC_REUSABLE_KHR)
1945 RETURN_EGL_EVAL(NULL, ret);
1946 else
1947 RETURN_EGL_EVAL(disp, ret);
Chia-I Wu4eebea72010-08-14 23:09:12 +08001948}
1949
Eric Engestrom66d5ec52017-02-21 23:56:46 +00001950EGLint EGLAPIENTRY
1951eglClientWaitSync(EGLDisplay dpy, EGLSync sync,
1952 EGLint flags, EGLTime timeout)
1953{
1954 _EGLDisplay *disp = _eglLockDisplay(dpy);
1955 _EGLSync *s = _eglLookupSync(sync, disp);
1956 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1957 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
1958}
1959
1960static EGLint EGLAPIENTRY
1961eglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync,
1962 EGLint flags, EGLTime timeout)
1963{
1964 _EGLDisplay *disp = _eglLockDisplay(dpy);
1965 _EGLSync *s = _eglLookupSync(sync, disp);
1966 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1967 return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
1968}
1969
Chia-I Wu4eebea72010-08-14 23:09:12 +08001970
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001971static EGLint
1972_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
Marek Olšáka8617cc2015-04-10 12:04:18 +02001973{
Marek Olšáka8617cc2015-04-10 12:04:18 +02001974 _EGLContext *ctx = _eglGetCurrentContext();
1975 _EGLDriver *drv;
1976 EGLint ret;
1977
1978 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1979 assert(disp->Extensions.KHR_wait_sync);
1980
1981 /* return an error if the client API doesn't support GL_OES_EGL_sync */
1982 if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
1983 RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1984
1985 /* the API doesn't allow any flags yet */
1986 if (flags != 0)
1987 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1988
1989 ret = drv->API.WaitSyncKHR(drv, disp, s);
1990
1991 RETURN_EGL_EVAL(disp, ret);
1992}
1993
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04001994static EGLint EGLAPIENTRY
1995eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
1996{
1997 _EGLDisplay *disp = _eglLockDisplay(dpy);
1998 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04001999 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002000 return _eglWaitSyncCommon(disp, s, flags);
2001}
2002
Marek Olšáka8617cc2015-04-10 12:04:18 +02002003
Marek Olšák75245922015-05-12 18:13:31 +02002004EGLBoolean EGLAPIENTRY
2005eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
2006{
2007 /* The KHR version returns EGLint, while the core version returns
2008 * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
2009 * EGL_TRUE.
2010 */
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002011 _EGLDisplay *disp = _eglLockDisplay(dpy);
2012 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002013 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman5b0b8442016-09-12 17:44:36 -04002014 return _eglWaitSyncCommon(disp, s, flags);
Marek Olšák75245922015-05-12 18:13:31 +02002015}
2016
2017
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002018static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002019eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
Chia-I Wu4eebea72010-08-14 23:09:12 +08002020{
2021 _EGLDisplay *disp = _eglLockDisplay(dpy);
2022 _EGLSync *s = _eglLookupSync(sync, disp);
2023 _EGLDriver *drv;
2024 EGLBoolean ret;
2025
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002026 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2027
Chia-I Wu4eebea72010-08-14 23:09:12 +08002028 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002029 assert(disp->Extensions.KHR_reusable_sync);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002030 ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
2031
2032 RETURN_EGL_EVAL(disp, ret);
2033}
2034
2035
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002036static EGLBoolean
2037_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
Chia-I Wu4eebea72010-08-14 23:09:12 +08002038{
Chia-I Wu4eebea72010-08-14 23:09:12 +08002039 _EGLDriver *drv;
2040 EGLBoolean ret;
2041
2042 _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
Marek Olšák9a0bda22015-04-10 10:56:02 +02002043 assert(disp->Extensions.KHR_reusable_sync ||
Rob Clark0201f012016-11-18 08:39:33 -05002044 disp->Extensions.KHR_fence_sync ||
2045 disp->Extensions.ANDROID_native_fence_sync);
Marek Olšák1e79e052015-05-12 18:14:31 +02002046 ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
Chia-I Wu4eebea72010-08-14 23:09:12 +08002047
2048 RETURN_EGL_EVAL(disp, ret);
2049}
2050
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002051EGLBoolean EGLAPIENTRY
2052eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
2053{
2054 _EGLDisplay *disp = _eglLockDisplay(dpy);
2055 _EGLSync *s = _eglLookupSync(sync, disp);
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002056 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002057 return _eglGetSyncAttribCommon(disp, s, attribute, value);
2058}
2059
Chia-I Wu4eebea72010-08-14 23:09:12 +08002060
Marek Olšák1e79e052015-05-12 18:14:31 +02002061static EGLBoolean EGLAPIENTRY
2062eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
2063{
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002064 _EGLDisplay *disp = _eglLockDisplay(dpy);
2065 _EGLSync *s = _eglLookupSync(sync, disp);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002066 EGLAttrib attrib;
2067 EGLBoolean result;
2068
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002069 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2070
Dongwon Kimd1e15632016-02-02 15:06:28 -08002071 if (!value)
Chad Versace17084b62016-09-27 23:06:37 -07002072 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
Dongwon Kimd1e15632016-02-02 15:06:28 -08002073
2074 attrib = *value;
Kyle Brenneman1d535c12016-09-12 17:46:04 -04002075 result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
Marek Olšák1e79e052015-05-12 18:14:31 +02002076
2077 /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
2078 *
2079 * If any error occurs, <*value> is not modified.
2080 */
2081 if (result == EGL_FALSE)
2082 return result;
2083
2084 *value = attrib;
2085 return result;
2086}
2087
Rob Clark0201f012016-11-18 08:39:33 -05002088static EGLint EGLAPIENTRY
2089eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
2090{
2091 _EGLDisplay *disp = _eglLockDisplay(dpy);
2092 _EGLSync *s = _eglLookupSync(sync, disp);
2093 _EGLDriver *drv;
2094 EGLBoolean ret;
2095
2096 _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2097
2098 /* the spec doesn't seem to specify what happens if the fence
2099 * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems
2100 * sensible:
2101 */
2102 if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)))
2103 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID);
2104
2105 _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv);
2106 assert(disp->Extensions.ANDROID_native_fence_sync);
2107 ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s);
2108
2109 RETURN_EGL_EVAL(disp, ret);
2110}
Marek Olšák1e79e052015-05-12 18:14:31 +02002111
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002112static EGLBoolean EGLAPIENTRY
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002113eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002114 EGLint numRects, const EGLint *rects)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002115{
2116 _EGLContext *ctx = _eglGetCurrentContext();
2117 _EGLDisplay *disp = _eglLockDisplay(dpy);
2118 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2119 _EGLDriver *drv;
2120 EGLBoolean ret;
2121
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002122 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2123
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002124 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2125
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002126 if (!disp->Extensions.NOK_swap_region)
2127 RETURN_EGL_EVAL(disp, EGL_FALSE);
2128
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002129 /* surface must be bound to current context in EGL 1.4 */
Chia-I Wud19afc52010-10-23 12:52:26 +08002130 if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
2131 surf != ctx->DrawSurface)
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002132 RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
2133
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002134 ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
Kristian Høgsberg52c554a2010-05-06 22:01:35 -04002135
2136 RETURN_EGL_EVAL(disp, ret);
2137}
2138
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002139
Marek Olšákd333d302015-05-12 17:34:57 +02002140static EGLImage EGLAPIENTRY
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002141eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
2142{
2143 _EGLDisplay *disp = _eglLockDisplay(dpy);
2144 _EGLDriver *drv;
2145 _EGLImage *img;
Marek Olšákd333d302015-05-12 17:34:57 +02002146 EGLImage ret;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002147
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002148 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2149
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002150 _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002151 if (!disp->Extensions.MESA_drm_image)
2152 RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002153
2154 img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
Chia-I Wu4ce33ec2010-10-23 00:37:19 +08002155 ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002156
2157 RETURN_EGL_EVAL(disp, ret);
2158}
2159
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002160static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002161eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002162 EGLint *name, EGLint *handle, EGLint *stride)
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002163{
2164 _EGLDisplay *disp = _eglLockDisplay(dpy);
2165 _EGLImage *img = _eglLookupImage(image, disp);
2166 _EGLDriver *drv;
2167 EGLBoolean ret;
2168
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002169 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2170
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002171 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
Chia-I Wu6b2f1562010-09-24 02:42:15 +08002172 assert(disp->Extensions.MESA_drm_image);
2173
Kristian Høgsbergb7a8893a2010-06-04 14:28:59 -04002174 if (!img)
2175 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2176
2177 ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
2178
2179 RETURN_EGL_EVAL(disp, ret);
2180}
2181
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002182
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002183struct wl_display;
2184
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002185static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002186eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2187{
2188 _EGLDisplay *disp = _eglLockDisplay(dpy);
2189 _EGLDriver *drv;
2190 EGLBoolean ret;
2191
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002192 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2193
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002194 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2195 assert(disp->Extensions.WL_bind_wayland_display);
2196
2197 if (!display)
2198 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2199
2200 ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
2201
2202 RETURN_EGL_EVAL(disp, ret);
2203}
2204
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002205static EGLBoolean EGLAPIENTRY
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002206eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2207{
2208 _EGLDisplay *disp = _eglLockDisplay(dpy);
2209 _EGLDriver *drv;
2210 EGLBoolean ret;
2211
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002212 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2213
Benjamin Franzke6b369c42011-02-21 16:22:34 +01002214 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2215 assert(disp->Extensions.WL_bind_wayland_display);
2216
2217 if (!display)
2218 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2219
2220 ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
2221
2222 RETURN_EGL_EVAL(disp, ret);
2223}
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002224
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002225static EGLBoolean EGLAPIENTRY
Ander Conselvan de Oliveira8d29b522013-07-18 15:11:25 +03002226eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002227 EGLint attribute, EGLint *value)
2228{
2229 _EGLDisplay *disp = _eglLockDisplay(dpy);
2230 _EGLDriver *drv;
2231 EGLBoolean ret;
2232
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002233 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2234
Kristian Høgsberge6a33572012-07-05 16:43:04 -04002235 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2236 assert(disp->Extensions.WL_bind_wayland_display);
2237
2238 if (!buffer)
2239 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2240
2241 ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
2242
2243 RETURN_EGL_EVAL(disp, ret);
2244}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002245
Emil Velikov720125f2015-07-10 11:22:13 +01002246
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002247static struct wl_buffer * EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002248eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002249{
2250 _EGLDisplay *disp = _eglLockDisplay(dpy);
2251 _EGLImage *img;
2252 _EGLDriver *drv;
2253 struct wl_buffer *ret;
2254
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002255 _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2256
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002257 _EGL_CHECK_DISPLAY(disp, NULL, drv);
Emil Velikov70131142017-05-15 16:14:15 +01002258 if (!disp->Extensions.WL_create_wayland_buffer_from_image)
2259 RETURN_EGL_EVAL(disp, NULL);
Neil Roberts5cddb1c2013-10-28 15:07:03 +00002260
2261 img = _eglLookupImage(image, disp);
2262
2263 if (!img)
2264 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
2265
2266 ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
2267
2268 RETURN_EGL_EVAL(disp, ret);
2269}
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002270
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002271static EGLBoolean EGLAPIENTRY
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002272eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
2273 EGLint x, EGLint y, EGLint width, EGLint height)
2274{
2275 _EGLDisplay *disp = _eglLockDisplay(dpy);
2276 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2277 _EGLDriver *drv;
2278 EGLBoolean ret;
2279
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002280 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2281
Fredrik Höglund7d46b452011-12-14 21:24:09 +01002282 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2283
2284 if (!disp->Extensions.NV_post_sub_buffer)
2285 RETURN_EGL_EVAL(disp, EGL_FALSE);
2286
2287 ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
2288
2289 RETURN_EGL_EVAL(disp, ret);
2290}
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002291
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002292static EGLBoolean EGLAPIENTRY
Eric Engestrom54fa5ec2019-02-02 11:38:45 +00002293eglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface,
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002294 EGLuint64KHR *ust, EGLuint64KHR *msc,
2295 EGLuint64KHR *sbc)
2296{
Eric Engestrom54fa5ec2019-02-02 11:38:45 +00002297 _EGLDisplay *disp = _eglLockDisplay(dpy);
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002298 _EGLSurface *surf = _eglLookupSurface(surface, disp);
2299 _EGLDriver *drv;
2300 EGLBoolean ret;
2301
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002302 _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2303
Sarah Sharpc524f3e2014-05-06 12:10:57 -07002304 _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
2305 if (!disp->Extensions.CHROMIUM_sync_control)
2306 RETURN_EGL_EVAL(disp, EGL_FALSE);
2307
2308 if (!ust || !msc || !sbc)
2309 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2310
2311 ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
2312
2313 RETURN_EGL_EVAL(disp, ret);
2314}
Dave Airlie8f7338f2014-03-03 13:57:16 +10002315
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002316static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002317eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002318 EGLint *fourcc, EGLint *nplanes,
Dave Airlieb5045e22015-05-05 09:10:34 +10002319 EGLuint64KHR *modifiers)
Dave Airlie8f7338f2014-03-03 13:57:16 +10002320{
2321 _EGLDisplay *disp = _eglLockDisplay(dpy);
2322 _EGLImage *img = _eglLookupImage(image, disp);
2323 _EGLDriver *drv;
2324 EGLBoolean ret;
2325
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002326 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2327
Dave Airlie8f7338f2014-03-03 13:57:16 +10002328 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2329 assert(disp->Extensions.MESA_image_dma_buf_export);
2330
2331 if (!img)
2332 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2333
2334 ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
2335 modifiers);
2336
2337 RETURN_EGL_EVAL(disp, ret);
2338}
2339
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002340static EGLBoolean EGLAPIENTRY
Marek Olšákd333d302015-05-12 17:34:57 +02002341eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
Dave Airlie8f7338f2014-03-03 13:57:16 +10002342 int *fds, EGLint *strides, EGLint *offsets)
2343{
2344 _EGLDisplay *disp = _eglLockDisplay(dpy);
2345 _EGLImage *img = _eglLookupImage(image, disp);
2346 _EGLDriver *drv;
2347 EGLBoolean ret;
2348
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002349 _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2350
Dave Airlie8f7338f2014-03-03 13:57:16 +10002351 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2352 assert(disp->Extensions.MESA_image_dma_buf_export);
2353
2354 if (!img)
2355 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2356
2357 ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
2358
2359 RETURN_EGL_EVAL(disp, ret);
2360}
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002361
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002362static EGLint EGLAPIENTRY
2363eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002364 EGLLabelKHR label)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002365{
2366 _EGLDisplay *disp = NULL;
2367 _EGLResourceType type;
2368
2369 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2370
2371 if (objectType == EGL_OBJECT_THREAD_KHR) {
2372 _EGLThreadInfo *t = _eglGetCurrentThread();
2373
2374 if (!_eglIsCurrentThreadDummy()) {
2375 t->Label = label;
2376 return EGL_SUCCESS;
2377 }
2378
2379 RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
2380 }
2381
2382 disp = _eglLockDisplay(dpy);
2383 if (disp == NULL)
2384 RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
2385
2386 if (objectType == EGL_OBJECT_DISPLAY_KHR) {
2387 if (dpy != (EGLDisplay) object)
2388 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2389
2390 disp->Label = label;
2391 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2392 }
2393
2394 switch (objectType) {
2395 case EGL_OBJECT_CONTEXT_KHR:
2396 type = _EGL_RESOURCE_CONTEXT;
2397 break;
2398 case EGL_OBJECT_SURFACE_KHR:
2399 type = _EGL_RESOURCE_SURFACE;
2400 break;
2401 case EGL_OBJECT_IMAGE_KHR:
2402 type = _EGL_RESOURCE_IMAGE;
2403 break;
2404 case EGL_OBJECT_SYNC_KHR:
2405 type = _EGL_RESOURCE_SYNC;
2406 break;
2407 case EGL_OBJECT_STREAM_KHR:
2408 default:
2409 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2410 }
2411
2412 if (_eglCheckResource(object, type, disp)) {
2413 _EGLResource *res = (_EGLResource *) object;
2414
2415 res->Label = label;
2416 RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2417 }
2418
2419 RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2420}
2421
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002422static EGLint EGLAPIENTRY
2423eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002424 const EGLAttrib *attrib_list)
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002425{
2426 unsigned int newEnabled;
2427
2428 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2429
2430 mtx_lock(_eglGlobal.Mutex);
2431
2432 newEnabled = _eglGlobal.debugTypesEnabled;
2433 if (attrib_list != NULL) {
2434 int i;
2435
2436 for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
Emil Velikov4df0d502017-09-07 17:03:53 +01002437 switch (attrib_list[i]) {
2438 case EGL_DEBUG_MSG_CRITICAL_KHR:
2439 case EGL_DEBUG_MSG_ERROR_KHR:
2440 case EGL_DEBUG_MSG_WARN_KHR:
2441 case EGL_DEBUG_MSG_INFO_KHR:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002442 if (attrib_list[i + 1])
2443 newEnabled |= DebugBitFromType(attrib_list[i]);
2444 else
2445 newEnabled &= ~DebugBitFromType(attrib_list[i]);
Emil Velikov4df0d502017-09-07 17:03:53 +01002446 break;
2447 default:
2448 // On error, set the last error code, call the current
2449 // debug callback, and return the error code.
2450 mtx_unlock(_eglGlobal.Mutex);
2451 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
2452 "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
2453 return EGL_BAD_ATTRIBUTE;
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002454 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002455 }
2456 }
2457
2458 if (callback != NULL) {
2459 _eglGlobal.debugCallback = callback;
2460 _eglGlobal.debugTypesEnabled = newEnabled;
2461 } else {
2462 _eglGlobal.debugCallback = NULL;
2463 _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
2464 }
2465
2466 mtx_unlock(_eglGlobal.Mutex);
2467 return EGL_SUCCESS;
2468}
2469
2470static EGLBoolean EGLAPIENTRY
2471eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
2472{
2473 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2474
2475 mtx_lock(_eglGlobal.Mutex);
2476
Emil Velikov4df0d502017-09-07 17:03:53 +01002477 switch (attribute) {
2478 case EGL_DEBUG_MSG_CRITICAL_KHR:
2479 case EGL_DEBUG_MSG_ERROR_KHR:
2480 case EGL_DEBUG_MSG_WARN_KHR:
2481 case EGL_DEBUG_MSG_INFO_KHR:
2482 if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
2483 *value = EGL_TRUE;
2484 else
2485 *value = EGL_FALSE;
2486 break;
2487 case EGL_DEBUG_CALLBACK_KHR:
2488 *value = (EGLAttrib) _eglGlobal.debugCallback;
2489 break;
2490 default:
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002491 mtx_unlock(_eglGlobal.Mutex);
2492 _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
Eric Engestrom5f4f5aa2017-08-08 16:17:13 +01002493 "Invalid attribute 0x%04lx", (unsigned long) attribute);
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002494 return EGL_FALSE;
Emil Velikov4df0d502017-09-07 17:03:53 +01002495 }
Kyle Brennemanca9f26a2016-09-12 17:51:22 -04002496
2497 mtx_unlock(_eglGlobal.Mutex);
2498 return EGL_TRUE;
2499}
2500
Eric Engestrom1534fc62017-02-21 23:56:52 +00002501static int
2502_eglFunctionCompare(const void *key, const void *elem)
2503{
2504 const char *procname = key;
2505 const struct _egl_entrypoint *entrypoint = elem;
2506 return strcmp(procname, entrypoint->name);
2507}
2508
Varad Gautam6719e052017-05-30 17:23:38 +05302509static EGLBoolean EGLAPIENTRY
2510eglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats,
2511 EGLint *formats, EGLint *num_formats)
2512{
2513 _EGLDisplay *disp = _eglLockDisplay(dpy);
2514 _EGLDriver *drv;
2515 EGLBoolean ret;
2516
2517 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2518
2519 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2520
2521 ret = drv->API.QueryDmaBufFormatsEXT(drv, disp, max_formats, formats,
2522 num_formats);
2523
2524 RETURN_EGL_EVAL(disp, ret);
2525}
2526
Varad Gautamde3c4592017-05-30 17:23:39 +05302527static EGLBoolean EGLAPIENTRY
2528eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
2529 EGLuint64KHR *modifiers, EGLBoolean *external_only,
2530 EGLint *num_modifiers)
2531{
2532 _EGLDisplay *disp = _eglLockDisplay(dpy);
2533 _EGLDriver *drv;
2534 EGLBoolean ret;
2535
2536 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2537
2538 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2539
2540 ret = drv->API.QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers,
2541 modifiers, external_only,
2542 num_modifiers);
2543
2544 RETURN_EGL_EVAL(disp, ret);
2545}
2546
Tapani Pälli6f5b5702017-12-28 10:51:11 +02002547static void EGLAPIENTRY
2548eglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
2549 EGLGetBlobFuncANDROID get)
2550{
2551 /* This function does not return anything so we cannot
2552 * utilize the helper macros _EGL_FUNC_START or _EGL_CHECK_DISPLAY.
2553 */
2554 _EGLDisplay *disp = _eglLockDisplay(dpy);
2555 if (!_eglSetFuncName(__func__, disp, EGL_OBJECT_DISPLAY_KHR, NULL)) {
2556 if (disp)
2557 _eglUnlockDisplay(disp);
2558 return;
2559 }
2560
2561 _EGLDriver *drv = _eglCheckDisplay(disp, __func__);
2562 if (!drv) {
2563 if (disp)
2564 _eglUnlockDisplay(disp);
2565 return;
2566 }
2567
2568 if (!set || !get) {
2569 _eglError(EGL_BAD_PARAMETER,
2570 "eglSetBlobCacheFuncsANDROID: NULL handler given");
2571 _eglUnlockDisplay(disp);
2572 return;
2573 }
2574
2575 if (disp->BlobCacheSet) {
2576 _eglError(EGL_BAD_PARAMETER,
2577 "eglSetBlobCacheFuncsANDROID: functions already set");
2578 _eglUnlockDisplay(disp);
2579 return;
2580 }
2581
2582 disp->BlobCacheSet = set;
2583 disp->BlobCacheGet = get;
2584
2585 drv->API.SetBlobCacheFuncsANDROID(drv, disp, set, get);
2586
2587 _eglUnlockDisplay(disp);
2588}
2589
Emil Velikov7552fcb2015-07-24 16:19:55 +02002590static EGLBoolean EGLAPIENTRY
2591eglQueryDeviceAttribEXT(EGLDeviceEXT device,
2592 EGLint attribute,
2593 EGLAttrib *value)
2594{
2595 _EGLDevice *dev = _eglLookupDevice(device);
2596 EGLBoolean ret;
2597
2598 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2599 if (!dev)
2600 RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, EGL_FALSE);
2601
2602 ret = _eglQueryDeviceAttribEXT(dev, attribute, value);
2603 RETURN_EGL_EVAL(NULL, ret);
2604}
2605
2606static const char * EGLAPIENTRY
2607eglQueryDeviceStringEXT(EGLDeviceEXT device,
2608 EGLint name)
2609{
2610 _EGLDevice *dev = _eglLookupDevice(device);
2611
2612 _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2613 if (!dev)
2614 RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, NULL);
2615
2616 RETURN_EGL_EVAL(NULL, _eglQueryDeviceStringEXT(dev, name));
2617}
2618
2619static EGLBoolean EGLAPIENTRY
2620eglQueryDevicesEXT(EGLint max_devices,
2621 EGLDeviceEXT *devices,
2622 EGLint *num_devices)
2623{
2624 EGLBoolean ret;
2625
2626 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2627 ret = _eglQueryDevicesEXT(max_devices, (_EGLDevice **) devices,
2628 num_devices);
2629 RETURN_EGL_EVAL(NULL, ret);
2630}
2631
2632static EGLBoolean EGLAPIENTRY
2633eglQueryDisplayAttribEXT(EGLDisplay dpy,
2634 EGLint attribute,
2635 EGLAttrib *value)
2636{
2637 _EGLDisplay *disp = _eglLockDisplay(dpy);
2638 _EGLDriver *drv;
2639
2640 _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2641 _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
2642
2643 switch (attribute) {
2644 case EGL_DEVICE_EXT:
2645 *value = (EGLAttrib) disp->Device;
2646 break;
2647 default:
2648 RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_FALSE);
2649 }
2650 RETURN_EGL_SUCCESS(disp, EGL_TRUE);
2651}
2652
Veluri Mithun6afce782019-01-23 22:44:25 +05302653static char * EGLAPIENTRY
2654eglGetDisplayDriverConfig(EGLDisplay dpy)
2655{
2656 _EGLDisplay *disp = _eglLockDisplay(dpy);
2657 _EGLDriver *drv;
2658 char *ret;
2659
2660 _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
2661 _EGL_CHECK_DISPLAY(disp, NULL, drv);
2662
2663 assert(disp->Extensions.MESA_query_driver);
2664
2665 ret = drv->API.QueryDriverConfig(disp);
2666 RETURN_EGL_EVAL(disp, ret);
2667}
2668
2669static const char * EGLAPIENTRY
2670eglGetDisplayDriverName(EGLDisplay dpy)
2671{
2672 _EGLDisplay *disp = _eglLockDisplay(dpy);
2673 _EGLDriver *drv;
2674 const char *ret;
2675
2676 _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
2677 _EGL_CHECK_DISPLAY(disp, NULL, drv);
2678
2679 assert(disp->Extensions.MESA_query_driver);
2680
2681 ret = drv->API.QueryDriverName(disp);
2682 RETURN_EGL_EVAL(disp, ret);
2683}
2684
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002685__eglMustCastToProperFunctionPointerType EGLAPIENTRY
2686eglGetProcAddress(const char *procname)
2687{
Eric Engestrom1534fc62017-02-21 23:56:52 +00002688 static const struct _egl_entrypoint egl_functions[] = {
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002689#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
Eric Engestromf92fd4d2017-02-21 23:56:49 +00002690#include "eglentrypoint.h"
Eric Engestrom3b69c4a2017-02-21 23:56:47 +00002691#undef EGL_ENTRYPOINT
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002692 };
Eric Engestrom1534fc62017-02-21 23:56:52 +00002693 _EGLProc ret = NULL;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002694
2695 if (!procname)
2696 RETURN_EGL_SUCCESS(NULL, NULL);
2697
Kyle Brenneman6a5545d2016-09-12 17:50:40 -04002698 _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2699
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002700 if (strncmp(procname, "egl", 3) == 0) {
Eric Engestrom1534fc62017-02-21 23:56:52 +00002701 const struct _egl_entrypoint *entrypoint =
2702 bsearch(procname,
2703 egl_functions, ARRAY_SIZE(egl_functions),
2704 sizeof(egl_functions[0]),
2705 _eglFunctionCompare);
2706 if (entrypoint)
2707 ret = entrypoint->function;
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002708 }
Eric Engestrom1534fc62017-02-21 23:56:52 +00002709
Emil Velikove3cc5ad2015-05-11 23:43:48 +01002710 if (!ret)
2711 ret = _eglGetDriverProc(procname);
2712
2713 RETURN_EGL_SUCCESS(NULL, ret);
2714}
Marek Olšákb6eda702016-03-03 15:59:48 +01002715
2716static int
2717_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
2718 _EGLDisplay **disp, _EGLDriver **drv,
2719 _EGLContext **ctx)
2720{
2721
2722 *disp = _eglLockDisplay(dpy);
2723 if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
2724 if (*disp)
2725 _eglUnlockDisplay(*disp);
2726 return MESA_GLINTEROP_INVALID_DISPLAY;
2727 }
2728
2729 *drv = (*disp)->Driver;
2730
2731 *ctx = _eglLookupContext(context, *disp);
2732 if (!*ctx ||
2733 ((*ctx)->ClientAPI != EGL_OPENGL_API &&
2734 (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
2735 _eglUnlockDisplay(*disp);
2736 return MESA_GLINTEROP_INVALID_CONTEXT;
2737 }
2738
2739 return MESA_GLINTEROP_SUCCESS;
2740}
2741
Marek Olšákee39d442016-11-02 18:59:22 +01002742PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002743MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002744 struct mesa_glinterop_device_info *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002745{
2746 _EGLDisplay *disp;
2747 _EGLDriver *drv;
2748 _EGLContext *ctx;
2749 int ret;
2750
2751 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2752 if (ret != MESA_GLINTEROP_SUCCESS)
2753 return ret;
2754
2755 if (drv->API.GLInteropQueryDeviceInfo)
2756 ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
2757 else
2758 ret = MESA_GLINTEROP_UNSUPPORTED;
2759
2760 _eglUnlockDisplay(disp);
2761 return ret;
2762}
2763
Marek Olšákee39d442016-11-02 18:59:22 +01002764PUBLIC int
Marek Olšákb6eda702016-03-03 15:59:48 +01002765MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
Emil Velikov13faddb2016-05-30 10:56:33 +01002766 struct mesa_glinterop_export_in *in,
2767 struct mesa_glinterop_export_out *out)
Marek Olšákb6eda702016-03-03 15:59:48 +01002768{
2769 _EGLDisplay *disp;
2770 _EGLDriver *drv;
2771 _EGLContext *ctx;
2772 int ret;
2773
2774 ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
2775 if (ret != MESA_GLINTEROP_SUCCESS)
2776 return ret;
2777
2778 if (drv->API.GLInteropExportObject)
2779 ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
2780 else
2781 ret = MESA_GLINTEROP_UNSUPPORTED;
2782
2783 _eglUnlockDisplay(disp);
2784 return ret;
2785}