Subversion Repositories Kolibri OS

Rev

Rev 4494 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/**************************************************************************
2
 *
3
 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4
 * Copyright 2009-2010 Chia-I Wu 
5
 * Copyright 2010-2011 LunarG, Inc.
6
 * All Rights Reserved.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * copy of this software and associated documentation files (the
10
 * "Software"), to deal in the Software without restriction, including
11
 * without limitation the rights to use, copy, modify, merge, publish,
12
 * distribute, sub license, and/or sell copies of the Software, and to
13
 * permit persons to whom the Software is furnished to do so, subject to
14
 * the following conditions:
15
 *
16
 * The above copyright notice and this permission notice (including the
17
 * next paragraph) shall be included in all copies or substantial portions
18
 * of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26
 * DEALINGS IN THE SOFTWARE.
27
 *
28
 **************************************************************************/
29
 
30
 
31
/**
32
 * Public EGL API entrypoints
33
 *
34
 * Generally, we use the EGLDisplay parameter as a key to lookup the
35
 * appropriate device driver handle, then jump though the driver's
36
 * dispatch table to handle the function.
37
 *
38
 * That allows us the option of supporting multiple, simultaneous,
39
 * heterogeneous hardware devices in the future.
40
 *
41
 * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
42
 * opaque handles. Internal objects are linked to a display to
43
 * create the handles.
44
 *
45
 * For each public API entry point, the opaque handles are looked up
46
 * before being dispatched to the drivers.  When it fails to look up
47
 * a handle, one of
48
 *
49
 * EGL_BAD_DISPLAY
50
 * EGL_BAD_CONFIG
51
 * EGL_BAD_CONTEXT
52
 * EGL_BAD_SURFACE
53
 * EGL_BAD_SCREEN_MESA
54
 * EGL_BAD_MODE_MESA
55
 *
56
 * is generated and the driver function is not called. An
57
 * uninitialized EGLDisplay has no driver associated with it. When
58
 * such display is detected,
59
 *
60
 * EGL_NOT_INITIALIZED
61
 *
62
 * is generated.
63
 *
64
 * Some of the entry points use current display, context, or surface
65
 * implicitly.  For such entry points, the implicit objects are also
66
 * checked before calling the driver function.  Other than the
67
 * errors listed above,
68
 *
69
 * EGL_BAD_CURRENT_SURFACE
70
 *
71
 * may also be generated.
72
 *
73
 * Notes on naming conventions:
74
 *
75
 * eglFooBar    - public EGL function
76
 * EGL_FOO_BAR  - public EGL token
77
 * EGLDatatype  - public EGL datatype
78
 *
79
 * _eglFooBar   - private EGL function
80
 * _EGLDatatype - private EGL datatype, typedef'd struct
81
 * _egl_struct  - private EGL struct, non-typedef'd
82
 *
83
 */
84
 
85
 
86
#include 
87
#include 
88
#include 
89
 
90
#include "eglcontext.h"
91
#include "egldisplay.h"
92
#include "egltypedefs.h"
93
#include "eglcurrent.h"
94
#include "egldriver.h"
95
#include "eglsurface.h"
96
#include "eglconfig.h"
97
#include "eglscreen.h"
98
#include "eglmode.h"
99
#include "eglimage.h"
100
#include "eglsync.h"
101
 
102
 
103
/**
104
 * Macros to help return an API entrypoint.
105
 *
106
 * These macros will unlock the display and record the error code.
107
 */
108
#define RETURN_EGL_ERROR(disp, err, ret)        \
109
   do {                                         \
110
      if (disp)                                 \
111
         _eglUnlockDisplay(disp);               \
112
      /* EGL error codes are non-zero */        \
113
      if (err)                                  \
114
         _eglError(err, __FUNCTION__);          \
115
      return ret;                               \
116
   } while (0)
117
 
118
#define RETURN_EGL_SUCCESS(disp, ret) \
119
   RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
120
 
121
/* record EGL_SUCCESS only when ret evaluates to true */
122
#define RETURN_EGL_EVAL(disp, ret) \
123
   RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
124
 
125
 
126
/*
127
 * A bunch of macros and checks to simplify error checking.
128
 */
129
 
130
#define _EGL_CHECK_DISPLAY(disp, ret, drv)         \
131
   do {                                            \
132
      drv = _eglCheckDisplay(disp, __FUNCTION__);  \
133
      if (!drv)                                    \
134
         RETURN_EGL_ERROR(disp, 0, ret);           \
135
   } while (0)
136
 
137
#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv)      \
138
   do {                                                   \
139
      drv = _eglCheck ## type(disp, obj, __FUNCTION__);   \
140
      if (!drv)                                           \
141
         RETURN_EGL_ERROR(disp, 0, ret);                  \
142
   } while (0)
143
 
144
#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
145
   _EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
146
 
147
#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
148
   _EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
149
 
150
#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
151
   _EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
152
 
153
#define _EGL_CHECK_SCREEN(disp, scrn, ret, drv) \
154
   _EGL_CHECK_OBJECT(disp, Screen, scrn, ret, drv)
155
 
156
#define _EGL_CHECK_MODE(disp, m, ret, drv) \
157
   _EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
158
 
159
#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
160
   _EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
161
 
162
 
163
static INLINE _EGLDriver *
164
_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
165
{
166
   if (!disp) {
167
      _eglError(EGL_BAD_DISPLAY, msg);
168
      return NULL;
169
   }
170
   if (!disp->Initialized) {
171
      _eglError(EGL_NOT_INITIALIZED, msg);
172
      return NULL;
173
   }
174
   return disp->Driver;
175
}
176
 
177
 
178
static INLINE _EGLDriver *
179
_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
180
{
181
   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
182
   if (!drv)
183
      return NULL;
184
   if (!surf) {
185
      _eglError(EGL_BAD_SURFACE, msg);
186
      return NULL;
187
   }
188
   return drv;
189
}
190
 
191
 
192
static INLINE _EGLDriver *
193
_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
194
{
195
   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
196
   if (!drv)
197
      return NULL;
198
   if (!context) {
199
      _eglError(EGL_BAD_CONTEXT, msg);
200
      return NULL;
201
   }
202
   return drv;
203
}
204
 
205
 
