1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc.
4bf215546Sopenharmony_ci * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5bf215546Sopenharmony_ci * Copyright 2010-2011 LunarG, Inc.
6bf215546Sopenharmony_ci * All Rights Reserved.
7bf215546Sopenharmony_ci *
8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
10bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
11bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
12bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
13bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
14bf215546Sopenharmony_ci * the following conditions:
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
17bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
18bf215546Sopenharmony_ci * of the Software.
19bf215546Sopenharmony_ci *
20bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
27bf215546Sopenharmony_ci *
28bf215546Sopenharmony_ci **************************************************************************/
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci/**
32bf215546Sopenharmony_ci * Public EGL API entrypoints
33bf215546Sopenharmony_ci *
34bf215546Sopenharmony_ci * Generally, we use the EGLDisplay parameter as a key to lookup the
35bf215546Sopenharmony_ci * appropriate device driver handle, then jump though the driver's
36bf215546Sopenharmony_ci * dispatch table to handle the function.
37bf215546Sopenharmony_ci *
38bf215546Sopenharmony_ci * That allows us the option of supporting multiple, simultaneous,
39bf215546Sopenharmony_ci * heterogeneous hardware devices in the future.
40bf215546Sopenharmony_ci *
41bf215546Sopenharmony_ci * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
42bf215546Sopenharmony_ci * opaque handles. Internal objects are linked to a display to
43bf215546Sopenharmony_ci * create the handles.
44bf215546Sopenharmony_ci *
45bf215546Sopenharmony_ci * For each public API entry point, the opaque handles are looked up
46bf215546Sopenharmony_ci * before being dispatched to the drivers.  When it fails to look up
47bf215546Sopenharmony_ci * a handle, one of
48bf215546Sopenharmony_ci *
49bf215546Sopenharmony_ci * EGL_BAD_DISPLAY
50bf215546Sopenharmony_ci * EGL_BAD_CONFIG
51bf215546Sopenharmony_ci * EGL_BAD_CONTEXT
52bf215546Sopenharmony_ci * EGL_BAD_SURFACE
53bf215546Sopenharmony_ci * EGL_BAD_SCREEN_MESA
54bf215546Sopenharmony_ci * EGL_BAD_MODE_MESA
55bf215546Sopenharmony_ci *
56bf215546Sopenharmony_ci * is generated and the driver function is not called. An
57bf215546Sopenharmony_ci * uninitialized EGLDisplay has no driver associated with it. When
58bf215546Sopenharmony_ci * such display is detected,
59bf215546Sopenharmony_ci *
60bf215546Sopenharmony_ci * EGL_NOT_INITIALIZED
61bf215546Sopenharmony_ci *
62bf215546Sopenharmony_ci * is generated.
63bf215546Sopenharmony_ci *
64bf215546Sopenharmony_ci * Some of the entry points use current display, context, or surface
65bf215546Sopenharmony_ci * implicitly.  For such entry points, the implicit objects are also
66bf215546Sopenharmony_ci * checked before calling the driver function.  Other than the
67bf215546Sopenharmony_ci * errors listed above,
68bf215546Sopenharmony_ci *
69bf215546Sopenharmony_ci * EGL_BAD_CURRENT_SURFACE
70bf215546Sopenharmony_ci *
71bf215546Sopenharmony_ci * may also be generated.
72bf215546Sopenharmony_ci *
73bf215546Sopenharmony_ci * Notes on naming conventions:
74bf215546Sopenharmony_ci *
75bf215546Sopenharmony_ci * eglFooBar    - public EGL function
76bf215546Sopenharmony_ci * EGL_FOO_BAR  - public EGL token
77bf215546Sopenharmony_ci * EGLDatatype  - public EGL datatype
78bf215546Sopenharmony_ci *
79bf215546Sopenharmony_ci * _eglFooBar   - private EGL function
80bf215546Sopenharmony_ci * _EGLDatatype - private EGL datatype, typedef'd struct
81bf215546Sopenharmony_ci * _egl_struct  - private EGL struct, non-typedef'd
82bf215546Sopenharmony_ci *
83bf215546Sopenharmony_ci */
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci#ifdef USE_LIBGLVND
87bf215546Sopenharmony_ci#define EGLAPI
88bf215546Sopenharmony_ci#undef PUBLIC
89bf215546Sopenharmony_ci#define PUBLIC
90bf215546Sopenharmony_ci#endif
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci#include <assert.h>
93bf215546Sopenharmony_ci#include <stdio.h>
94bf215546Sopenharmony_ci#include <stdlib.h>
95bf215546Sopenharmony_ci#include <string.h>
96bf215546Sopenharmony_ci#include "c11/threads.h"
97bf215546Sopenharmony_ci#include "util/debug.h"
98bf215546Sopenharmony_ci#include "util/macros.h"
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci#include "egldefines.h"
101bf215546Sopenharmony_ci#include "eglglobals.h"
102bf215546Sopenharmony_ci#include "eglcontext.h"
103bf215546Sopenharmony_ci#include "egldisplay.h"
104bf215546Sopenharmony_ci#include "egltypedefs.h"
105bf215546Sopenharmony_ci#include "eglcurrent.h"
106bf215546Sopenharmony_ci#include "egldevice.h"
107bf215546Sopenharmony_ci#include "egldriver.h"
108bf215546Sopenharmony_ci#include "eglsurface.h"
109bf215546Sopenharmony_ci#include "eglconfig.h"
110bf215546Sopenharmony_ci#include "eglimage.h"
111bf215546Sopenharmony_ci#include "eglsync.h"
112bf215546Sopenharmony_ci#include "egllog.h"
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci#include "GL/mesa_glinterop.h"
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci/**
117bf215546Sopenharmony_ci * Macros to help return an API entrypoint.
118bf215546Sopenharmony_ci *
119bf215546Sopenharmony_ci * These macros will unlock the display and record the error code.
120bf215546Sopenharmony_ci */
121bf215546Sopenharmony_ci#define RETURN_EGL_ERROR(disp, err, ret)        \
122bf215546Sopenharmony_ci   do {                                         \
123bf215546Sopenharmony_ci      if (disp)                                 \
124bf215546Sopenharmony_ci         _eglUnlockDisplay(disp);               \
125bf215546Sopenharmony_ci      /* EGL error codes are non-zero */        \
126bf215546Sopenharmony_ci      if (err)                                  \
127bf215546Sopenharmony_ci         _eglError(err, __func__);              \
128bf215546Sopenharmony_ci      return ret;                               \
129bf215546Sopenharmony_ci   } while (0)
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci#define RETURN_EGL_SUCCESS(disp, ret) \
132bf215546Sopenharmony_ci   RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci/* record EGL_SUCCESS only when ret evaluates to true */
135bf215546Sopenharmony_ci#define RETURN_EGL_EVAL(disp, ret) \
136bf215546Sopenharmony_ci   RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci/*
140bf215546Sopenharmony_ci * A bunch of macros and checks to simplify error checking.
141bf215546Sopenharmony_ci */
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci#define _EGL_CHECK_DISPLAY(disp, ret)              \
144bf215546Sopenharmony_ci   do {                                            \
145bf215546Sopenharmony_ci      if (!_eglCheckDisplay(disp, __func__))       \
146bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, 0, ret);           \
147bf215546Sopenharmony_ci   } while (0)
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci#define _EGL_CHECK_OBJECT(disp, type, obj, ret)           \
150bf215546Sopenharmony_ci   do {                                                   \
151bf215546Sopenharmony_ci      if (!_eglCheck ## type(disp, obj, __func__))        \
152bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, 0, ret);                  \
153bf215546Sopenharmony_ci   } while (0)
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci#define _EGL_CHECK_SURFACE(disp, surf, ret) \
156bf215546Sopenharmony_ci   _EGL_CHECK_OBJECT(disp, Surface, surf, ret)
157bf215546Sopenharmony_ci
158bf215546Sopenharmony_ci#define _EGL_CHECK_CONTEXT(disp, context, ret) \
159bf215546Sopenharmony_ci   _EGL_CHECK_OBJECT(disp, Context, context, ret)
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ci#define _EGL_CHECK_CONFIG(disp, conf, ret) \
162bf215546Sopenharmony_ci   _EGL_CHECK_OBJECT(disp, Config, conf, ret)
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci#define _EGL_CHECK_SYNC(disp, s, ret) \
165bf215546Sopenharmony_ci   _EGL_CHECK_OBJECT(disp, Sync, s, ret)
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ciextern const _EGLDriver _eglDriver;
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_cistruct _egl_entrypoint {
172bf215546Sopenharmony_ci   const char *name;
173bf215546Sopenharmony_ci   _EGLProc function;
174bf215546Sopenharmony_ci};
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_cistatic inline bool
178bf215546Sopenharmony_ci_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
179bf215546Sopenharmony_ci{
180bf215546Sopenharmony_ci   if (!disp) {
181bf215546Sopenharmony_ci      _eglError(EGL_BAD_DISPLAY, msg);
182bf215546Sopenharmony_ci      return false;
183bf215546Sopenharmony_ci   }
184bf215546Sopenharmony_ci   if (!disp->Initialized) {
185bf215546Sopenharmony_ci      _eglError(EGL_NOT_INITIALIZED, msg);
186bf215546Sopenharmony_ci      return false;
187bf215546Sopenharmony_ci   }
188bf215546Sopenharmony_ci   return true;
189bf215546Sopenharmony_ci}
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_cistatic inline bool
193bf215546Sopenharmony_ci_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
194bf215546Sopenharmony_ci{
195bf215546Sopenharmony_ci   if (!_eglCheckDisplay(disp, msg))
196bf215546Sopenharmony_ci      return false;
197bf215546Sopenharmony_ci   if (!surf) {
198bf215546Sopenharmony_ci      _eglError(EGL_BAD_SURFACE, msg);
199bf215546Sopenharmony_ci      return false;
200bf215546Sopenharmony_ci   }
201bf215546Sopenharmony_ci   return true;
202bf215546Sopenharmony_ci}
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_cistatic inline bool
206bf215546Sopenharmony_ci_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
207bf215546Sopenharmony_ci{
208bf215546Sopenharmony_ci   if (!_eglCheckDisplay(disp, msg))
209bf215546Sopenharmony_ci      return false;
210bf215546Sopenharmony_ci   if (!context) {
211bf215546Sopenharmony_ci      _eglError(EGL_BAD_CONTEXT, msg);
212bf215546Sopenharmony_ci      return false;
213bf215546Sopenharmony_ci   }
214bf215546Sopenharmony_ci   return true;
215bf215546Sopenharmony_ci}
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_cistatic inline bool
219bf215546Sopenharmony_ci_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
220bf215546Sopenharmony_ci{
221bf215546Sopenharmony_ci   if (!_eglCheckDisplay(disp, msg))
222bf215546Sopenharmony_ci      return false;
223bf215546Sopenharmony_ci   if (!conf) {
224bf215546Sopenharmony_ci      _eglError(EGL_BAD_CONFIG, msg);
225bf215546Sopenharmony_ci      return false;
226bf215546Sopenharmony_ci   }
227bf215546Sopenharmony_ci   return true;
228bf215546Sopenharmony_ci}
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_cistatic inline bool
232bf215546Sopenharmony_ci_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
233bf215546Sopenharmony_ci{
234bf215546Sopenharmony_ci   if (!_eglCheckDisplay(disp, msg))
235bf215546Sopenharmony_ci      return false;
236bf215546Sopenharmony_ci   if (!s) {
237bf215546Sopenharmony_ci      _eglError(EGL_BAD_PARAMETER, msg);
238bf215546Sopenharmony_ci      return false;
239bf215546Sopenharmony_ci   }
240bf215546Sopenharmony_ci   return true;
241bf215546Sopenharmony_ci}
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci/**
245bf215546Sopenharmony_ci * Lookup and lock a display.
246bf215546Sopenharmony_ci */
247bf215546Sopenharmony_cistatic inline _EGLDisplay *
248bf215546Sopenharmony_ci_eglLockDisplay(EGLDisplay dpy)
249bf215546Sopenharmony_ci{
250bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLookupDisplay(dpy);
251bf215546Sopenharmony_ci   if (disp)
252bf215546Sopenharmony_ci      mtx_lock(&disp->Mutex);
253bf215546Sopenharmony_ci   return disp;
254bf215546Sopenharmony_ci}
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci/**
258bf215546Sopenharmony_ci * Unlock a display.
259bf215546Sopenharmony_ci */
260bf215546Sopenharmony_cistatic inline void
261bf215546Sopenharmony_ci_eglUnlockDisplay(_EGLDisplay *disp)
262bf215546Sopenharmony_ci{
263bf215546Sopenharmony_ci   mtx_unlock(&disp->Mutex);
264bf215546Sopenharmony_ci}
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_cistatic EGLBoolean
267bf215546Sopenharmony_ci_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
268bf215546Sopenharmony_ci{
269bf215546Sopenharmony_ci   _EGLThreadInfo *thr = _eglGetCurrentThread();
270bf215546Sopenharmony_ci   thr->CurrentFuncName = funcName;
271bf215546Sopenharmony_ci   thr->CurrentObjectLabel = NULL;
272bf215546Sopenharmony_ci
273bf215546Sopenharmony_ci   if (objectType == EGL_OBJECT_THREAD_KHR)
274bf215546Sopenharmony_ci      thr->CurrentObjectLabel = thr->Label;
275bf215546Sopenharmony_ci   else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
276bf215546Sopenharmony_ci      thr->CurrentObjectLabel = disp->Label;
277bf215546Sopenharmony_ci   else if (object)
278bf215546Sopenharmony_ci      thr->CurrentObjectLabel = object->Label;
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   return EGL_TRUE;
281bf215546Sopenharmony_ci}
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci#define _EGL_FUNC_START(disp, objectType, object, ret) \
284bf215546Sopenharmony_ci   do { \
285bf215546Sopenharmony_ci      if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
286bf215546Sopenharmony_ci         if (disp)                                 \
287bf215546Sopenharmony_ci            _eglUnlockDisplay(disp);               \
288bf215546Sopenharmony_ci         return ret; \
289bf215546Sopenharmony_ci      } \
290bf215546Sopenharmony_ci   } while(0)
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci/**
293bf215546Sopenharmony_ci * Convert an attribute list from EGLint[] to EGLAttrib[].
294bf215546Sopenharmony_ci *
295bf215546Sopenharmony_ci * Return an EGL error code. The output parameter out_attrib_list is modified
296bf215546Sopenharmony_ci * only on success.
297bf215546Sopenharmony_ci */
298bf215546Sopenharmony_cistatic EGLint
299bf215546Sopenharmony_ci_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
300bf215546Sopenharmony_ci{
301bf215546Sopenharmony_ci   size_t len = 0;
302bf215546Sopenharmony_ci   EGLAttrib *attrib_list;
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci   if (int_list) {
305bf215546Sopenharmony_ci      while (int_list[2*len] != EGL_NONE)
306bf215546Sopenharmony_ci         ++len;
307bf215546Sopenharmony_ci   }
308bf215546Sopenharmony_ci
309bf215546Sopenharmony_ci   if (len == 0) {
310bf215546Sopenharmony_ci      *out_attrib_list = NULL;
311bf215546Sopenharmony_ci      return EGL_SUCCESS;
312bf215546Sopenharmony_ci   }
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci   if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
315bf215546Sopenharmony_ci      return EGL_BAD_ALLOC;
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci   attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
318bf215546Sopenharmony_ci   if (!attrib_list)
319bf215546Sopenharmony_ci      return EGL_BAD_ALLOC;
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci   for (size_t i = 0; i < len; ++i) {
322bf215546Sopenharmony_ci      attrib_list[2*i + 0] = int_list[2*i + 0];
323bf215546Sopenharmony_ci      attrib_list[2*i + 1] = int_list[2*i + 1];
324bf215546Sopenharmony_ci   }
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci   attrib_list[2*len] = EGL_NONE;
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci   *out_attrib_list = attrib_list;
329bf215546Sopenharmony_ci   return EGL_SUCCESS;
330bf215546Sopenharmony_ci}
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_cistatic EGLint *
334bf215546Sopenharmony_ci_eglConvertAttribsToInt(const EGLAttrib *attr_list)
335bf215546Sopenharmony_ci{
336bf215546Sopenharmony_ci   size_t size = _eglNumAttribs(attr_list);
337bf215546Sopenharmony_ci   EGLint *int_attribs = NULL;
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   /* Convert attributes from EGLAttrib[] to EGLint[] */
340bf215546Sopenharmony_ci   if (size) {
341bf215546Sopenharmony_ci      int_attribs = calloc(size, sizeof(int_attribs[0]));
342bf215546Sopenharmony_ci      if (!int_attribs)
343bf215546Sopenharmony_ci         return NULL;
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci      for (size_t i = 0; i < size; i++)
346bf215546Sopenharmony_ci         int_attribs[i] = attr_list[i];
347bf215546Sopenharmony_ci   }
348bf215546Sopenharmony_ci   return int_attribs;
349bf215546Sopenharmony_ci}
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci/**
353bf215546Sopenharmony_ci * This is typically the first EGL function that an application calls.
354bf215546Sopenharmony_ci * It associates a private _EGLDisplay object to the native display.
355bf215546Sopenharmony_ci */
356bf215546Sopenharmony_ciEGLDisplay EGLAPIENTRY
357bf215546Sopenharmony_cieglGetDisplay(EGLNativeDisplayType nativeDisplay)
358bf215546Sopenharmony_ci{
359bf215546Sopenharmony_ci   _EGLPlatformType plat;
360bf215546Sopenharmony_ci   _EGLDisplay *disp;
361bf215546Sopenharmony_ci   void *native_display_ptr;
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
366bf215546Sopenharmony_ci   native_display_ptr = (void*) nativeDisplay;
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci   plat = _eglGetNativePlatform(native_display_ptr);
369bf215546Sopenharmony_ci   disp = _eglFindDisplay(plat, native_display_ptr, NULL);
370bf215546Sopenharmony_ci   return _eglGetDisplayHandle(disp);
371bf215546Sopenharmony_ci}
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_cistatic EGLDisplay
374bf215546Sopenharmony_ci_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
375bf215546Sopenharmony_ci                             const EGLAttrib *attrib_list)
376bf215546Sopenharmony_ci{
377bf215546Sopenharmony_ci   _EGLDisplay *disp;
378bf215546Sopenharmony_ci
379bf215546Sopenharmony_ci   switch (platform) {
380bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM
381bf215546Sopenharmony_ci   case EGL_PLATFORM_X11_EXT:
382bf215546Sopenharmony_ci      disp = _eglGetX11Display((Display*) native_display, attrib_list);
383bf215546Sopenharmony_ci      break;
384bf215546Sopenharmony_ci#endif
385bf215546Sopenharmony_ci#ifdef HAVE_XCB_PLATFORM
386bf215546Sopenharmony_ci   case EGL_PLATFORM_XCB_EXT:
387bf215546Sopenharmony_ci      disp = _eglGetXcbDisplay((xcb_connection_t*) native_display, attrib_list);
388bf215546Sopenharmony_ci      break;
389bf215546Sopenharmony_ci#endif
390bf215546Sopenharmony_ci#ifdef HAVE_DRM_PLATFORM
391bf215546Sopenharmony_ci   case EGL_PLATFORM_GBM_MESA:
392bf215546Sopenharmony_ci      disp = _eglGetGbmDisplay((struct gbm_device*) native_display,
393bf215546Sopenharmony_ci                              attrib_list);
394bf215546Sopenharmony_ci      break;
395bf215546Sopenharmony_ci#endif
396bf215546Sopenharmony_ci#ifdef HAVE_WAYLAND_PLATFORM
397bf215546Sopenharmony_ci   case EGL_PLATFORM_WAYLAND_EXT:
398bf215546Sopenharmony_ci      disp = _eglGetWaylandDisplay((struct wl_display*) native_display,
399bf215546Sopenharmony_ci                                  attrib_list);
400bf215546Sopenharmony_ci      break;
401bf215546Sopenharmony_ci#endif
402bf215546Sopenharmony_ci   case EGL_PLATFORM_SURFACELESS_MESA:
403bf215546Sopenharmony_ci      disp = _eglGetSurfacelessDisplay(native_display, attrib_list);
404bf215546Sopenharmony_ci      break;
405bf215546Sopenharmony_ci#ifdef HAVE_ANDROID_PLATFORM
406bf215546Sopenharmony_ci   case EGL_PLATFORM_ANDROID_KHR:
407bf215546Sopenharmony_ci      disp = _eglGetAndroidDisplay(native_display, attrib_list);
408bf215546Sopenharmony_ci      break;
409bf215546Sopenharmony_ci#endif
410bf215546Sopenharmony_ci#ifdef HAVE_OHOS_PLATFORM
411bf215546Sopenharmony_ci    case EGL_PLATFORM_OHOS_KHR:
412bf215546Sopenharmony_ci        disp = _eglGetOHOSDisplay(native_display, attrib_list);
413bf215546Sopenharmony_ci        break;
414bf215546Sopenharmony_ci#endif
415bf215546Sopenharmony_ci   case EGL_PLATFORM_DEVICE_EXT:
416bf215546Sopenharmony_ci      disp = _eglGetDeviceDisplay(native_display, attrib_list);
417bf215546Sopenharmony_ci      break;
418bf215546Sopenharmony_ci   default:
419bf215546Sopenharmony_ci      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
420bf215546Sopenharmony_ci   }
421bf215546Sopenharmony_ci
422bf215546Sopenharmony_ci   return _eglGetDisplayHandle(disp);
423bf215546Sopenharmony_ci}
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_cistatic EGLDisplay EGLAPIENTRY
426bf215546Sopenharmony_cieglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
427bf215546Sopenharmony_ci                         const EGLint *int_attribs)
428bf215546Sopenharmony_ci{
429bf215546Sopenharmony_ci   EGLAttrib *attrib_list;
430bf215546Sopenharmony_ci   EGLDisplay disp;
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
433bf215546Sopenharmony_ci
434bf215546Sopenharmony_ci   if (_eglConvertIntsToAttribs(int_attribs, &attrib_list) != EGL_SUCCESS)
435bf215546Sopenharmony_ci      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
436bf215546Sopenharmony_ci
437bf215546Sopenharmony_ci   disp = _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
438bf215546Sopenharmony_ci   free(attrib_list);
439bf215546Sopenharmony_ci   return disp;
440bf215546Sopenharmony_ci}
441bf215546Sopenharmony_ci
442bf215546Sopenharmony_ciEGLDisplay EGLAPIENTRY
443bf215546Sopenharmony_cieglGetPlatformDisplay(EGLenum platform, void *native_display,
444bf215546Sopenharmony_ci                      const EGLAttrib *attrib_list)
445bf215546Sopenharmony_ci{
446bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
447bf215546Sopenharmony_ci   return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
448bf215546Sopenharmony_ci}
449bf215546Sopenharmony_ci
450bf215546Sopenharmony_ci/**
451bf215546Sopenharmony_ci * Copy the extension into the string and update the string pointer.
452bf215546Sopenharmony_ci */
453bf215546Sopenharmony_cistatic EGLint
454bf215546Sopenharmony_ci_eglAppendExtension(char **str, const char *ext)
455bf215546Sopenharmony_ci{
456bf215546Sopenharmony_ci   char *s = *str;
457bf215546Sopenharmony_ci   size_t len = strlen(ext);
458bf215546Sopenharmony_ci
459bf215546Sopenharmony_ci   if (s) {
460bf215546Sopenharmony_ci      memcpy(s, ext, len);
461bf215546Sopenharmony_ci      s[len++] = ' ';
462bf215546Sopenharmony_ci      s[len] = '\0';
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ci      *str += len;
465bf215546Sopenharmony_ci   }
466bf215546Sopenharmony_ci   else {
467bf215546Sopenharmony_ci      len++;
468bf215546Sopenharmony_ci   }
469bf215546Sopenharmony_ci
470bf215546Sopenharmony_ci   return (EGLint) len;
471bf215546Sopenharmony_ci}
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci/**
474bf215546Sopenharmony_ci * Examine the individual extension enable/disable flags and recompute
475bf215546Sopenharmony_ci * the driver's Extensions string.
476bf215546Sopenharmony_ci */
477bf215546Sopenharmony_cistatic void
478bf215546Sopenharmony_ci_eglCreateExtensionsString(_EGLDisplay *disp)
479bf215546Sopenharmony_ci{
480bf215546Sopenharmony_ci#define _EGL_CHECK_EXTENSION(ext)                                          \
481bf215546Sopenharmony_ci   do {                                                                    \
482bf215546Sopenharmony_ci      if (disp->Extensions.ext) {                                           \
483bf215546Sopenharmony_ci         _eglAppendExtension(&exts, "EGL_" #ext);                          \
484bf215546Sopenharmony_ci         assert(exts <= disp->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN);  \
485bf215546Sopenharmony_ci      }                                                                    \
486bf215546Sopenharmony_ci   } while (0)
487bf215546Sopenharmony_ci
488bf215546Sopenharmony_ci   char *exts = disp->ExtensionsString;
489bf215546Sopenharmony_ci
490bf215546Sopenharmony_ci   /* Please keep these sorted alphabetically. */
491bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(ANDROID_blob_cache);
492bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
493bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
494bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
495bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(ANDROID_recordable);
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
498bf215546Sopenharmony_ci
499bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_buffer_age);
500bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
501bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
502bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
503bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_protected_surface);
504bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_present_opaque);
505bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
506bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
507bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
508bf215546Sopenharmony_ci
509bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(IMG_context_priority);
510bf215546Sopenharmony_ci
511bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_cl_event2);
512bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_config_attribs);
513bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_context_flush_control);
514bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_create_context);
515bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
516bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_fence_sync);
517bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
518bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
519bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
520bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
521bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
522bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
523bf215546Sopenharmony_ci   if (disp->Extensions.KHR_image_base && disp->Extensions.KHR_image_pixmap)
524bf215546Sopenharmony_ci      disp->Extensions.KHR_image = EGL_TRUE;
525bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_image);
526bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_image_base);
527bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_image_pixmap);
528bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_mutable_render_buffer);
529bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_no_config_context);
530bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_partial_update);
531bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_reusable_sync);
532bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
533bf215546Sopenharmony_ci   if (disp->Extensions.EXT_swap_buffers_with_damage)
534bf215546Sopenharmony_ci      _eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
535bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(EXT_pixel_format_float);
536bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(KHR_wait_sync);
537bf215546Sopenharmony_ci
538bf215546Sopenharmony_ci   if (disp->Extensions.KHR_no_config_context)
539bf215546Sopenharmony_ci      _eglAppendExtension(&exts, "EGL_MESA_configless_context");
540bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(MESA_drm_image);
541bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
542bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(MESA_query_driver);
543bf215546Sopenharmony_ci
544bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(NOK_swap_region);
545bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(NV_post_sub_buffer);
548bf215546Sopenharmony_ci
549bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(WL_bind_wayland_display);
550bf215546Sopenharmony_ci   _EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
551bf215546Sopenharmony_ci
552bf215546Sopenharmony_ci#undef _EGL_CHECK_EXTENSION
553bf215546Sopenharmony_ci}
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_cistatic void
556bf215546Sopenharmony_ci_eglCreateAPIsString(_EGLDisplay *disp)
557bf215546Sopenharmony_ci{
558bf215546Sopenharmony_ci#define addstr(str) \
559bf215546Sopenharmony_ci   { \
560bf215546Sopenharmony_ci      const size_t old_len = strlen(disp->ClientAPIsString); \
561bf215546Sopenharmony_ci      const size_t add_len = sizeof(str); \
562bf215546Sopenharmony_ci      const size_t max_len = sizeof(disp->ClientAPIsString) - 1; \
563bf215546Sopenharmony_ci      if (old_len + add_len <= max_len) \
564bf215546Sopenharmony_ci         strcat(disp->ClientAPIsString, str " "); \
565bf215546Sopenharmony_ci      else \
566bf215546Sopenharmony_ci         assert(!"disp->ClientAPIsString is not large enough"); \
567bf215546Sopenharmony_ci   }
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_ci   if (disp->ClientAPIs & EGL_OPENGL_BIT)
570bf215546Sopenharmony_ci      addstr("OpenGL");
571bf215546Sopenharmony_ci
572bf215546Sopenharmony_ci   if (disp->ClientAPIs & EGL_OPENGL_ES_BIT ||
573bf215546Sopenharmony_ci       disp->ClientAPIs & EGL_OPENGL_ES2_BIT ||
574bf215546Sopenharmony_ci       disp->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
575bf215546Sopenharmony_ci      addstr("OpenGL_ES");
576bf215546Sopenharmony_ci   }
577bf215546Sopenharmony_ci
578bf215546Sopenharmony_ci   if (disp->ClientAPIs & EGL_OPENVG_BIT)
579bf215546Sopenharmony_ci      addstr("OpenVG");
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_ci#undef addstr
582bf215546Sopenharmony_ci}
583bf215546Sopenharmony_ci
584bf215546Sopenharmony_cistatic void
585bf215546Sopenharmony_ci_eglComputeVersion(_EGLDisplay *disp)
586bf215546Sopenharmony_ci{
587bf215546Sopenharmony_ci   disp->Version = 14;
588bf215546Sopenharmony_ci
589bf215546Sopenharmony_ci   if (disp->Extensions.KHR_fence_sync &&
590bf215546Sopenharmony_ci       disp->Extensions.KHR_cl_event2 &&
591bf215546Sopenharmony_ci       disp->Extensions.KHR_wait_sync &&
592bf215546Sopenharmony_ci       disp->Extensions.KHR_image_base &&
593bf215546Sopenharmony_ci       disp->Extensions.KHR_gl_texture_2D_image &&
594bf215546Sopenharmony_ci       disp->Extensions.KHR_gl_texture_3D_image &&
595bf215546Sopenharmony_ci       disp->Extensions.KHR_gl_texture_cubemap_image &&
596bf215546Sopenharmony_ci       disp->Extensions.KHR_gl_renderbuffer_image &&
597bf215546Sopenharmony_ci       disp->Extensions.KHR_create_context &&
598bf215546Sopenharmony_ci       disp->Extensions.EXT_create_context_robustness &&
599bf215546Sopenharmony_ci       disp->Extensions.KHR_get_all_proc_addresses &&
600bf215546Sopenharmony_ci       disp->Extensions.KHR_gl_colorspace &&
601bf215546Sopenharmony_ci       disp->Extensions.KHR_surfaceless_context)
602bf215546Sopenharmony_ci      disp->Version = 15;
603bf215546Sopenharmony_ci
604bf215546Sopenharmony_ci   /* For Android P and below limit the EGL version to 1.4 */
605bf215546Sopenharmony_ci#if defined(ANDROID) && ANDROID_API_LEVEL <= 28
606bf215546Sopenharmony_ci   disp->Version = 14;
607bf215546Sopenharmony_ci#endif
608bf215546Sopenharmony_ci}
609bf215546Sopenharmony_ci
610bf215546Sopenharmony_ci/**
611bf215546Sopenharmony_ci * This is typically the second EGL function that an application calls.
612bf215546Sopenharmony_ci * Here we load/initialize the actual hardware driver.
613bf215546Sopenharmony_ci */
614bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
615bf215546Sopenharmony_cieglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
616bf215546Sopenharmony_ci{
617bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
618bf215546Sopenharmony_ci
619bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
620bf215546Sopenharmony_ci
621bf215546Sopenharmony_ci   if (!disp)
622bf215546Sopenharmony_ci      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
623bf215546Sopenharmony_ci
624bf215546Sopenharmony_ci   if (!disp->Initialized) {
625bf215546Sopenharmony_ci      /* set options */
626bf215546Sopenharmony_ci      disp->Options.ForceSoftware =
627bf215546Sopenharmony_ci         env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false);
628bf215546Sopenharmony_ci      if (disp->Options.ForceSoftware)
629bf215546Sopenharmony_ci         _eglLog(_EGL_DEBUG, "Found 'LIBGL_ALWAYS_SOFTWARE' set, will use a CPU renderer");
630bf215546Sopenharmony_ci
631bf215546Sopenharmony_ci      const char *env = getenv("MESA_LOADER_DRIVER_OVERRIDE");
632bf215546Sopenharmony_ci      disp->Options.Zink = env && !strcmp(env, "zink");
633bf215546Sopenharmony_ci      disp->Options.ForceSoftware |= disp->Options.Zink;
634bf215546Sopenharmony_ci
635bf215546Sopenharmony_ci      /**
636bf215546Sopenharmony_ci       * Initialize the display using the driver's function.
637bf215546Sopenharmony_ci       * If the initialisation fails, try again using only software rendering.
638bf215546Sopenharmony_ci       */
639bf215546Sopenharmony_ci      if (!_eglDriver.Initialize(disp)) {
640bf215546Sopenharmony_ci         if (disp->Options.ForceSoftware)
641bf215546Sopenharmony_ci            RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
642bf215546Sopenharmony_ci         else {
643bf215546Sopenharmony_ci            disp->Options.ForceSoftware = EGL_TRUE;
644bf215546Sopenharmony_ci            if (!_eglDriver.Initialize(disp))
645bf215546Sopenharmony_ci               RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
646bf215546Sopenharmony_ci         }
647bf215546Sopenharmony_ci      }
648bf215546Sopenharmony_ci
649bf215546Sopenharmony_ci      disp->Initialized = EGL_TRUE;
650bf215546Sopenharmony_ci      disp->Driver = &_eglDriver;
651bf215546Sopenharmony_ci
652bf215546Sopenharmony_ci      /* limit to APIs supported by core */
653bf215546Sopenharmony_ci      disp->ClientAPIs &= _EGL_API_ALL_BITS;
654bf215546Sopenharmony_ci
655bf215546Sopenharmony_ci      /* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
656bf215546Sopenharmony_ci       * classifies it as an EGL display extension, though conceptually it's an
657bf215546Sopenharmony_ci       * EGL client extension.
658bf215546Sopenharmony_ci       *
659bf215546Sopenharmony_ci       * From the EGL_KHR_get_all_proc_addresses spec:
660bf215546Sopenharmony_ci       *
661bf215546Sopenharmony_ci       *    The EGL implementation must expose the name
662bf215546Sopenharmony_ci       *    EGL_KHR_client_get_all_proc_addresses if and only if it exposes
663bf215546Sopenharmony_ci       *    EGL_KHR_get_all_proc_addresses and supports
664bf215546Sopenharmony_ci       *    EGL_EXT_client_extensions.
665bf215546Sopenharmony_ci       *
666bf215546Sopenharmony_ci       * Mesa unconditionally exposes both client extensions mentioned above,
667bf215546Sopenharmony_ci       * so the spec requires that each EGLDisplay unconditionally expose
668bf215546Sopenharmony_ci       * EGL_KHR_get_all_proc_addresses also.
669bf215546Sopenharmony_ci       */
670bf215546Sopenharmony_ci      disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
671bf215546Sopenharmony_ci
672bf215546Sopenharmony_ci      /* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
673bf215546Sopenharmony_ci       * programs. It is driver agnostic and handled in the main EGL code.
674bf215546Sopenharmony_ci       */
675bf215546Sopenharmony_ci      disp->Extensions.KHR_config_attribs = EGL_TRUE;
676bf215546Sopenharmony_ci
677bf215546Sopenharmony_ci      _eglComputeVersion(disp);
678bf215546Sopenharmony_ci      _eglCreateExtensionsString(disp);
679bf215546Sopenharmony_ci      _eglCreateAPIsString(disp);
680bf215546Sopenharmony_ci      snprintf(disp->VersionString, sizeof(disp->VersionString),
681bf215546Sopenharmony_ci               "%d.%d", disp->Version / 10, disp->Version % 10);
682bf215546Sopenharmony_ci   }
683bf215546Sopenharmony_ci
684bf215546Sopenharmony_ci   /* Update applications version of major and minor if not NULL */
685bf215546Sopenharmony_ci   if ((major != NULL) && (minor != NULL)) {
686bf215546Sopenharmony_ci      *major = disp->Version / 10;
687bf215546Sopenharmony_ci      *minor = disp->Version % 10;
688bf215546Sopenharmony_ci   }
689bf215546Sopenharmony_ci
690bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
691bf215546Sopenharmony_ci}
692bf215546Sopenharmony_ci
693bf215546Sopenharmony_ci
694bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
695bf215546Sopenharmony_cieglTerminate(EGLDisplay dpy)
696bf215546Sopenharmony_ci{
697bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
698bf215546Sopenharmony_ci
699bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
700bf215546Sopenharmony_ci
701bf215546Sopenharmony_ci   if (!disp)
702bf215546Sopenharmony_ci      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
703bf215546Sopenharmony_ci
704bf215546Sopenharmony_ci   if (disp->Initialized) {
705bf215546Sopenharmony_ci      disp->Driver->Terminate(disp);
706bf215546Sopenharmony_ci      /* do not reset disp->Driver */
707bf215546Sopenharmony_ci      disp->ClientAPIsString[0] = 0;
708bf215546Sopenharmony_ci      disp->Initialized = EGL_FALSE;
709bf215546Sopenharmony_ci
710bf215546Sopenharmony_ci      /* Reset blob cache funcs on terminate. */
711bf215546Sopenharmony_ci      disp->BlobCacheSet = NULL;
712bf215546Sopenharmony_ci      disp->BlobCacheGet = NULL;
713bf215546Sopenharmony_ci   }
714bf215546Sopenharmony_ci
715bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
716bf215546Sopenharmony_ci}
717bf215546Sopenharmony_ci
718bf215546Sopenharmony_ci
719bf215546Sopenharmony_ciconst char * EGLAPIENTRY
720bf215546Sopenharmony_cieglQueryString(EGLDisplay dpy, EGLint name)
721bf215546Sopenharmony_ci{
722bf215546Sopenharmony_ci   _EGLDisplay *disp;
723bf215546Sopenharmony_ci
724bf215546Sopenharmony_ci#if !USE_LIBGLVND
725bf215546Sopenharmony_ci   if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
726bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
727bf215546Sopenharmony_ci   }
728bf215546Sopenharmony_ci#endif
729bf215546Sopenharmony_ci
730bf215546Sopenharmony_ci   disp = _eglLockDisplay(dpy);
731bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
732bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, NULL);
733bf215546Sopenharmony_ci
734bf215546Sopenharmony_ci   switch (name) {
735bf215546Sopenharmony_ci   case EGL_VENDOR:
736bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
737bf215546Sopenharmony_ci   case EGL_VERSION:
738bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(disp, disp->VersionString);
739bf215546Sopenharmony_ci   case EGL_EXTENSIONS:
740bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
741bf215546Sopenharmony_ci   case EGL_CLIENT_APIS:
742bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
743bf215546Sopenharmony_ci   default:
744bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
745bf215546Sopenharmony_ci   }
746bf215546Sopenharmony_ci}
747bf215546Sopenharmony_ci
748bf215546Sopenharmony_ci
749bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
750bf215546Sopenharmony_cieglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
751bf215546Sopenharmony_ci              EGLint config_size, EGLint *num_config)
752bf215546Sopenharmony_ci{
753bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
754bf215546Sopenharmony_ci   EGLBoolean ret;
755bf215546Sopenharmony_ci
756bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
757bf215546Sopenharmony_ci
758bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
759bf215546Sopenharmony_ci
760bf215546Sopenharmony_ci   if (!num_config)
761bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
762bf215546Sopenharmony_ci
763bf215546Sopenharmony_ci   ret = _eglGetConfigs(disp, configs, config_size, num_config);
764bf215546Sopenharmony_ci
765bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
766bf215546Sopenharmony_ci}
767bf215546Sopenharmony_ci
768bf215546Sopenharmony_ci
769bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
770bf215546Sopenharmony_cieglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
771bf215546Sopenharmony_ci                EGLint config_size, EGLint *num_config)
772bf215546Sopenharmony_ci{
773bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
774bf215546Sopenharmony_ci   EGLBoolean ret;
775bf215546Sopenharmony_ci
776bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
777bf215546Sopenharmony_ci
778bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
779bf215546Sopenharmony_ci
780bf215546Sopenharmony_ci   if (!num_config)
781bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
782bf215546Sopenharmony_ci
783bf215546Sopenharmony_ci   ret = _eglChooseConfig(disp, attrib_list, configs,
784bf215546Sopenharmony_ci                          config_size, num_config);
785bf215546Sopenharmony_ci
786bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
787bf215546Sopenharmony_ci}
788bf215546Sopenharmony_ci
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
791bf215546Sopenharmony_cieglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
792bf215546Sopenharmony_ci                   EGLint attribute, EGLint *value)
793bf215546Sopenharmony_ci{
794bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
795bf215546Sopenharmony_ci   _EGLConfig *conf = _eglLookupConfig(config, disp);
796bf215546Sopenharmony_ci   EGLBoolean ret;
797bf215546Sopenharmony_ci
798bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
799bf215546Sopenharmony_ci
800bf215546Sopenharmony_ci   _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE);
801bf215546Sopenharmony_ci
802bf215546Sopenharmony_ci   ret = _eglGetConfigAttrib(disp, conf, attribute, value);
803bf215546Sopenharmony_ci
804bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
805bf215546Sopenharmony_ci}
806bf215546Sopenharmony_ci
807bf215546Sopenharmony_ci
808bf215546Sopenharmony_ciEGLContext EGLAPIENTRY
809bf215546Sopenharmony_cieglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
810bf215546Sopenharmony_ci                 const EGLint *attrib_list)
811bf215546Sopenharmony_ci{
812bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
813bf215546Sopenharmony_ci   _EGLConfig *conf = _eglLookupConfig(config, disp);
814bf215546Sopenharmony_ci   _EGLContext *share = _eglLookupContext(share_list, disp);
815bf215546Sopenharmony_ci   _EGLContext *context;
816bf215546Sopenharmony_ci   EGLContext ret;
817bf215546Sopenharmony_ci
818bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
819bf215546Sopenharmony_ci
820bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT);
821bf215546Sopenharmony_ci
822bf215546Sopenharmony_ci   if (config != EGL_NO_CONFIG_KHR)
823bf215546Sopenharmony_ci      _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT);
824bf215546Sopenharmony_ci   else if (!disp->Extensions.KHR_no_config_context)
825bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
826bf215546Sopenharmony_ci
827bf215546Sopenharmony_ci   if (!share && share_list != EGL_NO_CONTEXT)
828bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
829bf215546Sopenharmony_ci
830bf215546Sopenharmony_ci   context = disp->Driver->CreateContext(disp, conf, share, attrib_list);
831bf215546Sopenharmony_ci   ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
832bf215546Sopenharmony_ci
833bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
834bf215546Sopenharmony_ci}
835bf215546Sopenharmony_ci
836bf215546Sopenharmony_ci
837bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
838bf215546Sopenharmony_cieglDestroyContext(EGLDisplay dpy, EGLContext ctx)
839bf215546Sopenharmony_ci{
840bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
841bf215546Sopenharmony_ci   _EGLContext *context = _eglLookupContext(ctx, disp);
842bf215546Sopenharmony_ci   EGLBoolean ret;
843bf215546Sopenharmony_ci
844bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
845bf215546Sopenharmony_ci
846bf215546Sopenharmony_ci   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
847bf215546Sopenharmony_ci   _eglUnlinkContext(context);
848bf215546Sopenharmony_ci   ret = disp->Driver->DestroyContext(disp, context);
849bf215546Sopenharmony_ci
850bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
851bf215546Sopenharmony_ci}
852bf215546Sopenharmony_ci
853bf215546Sopenharmony_ci
854bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
855bf215546Sopenharmony_cieglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
856bf215546Sopenharmony_ci               EGLContext ctx)
857bf215546Sopenharmony_ci{
858bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
859bf215546Sopenharmony_ci   _EGLContext *context = _eglLookupContext(ctx, disp);
860bf215546Sopenharmony_ci   _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
861bf215546Sopenharmony_ci   _EGLSurface *read_surf = _eglLookupSurface(read, disp);
862bf215546Sopenharmony_ci   EGLBoolean ret;
863bf215546Sopenharmony_ci
864bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
865bf215546Sopenharmony_ci
866bf215546Sopenharmony_ci   if (!disp)
867bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
868bf215546Sopenharmony_ci
869bf215546Sopenharmony_ci   /* display is allowed to be uninitialized under certain condition */
870bf215546Sopenharmony_ci   if (!disp->Initialized) {
871bf215546Sopenharmony_ci      if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
872bf215546Sopenharmony_ci          ctx != EGL_NO_CONTEXT)
873bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
874bf215546Sopenharmony_ci   }
875bf215546Sopenharmony_ci   if (!disp->Driver)
876bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(disp, EGL_TRUE);
877bf215546Sopenharmony_ci
878bf215546Sopenharmony_ci   if (!context && ctx != EGL_NO_CONTEXT)
879bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
880bf215546Sopenharmony_ci   if (!draw_surf || !read_surf) {
881bf215546Sopenharmony_ci      /* From the EGL 1.4 (20130211) spec:
882bf215546Sopenharmony_ci       *
883bf215546Sopenharmony_ci       *    To release the current context without assigning a new one, set ctx
884bf215546Sopenharmony_ci       *    to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
885bf215546Sopenharmony_ci       */
886bf215546Sopenharmony_ci      if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
887bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
888bf215546Sopenharmony_ci
889bf215546Sopenharmony_ci      if ((!draw_surf && draw != EGL_NO_SURFACE) ||
890bf215546Sopenharmony_ci          (!read_surf && read != EGL_NO_SURFACE))
891bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
892bf215546Sopenharmony_ci      if (draw_surf || read_surf)
893bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
894bf215546Sopenharmony_ci   }
895bf215546Sopenharmony_ci
896bf215546Sopenharmony_ci   /*    If a native window underlying either draw or read is no longer valid,
897bf215546Sopenharmony_ci    *    an EGL_BAD_NATIVE_WINDOW error is generated.
898bf215546Sopenharmony_ci    */
899bf215546Sopenharmony_ci   if (draw_surf && draw_surf->Lost)
900bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
901bf215546Sopenharmony_ci   if (read_surf && read_surf->Lost)
902bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
903bf215546Sopenharmony_ci   /* EGL_EXT_protected_surface spec says:
904bf215546Sopenharmony_ci    *     If EGL_PROTECTED_CONTENT_EXT attributes of read is EGL_TRUE and
905bf215546Sopenharmony_ci    *     EGL_PROTECTED_CONTENT_EXT attributes of draw is EGL_FALSE, an
906bf215546Sopenharmony_ci    *     EGL_BAD_ACCESS error is generated.
907bf215546Sopenharmony_ci    */
908bf215546Sopenharmony_ci   if (read_surf && read_surf->ProtectedContent &&
909bf215546Sopenharmony_ci       draw_surf && !draw_surf->ProtectedContent)
910bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
911bf215546Sopenharmony_ci
912bf215546Sopenharmony_ci   ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
913bf215546Sopenharmony_ci
914bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
915bf215546Sopenharmony_ci}
916bf215546Sopenharmony_ci
917bf215546Sopenharmony_ci
918bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
919bf215546Sopenharmony_cieglQueryContext(EGLDisplay dpy, EGLContext ctx,
920bf215546Sopenharmony_ci                EGLint attribute, EGLint *value)
921bf215546Sopenharmony_ci{
922bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
923bf215546Sopenharmony_ci   _EGLContext *context = _eglLookupContext(ctx, disp);
924bf215546Sopenharmony_ci   EGLBoolean ret;
925bf215546Sopenharmony_ci
926bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
927bf215546Sopenharmony_ci
928bf215546Sopenharmony_ci   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
929bf215546Sopenharmony_ci
930bf215546Sopenharmony_ci   ret = _eglQueryContext(context, attribute, value);
931bf215546Sopenharmony_ci
932bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
933bf215546Sopenharmony_ci}
934bf215546Sopenharmony_ci
935bf215546Sopenharmony_ci
936bf215546Sopenharmony_ci/* In EGL specs 1.4 and 1.5, at the end of sections 3.5.1 and 3.5.4, it says
937bf215546Sopenharmony_ci * that if native_surface was already used to create a window or pixmap, we
938bf215546Sopenharmony_ci * can't create a new one. This is what this function checks for.
939bf215546Sopenharmony_ci */
940bf215546Sopenharmony_cistatic bool
941bf215546Sopenharmony_ci_eglNativeSurfaceAlreadyUsed(_EGLDisplay *disp, void *native_surface)
942bf215546Sopenharmony_ci{
943bf215546Sopenharmony_ci   _EGLResource *list;
944bf215546Sopenharmony_ci
945bf215546Sopenharmony_ci   list = disp->ResourceLists[_EGL_RESOURCE_SURFACE];
946bf215546Sopenharmony_ci   while (list) {
947bf215546Sopenharmony_ci      _EGLSurface *surf = (_EGLSurface *) list;
948bf215546Sopenharmony_ci
949bf215546Sopenharmony_ci      list = list->Next;
950bf215546Sopenharmony_ci
951bf215546Sopenharmony_ci      if (surf->Type == EGL_PBUFFER_BIT)
952bf215546Sopenharmony_ci         continue;
953bf215546Sopenharmony_ci
954bf215546Sopenharmony_ci      if (surf->NativeSurface == native_surface)
955bf215546Sopenharmony_ci         return true;
956bf215546Sopenharmony_ci   }
957bf215546Sopenharmony_ci
958bf215546Sopenharmony_ci   return false;
959bf215546Sopenharmony_ci}
960bf215546Sopenharmony_ci
961bf215546Sopenharmony_ci
962bf215546Sopenharmony_cistatic EGLSurface
963bf215546Sopenharmony_ci_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
964bf215546Sopenharmony_ci                              void *native_window, const EGLint *attrib_list)
965bf215546Sopenharmony_ci{
966bf215546Sopenharmony_ci   _EGLConfig *conf = _eglLookupConfig(config, disp);
967bf215546Sopenharmony_ci   _EGLSurface *surf;
968bf215546Sopenharmony_ci   EGLSurface ret;
969bf215546Sopenharmony_ci
970bf215546Sopenharmony_ci
971bf215546Sopenharmony_ci   if (native_window == NULL)
972bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
973bf215546Sopenharmony_ci
974bf215546Sopenharmony_ci   if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
975bf215546Sopenharmony_ci                disp->Platform == _EGL_PLATFORM_DEVICE)) {
976bf215546Sopenharmony_ci      /* From the EGL_MESA_platform_surfaceless spec (v1):
977bf215546Sopenharmony_ci       *
978bf215546Sopenharmony_ci       *    eglCreatePlatformWindowSurface fails when called with a <display>
979bf215546Sopenharmony_ci       *    that belongs to the surfaceless platform. It returns
980bf215546Sopenharmony_ci       *    EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
981bf215546Sopenharmony_ci       *    justification for this unconditional failure is that the
982bf215546Sopenharmony_ci       *    surfaceless platform has no native windows, and therefore the
983bf215546Sopenharmony_ci       *    <native_window> parameter is always invalid.
984bf215546Sopenharmony_ci       *
985bf215546Sopenharmony_ci       * This check must occur before checking the EGLConfig, which emits
986bf215546Sopenharmony_ci       * EGL_BAD_CONFIG.
987bf215546Sopenharmony_ci       */
988bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
989bf215546Sopenharmony_ci   }
990bf215546Sopenharmony_ci
991bf215546Sopenharmony_ci   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
992bf215546Sopenharmony_ci
993bf215546Sopenharmony_ci   if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
994bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
995bf215546Sopenharmony_ci
996bf215546Sopenharmony_ci   if (_eglNativeSurfaceAlreadyUsed(disp, native_window))
997bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
998bf215546Sopenharmony_ci
999bf215546Sopenharmony_ci   surf = disp->Driver->CreateWindowSurface(disp, conf, native_window, attrib_list);
1000bf215546Sopenharmony_ci   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1001bf215546Sopenharmony_ci
1002bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1003bf215546Sopenharmony_ci}
1004bf215546Sopenharmony_ci
1005bf215546Sopenharmony_ci
1006bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY
1007bf215546Sopenharmony_cieglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
1008bf215546Sopenharmony_ci                       EGLNativeWindowType window, const EGLint *attrib_list)
1009bf215546Sopenharmony_ci{
1010bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1011bf215546Sopenharmony_ci
1012bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1013bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(void*) == sizeof(window));
1014bf215546Sopenharmony_ci   return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
1015bf215546Sopenharmony_ci                                        attrib_list);
1016bf215546Sopenharmony_ci}
1017bf215546Sopenharmony_ci
1018bf215546Sopenharmony_cistatic void *
1019bf215546Sopenharmony_ci_fixupNativeWindow(_EGLDisplay *disp, void *native_window)
1020bf215546Sopenharmony_ci{
1021bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM
1022bf215546Sopenharmony_ci   if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
1023bf215546Sopenharmony_ci      /* The `native_window` parameter for the X11 platform differs between
1024bf215546Sopenharmony_ci       * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
1025bf215546Sopenharmony_ci       * eglCreateWindowSurface(), the type of `native_window` is an Xlib
1026bf215546Sopenharmony_ci       * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
1027bf215546Sopenharmony_ci       * `Window*`.  Convert `Window*` to `Window` because that's what
1028bf215546Sopenharmony_ci       * dri2_x11_create_window_surface() expects.
1029bf215546Sopenharmony_ci       */
1030bf215546Sopenharmony_ci      return (void *)(* (Window*) native_window);
1031bf215546Sopenharmony_ci   }
1032bf215546Sopenharmony_ci#endif
1033bf215546Sopenharmony_ci#ifdef HAVE_XCB_PLATFORM
1034bf215546Sopenharmony_ci   if (disp && disp->Platform == _EGL_PLATFORM_XCB && native_window != NULL) {
1035bf215546Sopenharmony_ci      /* Similar to with X11, we need to convert (xcb_window_t *)
1036bf215546Sopenharmony_ci       * (i.e., uint32_t *) to xcb_window_t. We have to do an intermediate cast
1037bf215546Sopenharmony_ci       * to uintptr_t, since uint32_t may be smaller than a pointer.
1038bf215546Sopenharmony_ci       */
1039bf215546Sopenharmony_ci      return (void *)(uintptr_t) (* (uint32_t*) native_window);
1040bf215546Sopenharmony_ci   }
1041bf215546Sopenharmony_ci#endif
1042bf215546Sopenharmony_ci   return native_window;
1043bf215546Sopenharmony_ci}
1044bf215546Sopenharmony_ci
1045bf215546Sopenharmony_cistatic EGLSurface EGLAPIENTRY
1046bf215546Sopenharmony_cieglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
1047bf215546Sopenharmony_ci                                  void *native_window,
1048bf215546Sopenharmony_ci                                  const EGLint *attrib_list)
1049bf215546Sopenharmony_ci{
1050bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1051bf215546Sopenharmony_ci
1052bf215546Sopenharmony_ci   native_window = _fixupNativeWindow(disp, native_window);
1053bf215546Sopenharmony_ci
1054bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1055bf215546Sopenharmony_ci   return _eglCreateWindowSurfaceCommon(disp, config, native_window,
1056bf215546Sopenharmony_ci                                        attrib_list);
1057bf215546Sopenharmony_ci}
1058bf215546Sopenharmony_ci
1059bf215546Sopenharmony_ci
1060bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY
1061bf215546Sopenharmony_cieglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
1062bf215546Sopenharmony_ci                               void *native_window,
1063bf215546Sopenharmony_ci                               const EGLAttrib *attrib_list)
1064bf215546Sopenharmony_ci{
1065bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1066bf215546Sopenharmony_ci   EGLSurface surface;
1067bf215546Sopenharmony_ci   EGLint *int_attribs;
1068bf215546Sopenharmony_ci
1069bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1070bf215546Sopenharmony_ci
1071bf215546Sopenharmony_ci   int_attribs = _eglConvertAttribsToInt(attrib_list);
1072bf215546Sopenharmony_ci   if (attrib_list && !int_attribs)
1073bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
1074bf215546Sopenharmony_ci
1075bf215546Sopenharmony_ci   native_window = _fixupNativeWindow(disp, native_window);
1076bf215546Sopenharmony_ci   surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
1077bf215546Sopenharmony_ci                                           int_attribs);
1078bf215546Sopenharmony_ci   free(int_attribs);
1079bf215546Sopenharmony_ci   return surface;
1080bf215546Sopenharmony_ci}
1081bf215546Sopenharmony_ci
1082bf215546Sopenharmony_cistatic void *
1083bf215546Sopenharmony_ci_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
1084bf215546Sopenharmony_ci{
1085bf215546Sopenharmony_ci#ifdef HAVE_X11_PLATFORM
1086bf215546Sopenharmony_ci   /* The `native_pixmap` parameter for the X11 platform differs between
1087bf215546Sopenharmony_ci    * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
1088bf215546Sopenharmony_ci    * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
1089bf215546Sopenharmony_ci    * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
1090bf215546Sopenharmony_ci    * `Pixmap*`.  Convert `Pixmap*` to `Pixmap` because that's what
1091bf215546Sopenharmony_ci    * dri2_x11_create_pixmap_surface() expects.
1092bf215546Sopenharmony_ci    */
1093bf215546Sopenharmony_ci   if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
1094bf215546Sopenharmony_ci      return (void *)(* (Pixmap*) native_pixmap);
1095bf215546Sopenharmony_ci#endif
1096bf215546Sopenharmony_ci#ifdef HAVE_XCB_PLATFORM
1097bf215546Sopenharmony_ci   if (disp && disp->Platform == _EGL_PLATFORM_XCB && native_pixmap != NULL) {
1098bf215546Sopenharmony_ci      /* Similar to with X11, we need to convert (xcb_pixmap_t *)
1099bf215546Sopenharmony_ci       * (i.e., uint32_t *) to xcb_pixmap_t. We have to do an intermediate cast
1100bf215546Sopenharmony_ci       * to uintptr_t, since uint32_t may be smaller than a pointer.
1101bf215546Sopenharmony_ci       */
1102bf215546Sopenharmony_ci      return (void *)(uintptr_t) (* (uint32_t*) native_pixmap);
1103bf215546Sopenharmony_ci   }
1104bf215546Sopenharmony_ci#endif
1105bf215546Sopenharmony_ci   return native_pixmap;
1106bf215546Sopenharmony_ci}
1107bf215546Sopenharmony_ci
1108bf215546Sopenharmony_cistatic EGLSurface
1109bf215546Sopenharmony_ci_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
1110bf215546Sopenharmony_ci                              void *native_pixmap, const EGLint *attrib_list)
1111bf215546Sopenharmony_ci{
1112bf215546Sopenharmony_ci   _EGLConfig *conf = _eglLookupConfig(config, disp);
1113bf215546Sopenharmony_ci   _EGLSurface *surf;
1114bf215546Sopenharmony_ci   EGLSurface ret;
1115bf215546Sopenharmony_ci
1116bf215546Sopenharmony_ci   if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
1117bf215546Sopenharmony_ci                disp->Platform == _EGL_PLATFORM_DEVICE)) {
1118bf215546Sopenharmony_ci      /* From the EGL_MESA_platform_surfaceless spec (v1):
1119bf215546Sopenharmony_ci       *
1120bf215546Sopenharmony_ci       *   [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
1121bf215546Sopenharmony_ci       *   also fails when called with a <display> that belongs to the
1122bf215546Sopenharmony_ci       *   surfaceless platform.  It returns EGL_NO_SURFACE and generates
1123bf215546Sopenharmony_ci       *   EGL_BAD_NATIVE_PIXMAP.
1124bf215546Sopenharmony_ci       *
1125bf215546Sopenharmony_ci       * This check must occur before checking the EGLConfig, which emits
1126bf215546Sopenharmony_ci       * EGL_BAD_CONFIG.
1127bf215546Sopenharmony_ci       */
1128bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1129bf215546Sopenharmony_ci   }
1130bf215546Sopenharmony_ci
1131bf215546Sopenharmony_ci   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
1132bf215546Sopenharmony_ci
1133bf215546Sopenharmony_ci   if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
1134bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1135bf215546Sopenharmony_ci
1136bf215546Sopenharmony_ci   if (native_pixmap == NULL)
1137bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
1138bf215546Sopenharmony_ci
1139bf215546Sopenharmony_ci   if (_eglNativeSurfaceAlreadyUsed(disp, native_pixmap))
1140bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
1141bf215546Sopenharmony_ci
1142bf215546Sopenharmony_ci   surf = disp->Driver->CreatePixmapSurface(disp, conf, native_pixmap, attrib_list);
1143bf215546Sopenharmony_ci   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1144bf215546Sopenharmony_ci
1145bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1146bf215546Sopenharmony_ci}
1147bf215546Sopenharmony_ci
1148bf215546Sopenharmony_ci
1149bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY
1150bf215546Sopenharmony_cieglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
1151bf215546Sopenharmony_ci                       EGLNativePixmapType pixmap, const EGLint *attrib_list)
1152bf215546Sopenharmony_ci{
1153bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1154bf215546Sopenharmony_ci
1155bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1156bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
1157bf215546Sopenharmony_ci   return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
1158bf215546Sopenharmony_ci                                        attrib_list);
1159bf215546Sopenharmony_ci}
1160bf215546Sopenharmony_ci
1161bf215546Sopenharmony_cistatic EGLSurface EGLAPIENTRY
1162bf215546Sopenharmony_cieglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
1163bf215546Sopenharmony_ci                                  void *native_pixmap,
1164bf215546Sopenharmony_ci                                  const EGLint *attrib_list)
1165bf215546Sopenharmony_ci{
1166bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1167bf215546Sopenharmony_ci
1168bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1169bf215546Sopenharmony_ci   native_pixmap = _fixupNativePixmap(disp, native_pixmap);
1170bf215546Sopenharmony_ci   return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1171bf215546Sopenharmony_ci                                        attrib_list);
1172bf215546Sopenharmony_ci}
1173bf215546Sopenharmony_ci
1174bf215546Sopenharmony_ci
1175bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY
1176bf215546Sopenharmony_cieglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
1177bf215546Sopenharmony_ci                               void *native_pixmap,
1178bf215546Sopenharmony_ci                               const EGLAttrib *attrib_list)
1179bf215546Sopenharmony_ci{
1180bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1181bf215546Sopenharmony_ci   EGLSurface surface;
1182bf215546Sopenharmony_ci   EGLint *int_attribs;
1183bf215546Sopenharmony_ci
1184bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1185bf215546Sopenharmony_ci
1186bf215546Sopenharmony_ci   int_attribs = _eglConvertAttribsToInt(attrib_list);
1187bf215546Sopenharmony_ci   if (attrib_list && !int_attribs)
1188bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
1189bf215546Sopenharmony_ci
1190bf215546Sopenharmony_ci   native_pixmap = _fixupNativePixmap(disp, native_pixmap);
1191bf215546Sopenharmony_ci   surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
1192bf215546Sopenharmony_ci                                           int_attribs);
1193bf215546Sopenharmony_ci   free(int_attribs);
1194bf215546Sopenharmony_ci   return surface;
1195bf215546Sopenharmony_ci}
1196bf215546Sopenharmony_ci
1197bf215546Sopenharmony_ci
1198bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY
1199bf215546Sopenharmony_cieglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
1200bf215546Sopenharmony_ci                        const EGLint *attrib_list)
1201bf215546Sopenharmony_ci{
1202bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1203bf215546Sopenharmony_ci   _EGLConfig *conf = _eglLookupConfig(config, disp);
1204bf215546Sopenharmony_ci   _EGLSurface *surf;
1205bf215546Sopenharmony_ci   EGLSurface ret;
1206bf215546Sopenharmony_ci
1207bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1208bf215546Sopenharmony_ci   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
1209bf215546Sopenharmony_ci
1210bf215546Sopenharmony_ci   if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
1211bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
1212bf215546Sopenharmony_ci
1213bf215546Sopenharmony_ci   surf = disp->Driver->CreatePbufferSurface(disp, conf, attrib_list);
1214bf215546Sopenharmony_ci   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1215bf215546Sopenharmony_ci
1216bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1217bf215546Sopenharmony_ci}
1218bf215546Sopenharmony_ci
1219bf215546Sopenharmony_ci
1220bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1221bf215546Sopenharmony_cieglDestroySurface(EGLDisplay dpy, EGLSurface surface)
1222bf215546Sopenharmony_ci{
1223bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1224bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1225bf215546Sopenharmony_ci   EGLBoolean ret;
1226bf215546Sopenharmony_ci
1227bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1228bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1229bf215546Sopenharmony_ci   _eglUnlinkSurface(surf);
1230bf215546Sopenharmony_ci   ret = disp->Driver->DestroySurface(disp, surf);
1231bf215546Sopenharmony_ci
1232bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1233bf215546Sopenharmony_ci}
1234bf215546Sopenharmony_ci
1235bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1236bf215546Sopenharmony_cieglQuerySurface(EGLDisplay dpy, EGLSurface surface,
1237bf215546Sopenharmony_ci                EGLint attribute, EGLint *value)
1238bf215546Sopenharmony_ci{
1239bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1240bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1241bf215546Sopenharmony_ci   EGLBoolean ret;
1242bf215546Sopenharmony_ci
1243bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1244bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1245bf215546Sopenharmony_ci
1246bf215546Sopenharmony_ci   if (disp->Driver->QuerySurface)
1247bf215546Sopenharmony_ci      ret = disp->Driver->QuerySurface(disp, surf, attribute, value);
1248bf215546Sopenharmony_ci   else
1249bf215546Sopenharmony_ci      ret = _eglQuerySurface(disp, surf, attribute, value);
1250bf215546Sopenharmony_ci
1251bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1252bf215546Sopenharmony_ci}
1253bf215546Sopenharmony_ci
1254bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1255bf215546Sopenharmony_cieglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
1256bf215546Sopenharmony_ci                 EGLint attribute, EGLint value)
1257bf215546Sopenharmony_ci{
1258bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1259bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1260bf215546Sopenharmony_ci   EGLBoolean ret;
1261bf215546Sopenharmony_ci
1262bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1263bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1264bf215546Sopenharmony_ci
1265bf215546Sopenharmony_ci   ret = _eglSurfaceAttrib(disp, surf, attribute, value);
1266bf215546Sopenharmony_ci
1267bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1268bf215546Sopenharmony_ci}
1269bf215546Sopenharmony_ci
1270bf215546Sopenharmony_ci
1271bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1272bf215546Sopenharmony_cieglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1273bf215546Sopenharmony_ci{
1274bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1275bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1276bf215546Sopenharmony_ci   EGLBoolean ret;
1277bf215546Sopenharmony_ci
1278bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1279bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1280bf215546Sopenharmony_ci   ret = disp->Driver->BindTexImage(disp, surf, buffer);
1281bf215546Sopenharmony_ci
1282bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1283bf215546Sopenharmony_ci}
1284bf215546Sopenharmony_ci
1285bf215546Sopenharmony_ci
1286bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1287bf215546Sopenharmony_cieglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
1288bf215546Sopenharmony_ci{
1289bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1290bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1291bf215546Sopenharmony_ci   EGLBoolean ret;
1292bf215546Sopenharmony_ci
1293bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1294bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1295bf215546Sopenharmony_ci   ret = disp->Driver->ReleaseTexImage(disp, surf, buffer);
1296bf215546Sopenharmony_ci
1297bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1298bf215546Sopenharmony_ci}
1299bf215546Sopenharmony_ci
1300bf215546Sopenharmony_ci
1301bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1302bf215546Sopenharmony_cieglSwapInterval(EGLDisplay dpy, EGLint interval)
1303bf215546Sopenharmony_ci{
1304bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1305bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1306bf215546Sopenharmony_ci   _EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
1307bf215546Sopenharmony_ci   EGLBoolean ret;
1308bf215546Sopenharmony_ci
1309bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1310bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
1311bf215546Sopenharmony_ci
1312bf215546Sopenharmony_ci   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1313bf215546Sopenharmony_ci       ctx->Resource.Display != disp)
1314bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
1315bf215546Sopenharmony_ci
1316bf215546Sopenharmony_ci   if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
1317bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1318bf215546Sopenharmony_ci
1319bf215546Sopenharmony_ci   if (surf->Type != EGL_WINDOW_BIT)
1320bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_TRUE);
1321bf215546Sopenharmony_ci
1322bf215546Sopenharmony_ci   interval = CLAMP(interval,
1323bf215546Sopenharmony_ci                    surf->Config->MinSwapInterval,
1324bf215546Sopenharmony_ci                    surf->Config->MaxSwapInterval);
1325bf215546Sopenharmony_ci
1326bf215546Sopenharmony_ci   if (surf->SwapInterval != interval && disp->Driver->SwapInterval)
1327bf215546Sopenharmony_ci      ret = disp->Driver->SwapInterval(disp, surf, interval);
1328bf215546Sopenharmony_ci   else
1329bf215546Sopenharmony_ci      ret = EGL_TRUE;
1330bf215546Sopenharmony_ci
1331bf215546Sopenharmony_ci   if (ret)
1332bf215546Sopenharmony_ci      surf->SwapInterval = interval;
1333bf215546Sopenharmony_ci
1334bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1335bf215546Sopenharmony_ci}
1336bf215546Sopenharmony_ci
1337bf215546Sopenharmony_ci
1338bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1339bf215546Sopenharmony_cieglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1340bf215546Sopenharmony_ci{
1341bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1342bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1343bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1344bf215546Sopenharmony_ci   EGLBoolean ret;
1345bf215546Sopenharmony_ci
1346bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1347bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1348bf215546Sopenharmony_ci
1349bf215546Sopenharmony_ci   /* surface must be bound to current context in EGL 1.4 */
1350bf215546Sopenharmony_ci   #ifndef _EGL_BUILT_IN_DRIVER_HAIKU
1351bf215546Sopenharmony_ci   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1352bf215546Sopenharmony_ci       surf != ctx->DrawSurface)
1353bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1354bf215546Sopenharmony_ci   #endif
1355bf215546Sopenharmony_ci
1356bf215546Sopenharmony_ci   if (surf->Type != EGL_WINDOW_BIT)
1357bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_TRUE);
1358bf215546Sopenharmony_ci
1359bf215546Sopenharmony_ci   /* From the EGL 1.5 spec:
1360bf215546Sopenharmony_ci    *
1361bf215546Sopenharmony_ci    *    If eglSwapBuffers is called and the native window associated with
1362bf215546Sopenharmony_ci    *    surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
1363bf215546Sopenharmony_ci    *    generated.
1364bf215546Sopenharmony_ci    */
1365bf215546Sopenharmony_ci   if (surf->Lost)
1366bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
1367bf215546Sopenharmony_ci
1368bf215546Sopenharmony_ci   ret = disp->Driver->SwapBuffers(disp, surf);
1369bf215546Sopenharmony_ci
1370bf215546Sopenharmony_ci   /* EGL_KHR_partial_update
1371bf215546Sopenharmony_ci    * Frame boundary successfully reached,
1372bf215546Sopenharmony_ci    * reset damage region and reset BufferAgeRead
1373bf215546Sopenharmony_ci    */
1374bf215546Sopenharmony_ci   if (ret) {
1375bf215546Sopenharmony_ci      surf->SetDamageRegionCalled = EGL_FALSE;
1376bf215546Sopenharmony_ci      surf->BufferAgeRead = EGL_FALSE;
1377bf215546Sopenharmony_ci   }
1378bf215546Sopenharmony_ci
1379bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1380bf215546Sopenharmony_ci}
1381bf215546Sopenharmony_ci
1382bf215546Sopenharmony_ci
1383bf215546Sopenharmony_cistatic EGLBoolean
1384bf215546Sopenharmony_ci_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
1385bf215546Sopenharmony_ci                                const EGLint *rects, EGLint n_rects)
1386bf215546Sopenharmony_ci{
1387bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1388bf215546Sopenharmony_ci   EGLBoolean ret;
1389bf215546Sopenharmony_ci
1390bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1391bf215546Sopenharmony_ci
1392bf215546Sopenharmony_ci   /* surface must be bound to current context in EGL 1.4 */
1393bf215546Sopenharmony_ci   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1394bf215546Sopenharmony_ci       surf != ctx->DrawSurface)
1395bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1396bf215546Sopenharmony_ci
1397bf215546Sopenharmony_ci   if (surf->Type != EGL_WINDOW_BIT)
1398bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_TRUE);
1399bf215546Sopenharmony_ci
1400bf215546Sopenharmony_ci   if ((n_rects > 0 && rects == NULL) || n_rects < 0)
1401bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1402bf215546Sopenharmony_ci
1403bf215546Sopenharmony_ci   ret = disp->Driver->SwapBuffersWithDamageEXT(disp, surf, rects, n_rects);
1404bf215546Sopenharmony_ci
1405bf215546Sopenharmony_ci   /* EGL_KHR_partial_update
1406bf215546Sopenharmony_ci    * Frame boundary successfully reached,
1407bf215546Sopenharmony_ci    * reset damage region and reset BufferAgeRead
1408bf215546Sopenharmony_ci    */
1409bf215546Sopenharmony_ci   if (ret) {
1410bf215546Sopenharmony_ci      surf->SetDamageRegionCalled = EGL_FALSE;
1411bf215546Sopenharmony_ci      surf->BufferAgeRead = EGL_FALSE;
1412bf215546Sopenharmony_ci   }
1413bf215546Sopenharmony_ci
1414bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1415bf215546Sopenharmony_ci}
1416bf215546Sopenharmony_ci
1417bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
1418bf215546Sopenharmony_cieglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
1419bf215546Sopenharmony_ci                            const EGLint *rects, EGLint n_rects)
1420bf215546Sopenharmony_ci{
1421bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1422bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1423bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1424bf215546Sopenharmony_ci   return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
1425bf215546Sopenharmony_ci}
1426bf215546Sopenharmony_ci
1427bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
1428bf215546Sopenharmony_cieglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
1429bf215546Sopenharmony_ci                            const EGLint *rects, EGLint n_rects)
1430bf215546Sopenharmony_ci{
1431bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1432bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1433bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1434bf215546Sopenharmony_ci   return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
1435bf215546Sopenharmony_ci}
1436bf215546Sopenharmony_ci
1437bf215546Sopenharmony_ci/**
1438bf215546Sopenharmony_ci * Clamp the rectangles so that they lie within the surface.
1439bf215546Sopenharmony_ci */
1440bf215546Sopenharmony_ci
1441bf215546Sopenharmony_cistatic void
1442bf215546Sopenharmony_ci_eglSetDamageRegionKHRClampRects(_EGLSurface* surf,
1443bf215546Sopenharmony_ci                                 EGLint *rects, EGLint n_rects)
1444bf215546Sopenharmony_ci{
1445bf215546Sopenharmony_ci   EGLint i;
1446bf215546Sopenharmony_ci   EGLint surf_height = surf->Height;
1447bf215546Sopenharmony_ci   EGLint surf_width = surf->Width;
1448bf215546Sopenharmony_ci
1449bf215546Sopenharmony_ci   for (i = 0; i < (4 * n_rects); i += 4) {
1450bf215546Sopenharmony_ci      EGLint x1, y1, x2, y2;
1451bf215546Sopenharmony_ci      x1 = rects[i];
1452bf215546Sopenharmony_ci      y1 = rects[i + 1];
1453bf215546Sopenharmony_ci      x2 = rects[i + 2] + x1;
1454bf215546Sopenharmony_ci      y2 = rects[i + 3] + y1;
1455bf215546Sopenharmony_ci
1456bf215546Sopenharmony_ci      rects[i] = CLAMP(x1, 0, surf_width);
1457bf215546Sopenharmony_ci      rects[i + 1] = CLAMP(y1, 0, surf_height);
1458bf215546Sopenharmony_ci      rects[i + 2] = CLAMP(x2, 0, surf_width) - rects[i];
1459bf215546Sopenharmony_ci      rects[i + 3] = CLAMP(y2, 0, surf_height) - rects[i + 1];
1460bf215546Sopenharmony_ci   }
1461bf215546Sopenharmony_ci}
1462bf215546Sopenharmony_ci
1463bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
1464bf215546Sopenharmony_cieglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
1465bf215546Sopenharmony_ci                      EGLint *rects, EGLint n_rects)
1466bf215546Sopenharmony_ci{
1467bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1468bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1469bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1470bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1471bf215546Sopenharmony_ci   EGLBoolean ret;
1472bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1473bf215546Sopenharmony_ci
1474bf215546Sopenharmony_ci   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1475bf215546Sopenharmony_ci       surf->Type != EGL_WINDOW_BIT ||
1476bf215546Sopenharmony_ci       ctx->DrawSurface != surf ||
1477bf215546Sopenharmony_ci       surf->SwapBehavior != EGL_BUFFER_DESTROYED)
1478bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
1479bf215546Sopenharmony_ci
1480bf215546Sopenharmony_ci   /* If the damage region is already set or
1481bf215546Sopenharmony_ci    * buffer age is not queried between
1482bf215546Sopenharmony_ci    * frame boundaries, throw bad access error
1483bf215546Sopenharmony_ci    */
1484bf215546Sopenharmony_ci
1485bf215546Sopenharmony_ci   if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
1486bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
1487bf215546Sopenharmony_ci
1488bf215546Sopenharmony_ci   _eglSetDamageRegionKHRClampRects(surf, rects, n_rects);
1489bf215546Sopenharmony_ci   ret = disp->Driver->SetDamageRegion(disp, surf, rects, n_rects);
1490bf215546Sopenharmony_ci
1491bf215546Sopenharmony_ci   if (ret)
1492bf215546Sopenharmony_ci      surf->SetDamageRegionCalled = EGL_TRUE;
1493bf215546Sopenharmony_ci
1494bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1495bf215546Sopenharmony_ci}
1496bf215546Sopenharmony_ci
1497bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1498bf215546Sopenharmony_cieglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
1499bf215546Sopenharmony_ci{
1500bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1501bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1502bf215546Sopenharmony_ci   EGLBoolean ret;
1503bf215546Sopenharmony_ci   void *native_pixmap_ptr;
1504bf215546Sopenharmony_ci
1505bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
1506bf215546Sopenharmony_ci   STATIC_ASSERT(sizeof(void*) == sizeof(target));
1507bf215546Sopenharmony_ci   native_pixmap_ptr = (void*) target;
1508bf215546Sopenharmony_ci
1509bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
1510bf215546Sopenharmony_ci   if (surf->ProtectedContent)
1511bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
1512bf215546Sopenharmony_ci   ret = disp->Driver->CopyBuffers(disp, surf, native_pixmap_ptr);
1513bf215546Sopenharmony_ci
1514bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1515bf215546Sopenharmony_ci}
1516bf215546Sopenharmony_ci
1517bf215546Sopenharmony_ci
1518bf215546Sopenharmony_cistatic EGLBoolean
1519bf215546Sopenharmony_ci_eglWaitClientCommon(void)
1520bf215546Sopenharmony_ci{
1521bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1522bf215546Sopenharmony_ci   _EGLDisplay *disp;
1523bf215546Sopenharmony_ci   EGLBoolean ret;
1524bf215546Sopenharmony_ci
1525bf215546Sopenharmony_ci   if (!ctx)
1526bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1527bf215546Sopenharmony_ci
1528bf215546Sopenharmony_ci   disp = ctx->Resource.Display;
1529bf215546Sopenharmony_ci   mtx_lock(&disp->Mutex);
1530bf215546Sopenharmony_ci
1531bf215546Sopenharmony_ci   /* let bad current context imply bad current surface */
1532bf215546Sopenharmony_ci   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1533bf215546Sopenharmony_ci       _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
1534bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
1535bf215546Sopenharmony_ci
1536bf215546Sopenharmony_ci   /* a valid current context implies an initialized current display */
1537bf215546Sopenharmony_ci   assert(disp->Initialized);
1538bf215546Sopenharmony_ci   ret = disp->Driver->WaitClient(disp, ctx);
1539bf215546Sopenharmony_ci
1540bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1541bf215546Sopenharmony_ci}
1542bf215546Sopenharmony_ci
1543bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1544bf215546Sopenharmony_cieglWaitClient(void)
1545bf215546Sopenharmony_ci{
1546bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
1547bf215546Sopenharmony_ci   return _eglWaitClientCommon();
1548bf215546Sopenharmony_ci}
1549bf215546Sopenharmony_ci
1550bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1551bf215546Sopenharmony_cieglWaitGL(void)
1552bf215546Sopenharmony_ci{
1553bf215546Sopenharmony_ci   /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
1554bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
1555bf215546Sopenharmony_ci   return _eglWaitClientCommon();
1556bf215546Sopenharmony_ci}
1557bf215546Sopenharmony_ci
1558bf215546Sopenharmony_ci
1559bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1560bf215546Sopenharmony_cieglWaitNative(EGLint engine)
1561bf215546Sopenharmony_ci{
1562bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1563bf215546Sopenharmony_ci   _EGLDisplay *disp;
1564bf215546Sopenharmony_ci   EGLBoolean ret;
1565bf215546Sopenharmony_ci
1566bf215546Sopenharmony_ci   if (!ctx)
1567bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1568bf215546Sopenharmony_ci
1569bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1570bf215546Sopenharmony_ci
1571bf215546Sopenharmony_ci   disp = ctx->Resource.Display;
1572bf215546Sopenharmony_ci   mtx_lock(&disp->Mutex);
1573bf215546Sopenharmony_ci
1574bf215546Sopenharmony_ci   /* let bad current context imply bad current surface */
1575bf215546Sopenharmony_ci   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1576bf215546Sopenharmony_ci       _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
1577bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
1578bf215546Sopenharmony_ci
1579bf215546Sopenharmony_ci   /* a valid current context implies an initialized current display */
1580bf215546Sopenharmony_ci   assert(disp->Initialized);
1581bf215546Sopenharmony_ci   ret = disp->Driver->WaitNative(engine);
1582bf215546Sopenharmony_ci
1583bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1584bf215546Sopenharmony_ci}
1585bf215546Sopenharmony_ci
1586bf215546Sopenharmony_ci
1587bf215546Sopenharmony_ciEGLDisplay EGLAPIENTRY
1588bf215546Sopenharmony_cieglGetCurrentDisplay(void)
1589bf215546Sopenharmony_ci{
1590bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1591bf215546Sopenharmony_ci   EGLDisplay ret;
1592bf215546Sopenharmony_ci
1593bf215546Sopenharmony_ci   ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
1594bf215546Sopenharmony_ci
1595bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(NULL, ret);
1596bf215546Sopenharmony_ci}
1597bf215546Sopenharmony_ci
1598bf215546Sopenharmony_ci
1599bf215546Sopenharmony_ciEGLContext EGLAPIENTRY
1600bf215546Sopenharmony_cieglGetCurrentContext(void)
1601bf215546Sopenharmony_ci{
1602bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1603bf215546Sopenharmony_ci   EGLContext ret;
1604bf215546Sopenharmony_ci
1605bf215546Sopenharmony_ci   ret = _eglGetContextHandle(ctx);
1606bf215546Sopenharmony_ci
1607bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(NULL, ret);
1608bf215546Sopenharmony_ci}
1609bf215546Sopenharmony_ci
1610bf215546Sopenharmony_ci
1611bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY
1612bf215546Sopenharmony_cieglGetCurrentSurface(EGLint readdraw)
1613bf215546Sopenharmony_ci{
1614bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1615bf215546Sopenharmony_ci   EGLint err = EGL_SUCCESS;
1616bf215546Sopenharmony_ci   _EGLSurface *surf;
1617bf215546Sopenharmony_ci   EGLSurface ret;
1618bf215546Sopenharmony_ci
1619bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
1620bf215546Sopenharmony_ci
1621bf215546Sopenharmony_ci   if (!ctx)
1622bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
1623bf215546Sopenharmony_ci
1624bf215546Sopenharmony_ci   switch (readdraw) {
1625bf215546Sopenharmony_ci   case EGL_DRAW:
1626bf215546Sopenharmony_ci      surf = ctx->DrawSurface;
1627bf215546Sopenharmony_ci      break;
1628bf215546Sopenharmony_ci   case EGL_READ:
1629bf215546Sopenharmony_ci      surf = ctx->ReadSurface;
1630bf215546Sopenharmony_ci      break;
1631bf215546Sopenharmony_ci   default:
1632bf215546Sopenharmony_ci      surf = NULL;
1633bf215546Sopenharmony_ci      err = EGL_BAD_PARAMETER;
1634bf215546Sopenharmony_ci      break;
1635bf215546Sopenharmony_ci   }
1636bf215546Sopenharmony_ci
1637bf215546Sopenharmony_ci   ret = _eglGetSurfaceHandle(surf);
1638bf215546Sopenharmony_ci
1639bf215546Sopenharmony_ci   RETURN_EGL_ERROR(NULL, err, ret);
1640bf215546Sopenharmony_ci}
1641bf215546Sopenharmony_ci
1642bf215546Sopenharmony_ci
1643bf215546Sopenharmony_ciEGLint EGLAPIENTRY
1644bf215546Sopenharmony_cieglGetError(void)
1645bf215546Sopenharmony_ci{
1646bf215546Sopenharmony_ci   _EGLThreadInfo *t = _eglGetCurrentThread();
1647bf215546Sopenharmony_ci   EGLint e = t->LastError;
1648bf215546Sopenharmony_ci   t->LastError = EGL_SUCCESS;
1649bf215546Sopenharmony_ci   return e;
1650bf215546Sopenharmony_ci}
1651bf215546Sopenharmony_ci
1652bf215546Sopenharmony_ci
1653bf215546Sopenharmony_ci/**
1654bf215546Sopenharmony_ci ** EGL 1.2
1655bf215546Sopenharmony_ci **/
1656bf215546Sopenharmony_ci
1657bf215546Sopenharmony_ci/**
1658bf215546Sopenharmony_ci * Specify the client API to use for subsequent calls including:
1659bf215546Sopenharmony_ci *  eglCreateContext()
1660bf215546Sopenharmony_ci *  eglGetCurrentContext()
1661bf215546Sopenharmony_ci *  eglGetCurrentDisplay()
1662bf215546Sopenharmony_ci *  eglGetCurrentSurface()
1663bf215546Sopenharmony_ci *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1664bf215546Sopenharmony_ci *  eglWaitClient()
1665bf215546Sopenharmony_ci *  eglWaitNative()
1666bf215546Sopenharmony_ci * See section 3.7 "Rendering Context" in the EGL specification for details.
1667bf215546Sopenharmony_ci */
1668bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1669bf215546Sopenharmony_cieglBindAPI(EGLenum api)
1670bf215546Sopenharmony_ci{
1671bf215546Sopenharmony_ci   _EGLThreadInfo *t;
1672bf215546Sopenharmony_ci
1673bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1674bf215546Sopenharmony_ci
1675bf215546Sopenharmony_ci   t = _eglGetCurrentThread();
1676bf215546Sopenharmony_ci
1677bf215546Sopenharmony_ci   if (!_eglIsApiValid(api))
1678bf215546Sopenharmony_ci      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1679bf215546Sopenharmony_ci
1680bf215546Sopenharmony_ci   t->CurrentAPI = api;
1681bf215546Sopenharmony_ci
1682bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1683bf215546Sopenharmony_ci}
1684bf215546Sopenharmony_ci
1685bf215546Sopenharmony_ci
1686bf215546Sopenharmony_ci/**
1687bf215546Sopenharmony_ci * Return the last value set with eglBindAPI().
1688bf215546Sopenharmony_ci */
1689bf215546Sopenharmony_ciEGLenum EGLAPIENTRY
1690bf215546Sopenharmony_cieglQueryAPI(void)
1691bf215546Sopenharmony_ci{
1692bf215546Sopenharmony_ci   _EGLThreadInfo *t = _eglGetCurrentThread();
1693bf215546Sopenharmony_ci   EGLenum ret;
1694bf215546Sopenharmony_ci
1695bf215546Sopenharmony_ci   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1696bf215546Sopenharmony_ci   ret = t->CurrentAPI;
1697bf215546Sopenharmony_ci
1698bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(NULL, ret);
1699bf215546Sopenharmony_ci}
1700bf215546Sopenharmony_ci
1701bf215546Sopenharmony_ci
1702bf215546Sopenharmony_ciEGLSurface EGLAPIENTRY
1703bf215546Sopenharmony_cieglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1704bf215546Sopenharmony_ci                                 EGLClientBuffer buffer, EGLConfig config,
1705bf215546Sopenharmony_ci                                 const EGLint *attrib_list)
1706bf215546Sopenharmony_ci{
1707bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1708bf215546Sopenharmony_ci   _EGLConfig *conf = _eglLookupConfig(config, disp);
1709bf215546Sopenharmony_ci
1710bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
1711bf215546Sopenharmony_ci
1712bf215546Sopenharmony_ci   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE);
1713bf215546Sopenharmony_ci
1714bf215546Sopenharmony_ci   /* OpenVG is not supported */
1715bf215546Sopenharmony_ci   RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
1716bf215546Sopenharmony_ci}
1717bf215546Sopenharmony_ci
1718bf215546Sopenharmony_ci
1719bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1720bf215546Sopenharmony_cieglReleaseThread(void)
1721bf215546Sopenharmony_ci{
1722bf215546Sopenharmony_ci   /* unbind current contexts */
1723bf215546Sopenharmony_ci   _EGLThreadInfo *t = _eglGetCurrentThread();
1724bf215546Sopenharmony_ci   _EGLContext *ctx = t->CurrentContext;
1725bf215546Sopenharmony_ci
1726bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
1727bf215546Sopenharmony_ci
1728bf215546Sopenharmony_ci   if (ctx) {
1729bf215546Sopenharmony_ci      _EGLDisplay *disp = ctx->Resource.Display;
1730bf215546Sopenharmony_ci
1731bf215546Sopenharmony_ci      mtx_lock(&disp->Mutex);
1732bf215546Sopenharmony_ci      (void) disp->Driver->MakeCurrent(disp, NULL, NULL, NULL);
1733bf215546Sopenharmony_ci      mtx_unlock(&disp->Mutex);
1734bf215546Sopenharmony_ci   }
1735bf215546Sopenharmony_ci
1736bf215546Sopenharmony_ci   _eglDestroyCurrentThread();
1737bf215546Sopenharmony_ci
1738bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1739bf215546Sopenharmony_ci}
1740bf215546Sopenharmony_ci
1741bf215546Sopenharmony_ci
1742bf215546Sopenharmony_cistatic EGLImage
1743bf215546Sopenharmony_ci_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
1744bf215546Sopenharmony_ci                      EGLClientBuffer buffer, const EGLint *attr_list)
1745bf215546Sopenharmony_ci{
1746bf215546Sopenharmony_ci   _EGLContext *context = _eglLookupContext(ctx, disp);
1747bf215546Sopenharmony_ci   _EGLImage *img;
1748bf215546Sopenharmony_ci   EGLImage ret;
1749bf215546Sopenharmony_ci
1750bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR);
1751bf215546Sopenharmony_ci   if (!disp->Extensions.KHR_image_base)
1752bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1753bf215546Sopenharmony_ci   if (!context && ctx != EGL_NO_CONTEXT)
1754bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1755bf215546Sopenharmony_ci   /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1756bf215546Sopenharmony_ci    *  <ctx> must be EGL_NO_CONTEXT..."
1757bf215546Sopenharmony_ci    */
1758bf215546Sopenharmony_ci   if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1759bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1760bf215546Sopenharmony_ci
1761bf215546Sopenharmony_ci   img = disp->Driver->CreateImageKHR(disp, context, target, buffer, attr_list);
1762bf215546Sopenharmony_ci   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1763bf215546Sopenharmony_ci
1764bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1765bf215546Sopenharmony_ci}
1766bf215546Sopenharmony_ci
1767bf215546Sopenharmony_cistatic EGLImage EGLAPIENTRY
1768bf215546Sopenharmony_cieglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1769bf215546Sopenharmony_ci                  EGLClientBuffer buffer, const EGLint *attr_list)
1770bf215546Sopenharmony_ci{
1771bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1772bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
1773bf215546Sopenharmony_ci   return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
1774bf215546Sopenharmony_ci}
1775bf215546Sopenharmony_ci
1776bf215546Sopenharmony_ci
1777bf215546Sopenharmony_ciEGLImage EGLAPIENTRY
1778bf215546Sopenharmony_cieglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1779bf215546Sopenharmony_ci               EGLClientBuffer buffer, const EGLAttrib *attr_list)
1780bf215546Sopenharmony_ci{
1781bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1782bf215546Sopenharmony_ci   EGLImage image;
1783bf215546Sopenharmony_ci   EGLint *int_attribs;
1784bf215546Sopenharmony_ci
1785bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
1786bf215546Sopenharmony_ci
1787bf215546Sopenharmony_ci   int_attribs = _eglConvertAttribsToInt(attr_list);
1788bf215546Sopenharmony_ci   if (attr_list && !int_attribs)
1789bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
1790bf215546Sopenharmony_ci
1791bf215546Sopenharmony_ci   image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
1792bf215546Sopenharmony_ci   free(int_attribs);
1793bf215546Sopenharmony_ci   return image;
1794bf215546Sopenharmony_ci}
1795bf215546Sopenharmony_ci
1796bf215546Sopenharmony_ci
1797bf215546Sopenharmony_cistatic EGLBoolean
1798bf215546Sopenharmony_ci_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
1799bf215546Sopenharmony_ci{
1800bf215546Sopenharmony_ci   EGLBoolean ret;
1801bf215546Sopenharmony_ci
1802bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
1803bf215546Sopenharmony_ci   if (!disp->Extensions.KHR_image_base)
1804bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_FALSE);
1805bf215546Sopenharmony_ci   if (!img)
1806bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1807bf215546Sopenharmony_ci
1808bf215546Sopenharmony_ci   _eglUnlinkImage(img);
1809bf215546Sopenharmony_ci   ret = disp->Driver->DestroyImageKHR(disp, img);
1810bf215546Sopenharmony_ci
1811bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1812bf215546Sopenharmony_ci}
1813bf215546Sopenharmony_ci
1814bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1815bf215546Sopenharmony_cieglDestroyImage(EGLDisplay dpy, EGLImage image)
1816bf215546Sopenharmony_ci{
1817bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1818bf215546Sopenharmony_ci   _EGLImage *img = _eglLookupImage(image, disp);
1819bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1820bf215546Sopenharmony_ci   return _eglDestroyImageCommon(disp, img);
1821bf215546Sopenharmony_ci}
1822bf215546Sopenharmony_ci
1823bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
1824bf215546Sopenharmony_cieglDestroyImageKHR(EGLDisplay dpy, EGLImage image)
1825bf215546Sopenharmony_ci{
1826bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1827bf215546Sopenharmony_ci   _EGLImage *img = _eglLookupImage(image, disp);
1828bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
1829bf215546Sopenharmony_ci   return _eglDestroyImageCommon(disp, img);
1830bf215546Sopenharmony_ci}
1831bf215546Sopenharmony_ci
1832bf215546Sopenharmony_ci
1833bf215546Sopenharmony_cistatic EGLSync
1834bf215546Sopenharmony_ci_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
1835bf215546Sopenharmony_ci               EGLBoolean orig_is_EGLAttrib,
1836bf215546Sopenharmony_ci               EGLenum invalid_type_error)
1837bf215546Sopenharmony_ci{
1838bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
1839bf215546Sopenharmony_ci   _EGLSync *sync;
1840bf215546Sopenharmony_ci   EGLSync ret;
1841bf215546Sopenharmony_ci
1842bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR);
1843bf215546Sopenharmony_ci
1844bf215546Sopenharmony_ci   if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
1845bf215546Sopenharmony_ci      /* There exist two EGLAttrib variants of eglCreateSync*:
1846bf215546Sopenharmony_ci       * eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
1847bf215546Sopenharmony_ci       * which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
1848bf215546Sopenharmony_ci       * support as a proxy for EGL 1.5 support, even though that's not
1849bf215546Sopenharmony_ci       * entirely correct (though _eglComputeVersion does the same).
1850bf215546Sopenharmony_ci       *
1851bf215546Sopenharmony_ci       * The EGL spec provides no guidance on how to handle unsupported
1852bf215546Sopenharmony_ci       * functions. EGL_BAD_MATCH seems reasonable.
1853bf215546Sopenharmony_ci       */
1854bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1855bf215546Sopenharmony_ci   }
1856bf215546Sopenharmony_ci
1857bf215546Sopenharmony_ci   /* If type is EGL_SYNC_FENCE and no context is current for the bound API
1858bf215546Sopenharmony_ci    * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH
1859bf215546Sopenharmony_ci    * error is generated.
1860bf215546Sopenharmony_ci    */
1861bf215546Sopenharmony_ci   if (!ctx &&
1862bf215546Sopenharmony_ci       (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
1863bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1864bf215546Sopenharmony_ci
1865bf215546Sopenharmony_ci   /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
1866bf215546Sopenharmony_ci   if (ctx && (ctx->Resource.Display != disp ||
1867bf215546Sopenharmony_ci               (ctx->ClientAPI != EGL_OPENGL_ES_API &&
1868bf215546Sopenharmony_ci                ctx->ClientAPI != EGL_OPENGL_API)))
1869bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
1870bf215546Sopenharmony_ci
1871bf215546Sopenharmony_ci   switch (type) {
1872bf215546Sopenharmony_ci   case EGL_SYNC_FENCE_KHR:
1873bf215546Sopenharmony_ci      if (!disp->Extensions.KHR_fence_sync)
1874bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1875bf215546Sopenharmony_ci      break;
1876bf215546Sopenharmony_ci   case EGL_SYNC_REUSABLE_KHR:
1877bf215546Sopenharmony_ci      if (!disp->Extensions.KHR_reusable_sync)
1878bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1879bf215546Sopenharmony_ci      break;
1880bf215546Sopenharmony_ci   case EGL_SYNC_CL_EVENT_KHR:
1881bf215546Sopenharmony_ci      if (!disp->Extensions.KHR_cl_event2)
1882bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1883bf215546Sopenharmony_ci      break;
1884bf215546Sopenharmony_ci   case EGL_SYNC_NATIVE_FENCE_ANDROID:
1885bf215546Sopenharmony_ci      if (!disp->Extensions.ANDROID_native_fence_sync)
1886bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1887bf215546Sopenharmony_ci      break;
1888bf215546Sopenharmony_ci   default:
1889bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
1890bf215546Sopenharmony_ci   }
1891bf215546Sopenharmony_ci
1892bf215546Sopenharmony_ci   sync = disp->Driver->CreateSyncKHR(disp, type, attrib_list);
1893bf215546Sopenharmony_ci   ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
1894bf215546Sopenharmony_ci
1895bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1896bf215546Sopenharmony_ci}
1897bf215546Sopenharmony_ci
1898bf215546Sopenharmony_ci
1899bf215546Sopenharmony_cistatic EGLSync EGLAPIENTRY
1900bf215546Sopenharmony_cieglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
1901bf215546Sopenharmony_ci{
1902bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1903bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
1904bf215546Sopenharmony_ci
1905bf215546Sopenharmony_ci   EGLSync sync;
1906bf215546Sopenharmony_ci   EGLAttrib *attrib_list;
1907bf215546Sopenharmony_ci   EGLint err;
1908bf215546Sopenharmony_ci
1909bf215546Sopenharmony_ci   if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
1910bf215546Sopenharmony_ci      attrib_list = (EGLAttrib *) int_list;
1911bf215546Sopenharmony_ci   } else {
1912bf215546Sopenharmony_ci      err = _eglConvertIntsToAttribs(int_list, &attrib_list);
1913bf215546Sopenharmony_ci      if (err != EGL_SUCCESS)
1914bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
1915bf215546Sopenharmony_ci   }
1916bf215546Sopenharmony_ci
1917bf215546Sopenharmony_ci   sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
1918bf215546Sopenharmony_ci                         EGL_BAD_ATTRIBUTE);
1919bf215546Sopenharmony_ci
1920bf215546Sopenharmony_ci   if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
1921bf215546Sopenharmony_ci      free(attrib_list);
1922bf215546Sopenharmony_ci
1923bf215546Sopenharmony_ci   /* Don't double-unlock the display. _eglCreateSync already unlocked it. */
1924bf215546Sopenharmony_ci   return sync;
1925bf215546Sopenharmony_ci}
1926bf215546Sopenharmony_ci
1927bf215546Sopenharmony_ci
1928bf215546Sopenharmony_cistatic EGLSync EGLAPIENTRY
1929bf215546Sopenharmony_cieglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1930bf215546Sopenharmony_ci{
1931bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1932bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
1933bf215546Sopenharmony_ci   return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
1934bf215546Sopenharmony_ci                         EGL_BAD_ATTRIBUTE);
1935bf215546Sopenharmony_ci}
1936bf215546Sopenharmony_ci
1937bf215546Sopenharmony_ci
1938bf215546Sopenharmony_ciEGLSync EGLAPIENTRY
1939bf215546Sopenharmony_cieglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1940bf215546Sopenharmony_ci{
1941bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1942bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
1943bf215546Sopenharmony_ci   return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
1944bf215546Sopenharmony_ci                         EGL_BAD_PARAMETER);
1945bf215546Sopenharmony_ci}
1946bf215546Sopenharmony_ci
1947bf215546Sopenharmony_ci
1948bf215546Sopenharmony_cistatic EGLBoolean
1949bf215546Sopenharmony_ci_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
1950bf215546Sopenharmony_ci{
1951bf215546Sopenharmony_ci   EGLBoolean ret;
1952bf215546Sopenharmony_ci
1953bf215546Sopenharmony_ci   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
1954bf215546Sopenharmony_ci   assert(disp->Extensions.KHR_reusable_sync ||
1955bf215546Sopenharmony_ci          disp->Extensions.KHR_fence_sync ||
1956bf215546Sopenharmony_ci          disp->Extensions.ANDROID_native_fence_sync);
1957bf215546Sopenharmony_ci
1958bf215546Sopenharmony_ci   _eglUnlinkSync(s);
1959bf215546Sopenharmony_ci   ret = disp->Driver->DestroySyncKHR(disp, s);
1960bf215546Sopenharmony_ci
1961bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
1962bf215546Sopenharmony_ci}
1963bf215546Sopenharmony_ci
1964bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
1965bf215546Sopenharmony_cieglDestroySync(EGLDisplay dpy, EGLSync sync)
1966bf215546Sopenharmony_ci{
1967bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1968bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
1969bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1970bf215546Sopenharmony_ci   return _eglDestroySync(disp, s);
1971bf215546Sopenharmony_ci}
1972bf215546Sopenharmony_ci
1973bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
1974bf215546Sopenharmony_cieglDestroySyncKHR(EGLDisplay dpy, EGLSync sync)
1975bf215546Sopenharmony_ci{
1976bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
1977bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
1978bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
1979bf215546Sopenharmony_ci   return _eglDestroySync(disp, s);
1980bf215546Sopenharmony_ci}
1981bf215546Sopenharmony_ci
1982bf215546Sopenharmony_ci
1983bf215546Sopenharmony_cistatic EGLint
1984bf215546Sopenharmony_ci_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
1985bf215546Sopenharmony_ci                         _EGLSync *s, EGLint flags, EGLTime timeout)
1986bf215546Sopenharmony_ci{
1987bf215546Sopenharmony_ci   EGLint ret;
1988bf215546Sopenharmony_ci
1989bf215546Sopenharmony_ci   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
1990bf215546Sopenharmony_ci   assert(disp->Extensions.KHR_reusable_sync ||
1991bf215546Sopenharmony_ci          disp->Extensions.KHR_fence_sync ||
1992bf215546Sopenharmony_ci          disp->Extensions.ANDROID_native_fence_sync);
1993bf215546Sopenharmony_ci
1994bf215546Sopenharmony_ci   if (s->SyncStatus == EGL_SIGNALED_KHR)
1995bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
1996bf215546Sopenharmony_ci
1997bf215546Sopenharmony_ci   /* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
1998bf215546Sopenharmony_ci    * unlocked here to allow other threads also to be able to
1999bf215546Sopenharmony_ci    * go into waiting state.
2000bf215546Sopenharmony_ci    */
2001bf215546Sopenharmony_ci
2002bf215546Sopenharmony_ci   if (s->Type == EGL_SYNC_REUSABLE_KHR)
2003bf215546Sopenharmony_ci      _eglUnlockDisplay(dpy);
2004bf215546Sopenharmony_ci
2005bf215546Sopenharmony_ci   ret = disp->Driver->ClientWaitSyncKHR(disp, s, flags, timeout);
2006bf215546Sopenharmony_ci
2007bf215546Sopenharmony_ci   /*
2008bf215546Sopenharmony_ci    * 'disp' is already unlocked for reusable sync type,
2009bf215546Sopenharmony_ci    * so passing 'NULL' to bypass unlocking display.
2010bf215546Sopenharmony_ci    */
2011bf215546Sopenharmony_ci   if (s->Type == EGL_SYNC_REUSABLE_KHR)
2012bf215546Sopenharmony_ci      RETURN_EGL_EVAL(NULL, ret);
2013bf215546Sopenharmony_ci   else
2014bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, ret);
2015bf215546Sopenharmony_ci}
2016bf215546Sopenharmony_ci
2017bf215546Sopenharmony_ciEGLint EGLAPIENTRY
2018bf215546Sopenharmony_cieglClientWaitSync(EGLDisplay dpy, EGLSync sync,
2019bf215546Sopenharmony_ci                  EGLint flags, EGLTime timeout)
2020bf215546Sopenharmony_ci{
2021bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2022bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2023bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2024bf215546Sopenharmony_ci   return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
2025bf215546Sopenharmony_ci}
2026bf215546Sopenharmony_ci
2027bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY
2028bf215546Sopenharmony_cieglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync,
2029bf215546Sopenharmony_ci                     EGLint flags, EGLTime timeout)
2030bf215546Sopenharmony_ci{
2031bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2032bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2033bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2034bf215546Sopenharmony_ci   return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
2035bf215546Sopenharmony_ci}
2036bf215546Sopenharmony_ci
2037bf215546Sopenharmony_ci
2038bf215546Sopenharmony_cistatic EGLint
2039bf215546Sopenharmony_ci_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
2040bf215546Sopenharmony_ci{
2041bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
2042bf215546Sopenharmony_ci   EGLint ret;
2043bf215546Sopenharmony_ci
2044bf215546Sopenharmony_ci   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
2045bf215546Sopenharmony_ci   assert(disp->Extensions.KHR_wait_sync);
2046bf215546Sopenharmony_ci
2047bf215546Sopenharmony_ci   /* return an error if the client API doesn't support GL_[OES|MESA]_EGL_sync. */
2048bf215546Sopenharmony_ci   if (ctx == EGL_NO_CONTEXT ||
2049bf215546Sopenharmony_ci         (ctx->ClientAPI != EGL_OPENGL_ES_API &&
2050bf215546Sopenharmony_ci          ctx->ClientAPI != EGL_OPENGL_API))
2051bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
2052bf215546Sopenharmony_ci
2053bf215546Sopenharmony_ci   /* the API doesn't allow any flags yet */
2054bf215546Sopenharmony_ci   if (flags != 0)
2055bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2056bf215546Sopenharmony_ci
2057bf215546Sopenharmony_ci   ret = disp->Driver->WaitSyncKHR(disp, s);
2058bf215546Sopenharmony_ci
2059bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2060bf215546Sopenharmony_ci}
2061bf215546Sopenharmony_ci
2062bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY
2063bf215546Sopenharmony_cieglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
2064bf215546Sopenharmony_ci{
2065bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2066bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2067bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2068bf215546Sopenharmony_ci   return _eglWaitSyncCommon(disp, s, flags);
2069bf215546Sopenharmony_ci}
2070bf215546Sopenharmony_ci
2071bf215546Sopenharmony_ci
2072bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
2073bf215546Sopenharmony_cieglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
2074bf215546Sopenharmony_ci{
2075bf215546Sopenharmony_ci   /* The KHR version returns EGLint, while the core version returns
2076bf215546Sopenharmony_ci    * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
2077bf215546Sopenharmony_ci    * EGL_TRUE.
2078bf215546Sopenharmony_ci    */
2079bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2080bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2081bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2082bf215546Sopenharmony_ci   return _eglWaitSyncCommon(disp, s, flags);
2083bf215546Sopenharmony_ci}
2084bf215546Sopenharmony_ci
2085bf215546Sopenharmony_ci
2086bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2087bf215546Sopenharmony_cieglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
2088bf215546Sopenharmony_ci{
2089bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2090bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2091bf215546Sopenharmony_ci   EGLBoolean ret;
2092bf215546Sopenharmony_ci
2093bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2094bf215546Sopenharmony_ci
2095bf215546Sopenharmony_ci   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
2096bf215546Sopenharmony_ci   assert(disp->Extensions.KHR_reusable_sync);
2097bf215546Sopenharmony_ci   ret = disp->Driver->SignalSyncKHR(disp, s, mode);
2098bf215546Sopenharmony_ci
2099bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2100bf215546Sopenharmony_ci}
2101bf215546Sopenharmony_ci
2102bf215546Sopenharmony_ci
2103bf215546Sopenharmony_cistatic EGLBoolean
2104bf215546Sopenharmony_ci_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
2105bf215546Sopenharmony_ci{
2106bf215546Sopenharmony_ci   EGLBoolean ret;
2107bf215546Sopenharmony_ci
2108bf215546Sopenharmony_ci   _EGL_CHECK_SYNC(disp, s, EGL_FALSE);
2109bf215546Sopenharmony_ci   assert(disp->Extensions.KHR_reusable_sync ||
2110bf215546Sopenharmony_ci          disp->Extensions.KHR_fence_sync ||
2111bf215546Sopenharmony_ci          disp->Extensions.ANDROID_native_fence_sync);
2112bf215546Sopenharmony_ci
2113bf215546Sopenharmony_ci   ret = _eglGetSyncAttrib(disp, s, attribute, value);
2114bf215546Sopenharmony_ci
2115bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2116bf215546Sopenharmony_ci}
2117bf215546Sopenharmony_ci
2118bf215546Sopenharmony_ciEGLBoolean EGLAPIENTRY
2119bf215546Sopenharmony_cieglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
2120bf215546Sopenharmony_ci{
2121bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2122bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2123bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2124bf215546Sopenharmony_ci
2125bf215546Sopenharmony_ci   if (!value)
2126bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2127bf215546Sopenharmony_ci
2128bf215546Sopenharmony_ci   return _eglGetSyncAttribCommon(disp, s, attribute, value);
2129bf215546Sopenharmony_ci}
2130bf215546Sopenharmony_ci
2131bf215546Sopenharmony_ci
2132bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2133bf215546Sopenharmony_cieglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
2134bf215546Sopenharmony_ci{
2135bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2136bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2137bf215546Sopenharmony_ci   EGLAttrib attrib;
2138bf215546Sopenharmony_ci   EGLBoolean result;
2139bf215546Sopenharmony_ci
2140bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2141bf215546Sopenharmony_ci
2142bf215546Sopenharmony_ci   if (!value)
2143bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2144bf215546Sopenharmony_ci
2145bf215546Sopenharmony_ci   attrib = *value;
2146bf215546Sopenharmony_ci   result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
2147bf215546Sopenharmony_ci
2148bf215546Sopenharmony_ci   /* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
2149bf215546Sopenharmony_ci    *
2150bf215546Sopenharmony_ci    *    If any error occurs, <*value> is not modified.
2151bf215546Sopenharmony_ci    */
2152bf215546Sopenharmony_ci   if (result == EGL_FALSE)
2153bf215546Sopenharmony_ci      return result;
2154bf215546Sopenharmony_ci
2155bf215546Sopenharmony_ci   *value = attrib;
2156bf215546Sopenharmony_ci   return result;
2157bf215546Sopenharmony_ci}
2158bf215546Sopenharmony_ci
2159bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY
2160bf215546Sopenharmony_cieglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
2161bf215546Sopenharmony_ci{
2162bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2163bf215546Sopenharmony_ci   _EGLSync *s = _eglLookupSync(sync, disp);
2164bf215546Sopenharmony_ci   EGLint ret;
2165bf215546Sopenharmony_ci
2166bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
2167bf215546Sopenharmony_ci
2168bf215546Sopenharmony_ci   /* the spec doesn't seem to specify what happens if the fence
2169bf215546Sopenharmony_ci    * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems
2170bf215546Sopenharmony_ci    * sensible:
2171bf215546Sopenharmony_ci    */
2172bf215546Sopenharmony_ci   if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)))
2173bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID);
2174bf215546Sopenharmony_ci
2175bf215546Sopenharmony_ci   _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID);
2176bf215546Sopenharmony_ci   assert(disp->Extensions.ANDROID_native_fence_sync);
2177bf215546Sopenharmony_ci   ret = disp->Driver->DupNativeFenceFDANDROID(disp, s);
2178bf215546Sopenharmony_ci
2179bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(disp, ret);
2180bf215546Sopenharmony_ci}
2181bf215546Sopenharmony_ci
2182bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2183bf215546Sopenharmony_cieglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
2184bf215546Sopenharmony_ci                        EGLint numRects, const EGLint *rects)
2185bf215546Sopenharmony_ci{
2186bf215546Sopenharmony_ci   _EGLContext *ctx = _eglGetCurrentContext();
2187bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2188bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
2189bf215546Sopenharmony_ci   EGLBoolean ret;
2190bf215546Sopenharmony_ci
2191bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2192bf215546Sopenharmony_ci
2193bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
2194bf215546Sopenharmony_ci
2195bf215546Sopenharmony_ci   if (!disp->Extensions.NOK_swap_region)
2196bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_FALSE);
2197bf215546Sopenharmony_ci
2198bf215546Sopenharmony_ci   /* surface must be bound to current context in EGL 1.4 */
2199bf215546Sopenharmony_ci   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
2200bf215546Sopenharmony_ci       surf != ctx->DrawSurface)
2201bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
2202bf215546Sopenharmony_ci
2203bf215546Sopenharmony_ci   ret = disp->Driver->SwapBuffersRegionNOK(disp, surf, numRects, rects);
2204bf215546Sopenharmony_ci
2205bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2206bf215546Sopenharmony_ci}
2207bf215546Sopenharmony_ci
2208bf215546Sopenharmony_ci
2209bf215546Sopenharmony_cistatic EGLImage EGLAPIENTRY
2210bf215546Sopenharmony_cieglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
2211bf215546Sopenharmony_ci{
2212bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2213bf215546Sopenharmony_ci   _EGLImage *img;
2214bf215546Sopenharmony_ci   EGLImage ret;
2215bf215546Sopenharmony_ci
2216bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
2217bf215546Sopenharmony_ci
2218bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR);
2219bf215546Sopenharmony_ci   if (!disp->Extensions.MESA_drm_image)
2220bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
2221bf215546Sopenharmony_ci
2222bf215546Sopenharmony_ci   img = disp->Driver->CreateDRMImageMESA(disp, attr_list);
2223bf215546Sopenharmony_ci   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
2224bf215546Sopenharmony_ci
2225bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2226bf215546Sopenharmony_ci}
2227bf215546Sopenharmony_ci
2228bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2229bf215546Sopenharmony_cieglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
2230bf215546Sopenharmony_ci                      EGLint *name, EGLint *handle, EGLint *stride)
2231bf215546Sopenharmony_ci{
2232bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2233bf215546Sopenharmony_ci   _EGLImage *img = _eglLookupImage(image, disp);
2234bf215546Sopenharmony_ci   EGLBoolean ret;
2235bf215546Sopenharmony_ci
2236bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2237bf215546Sopenharmony_ci
2238bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2239bf215546Sopenharmony_ci   assert(disp->Extensions.MESA_drm_image);
2240bf215546Sopenharmony_ci
2241bf215546Sopenharmony_ci   if (!img)
2242bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2243bf215546Sopenharmony_ci
2244bf215546Sopenharmony_ci   ret = disp->Driver->ExportDRMImageMESA(disp, img, name, handle, stride);
2245bf215546Sopenharmony_ci
2246bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2247bf215546Sopenharmony_ci}
2248bf215546Sopenharmony_ci
2249bf215546Sopenharmony_ci
2250bf215546Sopenharmony_cistruct wl_display;
2251bf215546Sopenharmony_ci
2252bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2253bf215546Sopenharmony_cieglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2254bf215546Sopenharmony_ci{
2255bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2256bf215546Sopenharmony_ci   EGLBoolean ret;
2257bf215546Sopenharmony_ci
2258bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2259bf215546Sopenharmony_ci
2260bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2261bf215546Sopenharmony_ci   assert(disp->Extensions.WL_bind_wayland_display);
2262bf215546Sopenharmony_ci
2263bf215546Sopenharmony_ci   if (!display)
2264bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2265bf215546Sopenharmony_ci
2266bf215546Sopenharmony_ci   ret = disp->Driver->BindWaylandDisplayWL(disp, display);
2267bf215546Sopenharmony_ci
2268bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2269bf215546Sopenharmony_ci}
2270bf215546Sopenharmony_ci
2271bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2272bf215546Sopenharmony_cieglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
2273bf215546Sopenharmony_ci{
2274bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2275bf215546Sopenharmony_ci   EGLBoolean ret;
2276bf215546Sopenharmony_ci
2277bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2278bf215546Sopenharmony_ci
2279bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2280bf215546Sopenharmony_ci   assert(disp->Extensions.WL_bind_wayland_display);
2281bf215546Sopenharmony_ci
2282bf215546Sopenharmony_ci   if (!display)
2283bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2284bf215546Sopenharmony_ci
2285bf215546Sopenharmony_ci   ret = disp->Driver->UnbindWaylandDisplayWL(disp, display);
2286bf215546Sopenharmony_ci
2287bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2288bf215546Sopenharmony_ci}
2289bf215546Sopenharmony_ci
2290bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2291bf215546Sopenharmony_cieglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
2292bf215546Sopenharmony_ci                        EGLint attribute, EGLint *value)
2293bf215546Sopenharmony_ci{
2294bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2295bf215546Sopenharmony_ci   EGLBoolean ret;
2296bf215546Sopenharmony_ci
2297bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
2298bf215546Sopenharmony_ci
2299bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2300bf215546Sopenharmony_ci   assert(disp->Extensions.WL_bind_wayland_display);
2301bf215546Sopenharmony_ci
2302bf215546Sopenharmony_ci   if (!buffer)
2303bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2304bf215546Sopenharmony_ci
2305bf215546Sopenharmony_ci   ret = disp->Driver->QueryWaylandBufferWL(disp, buffer, attribute, value);
2306bf215546Sopenharmony_ci
2307bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2308bf215546Sopenharmony_ci}
2309bf215546Sopenharmony_ci
2310bf215546Sopenharmony_ci
2311bf215546Sopenharmony_cistatic struct wl_buffer * EGLAPIENTRY
2312bf215546Sopenharmony_cieglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
2313bf215546Sopenharmony_ci{
2314bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2315bf215546Sopenharmony_ci   _EGLImage *img;
2316bf215546Sopenharmony_ci   struct wl_buffer *ret;
2317bf215546Sopenharmony_ci
2318bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
2319bf215546Sopenharmony_ci
2320bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, NULL);
2321bf215546Sopenharmony_ci   if (!disp->Extensions.WL_create_wayland_buffer_from_image)
2322bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, NULL);
2323bf215546Sopenharmony_ci
2324bf215546Sopenharmony_ci   img = _eglLookupImage(image, disp);
2325bf215546Sopenharmony_ci
2326bf215546Sopenharmony_ci   if (!img)
2327bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
2328bf215546Sopenharmony_ci
2329bf215546Sopenharmony_ci   ret = disp->Driver->CreateWaylandBufferFromImageWL(disp, img);
2330bf215546Sopenharmony_ci
2331bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2332bf215546Sopenharmony_ci}
2333bf215546Sopenharmony_ci
2334bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2335bf215546Sopenharmony_cieglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
2336bf215546Sopenharmony_ci                   EGLint x, EGLint y, EGLint width, EGLint height)
2337bf215546Sopenharmony_ci{
2338bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2339bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
2340bf215546Sopenharmony_ci   EGLBoolean ret;
2341bf215546Sopenharmony_ci
2342bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2343bf215546Sopenharmony_ci
2344bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
2345bf215546Sopenharmony_ci
2346bf215546Sopenharmony_ci   if (!disp->Extensions.NV_post_sub_buffer)
2347bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_FALSE);
2348bf215546Sopenharmony_ci
2349bf215546Sopenharmony_ci   ret = disp->Driver->PostSubBufferNV(disp, surf, x, y, width, height);
2350bf215546Sopenharmony_ci
2351bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2352bf215546Sopenharmony_ci}
2353bf215546Sopenharmony_ci
2354bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2355bf215546Sopenharmony_cieglGetSyncValuesCHROMIUM(EGLDisplay dpy, EGLSurface surface,
2356bf215546Sopenharmony_ci                         EGLuint64KHR *ust, EGLuint64KHR *msc,
2357bf215546Sopenharmony_ci                         EGLuint64KHR *sbc)
2358bf215546Sopenharmony_ci{
2359bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2360bf215546Sopenharmony_ci   _EGLSurface *surf = _eglLookupSurface(surface, disp);
2361bf215546Sopenharmony_ci   EGLBoolean ret;
2362bf215546Sopenharmony_ci
2363bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
2364bf215546Sopenharmony_ci
2365bf215546Sopenharmony_ci   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE);
2366bf215546Sopenharmony_ci   if (!disp->Extensions.CHROMIUM_sync_control)
2367bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_FALSE);
2368bf215546Sopenharmony_ci
2369bf215546Sopenharmony_ci   if (!ust || !msc || !sbc)
2370bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2371bf215546Sopenharmony_ci
2372bf215546Sopenharmony_ci   ret = disp->Driver->GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
2373bf215546Sopenharmony_ci
2374bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2375bf215546Sopenharmony_ci}
2376bf215546Sopenharmony_ci
2377bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2378bf215546Sopenharmony_cieglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
2379bf215546Sopenharmony_ci                              EGLint *fourcc, EGLint *nplanes,
2380bf215546Sopenharmony_ci                              EGLuint64KHR *modifiers)
2381bf215546Sopenharmony_ci{
2382bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2383bf215546Sopenharmony_ci   _EGLImage *img = _eglLookupImage(image, disp);
2384bf215546Sopenharmony_ci   EGLBoolean ret;
2385bf215546Sopenharmony_ci
2386bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2387bf215546Sopenharmony_ci
2388bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2389bf215546Sopenharmony_ci   assert(disp->Extensions.MESA_image_dma_buf_export);
2390bf215546Sopenharmony_ci
2391bf215546Sopenharmony_ci   if (!img)
2392bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2393bf215546Sopenharmony_ci
2394bf215546Sopenharmony_ci   ret = disp->Driver->ExportDMABUFImageQueryMESA(disp, img, fourcc, nplanes, modifiers);
2395bf215546Sopenharmony_ci
2396bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2397bf215546Sopenharmony_ci}
2398bf215546Sopenharmony_ci
2399bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2400bf215546Sopenharmony_cieglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
2401bf215546Sopenharmony_ci                         int *fds, EGLint *strides, EGLint *offsets)
2402bf215546Sopenharmony_ci{
2403bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2404bf215546Sopenharmony_ci   _EGLImage *img = _eglLookupImage(image, disp);
2405bf215546Sopenharmony_ci   EGLBoolean ret;
2406bf215546Sopenharmony_ci
2407bf215546Sopenharmony_ci   _EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
2408bf215546Sopenharmony_ci
2409bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2410bf215546Sopenharmony_ci   assert(disp->Extensions.MESA_image_dma_buf_export);
2411bf215546Sopenharmony_ci
2412bf215546Sopenharmony_ci   if (!img)
2413bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
2414bf215546Sopenharmony_ci
2415bf215546Sopenharmony_ci   ret = disp->Driver->ExportDMABUFImageMESA(disp, img, fds, strides, offsets);
2416bf215546Sopenharmony_ci
2417bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2418bf215546Sopenharmony_ci}
2419bf215546Sopenharmony_ci
2420bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY
2421bf215546Sopenharmony_cieglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
2422bf215546Sopenharmony_ci                  EGLLabelKHR label)
2423bf215546Sopenharmony_ci{
2424bf215546Sopenharmony_ci   _EGLDisplay *disp = NULL;
2425bf215546Sopenharmony_ci   _EGLResourceType type;
2426bf215546Sopenharmony_ci
2427bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2428bf215546Sopenharmony_ci
2429bf215546Sopenharmony_ci   if (objectType == EGL_OBJECT_THREAD_KHR) {
2430bf215546Sopenharmony_ci      _EGLThreadInfo *t = _eglGetCurrentThread();
2431bf215546Sopenharmony_ci
2432bf215546Sopenharmony_ci     t->Label = label;
2433bf215546Sopenharmony_ci     return EGL_SUCCESS;
2434bf215546Sopenharmony_ci   }
2435bf215546Sopenharmony_ci
2436bf215546Sopenharmony_ci   disp = _eglLockDisplay(dpy);
2437bf215546Sopenharmony_ci   if (disp == NULL)
2438bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
2439bf215546Sopenharmony_ci
2440bf215546Sopenharmony_ci   if (objectType == EGL_OBJECT_DISPLAY_KHR) {
2441bf215546Sopenharmony_ci      if (dpy != (EGLDisplay) object)
2442bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2443bf215546Sopenharmony_ci
2444bf215546Sopenharmony_ci      disp->Label = label;
2445bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2446bf215546Sopenharmony_ci   }
2447bf215546Sopenharmony_ci
2448bf215546Sopenharmony_ci   switch (objectType) {
2449bf215546Sopenharmony_ci      case EGL_OBJECT_CONTEXT_KHR:
2450bf215546Sopenharmony_ci         type = _EGL_RESOURCE_CONTEXT;
2451bf215546Sopenharmony_ci         break;
2452bf215546Sopenharmony_ci      case EGL_OBJECT_SURFACE_KHR:
2453bf215546Sopenharmony_ci         type = _EGL_RESOURCE_SURFACE;
2454bf215546Sopenharmony_ci         break;
2455bf215546Sopenharmony_ci      case EGL_OBJECT_IMAGE_KHR:
2456bf215546Sopenharmony_ci         type = _EGL_RESOURCE_IMAGE;
2457bf215546Sopenharmony_ci         break;
2458bf215546Sopenharmony_ci      case EGL_OBJECT_SYNC_KHR:
2459bf215546Sopenharmony_ci         type = _EGL_RESOURCE_SYNC;
2460bf215546Sopenharmony_ci         break;
2461bf215546Sopenharmony_ci      case EGL_OBJECT_STREAM_KHR:
2462bf215546Sopenharmony_ci      default:
2463bf215546Sopenharmony_ci         RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2464bf215546Sopenharmony_ci   }
2465bf215546Sopenharmony_ci
2466bf215546Sopenharmony_ci   if (_eglCheckResource(object, type, disp)) {
2467bf215546Sopenharmony_ci      _EGLResource *res = (_EGLResource *) object;
2468bf215546Sopenharmony_ci
2469bf215546Sopenharmony_ci      res->Label = label;
2470bf215546Sopenharmony_ci      RETURN_EGL_EVAL(disp, EGL_SUCCESS);
2471bf215546Sopenharmony_ci   }
2472bf215546Sopenharmony_ci
2473bf215546Sopenharmony_ci   RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
2474bf215546Sopenharmony_ci}
2475bf215546Sopenharmony_ci
2476bf215546Sopenharmony_cistatic EGLint EGLAPIENTRY
2477bf215546Sopenharmony_cieglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
2478bf215546Sopenharmony_ci                          const EGLAttrib *attrib_list)
2479bf215546Sopenharmony_ci{
2480bf215546Sopenharmony_ci   unsigned int newEnabled;
2481bf215546Sopenharmony_ci
2482bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2483bf215546Sopenharmony_ci
2484bf215546Sopenharmony_ci   mtx_lock(_eglGlobal.Mutex);
2485bf215546Sopenharmony_ci
2486bf215546Sopenharmony_ci   newEnabled = _eglGlobal.debugTypesEnabled;
2487bf215546Sopenharmony_ci   if (attrib_list != NULL) {
2488bf215546Sopenharmony_ci      int i;
2489bf215546Sopenharmony_ci
2490bf215546Sopenharmony_ci      for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
2491bf215546Sopenharmony_ci         switch (attrib_list[i]) {
2492bf215546Sopenharmony_ci         case EGL_DEBUG_MSG_CRITICAL_KHR:
2493bf215546Sopenharmony_ci         case EGL_DEBUG_MSG_ERROR_KHR:
2494bf215546Sopenharmony_ci         case EGL_DEBUG_MSG_WARN_KHR:
2495bf215546Sopenharmony_ci         case EGL_DEBUG_MSG_INFO_KHR:
2496bf215546Sopenharmony_ci            if (attrib_list[i + 1])
2497bf215546Sopenharmony_ci               newEnabled |= DebugBitFromType(attrib_list[i]);
2498bf215546Sopenharmony_ci            else
2499bf215546Sopenharmony_ci               newEnabled &= ~DebugBitFromType(attrib_list[i]);
2500bf215546Sopenharmony_ci            break;
2501bf215546Sopenharmony_ci         default:
2502bf215546Sopenharmony_ci            // On error, set the last error code, call the current
2503bf215546Sopenharmony_ci            // debug callback, and return the error code.
2504bf215546Sopenharmony_ci            mtx_unlock(_eglGlobal.Mutex);
2505bf215546Sopenharmony_ci            _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
2506bf215546Sopenharmony_ci                  "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
2507bf215546Sopenharmony_ci            return EGL_BAD_ATTRIBUTE;
2508bf215546Sopenharmony_ci         }
2509bf215546Sopenharmony_ci      }
2510bf215546Sopenharmony_ci   }
2511bf215546Sopenharmony_ci
2512bf215546Sopenharmony_ci   if (callback != NULL) {
2513bf215546Sopenharmony_ci      _eglGlobal.debugCallback = callback;
2514bf215546Sopenharmony_ci      _eglGlobal.debugTypesEnabled = newEnabled;
2515bf215546Sopenharmony_ci   } else {
2516bf215546Sopenharmony_ci      _eglGlobal.debugCallback = NULL;
2517bf215546Sopenharmony_ci      _eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
2518bf215546Sopenharmony_ci   }
2519bf215546Sopenharmony_ci
2520bf215546Sopenharmony_ci   mtx_unlock(_eglGlobal.Mutex);
2521bf215546Sopenharmony_ci   return EGL_SUCCESS;
2522bf215546Sopenharmony_ci}
2523bf215546Sopenharmony_ci
2524bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2525bf215546Sopenharmony_cieglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
2526bf215546Sopenharmony_ci{
2527bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
2528bf215546Sopenharmony_ci
2529bf215546Sopenharmony_ci   mtx_lock(_eglGlobal.Mutex);
2530bf215546Sopenharmony_ci
2531bf215546Sopenharmony_ci   switch (attribute) {
2532bf215546Sopenharmony_ci   case EGL_DEBUG_MSG_CRITICAL_KHR:
2533bf215546Sopenharmony_ci   case EGL_DEBUG_MSG_ERROR_KHR:
2534bf215546Sopenharmony_ci   case EGL_DEBUG_MSG_WARN_KHR:
2535bf215546Sopenharmony_ci   case EGL_DEBUG_MSG_INFO_KHR:
2536bf215546Sopenharmony_ci      if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
2537bf215546Sopenharmony_ci         *value = EGL_TRUE;
2538bf215546Sopenharmony_ci      else
2539bf215546Sopenharmony_ci         *value = EGL_FALSE;
2540bf215546Sopenharmony_ci      break;
2541bf215546Sopenharmony_ci   case EGL_DEBUG_CALLBACK_KHR:
2542bf215546Sopenharmony_ci      *value = (EGLAttrib) _eglGlobal.debugCallback;
2543bf215546Sopenharmony_ci      break;
2544bf215546Sopenharmony_ci   default:
2545bf215546Sopenharmony_ci      mtx_unlock(_eglGlobal.Mutex);
2546bf215546Sopenharmony_ci      _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
2547bf215546Sopenharmony_ci                      "Invalid attribute 0x%04lx", (unsigned long) attribute);
2548bf215546Sopenharmony_ci      return EGL_FALSE;
2549bf215546Sopenharmony_ci   }
2550bf215546Sopenharmony_ci
2551bf215546Sopenharmony_ci   mtx_unlock(_eglGlobal.Mutex);
2552bf215546Sopenharmony_ci   return EGL_TRUE;
2553bf215546Sopenharmony_ci}
2554bf215546Sopenharmony_ci
2555bf215546Sopenharmony_cistatic int
2556bf215546Sopenharmony_ci_eglFunctionCompare(const void *key, const void *elem)
2557bf215546Sopenharmony_ci{
2558bf215546Sopenharmony_ci   const char *procname = key;
2559bf215546Sopenharmony_ci   const struct _egl_entrypoint *entrypoint = elem;
2560bf215546Sopenharmony_ci   return strcmp(procname, entrypoint->name);
2561bf215546Sopenharmony_ci}
2562bf215546Sopenharmony_ci
2563bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2564bf215546Sopenharmony_cieglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats,
2565bf215546Sopenharmony_ci                         EGLint *formats, EGLint *num_formats)
2566bf215546Sopenharmony_ci{
2567bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2568bf215546Sopenharmony_ci   EGLBoolean ret;
2569bf215546Sopenharmony_ci
2570bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2571bf215546Sopenharmony_ci
2572bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2573bf215546Sopenharmony_ci
2574bf215546Sopenharmony_ci   ret = disp->Driver->QueryDmaBufFormatsEXT(disp, max_formats, formats, num_formats);
2575bf215546Sopenharmony_ci
2576bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2577bf215546Sopenharmony_ci}
2578bf215546Sopenharmony_ci
2579bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2580bf215546Sopenharmony_cieglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
2581bf215546Sopenharmony_ci                           EGLuint64KHR *modifiers, EGLBoolean *external_only,
2582bf215546Sopenharmony_ci                           EGLint *num_modifiers)
2583bf215546Sopenharmony_ci{
2584bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2585bf215546Sopenharmony_ci   EGLBoolean ret;
2586bf215546Sopenharmony_ci
2587bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2588bf215546Sopenharmony_ci
2589bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2590bf215546Sopenharmony_ci
2591bf215546Sopenharmony_ci   ret = disp->Driver->QueryDmaBufModifiersEXT(disp, format, max_modifiers, modifiers,
2592bf215546Sopenharmony_ci                                      external_only, num_modifiers);
2593bf215546Sopenharmony_ci
2594bf215546Sopenharmony_ci   RETURN_EGL_EVAL(disp, ret);
2595bf215546Sopenharmony_ci}
2596bf215546Sopenharmony_ci
2597bf215546Sopenharmony_cistatic void EGLAPIENTRY
2598bf215546Sopenharmony_cieglSetBlobCacheFuncsANDROID(EGLDisplay *dpy, EGLSetBlobFuncANDROID set,
2599bf215546Sopenharmony_ci                            EGLGetBlobFuncANDROID get)
2600bf215546Sopenharmony_ci{
2601bf215546Sopenharmony_ci   /* This function does not return anything so we cannot
2602bf215546Sopenharmony_ci    * utilize the helper macros _EGL_FUNC_START or _EGL_CHECK_DISPLAY.
2603bf215546Sopenharmony_ci    */
2604bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2605bf215546Sopenharmony_ci   if (!_eglSetFuncName(__func__, disp, EGL_OBJECT_DISPLAY_KHR, NULL)) {
2606bf215546Sopenharmony_ci      if (disp)
2607bf215546Sopenharmony_ci         _eglUnlockDisplay(disp);
2608bf215546Sopenharmony_ci      return;
2609bf215546Sopenharmony_ci   }
2610bf215546Sopenharmony_ci
2611bf215546Sopenharmony_ci   if (!_eglCheckDisplay(disp, __func__)) {
2612bf215546Sopenharmony_ci      if (disp)
2613bf215546Sopenharmony_ci         _eglUnlockDisplay(disp);
2614bf215546Sopenharmony_ci      return;
2615bf215546Sopenharmony_ci   }
2616bf215546Sopenharmony_ci
2617bf215546Sopenharmony_ci   if (!set || !get) {
2618bf215546Sopenharmony_ci      _eglError(EGL_BAD_PARAMETER,
2619bf215546Sopenharmony_ci                "eglSetBlobCacheFuncsANDROID: NULL handler given");
2620bf215546Sopenharmony_ci      _eglUnlockDisplay(disp);
2621bf215546Sopenharmony_ci      return;
2622bf215546Sopenharmony_ci   }
2623bf215546Sopenharmony_ci
2624bf215546Sopenharmony_ci   if (disp->BlobCacheSet) {
2625bf215546Sopenharmony_ci      _eglError(EGL_BAD_PARAMETER,
2626bf215546Sopenharmony_ci                "eglSetBlobCacheFuncsANDROID: functions already set");
2627bf215546Sopenharmony_ci      _eglUnlockDisplay(disp);
2628bf215546Sopenharmony_ci      return;
2629bf215546Sopenharmony_ci   }
2630bf215546Sopenharmony_ci
2631bf215546Sopenharmony_ci   disp->BlobCacheSet = set;
2632bf215546Sopenharmony_ci   disp->BlobCacheGet = get;
2633bf215546Sopenharmony_ci
2634bf215546Sopenharmony_ci   disp->Driver->SetBlobCacheFuncsANDROID(disp, set, get);
2635bf215546Sopenharmony_ci
2636bf215546Sopenharmony_ci   _eglUnlockDisplay(disp);
2637bf215546Sopenharmony_ci}
2638bf215546Sopenharmony_ci
2639bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2640bf215546Sopenharmony_cieglQueryDeviceAttribEXT(EGLDeviceEXT device,
2641bf215546Sopenharmony_ci                        EGLint attribute,
2642bf215546Sopenharmony_ci                        EGLAttrib *value)
2643bf215546Sopenharmony_ci{
2644bf215546Sopenharmony_ci   _EGLDevice *dev = _eglLookupDevice(device);
2645bf215546Sopenharmony_ci   EGLBoolean ret;
2646bf215546Sopenharmony_ci
2647bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2648bf215546Sopenharmony_ci   if (!dev)
2649bf215546Sopenharmony_ci      RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, EGL_FALSE);
2650bf215546Sopenharmony_ci
2651bf215546Sopenharmony_ci   ret = _eglQueryDeviceAttribEXT(dev, attribute, value);
2652bf215546Sopenharmony_ci   RETURN_EGL_EVAL(NULL, ret);
2653bf215546Sopenharmony_ci}
2654bf215546Sopenharmony_ci
2655bf215546Sopenharmony_cistatic const char * EGLAPIENTRY
2656bf215546Sopenharmony_cieglQueryDeviceStringEXT(EGLDeviceEXT device,
2657bf215546Sopenharmony_ci                        EGLint name)
2658bf215546Sopenharmony_ci{
2659bf215546Sopenharmony_ci   _EGLDevice *dev = _eglLookupDevice(device);
2660bf215546Sopenharmony_ci
2661bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2662bf215546Sopenharmony_ci   if (!dev)
2663bf215546Sopenharmony_ci      RETURN_EGL_ERROR(NULL, EGL_BAD_DEVICE_EXT, NULL);
2664bf215546Sopenharmony_ci
2665bf215546Sopenharmony_ci   RETURN_EGL_EVAL(NULL, _eglQueryDeviceStringEXT(dev, name));
2666bf215546Sopenharmony_ci}
2667bf215546Sopenharmony_ci
2668bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2669bf215546Sopenharmony_cieglQueryDevicesEXT(EGLint max_devices,
2670bf215546Sopenharmony_ci                   EGLDeviceEXT *devices,
2671bf215546Sopenharmony_ci                   EGLint *num_devices)
2672bf215546Sopenharmony_ci{
2673bf215546Sopenharmony_ci   EGLBoolean ret;
2674bf215546Sopenharmony_ci
2675bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2676bf215546Sopenharmony_ci   ret = _eglQueryDevicesEXT(max_devices, (_EGLDevice **) devices,
2677bf215546Sopenharmony_ci                             num_devices);
2678bf215546Sopenharmony_ci   RETURN_EGL_EVAL(NULL, ret);
2679bf215546Sopenharmony_ci}
2680bf215546Sopenharmony_ci
2681bf215546Sopenharmony_cistatic EGLBoolean EGLAPIENTRY
2682bf215546Sopenharmony_cieglQueryDisplayAttribEXT(EGLDisplay dpy,
2683bf215546Sopenharmony_ci                         EGLint attribute,
2684bf215546Sopenharmony_ci                         EGLAttrib *value)
2685bf215546Sopenharmony_ci{
2686bf215546Sopenharmony_ci   _EGLDisplay *disp = _eglLockDisplay(dpy);
2687bf215546Sopenharmony_ci
2688bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
2689bf215546Sopenharmony_ci   _EGL_CHECK_DISPLAY(disp, EGL_FALSE);
2690bf215546Sopenharmony_ci
2691bf215546Sopenharmony_ci   switch (attribute) {
2692bf215546Sopenharmony_ci   case EGL_DEVICE_EXT:
2693bf215546Sopenharmony_ci      *value = (EGLAttrib) disp->Device;
2694bf215546Sopenharmony_ci      break;
2695bf215546Sopenharmony_ci   default:
2696bf215546Sopenharmony_ci      RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_FALSE);
2697bf215546Sopenharmony_ci   }
2698bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
2699bf215546Sopenharmony_ci}
2700bf215546Sopenharmony_ci
2701bf215546Sopenharmony_cistatic char * EGLAPIENTRY
2702bf215546Sopenharmony_cieglGetDisplayDriverConfig(EGLDisplay dpy)
2703bf215546Sopenharmony_ci{
2704bf215546Sopenharmony_ci    _EGLDisplay *disp = _eglLockDisplay(dpy);
2705bf215546Sopenharmony_ci    char *ret;
2706bf215546Sopenharmony_ci
2707bf215546Sopenharmony_ci    _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
2708bf215546Sopenharmony_ci    _EGL_CHECK_DISPLAY(disp, NULL);
2709bf215546Sopenharmony_ci
2710bf215546Sopenharmony_ci    assert(disp->Extensions.MESA_query_driver);
2711bf215546Sopenharmony_ci
2712bf215546Sopenharmony_ci    ret = disp->Driver->QueryDriverConfig(disp);
2713bf215546Sopenharmony_ci    RETURN_EGL_EVAL(disp, ret);
2714bf215546Sopenharmony_ci}
2715bf215546Sopenharmony_ci
2716bf215546Sopenharmony_cistatic const char * EGLAPIENTRY
2717bf215546Sopenharmony_cieglGetDisplayDriverName(EGLDisplay dpy)
2718bf215546Sopenharmony_ci{
2719bf215546Sopenharmony_ci    _EGLDisplay *disp = _eglLockDisplay(dpy);
2720bf215546Sopenharmony_ci    const char *ret;
2721bf215546Sopenharmony_ci
2722bf215546Sopenharmony_ci    _EGL_FUNC_START(disp, EGL_NONE, NULL, NULL);
2723bf215546Sopenharmony_ci    _EGL_CHECK_DISPLAY(disp, NULL);
2724bf215546Sopenharmony_ci
2725bf215546Sopenharmony_ci    assert(disp->Extensions.MESA_query_driver);
2726bf215546Sopenharmony_ci
2727bf215546Sopenharmony_ci    ret = disp->Driver->QueryDriverName(disp);
2728bf215546Sopenharmony_ci    RETURN_EGL_EVAL(disp, ret);
2729bf215546Sopenharmony_ci}
2730bf215546Sopenharmony_ci
2731bf215546Sopenharmony_ci__eglMustCastToProperFunctionPointerType EGLAPIENTRY
2732bf215546Sopenharmony_cieglGetProcAddress(const char *procname)
2733bf215546Sopenharmony_ci{
2734bf215546Sopenharmony_ci   static const struct _egl_entrypoint egl_functions[] = {
2735bf215546Sopenharmony_ci#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
2736bf215546Sopenharmony_ci#include "eglentrypoint.h"
2737bf215546Sopenharmony_ci#undef EGL_ENTRYPOINT
2738bf215546Sopenharmony_ci   };
2739bf215546Sopenharmony_ci   _EGLProc ret = NULL;
2740bf215546Sopenharmony_ci
2741bf215546Sopenharmony_ci   if (!procname)
2742bf215546Sopenharmony_ci      RETURN_EGL_SUCCESS(NULL, NULL);
2743bf215546Sopenharmony_ci
2744bf215546Sopenharmony_ci   _EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
2745bf215546Sopenharmony_ci
2746bf215546Sopenharmony_ci   if (strncmp(procname, "egl", 3) == 0) {
2747bf215546Sopenharmony_ci      const struct _egl_entrypoint *entrypoint =
2748bf215546Sopenharmony_ci         bsearch(procname,
2749bf215546Sopenharmony_ci                 egl_functions, ARRAY_SIZE(egl_functions),
2750bf215546Sopenharmony_ci                 sizeof(egl_functions[0]),
2751bf215546Sopenharmony_ci                 _eglFunctionCompare);
2752bf215546Sopenharmony_ci      if (entrypoint)
2753bf215546Sopenharmony_ci         ret = entrypoint->function;
2754bf215546Sopenharmony_ci   }
2755bf215546Sopenharmony_ci
2756bf215546Sopenharmony_ci   if (!ret && _eglDriver.GetProcAddress)
2757bf215546Sopenharmony_ci      ret = _eglDriver.GetProcAddress(procname);
2758bf215546Sopenharmony_ci
2759bf215546Sopenharmony_ci   RETURN_EGL_SUCCESS(NULL, ret);
2760bf215546Sopenharmony_ci}
2761bf215546Sopenharmony_ci
2762bf215546Sopenharmony_cistatic int
2763bf215546Sopenharmony_ci_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
2764bf215546Sopenharmony_ci                       _EGLDisplay **disp, _EGLContext **ctx)
2765bf215546Sopenharmony_ci{
2766bf215546Sopenharmony_ci
2767bf215546Sopenharmony_ci   *disp = _eglLockDisplay(dpy);
2768bf215546Sopenharmony_ci   if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
2769bf215546Sopenharmony_ci      if (*disp)
2770bf215546Sopenharmony_ci         _eglUnlockDisplay(*disp);
2771bf215546Sopenharmony_ci      return MESA_GLINTEROP_INVALID_DISPLAY;
2772bf215546Sopenharmony_ci   }
2773bf215546Sopenharmony_ci
2774bf215546Sopenharmony_ci   *ctx = _eglLookupContext(context, *disp);
2775bf215546Sopenharmony_ci   if (!*ctx ||
2776bf215546Sopenharmony_ci       ((*ctx)->ClientAPI != EGL_OPENGL_API &&
2777bf215546Sopenharmony_ci        (*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
2778bf215546Sopenharmony_ci      _eglUnlockDisplay(*disp);
2779bf215546Sopenharmony_ci      return MESA_GLINTEROP_INVALID_CONTEXT;
2780bf215546Sopenharmony_ci   }
2781bf215546Sopenharmony_ci
2782bf215546Sopenharmony_ci   return MESA_GLINTEROP_SUCCESS;
2783bf215546Sopenharmony_ci}
2784bf215546Sopenharmony_ci
2785bf215546Sopenharmony_ciPUBLIC int
2786bf215546Sopenharmony_ciMesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
2787bf215546Sopenharmony_ci                                struct mesa_glinterop_device_info *out)
2788bf215546Sopenharmony_ci{
2789bf215546Sopenharmony_ci   _EGLDisplay *disp;
2790bf215546Sopenharmony_ci   _EGLContext *ctx;
2791bf215546Sopenharmony_ci   int ret;
2792bf215546Sopenharmony_ci
2793bf215546Sopenharmony_ci   ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx);
2794bf215546Sopenharmony_ci   if (ret != MESA_GLINTEROP_SUCCESS)
2795bf215546Sopenharmony_ci      return ret;
2796bf215546Sopenharmony_ci
2797bf215546Sopenharmony_ci   if (disp->Driver->GLInteropQueryDeviceInfo)
2798bf215546Sopenharmony_ci      ret = disp->Driver->GLInteropQueryDeviceInfo(disp, ctx, out);
2799bf215546Sopenharmony_ci   else
2800bf215546Sopenharmony_ci      ret = MESA_GLINTEROP_UNSUPPORTED;
2801bf215546Sopenharmony_ci
2802bf215546Sopenharmony_ci   _eglUnlockDisplay(disp);
2803bf215546Sopenharmony_ci   return ret;
2804bf215546Sopenharmony_ci}
2805bf215546Sopenharmony_ci
2806bf215546Sopenharmony_ciPUBLIC int
2807bf215546Sopenharmony_ciMesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
2808bf215546Sopenharmony_ci                             struct mesa_glinterop_export_in *in,
2809bf215546Sopenharmony_ci                             struct mesa_glinterop_export_out *out)
2810bf215546Sopenharmony_ci{
2811bf215546Sopenharmony_ci   _EGLDisplay *disp;
2812bf215546Sopenharmony_ci   _EGLContext *ctx;
2813bf215546Sopenharmony_ci   int ret;
2814bf215546Sopenharmony_ci
2815bf215546Sopenharmony_ci   ret = _eglLockDisplayInterop(dpy, context, &disp, &ctx);
2816bf215546Sopenharmony_ci   if (ret != MESA_GLINTEROP_SUCCESS)
2817bf215546Sopenharmony_ci      return ret;
2818bf215546Sopenharmony_ci
2819bf215546Sopenharmony_ci   if (disp->Driver->GLInteropExportObject)
2820bf215546Sopenharmony_ci      ret = disp->Driver->GLInteropExportObject(disp, ctx, in, out);
2821bf215546Sopenharmony_ci   else
2822bf215546Sopenharmony_ci      ret = MESA_GLINTEROP_UNSUPPORTED;
2823bf215546Sopenharmony_ci
2824bf215546Sopenharmony_ci   _eglUnlockDisplay(disp);
2825bf215546Sopenharmony_ci   return ret;
2826bf215546Sopenharmony_ci}
2827