eglapi.c revision 848b8605
1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2008 VMware, Inc.
4848b8605Smrg * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5848b8605Smrg * Copyright 2010-2011 LunarG, Inc.
6848b8605Smrg * All Rights Reserved.
7848b8605Smrg *
8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9848b8605Smrg * copy of this software and associated documentation files (the
10848b8605Smrg * "Software"), to deal in the Software without restriction, including
11848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
12848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
13848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
14848b8605Smrg * the following conditions:
15848b8605Smrg *
16848b8605Smrg * The above copyright notice and this permission notice (including the
17848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
18848b8605Smrg * of the Software.
19848b8605Smrg *
20848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26848b8605Smrg * DEALINGS IN THE SOFTWARE.
27848b8605Smrg *
28848b8605Smrg **************************************************************************/
29848b8605Smrg
30848b8605Smrg
31848b8605Smrg/**
32848b8605Smrg * Public EGL API entrypoints
33848b8605Smrg *
34848b8605Smrg * Generally, we use the EGLDisplay parameter as a key to lookup the
35848b8605Smrg * appropriate device driver handle, then jump though the driver's
36848b8605Smrg * dispatch table to handle the function.
37848b8605Smrg *
38848b8605Smrg * That allows us the option of supporting multiple, simultaneous,
39848b8605Smrg * heterogeneous hardware devices in the future.
40848b8605Smrg *
41848b8605Smrg * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
42848b8605Smrg * opaque handles. Internal objects are linked to a display to
43848b8605Smrg * create the handles.
44848b8605Smrg *
45848b8605Smrg * For each public API entry point, the opaque handles are looked up
46848b8605Smrg * before being dispatched to the drivers.  When it fails to look up
47848b8605Smrg * a handle, one of
48848b8605Smrg *
49848b8605Smrg * EGL_BAD_DISPLAY
50848b8605Smrg * EGL_BAD_CONFIG
51848b8605Smrg * EGL_BAD_CONTEXT
52848b8605Smrg * EGL_BAD_SURFACE
53848b8605Smrg * EGL_BAD_SCREEN_MESA
54848b8605Smrg * EGL_BAD_MODE_MESA
55848b8605Smrg *
56848b8605Smrg * is generated and the driver function is not called. An
57848b8605Smrg * uninitialized EGLDisplay has no driver associated with it. When
58848b8605Smrg * such display is detected,
59848b8605Smrg *
60848b8605Smrg * EGL_NOT_INITIALIZED
61848b8605Smrg *
62848b8605Smrg * is generated.
63848b8605Smrg *
64848b8605Smrg * Some of the entry points use current display, context, or surface
65848b8605Smrg * implicitly.  For such entry points, the implicit objects are also
66848b8605Smrg * checked before calling the driver function.  Other than the
67848b8605Smrg * errors listed above,
68848b8605Smrg *
69848b8605Smrg * EGL_BAD_CURRENT_SURFACE
70848b8605Smrg *
71848b8605Smrg * may also be generated.
72848b8605Smrg *
73848b8605Smrg * Notes on naming conventions:
74848b8605Smrg *
75848b8605Smrg * eglFooBar    - public EGL function
76848b8605Smrg * EGL_FOO_BAR  - public EGL token
77848b8605Smrg * EGLDatatype  - public EGL datatype
78848b8605Smrg *
79848b8605Smrg * _eglFooBar   - private EGL function
80848b8605Smrg * _EGLDatatype - private EGL datatype, typedef'd struct
81848b8605Smrg * _egl_struct  - private EGL struct, non-typedef'd
82848b8605Smrg *
83848b8605Smrg */
84848b8605Smrg
85848b8605Smrg
86848b8605Smrg#include <stdio.h>
87848b8605Smrg#include <stdlib.h>
88848b8605Smrg#include <string.h>
89848b8605Smrg
90848b8605Smrg#include "eglglobals.h"
91848b8605Smrg#include "eglcontext.h"
92848b8605Smrg#include "egldisplay.h"
93848b8605Smrg#include "egltypedefs.h"
94848b8605Smrg#include "eglcurrent.h"
95848b8605Smrg#include "egldriver.h"
96848b8605Smrg#include "eglsurface.h"
97848b8605Smrg#include "eglconfig.h"
98848b8605Smrg#include "eglscreen.h"
99848b8605Smrg#include "eglmode.h"
100848b8605Smrg#include "eglimage.h"
101848b8605Smrg#include "eglsync.h"
102848b8605Smrg
103848b8605Smrg
104848b8605Smrg/**
105848b8605Smrg * Macros to help return an API entrypoint.
106848b8605Smrg *
107848b8605Smrg * These macros will unlock the display and record the error code.
108848b8605Smrg */
109848b8605Smrg#define RETURN_EGL_ERROR(disp, err, ret)        \
110848b8605Smrg   do {                                         \
111848b8605Smrg      if (disp)                                 \
112848b8605Smrg         _eglUnlockDisplay(disp);               \
113848b8605Smrg      /* EGL error codes are non-zero */        \
114848b8605Smrg      if (err)                                  \
115848b8605Smrg         _eglError(err, __FUNCTION__);          \
116848b8605Smrg      return ret;                               \
117848b8605Smrg   } while (0)
118848b8605Smrg
119848b8605Smrg#define RETURN_EGL_SUCCESS(disp, ret) \
120848b8605Smrg   RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
121848b8605Smrg
122848b8605Smrg/* record EGL_SUCCESS only when ret evaluates to true */
123848b8605Smrg#define RETURN_EGL_EVAL(disp, ret) \
124848b8605Smrg   RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
125848b8605Smrg
126848b8605Smrg
127848b8605Smrg/*
128848b8605Smrg * A bunch of macros and checks to simplify error checking.
129848b8605Smrg */
130848b8605Smrg
131848b8605Smrg#define _EGL_CHECK_DISPLAY(disp, ret, drv)         \
132848b8605Smrg   do {                                            \
133848b8605Smrg      drv = _eglCheckDisplay(disp, __FUNCTION__);  \
134848b8605Smrg      if (!drv)                                    \
135848b8605Smrg         RETURN_EGL_ERROR(disp, 0, ret);           \
136848b8605Smrg   } while (0)
137848b8605Smrg
138848b8605Smrg#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv)      \
139848b8605Smrg   do {                                                   \
140848b8605Smrg      drv = _eglCheck ## type(disp, obj, __FUNCTION__);   \
141848b8605Smrg      if (!drv)                                           \
142848b8605Smrg         RETURN_EGL_ERROR(disp, 0, ret);                  \
143848b8605Smrg   } while (0)
144848b8605Smrg
145848b8605Smrg#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
146848b8605Smrg   _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
147848b8605Smrg
148848b8605Smrg#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
149848b8605Smrg   _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
150848b8605Smrg
151848b8605Smrg#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
152848b8605Smrg   _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
153848b8605Smrg
154848b8605Smrg#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
155848b8605Smrg   _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
156848b8605Smrg
157848b8605Smrg#define _EGL_CHECK_MODE(disp, m, ret, drv) \
158848b8605Smrg   _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
159848b8605Smrg
160848b8605Smrg#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
161848b8605Smrg   _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
162848b8605Smrg
163848b8605Smrg
164848b8605Smrgstatic INLINE _EGLDriver *
165848b8605Smrg_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
166848b8605Smrg{
167848b8605Smrg   if (!disp) {
168848b8605Smrg      _eglError(EGL_BAD_DISPLAY, msg);
169848b8605Smrg      return NULL;
170848b8605Smrg   }
171848b8605Smrg   if (!disp->Initialized) {
172848b8605Smrg      _eglError(EGL_NOT_INITIALIZED, msg);
173848b8605Smrg      return NULL;
174848b8605Smrg   }
175848b8605Smrg   return disp->Driver;
176848b8605Smrg}
177848b8605Smrg
178848b8605Smrg
179848b8605Smrgstatic INLINE _EGLDriver *
180848b8605Smrg_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
181848b8605Smrg{
182848b8605Smrg   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
183848b8605Smrg   if (!drv)
184848b8605Smrg      return NULL;
185848b8605Smrg   if (!surf) {
186848b8605Smrg      _eglError(EGL_BAD_SURFACE, msg);
187848b8605Smrg      return NULL;
188848b8605Smrg   }
189848b8605Smrg   return drv;
190848b8605Smrg}
191848b8605Smrg
192848b8605Smrg
193848b8605Smrgstatic INLINE _EGLDriver *
194848b8605Smrg_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
195848b8605Smrg{
196848b8605Smrg   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
197848b8605Smrg   if (!drv)
198848b8605Smrg      return NULL;
199848b8605Smrg   if (!context) {
200848b8605Smrg      _eglError(EGL_BAD_CONTEXT, msg);
201848b8605Smrg      return NULL;
202848b8605Smrg   }
203848b8605Smrg   return drv;
204848b8605Smrg}
205848b8605Smrg
206848b8605Smrg
207848b8605Smrgstatic INLINE _EGLDriver *
208848b8605Smrg_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
209848b8605Smrg{
210848b8605Smrg   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
211848b8605Smrg   if (!drv)
212848b8605Smrg      return NULL;
213848b8605Smrg   if (!conf) {
214848b8605Smrg      _eglError(EGL_BAD_CONFIG, msg);
215848b8605Smrg      return NULL;
216848b8605Smrg   }
217848b8605Smrg   return drv;
218848b8605Smrg}
219848b8605Smrg
220848b8605Smrg
221848b8605Smrgstatic INLINE _EGLDriver *
222848b8605Smrg_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
223848b8605Smrg{
224848b8605Smrg   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
225848b8605Smrg   if (!drv)
226848b8605Smrg      return NULL;
227848b8605Smrg   if (!s) {
228848b8605Smrg      _eglError(EGL_BAD_PARAMETER, msg);
229848b8605Smrg      return NULL;
230848b8605Smrg   }
231848b8605Smrg   return drv;
232848b8605Smrg}
233848b8605Smrg
234848b8605Smrg
235848b8605Smrg#ifdef EGL_MESA_screen_surface
236848b8605Smrg
237848b8605Smrg
238848b8605Smrgstatic INLINE _EGLDriver *
239848b8605Smrg_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
240848b8605Smrg{
241848b8605Smrg   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
242848b8605Smrg   if (!drv)
243848b8605Smrg      return NULL;
244848b8605Smrg   if (!scrn) {
245848b8605Smrg      _eglError(EGL_BAD_SCREEN_MESA, msg);
246848b8605Smrg      return NULL;
247848b8605Smrg   }
248848b8605Smrg   return drv;
249848b8605Smrg}
250848b8605Smrg
251848b8605Smrg
252848b8605Smrgstatic INLINE _EGLDriver *
253848b8605Smrg_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
254848b8605Smrg{
255848b8605Smrg   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
256848b8605Smrg   if (!drv)
257848b8605Smrg      return NULL;
258848b8605Smrg   if (!m) {
259848b8605Smrg      _eglError(EGL_BAD_MODE_MESA, msg);
260848b8605Smrg      return NULL;
261848b8605Smrg   }
262848b8605Smrg   return drv;
263848b8605Smrg}
264848b8605Smrg
265848b8605Smrg
266848b8605Smrg#endif /* EGL_MESA_screen_surface */
267848b8605Smrg
268848b8605Smrg
269848b8605Smrg/**
270848b8605Smrg * Lookup and lock a display.
271848b8605Smrg */
272848b8605Smrgstatic INLINE _EGLDisplay *
273848b8605Smrg_eglLockDisplay(EGLDisplay display)
274848b8605Smrg{
275848b8605Smrg   _EGLDisplay *dpy = _eglLookupDisplay(display);
276848b8605Smrg   if (dpy)
277848b8605Smrg      _eglLockMutex(&dpy->Mutex);
278848b8605Smrg   return dpy;
279848b8605Smrg}
280848b8605Smrg
281848b8605Smrg
282848b8605Smrg/**
283848b8605Smrg * Unlock a display.
284848b8605Smrg */
285848b8605Smrgstatic INLINE void
286848b8605Smrg_eglUnlockDisplay(_EGLDisplay *dpy)
287848b8605Smrg{
288848b8605Smrg   _eglUnlockMutex(&dpy->Mutex);
289848b8605Smrg}
290848b8605Smrg
291848b8605Smrg
292848b8605Smrg/**
293848b8605Smrg * This is typically the first EGL function that an application calls.
294848b8605Smrg * It associates a private _EGLDisplay object to the native display.
295848b8605Smrg */
296848b8605SmrgEGLDisplay EGLAPIENTRY
297848b8605SmrgeglGetDisplay(EGLNativeDisplayType nativeDisplay)
298848b8605Smrg{
299848b8605Smrg   _EGLPlatformType plat;
300848b8605Smrg   _EGLDisplay *dpy;
301848b8605Smrg   void *native_display_ptr;
302848b8605Smrg
303848b8605Smrg   STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
304848b8605Smrg   native_display_ptr = (void*) nativeDisplay;
305848b8605Smrg
306848b8605Smrg   plat = _eglGetNativePlatform(native_display_ptr);
307848b8605Smrg   dpy = _eglFindDisplay(plat, native_display_ptr);
308848b8605Smrg   return _eglGetDisplayHandle(dpy);
309848b8605Smrg}
310848b8605Smrg
311848b8605SmrgEGLDisplay EGLAPIENTRY
312848b8605SmrgeglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
313848b8605Smrg                         const EGLint *attrib_list)
314848b8605Smrg{
315848b8605Smrg   _EGLDisplay *dpy;
316848b8605Smrg
317848b8605Smrg   switch (platform) {
318848b8605Smrg#ifdef HAVE_X11_PLATFORM
319848b8605Smrg   case EGL_PLATFORM_X11_EXT:
320848b8605Smrg      dpy = _eglGetX11Display((Display*) native_display, attrib_list);
321848b8605Smrg      break;
322848b8605Smrg#endif
323848b8605Smrg#ifdef HAVE_DRM_PLATFORM
324848b8605Smrg   case EGL_PLATFORM_GBM_MESA:
325848b8605Smrg      dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
326848b8605Smrg                              attrib_list);
327848b8605Smrg      break;
328848b8605Smrg#endif
329848b8605Smrg#ifdef HAVE_WAYLAND_PLATFORM
330848b8605Smrg   case EGL_PLATFORM_WAYLAND_EXT:
331848b8605Smrg      dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
332848b8605Smrg                                  attrib_list);
333848b8605Smrg      break;
334848b8605Smrg#endif
335848b8605Smrg   default:
336848b8605Smrg      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
337848b8605Smrg   }
338848b8605Smrg
339848b8605Smrg   return _eglGetDisplayHandle(dpy);
340848b8605Smrg}
341848b8605Smrg
342848b8605Smrg/**
343848b8605Smrg * This is typically the second EGL function that an application calls.
344848b8605Smrg * Here we load/initialize the actual hardware driver.
345848b8605Smrg */
346848b8605SmrgEGLBoolean EGLAPIENTRY
347848b8605SmrgeglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
348848b8605Smrg{
349848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
350848b8605Smrg
351848b8605Smrg   if (!disp)
352848b8605Smrg      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
353848b8605Smrg
354848b8605Smrg   if (!disp->Initialized) {
355848b8605Smrg      if (!_eglMatchDriver(disp, EGL_FALSE))
356848b8605Smrg         RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
357848b8605Smrg
358848b8605Smrg      /* limit to APIs supported by core */
359848b8605Smrg      disp->ClientAPIs &= _EGL_API_ALL_BITS;
360848b8605Smrg   }
361848b8605Smrg
362848b8605Smrg   /* Update applications version of major and minor if not NULL */
363848b8605Smrg   if ((major != NULL) && (minor != NULL)) {
364848b8605Smrg      *major = disp->VersionMajor;
365848b8605Smrg      *minor = disp->VersionMinor;
366848b8605Smrg   }
367848b8605Smrg
368848b8605Smrg   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
369848b8605Smrg}
370848b8605Smrg
371848b8605Smrg
372848b8605SmrgEGLBoolean EGLAPIENTRY
373848b8605SmrgeglTerminate(EGLDisplay dpy)
374848b8605Smrg{
375848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
376848b8605Smrg
377848b8605Smrg   if (!disp)
378848b8605Smrg      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
379848b8605Smrg
380848b8605Smrg   if (disp->Initialized) {
381848b8605Smrg      _EGLDriver *drv = disp->Driver;
382848b8605Smrg
383848b8605Smrg      drv->API.Terminate(drv, disp);
384848b8605Smrg      /* do not reset disp->Driver */
385848b8605Smrg      disp->Initialized = EGL_FALSE;
386848b8605Smrg   }
387848b8605Smrg
388848b8605Smrg   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
389848b8605Smrg}
390848b8605Smrg
391848b8605Smrg
392848b8605Smrgconst char * EGLAPIENTRY
393848b8605SmrgeglQueryString(EGLDisplay dpy, EGLint name)
394848b8605Smrg{
395848b8605Smrg   _EGLDisplay *disp;
396848b8605Smrg   _EGLDriver *drv;
397848b8605Smrg   const char *ret;
398848b8605Smrg
399848b8605Smrg   if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
400848b8605Smrg      RETURN_EGL_SUCCESS(NULL, _eglGlobal.ClientExtensionString);
401848b8605Smrg   }
402848b8605Smrg
403848b8605Smrg   disp = _eglLockDisplay(dpy);
404848b8605Smrg   _EGL_CHECK_DISPLAY(disp, NULL, drv);
405848b8605Smrg   ret = drv->API.QueryString(drv, disp, name);
406848b8605Smrg
407848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
408848b8605Smrg}
409848b8605Smrg
410848b8605Smrg
411848b8605SmrgEGLBoolean EGLAPIENTRY
412848b8605SmrgeglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
413848b8605Smrg              EGLint config_size, EGLint *num_config)
414848b8605Smrg{
415848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
416848b8605Smrg   _EGLDriver *drv;
417848b8605Smrg   EGLBoolean ret;
418848b8605Smrg
419848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
420848b8605Smrg   ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
421848b8605Smrg
422848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
423848b8605Smrg}
424848b8605Smrg
425848b8605Smrg
426848b8605SmrgEGLBoolean EGLAPIENTRY
427848b8605SmrgeglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
428848b8605Smrg                EGLint config_size, EGLint *num_config)
429848b8605Smrg{
430848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
431848b8605Smrg   _EGLDriver *drv;
432848b8605Smrg   EGLBoolean ret;
433848b8605Smrg
434848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
435848b8605Smrg   ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
436848b8605Smrg                                config_size, num_config);
437848b8605Smrg
438848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
439848b8605Smrg}
440848b8605Smrg
441848b8605Smrg
442848b8605SmrgEGLBoolean EGLAPIENTRY
443848b8605SmrgeglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
444848b8605Smrg                   EGLint attribute, EGLint *value)
445848b8605Smrg{
446848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
447848b8605Smrg   _EGLConfig *conf = _eglLookupConfig(config, disp);
448848b8605Smrg   _EGLDriver *drv;
449848b8605Smrg   EGLBoolean ret;
450848b8605Smrg
451848b8605Smrg   _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
452848b8605Smrg   ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
453848b8605Smrg
454848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
455848b8605Smrg}
456848b8605Smrg
457848b8605Smrg
458848b8605SmrgEGLContext EGLAPIENTRY
459848b8605SmrgeglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
460848b8605Smrg                 const EGLint *attrib_list)
461848b8605Smrg{
462848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
463848b8605Smrg   _EGLConfig *conf = _eglLookupConfig(config, disp);
464848b8605Smrg   _EGLContext *share = _eglLookupContext(share_list, disp);
465848b8605Smrg   _EGLDriver *drv;
466848b8605Smrg   _EGLContext *context;
467848b8605Smrg   EGLContext ret;
468848b8605Smrg
469848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
470848b8605Smrg
471848b8605Smrg   if (!config && !disp->Extensions.MESA_configless_context)
472848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
473848b8605Smrg
474848b8605Smrg   if (!share && share_list != EGL_NO_CONTEXT)
475848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
476848b8605Smrg
477848b8605Smrg   context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
478848b8605Smrg   ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
479848b8605Smrg
480848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
481848b8605Smrg}
482848b8605Smrg
483848b8605Smrg
484848b8605SmrgEGLBoolean EGLAPIENTRY
485848b8605SmrgeglDestroyContext(EGLDisplay dpy, EGLContext ctx)
486848b8605Smrg{
487848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
488848b8605Smrg   _EGLContext *context = _eglLookupContext(ctx, disp);
489848b8605Smrg   _EGLDriver *drv;
490848b8605Smrg   EGLBoolean ret;
491848b8605Smrg
492848b8605Smrg   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
493848b8605Smrg   _eglUnlinkContext(context);
494848b8605Smrg   ret = drv->API.DestroyContext(drv, disp, context);
495848b8605Smrg
496848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
497848b8605Smrg}
498848b8605Smrg
499848b8605Smrg
500848b8605SmrgEGLBoolean EGLAPIENTRY
501848b8605SmrgeglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
502848b8605Smrg               EGLContext ctx)
503848b8605Smrg{
504848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
505848b8605Smrg   _EGLContext *context = _eglLookupContext(ctx, disp);
506848b8605Smrg   _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
507848b8605Smrg   _EGLSurface *read_surf = _eglLookupSurface(read, disp);
508848b8605Smrg   _EGLDriver *drv;
509848b8605Smrg   EGLBoolean ret;
510848b8605Smrg
511848b8605Smrg   if (!disp)
512848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
513848b8605Smrg   drv = disp->Driver;
514848b8605Smrg
515848b8605Smrg   /* display is allowed to be uninitialized under certain condition */
516848b8605Smrg   if (!disp->Initialized) {
517848b8605Smrg      if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
518848b8605Smrg          ctx != EGL_NO_CONTEXT)
519848b8605Smrg         RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
520848b8605Smrg   }
521848b8605Smrg   if (!drv)
522848b8605Smrg      RETURN_EGL_SUCCESS(disp, EGL_TRUE);
523848b8605Smrg
524848b8605Smrg   if (!context && ctx != EGL_NO_CONTEXT)
525848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
526848b8605Smrg   if (!draw_surf || !read_surf) {
527848b8605Smrg      /* From the EGL 1.4 (20130211) spec:
528848b8605Smrg       *
529848b8605Smrg       *    To release the current context without assigning a new one, set ctx
530848b8605Smrg       *    to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
531848b8605Smrg       */
532848b8605Smrg      if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
533848b8605Smrg         RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
534848b8605Smrg
535848b8605Smrg      if ((!draw_surf && draw != EGL_NO_SURFACE) ||
536848b8605Smrg          (!read_surf && read != EGL_NO_SURFACE))
537848b8605Smrg         RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
538848b8605Smrg      if (draw_surf || read_surf)
539848b8605Smrg         RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
540848b8605Smrg   }
541848b8605Smrg
542848b8605Smrg   ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
543848b8605Smrg
544848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
545848b8605Smrg}
546848b8605Smrg
547848b8605Smrg
548848b8605SmrgEGLBoolean EGLAPIENTRY
549848b8605SmrgeglQueryContext(EGLDisplay dpy, EGLContext ctx,
550848b8605Smrg                EGLint attribute, EGLint *value)
551848b8605Smrg{
552848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
553848b8605Smrg   _EGLContext *context = _eglLookupContext(ctx, disp);
554848b8605Smrg   _EGLDriver *drv;
555848b8605Smrg   EGLBoolean ret;
556848b8605Smrg
557848b8605Smrg   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
558848b8605Smrg   ret = drv->API.QueryContext(drv, disp, context, attribute, value);
559848b8605Smrg
560848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
561848b8605Smrg}
562848b8605Smrg
563848b8605Smrg
564848b8605Smrgstatic EGLSurface
565848b8605Smrg_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
566848b8605Smrg                              void *native_window, const EGLint *attrib_list)
567848b8605Smrg{
568848b8605Smrg   _EGLConfig *conf = _eglLookupConfig(config, disp);
569848b8605Smrg   _EGLDriver *drv;
570848b8605Smrg   _EGLSurface *surf;
571848b8605Smrg   EGLSurface ret;
572848b8605Smrg
573848b8605Smrg   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
574848b8605Smrg
575848b8605Smrg   if (native_window == NULL)
576848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
577848b8605Smrg
578848b8605Smrg   surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
579848b8605Smrg                                       attrib_list);
580848b8605Smrg   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
581848b8605Smrg
582848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
583848b8605Smrg}
584848b8605Smrg
585848b8605Smrg
586848b8605SmrgEGLSurface EGLAPIENTRY
587848b8605SmrgeglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
588848b8605Smrg                       EGLNativeWindowType window, const EGLint *attrib_list)
589848b8605Smrg{
590848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
591848b8605Smrg   STATIC_ASSERT(sizeof(void*) == sizeof(window));
592848b8605Smrg   return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
593848b8605Smrg                                        attrib_list);
594848b8605Smrg}
595848b8605Smrg
596848b8605Smrg
597848b8605SmrgEGLSurface EGLAPIENTRY
598848b8605SmrgeglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
599848b8605Smrg                                  void *native_window,
600848b8605Smrg                                  const EGLint *attrib_list)
601848b8605Smrg{
602848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
603848b8605Smrg
604848b8605Smrg#ifdef HAVE_X11_PLATFORM
605848b8605Smrg   if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
606848b8605Smrg      /* The `native_window` parameter for the X11 platform differs between
607848b8605Smrg       * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
608848b8605Smrg       * eglCreateWindowSurface(), the type of `native_window` is an Xlib
609848b8605Smrg       * `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
610848b8605Smrg       * `Window*`.  Convert `Window*` to `Window` because that's what
611848b8605Smrg       * dri2_x11_create_window_surface() expects.
612848b8605Smrg       */
613848b8605Smrg      native_window = (void*) (* (Window*) native_window);
614848b8605Smrg   }
615848b8605Smrg#endif
616848b8605Smrg
617848b8605Smrg   return _eglCreateWindowSurfaceCommon(disp, config, native_window,
618848b8605Smrg                                        attrib_list);
619848b8605Smrg}
620848b8605Smrg
621848b8605Smrg
622848b8605Smrgstatic EGLSurface
623848b8605Smrg_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
624848b8605Smrg                              void *native_pixmap, const EGLint *attrib_list)
625848b8605Smrg{
626848b8605Smrg   _EGLConfig *conf = _eglLookupConfig(config, disp);
627848b8605Smrg   _EGLDriver *drv;
628848b8605Smrg   _EGLSurface *surf;
629848b8605Smrg   EGLSurface ret;
630848b8605Smrg
631848b8605Smrg   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
632848b8605Smrg   surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
633848b8605Smrg                                       attrib_list);
634848b8605Smrg   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
635848b8605Smrg
636848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
637848b8605Smrg}
638848b8605Smrg
639848b8605Smrg
640848b8605SmrgEGLSurface EGLAPIENTRY
641848b8605SmrgeglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
642848b8605Smrg                       EGLNativePixmapType pixmap, const EGLint *attrib_list)
643848b8605Smrg{
644848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
645848b8605Smrg   STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
646848b8605Smrg   return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
647848b8605Smrg                                         attrib_list);
648848b8605Smrg}
649848b8605Smrg
650848b8605SmrgEGLSurface EGLAPIENTRY
651848b8605SmrgeglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
652848b8605Smrg                                   void *native_pixmap,
653848b8605Smrg                                   const EGLint *attrib_list)
654848b8605Smrg{
655848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
656848b8605Smrg
657848b8605Smrg#ifdef HAVE_X11_PLATFORM
658848b8605Smrg      /* The `native_pixmap` parameter for the X11 platform differs between
659848b8605Smrg       * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
660848b8605Smrg       * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
661848b8605Smrg       * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
662848b8605Smrg       * `Pixmap*`.  Convert `Pixmap*` to `Pixmap` because that's what
663848b8605Smrg       * dri2_x11_create_pixmap_surface() expects.
664848b8605Smrg       */
665848b8605Smrg   if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
666848b8605Smrg      native_pixmap = (void*) (* (Pixmap*) native_pixmap);
667848b8605Smrg   }
668848b8605Smrg#endif
669848b8605Smrg
670848b8605Smrg   return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
671848b8605Smrg                                        attrib_list);
672848b8605Smrg}
673848b8605Smrg
674848b8605Smrg
675848b8605SmrgEGLSurface EGLAPIENTRY
676848b8605SmrgeglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
677848b8605Smrg                        const EGLint *attrib_list)
678848b8605Smrg{
679848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
680848b8605Smrg   _EGLConfig *conf = _eglLookupConfig(config, disp);
681848b8605Smrg   _EGLDriver *drv;
682848b8605Smrg   _EGLSurface *surf;
683848b8605Smrg   EGLSurface ret;
684848b8605Smrg
685848b8605Smrg   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
686848b8605Smrg
687848b8605Smrg   surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
688848b8605Smrg   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
689848b8605Smrg
690848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
691848b8605Smrg}
692848b8605Smrg
693848b8605Smrg
694848b8605SmrgEGLBoolean EGLAPIENTRY
695848b8605SmrgeglDestroySurface(EGLDisplay dpy, EGLSurface surface)
696848b8605Smrg{
697848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
698848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
699848b8605Smrg   _EGLDriver *drv;
700848b8605Smrg   EGLBoolean ret;
701848b8605Smrg
702848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
703848b8605Smrg   _eglUnlinkSurface(surf);
704848b8605Smrg   ret = drv->API.DestroySurface(drv, disp, surf);
705848b8605Smrg
706848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
707848b8605Smrg}
708848b8605Smrg
709848b8605SmrgEGLBoolean EGLAPIENTRY
710848b8605SmrgeglQuerySurface(EGLDisplay dpy, EGLSurface surface,
711848b8605Smrg                EGLint attribute, EGLint *value)
712848b8605Smrg{
713848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
714848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
715848b8605Smrg   _EGLDriver *drv;
716848b8605Smrg   EGLBoolean ret;
717848b8605Smrg
718848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
719848b8605Smrg   ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
720848b8605Smrg
721848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
722848b8605Smrg}
723848b8605Smrg
724848b8605SmrgEGLBoolean EGLAPIENTRY
725848b8605SmrgeglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
726848b8605Smrg                 EGLint attribute, EGLint value)
727848b8605Smrg{
728848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
729848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
730848b8605Smrg   _EGLDriver *drv;
731848b8605Smrg   EGLBoolean ret;
732848b8605Smrg
733848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
734848b8605Smrg   ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
735848b8605Smrg
736848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
737848b8605Smrg}
738848b8605Smrg
739848b8605Smrg
740848b8605SmrgEGLBoolean EGLAPIENTRY
741848b8605SmrgeglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
742848b8605Smrg{
743848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
744848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
745848b8605Smrg   _EGLDriver *drv;
746848b8605Smrg   EGLBoolean ret;
747848b8605Smrg
748848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
749848b8605Smrg   ret = drv->API.BindTexImage(drv, disp, surf, buffer);
750848b8605Smrg
751848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
752848b8605Smrg}
753848b8605Smrg
754848b8605Smrg
755848b8605SmrgEGLBoolean EGLAPIENTRY
756848b8605SmrgeglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
757848b8605Smrg{
758848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
759848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
760848b8605Smrg   _EGLDriver *drv;
761848b8605Smrg   EGLBoolean ret;
762848b8605Smrg
763848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
764848b8605Smrg   ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
765848b8605Smrg
766848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
767848b8605Smrg}
768848b8605Smrg
769848b8605Smrg
770848b8605SmrgEGLBoolean EGLAPIENTRY
771848b8605SmrgeglSwapInterval(EGLDisplay dpy, EGLint interval)
772848b8605Smrg{
773848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
774848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
775848b8605Smrg   _EGLSurface *surf;
776848b8605Smrg   _EGLDriver *drv;
777848b8605Smrg   EGLBoolean ret;
778848b8605Smrg
779848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
780848b8605Smrg
781848b8605Smrg   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
782848b8605Smrg       ctx->Resource.Display != disp)
783848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
784848b8605Smrg
785848b8605Smrg   surf = ctx->DrawSurface;
786848b8605Smrg   if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
787848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
788848b8605Smrg
789848b8605Smrg   ret = drv->API.SwapInterval(drv, disp, surf, interval);
790848b8605Smrg
791848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
792848b8605Smrg}
793848b8605Smrg
794848b8605Smrg
795848b8605SmrgEGLBoolean EGLAPIENTRY
796848b8605SmrgeglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
797848b8605Smrg{
798848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
799848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
800848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
801848b8605Smrg   _EGLDriver *drv;
802848b8605Smrg   EGLBoolean ret;
803848b8605Smrg
804848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
805848b8605Smrg
806848b8605Smrg   /* surface must be bound to current context in EGL 1.4 */
807848b8605Smrg   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
808848b8605Smrg       surf != ctx->DrawSurface)
809848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
810848b8605Smrg
811848b8605Smrg   ret = drv->API.SwapBuffers(drv, disp, surf);
812848b8605Smrg
813848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
814848b8605Smrg}
815848b8605Smrg
816848b8605Smrg
817848b8605Smrg#ifdef EGL_EXT_swap_buffers_with_damage
818848b8605Smrg
819848b8605SmrgEGLBoolean EGLAPIENTRY
820848b8605SmrgeglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
821848b8605Smrg                            EGLint *rects, EGLint n_rects)
822848b8605Smrg{
823848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
824848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
825848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
826848b8605Smrg   _EGLDriver *drv;
827848b8605Smrg   EGLBoolean ret;
828848b8605Smrg
829848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
830848b8605Smrg
831848b8605Smrg   /* surface must be bound to current context in EGL 1.4 */
832848b8605Smrg   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
833848b8605Smrg       surf != ctx->DrawSurface)
834848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
835848b8605Smrg
836848b8605Smrg   if ((n_rects > 0 && rects == NULL) || n_rects < 0)
837848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
838848b8605Smrg
839848b8605Smrg   ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
840848b8605Smrg
841848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
842848b8605Smrg}
843848b8605Smrg
844848b8605Smrg#endif /* EGL_EXT_swap_buffers_with_damage */
845848b8605Smrg
846848b8605SmrgEGLBoolean EGLAPIENTRY
847848b8605SmrgeglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
848848b8605Smrg{
849848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
850848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
851848b8605Smrg   _EGLDriver *drv;
852848b8605Smrg   EGLBoolean ret;
853848b8605Smrg   void *native_pixmap_ptr;
854848b8605Smrg
855848b8605Smrg   STATIC_ASSERT(sizeof(void*) == sizeof(target));
856848b8605Smrg   native_pixmap_ptr = (void*) target;
857848b8605Smrg
858848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
859848b8605Smrg   if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
860848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
861848b8605Smrg   ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
862848b8605Smrg
863848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
864848b8605Smrg}
865848b8605Smrg
866848b8605Smrg
867848b8605SmrgEGLBoolean EGLAPIENTRY
868848b8605SmrgeglWaitClient(void)
869848b8605Smrg{
870848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
871848b8605Smrg   _EGLDisplay *disp;
872848b8605Smrg   _EGLDriver *drv;
873848b8605Smrg   EGLBoolean ret;
874848b8605Smrg
875848b8605Smrg   if (!ctx)
876848b8605Smrg      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
877848b8605Smrg
878848b8605Smrg   disp = ctx->Resource.Display;
879848b8605Smrg   _eglLockMutex(&disp->Mutex);
880848b8605Smrg
881848b8605Smrg   /* let bad current context imply bad current surface */
882848b8605Smrg   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
883848b8605Smrg       _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
884848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
885848b8605Smrg
886848b8605Smrg   /* a valid current context implies an initialized current display */
887848b8605Smrg   assert(disp->Initialized);
888848b8605Smrg   drv = disp->Driver;
889848b8605Smrg   ret = drv->API.WaitClient(drv, disp, ctx);
890848b8605Smrg
891848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
892848b8605Smrg}
893848b8605Smrg
894848b8605Smrg
895848b8605SmrgEGLBoolean EGLAPIENTRY
896848b8605SmrgeglWaitGL(void)
897848b8605Smrg{
898848b8605Smrg   _EGLThreadInfo *t = _eglGetCurrentThread();
899848b8605Smrg   EGLint api_index = t->CurrentAPIIndex;
900848b8605Smrg   EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
901848b8605Smrg   EGLBoolean ret;
902848b8605Smrg
903848b8605Smrg   if (api_index != es_index && _eglIsCurrentThreadDummy())
904848b8605Smrg      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
905848b8605Smrg
906848b8605Smrg   t->CurrentAPIIndex = es_index;
907848b8605Smrg   ret = eglWaitClient();
908848b8605Smrg   t->CurrentAPIIndex = api_index;
909848b8605Smrg   return ret;
910848b8605Smrg}
911848b8605Smrg
912848b8605Smrg
913848b8605SmrgEGLBoolean EGLAPIENTRY
914848b8605SmrgeglWaitNative(EGLint engine)
915848b8605Smrg{
916848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
917848b8605Smrg   _EGLDisplay *disp;
918848b8605Smrg   _EGLDriver *drv;
919848b8605Smrg   EGLBoolean ret;
920848b8605Smrg
921848b8605Smrg   if (!ctx)
922848b8605Smrg      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
923848b8605Smrg
924848b8605Smrg   disp = ctx->Resource.Display;
925848b8605Smrg   _eglLockMutex(&disp->Mutex);
926848b8605Smrg
927848b8605Smrg   /* let bad current context imply bad current surface */
928848b8605Smrg   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
929848b8605Smrg       _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
930848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
931848b8605Smrg
932848b8605Smrg   /* a valid current context implies an initialized current display */
933848b8605Smrg   assert(disp->Initialized);
934848b8605Smrg   drv = disp->Driver;
935848b8605Smrg   ret = drv->API.WaitNative(drv, disp, engine);
936848b8605Smrg
937848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
938848b8605Smrg}
939848b8605Smrg
940848b8605Smrg
941848b8605SmrgEGLDisplay EGLAPIENTRY
942848b8605SmrgeglGetCurrentDisplay(void)
943848b8605Smrg{
944848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
945848b8605Smrg   EGLDisplay ret;
946848b8605Smrg
947848b8605Smrg   ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
948848b8605Smrg
949848b8605Smrg   RETURN_EGL_SUCCESS(NULL, ret);
950848b8605Smrg}
951848b8605Smrg
952848b8605Smrg
953848b8605SmrgEGLContext EGLAPIENTRY
954848b8605SmrgeglGetCurrentContext(void)
955848b8605Smrg{
956848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
957848b8605Smrg   EGLContext ret;
958848b8605Smrg
959848b8605Smrg   ret = _eglGetContextHandle(ctx);
960848b8605Smrg
961848b8605Smrg   RETURN_EGL_SUCCESS(NULL, ret);
962848b8605Smrg}
963848b8605Smrg
964848b8605Smrg
965848b8605SmrgEGLSurface EGLAPIENTRY
966848b8605SmrgeglGetCurrentSurface(EGLint readdraw)
967848b8605Smrg{
968848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
969848b8605Smrg   EGLint err = EGL_SUCCESS;
970848b8605Smrg   _EGLSurface *surf;
971848b8605Smrg   EGLSurface ret;
972848b8605Smrg
973848b8605Smrg   if (!ctx)
974848b8605Smrg      RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
975848b8605Smrg
976848b8605Smrg   switch (readdraw) {
977848b8605Smrg   case EGL_DRAW:
978848b8605Smrg      surf = ctx->DrawSurface;
979848b8605Smrg      break;
980848b8605Smrg   case EGL_READ:
981848b8605Smrg      surf = ctx->ReadSurface;
982848b8605Smrg      break;
983848b8605Smrg   default:
984848b8605Smrg      surf = NULL;
985848b8605Smrg      err = EGL_BAD_PARAMETER;
986848b8605Smrg      break;
987848b8605Smrg   }
988848b8605Smrg
989848b8605Smrg   ret = _eglGetSurfaceHandle(surf);
990848b8605Smrg
991848b8605Smrg   RETURN_EGL_ERROR(NULL, err, ret);
992848b8605Smrg}
993848b8605Smrg
994848b8605Smrg
995848b8605SmrgEGLint EGLAPIENTRY
996848b8605SmrgeglGetError(void)
997848b8605Smrg{
998848b8605Smrg   _EGLThreadInfo *t = _eglGetCurrentThread();
999848b8605Smrg   EGLint e = t->LastError;
1000848b8605Smrg   if (!_eglIsCurrentThreadDummy())
1001848b8605Smrg      t->LastError = EGL_SUCCESS;
1002848b8605Smrg   return e;
1003848b8605Smrg}
1004848b8605Smrg
1005848b8605Smrg
1006848b8605Smrg__eglMustCastToProperFunctionPointerType EGLAPIENTRY
1007848b8605SmrgeglGetProcAddress(const char *procname)
1008848b8605Smrg{
1009848b8605Smrg   static const struct {
1010848b8605Smrg      const char *name;
1011848b8605Smrg      _EGLProc function;
1012848b8605Smrg   } egl_functions[] = {
1013848b8605Smrg      /* core functions should not be queryable, but, well... */
1014848b8605Smrg#ifdef _EGL_GET_CORE_ADDRESSES
1015848b8605Smrg      /* alphabetical order */
1016848b8605Smrg      { "eglBindAPI", (_EGLProc) eglBindAPI },
1017848b8605Smrg      { "eglBindTexImage", (_EGLProc) eglBindTexImage },
1018848b8605Smrg      { "eglChooseConfig", (_EGLProc) eglChooseConfig },
1019848b8605Smrg      { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
1020848b8605Smrg      { "eglCreateContext", (_EGLProc) eglCreateContext },
1021848b8605Smrg      { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
1022848b8605Smrg      { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
1023848b8605Smrg      { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
1024848b8605Smrg      { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
1025848b8605Smrg      { "eglDestroyContext", (_EGLProc) eglDestroyContext },
1026848b8605Smrg      { "eglDestroySurface", (_EGLProc) eglDestroySurface },
1027848b8605Smrg      { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
1028848b8605Smrg      { "eglGetConfigs", (_EGLProc) eglGetConfigs },
1029848b8605Smrg      { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
1030848b8605Smrg      { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
1031848b8605Smrg      { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
1032848b8605Smrg      { "eglGetDisplay", (_EGLProc) eglGetDisplay },
1033848b8605Smrg      { "eglGetError", (_EGLProc) eglGetError },
1034848b8605Smrg      { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
1035848b8605Smrg      { "eglInitialize", (_EGLProc) eglInitialize },
1036848b8605Smrg      { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
1037848b8605Smrg      { "eglQueryAPI", (_EGLProc) eglQueryAPI },
1038848b8605Smrg      { "eglQueryContext", (_EGLProc) eglQueryContext },
1039848b8605Smrg      { "eglQueryString", (_EGLProc) eglQueryString },
1040848b8605Smrg      { "eglQuerySurface", (_EGLProc) eglQuerySurface },
1041848b8605Smrg      { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
1042848b8605Smrg      { "eglReleaseThread", (_EGLProc) eglReleaseThread },
1043848b8605Smrg      { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
1044848b8605Smrg      { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
1045848b8605Smrg      { "eglSwapInterval", (_EGLProc) eglSwapInterval },
1046848b8605Smrg      { "eglTerminate", (_EGLProc) eglTerminate },
1047848b8605Smrg      { "eglWaitClient", (_EGLProc) eglWaitClient },
1048848b8605Smrg      { "eglWaitGL", (_EGLProc) eglWaitGL },
1049848b8605Smrg      { "eglWaitNative", (_EGLProc) eglWaitNative },
1050848b8605Smrg#endif /* _EGL_GET_CORE_ADDRESSES */
1051848b8605Smrg#ifdef EGL_MESA_screen_surface
1052848b8605Smrg      { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
1053848b8605Smrg      { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
1054848b8605Smrg      { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
1055848b8605Smrg      { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
1056848b8605Smrg      { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
1057848b8605Smrg      { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
1058848b8605Smrg      { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
1059848b8605Smrg      { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
1060848b8605Smrg      { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
1061848b8605Smrg      { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
1062848b8605Smrg      { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
1063848b8605Smrg      { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
1064848b8605Smrg#endif /* EGL_MESA_screen_surface */
1065848b8605Smrg#ifdef EGL_MESA_drm_display
1066848b8605Smrg      { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
1067848b8605Smrg#endif
1068848b8605Smrg      { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
1069848b8605Smrg      { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
1070848b8605Smrg      { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
1071848b8605Smrg      { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
1072848b8605Smrg      { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
1073848b8605Smrg      { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
1074848b8605Smrg      { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
1075848b8605Smrg#ifdef EGL_NOK_swap_region
1076848b8605Smrg      { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
1077848b8605Smrg#endif
1078848b8605Smrg#ifdef EGL_MESA_drm_image
1079848b8605Smrg      { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
1080848b8605Smrg      { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
1081848b8605Smrg#endif
1082848b8605Smrg#ifdef EGL_WL_bind_wayland_display
1083848b8605Smrg      { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
1084848b8605Smrg      { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
1085848b8605Smrg      { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
1086848b8605Smrg#endif
1087848b8605Smrg#ifdef EGL_WL_create_wayland_buffer_from_image
1088848b8605Smrg      { "eglCreateWaylandBufferFromImageWL", (_EGLProc) eglCreateWaylandBufferFromImageWL },
1089848b8605Smrg#endif
1090848b8605Smrg      { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
1091848b8605Smrg#ifdef EGL_EXT_swap_buffers_with_damage
1092848b8605Smrg      { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
1093848b8605Smrg#endif
1094848b8605Smrg      { "eglGetPlatformDisplayEXT", (_EGLProc) eglGetPlatformDisplayEXT },
1095848b8605Smrg      { "eglCreatePlatformWindowSurfaceEXT", (_EGLProc) eglCreatePlatformWindowSurfaceEXT },
1096848b8605Smrg      { "eglCreatePlatformPixmapSurfaceEXT", (_EGLProc) eglCreatePlatformPixmapSurfaceEXT },
1097848b8605Smrg      { "eglGetSyncValuesCHROMIUM", (_EGLProc) eglGetSyncValuesCHROMIUM },
1098848b8605Smrg      { NULL, NULL }
1099848b8605Smrg   };
1100848b8605Smrg   EGLint i;
1101848b8605Smrg   _EGLProc ret;
1102848b8605Smrg
1103848b8605Smrg   if (!procname)
1104848b8605Smrg      RETURN_EGL_SUCCESS(NULL, NULL);
1105848b8605Smrg
1106848b8605Smrg   ret = NULL;
1107848b8605Smrg   if (strncmp(procname, "egl", 3) == 0) {
1108848b8605Smrg      for (i = 0; egl_functions[i].name; i++) {
1109848b8605Smrg         if (strcmp(egl_functions[i].name, procname) == 0) {
1110848b8605Smrg            ret = egl_functions[i].function;
1111848b8605Smrg            break;
1112848b8605Smrg         }
1113848b8605Smrg      }
1114848b8605Smrg   }
1115848b8605Smrg   if (!ret)
1116848b8605Smrg      ret = _eglGetDriverProc(procname);
1117848b8605Smrg
1118848b8605Smrg   RETURN_EGL_SUCCESS(NULL, ret);
1119848b8605Smrg}
1120848b8605Smrg
1121848b8605Smrg
1122848b8605Smrg#ifdef EGL_MESA_screen_surface
1123848b8605Smrg
1124848b8605Smrg
1125848b8605Smrg/*
1126848b8605Smrg * EGL_MESA_screen extension
1127848b8605Smrg */
1128848b8605Smrg
1129848b8605SmrgEGLBoolean EGLAPIENTRY
1130848b8605SmrgeglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
1131848b8605Smrg                  const EGLint *attrib_list, EGLModeMESA *modes,
1132848b8605Smrg                  EGLint modes_size, EGLint *num_modes)
1133848b8605Smrg{
1134848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1135848b8605Smrg   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1136848b8605Smrg   _EGLDriver *drv;
1137848b8605Smrg   EGLBoolean ret;
1138848b8605Smrg
1139848b8605Smrg   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1140848b8605Smrg   ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
1141848b8605Smrg         modes, modes_size, num_modes);
1142848b8605Smrg
1143848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1144848b8605Smrg}
1145848b8605Smrg
1146848b8605Smrg
1147848b8605SmrgEGLBoolean EGLAPIENTRY
1148848b8605SmrgeglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
1149848b8605Smrg                EGLint mode_size, EGLint *num_mode)
1150848b8605Smrg{
1151848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1152848b8605Smrg   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1153848b8605Smrg   _EGLDriver *drv;
1154848b8605Smrg   EGLBoolean ret;
1155848b8605Smrg
1156848b8605Smrg   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1157848b8605Smrg   ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
1158848b8605Smrg
1159848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1160848b8605Smrg}
1161848b8605Smrg
1162848b8605Smrg
1163848b8605SmrgEGLBoolean EGLAPIENTRY
1164848b8605SmrgeglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
1165848b8605Smrg                     EGLint attribute, EGLint *value)
1166848b8605Smrg{
1167848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1168848b8605Smrg   _EGLMode *m = _eglLookupMode(mode, disp);
1169848b8605Smrg   _EGLDriver *drv;
1170848b8605Smrg   EGLBoolean ret;
1171848b8605Smrg
1172848b8605Smrg   _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
1173848b8605Smrg   ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
1174848b8605Smrg
1175848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1176848b8605Smrg}
1177848b8605Smrg
1178848b8605Smrg
1179848b8605SmrgEGLBoolean EGLAPIENTRY
1180848b8605SmrgeglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
1181848b8605Smrg                   EGLint mask)
1182848b8605Smrg{
1183848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1184848b8605Smrg   _EGLContext *source_context = _eglLookupContext(source, disp);
1185848b8605Smrg   _EGLContext *dest_context = _eglLookupContext(dest, disp);
1186848b8605Smrg   _EGLDriver *drv;
1187848b8605Smrg   EGLBoolean ret;
1188848b8605Smrg
1189848b8605Smrg   _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
1190848b8605Smrg   if (!dest_context)
1191848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
1192848b8605Smrg
1193848b8605Smrg   ret = drv->API.CopyContextMESA(drv, disp,
1194848b8605Smrg         source_context, dest_context, mask);
1195848b8605Smrg
1196848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1197848b8605Smrg}
1198848b8605Smrg
1199848b8605Smrg
1200848b8605SmrgEGLBoolean EGLAPIENTRY
1201848b8605SmrgeglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
1202848b8605Smrg                  EGLint max_screens, EGLint *num_screens)
1203848b8605Smrg{
1204848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1205848b8605Smrg   _EGLDriver *drv;
1206848b8605Smrg   EGLBoolean ret;
1207848b8605Smrg
1208848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1209848b8605Smrg   ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
1210848b8605Smrg
1211848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1212848b8605Smrg}
1213848b8605Smrg
1214848b8605Smrg
1215848b8605SmrgEGLSurface EGLAPIENTRY
1216848b8605SmrgeglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
1217848b8605Smrg                           const EGLint *attrib_list)
1218848b8605Smrg{
1219848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1220848b8605Smrg   _EGLConfig *conf = _eglLookupConfig(config, disp);
1221848b8605Smrg   _EGLDriver *drv;
1222848b8605Smrg   _EGLSurface *surf;
1223848b8605Smrg   EGLSurface ret;
1224848b8605Smrg
1225848b8605Smrg   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1226848b8605Smrg
1227848b8605Smrg   surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
1228848b8605Smrg   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1229848b8605Smrg
1230848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1231848b8605Smrg}
1232848b8605Smrg
1233848b8605Smrg
1234848b8605SmrgEGLBoolean EGLAPIENTRY
1235848b8605SmrgeglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
1236848b8605Smrg                         EGLSurface surface, EGLModeMESA mode)
1237848b8605Smrg{
1238848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1239848b8605Smrg   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1240848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1241848b8605Smrg   _EGLMode *m = _eglLookupMode(mode, disp);
1242848b8605Smrg   _EGLDriver *drv;
1243848b8605Smrg   EGLBoolean ret;
1244848b8605Smrg
1245848b8605Smrg   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1246848b8605Smrg   if (!surf && surface != EGL_NO_SURFACE)
1247848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1248848b8605Smrg   if (!m && mode != EGL_NO_MODE_MESA)
1249848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
1250848b8605Smrg
1251848b8605Smrg   ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
1252848b8605Smrg
1253848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1254848b8605Smrg}
1255848b8605Smrg
1256848b8605Smrg
1257848b8605SmrgEGLBoolean EGLAPIENTRY
1258848b8605SmrgeglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
1259848b8605Smrg{
1260848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1261848b8605Smrg   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1262848b8605Smrg   _EGLDriver *drv;
1263848b8605Smrg   EGLBoolean ret;
1264848b8605Smrg
1265848b8605Smrg   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1266848b8605Smrg   ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
1267848b8605Smrg
1268848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1269848b8605Smrg}
1270848b8605Smrg
1271848b8605Smrg
1272848b8605SmrgEGLBoolean EGLAPIENTRY
1273848b8605SmrgeglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
1274848b8605Smrg                   EGLint attribute, EGLint *value)
1275848b8605Smrg{
1276848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1277848b8605Smrg   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1278848b8605Smrg   _EGLDriver *drv;
1279848b8605Smrg   EGLBoolean ret;
1280848b8605Smrg
1281848b8605Smrg   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1282848b8605Smrg   ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
1283848b8605Smrg
1284848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1285848b8605Smrg}
1286848b8605Smrg
1287848b8605Smrg
1288848b8605SmrgEGLBoolean EGLAPIENTRY
1289848b8605SmrgeglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
1290848b8605Smrg                          EGLSurface *surface)
1291848b8605Smrg{
1292848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1293848b8605Smrg   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1294848b8605Smrg   _EGLDriver *drv;
1295848b8605Smrg   _EGLSurface *surf;
1296848b8605Smrg   EGLBoolean ret;
1297848b8605Smrg
1298848b8605Smrg   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1299848b8605Smrg   ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
1300848b8605Smrg   if (ret && surface)
1301848b8605Smrg      *surface = _eglGetSurfaceHandle(surf);
1302848b8605Smrg
1303848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1304848b8605Smrg}
1305848b8605Smrg
1306848b8605Smrg
1307848b8605SmrgEGLBoolean EGLAPIENTRY
1308848b8605SmrgeglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
1309848b8605Smrg{
1310848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1311848b8605Smrg   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1312848b8605Smrg   _EGLDriver *drv;
1313848b8605Smrg   _EGLMode *m;
1314848b8605Smrg   EGLBoolean ret;
1315848b8605Smrg
1316848b8605Smrg   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1317848b8605Smrg   ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
1318848b8605Smrg   if (ret && mode)
1319848b8605Smrg      *mode = m->Handle;
1320848b8605Smrg
1321848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1322848b8605Smrg}
1323848b8605Smrg
1324848b8605Smrg
1325848b8605Smrgconst char * EGLAPIENTRY
1326848b8605SmrgeglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
1327848b8605Smrg{
1328848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1329848b8605Smrg   _EGLMode *m = _eglLookupMode(mode, disp);
1330848b8605Smrg   _EGLDriver *drv;
1331848b8605Smrg   const char *ret;
1332848b8605Smrg
1333848b8605Smrg   _EGL_CHECK_MODE(disp, m, NULL, drv);
1334848b8605Smrg   ret = drv->API.QueryModeStringMESA(drv, disp, m);
1335848b8605Smrg
1336848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1337848b8605Smrg}
1338848b8605Smrg
1339848b8605Smrg
1340848b8605Smrg#endif /* EGL_MESA_screen_surface */
1341848b8605Smrg
1342848b8605Smrg
1343848b8605Smrg#ifdef EGL_MESA_drm_display
1344848b8605Smrg
1345848b8605SmrgEGLDisplay EGLAPIENTRY
1346848b8605SmrgeglGetDRMDisplayMESA(int fd)
1347848b8605Smrg{
1348848b8605Smrg   _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
1349848b8605Smrg   return _eglGetDisplayHandle(dpy);
1350848b8605Smrg}
1351848b8605Smrg
1352848b8605Smrg#endif /* EGL_MESA_drm_display */
1353848b8605Smrg
1354848b8605Smrg/**
1355848b8605Smrg ** EGL 1.2
1356848b8605Smrg **/
1357848b8605Smrg
1358848b8605Smrg/**
1359848b8605Smrg * Specify the client API to use for subsequent calls including:
1360848b8605Smrg *  eglCreateContext()
1361848b8605Smrg *  eglGetCurrentContext()
1362848b8605Smrg *  eglGetCurrentDisplay()
1363848b8605Smrg *  eglGetCurrentSurface()
1364848b8605Smrg *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1365848b8605Smrg *  eglWaitClient()
1366848b8605Smrg *  eglWaitNative()
1367848b8605Smrg * See section 3.7 "Rendering Context" in the EGL specification for details.
1368848b8605Smrg */
1369848b8605SmrgEGLBoolean EGLAPIENTRY
1370848b8605SmrgeglBindAPI(EGLenum api)
1371848b8605Smrg{
1372848b8605Smrg   _EGLThreadInfo *t = _eglGetCurrentThread();
1373848b8605Smrg
1374848b8605Smrg   if (_eglIsCurrentThreadDummy())
1375848b8605Smrg      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1376848b8605Smrg
1377848b8605Smrg   if (!_eglIsApiValid(api))
1378848b8605Smrg      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1379848b8605Smrg
1380848b8605Smrg   t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1381848b8605Smrg
1382848b8605Smrg   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1383848b8605Smrg}
1384848b8605Smrg
1385848b8605Smrg
1386848b8605Smrg/**
1387848b8605Smrg * Return the last value set with eglBindAPI().
1388848b8605Smrg */
1389848b8605SmrgEGLenum EGLAPIENTRY
1390848b8605SmrgeglQueryAPI(void)
1391848b8605Smrg{
1392848b8605Smrg   _EGLThreadInfo *t = _eglGetCurrentThread();
1393848b8605Smrg   EGLenum ret;
1394848b8605Smrg
1395848b8605Smrg   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1396848b8605Smrg   ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1397848b8605Smrg
1398848b8605Smrg   RETURN_EGL_SUCCESS(NULL, ret);
1399848b8605Smrg}
1400848b8605Smrg
1401848b8605Smrg
1402848b8605SmrgEGLSurface EGLAPIENTRY
1403848b8605SmrgeglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1404848b8605Smrg                                 EGLClientBuffer buffer, EGLConfig config,
1405848b8605Smrg                                 const EGLint *attrib_list)
1406848b8605Smrg{
1407848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1408848b8605Smrg   _EGLConfig *conf = _eglLookupConfig(config, disp);
1409848b8605Smrg   _EGLDriver *drv;
1410848b8605Smrg   _EGLSurface *surf;
1411848b8605Smrg   EGLSurface ret;
1412848b8605Smrg
1413848b8605Smrg   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1414848b8605Smrg
1415848b8605Smrg   surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1416848b8605Smrg                                                 conf, attrib_list);
1417848b8605Smrg   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1418848b8605Smrg
1419848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1420848b8605Smrg}
1421848b8605Smrg
1422848b8605Smrg
1423848b8605SmrgEGLBoolean EGLAPIENTRY
1424848b8605SmrgeglReleaseThread(void)
1425848b8605Smrg{
1426848b8605Smrg   /* unbind current contexts */
1427848b8605Smrg   if (!_eglIsCurrentThreadDummy()) {
1428848b8605Smrg      _EGLThreadInfo *t = _eglGetCurrentThread();
1429848b8605Smrg      EGLint api_index = t->CurrentAPIIndex;
1430848b8605Smrg      EGLint i;
1431848b8605Smrg
1432848b8605Smrg      for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1433848b8605Smrg         _EGLContext *ctx = t->CurrentContexts[i];
1434848b8605Smrg         if (ctx) {
1435848b8605Smrg            _EGLDisplay *disp = ctx->Resource.Display;
1436848b8605Smrg            _EGLDriver *drv;
1437848b8605Smrg
1438848b8605Smrg            t->CurrentAPIIndex = i;
1439848b8605Smrg
1440848b8605Smrg            _eglLockMutex(&disp->Mutex);
1441848b8605Smrg            drv = disp->Driver;
1442848b8605Smrg            (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1443848b8605Smrg            _eglUnlockMutex(&disp->Mutex);
1444848b8605Smrg         }
1445848b8605Smrg      }
1446848b8605Smrg
1447848b8605Smrg      t->CurrentAPIIndex = api_index;
1448848b8605Smrg   }
1449848b8605Smrg
1450848b8605Smrg   _eglDestroyCurrentThread();
1451848b8605Smrg
1452848b8605Smrg   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1453848b8605Smrg}
1454848b8605Smrg
1455848b8605Smrg
1456848b8605SmrgEGLImageKHR EGLAPIENTRY
1457848b8605SmrgeglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1458848b8605Smrg                  EGLClientBuffer buffer, const EGLint *attr_list)
1459848b8605Smrg{
1460848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1461848b8605Smrg   _EGLContext *context = _eglLookupContext(ctx, disp);
1462848b8605Smrg   _EGLDriver *drv;
1463848b8605Smrg   _EGLImage *img;
1464848b8605Smrg   EGLImageKHR ret;
1465848b8605Smrg
1466848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1467848b8605Smrg   if (!disp->Extensions.KHR_image_base)
1468848b8605Smrg      RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1469848b8605Smrg   if (!context && ctx != EGL_NO_CONTEXT)
1470848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1471848b8605Smrg   /* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
1472848b8605Smrg    *  <ctx> must be EGL_NO_CONTEXT..."
1473848b8605Smrg    */
1474848b8605Smrg   if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
1475848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
1476848b8605Smrg
1477848b8605Smrg   img = drv->API.CreateImageKHR(drv,
1478848b8605Smrg         disp, context, target, buffer, attr_list);
1479848b8605Smrg   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1480848b8605Smrg
1481848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1482848b8605Smrg}
1483848b8605Smrg
1484848b8605Smrg
1485848b8605SmrgEGLBoolean EGLAPIENTRY
1486848b8605SmrgeglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1487848b8605Smrg{
1488848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1489848b8605Smrg   _EGLImage *img = _eglLookupImage(image, disp);
1490848b8605Smrg   _EGLDriver *drv;
1491848b8605Smrg   EGLBoolean ret;
1492848b8605Smrg
1493848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1494848b8605Smrg   if (!disp->Extensions.KHR_image_base)
1495848b8605Smrg      RETURN_EGL_EVAL(disp, EGL_FALSE);
1496848b8605Smrg   if (!img)
1497848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1498848b8605Smrg
1499848b8605Smrg   _eglUnlinkImage(img);
1500848b8605Smrg   ret = drv->API.DestroyImageKHR(drv, disp, img);
1501848b8605Smrg
1502848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1503848b8605Smrg}
1504848b8605Smrg
1505848b8605Smrg
1506848b8605SmrgEGLSyncKHR EGLAPIENTRY
1507848b8605SmrgeglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1508848b8605Smrg{
1509848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1510848b8605Smrg   _EGLDriver *drv;
1511848b8605Smrg   _EGLSync *sync;
1512848b8605Smrg   EGLSyncKHR ret;
1513848b8605Smrg
1514848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
1515848b8605Smrg   if (!disp->Extensions.KHR_reusable_sync)
1516848b8605Smrg      RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
1517848b8605Smrg
1518848b8605Smrg   sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
1519848b8605Smrg   ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
1520848b8605Smrg
1521848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1522848b8605Smrg}
1523848b8605Smrg
1524848b8605Smrg
1525848b8605SmrgEGLBoolean EGLAPIENTRY
1526848b8605SmrgeglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1527848b8605Smrg{
1528848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1529848b8605Smrg   _EGLSync *s = _eglLookupSync(sync, disp);
1530848b8605Smrg   _EGLDriver *drv;
1531848b8605Smrg   EGLBoolean ret;
1532848b8605Smrg
1533848b8605Smrg   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1534848b8605Smrg   assert(disp->Extensions.KHR_reusable_sync);
1535848b8605Smrg
1536848b8605Smrg   _eglUnlinkSync(s);
1537848b8605Smrg   ret = drv->API.DestroySyncKHR(drv, disp, s);
1538848b8605Smrg
1539848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1540848b8605Smrg}
1541848b8605Smrg
1542848b8605Smrg
1543848b8605SmrgEGLint EGLAPIENTRY
1544848b8605SmrgeglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1545848b8605Smrg{
1546848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1547848b8605Smrg   _EGLSync *s = _eglLookupSync(sync, disp);
1548848b8605Smrg   _EGLDriver *drv;
1549848b8605Smrg   EGLint ret;
1550848b8605Smrg
1551848b8605Smrg   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1552848b8605Smrg   assert(disp->Extensions.KHR_reusable_sync);
1553848b8605Smrg   ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1554848b8605Smrg
1555848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1556848b8605Smrg}
1557848b8605Smrg
1558848b8605Smrg
1559848b8605SmrgEGLBoolean EGLAPIENTRY
1560848b8605SmrgeglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
1561848b8605Smrg{
1562848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1563848b8605Smrg   _EGLSync *s = _eglLookupSync(sync, disp);
1564848b8605Smrg   _EGLDriver *drv;
1565848b8605Smrg   EGLBoolean ret;
1566848b8605Smrg
1567848b8605Smrg   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1568848b8605Smrg   assert(disp->Extensions.KHR_reusable_sync);
1569848b8605Smrg   ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1570848b8605Smrg
1571848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1572848b8605Smrg}
1573848b8605Smrg
1574848b8605Smrg
1575848b8605SmrgEGLBoolean EGLAPIENTRY
1576848b8605SmrgeglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1577848b8605Smrg{
1578848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1579848b8605Smrg   _EGLSync *s = _eglLookupSync(sync, disp);
1580848b8605Smrg   _EGLDriver *drv;
1581848b8605Smrg   EGLBoolean ret;
1582848b8605Smrg
1583848b8605Smrg   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1584848b8605Smrg   assert(disp->Extensions.KHR_reusable_sync);
1585848b8605Smrg   ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
1586848b8605Smrg
1587848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1588848b8605Smrg}
1589848b8605Smrg
1590848b8605Smrg
1591848b8605Smrg#ifdef EGL_NOK_swap_region
1592848b8605Smrg
1593848b8605SmrgEGLBoolean EGLAPIENTRY
1594848b8605SmrgeglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1595848b8605Smrg			EGLint numRects, const EGLint *rects)
1596848b8605Smrg{
1597848b8605Smrg   _EGLContext *ctx = _eglGetCurrentContext();
1598848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1599848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1600848b8605Smrg   _EGLDriver *drv;
1601848b8605Smrg   EGLBoolean ret;
1602848b8605Smrg
1603848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1604848b8605Smrg
1605848b8605Smrg   if (!disp->Extensions.NOK_swap_region)
1606848b8605Smrg      RETURN_EGL_EVAL(disp, EGL_FALSE);
1607848b8605Smrg
1608848b8605Smrg   /* surface must be bound to current context in EGL 1.4 */
1609848b8605Smrg   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1610848b8605Smrg       surf != ctx->DrawSurface)
1611848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1612848b8605Smrg
1613848b8605Smrg   ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1614848b8605Smrg
1615848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1616848b8605Smrg}
1617848b8605Smrg
1618848b8605Smrg#endif /* EGL_NOK_swap_region */
1619848b8605Smrg
1620848b8605Smrg
1621848b8605Smrg#ifdef EGL_MESA_drm_image
1622848b8605Smrg
1623848b8605SmrgEGLImageKHR EGLAPIENTRY
1624848b8605SmrgeglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1625848b8605Smrg{
1626848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1627848b8605Smrg   _EGLDriver *drv;
1628848b8605Smrg   _EGLImage *img;
1629848b8605Smrg   EGLImageKHR ret;
1630848b8605Smrg
1631848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1632848b8605Smrg   if (!disp->Extensions.MESA_drm_image)
1633848b8605Smrg      RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1634848b8605Smrg
1635848b8605Smrg   img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
1636848b8605Smrg   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1637848b8605Smrg
1638848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1639848b8605Smrg}
1640848b8605Smrg
1641848b8605SmrgEGLBoolean EGLAPIENTRY
1642848b8605SmrgeglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
1643848b8605Smrg		      EGLint *name, EGLint *handle, EGLint *stride)
1644848b8605Smrg{
1645848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1646848b8605Smrg   _EGLImage *img = _eglLookupImage(image, disp);
1647848b8605Smrg   _EGLDriver *drv;
1648848b8605Smrg   EGLBoolean ret;
1649848b8605Smrg
1650848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1651848b8605Smrg   assert(disp->Extensions.MESA_drm_image);
1652848b8605Smrg
1653848b8605Smrg   if (!img)
1654848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1655848b8605Smrg
1656848b8605Smrg   ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1657848b8605Smrg
1658848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1659848b8605Smrg}
1660848b8605Smrg
1661848b8605Smrg#endif
1662848b8605Smrg
1663848b8605Smrg#ifdef EGL_WL_bind_wayland_display
1664848b8605Smrgstruct wl_display;
1665848b8605Smrg
1666848b8605SmrgEGLBoolean EGLAPIENTRY
1667848b8605SmrgeglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1668848b8605Smrg{
1669848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1670848b8605Smrg   _EGLDriver *drv;
1671848b8605Smrg   EGLBoolean ret;
1672848b8605Smrg
1673848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1674848b8605Smrg   assert(disp->Extensions.WL_bind_wayland_display);
1675848b8605Smrg
1676848b8605Smrg   if (!display)
1677848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1678848b8605Smrg
1679848b8605Smrg   ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
1680848b8605Smrg
1681848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1682848b8605Smrg}
1683848b8605Smrg
1684848b8605SmrgEGLBoolean EGLAPIENTRY
1685848b8605SmrgeglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1686848b8605Smrg{
1687848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1688848b8605Smrg   _EGLDriver *drv;
1689848b8605Smrg   EGLBoolean ret;
1690848b8605Smrg
1691848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1692848b8605Smrg   assert(disp->Extensions.WL_bind_wayland_display);
1693848b8605Smrg
1694848b8605Smrg   if (!display)
1695848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1696848b8605Smrg
1697848b8605Smrg   ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
1698848b8605Smrg
1699848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1700848b8605Smrg}
1701848b8605Smrg
1702848b8605SmrgEGLBoolean EGLAPIENTRY
1703848b8605SmrgeglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
1704848b8605Smrg                        EGLint attribute, EGLint *value)
1705848b8605Smrg{
1706848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1707848b8605Smrg   _EGLDriver *drv;
1708848b8605Smrg   EGLBoolean ret;
1709848b8605Smrg
1710848b8605Smrg   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1711848b8605Smrg   assert(disp->Extensions.WL_bind_wayland_display);
1712848b8605Smrg
1713848b8605Smrg   if (!buffer)
1714848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1715848b8605Smrg
1716848b8605Smrg   ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
1717848b8605Smrg
1718848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1719848b8605Smrg}
1720848b8605Smrg#endif
1721848b8605Smrg
1722848b8605Smrg#ifdef EGL_WL_create_wayland_buffer_from_image
1723848b8605Smrgstruct wl_buffer * EGLAPIENTRY
1724848b8605SmrgeglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImageKHR image)
1725848b8605Smrg{
1726848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1727848b8605Smrg   _EGLImage *img;
1728848b8605Smrg   _EGLDriver *drv;
1729848b8605Smrg   struct wl_buffer *ret;
1730848b8605Smrg
1731848b8605Smrg   _EGL_CHECK_DISPLAY(disp, NULL, drv);
1732848b8605Smrg   assert(disp->Extensions.WL_create_wayland_buffer_from_image);
1733848b8605Smrg
1734848b8605Smrg   img = _eglLookupImage(image, disp);
1735848b8605Smrg
1736848b8605Smrg   if (!img)
1737848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
1738848b8605Smrg
1739848b8605Smrg   ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
1740848b8605Smrg
1741848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1742848b8605Smrg}
1743848b8605Smrg#endif
1744848b8605Smrg
1745848b8605SmrgEGLBoolean EGLAPIENTRY
1746848b8605SmrgeglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
1747848b8605Smrg                   EGLint x, EGLint y, EGLint width, EGLint height)
1748848b8605Smrg{
1749848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(dpy);
1750848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1751848b8605Smrg   _EGLDriver *drv;
1752848b8605Smrg   EGLBoolean ret;
1753848b8605Smrg
1754848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1755848b8605Smrg
1756848b8605Smrg   if (!disp->Extensions.NV_post_sub_buffer)
1757848b8605Smrg      RETURN_EGL_EVAL(disp, EGL_FALSE);
1758848b8605Smrg
1759848b8605Smrg   ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
1760848b8605Smrg
1761848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1762848b8605Smrg}
1763848b8605Smrg
1764848b8605SmrgEGLBoolean EGLAPIENTRY
1765848b8605SmrgeglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
1766848b8605Smrg                         EGLuint64KHR *ust, EGLuint64KHR *msc,
1767848b8605Smrg                         EGLuint64KHR *sbc)
1768848b8605Smrg{
1769848b8605Smrg   _EGLDisplay *disp = _eglLockDisplay(display);
1770848b8605Smrg   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1771848b8605Smrg   _EGLDriver *drv;
1772848b8605Smrg   EGLBoolean ret;
1773848b8605Smrg
1774848b8605Smrg   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1775848b8605Smrg   if (!disp->Extensions.CHROMIUM_sync_control)
1776848b8605Smrg      RETURN_EGL_EVAL(disp, EGL_FALSE);
1777848b8605Smrg
1778848b8605Smrg   if (!ust || !msc || !sbc)
1779848b8605Smrg      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1780848b8605Smrg
1781848b8605Smrg   ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
1782848b8605Smrg
1783848b8605Smrg   RETURN_EGL_EVAL(disp, ret);
1784848b8605Smrg}
1785