206
static INLINE _EGLDriver *
207
_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
208
{
209
   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
210
   if (!drv)
211
      return NULL;
212
   if (!conf) {
213
      _eglError(EGL_BAD_CONFIG, msg);
214
      return NULL;
215
   }
216
   return drv;
217
}
218
 
219
 
220
static INLINE _EGLDriver *
221
_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
222
{
223
   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
224
   if (!drv)
225
      return NULL;
226
   if (!s) {
227
      _eglError(EGL_BAD_PARAMETER, msg);
228
      return NULL;
229
   }
230
   return drv;
231
}
232
 
233
 
234
#ifdef EGL_MESA_screen_surface
235
 
236
 
237
static INLINE _EGLDriver *
238
_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
239
{
240
   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
241
   if (!drv)
242
      return NULL;
243
   if (!scrn) {
244
      _eglError(EGL_BAD_SCREEN_MESA, msg);
245
      return NULL;
246
   }
247
   return drv;
248
}
249
 
250
 
251
static INLINE _EGLDriver *
252
_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
253
{
254
   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
255
   if (!drv)
256
      return NULL;
257
   if (!m) {
258
      _eglError(EGL_BAD_MODE_MESA, msg);
259
      return NULL;
260
   }
261
   return drv;
262
}
263
 
264
 
265
#endif /* EGL_MESA_screen_surface */
266
 
267
 
268
/**
269
 * Lookup and lock a display.
270
 */
271
static INLINE _EGLDisplay *
272
_eglLockDisplay(EGLDisplay display)
273
{
274
   _EGLDisplay *dpy = _eglLookupDisplay(display);
275
   if (dpy)
276
      _eglLockMutex(&dpy->Mutex);
277
   return dpy;
278
}
279
 
280
 
281
/**
282
 * Unlock a display.
283
 */
284
static INLINE void
285
_eglUnlockDisplay(_EGLDisplay *dpy)
286
{
287
   _eglUnlockMutex(&dpy->Mutex);
288
}
289
 
290
 
291
/**
292
 * This is typically the first EGL function that an application calls.
293
 * It associates a private _EGLDisplay object to the native display.
294
 */
295
EGLDisplay EGLAPIENTRY
296
eglGetDisplay(EGLNativeDisplayType nativeDisplay)
297
{
298
   _EGLPlatformType plat = _eglGetNativePlatform(nativeDisplay);
299
   _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
300
   return _eglGetDisplayHandle(dpy);
301
}
302
 
303
 
304
/**
305
 * This is typically the second EGL function that an application calls.
306
 * Here we load/initialize the actual hardware driver.
307
 */
308
EGLBoolean EGLAPIENTRY
309
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
310
{
311
   _EGLDisplay *disp = _eglLockDisplay(dpy);
312
 
313
   if (!disp)
314
      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
315
 
316
   if (!disp->Initialized) {
317
      if (!_eglMatchDriver(disp, EGL_FALSE))
318
         RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
319
 
320
      /* limit to APIs supported by core */
321
      disp->ClientAPIs &= _EGL_API_ALL_BITS;
322
   }
323
 
324
   /* Update applications version of major and minor if not NULL */
325
   if ((major != NULL) && (minor != NULL)) {
326
      *major = disp->VersionMajor;
327
      *minor = disp->VersionMinor;
328
   }
329
 
330
   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
331
}
332
 
333
 
334
EGLBoolean EGLAPIENTRY
335
eglTerminate(EGLDisplay dpy)
336
{
337
   _EGLDisplay *disp = _eglLockDisplay(dpy);
338
 
339
   if (!disp)
340
      RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
341
 
342
   if (disp->Initialized) {
343
      _EGLDriver *drv = disp->Driver;
344
 
345
      drv->API.Terminate(drv, disp);
346
      /* do not reset disp->Driver */
347
      disp->Initialized = EGL_FALSE;
348
   }
349
 
350
   RETURN_EGL_SUCCESS(disp, EGL_TRUE);
351
}
352
 
353
 
354
const char * EGLAPIENTRY
355
eglQueryString(EGLDisplay dpy, EGLint name)
356
{
357
   _EGLDisplay *disp = _eglLockDisplay(dpy);
358
   _EGLDriver *drv;
359
   const char *ret;
360
 
361
   _EGL_CHECK_DISPLAY(disp, NULL, drv);
362
   ret = drv->API.QueryString(drv, disp, name);
363
 
364
   RETURN_EGL_EVAL(disp, ret);
365
}
366
 
367
 
368
EGLBoolean EGLAPIENTRY
369
eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
370
              EGLint config_size, EGLint *num_config)
371
{
372
   _EGLDisplay *disp = _eglLockDisplay(dpy);
373
   _EGLDriver *drv;
374
   EGLBoolean ret;
375
 
376
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
377
   ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
378
 
379
   RETURN_EGL_EVAL(disp, ret);
380
}
381
 
382
 
383
EGLBoolean EGLAPIENTRY
384
eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
385
                EGLint config_size, EGLint *num_config)
386
{
387
   _EGLDisplay *disp = _eglLockDisplay(dpy);
388
   _EGLDriver *drv;
389
   EGLBoolean ret;
390
 
391
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
392
   ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
393
                                config_size, num_config);
394
 
395
   RETURN_EGL_EVAL(disp, ret);
396
}
397
 
398
 
399
EGLBoolean EGLAPIENTRY
400
eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
401
                   EGLint attribute, EGLint *value)
402
{
403
   _EGLDisplay *disp = _eglLockDisplay(dpy);
404
   _EGLConfig *conf = _eglLookupConfig(config, disp);
405
   _EGLDriver *drv;
406
   EGLBoolean ret;
407
 
408
   _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
409
   ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
410
 
411
   RETURN_EGL_EVAL(disp, ret);
412
}
413
 
414
 
415
EGLContext EGLAPIENTRY
416
eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
417
                 const EGLint *attrib_list)
418
{
419
   _EGLDisplay *disp = _eglLockDisplay(dpy);
420
   _EGLConfig *conf = _eglLookupConfig(config, disp);
421
   _EGLContext *share = _eglLookupContext(share_list, disp);
422
   _EGLDriver *drv;
423
   _EGLContext *context;
424
   EGLContext ret;
425
 
426
   _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
427
 
428
   if (!config) {
429
      /* config may be NULL if surfaceless */
430
      if (!disp->Extensions.KHR_surfaceless_context)
431
         RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
432
   }
433
 
434
   if (!share && share_list != EGL_NO_CONTEXT)
435
      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
436
 
437
   context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
438
   ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
439
 
440
   RETURN_EGL_EVAL(disp, ret);
441
}
442
 
443
 
444
EGLBoolean EGLAPIENTRY
445
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
446
{
447
   _EGLDisplay *disp = _eglLockDisplay(dpy);
448
   _EGLContext *context = _eglLookupContext(ctx, disp);
449
   _EGLDriver *drv;
450
   EGLBoolean ret;
451
 
452
   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
453
   _eglUnlinkContext(context);
454
   ret = drv->API.DestroyContext(drv, disp, context);
455
 
456
   RETURN_EGL_EVAL(disp, ret);
457
}
458
 
459
 
460
EGLBoolean EGLAPIENTRY
461
eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
462
               EGLContext ctx)
463
{
464
   _EGLDisplay *disp = _eglLockDisplay(dpy);
465
   _EGLContext *context = _eglLookupContext(ctx, disp);
466
   _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
467
   _EGLSurface *read_surf = _eglLookupSurface(read, disp);
468
   _EGLDriver *drv;
469
   EGLBoolean ret;
470
 
471
   if (!disp)
472
      RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
473
   drv = disp->Driver;
474
 
475
   /* display is allowed to be uninitialized under certain condition */
476
   if (!disp->Initialized) {
477
      if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
478
          ctx != EGL_NO_CONTEXT)
479
         RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
480
   }
481
   if (!drv)
482
      RETURN_EGL_SUCCESS(disp, EGL_TRUE);
483
 
484
   if (!context && ctx != EGL_NO_CONTEXT)
485
      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
486
   if (!draw_surf || !read_surf) {
487
      /* surfaces may be NULL if surfaceless */
488
      if (!disp->Extensions.KHR_surfaceless_context)
489
         RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
490
 
491
      if ((!draw_surf && draw != EGL_NO_SURFACE) ||
492
          (!read_surf && read != EGL_NO_SURFACE))
493
         RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
494
      if (draw_surf || read_surf)
495
         RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
496
   }
497
 
498
   ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
499
 
500
   RETURN_EGL_EVAL(disp, ret);
501
}
502
 
503
 
504
EGLBoolean EGLAPIENTRY
505
eglQueryContext(EGLDisplay dpy, EGLContext ctx,
506
                EGLint attribute, EGLint *value)
507
{
508
   _EGLDisplay *disp = _eglLockDisplay(dpy);
509
   _EGLContext *context = _eglLookupContext(ctx, disp);
510
   _EGLDriver *drv;
511
   EGLBoolean ret;
512
 
513
   _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
514
   ret = drv->API.QueryContext(drv, disp, context, attribute, value);
515
 
516
   RETURN_EGL_EVAL(disp, ret);
517
}
518
 
519
 
520
EGLSurface EGLAPIENTRY
521
eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
522
                       EGLNativeWindowType window, const EGLint *attrib_list)
523
{
524
   _EGLDisplay *disp = _eglLockDisplay(dpy);
525
   _EGLConfig *conf = _eglLookupConfig(config, disp);
526
   _EGLDriver *drv;
527
   _EGLSurface *surf;
528
   EGLSurface ret;
529
 
530
   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
531
   if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
532
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
533
 
534
   surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
535
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
536
 
537
   RETURN_EGL_EVAL(disp, ret);
538
}
539
 
540
 
541
EGLSurface EGLAPIENTRY
542
eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
543
                       EGLNativePixmapType pixmap, const EGLint *attrib_list)
544
{
545
   _EGLDisplay *disp = _eglLockDisplay(dpy);
546
   _EGLConfig *conf = _eglLookupConfig(config, disp);
547
   _EGLDriver *drv;
548
   _EGLSurface *surf;
549
   EGLSurface ret;
550
 
551
   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
552
   if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
553
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
554
 
555
   surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
556
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
557
 
558
   RETURN_EGL_EVAL(disp, ret);
559
}
560
 
561
 
562
EGLSurface EGLAPIENTRY
563
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
564
                        const EGLint *attrib_list)
565
{
566
   _EGLDisplay *disp = _eglLockDisplay(dpy);
567
   _EGLConfig *conf = _eglLookupConfig(config, disp);
568
   _EGLDriver *drv;
569
   _EGLSurface *surf;
570
   EGLSurface ret;
571
 
572
   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
573
 
574
   surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
575
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
576
 
577
   RETURN_EGL_EVAL(disp, ret);
578
}
579
 
580
 
581
EGLBoolean EGLAPIENTRY
582
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
583
{
584
   _EGLDisplay *disp = _eglLockDisplay(dpy);
585
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
586
   _EGLDriver *drv;
587
   EGLBoolean ret;
588
 
589
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
590
   _eglUnlinkSurface(surf);
591
   ret = drv->API.DestroySurface(drv, disp, surf);
592
 
593
   RETURN_EGL_EVAL(disp, ret);
594
}
595
 
596
EGLBoolean EGLAPIENTRY
597
eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
598
                EGLint attribute, EGLint *value)
599
{
600
   _EGLDisplay *disp = _eglLockDisplay(dpy);
601
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
602
   _EGLDriver *drv;
603
   EGLBoolean ret;
604
 
605
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
606
   ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
607
 
608
   RETURN_EGL_EVAL(disp, ret);
609
}
610
 
611
EGLBoolean EGLAPIENTRY
612
eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
613
                 EGLint attribute, EGLint value)
614
{
615
   _EGLDisplay *disp = _eglLockDisplay(dpy);
616
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
617
   _EGLDriver *drv;
618
   EGLBoolean ret;
619
 
620
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
621
   ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
622
 
623
   RETURN_EGL_EVAL(disp, ret);
624
}
625
 
626
 
627
EGLBoolean EGLAPIENTRY
628
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
629
{
630
   _EGLDisplay *disp = _eglLockDisplay(dpy);
631
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
632
   _EGLDriver *drv;
633
   EGLBoolean ret;
634
 
635
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
636
   ret = drv->API.BindTexImage(drv, disp, surf, buffer);
637
 
638
   RETURN_EGL_EVAL(disp, ret);
639
}
640
 
641
 
642
EGLBoolean EGLAPIENTRY
643
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
644
{
645
   _EGLDisplay *disp = _eglLockDisplay(dpy);
646
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
647
   _EGLDriver *drv;
648
   EGLBoolean ret;
649
 
650
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
651
   ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
652
 
653
   RETURN_EGL_EVAL(disp, ret);
654
}
655
 
656
 
657
EGLBoolean EGLAPIENTRY
658
eglSwapInterval(EGLDisplay dpy, EGLint interval)
659
{
660
   _EGLDisplay *disp = _eglLockDisplay(dpy);
661
   _EGLContext *ctx = _eglGetCurrentContext();
662
   _EGLSurface *surf;
663
   _EGLDriver *drv;
664
   EGLBoolean ret;
665
 
666
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
667
 
668
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
669
       ctx->Resource.Display != disp)
670
      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
671
 
672
   surf = ctx->DrawSurface;
673
   if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
674
      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
675
 
676
   ret = drv->API.SwapInterval(drv, disp, surf, interval);
677
 
678
   RETURN_EGL_EVAL(disp, ret);
679
}
680
 
681
 
682
EGLBoolean EGLAPIENTRY
683
eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
684
{
685
   _EGLContext *ctx = _eglGetCurrentContext();
686
   _EGLDisplay *disp = _eglLockDisplay(dpy);
687
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
688
   _EGLDriver *drv;
689
   EGLBoolean ret;
690
 
691
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
692
 
693
   /* surface must be bound to current context in EGL 1.4 */
694
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
695
       surf != ctx->DrawSurface)
696
      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
697
 
698
   ret = drv->API.SwapBuffers(drv, disp, surf);
699
 
700
   RETURN_EGL_EVAL(disp, ret);
701
}
702
 
703
 
704
#ifdef EGL_EXT_swap_buffers_with_damage
705
 
706
EGLBoolean EGLAPIENTRY
707
eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
708
                            EGLint *rects, EGLint n_rects)
709
{
710
   _EGLContext *ctx = _eglGetCurrentContext();
711
   _EGLDisplay *disp = _eglLockDisplay(dpy);
712
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
713
   _EGLDriver *drv;
714
   EGLBoolean ret;
715
 
716
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
717
 
718
   /* surface must be bound to current context in EGL 1.4 */
719
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
720
       surf != ctx->DrawSurface)
721
      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
722
 
723
   if ((n_rects > 0 && rects == NULL) || n_rects < 0)
724
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
725
 
726
   ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
727
 
728
   RETURN_EGL_EVAL(disp, ret);
729
}
730
 
731
#endif /* EGL_EXT_swap_buffers_with_damage */
732
 
733
EGLBoolean EGLAPIENTRY
734
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
735
{
736
   _EGLDisplay *disp = _eglLockDisplay(dpy);
737
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
738
   _EGLDriver *drv;
739
   EGLBoolean ret;
740
 
741
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
742
   if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
743
      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
744
   ret = drv->API.CopyBuffers(drv, disp, surf, target);
745
 
746
   RETURN_EGL_EVAL(disp, ret);
747
}
748
 
749
 
750
EGLBoolean EGLAPIENTRY
751
eglWaitClient(void)
752
{
753
   _EGLContext *ctx = _eglGetCurrentContext();
754
   _EGLDisplay *disp;
755
   _EGLDriver *drv;
756
   EGLBoolean ret;
757
 
758
   if (!ctx)
759
      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
760
 
761
   disp = ctx->Resource.Display;
762
   _eglLockMutex(&disp->Mutex);
763
 
764
   /* let bad current context imply bad current surface */
765
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
766
       _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
767
      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
768
 
769
   /* a valid current context implies an initialized current display */
770
   assert(disp->Initialized);
771
   drv = disp->Driver;
772
   ret = drv->API.WaitClient(drv, disp, ctx);
773
 
774
   RETURN_EGL_EVAL(disp, ret);
775
}
776
 
777
 
778
EGLBoolean EGLAPIENTRY
779
eglWaitGL(void)
780
{
781
   _EGLThreadInfo *t = _eglGetCurrentThread();
782
   EGLint api_index = t->CurrentAPIIndex;
783
   EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API);
784
   EGLBoolean ret;
785
 
786
   if (api_index != es_index && _eglIsCurrentThreadDummy())
787
      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
788
 
789
   t->CurrentAPIIndex = es_index;
790
   ret = eglWaitClient();
791
   t->CurrentAPIIndex = api_index;
792
   return ret;
793
}
794
 
795
 
796
EGLBoolean EGLAPIENTRY
797
eglWaitNative(EGLint engine)
798
{
799
   _EGLContext *ctx = _eglGetCurrentContext();
800
   _EGLDisplay *disp;
801
   _EGLDriver *drv;
802
   EGLBoolean ret;
803
 
804
   if (!ctx)
805
      RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
806
 
807
   disp = ctx->Resource.Display;
808
   _eglLockMutex(&disp->Mutex);
809
 
810
   /* let bad current context imply bad current surface */
811
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
812
       _eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
813
      RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
814
 
815
   /* a valid current context implies an initialized current display */
816
   assert(disp->Initialized);
817
   drv = disp->Driver;
818
   ret = drv->API.WaitNative(drv, disp, engine);
819
 
820
   RETURN_EGL_EVAL(disp, ret);
821
}
822
 
823
 
824
EGLDisplay EGLAPIENTRY
825
eglGetCurrentDisplay(void)
826
{
827
   _EGLContext *ctx = _eglGetCurrentContext();
828
   EGLDisplay ret;
829
 
830
   ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
831
 
832
   RETURN_EGL_SUCCESS(NULL, ret);
833
}
834
 
835
 
836
EGLContext EGLAPIENTRY
837
eglGetCurrentContext(void)
838
{
839
   _EGLContext *ctx = _eglGetCurrentContext();
840
   EGLContext ret;
841
 
842
   ret = _eglGetContextHandle(ctx);
843
 
844
   RETURN_EGL_SUCCESS(NULL, ret);
845
}
846
 
847
 
848
EGLSurface EGLAPIENTRY
849
eglGetCurrentSurface(EGLint readdraw)
850
{
851
   _EGLContext *ctx = _eglGetCurrentContext();
852
   EGLint err = EGL_SUCCESS;
853
   _EGLSurface *surf;
854
   EGLSurface ret;
855
 
856
   if (!ctx)
857
      RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
858
 
859
   switch (readdraw) {
860
   case EGL_DRAW:
861
      surf = ctx->DrawSurface;
862
      break;
863
   case EGL_READ:
864
      surf = ctx->ReadSurface;
865
      break;
866
   default:
867
      surf = NULL;
868
      err = EGL_BAD_PARAMETER;
869
      break;
870
   }
871
 
872
   ret = _eglGetSurfaceHandle(surf);
873
 
874
   RETURN_EGL_ERROR(NULL, err, ret);
875
}
876
 
877
 
878
EGLint EGLAPIENTRY
879
eglGetError(void)
880
{
881
   _EGLThreadInfo *t = _eglGetCurrentThread();
882
   EGLint e = t->LastError;
883
   if (!_eglIsCurrentThreadDummy())
884
      t->LastError = EGL_SUCCESS;
885
   return e;
886
}
887
 
888
 
889
__eglMustCastToProperFunctionPointerType EGLAPIENTRY
890
eglGetProcAddress(const char *procname)
891
{
892
   static const struct {
893
      const char *name;
894
      _EGLProc function;
895
   } egl_functions[] = {
896
      /* core functions should not be queryable, but, well... */
897
#ifdef _EGL_GET_CORE_ADDRESSES
898
      /* alphabetical order */
899
      { "eglBindAPI", (_EGLProc) eglBindAPI },
900
      { "eglBindTexImage", (_EGLProc) eglBindTexImage },
901
      { "eglChooseConfig", (_EGLProc) eglChooseConfig },
902
      { "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
903
      { "eglCreateContext", (_EGLProc) eglCreateContext },
904
      { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer },
905
      { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
906
      { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
907
      { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
908
      { "eglDestroyContext", (_EGLProc) eglDestroyContext },
909
      { "eglDestroySurface", (_EGLProc) eglDestroySurface },
910
      { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
911
      { "eglGetConfigs", (_EGLProc) eglGetConfigs },
912
      { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
913
      { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
914
      { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
915
      { "eglGetDisplay", (_EGLProc) eglGetDisplay },
916
      { "eglGetError", (_EGLProc) eglGetError },
917
      { "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
918
      { "eglInitialize", (_EGLProc) eglInitialize },
919
      { "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
920
      { "eglQueryAPI", (_EGLProc) eglQueryAPI },
921
      { "eglQueryContext", (_EGLProc) eglQueryContext },
922
      { "eglQueryString", (_EGLProc) eglQueryString },
923
      { "eglQuerySurface", (_EGLProc) eglQuerySurface },
924
      { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
925
      { "eglReleaseThread", (_EGLProc) eglReleaseThread },
926
      { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
927
      { "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
928
      { "eglSwapInterval", (_EGLProc) eglSwapInterval },
929
      { "eglTerminate", (_EGLProc) eglTerminate },
930
      { "eglWaitClient", (_EGLProc) eglWaitClient },
931
      { "eglWaitGL", (_EGLProc) eglWaitGL },
932
      { "eglWaitNative", (_EGLProc) eglWaitNative },
933
#endif /* _EGL_GET_CORE_ADDRESSES */
934
#ifdef EGL_MESA_screen_surface
935
      { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },
936
      { "eglGetModesMESA", (_EGLProc) eglGetModesMESA },
937
      { "eglGetModeAttribMESA", (_EGLProc) eglGetModeAttribMESA },
938
      { "eglCopyContextMESA", (_EGLProc) eglCopyContextMESA },
939
      { "eglGetScreensMESA", (_EGLProc) eglGetScreensMESA },
940
      { "eglCreateScreenSurfaceMESA", (_EGLProc) eglCreateScreenSurfaceMESA },
941
      { "eglShowScreenSurfaceMESA", (_EGLProc) eglShowScreenSurfaceMESA },
942
      { "eglScreenPositionMESA", (_EGLProc) eglScreenPositionMESA },
943
      { "eglQueryScreenMESA", (_EGLProc) eglQueryScreenMESA },
944
      { "eglQueryScreenSurfaceMESA", (_EGLProc) eglQueryScreenSurfaceMESA },
945
      { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
946
      { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
947
#endif /* EGL_MESA_screen_surface */
948
#ifdef EGL_MESA_drm_display
949
      { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
950
#endif
951
      { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
952
      { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
953
      { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR },
954
      { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR },
955
      { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR },
956
      { "eglSignalSyncKHR", (_EGLProc) eglSignalSyncKHR },
957
      { "eglGetSyncAttribKHR", (_EGLProc) eglGetSyncAttribKHR },
958
#ifdef EGL_NOK_swap_region
959
      { "eglSwapBuffersRegionNOK", (_EGLProc) eglSwapBuffersRegionNOK },
960
#endif
961
#ifdef EGL_MESA_drm_image
962
      { "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
963
      { "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
964
#endif
965
#ifdef EGL_WL_bind_wayland_display
966
      { "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
967
      { "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
968
      { "eglQueryWaylandBufferWL", (_EGLProc) eglQueryWaylandBufferWL },
969
#endif
970
      { "eglPostSubBufferNV", (_EGLProc) eglPostSubBufferNV },
971
#ifdef EGL_EXT_swap_buffers_with_damage
972
      { "eglSwapBuffersWithDamageEXT", (_EGLProc) eglSwapBuffersWithDamageEXT },
973
#endif
974
      { NULL, NULL }
975
   };
976
   EGLint i;
977
   _EGLProc ret;
978
 
979
   if (!procname)
980
      RETURN_EGL_SUCCESS(NULL, NULL);
981
 
982
   ret = NULL;
983
   if (strncmp(procname, "egl", 3) == 0) {
984
      for (i = 0; egl_functions[i].name; i++) {
985
         if (strcmp(egl_functions[i].name, procname) == 0) {
986
            ret = egl_functions[i].function;
987
            break;
988
         }
989
      }
990
   }
991
   if (!ret)
992
      ret = _eglGetDriverProc(procname);
993
 
994
   RETURN_EGL_SUCCESS(NULL, ret);
995
}
996
 
997
 
998
#ifdef EGL_MESA_screen_surface
999
 
1000
 
1001
/*
1002
 * EGL_MESA_screen extension
1003
 */
1004
 
1005
EGLBoolean EGLAPIENTRY
1006
eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
1007
                  const EGLint *attrib_list, EGLModeMESA *modes,
1008
                  EGLint modes_size, EGLint *num_modes)
1009
{
1010
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1011
   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1012
   _EGLDriver *drv;
1013
   EGLBoolean ret;
1014
 
1015
   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1016
   ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
1017
         modes, modes_size, num_modes);
1018
 
1019
   RETURN_EGL_EVAL(disp, ret);
1020
}
1021
 
1022
 
1023
EGLBoolean EGLAPIENTRY
1024
eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
1025
                EGLint mode_size, EGLint *num_mode)
1026
{
1027
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1028
   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1029
   _EGLDriver *drv;
1030
   EGLBoolean ret;
1031
 
1032
   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1033
   ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
1034
 
1035
   RETURN_EGL_EVAL(disp, ret);
1036
}
1037
 
1038
 
1039
EGLBoolean EGLAPIENTRY
1040
eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
1041
                     EGLint attribute, EGLint *value)
1042
{
1043
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1044
   _EGLMode *m = _eglLookupMode(mode, disp);
1045
   _EGLDriver *drv;
1046
   EGLBoolean ret;
1047
 
1048
   _EGL_CHECK_MODE(disp, m, EGL_FALSE, drv);
1049
   ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
1050
 
1051
   RETURN_EGL_EVAL(disp, ret);
1052
}
1053
 
1054
 
1055
EGLBoolean EGLAPIENTRY
1056
eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
1057
                   EGLint mask)
1058
{
1059
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1060
   _EGLContext *source_context = _eglLookupContext(source, disp);
1061
   _EGLContext *dest_context = _eglLookupContext(dest, disp);
1062
   _EGLDriver *drv;
1063
   EGLBoolean ret;
1064
 
1065
   _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE, drv);
1066
   if (!dest_context)
1067
      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
1068
 
1069
   ret = drv->API.CopyContextMESA(drv, disp,
1070
         source_context, dest_context, mask);
1071
 
1072
   RETURN_EGL_EVAL(disp, ret);
1073
}
1074
 
1075
 
1076
EGLBoolean EGLAPIENTRY
1077
eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
1078
                  EGLint max_screens, EGLint *num_screens)
1079
{
1080
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1081
   _EGLDriver *drv;
1082
   EGLBoolean ret;
1083
 
1084
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1085
   ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens);
1086
 
1087
   RETURN_EGL_EVAL(disp, ret);
1088
}
1089
 
1090
 
1091
EGLSurface EGLAPIENTRY
1092
eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
1093
                           const EGLint *attrib_list)
1094
{
1095
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1096
   _EGLConfig *conf = _eglLookupConfig(config, disp);
1097
   _EGLDriver *drv;
1098
   _EGLSurface *surf;
1099
   EGLSurface ret;
1100
 
1101
   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1102
 
1103
   surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
1104
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1105
 
1106
   RETURN_EGL_EVAL(disp, ret);
1107
}
1108
 
1109
 
1110
EGLBoolean EGLAPIENTRY
1111
eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
1112
                         EGLSurface surface, EGLModeMESA mode)
1113
{
1114
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1115
   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1116
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1117
   _EGLMode *m = _eglLookupMode(mode, disp);
1118
   _EGLDriver *drv;
1119
   EGLBoolean ret;
1120
 
1121
   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1122
   if (!surf && surface != EGL_NO_SURFACE)
1123
      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1124
   if (!m && mode != EGL_NO_MODE_MESA)
1125
      RETURN_EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE);
1126
 
1127
   ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
1128
 
1129
   RETURN_EGL_EVAL(disp, ret);
1130
}
1131
 
1132
 
1133
EGLBoolean EGLAPIENTRY
1134
eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
1135
{
1136
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1137
   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1138
   _EGLDriver *drv;
1139
   EGLBoolean ret;
1140
 
1141
   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1142
   ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
1143
 
1144
   RETURN_EGL_EVAL(disp, ret);
1145
}
1146
 
1147
 
1148
EGLBoolean EGLAPIENTRY
1149
eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
1150
                   EGLint attribute, EGLint *value)
1151
{
1152
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1153
   _EGLScreen *scrn = _eglLookupScreen(screen, disp);
1154
   _EGLDriver *drv;
1155
   EGLBoolean ret;
1156
 
1157
   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1158
   ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
1159
 
1160
   RETURN_EGL_EVAL(disp, ret);
1161
}
1162
 
1163
 
1164
EGLBoolean EGLAPIENTRY
1165
eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
1166
                          EGLSurface *surface)
1167
{
1168
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1169
   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1170
   _EGLDriver *drv;
1171
   _EGLSurface *surf;
1172
   EGLBoolean ret;
1173
 
1174
   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1175
   ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf);
1176
   if (ret && surface)
1177
      *surface = _eglGetSurfaceHandle(surf);
1178
 
1179
   RETURN_EGL_EVAL(disp, ret);
1180
}
1181
 
1182
 
1183
EGLBoolean EGLAPIENTRY
1184
eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
1185
{
1186
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1187
   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
1188
   _EGLDriver *drv;
1189
   _EGLMode *m;
1190
   EGLBoolean ret;
1191
 
1192
   _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE, drv);
1193
   ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m);
1194
   if (ret && mode)
1195
      *mode = m->Handle;
1196
 
1197
   RETURN_EGL_EVAL(disp, ret);
1198
}
1199
 
1200
 
1201
const char * EGLAPIENTRY
1202
eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
1203
{
1204
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1205
   _EGLMode *m = _eglLookupMode(mode, disp);
1206
   _EGLDriver *drv;
1207
   const char *ret;
1208
 
1209
   _EGL_CHECK_MODE(disp, m, NULL, drv);
1210
   ret = drv->API.QueryModeStringMESA(drv, disp, m);
1211
 
1212
   RETURN_EGL_EVAL(disp, ret);
1213
}
1214
 
1215
 
1216
#endif /* EGL_MESA_screen_surface */
1217
 
1218
 
1219
#ifdef EGL_MESA_drm_display
1220
 
1221
EGLDisplay EGLAPIENTRY
1222
eglGetDRMDisplayMESA(int fd)
1223
{
1224
   _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) (intptr_t) fd);
1225
   return _eglGetDisplayHandle(dpy);
1226
}
1227
 
1228
#endif /* EGL_MESA_drm_display */
1229
 
1230
/**
1231
 ** EGL 1.2
1232
 **/
1233
 
1234
/**
1235
 * Specify the client API to use for subsequent calls including:
1236
 *  eglCreateContext()
1237
 *  eglGetCurrentContext()
1238
 *  eglGetCurrentDisplay()
1239
 *  eglGetCurrentSurface()
1240
 *  eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
1241
 *  eglWaitClient()
1242
 *  eglWaitNative()
1243
 * See section 3.7 "Rendering Context" in the EGL specification for details.
1244
 */
1245
EGLBoolean EGLAPIENTRY
1246
eglBindAPI(EGLenum api)
1247
{
1248
   _EGLThreadInfo *t = _eglGetCurrentThread();
1249
 
1250
   if (_eglIsCurrentThreadDummy())
1251
      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
1252
 
1253
   if (!_eglIsApiValid(api))
1254
      RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
1255
 
1256
   t->CurrentAPIIndex = _eglConvertApiToIndex(api);
1257
 
1258
   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1259
}
1260
 
1261
 
1262
/**
1263
 * Return the last value set with eglBindAPI().
1264
 */
1265
EGLenum EGLAPIENTRY
1266
eglQueryAPI(void)
1267
{
1268
   _EGLThreadInfo *t = _eglGetCurrentThread();
1269
   EGLenum ret;
1270
 
1271
   /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
1272
   ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
1273
 
1274
   RETURN_EGL_SUCCESS(NULL, ret);
1275
}
1276
 
1277
 
1278
EGLSurface EGLAPIENTRY
1279
eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
1280
                                 EGLClientBuffer buffer, EGLConfig config,
1281
                                 const EGLint *attrib_list)
1282
{
1283
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1284
   _EGLConfig *conf = _eglLookupConfig(config, disp);
1285
   _EGLDriver *drv;
1286
   _EGLSurface *surf;
1287
   EGLSurface ret;
1288
 
1289
   _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
1290
 
1291
   surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
1292
                                                 conf, attrib_list);
1293
   ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
1294
 
1295
   RETURN_EGL_EVAL(disp, ret);
1296
}
1297
 
1298
 
1299
EGLBoolean EGLAPIENTRY
1300
eglReleaseThread(void)
1301
{
1302
   /* unbind current contexts */
1303
   if (!_eglIsCurrentThreadDummy()) {
1304
      _EGLThreadInfo *t = _eglGetCurrentThread();
1305
      EGLint api_index = t->CurrentAPIIndex;
1306
      EGLint i;
1307
 
1308
      for (i = 0; i < _EGL_API_NUM_APIS; i++) {
1309
         _EGLContext *ctx = t->CurrentContexts[i];
1310
         if (ctx) {
1311
            _EGLDisplay *disp = ctx->Resource.Display;
1312
            _EGLDriver *drv;
1313
 
1314
            t->CurrentAPIIndex = i;
1315
 
1316
            _eglLockMutex(&disp->Mutex);
1317
            drv = disp->Driver;
1318
            (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
1319
            _eglUnlockMutex(&disp->Mutex);
1320
         }
1321
      }
1322
 
1323
      t->CurrentAPIIndex = api_index;
1324
   }
1325
 
1326
   _eglDestroyCurrentThread();
1327
 
1328
   RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
1329
}
1330
 
1331
 
1332
EGLImageKHR EGLAPIENTRY
1333
eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
1334
                  EGLClientBuffer buffer, const EGLint *attr_list)
1335
{
1336
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1337
   _EGLContext *context = _eglLookupContext(ctx, disp);
1338
   _EGLDriver *drv;
1339
   _EGLImage *img;
1340
   EGLImageKHR ret;
1341
 
1342
   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1343
   if (!disp->Extensions.KHR_image_base)
1344
      RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1345
   if (!context && ctx != EGL_NO_CONTEXT)
1346
      RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
1347
 
1348
   img = drv->API.CreateImageKHR(drv,
1349
         disp, context, target, buffer, attr_list);
1350
   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1351
 
1352
   RETURN_EGL_EVAL(disp, ret);
1353
}
1354
 
1355
 
1356
EGLBoolean EGLAPIENTRY
1357
eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
1358
{
1359
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1360
   _EGLImage *img = _eglLookupImage(image, disp);
1361
   _EGLDriver *drv;
1362
   EGLBoolean ret;
1363
 
1364
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1365
   if (!disp->Extensions.KHR_image_base)
1366
      RETURN_EGL_EVAL(disp, EGL_FALSE);
1367
   if (!img)
1368
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1369
 
1370
   _eglUnlinkImage(img);
1371
   ret = drv->API.DestroyImageKHR(drv, disp, img);
1372
 
1373
   RETURN_EGL_EVAL(disp, ret);
1374
}
1375
 
1376
 
1377
EGLSyncKHR EGLAPIENTRY
1378
eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
1379
{
1380
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1381
   _EGLDriver *drv;
1382
   _EGLSync *sync;
1383
   EGLSyncKHR ret;
1384
 
1385
   _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
1386
   if (!disp->Extensions.KHR_reusable_sync)
1387
      RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
1388
 
1389
   sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
1390
   ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
1391
 
1392
   RETURN_EGL_EVAL(disp, ret);
1393
}
1394
 
1395
 
1396
EGLBoolean EGLAPIENTRY
1397
eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
1398
{
1399
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1400
   _EGLSync *s = _eglLookupSync(sync, disp);
1401
   _EGLDriver *drv;
1402
   EGLBoolean ret;
1403
 
1404
   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1405
   assert(disp->Extensions.KHR_reusable_sync);
1406
 
1407
   _eglUnlinkSync(s);
1408
   ret = drv->API.DestroySyncKHR(drv, disp, s);
1409
 
1410
   RETURN_EGL_EVAL(disp, ret);
1411
}
1412
 
1413
 
1414
EGLint EGLAPIENTRY
1415
eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
1416
{
1417
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1418
   _EGLSync *s = _eglLookupSync(sync, disp);
1419
   _EGLDriver *drv;
1420
   EGLint ret;
1421
 
1422
   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1423
   assert(disp->Extensions.KHR_reusable_sync);
1424
   ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
1425
 
1426
   RETURN_EGL_EVAL(disp, ret);
1427
}
1428
 
1429
 
1430
EGLBoolean EGLAPIENTRY
1431
eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
1432
{
1433
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1434
   _EGLSync *s = _eglLookupSync(sync, disp);
1435
   _EGLDriver *drv;
1436
   EGLBoolean ret;
1437
 
1438
   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1439
   assert(disp->Extensions.KHR_reusable_sync);
1440
   ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
1441
 
1442
   RETURN_EGL_EVAL(disp, ret);
1443
}
1444
 
1445
 
1446
EGLBoolean EGLAPIENTRY
1447
eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
1448
{
1449
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1450
   _EGLSync *s = _eglLookupSync(sync, disp);
1451
   _EGLDriver *drv;
1452
   EGLBoolean ret;
1453
 
1454
   _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
1455
   assert(disp->Extensions.KHR_reusable_sync);
1456
   ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
1457
 
1458
   RETURN_EGL_EVAL(disp, ret);
1459
}
1460
 
1461
 
1462
#ifdef EGL_NOK_swap_region
1463
 
1464
EGLBoolean EGLAPIENTRY
1465
eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
1466
			EGLint numRects, const EGLint *rects)
1467
{
1468
   _EGLContext *ctx = _eglGetCurrentContext();
1469
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1470
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1471
   _EGLDriver *drv;
1472
   EGLBoolean ret;
1473
 
1474
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1475
 
1476
   if (!disp->Extensions.NOK_swap_region)
1477
      RETURN_EGL_EVAL(disp, EGL_FALSE);
1478
 
1479
   /* surface must be bound to current context in EGL 1.4 */
1480
   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
1481
       surf != ctx->DrawSurface)
1482
      RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
1483
 
1484
   ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
1485
 
1486
   RETURN_EGL_EVAL(disp, ret);
1487
}
1488
 
1489
#endif /* EGL_NOK_swap_region */
1490
 
1491
 
1492
#ifdef EGL_MESA_drm_image
1493
 
1494
EGLImageKHR EGLAPIENTRY
1495
eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
1496
{
1497
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1498
   _EGLDriver *drv;
1499
   _EGLImage *img;
1500
   EGLImageKHR ret;
1501
 
1502
   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1503
   if (!disp->Extensions.MESA_drm_image)
1504
      RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1505
 
1506
   img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
1507
   ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
1508
 
1509
   RETURN_EGL_EVAL(disp, ret);
1510
}
1511
 
1512
EGLBoolean EGLAPIENTRY
1513
eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
1514
		      EGLint *name, EGLint *handle, EGLint *stride)
1515
{
1516
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1517
   _EGLImage *img = _eglLookupImage(image, disp);
1518
   _EGLDriver *drv;
1519
   EGLBoolean ret;
1520
 
1521
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1522
   assert(disp->Extensions.MESA_drm_image);
1523
 
1524
   if (!img)
1525
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1526
 
1527
   ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
1528
 
1529
   RETURN_EGL_EVAL(disp, ret);
1530
}
1531
 
4494 Serge 1532
EGLImageKHR EGLAPIENTRY
1533
eglGetBufferImage(EGLDisplay dpy, EGLSurface surface, EGLint type)
1534
{
1535
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1536
   _EGLDriver *drv;
1537
   EGLImageKHR ret;
1538
 
1539
   _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
1540
   if (!disp->Extensions.MESA_drm_image)
1541
      RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
1542
 
1543
   ret = drv->API.GetImageFB(drv, disp, surface, type);
1544
 
1545
   RETURN_EGL_EVAL(disp, ret);
1546
}
1547
 
4358 Serge 1548
#endif
1549
 
1550
#ifdef EGL_WL_bind_wayland_display
1551
struct wl_display;
1552
 
1553
EGLBoolean EGLAPIENTRY
1554
eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1555
{
1556
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1557
   _EGLDriver *drv;
1558
   EGLBoolean ret;
1559
 
1560
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1561
   assert(disp->Extensions.WL_bind_wayland_display);
1562
 
1563
   if (!display)
1564
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1565
 
1566
   ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
1567
 
1568
   RETURN_EGL_EVAL(disp, ret);
1569
}
1570
 
1571
EGLBoolean EGLAPIENTRY
1572
eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
1573
{
1574
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1575
   _EGLDriver *drv;
1576
   EGLBoolean ret;
1577
 
1578
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1579
   assert(disp->Extensions.WL_bind_wayland_display);
1580
 
1581
   if (!display)
1582
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1583
 
1584
   ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
1585
 
1586
   RETURN_EGL_EVAL(disp, ret);
1587
}
1588
 
1589
EGLBoolean EGLAPIENTRY
1590
eglQueryWaylandBufferWL(EGLDisplay dpy,struct wl_buffer *buffer,
1591
                        EGLint attribute, EGLint *value)
1592
{
1593
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1594
   _EGLDriver *drv;
1595
   EGLBoolean ret;
1596
 
1597
   _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
1598
   assert(disp->Extensions.WL_bind_wayland_display);
1599
 
1600
   if (!buffer)
1601
      RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
1602
 
1603
   ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
1604
 
1605
   RETURN_EGL_EVAL(disp, ret);
1606
}
1607
#endif
1608
 
1609
 
1610
EGLBoolean EGLAPIENTRY
1611
eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
1612
                   EGLint x, EGLint y, EGLint width, EGLint height)
1613
{
1614
   _EGLDisplay *disp = _eglLockDisplay(dpy);
1615
   _EGLSurface *surf = _eglLookupSurface(surface, disp);
1616
   _EGLDriver *drv;
1617
   EGLBoolean ret;
1618
 
1619
   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
1620
 
1621
   if (!disp->Extensions.NV_post_sub_buffer)
1622
      RETURN_EGL_EVAL(disp, EGL_FALSE);
1623
 
1624
   ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
1625
 
1626
   RETURN_EGL_EVAL(disp, ret);
1627
}