2011-07-02 09:57:30 +01:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
s/Tungsten Graphics/VMware/
Tungsten Graphics Inc. was acquired by VMware Inc. in 2008. Leaving the
old copyright name is creating unnecessary confusion, hence this change.
This was the sed script I used:
$ cat tg2vmw.sed
# Run as:
#
# git reset --hard HEAD && find include scons src -type f -not -name 'sed*' -print0 | xargs -0 sed -i -f tg2vmw.sed
#
# Rename copyrights
s/Tungsten Gra\(ph\|hp\)ics,\? [iI]nc\.\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./g
/Copyright/s/Tungsten Graphics\(,\? [iI]nc\.\)\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./
s/TUNGSTEN GRAPHICS/VMWARE/g
# Rename emails
s/alanh@tungstengraphics.com/alanh@vmware.com/
s/jens@tungstengraphics.com/jowen@vmware.com/g
s/jrfonseca-at-tungstengraphics-dot-com/jfonseca-at-vmware-dot-com/
s/jrfonseca\?@tungstengraphics.com/jfonseca@vmware.com/g
s/keithw\?@tungstengraphics.com/keithw@vmware.com/g
s/michel@tungstengraphics.com/daenzer@vmware.com/g
s/thomas-at-tungstengraphics-dot-com/thellstom-at-vmware-dot-com/
s/zack@tungstengraphics.com/zackr@vmware.com/
# Remove dead links
s@Tungsten Graphics (http://www.tungstengraphics.com)@Tungsten Graphics@g
# C string src/gallium/state_trackers/vega/api_misc.c
s/"Tungsten Graphics, Inc"/"VMware, Inc"/
Reviewed-by: Brian Paul <brianp@vmware.com>
2014-01-17 16:27:50 +00:00
|
|
|
* Copyright 2008 VMware, Inc.
|
2011-07-02 09:57:30 +01:00
|
|
|
* Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
|
|
|
|
* Copyright 2010-2011 LunarG, Inc.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sub license, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the
|
|
|
|
* next paragraph) shall be included in all copies or substantial portions
|
|
|
|
* of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
|
2005-04-22 22:09:39 +01:00
|
|
|
/**
|
|
|
|
* Public EGL API entrypoints
|
|
|
|
*
|
|
|
|
* Generally, we use the EGLDisplay parameter as a key to lookup the
|
|
|
|
* appropriate device driver handle, then jump though the driver's
|
|
|
|
* dispatch table to handle the function.
|
|
|
|
*
|
|
|
|
* That allows us the option of supporting multiple, simultaneous,
|
|
|
|
* heterogeneous hardware devices in the future.
|
|
|
|
*
|
|
|
|
* The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
|
2009-09-30 08:08:34 +01:00
|
|
|
* opaque handles. Internal objects are linked to a display to
|
|
|
|
* create the handles.
|
2005-04-22 22:09:39 +01:00
|
|
|
*
|
2009-09-30 08:08:34 +01:00
|
|
|
* For each public API entry point, the opaque handles are looked up
|
|
|
|
* before being dispatched to the drivers. When it fails to look up
|
|
|
|
* a handle, one of
|
|
|
|
*
|
|
|
|
* EGL_BAD_DISPLAY
|
|
|
|
* EGL_BAD_CONFIG
|
|
|
|
* EGL_BAD_CONTEXT
|
|
|
|
* EGL_BAD_SURFACE
|
|
|
|
* EGL_BAD_SCREEN_MESA
|
|
|
|
* EGL_BAD_MODE_MESA
|
|
|
|
*
|
|
|
|
* is generated and the driver function is not called. An
|
|
|
|
* uninitialized EGLDisplay has no driver associated with it. When
|
|
|
|
* such display is detected,
|
|
|
|
*
|
|
|
|
* EGL_NOT_INITIALIZED
|
|
|
|
*
|
|
|
|
* is generated.
|
2005-04-22 22:09:39 +01:00
|
|
|
*
|
2009-10-15 04:08:33 +01:00
|
|
|
* Some of the entry points use current display, context, or surface
|
|
|
|
* implicitly. For such entry points, the implicit objects are also
|
|
|
|
* checked before calling the driver function. Other than the
|
|
|
|
* errors listed above,
|
|
|
|
*
|
|
|
|
* EGL_BAD_CURRENT_SURFACE
|
|
|
|
*
|
|
|
|
* may also be generated.
|
|
|
|
*
|
2005-04-22 22:09:39 +01:00
|
|
|
* Notes on naming conventions:
|
|
|
|
*
|
|
|
|
* eglFooBar - public EGL function
|
|
|
|
* EGL_FOO_BAR - public EGL token
|
|
|
|
* EGLDatatype - public EGL datatype
|
|
|
|
*
|
|
|
|
* _eglFooBar - private EGL function
|
|
|
|
* _EGLDatatype - private EGL datatype, typedef'd struct
|
|
|
|
* _egl_struct - private EGL struct, non-typedef'd
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2006-01-30 00:10:55 +00:00
|
|
|
#include <stdlib.h>
|
2005-04-22 22:09:39 +01:00
|
|
|
#include <string.h>
|
2015-02-28 16:35:22 +00:00
|
|
|
#include "c99_compat.h"
|
2015-03-06 16:54:55 +00:00
|
|
|
#include "c11/threads.h"
|
2017-05-04 18:55:36 +01:00
|
|
|
#include "util/macros.h"
|
2010-05-31 04:47:58 +01:00
|
|
|
|
2013-10-12 00:04:55 +01:00
|
|
|
#include "eglglobals.h"
|
2005-04-22 22:09:39 +01:00
|
|
|
#include "eglcontext.h"
|
|
|
|
#include "egldisplay.h"
|
|
|
|
#include "egltypedefs.h"
|
2010-01-29 01:00:30 +00:00
|
|
|
#include "eglcurrent.h"
|
2005-04-22 22:09:39 +01:00
|
|
|
#include "egldriver.h"
|
|
|
|
#include "eglsurface.h"
|
2009-08-11 10:09:39 +01:00
|
|
|
#include "eglconfig.h"
|
2009-08-15 15:58:13 +01:00
|
|
|
#include "eglimage.h"
|
2010-08-14 16:09:12 +01:00
|
|
|
#include "eglsync.h"
|
2005-04-22 22:09:39 +01:00
|
|
|
|
2017-07-07 02:40:53 +01:00
|
|
|
#include "GL/mesa_glinterop.h"
|
2005-04-22 22:09:39 +01:00
|
|
|
|
2010-02-17 07:22:03 +00:00
|
|
|
/**
|
|
|
|
* Macros to help return an API entrypoint.
|
2010-02-17 09:30:44 +00:00
|
|
|
*
|
|
|
|
* These macros will unlock the display and record the error code.
|
2010-02-17 07:22:03 +00:00
|
|
|
*/
|
2010-02-19 04:08:50 +00:00
|
|
|
#define RETURN_EGL_ERROR(disp, err, ret) \
|
|
|
|
do { \
|
2010-02-17 09:30:44 +00:00
|
|
|
if (disp) \
|
|
|
|
_eglUnlockDisplay(disp); \
|
2010-02-17 07:22:03 +00:00
|
|
|
/* EGL error codes are non-zero */ \
|
|
|
|
if (err) \
|
2015-02-28 16:39:10 +00:00
|
|
|
_eglError(err, __func__); \
|
2010-02-19 04:08:50 +00:00
|
|
|
return ret; \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define RETURN_EGL_SUCCESS(disp, ret) \
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_SUCCESS, ret)
|
|
|
|
|
2010-02-17 08:05:27 +00:00
|
|
|
/* record EGL_SUCCESS only when ret evaluates to true */
|
2010-02-19 04:08:50 +00:00
|
|
|
#define RETURN_EGL_EVAL(disp, ret) \
|
|
|
|
RETURN_EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret)
|
2010-02-17 07:22:03 +00:00
|
|
|
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
/*
|
2010-02-17 07:22:03 +00:00
|
|
|
* A bunch of macros and checks to simplify error checking.
|
|
|
|
*/
|
2010-02-19 04:08:50 +00:00
|
|
|
|
|
|
|
#define _EGL_CHECK_DISPLAY(disp, ret, drv) \
|
|
|
|
do { \
|
2015-02-28 16:39:10 +00:00
|
|
|
drv = _eglCheckDisplay(disp, __func__); \
|
2010-02-19 04:08:50 +00:00
|
|
|
if (!drv) \
|
|
|
|
RETURN_EGL_ERROR(disp, 0, ret); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define _EGL_CHECK_OBJECT(disp, type, obj, ret, drv) \
|
|
|
|
do { \
|
2015-02-28 16:39:10 +00:00
|
|
|
drv = _eglCheck ## type(disp, obj, __func__); \
|
2010-02-19 04:08:50 +00:00
|
|
|
if (!drv) \
|
|
|
|
RETURN_EGL_ERROR(disp, 0, ret); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define _EGL_CHECK_SURFACE(disp, surf, ret, drv) \
|
|
|
|
_EGL_CHECK_OBJECT(disp, Surface, surf, ret, drv)
|
|
|
|
|
|
|
|
#define _EGL_CHECK_CONTEXT(disp, context, ret, drv) \
|
|
|
|
_EGL_CHECK_OBJECT(disp, Context, context, ret, drv)
|
|
|
|
|
|
|
|
#define _EGL_CHECK_CONFIG(disp, conf, ret, drv) \
|
|
|
|
_EGL_CHECK_OBJECT(disp, Config, conf, ret, drv)
|
|
|
|
|
2010-08-14 16:09:12 +01:00
|
|
|
#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
|
|
|
|
_EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
|
2010-02-17 07:22:03 +00:00
|
|
|
|
|
|
|
|
2017-02-21 23:56:52 +00:00
|
|
|
struct _egl_entrypoint {
|
|
|
|
const char *name;
|
|
|
|
_EGLProc function;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-02-28 16:35:22 +00:00
|
|
|
static inline _EGLDriver *
|
2010-02-17 07:22:03 +00:00
|
|
|
_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
|
|
|
|
{
|
|
|
|
if (!disp) {
|
|
|
|
_eglError(EGL_BAD_DISPLAY, msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!disp->Initialized) {
|
|
|
|
_eglError(EGL_NOT_INITIALIZED, msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return disp->Driver;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-28 16:35:22 +00:00
|
|
|
static inline _EGLDriver *
|
2010-02-17 07:22:03 +00:00
|
|
|
_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
|
|
|
|
{
|
|
|
|
_EGLDriver *drv = _eglCheckDisplay(disp, msg);
|
|
|
|
if (!drv)
|
|
|
|
return NULL;
|
|
|
|
if (!surf) {
|
|
|
|
_eglError(EGL_BAD_SURFACE, msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return drv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-28 16:35:22 +00:00
|
|
|
static inline _EGLDriver *
|
2010-02-17 07:22:03 +00:00
|
|
|
_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
|
|
|
|
{
|
|
|
|
_EGLDriver *drv = _eglCheckDisplay(disp, msg);
|
|
|
|
if (!drv)
|
|
|
|
return NULL;
|
|
|
|
if (!context) {
|
|
|
|
_eglError(EGL_BAD_CONTEXT, msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return drv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-28 16:35:22 +00:00
|
|
|
static inline _EGLDriver *
|
2010-02-17 07:22:03 +00:00
|
|
|
_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
|
|
|
|
{
|
|
|
|
_EGLDriver *drv = _eglCheckDisplay(disp, msg);
|
|
|
|
if (!drv)
|
|
|
|
return NULL;
|
|
|
|
if (!conf) {
|
|
|
|
_eglError(EGL_BAD_CONFIG, msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return drv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-28 16:35:22 +00:00
|
|
|
static inline _EGLDriver *
|
2010-08-14 16:09:12 +01:00
|
|
|
_eglCheckSync(_EGLDisplay *disp, _EGLSync *s, const char *msg)
|
|
|
|
{
|
|
|
|
_EGLDriver *drv = _eglCheckDisplay(disp, msg);
|
|
|
|
if (!drv)
|
|
|
|
return NULL;
|
|
|
|
if (!s) {
|
|
|
|
_eglError(EGL_BAD_PARAMETER, msg);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return drv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-17 09:30:44 +00:00
|
|
|
/**
|
|
|
|
* Lookup and lock a display.
|
|
|
|
*/
|
2015-02-28 16:35:22 +00:00
|
|
|
static inline _EGLDisplay *
|
2010-02-17 09:30:44 +00:00
|
|
|
_eglLockDisplay(EGLDisplay display)
|
|
|
|
{
|
|
|
|
_EGLDisplay *dpy = _eglLookupDisplay(display);
|
|
|
|
if (dpy)
|
2015-03-06 16:54:55 +00:00
|
|
|
mtx_lock(&dpy->Mutex);
|
2010-02-17 09:30:44 +00:00
|
|
|
return dpy;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unlock a display.
|
|
|
|
*/
|
2015-02-28 16:35:22 +00:00
|
|
|
static inline void
|
2010-02-17 09:30:44 +00:00
|
|
|
_eglUnlockDisplay(_EGLDisplay *dpy)
|
|
|
|
{
|
2015-03-06 16:54:55 +00:00
|
|
|
mtx_unlock(&dpy->Mutex);
|
2010-02-17 09:30:44 +00:00
|
|
|
}
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
static EGLBoolean
|
|
|
|
_eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object)
|
|
|
|
{
|
|
|
|
_EGLThreadInfo *thr = _eglGetCurrentThread();
|
|
|
|
if (!_eglIsCurrentThreadDummy()) {
|
|
|
|
thr->CurrentFuncName = funcName;
|
|
|
|
thr->CurrentObjectLabel = NULL;
|
|
|
|
|
|
|
|
if (objectType == EGL_OBJECT_THREAD_KHR)
|
|
|
|
thr->CurrentObjectLabel = thr->Label;
|
|
|
|
else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp)
|
|
|
|
thr->CurrentObjectLabel = disp->Label;
|
|
|
|
else if (object)
|
|
|
|
thr->CurrentObjectLabel = object->Label;
|
|
|
|
|
|
|
|
return EGL_TRUE;
|
|
|
|
}
|
|
|
|
|
2017-09-07 17:03:50 +01:00
|
|
|
_eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
|
2016-09-12 22:50:40 +01:00
|
|
|
return EGL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define _EGL_FUNC_START(disp, objectType, object, ret) \
|
|
|
|
do { \
|
|
|
|
if (!_eglSetFuncName(__func__, disp, objectType, (_EGLResource *) object)) { \
|
|
|
|
if (disp) \
|
|
|
|
_eglUnlockDisplay(disp); \
|
|
|
|
return ret; \
|
|
|
|
} \
|
|
|
|
} while(0)
|
2010-02-17 09:30:44 +00:00
|
|
|
|
2016-09-27 21:27:17 +01:00
|
|
|
/**
|
|
|
|
* Convert an attribute list from EGLint[] to EGLAttrib[].
|
|
|
|
*
|
|
|
|
* Return an EGL error code. The output parameter out_attrib_list is modified
|
|
|
|
* only on success.
|
|
|
|
*/
|
2016-12-08 00:36:03 +00:00
|
|
|
static EGLint
|
2016-09-27 21:27:17 +01:00
|
|
|
_eglConvertIntsToAttribs(const EGLint *int_list, EGLAttrib **out_attrib_list)
|
|
|
|
{
|
|
|
|
size_t len = 0;
|
|
|
|
EGLAttrib *attrib_list;
|
|
|
|
|
|
|
|
if (int_list) {
|
|
|
|
while (int_list[2*len] != EGL_NONE)
|
|
|
|
++len;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len == 0) {
|
|
|
|
*out_attrib_list = NULL;
|
|
|
|
return EGL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (2*len + 1 > SIZE_MAX / sizeof(EGLAttrib))
|
|
|
|
return EGL_BAD_ALLOC;
|
|
|
|
|
|
|
|
attrib_list = malloc((2*len + 1) * sizeof(EGLAttrib));
|
|
|
|
if (!attrib_list)
|
|
|
|
return EGL_BAD_ALLOC;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < len; ++i) {
|
|
|
|
attrib_list[2*i + 0] = int_list[2*i + 0];
|
|
|
|
attrib_list[2*i + 1] = int_list[2*i + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
attrib_list[2*len] = EGL_NONE;
|
|
|
|
|
|
|
|
*out_attrib_list = attrib_list;
|
|
|
|
return EGL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-12 19:42:05 +01:00
|
|
|
static EGLint *
|
|
|
|
_eglConvertAttribsToInt(const EGLAttrib *attr_list)
|
|
|
|
{
|
|
|
|
EGLint *int_attribs = NULL;
|
|
|
|
|
|
|
|
/* Convert attributes from EGLAttrib[] to EGLint[] */
|
|
|
|
if (attr_list) {
|
|
|
|
int i, size = 0;
|
|
|
|
|
|
|
|
while (attr_list[size] != EGL_NONE)
|
|
|
|
size += 2;
|
|
|
|
|
|
|
|
size += 1; /* add space for EGL_NONE */
|
|
|
|
|
|
|
|
int_attribs = calloc(size, sizeof(int_attribs[0]));
|
|
|
|
if (!int_attribs)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++)
|
|
|
|
int_attribs[i] = attr_list[i];
|
|
|
|
}
|
|
|
|
return int_attribs;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-04-22 22:09:39 +01:00
|
|
|
/**
|
2008-05-27 23:48:23 +01:00
|
|
|
* This is typically the first EGL function that an application calls.
|
2010-02-17 10:39:27 +00:00
|
|
|
* It associates a private _EGLDisplay object to the native display.
|
2005-04-22 22:09:39 +01:00
|
|
|
*/
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLDisplay EGLAPIENTRY
|
2010-01-25 03:55:48 +00:00
|
|
|
eglGetDisplay(EGLNativeDisplayType nativeDisplay)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
egl/main: Stop using EGLNative types internally
Internally, much of the EGL code uses EGLNativeDisplayType,
EGLNativeWindowType, and EGLPixmapType. However, the EGLNative type
often does not match the variable's actual type.
The concept of EGLNative types are a bad match for Linux, as explained
below. And the EGL platform extensions don't use EGLNative types at all.
Those extensions attempt to solve cross-platform issues by moving the
EGL API away from the EGLNative types.
The core of the problem is that eglplatform.h can define each EGLNative
type once only, but Linux supports multiple EGL platforms.
To work around the problem, Mesa's eglplatform.h contains multiple
definitions of each EGLNative type, selected by feature macros. Mesa
expects EGL clients to set the feature macro approrpiately. But the
feature macros don't work when a single codebase must be built with
support for multiple EGL platforms, *such as Mesa itself*.
When building libEGL, autotools chooses the EGLNative typedefs based on
the first element of '--with-egl-platforms'. For example,
'--with-egl-platforms=x11,drm,wayland' defines the following:
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
typedef Pixmap EGLNativePixmapType;
Clearly, this doesn't work well for Wayland and GBM. Mesa works around
the problem by casting the EGLNative types to different things in
different files.
For sanity's sake, and to prepare for the EGL platform extensions, this
patch removes from egl/main and egl/dri2 all internal use of the
EGLNative types. It replaces them with 'void*' and checks each explicit
cast with a static assertion. Also, the patch touches egl_gallium the
minimal amount to keep it compatible with eglapi.h.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2014-01-07 22:54:51 +00:00
|
|
|
_EGLPlatformType plat;
|
|
|
|
_EGLDisplay *dpy;
|
|
|
|
void *native_display_ptr;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
|
|
|
|
|
egl/main: Stop using EGLNative types internally
Internally, much of the EGL code uses EGLNativeDisplayType,
EGLNativeWindowType, and EGLPixmapType. However, the EGLNative type
often does not match the variable's actual type.
The concept of EGLNative types are a bad match for Linux, as explained
below. And the EGL platform extensions don't use EGLNative types at all.
Those extensions attempt to solve cross-platform issues by moving the
EGL API away from the EGLNative types.
The core of the problem is that eglplatform.h can define each EGLNative
type once only, but Linux supports multiple EGL platforms.
To work around the problem, Mesa's eglplatform.h contains multiple
definitions of each EGLNative type, selected by feature macros. Mesa
expects EGL clients to set the feature macro approrpiately. But the
feature macros don't work when a single codebase must be built with
support for multiple EGL platforms, *such as Mesa itself*.
When building libEGL, autotools chooses the EGLNative typedefs based on
the first element of '--with-egl-platforms'. For example,
'--with-egl-platforms=x11,drm,wayland' defines the following:
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
typedef Pixmap EGLNativePixmapType;
Clearly, this doesn't work well for Wayland and GBM. Mesa works around
the problem by casting the EGLNative types to different things in
different files.
For sanity's sake, and to prepare for the EGL platform extensions, this
patch removes from egl/main and egl/dri2 all internal use of the
EGLNative types. It replaces them with 'void*' and checks each explicit
cast with a static assertion. Also, the patch touches egl_gallium the
minimal amount to keep it compatible with eglapi.h.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2014-01-07 22:54:51 +00:00
|
|
|
STATIC_ASSERT(sizeof(void*) == sizeof(nativeDisplay));
|
|
|
|
native_display_ptr = (void*) nativeDisplay;
|
|
|
|
|
|
|
|
plat = _eglGetNativePlatform(native_display_ptr);
|
|
|
|
dpy = _eglFindDisplay(plat, native_display_ptr);
|
2008-05-27 21:33:54 +01:00
|
|
|
return _eglGetDisplayHandle(dpy);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
2016-09-12 21:42:56 +01:00
|
|
|
static EGLDisplay
|
|
|
|
_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
|
2017-08-08 16:17:13 +01:00
|
|
|
const EGLint *attrib_list)
|
2014-01-23 15:26:10 +00:00
|
|
|
{
|
|
|
|
_EGLDisplay *dpy;
|
|
|
|
|
|
|
|
switch (platform) {
|
|
|
|
#ifdef HAVE_X11_PLATFORM
|
|
|
|
case EGL_PLATFORM_X11_EXT:
|
|
|
|
dpy = _eglGetX11Display((Display*) native_display, attrib_list);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_DRM_PLATFORM
|
|
|
|
case EGL_PLATFORM_GBM_MESA:
|
|
|
|
dpy = _eglGetGbmDisplay((struct gbm_device*) native_display,
|
|
|
|
attrib_list);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_WAYLAND_PLATFORM
|
|
|
|
case EGL_PLATFORM_WAYLAND_EXT:
|
|
|
|
dpy = _eglGetWaylandDisplay((struct wl_display*) native_display,
|
|
|
|
attrib_list);
|
|
|
|
break;
|
2016-10-12 23:48:15 +01:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SURFACELESS_PLATFORM
|
|
|
|
case EGL_PLATFORM_SURFACELESS_MESA:
|
|
|
|
dpy = _eglGetSurfacelessDisplay(native_display, attrib_list);
|
|
|
|
break;
|
2014-01-23 15:26:10 +00:00
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return _eglGetDisplayHandle(dpy);
|
|
|
|
}
|
2005-04-22 22:09:39 +01:00
|
|
|
|
2016-09-12 21:42:56 +01:00
|
|
|
static EGLDisplay EGLAPIENTRY
|
|
|
|
eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
|
|
|
|
const EGLint *attrib_list)
|
|
|
|
{
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
|
2016-09-12 21:42:56 +01:00
|
|
|
return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
|
|
|
|
}
|
|
|
|
|
2015-05-12 20:06:41 +01:00
|
|
|
EGLDisplay EGLAPIENTRY
|
|
|
|
eglGetPlatformDisplay(EGLenum platform, void *native_display,
|
|
|
|
const EGLAttrib *attrib_list)
|
|
|
|
{
|
|
|
|
EGLDisplay display;
|
2016-09-12 21:42:56 +01:00
|
|
|
EGLint *int_attribs;
|
2015-05-12 20:06:41 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_NO_DISPLAY);
|
|
|
|
|
2016-09-12 21:42:56 +01:00
|
|
|
int_attribs = _eglConvertAttribsToInt(attrib_list);
|
2015-05-12 20:06:41 +01:00
|
|
|
if (attrib_list && !int_attribs)
|
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
|
|
|
|
|
2016-09-12 21:42:56 +01:00
|
|
|
display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
|
2015-05-12 20:06:41 +01:00
|
|
|
free(int_attribs);
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
|
2015-03-10 18:41:57 +00:00
|
|
|
/**
|
|
|
|
* Copy the extension into the string and update the string pointer.
|
|
|
|
*/
|
|
|
|
static EGLint
|
|
|
|
_eglAppendExtension(char **str, const char *ext)
|
|
|
|
{
|
|
|
|
char *s = *str;
|
|
|
|
size_t len = strlen(ext);
|
|
|
|
|
|
|
|
if (s) {
|
|
|
|
memcpy(s, ext, len);
|
|
|
|
s[len++] = ' ';
|
|
|
|
s[len] = '\0';
|
|
|
|
|
|
|
|
*str += len;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (EGLint) len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Examine the individual extension enable/disable flags and recompute
|
|
|
|
* the driver's Extensions string.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
_eglCreateExtensionsString(_EGLDisplay *dpy)
|
|
|
|
{
|
|
|
|
#define _EGL_CHECK_EXTENSION(ext) \
|
|
|
|
do { \
|
|
|
|
if (dpy->Extensions.ext) { \
|
|
|
|
_eglAppendExtension(&exts, "EGL_" #ext); \
|
|
|
|
assert(exts <= dpy->ExtensionsString + _EGL_MAX_EXTENSIONS_LEN); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
char *exts = dpy->ExtensionsString;
|
|
|
|
|
2015-06-09 22:08:57 +01:00
|
|
|
/* Please keep these sorted alphabetically. */
|
2016-02-02 20:23:07 +00:00
|
|
|
_EGL_CHECK_EXTENSION(ANDROID_framebuffer_target);
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
|
2016-11-18 13:39:33 +00:00
|
|
|
_EGL_CHECK_EXTENSION(ANDROID_native_fence_sync);
|
2016-02-02 20:23:08 +00:00
|
|
|
_EGL_CHECK_EXTENSION(ANDROID_recordable);
|
2015-03-10 18:41:57 +00:00
|
|
|
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(CHROMIUM_sync_control);
|
2015-03-10 18:41:57 +00:00
|
|
|
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(EXT_buffer_age);
|
|
|
|
_EGL_CHECK_EXTENSION(EXT_create_context_robustness);
|
|
|
|
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
|
2017-05-30 12:53:40 +01:00
|
|
|
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
|
2015-03-10 18:41:57 +00:00
|
|
|
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_cl_event2);
|
2016-12-05 14:42:04 +00:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_config_attribs);
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_create_context);
|
2017-06-29 01:44:03 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_create_context_no_error);
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_fence_sync);
|
2015-03-10 18:41:57 +00:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_gl_colorspace);
|
|
|
|
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
|
2015-03-10 18:41:57 +00:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_gl_texture_2D_image);
|
|
|
|
_EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_gl_texture_cubemap_image);
|
|
|
|
if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
|
|
|
|
_eglAppendExtension(&exts, "EGL_KHR_image");
|
|
|
|
_EGL_CHECK_EXTENSION(KHR_image_base);
|
|
|
|
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
|
2016-09-09 17:25:34 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_no_config_context);
|
2017-06-09 15:43:34 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_partial_update);
|
2015-03-10 18:41:57 +00:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_reusable_sync);
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_surfaceless_context);
|
2016-10-10 17:33:17 +01:00
|
|
|
if (dpy->Extensions.EXT_swap_buffers_with_damage)
|
|
|
|
_eglAppendExtension(&exts, "EGL_KHR_swap_buffers_with_damage");
|
2015-04-10 11:04:18 +01:00
|
|
|
_EGL_CHECK_EXTENSION(KHR_wait_sync);
|
2015-03-10 18:41:57 +00:00
|
|
|
|
2016-09-09 17:25:34 +01:00
|
|
|
if (dpy->Extensions.KHR_no_config_context)
|
|
|
|
_eglAppendExtension(&exts, "EGL_MESA_configless_context");
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(MESA_drm_image);
|
|
|
|
_EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
|
2015-03-10 18:41:57 +00:00
|
|
|
|
|
|
|
_EGL_CHECK_EXTENSION(NOK_swap_region);
|
|
|
|
_EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
|
|
|
|
|
|
|
|
_EGL_CHECK_EXTENSION(NV_post_sub_buffer);
|
2014-03-03 03:57:16 +00:00
|
|
|
|
2015-06-09 22:08:57 +01:00
|
|
|
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
|
|
|
|
_EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
|
|
|
|
|
2015-03-10 18:41:57 +00:00
|
|
|
#undef _EGL_CHECK_EXTENSION
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eglCreateAPIsString(_EGLDisplay *dpy)
|
|
|
|
{
|
|
|
|
if (dpy->ClientAPIs & EGL_OPENGL_BIT)
|
|
|
|
strcat(dpy->ClientAPIsString, "OpenGL ");
|
|
|
|
|
2016-05-12 18:21:38 +01:00
|
|
|
if (dpy->ClientAPIs & EGL_OPENGL_ES_BIT ||
|
|
|
|
dpy->ClientAPIs & EGL_OPENGL_ES2_BIT ||
|
|
|
|
dpy->ClientAPIs & EGL_OPENGL_ES3_BIT_KHR) {
|
2015-03-10 18:41:57 +00:00
|
|
|
strcat(dpy->ClientAPIsString, "OpenGL_ES ");
|
2016-05-12 18:21:38 +01:00
|
|
|
}
|
2015-03-10 18:41:57 +00:00
|
|
|
|
|
|
|
if (dpy->ClientAPIs & EGL_OPENVG_BIT)
|
|
|
|
strcat(dpy->ClientAPIsString, "OpenVG ");
|
|
|
|
|
|
|
|
assert(strlen(dpy->ClientAPIsString) < sizeof(dpy->ClientAPIsString));
|
|
|
|
}
|
|
|
|
|
2015-05-11 21:16:52 +01:00
|
|
|
static void
|
|
|
|
_eglComputeVersion(_EGLDisplay *disp)
|
|
|
|
{
|
2015-05-12 15:40:29 +01:00
|
|
|
disp->Version = 14;
|
2015-05-11 21:18:04 +01:00
|
|
|
|
|
|
|
if (disp->Extensions.KHR_fence_sync &&
|
|
|
|
disp->Extensions.KHR_cl_event2 &&
|
|
|
|
disp->Extensions.KHR_wait_sync &&
|
|
|
|
disp->Extensions.KHR_image_base &&
|
|
|
|
disp->Extensions.KHR_gl_texture_2D_image &&
|
|
|
|
disp->Extensions.KHR_gl_texture_3D_image &&
|
|
|
|
disp->Extensions.KHR_gl_texture_cubemap_image &&
|
|
|
|
disp->Extensions.KHR_gl_renderbuffer_image &&
|
|
|
|
disp->Extensions.KHR_create_context &&
|
|
|
|
disp->Extensions.EXT_create_context_robustness &&
|
|
|
|
disp->Extensions.KHR_get_all_proc_addresses &&
|
|
|
|
disp->Extensions.KHR_gl_colorspace &&
|
|
|
|
disp->Extensions.KHR_surfaceless_context)
|
|
|
|
disp->Version = 15;
|
2015-05-11 21:16:52 +01:00
|
|
|
}
|
2015-03-10 18:41:57 +00:00
|
|
|
|
2008-05-27 23:48:23 +01:00
|
|
|
/**
|
|
|
|
* This is typically the second EGL function that an application calls.
|
|
|
|
* Here we load/initialize the actual hardware driver.
|
|
|
|
*/
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2008-08-06 20:40:03 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2009-08-11 10:09:39 +01:00
|
|
|
if (!disp)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2010-01-27 15:55:58 +00:00
|
|
|
if (!disp->Initialized) {
|
2010-07-04 08:55:12 +01:00
|
|
|
if (!_eglMatchDriver(disp, EGL_FALSE))
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2009-08-17 08:53:54 +01:00
|
|
|
/* limit to APIs supported by core */
|
2011-01-13 08:53:13 +00:00
|
|
|
disp->ClientAPIs &= _EGL_API_ALL_BITS;
|
2014-11-20 18:26:38 +00:00
|
|
|
|
|
|
|
/* EGL_KHR_get_all_proc_addresses is a corner-case extension. The spec
|
|
|
|
* classifies it as an EGL display extension, though conceptually it's an
|
|
|
|
* EGL client extension.
|
|
|
|
*
|
|
|
|
* From the EGL_KHR_get_all_proc_addresses spec:
|
|
|
|
*
|
|
|
|
* The EGL implementation must expose the name
|
|
|
|
* EGL_KHR_client_get_all_proc_addresses if and only if it exposes
|
|
|
|
* EGL_KHR_get_all_proc_addresses and supports
|
|
|
|
* EGL_EXT_client_extensions.
|
|
|
|
*
|
|
|
|
* Mesa unconditionally exposes both client extensions mentioned above,
|
|
|
|
* so the spec requires that each EGLDisplay unconditionally expose
|
|
|
|
* EGL_KHR_get_all_proc_addresses also.
|
|
|
|
*/
|
|
|
|
disp->Extensions.KHR_get_all_proc_addresses = EGL_TRUE;
|
2015-03-10 18:41:57 +00:00
|
|
|
|
2016-12-05 14:42:04 +00:00
|
|
|
/* Extensions is used to provide EGL 1.3 functionality for 1.2 aware
|
|
|
|
* programs. It is driver agnostic and handled in the main EGL code.
|
|
|
|
*/
|
|
|
|
disp->Extensions.KHR_config_attribs = EGL_TRUE;
|
|
|
|
|
2015-05-11 21:16:52 +01:00
|
|
|
_eglComputeVersion(disp);
|
2015-03-10 18:41:57 +00:00
|
|
|
_eglCreateExtensionsString(disp);
|
|
|
|
_eglCreateAPIsString(disp);
|
2015-07-14 00:19:54 +01:00
|
|
|
snprintf(disp->VersionString, sizeof(disp->VersionString),
|
2017-08-08 16:17:13 +01:00
|
|
|
"%d.%d (%s)", disp->Version / 10, disp->Version % 10,
|
|
|
|
disp->Driver->Name);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
2009-08-11 10:09:39 +01:00
|
|
|
|
|
|
|
/* Update applications version of major and minor if not NULL */
|
|
|
|
if ((major != NULL) && (minor != NULL)) {
|
2015-05-12 15:40:29 +01:00
|
|
|
*major = disp->Version / 10;
|
|
|
|
*minor = disp->Version % 10;
|
2009-08-11 10:09:39 +01:00
|
|
|
}
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(disp, EGL_TRUE);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglTerminate(EGLDisplay dpy)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2009-08-11 10:09:39 +01:00
|
|
|
if (!disp)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2010-01-27 15:55:58 +00:00
|
|
|
if (disp->Initialized) {
|
|
|
|
_EGLDriver *drv = disp->Driver;
|
|
|
|
|
2009-08-13 06:39:51 +01:00
|
|
|
drv->API.Terminate(drv, disp);
|
2010-01-27 15:55:58 +00:00
|
|
|
/* do not reset disp->Driver */
|
2015-03-16 05:21:55 +00:00
|
|
|
disp->ClientAPIsString[0] = 0;
|
2010-01-27 15:55:58 +00:00
|
|
|
disp->Initialized = EGL_FALSE;
|
2009-08-11 10:09:39 +01:00
|
|
|
}
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(disp, EGL_TRUE);
|
2009-08-11 10:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
const char * EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglQueryString(EGLDisplay dpy, EGLint name)
|
|
|
|
{
|
2013-10-12 00:04:55 +01:00
|
|
|
_EGLDisplay *disp;
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLDriver *drv;
|
|
|
|
|
2013-10-12 00:04:55 +01:00
|
|
|
if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
|
2017-01-04 18:31:58 +00:00
|
|
|
const char *ret = _eglGetClientExtensionString();
|
|
|
|
if (ret != NULL)
|
|
|
|
RETURN_EGL_SUCCESS(NULL, ret);
|
|
|
|
else
|
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
|
2013-10-12 00:04:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
disp = _eglLockDisplay(dpy);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, NULL);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, NULL, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2015-03-14 00:00:26 +00:00
|
|
|
switch (name) {
|
|
|
|
case EGL_VENDOR:
|
|
|
|
RETURN_EGL_SUCCESS(disp, _EGL_VENDOR_STRING);
|
|
|
|
case EGL_VERSION:
|
|
|
|
RETURN_EGL_SUCCESS(disp, disp->VersionString);
|
|
|
|
case EGL_EXTENSIONS:
|
|
|
|
RETURN_EGL_SUCCESS(disp, disp->ExtensionsString);
|
|
|
|
case EGL_CLIENT_APIS:
|
|
|
|
RETURN_EGL_SUCCESS(disp, disp->ClientAPIsString);
|
|
|
|
default:
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
|
|
|
|
}
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
|
|
|
|
EGLint config_size, EGLint *num_config)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
|
|
|
|
EGLint config_size, EGLint *num_config)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
|
2017-08-08 16:17:13 +01:00
|
|
|
config_size, num_config);
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
|
|
|
|
EGLint attribute, EGLint *value)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLConfig *conf = _eglLookupConfig(config, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_CONFIG(disp, conf, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLContext EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
|
|
|
|
const EGLint *attrib_list)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLConfig *conf = _eglLookupConfig(config, disp);
|
|
|
|
_EGLContext *share = _eglLookupContext(share_list, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLContext *context;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLContext ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_CONTEXT);
|
|
|
|
|
2010-09-23 19:42:15 +01:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
|
|
|
|
|
2016-10-20 12:11:16 +01:00
|
|
|
if (config != EGL_NO_CONFIG_KHR)
|
|
|
|
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv);
|
|
|
|
else if (!disp->Extensions.KHR_no_config_context)
|
2014-03-07 18:05:46 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
|
2010-06-03 03:48:06 +01:00
|
|
|
|
2010-02-17 08:05:27 +00:00
|
|
|
if (!share && share_list != EGL_NO_CONTEXT)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
|
|
|
context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (context) ? _eglLinkContext(context) : EGL_NO_CONTEXT;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLContext *context = _eglLookupContext(ctx, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
|
2009-08-11 10:09:39 +01:00
|
|
|
_eglUnlinkContext(context);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.DestroyContext(drv, disp, context);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
|
|
|
|
EGLContext ctx)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLContext *context = _eglLookupContext(ctx, disp);
|
|
|
|
_EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
|
|
|
|
_EGLSurface *read_surf = _eglLookupSurface(read, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
|
|
|
|
|
2010-01-27 15:51:54 +00:00
|
|
|
if (!disp)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
|
2010-01-27 15:51:54 +00:00
|
|
|
drv = disp->Driver;
|
|
|
|
|
|
|
|
/* display is allowed to be uninitialized under certain condition */
|
|
|
|
if (!disp->Initialized) {
|
|
|
|
if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE ||
|
|
|
|
ctx != EGL_NO_CONTEXT)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE);
|
2010-01-27 15:51:54 +00:00
|
|
|
}
|
2009-08-11 10:09:39 +01:00
|
|
|
if (!drv)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(disp, EGL_TRUE);
|
2010-01-27 15:51:54 +00:00
|
|
|
|
2009-08-11 10:09:39 +01:00
|
|
|
if (!context && ctx != EGL_NO_CONTEXT)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
|
2010-09-23 19:42:15 +01:00
|
|
|
if (!draw_surf || !read_surf) {
|
2014-03-20 07:36:34 +00:00
|
|
|
/* From the EGL 1.4 (20130211) spec:
|
|
|
|
*
|
|
|
|
* To release the current context without assigning a new one, set ctx
|
|
|
|
* to EGL_NO_CONTEXT and set draw and read to EGL_NO_SURFACE.
|
|
|
|
*/
|
|
|
|
if (!disp->Extensions.KHR_surfaceless_context && ctx != EGL_NO_CONTEXT)
|
2010-09-23 19:42:15 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
|
|
|
|
|
|
|
|
if ((!draw_surf && draw != EGL_NO_SURFACE) ||
|
|
|
|
(!read_surf && read != EGL_NO_SURFACE))
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
|
|
|
|
if (draw_surf || read_surf)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
|
|
|
|
}
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2017-05-05 01:46:33 +01:00
|
|
|
/* If a native window underlying either draw or read is no longer valid,
|
|
|
|
* an EGL_BAD_NATIVE_WINDOW error is generated.
|
|
|
|
*/
|
|
|
|
if (draw_surf && draw_surf->Lost)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
|
|
|
|
if (read_surf && read_surf->Lost)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
|
|
|
|
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglQueryContext(EGLDisplay dpy, EGLContext ctx,
|
|
|
|
EGLint attribute, EGLint *value)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLContext *context = _eglLookupContext(ctx, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_CONTEXT_KHR, context, EGL_FALSE);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_CONTEXT(disp, context, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.QueryContext(drv, disp, context, attribute, value);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-23 15:26:10 +00:00
|
|
|
static EGLSurface
|
|
|
|
_eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
|
|
|
|
void *native_window, const EGLint *attrib_list)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLConfig *conf = _eglLookupConfig(config, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLSurface *surf;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLSurface ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2014-06-03 22:00:13 +01:00
|
|
|
|
|
|
|
if (native_window == NULL)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
|
|
|
|
|
2016-10-12 23:48:15 +01:00
|
|
|
#ifdef HAVE_SURFACELESS_PLATFORM
|
2016-12-13 22:23:55 +00:00
|
|
|
if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
|
2016-10-12 23:48:15 +01:00
|
|
|
/* From the EGL_MESA_platform_surfaceless spec (v1):
|
|
|
|
*
|
|
|
|
* eglCreatePlatformWindowSurface fails when called with a <display>
|
|
|
|
* that belongs to the surfaceless platform. It returns
|
|
|
|
* EGL_NO_SURFACE and generates EGL_BAD_NATIVE_WINDOW. The
|
|
|
|
* justification for this unconditional failure is that the
|
|
|
|
* surfaceless platform has no native windows, and therefore the
|
|
|
|
* <native_window> parameter is always invalid.
|
|
|
|
*
|
|
|
|
* This check must occur before checking the EGLConfig, which emits
|
|
|
|
* EGL_BAD_CONFIG.
|
|
|
|
*/
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
|
|
|
|
|
2016-12-16 19:00:13 +00:00
|
|
|
if ((conf->SurfaceType & EGL_WINDOW_BIT) == 0)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
|
|
|
|
|
2014-01-23 15:26:10 +00:00
|
|
|
surf = drv->API.CreateWindowSurface(drv, disp, conf, native_window,
|
egl/main: Stop using EGLNative types internally
Internally, much of the EGL code uses EGLNativeDisplayType,
EGLNativeWindowType, and EGLPixmapType. However, the EGLNative type
often does not match the variable's actual type.
The concept of EGLNative types are a bad match for Linux, as explained
below. And the EGL platform extensions don't use EGLNative types at all.
Those extensions attempt to solve cross-platform issues by moving the
EGL API away from the EGLNative types.
The core of the problem is that eglplatform.h can define each EGLNative
type once only, but Linux supports multiple EGL platforms.
To work around the problem, Mesa's eglplatform.h contains multiple
definitions of each EGLNative type, selected by feature macros. Mesa
expects EGL clients to set the feature macro approrpiately. But the
feature macros don't work when a single codebase must be built with
support for multiple EGL platforms, *such as Mesa itself*.
When building libEGL, autotools chooses the EGLNative typedefs based on
the first element of '--with-egl-platforms'. For example,
'--with-egl-platforms=x11,drm,wayland' defines the following:
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
typedef Pixmap EGLNativePixmapType;
Clearly, this doesn't work well for Wayland and GBM. Mesa works around
the problem by casting the EGLNative types to different things in
different files.
For sanity's sake, and to prepare for the EGL platform extensions, this
patch removes from egl/main and egl/dri2 all internal use of the
EGLNative types. It replaces them with 'void*' and checks each explicit
cast with a static assertion. Also, the patch touches egl_gallium the
minimal amount to keep it compatible with eglapi.h.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2014-01-07 22:54:51 +00:00
|
|
|
attrib_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLSurface EGLAPIENTRY
|
2014-01-23 15:26:10 +00:00
|
|
|
eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
|
|
|
|
EGLNativeWindowType window, const EGLint *attrib_list)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2016-09-12 22:50:40 +01:00
|
|
|
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
2014-01-23 15:26:10 +00:00
|
|
|
STATIC_ASSERT(sizeof(void*) == sizeof(window));
|
|
|
|
return _eglCreateWindowSurfaceCommon(disp, config, (void*) window,
|
|
|
|
attrib_list);
|
|
|
|
}
|
|
|
|
|
2016-09-12 22:04:38 +01:00
|
|
|
static void *
|
2016-12-08 00:36:02 +00:00
|
|
|
_fixupNativeWindow(_EGLDisplay *disp, void *native_window)
|
2014-01-23 15:26:10 +00:00
|
|
|
{
|
|
|
|
#ifdef HAVE_X11_PLATFORM
|
2017-08-08 15:55:36 +01:00
|
|
|
if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
|
2014-01-23 15:26:10 +00:00
|
|
|
/* The `native_window` parameter for the X11 platform differs between
|
|
|
|
* eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
|
|
|
|
* eglCreateWindowSurface(), the type of `native_window` is an Xlib
|
|
|
|
* `Window`. In eglCreatePlatformWindowSurfaceEXT(), the type is
|
|
|
|
* `Window*`. Convert `Window*` to `Window` because that's what
|
|
|
|
* dri2_x11_create_window_surface() expects.
|
|
|
|
*/
|
2016-09-12 22:04:38 +01:00
|
|
|
return (void *)(* (Window*) native_window);
|
2014-01-23 15:26:10 +00:00
|
|
|
}
|
|
|
|
#endif
|
2016-09-12 22:04:38 +01:00
|
|
|
return native_window;
|
|
|
|
}
|
|
|
|
|
|
|
|
static EGLSurface EGLAPIENTRY
|
|
|
|
eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
|
|
|
|
void *native_window,
|
|
|
|
const EGLint *attrib_list)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
|
2016-12-08 00:36:02 +00:00
|
|
|
native_window = _fixupNativeWindow(disp, native_window);
|
2014-01-23 15:26:10 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
2014-01-23 15:26:10 +00:00
|
|
|
return _eglCreateWindowSurfaceCommon(disp, config, native_window,
|
|
|
|
attrib_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-12 20:06:41 +01:00
|
|
|
EGLSurface EGLAPIENTRY
|
|
|
|
eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
|
|
|
|
void *native_window,
|
|
|
|
const EGLAttrib *attrib_list)
|
|
|
|
{
|
2016-09-12 22:04:38 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2015-05-12 20:06:41 +01:00
|
|
|
EGLSurface surface;
|
2016-09-12 22:50:40 +01:00
|
|
|
EGLint *int_attribs;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
2015-05-12 20:06:41 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
int_attribs = _eglConvertAttribsToInt(attrib_list);
|
2015-05-12 20:06:41 +01:00
|
|
|
if (attrib_list && !int_attribs)
|
2016-09-12 22:50:40 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
|
2015-05-12 20:06:41 +01:00
|
|
|
|
2016-12-08 00:36:02 +00:00
|
|
|
native_window = _fixupNativeWindow(disp, native_window);
|
2016-09-12 22:04:38 +01:00
|
|
|
surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
|
|
|
|
int_attribs);
|
2015-05-12 20:06:41 +01:00
|
|
|
free(int_attribs);
|
|
|
|
return surface;
|
|
|
|
}
|
|
|
|
|
2016-09-12 22:25:56 +01:00
|
|
|
static void *
|
2016-12-08 00:36:02 +00:00
|
|
|
_fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
|
2016-09-12 22:25:56 +01:00
|
|
|
{
|
|
|
|
#ifdef HAVE_X11_PLATFORM
|
2017-08-08 16:17:13 +01:00
|
|
|
/* The `native_pixmap` parameter for the X11 platform differs between
|
|
|
|
* eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
|
|
|
|
* eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
|
|
|
|
* `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
|
|
|
|
* `Pixmap*`. Convert `Pixmap*` to `Pixmap` because that's what
|
|
|
|
* dri2_x11_create_pixmap_surface() expects.
|
|
|
|
*/
|
2017-08-08 15:55:36 +01:00
|
|
|
if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
|
2016-09-12 22:25:56 +01:00
|
|
|
return (void *)(* (Pixmap*) native_pixmap);
|
|
|
|
#endif
|
|
|
|
return native_pixmap;
|
|
|
|
}
|
2015-05-12 20:06:41 +01:00
|
|
|
|
2014-01-23 15:26:10 +00:00
|
|
|
static EGLSurface
|
|
|
|
_eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
|
|
|
|
void *native_pixmap, const EGLint *attrib_list)
|
|
|
|
{
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLConfig *conf = _eglLookupConfig(config, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLSurface *surf;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLSurface ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-10-12 23:48:15 +01:00
|
|
|
#if HAVE_SURFACELESS_PLATFORM
|
2016-12-13 22:23:55 +00:00
|
|
|
if (disp && disp->Platform == _EGL_PLATFORM_SURFACELESS) {
|
2016-10-12 23:48:15 +01:00
|
|
|
/* From the EGL_MESA_platform_surfaceless spec (v1):
|
|
|
|
*
|
|
|
|
* [Like eglCreatePlatformWindowSurface,] eglCreatePlatformPixmapSurface
|
|
|
|
* also fails when called with a <display> that belongs to the
|
|
|
|
* surfaceless platform. It returns EGL_NO_SURFACE and generates
|
|
|
|
* EGL_BAD_NATIVE_PIXMAP.
|
|
|
|
*
|
|
|
|
* This check must occur before checking the EGLConfig, which emits
|
|
|
|
* EGL_BAD_CONFIG.
|
|
|
|
*/
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
|
2016-12-16 19:00:13 +00:00
|
|
|
|
|
|
|
if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
|
|
|
|
|
2017-08-05 00:25:48 +01:00
|
|
|
if (native_pixmap == NULL)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
|
|
|
|
|
2014-01-23 15:26:10 +00:00
|
|
|
surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
|
egl/main: Stop using EGLNative types internally
Internally, much of the EGL code uses EGLNativeDisplayType,
EGLNativeWindowType, and EGLPixmapType. However, the EGLNative type
often does not match the variable's actual type.
The concept of EGLNative types are a bad match for Linux, as explained
below. And the EGL platform extensions don't use EGLNative types at all.
Those extensions attempt to solve cross-platform issues by moving the
EGL API away from the EGLNative types.
The core of the problem is that eglplatform.h can define each EGLNative
type once only, but Linux supports multiple EGL platforms.
To work around the problem, Mesa's eglplatform.h contains multiple
definitions of each EGLNative type, selected by feature macros. Mesa
expects EGL clients to set the feature macro approrpiately. But the
feature macros don't work when a single codebase must be built with
support for multiple EGL platforms, *such as Mesa itself*.
When building libEGL, autotools chooses the EGLNative typedefs based on
the first element of '--with-egl-platforms'. For example,
'--with-egl-platforms=x11,drm,wayland' defines the following:
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
typedef Pixmap EGLNativePixmapType;
Clearly, this doesn't work well for Wayland and GBM. Mesa works around
the problem by casting the EGLNative types to different things in
different files.
For sanity's sake, and to prepare for the EGL platform extensions, this
patch removes from egl/main and egl/dri2 all internal use of the
EGLNative types. It replaces them with 'void*' and checks each explicit
cast with a static assertion. Also, the patch touches egl_gallium the
minimal amount to keep it compatible with eglapi.h.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2014-01-07 22:54:51 +00:00
|
|
|
attrib_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-23 15:26:10 +00:00
|
|
|
EGLSurface EGLAPIENTRY
|
|
|
|
eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
|
|
|
|
EGLNativePixmapType pixmap, const EGLint *attrib_list)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2016-09-12 22:50:40 +01:00
|
|
|
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
2014-01-23 15:26:10 +00:00
|
|
|
STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
|
|
|
|
return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
|
2017-08-08 16:17:13 +01:00
|
|
|
attrib_list);
|
2014-01-23 15:26:10 +00:00
|
|
|
}
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLSurface EGLAPIENTRY
|
2014-01-23 15:26:10 +00:00
|
|
|
eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
|
2017-08-08 16:17:13 +01:00
|
|
|
void *native_pixmap,
|
|
|
|
const EGLint *attrib_list)
|
2014-01-23 15:26:10 +00:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
2016-12-08 00:36:02 +00:00
|
|
|
native_pixmap = _fixupNativePixmap(disp, native_pixmap);
|
2014-01-23 15:26:10 +00:00
|
|
|
return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
|
|
|
|
attrib_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-12 20:06:41 +01:00
|
|
|
EGLSurface EGLAPIENTRY
|
|
|
|
eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
|
|
|
|
void *native_pixmap,
|
|
|
|
const EGLAttrib *attrib_list)
|
|
|
|
{
|
2016-09-12 22:25:56 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2015-05-12 20:06:41 +01:00
|
|
|
EGLSurface surface;
|
2016-09-12 22:50:40 +01:00
|
|
|
EGLint *int_attribs;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
2015-05-12 20:06:41 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
int_attribs = _eglConvertAttribsToInt(attrib_list);
|
2015-05-12 20:06:41 +01:00
|
|
|
if (attrib_list && !int_attribs)
|
2016-09-12 22:50:40 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_SURFACE);
|
2015-05-12 20:06:41 +01:00
|
|
|
|
2016-12-08 00:36:02 +00:00
|
|
|
native_pixmap = _fixupNativePixmap(disp, native_pixmap);
|
2016-09-12 22:25:56 +01:00
|
|
|
surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
|
|
|
|
int_attribs);
|
2015-05-12 20:06:41 +01:00
|
|
|
free(int_attribs);
|
|
|
|
return surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLSurface EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
|
|
|
|
const EGLint *attrib_list)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLConfig *conf = _eglLookupConfig(config, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLSurface *surf;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLSurface ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-12-16 19:00:13 +00:00
|
|
|
if ((conf->SurfaceType & EGL_PBUFFER_BIT) == 0)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
|
|
|
|
|
2009-08-11 10:09:39 +01:00
|
|
|
surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
2009-08-11 10:09:39 +01:00
|
|
|
_eglUnlinkSurface(surf);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.DestroySurface(drv, disp, surf);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
|
|
|
|
EGLint attribute, EGLint *value)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.QuerySurface(drv, disp, surf, attribute, value);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
|
|
|
|
EGLint attribute, EGLint value)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.BindTexImage(drv, disp, surf, buffer);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglSwapInterval(EGLDisplay dpy, EGLint interval)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2009-10-15 04:08:48 +01:00
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGLSurface *surf = ctx ? ctx->DrawSurface : NULL;
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
2009-10-15 04:08:48 +01:00
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
|
|
|
|
ctx->Resource.Display != disp)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE);
|
2009-10-15 04:08:48 +01:00
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
|
2009-10-15 04:08:48 +01:00
|
|
|
|
2017-07-31 14:49:31 +01:00
|
|
|
interval = CLAMP(interval,
|
|
|
|
surf->Config->MinSwapInterval,
|
|
|
|
surf->Config->MaxSwapInterval);
|
|
|
|
|
2017-08-02 17:25:44 +01:00
|
|
|
if (surf->SwapInterval != interval)
|
2017-07-31 14:49:31 +01:00
|
|
|
ret = drv->API.SwapInterval(drv, disp, surf, interval);
|
|
|
|
else
|
|
|
|
ret = EGL_TRUE;
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
surf->SwapInterval = interval;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2009-08-11 10:09:39 +01:00
|
|
|
eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2009-10-15 04:08:33 +01:00
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
2009-10-15 04:08:33 +01:00
|
|
|
|
|
|
|
/* surface must be bound to current context in EGL 1.4 */
|
2014-12-22 15:10:13 +00:00
|
|
|
#ifndef _EGL_BUILT_IN_DRIVER_HAIKU
|
2010-10-23 05:52:26 +01:00
|
|
|
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
|
|
|
|
surf != ctx->DrawSurface)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
|
2014-12-22 15:10:13 +00:00
|
|
|
#endif
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2017-05-05 01:46:33 +01:00
|
|
|
/* From the EGL 1.5 spec:
|
|
|
|
*
|
|
|
|
* If eglSwapBuffers is called and the native window associated with
|
|
|
|
* surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
|
|
|
|
* generated.
|
|
|
|
*/
|
|
|
|
if (surf->Lost)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
|
|
|
|
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.SwapBuffers(drv, disp, surf);
|
2009-10-15 04:08:33 +01:00
|
|
|
|
2017-06-09 15:43:34 +01:00
|
|
|
/* EGL_KHR_partial_update
|
|
|
|
* Frame boundary successfully reached,
|
|
|
|
* reset damage region and reset BufferAgeRead
|
|
|
|
*/
|
|
|
|
if (ret) {
|
|
|
|
surf->SetDamageRegionCalled = EGL_FALSE;
|
|
|
|
surf->BufferAgeRead = EGL_FALSE;
|
|
|
|
}
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-10 17:33:17 +01:00
|
|
|
static EGLBoolean
|
2016-11-16 22:29:53 +00:00
|
|
|
_eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
|
|
|
|
EGLint *rects, EGLint n_rects)
|
2013-04-25 13:41:42 +01:00
|
|
|
{
|
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
|
|
|
|
|
|
|
/* surface must be bound to current context in EGL 1.4 */
|
|
|
|
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
|
|
|
|
surf != ctx->DrawSurface)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
|
|
|
|
|
|
|
|
if ((n_rects > 0 && rects == NULL) || n_rects < 0)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
|
|
|
|
|
2017-06-09 15:43:34 +01:00
|
|
|
/* EGL_KHR_partial_update
|
|
|
|
* Frame boundary successfully reached,
|
|
|
|
* reset damage region and reset BufferAgeRead
|
|
|
|
*/
|
|
|
|
if (ret) {
|
|
|
|
surf->SetDamageRegionCalled = EGL_FALSE;
|
|
|
|
surf->BufferAgeRead = EGL_FALSE;
|
|
|
|
}
|
|
|
|
|
2013-04-25 13:41:42 +01:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2016-10-10 17:33:17 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglSwapBuffersWithDamageEXT(EGLDisplay dpy, EGLSurface surface,
|
|
|
|
EGLint *rects, EGLint n_rects)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2016-11-16 22:29:53 +00:00
|
|
|
return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
|
2016-10-10 17:33:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
|
|
|
|
EGLint *rects, EGLint n_rects)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
2016-11-16 22:29:53 +00:00
|
|
|
return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
|
2016-10-10 17:33:17 +01:00
|
|
|
}
|
|
|
|
|
2017-06-09 15:43:34 +01:00
|
|
|
/**
|
|
|
|
* If the width of the passed rect is greater than the surface's
|
|
|
|
* width then it is clamped to the width of the surface. Same with
|
|
|
|
* height.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf,
|
|
|
|
EGLint *rects, EGLint n_rects)
|
|
|
|
{
|
|
|
|
EGLint i;
|
|
|
|
EGLint surf_height = surf->Height;
|
|
|
|
EGLint surf_width = surf->Width;
|
|
|
|
|
|
|
|
for (i = 0; i < (4 * n_rects); i += 4) {
|
|
|
|
EGLint x, y, rect_width, rect_height;
|
|
|
|
x = rects[i];
|
|
|
|
y = rects[i + 1];
|
|
|
|
rect_width = rects[i + 2];
|
|
|
|
rect_height = rects[i + 3];
|
|
|
|
|
|
|
|
if (rect_width > surf_width - x)
|
|
|
|
rects[i + 2] = surf_width - x;
|
|
|
|
|
|
|
|
if (rect_height > surf_height - y)
|
|
|
|
rects[i + 3] = surf_height - y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
|
|
|
|
EGLint *rects, EGLint n_rects)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
|
|
|
|
|
|
|
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
|
|
|
|
surf->Type != EGL_WINDOW_BIT ||
|
|
|
|
ctx->DrawSurface != surf ||
|
|
|
|
surf->SwapBehavior != EGL_BUFFER_DESTROYED)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
|
|
|
|
|
|
|
|
/* If the damage region is already set or
|
|
|
|
* buffer age is not queried between
|
|
|
|
* frame boundaries, throw bad access error
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
|
|
|
|
|
|
|
|
_eglSetDamageRegionKHRClampRects(disp, surf, rects, n_rects);
|
|
|
|
ret = drv->API.SetDamageRegion(drv, disp, surf, rects, n_rects);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
surf->SetDamageRegionCalled = EGL_TRUE;
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2010-01-25 03:55:48 +00:00
|
|
|
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2010-02-17 07:43:47 +00:00
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
egl/main: Stop using EGLNative types internally
Internally, much of the EGL code uses EGLNativeDisplayType,
EGLNativeWindowType, and EGLPixmapType. However, the EGLNative type
often does not match the variable's actual type.
The concept of EGLNative types are a bad match for Linux, as explained
below. And the EGL platform extensions don't use EGLNative types at all.
Those extensions attempt to solve cross-platform issues by moving the
EGL API away from the EGLNative types.
The core of the problem is that eglplatform.h can define each EGLNative
type once only, but Linux supports multiple EGL platforms.
To work around the problem, Mesa's eglplatform.h contains multiple
definitions of each EGLNative type, selected by feature macros. Mesa
expects EGL clients to set the feature macro approrpiately. But the
feature macros don't work when a single codebase must be built with
support for multiple EGL platforms, *such as Mesa itself*.
When building libEGL, autotools chooses the EGLNative typedefs based on
the first element of '--with-egl-platforms'. For example,
'--with-egl-platforms=x11,drm,wayland' defines the following:
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
typedef Pixmap EGLNativePixmapType;
Clearly, this doesn't work well for Wayland and GBM. Mesa works around
the problem by casting the EGLNative types to different things in
different files.
For sanity's sake, and to prepare for the EGL platform extensions, this
patch removes from egl/main and egl/dri2 all internal use of the
EGLNative types. It replaces them with 'void*' and checks each explicit
cast with a static assertion. Also, the patch touches egl_gallium the
minimal amount to keep it compatible with eglapi.h.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2014-01-07 22:54:51 +00:00
|
|
|
void *native_pixmap_ptr;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
egl/main: Stop using EGLNative types internally
Internally, much of the EGL code uses EGLNativeDisplayType,
EGLNativeWindowType, and EGLPixmapType. However, the EGLNative type
often does not match the variable's actual type.
The concept of EGLNative types are a bad match for Linux, as explained
below. And the EGL platform extensions don't use EGLNative types at all.
Those extensions attempt to solve cross-platform issues by moving the
EGL API away from the EGLNative types.
The core of the problem is that eglplatform.h can define each EGLNative
type once only, but Linux supports multiple EGL platforms.
To work around the problem, Mesa's eglplatform.h contains multiple
definitions of each EGLNative type, selected by feature macros. Mesa
expects EGL clients to set the feature macro approrpiately. But the
feature macros don't work when a single codebase must be built with
support for multiple EGL platforms, *such as Mesa itself*.
When building libEGL, autotools chooses the EGLNative typedefs based on
the first element of '--with-egl-platforms'. For example,
'--with-egl-platforms=x11,drm,wayland' defines the following:
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
typedef Pixmap EGLNativePixmapType;
Clearly, this doesn't work well for Wayland and GBM. Mesa works around
the problem by casting the EGLNative types to different things in
different files.
For sanity's sake, and to prepare for the EGL platform extensions, this
patch removes from egl/main and egl/dri2 all internal use of the
EGLNative types. It replaces them with 'void*' and checks each explicit
cast with a static assertion. Also, the patch touches egl_gallium the
minimal amount to keep it compatible with eglapi.h.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2014-01-07 22:54:51 +00:00
|
|
|
STATIC_ASSERT(sizeof(void*) == sizeof(target));
|
|
|
|
native_pixmap_ptr = (void*) target;
|
2010-02-17 07:43:47 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
2011-08-09 13:23:18 +01:00
|
|
|
if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
|
2010-06-17 10:14:03 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
|
egl/main: Stop using EGLNative types internally
Internally, much of the EGL code uses EGLNativeDisplayType,
EGLNativeWindowType, and EGLPixmapType. However, the EGLNative type
often does not match the variable's actual type.
The concept of EGLNative types are a bad match for Linux, as explained
below. And the EGL platform extensions don't use EGLNative types at all.
Those extensions attempt to solve cross-platform issues by moving the
EGL API away from the EGLNative types.
The core of the problem is that eglplatform.h can define each EGLNative
type once only, but Linux supports multiple EGL platforms.
To work around the problem, Mesa's eglplatform.h contains multiple
definitions of each EGLNative type, selected by feature macros. Mesa
expects EGL clients to set the feature macro approrpiately. But the
feature macros don't work when a single codebase must be built with
support for multiple EGL platforms, *such as Mesa itself*.
When building libEGL, autotools chooses the EGLNative typedefs based on
the first element of '--with-egl-platforms'. For example,
'--with-egl-platforms=x11,drm,wayland' defines the following:
typedef Display* EGLNativeDisplayType;
typedef Window EGLNativeWindowType;
typedef Pixmap EGLNativePixmapType;
Clearly, this doesn't work well for Wayland and GBM. Mesa works around
the problem by casting the EGLNative types to different things in
different files.
For sanity's sake, and to prepare for the EGL platform extensions, this
patch removes from egl/main and egl/dri2 all internal use of the
EGLNative types. It replaces them with 'void*' and checks each explicit
cast with a static assertion. Also, the patch touches egl_gallium the
minimal amount to keep it compatible with eglapi.h.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
2014-01-07 22:54:51 +00:00
|
|
|
ret = drv->API.CopyBuffers(drv, disp, surf, native_pixmap_ptr);
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-12 22:35:22 +01:00
|
|
|
static EGLBoolean
|
|
|
|
_eglWaitClientCommon(void)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2009-09-28 07:12:39 +01:00
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
|
|
|
_EGLDisplay *disp;
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2009-09-28 07:12:39 +01:00
|
|
|
if (!ctx)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2010-01-24 12:32:34 +00:00
|
|
|
disp = ctx->Resource.Display;
|
2015-03-06 16:54:55 +00:00
|
|
|
mtx_lock(&disp->Mutex);
|
2010-02-17 09:30:44 +00:00
|
|
|
|
|
|
|
/* let bad current context imply bad current surface */
|
2010-10-23 05:52:26 +01:00
|
|
|
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
|
|
|
|
_eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
|
2010-02-17 08:05:27 +00:00
|
|
|
|
|
|
|
/* a valid current context implies an initialized current display */
|
2010-01-27 15:55:58 +00:00
|
|
|
assert(disp->Initialized);
|
2009-08-11 10:09:39 +01:00
|
|
|
drv = disp->Driver;
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.WaitClient(drv, disp, ctx);
|
2009-09-28 07:12:39 +01:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2009-09-28 07:12:39 +01:00
|
|
|
}
|
|
|
|
|
2016-09-12 22:35:22 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
|
|
|
eglWaitClient(void)
|
|
|
|
{
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
|
2016-09-12 22:35:22 +01:00
|
|
|
return _eglWaitClientCommon();
|
|
|
|
}
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2009-09-28 07:12:39 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
|
|
|
eglWaitGL(void)
|
|
|
|
{
|
2016-07-08 22:21:17 +01:00
|
|
|
/* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_CONTEXT_KHR, _eglGetCurrentContext(), EGL_FALSE);
|
2016-09-12 22:35:22 +01:00
|
|
|
return _eglWaitClientCommon();
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglWaitNative(EGLint engine)
|
|
|
|
{
|
2009-09-28 07:12:39 +01:00
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
|
|
|
_EGLDisplay *disp;
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2009-09-28 07:12:39 +01:00
|
|
|
if (!ctx)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2010-02-17 09:30:44 +00:00
|
|
|
disp = ctx->Resource.Display;
|
2015-03-06 16:54:55 +00:00
|
|
|
mtx_lock(&disp->Mutex);
|
2010-02-17 09:30:44 +00:00
|
|
|
|
2009-09-28 07:12:39 +01:00
|
|
|
/* let bad current context imply bad current surface */
|
2010-10-23 05:52:26 +01:00
|
|
|
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
|
|
|
|
_eglGetSurfaceHandle(ctx->DrawSurface) == EGL_NO_SURFACE)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
|
2010-02-17 08:05:27 +00:00
|
|
|
|
|
|
|
/* a valid current context implies an initialized current display */
|
2010-01-27 15:55:58 +00:00
|
|
|
assert(disp->Initialized);
|
2009-08-11 10:09:39 +01:00
|
|
|
drv = disp->Driver;
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.WaitNative(drv, disp, engine);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLDisplay EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglGetCurrentDisplay(void)
|
|
|
|
{
|
2010-01-26 09:13:51 +00:00
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLDisplay ret;
|
|
|
|
|
|
|
|
ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY;
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLContext EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglGetCurrentContext(void)
|
|
|
|
{
|
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLContext ret;
|
|
|
|
|
|
|
|
ret = _eglGetContextHandle(ctx);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLSurface EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglGetCurrentSurface(EGLint readdraw)
|
|
|
|
{
|
2009-09-30 08:34:45 +01:00
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLint err = EGL_SUCCESS;
|
2009-09-30 08:34:45 +01:00
|
|
|
_EGLSurface *surf;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLSurface ret;
|
2009-09-30 08:34:45 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_NO_SURFACE);
|
|
|
|
|
2009-09-30 08:34:45 +01:00
|
|
|
if (!ctx)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, EGL_NO_SURFACE);
|
2009-09-30 08:34:45 +01:00
|
|
|
|
|
|
|
switch (readdraw) {
|
|
|
|
case EGL_DRAW:
|
|
|
|
surf = ctx->DrawSurface;
|
|
|
|
break;
|
|
|
|
case EGL_READ:
|
|
|
|
surf = ctx->ReadSurface;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
surf = NULL;
|
2010-02-17 08:05:27 +00:00
|
|
|
err = EGL_BAD_PARAMETER;
|
2009-09-30 08:34:45 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = _eglGetSurfaceHandle(surf);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(NULL, err, ret);
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-27 20:45:41 +01:00
|
|
|
EGLint EGLAPIENTRY
|
2005-04-22 22:09:39 +01:00
|
|
|
eglGetError(void)
|
|
|
|
{
|
2005-12-10 17:54:00 +00:00
|
|
|
_EGLThreadInfo *t = _eglGetCurrentThread();
|
|
|
|
EGLint e = t->LastError;
|
2009-07-17 18:41:02 +01:00
|
|
|
if (!_eglIsCurrentThreadDummy())
|
|
|
|
t->LastError = EGL_SUCCESS;
|
2005-04-22 22:09:39 +01:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-01-30 00:10:55 +00:00
|
|
|
/**
|
|
|
|
** EGL 1.2
|
|
|
|
**/
|
|
|
|
|
2008-05-30 20:45:40 +01:00
|
|
|
/**
|
|
|
|
* Specify the client API to use for subsequent calls including:
|
|
|
|
* eglCreateContext()
|
|
|
|
* eglGetCurrentContext()
|
|
|
|
* eglGetCurrentDisplay()
|
|
|
|
* eglGetCurrentSurface()
|
|
|
|
* eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
|
|
|
|
* eglWaitClient()
|
|
|
|
* eglWaitNative()
|
|
|
|
* See section 3.7 "Rendering Context" in the EGL specification for details.
|
|
|
|
*/
|
2010-07-03 00:38:07 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2006-01-30 00:10:55 +00:00
|
|
|
eglBindAPI(EGLenum api)
|
|
|
|
{
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGLThreadInfo *t;
|
2006-01-30 00:10:55 +00:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
|
|
|
|
|
|
|
|
t = _eglGetCurrentThread();
|
2009-07-17 18:41:02 +01:00
|
|
|
if (_eglIsCurrentThreadDummy())
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
|
2009-07-17 18:41:02 +01:00
|
|
|
|
2009-07-17 18:42:04 +01:00
|
|
|
if (!_eglIsApiValid(api))
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
|
2009-07-17 18:42:04 +01:00
|
|
|
|
2016-07-08 22:21:17 +01:00
|
|
|
t->CurrentAPI = api;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
|
2006-01-30 00:10:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-30 20:45:40 +01:00
|
|
|
/**
|
|
|
|
* Return the last value set with eglBindAPI().
|
|
|
|
*/
|
2010-07-03 00:38:07 +01:00
|
|
|
EGLenum EGLAPIENTRY
|
2008-05-30 20:45:40 +01:00
|
|
|
eglQueryAPI(void)
|
|
|
|
{
|
|
|
|
_EGLThreadInfo *t = _eglGetCurrentThread();
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLenum ret;
|
|
|
|
|
|
|
|
/* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
|
2016-07-08 22:21:17 +01:00
|
|
|
ret = t->CurrentAPI;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, ret);
|
2008-05-30 20:45:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-03 00:38:07 +01:00
|
|
|
EGLSurface EGLAPIENTRY
|
2006-01-30 00:10:55 +00:00
|
|
|
eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
|
|
|
|
EGLClientBuffer buffer, EGLConfig config,
|
|
|
|
const EGLint *attrib_list)
|
|
|
|
{
|
2010-02-17 09:30:44 +00:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2009-08-11 10:09:39 +01:00
|
|
|
_EGLConfig *conf = _eglLookupConfig(config, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLSurface *surf;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLSurface ret;
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
|
2009-08-11 10:09:39 +01:00
|
|
|
|
|
|
|
surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
|
|
|
|
conf, attrib_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2006-01-30 00:10:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-03 00:38:07 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
2006-01-30 00:10:55 +00:00
|
|
|
eglReleaseThread(void)
|
|
|
|
{
|
2010-01-26 09:22:21 +00:00
|
|
|
/* unbind current contexts */
|
2009-08-11 10:09:39 +01:00
|
|
|
if (!_eglIsCurrentThreadDummy()) {
|
2010-01-26 09:22:21 +00:00
|
|
|
_EGLThreadInfo *t = _eglGetCurrentThread();
|
2016-07-08 22:21:17 +01:00
|
|
|
_EGLContext *ctx = t->CurrentContext;
|
2016-09-12 22:50:40 +01:00
|
|
|
|
|
|
|
_EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2016-07-08 22:21:17 +01:00
|
|
|
if (ctx) {
|
|
|
|
_EGLDisplay *disp = ctx->Resource.Display;
|
|
|
|
_EGLDriver *drv;
|
|
|
|
|
|
|
|
mtx_lock(&disp->Mutex);
|
|
|
|
drv = disp->Driver;
|
|
|
|
(void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
|
|
|
|
mtx_unlock(&disp->Mutex);
|
|
|
|
}
|
2006-01-30 00:10:55 +00:00
|
|
|
}
|
2009-08-11 10:09:39 +01:00
|
|
|
|
2009-07-17 18:41:02 +01:00
|
|
|
_eglDestroyCurrentThread();
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
|
2006-01-30 00:10:55 +00:00
|
|
|
}
|
2005-05-13 19:31:35 +01:00
|
|
|
|
|
|
|
|
2016-09-12 22:38:13 +01:00
|
|
|
static EGLImage
|
|
|
|
_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
|
2017-08-08 16:17:13 +01:00
|
|
|
EGLClientBuffer buffer, const EGLint *attr_list)
|
2009-08-15 15:58:13 +01:00
|
|
|
{
|
|
|
|
_EGLContext *context = _eglLookupContext(ctx, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLImage *img;
|
2015-05-12 16:34:57 +01:00
|
|
|
EGLImage ret;
|
2009-08-15 15:58:13 +01:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
|
2010-09-23 19:42:15 +01:00
|
|
|
if (!disp->Extensions.KHR_image_base)
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
|
2010-02-17 08:05:27 +00:00
|
|
|
if (!context && ctx != EGL_NO_CONTEXT)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
|
2013-03-22 12:31:01 +00:00
|
|
|
/* "If <target> is EGL_LINUX_DMA_BUF_EXT, <dpy> must be a valid display,
|
|
|
|
* <ctx> must be EGL_NO_CONTEXT..."
|
|
|
|
*/
|
|
|
|
if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
|
2009-08-15 15:58:13 +01:00
|
|
|
|
2017-08-08 16:17:13 +01:00
|
|
|
img = drv->API.CreateImageKHR(drv, disp, context, target,
|
|
|
|
buffer, attr_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
|
2010-02-17 08:05:27 +00:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2009-08-15 15:58:13 +01:00
|
|
|
}
|
|
|
|
|
2016-09-12 22:38:13 +01:00
|
|
|
static EGLImage EGLAPIENTRY
|
|
|
|
eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
|
|
|
|
EGLClientBuffer buffer, const EGLint *attr_list)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
|
2016-09-12 22:38:13 +01:00
|
|
|
return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
|
|
|
|
}
|
|
|
|
|
2009-08-15 15:58:13 +01:00
|
|
|
|
2015-05-12 19:42:05 +01:00
|
|
|
EGLImage EGLAPIENTRY
|
|
|
|
eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
|
|
|
|
EGLClientBuffer buffer, const EGLAttrib *attr_list)
|
|
|
|
{
|
2016-09-12 22:38:13 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2015-05-12 19:42:05 +01:00
|
|
|
EGLImage image;
|
2016-09-12 22:50:40 +01:00
|
|
|
EGLint *int_attribs;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_IMAGE_KHR);
|
2015-05-12 19:42:05 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
int_attribs = _eglConvertAttribsToInt(attr_list);
|
2015-05-12 19:42:05 +01:00
|
|
|
if (attr_list && !int_attribs)
|
2016-09-12 22:38:13 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
|
2015-05-12 19:42:05 +01:00
|
|
|
|
2016-09-12 22:38:13 +01:00
|
|
|
image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
|
2015-05-12 19:42:05 +01:00
|
|
|
free(int_attribs);
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-21 23:56:44 +00:00
|
|
|
static EGLBoolean
|
|
|
|
_eglDestroyImageCommon(_EGLDisplay *disp, _EGLImage *img)
|
2009-08-15 15:58:13 +01:00
|
|
|
{
|
|
|
|
_EGLDriver *drv;
|
2010-02-17 08:05:27 +00:00
|
|
|
EGLBoolean ret;
|
2009-08-15 15:58:13 +01:00
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
2010-09-23 19:42:15 +01:00
|
|
|
if (!disp->Extensions.KHR_image_base)
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_FALSE);
|
2009-08-15 15:58:13 +01:00
|
|
|
if (!img)
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
2009-08-15 15:58:13 +01:00
|
|
|
|
|
|
|
_eglUnlinkImage(img);
|
2010-02-17 08:05:27 +00:00
|
|
|
ret = drv->API.DestroyImageKHR(drv, disp, img);
|
|
|
|
|
2010-02-19 04:08:50 +00:00
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2009-08-15 15:58:13 +01:00
|
|
|
}
|
|
|
|
|
2017-02-21 23:56:44 +00:00
|
|
|
EGLBoolean EGLAPIENTRY
|
|
|
|
eglDestroyImage(EGLDisplay dpy, EGLImage image)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLImage *img = _eglLookupImage(image, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
|
|
|
|
return _eglDestroyImageCommon(disp, img);
|
|
|
|
}
|
|
|
|
|
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglDestroyImageKHR(EGLDisplay dpy, EGLImage image)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLImage *img = _eglLookupImage(image, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
|
|
|
|
return _eglDestroyImageCommon(disp, img);
|
|
|
|
}
|
|
|
|
|
2009-08-15 15:58:13 +01:00
|
|
|
|
2015-05-12 16:34:57 +01:00
|
|
|
static EGLSync
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
|
|
|
|
EGLBoolean orig_is_EGLAttrib,
|
2015-05-12 20:41:32 +01:00
|
|
|
EGLenum invalid_type_error)
|
2010-08-14 16:09:12 +01:00
|
|
|
{
|
2015-04-10 09:56:02 +01:00
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
2010-08-14 16:09:12 +01:00
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLSync *sync;
|
2015-05-12 16:34:57 +01:00
|
|
|
EGLSync ret;
|
2010-08-14 16:09:12 +01:00
|
|
|
|
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
|
2015-04-10 09:56:02 +01:00
|
|
|
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
if (!disp->Extensions.KHR_cl_event2 && orig_is_EGLAttrib) {
|
2016-09-27 21:27:12 +01:00
|
|
|
/* There exist two EGLAttrib variants of eglCreateSync*:
|
|
|
|
* eglCreateSync64KHR which requires EGL_KHR_cl_event2, and eglCreateSync
|
|
|
|
* which requires EGL 1.5. Here we use the presence of EGL_KHR_cl_event2
|
|
|
|
* support as a proxy for EGL 1.5 support, even though that's not
|
|
|
|
* entirely correct (though _eglComputeVersion does the same).
|
|
|
|
*
|
|
|
|
* The EGL spec provides no guidance on how to handle unsupported
|
|
|
|
* functions. EGL_BAD_MATCH seems reasonable.
|
|
|
|
*/
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
|
|
|
|
}
|
2015-04-10 12:16:30 +01:00
|
|
|
|
2016-10-25 09:29:53 +01:00
|
|
|
/* If type is EGL_SYNC_FENCE and no context is current for the bound API
|
|
|
|
* (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH
|
|
|
|
* error is generated.
|
|
|
|
*/
|
2016-11-18 13:39:33 +00:00
|
|
|
if (!ctx &&
|
|
|
|
(type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID))
|
2016-10-25 09:29:53 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
|
|
|
|
|
2015-04-10 09:56:02 +01:00
|
|
|
/* return an error if the client API doesn't support GL_OES_EGL_sync */
|
2016-10-25 09:29:53 +01:00
|
|
|
if (ctx && (ctx->Resource.Display != disp ||
|
2017-08-08 16:17:13 +01:00
|
|
|
ctx->ClientAPI != EGL_OPENGL_ES_API))
|
2015-04-10 09:56:02 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case EGL_SYNC_FENCE_KHR:
|
|
|
|
if (!disp->Extensions.KHR_fence_sync)
|
2015-05-12 20:41:32 +01:00
|
|
|
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
|
2015-04-10 09:56:02 +01:00
|
|
|
break;
|
|
|
|
case EGL_SYNC_REUSABLE_KHR:
|
|
|
|
if (!disp->Extensions.KHR_reusable_sync)
|
2015-05-12 20:41:32 +01:00
|
|
|
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
|
2015-04-10 09:56:02 +01:00
|
|
|
break;
|
2015-04-10 12:16:30 +01:00
|
|
|
case EGL_SYNC_CL_EVENT_KHR:
|
|
|
|
if (!disp->Extensions.KHR_cl_event2)
|
2015-05-12 20:41:32 +01:00
|
|
|
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
|
2015-04-10 12:16:30 +01:00
|
|
|
break;
|
2016-11-18 13:39:33 +00:00
|
|
|
case EGL_SYNC_NATIVE_FENCE_ANDROID:
|
|
|
|
if (!disp->Extensions.ANDROID_native_fence_sync)
|
|
|
|
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
|
|
|
|
break;
|
2015-04-10 09:56:02 +01:00
|
|
|
default:
|
2015-05-12 20:41:32 +01:00
|
|
|
RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR);
|
2015-04-10 09:56:02 +01:00
|
|
|
}
|
2010-08-14 16:09:12 +01:00
|
|
|
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR;
|
2010-08-14 16:09:12 +01:00
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-12 16:34:57 +01:00
|
|
|
static EGLSync EGLAPIENTRY
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *int_list)
|
2015-04-10 12:16:30 +01:00
|
|
|
{
|
2016-09-12 22:40:29 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
|
|
|
|
EGLSync sync;
|
|
|
|
EGLAttrib *attrib_list;
|
|
|
|
EGLint err;
|
|
|
|
|
|
|
|
if (sizeof(int_list[0]) == sizeof(attrib_list[0])) {
|
|
|
|
attrib_list = (EGLAttrib *) int_list;
|
|
|
|
} else {
|
|
|
|
err = _eglConvertIntsToAttribs(int_list, &attrib_list);
|
|
|
|
if (err != EGL_SUCCESS)
|
|
|
|
RETURN_EGL_ERROR(disp, err, EGL_NO_SYNC);
|
|
|
|
}
|
|
|
|
|
|
|
|
sync = _eglCreateSync(disp, type, attrib_list, EGL_FALSE,
|
2015-05-12 20:41:32 +01:00
|
|
|
EGL_BAD_ATTRIBUTE);
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
|
|
|
|
if (sizeof(int_list[0]) != sizeof(attrib_list[0]))
|
|
|
|
free(attrib_list);
|
|
|
|
|
|
|
|
/* Don't double-unlock the display. _eglCreateSync already unlocked it. */
|
|
|
|
return sync;
|
2015-05-12 20:41:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static EGLSync EGLAPIENTRY
|
|
|
|
eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
|
|
|
|
{
|
2016-09-12 22:40:29 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
|
2015-05-12 20:41:32 +01:00
|
|
|
EGL_BAD_ATTRIBUTE);
|
2015-04-10 12:16:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-12 19:54:22 +01:00
|
|
|
EGLSync EGLAPIENTRY
|
|
|
|
eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
|
2015-04-10 12:16:30 +01:00
|
|
|
{
|
2016-09-12 22:40:29 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
egl: Unify the EGLint/EGLAttrib paths in eglCreateSync* (v3)
Pre-patch, there were two code paths for parsing EGLSync attribute
lists: one path for old-style EGLint lists, used by eglCreateSyncKHR,
and another for new-style EGLAttrib lists, used by eglCreateSync (1.5)
and eglCreateSync64 (EGL_KHR_cl_event2).
There were two attrib_list parsing functions,
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
_eglParseSyncAttribList64(_EGLSync *sync, const EGLattrib *attrib_list)
This patch unifies the two attrib_list parsing functions into one,
_eglParseSyncAttribList(_EGLSync *sync, const EGLattrib *attrib_list)
Many internal EGLSync function signatures had *two* attrib_list
parameters to accomodate both code paths: one parameter was an EGLint
list and other an EGLAttrib list. At most one of the parameters was
allowed to be non-null. This patch removes the `EGLint *attrib_list`
parameter, leaving only the `EGLAttrib *attrib_list` parameter, for all
internal EGLSync functions.
v2:
- Consistently use condition (sizeof(int_list[0]) ==
sizeof(attrib_list[0])). [for emil]
v3:
- Don't double-unlock the display in eglCreateSyncKHR.
Reviewed-by: Emil Velikov <emil.velikov@collabora.com> (v2)
2016-09-27 21:27:21 +01:00
|
|
|
return _eglCreateSync(disp, type, attrib_list, EGL_TRUE,
|
2015-05-12 20:41:32 +01:00
|
|
|
EGL_BAD_PARAMETER);
|
2015-04-10 12:16:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-21 23:56:45 +00:00
|
|
|
static EGLBoolean
|
|
|
|
_eglDestroySync(_EGLDisplay *disp, _EGLSync *s)
|
2010-08-14 16:09:12 +01:00
|
|
|
{
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
2015-04-10 09:56:02 +01:00
|
|
|
assert(disp->Extensions.KHR_reusable_sync ||
|
2016-11-18 13:39:33 +00:00
|
|
|
disp->Extensions.KHR_fence_sync ||
|
|
|
|
disp->Extensions.ANDROID_native_fence_sync);
|
2010-09-23 19:42:15 +01:00
|
|
|
|
2010-08-14 16:09:12 +01:00
|
|
|
_eglUnlinkSync(s);
|
|
|
|
ret = drv->API.DestroySyncKHR(drv, disp, s);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2017-02-21 23:56:45 +00:00
|
|
|
EGLBoolean EGLAPIENTRY
|
|
|
|
eglDestroySync(EGLDisplay dpy, EGLSync sync)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
|
|
|
return _eglDestroySync(disp, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglDestroySyncKHR(EGLDisplay dpy, EGLSync sync)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
|
|
|
return _eglDestroySync(disp, s);
|
|
|
|
}
|
|
|
|
|
2010-08-14 16:09:12 +01:00
|
|
|
|
2017-02-21 23:56:46 +00:00
|
|
|
static EGLint
|
|
|
|
_eglClientWaitSyncCommon(_EGLDisplay *disp, EGLDisplay dpy,
|
|
|
|
_EGLSync *s, EGLint flags, EGLTime timeout)
|
2010-08-14 16:09:12 +01:00
|
|
|
{
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLint ret;
|
|
|
|
|
|
|
|
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
2015-04-10 09:56:02 +01:00
|
|
|
assert(disp->Extensions.KHR_reusable_sync ||
|
2016-11-18 13:39:33 +00:00
|
|
|
disp->Extensions.KHR_fence_sync ||
|
|
|
|
disp->Extensions.ANDROID_native_fence_sync);
|
2015-04-10 09:56:02 +01:00
|
|
|
|
|
|
|
if (s->SyncStatus == EGL_SIGNALED_KHR)
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR);
|
|
|
|
|
2016-04-05 01:14:10 +01:00
|
|
|
/* if sync type is EGL_SYNC_REUSABLE_KHR, dpy should be
|
|
|
|
* unlocked here to allow other threads also to be able to
|
|
|
|
* go into waiting state.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (s->Type == EGL_SYNC_REUSABLE_KHR)
|
|
|
|
_eglUnlockDisplay(dpy);
|
|
|
|
|
2010-08-14 16:09:12 +01:00
|
|
|
ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
|
|
|
|
|
2016-04-05 01:14:10 +01:00
|
|
|
/*
|
|
|
|
* 'disp' is already unlocked for reusable sync type,
|
|
|
|
* so passing 'NULL' to bypass unlocking display.
|
|
|
|
*/
|
|
|
|
if (s->Type == EGL_SYNC_REUSABLE_KHR)
|
|
|
|
RETURN_EGL_EVAL(NULL, ret);
|
|
|
|
else
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
2010-08-14 16:09:12 +01:00
|
|
|
}
|
|
|
|
|
2017-02-21 23:56:46 +00:00
|
|
|
EGLint EGLAPIENTRY
|
|
|
|
eglClientWaitSync(EGLDisplay dpy, EGLSync sync,
|
|
|
|
EGLint flags, EGLTime timeout)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
|
|
|
return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
static EGLint EGLAPIENTRY
|
|
|
|
eglClientWaitSyncKHR(EGLDisplay dpy, EGLSync sync,
|
|
|
|
EGLint flags, EGLTime timeout)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
|
|
|
return _eglClientWaitSyncCommon(disp, dpy, s, flags, timeout);
|
|
|
|
}
|
|
|
|
|
2010-08-14 16:09:12 +01:00
|
|
|
|
2016-09-12 22:44:36 +01:00
|
|
|
static EGLint
|
|
|
|
_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
|
2015-04-10 11:04:18 +01:00
|
|
|
{
|
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLint ret;
|
|
|
|
|
|
|
|
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
|
|
|
assert(disp->Extensions.KHR_wait_sync);
|
|
|
|
|
|
|
|
/* return an error if the client API doesn't support GL_OES_EGL_sync */
|
|
|
|
if (ctx == EGL_NO_CONTEXT || ctx->ClientAPI != EGL_OPENGL_ES_API)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
|
|
|
|
|
|
|
|
/* the API doesn't allow any flags yet */
|
|
|
|
if (flags != 0)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.WaitSyncKHR(drv, disp, s);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2016-09-12 22:44:36 +01:00
|
|
|
static EGLint EGLAPIENTRY
|
|
|
|
eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
2016-09-12 22:44:36 +01:00
|
|
|
return _eglWaitSyncCommon(disp, s, flags);
|
|
|
|
}
|
|
|
|
|
2015-04-10 11:04:18 +01:00
|
|
|
|
2015-05-12 17:13:31 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
|
|
|
eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
|
|
|
|
{
|
|
|
|
/* The KHR version returns EGLint, while the core version returns
|
|
|
|
* EGLBoolean. In both cases, the return values can only be EGL_FALSE and
|
|
|
|
* EGL_TRUE.
|
|
|
|
*/
|
2016-09-12 22:44:36 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
2016-09-12 22:44:36 +01:00
|
|
|
return _eglWaitSyncCommon(disp, s, flags);
|
2015-05-12 17:13:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2015-05-12 16:34:57 +01:00
|
|
|
eglSignalSyncKHR(EGLDisplay dpy, EGLSync sync, EGLenum mode)
|
2010-08-14 16:09:12 +01:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
|
|
|
|
2010-08-14 16:09:12 +01:00
|
|
|
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
2010-09-23 19:42:15 +01:00
|
|
|
assert(disp->Extensions.KHR_reusable_sync);
|
2010-08-14 16:09:12 +01:00
|
|
|
ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-12 22:46:04 +01:00
|
|
|
static EGLBoolean
|
|
|
|
_eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, EGLint attribute, EGLAttrib *value)
|
2010-08-14 16:09:12 +01:00
|
|
|
{
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
2015-04-10 09:56:02 +01:00
|
|
|
assert(disp->Extensions.KHR_reusable_sync ||
|
2016-11-18 13:39:33 +00:00
|
|
|
disp->Extensions.KHR_fence_sync ||
|
|
|
|
disp->Extensions.ANDROID_native_fence_sync);
|
2015-05-12 17:14:31 +01:00
|
|
|
ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value);
|
2010-08-14 16:09:12 +01:00
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2016-09-12 22:46:04 +01:00
|
|
|
EGLBoolean EGLAPIENTRY
|
|
|
|
eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
2016-09-12 22:46:04 +01:00
|
|
|
return _eglGetSyncAttribCommon(disp, s, attribute, value);
|
|
|
|
}
|
|
|
|
|
2010-08-14 16:09:12 +01:00
|
|
|
|
2015-05-12 17:14:31 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint *value)
|
|
|
|
{
|
2016-09-12 22:46:04 +01:00
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
2016-02-02 23:06:28 +00:00
|
|
|
EGLAttrib attrib;
|
|
|
|
EGLBoolean result;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
|
|
|
|
2016-02-02 23:06:28 +00:00
|
|
|
if (!value)
|
2016-09-28 07:06:37 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
2016-02-02 23:06:28 +00:00
|
|
|
|
|
|
|
attrib = *value;
|
2016-09-12 22:46:04 +01:00
|
|
|
result = _eglGetSyncAttribCommon(disp, s, attribute, &attrib);
|
2015-05-12 17:14:31 +01:00
|
|
|
|
|
|
|
/* The EGL_KHR_fence_sync spec says this about eglGetSyncAttribKHR:
|
|
|
|
*
|
|
|
|
* If any error occurs, <*value> is not modified.
|
|
|
|
*/
|
|
|
|
if (result == EGL_FALSE)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
*value = attrib;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-11-18 13:39:33 +00:00
|
|
|
static EGLint EGLAPIENTRY
|
|
|
|
eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSync *s = _eglLookupSync(sync, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE);
|
|
|
|
|
|
|
|
/* the spec doesn't seem to specify what happens if the fence
|
|
|
|
* type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems
|
|
|
|
* sensible:
|
|
|
|
*/
|
|
|
|
if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)))
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_NATIVE_FENCE_FD_ANDROID);
|
|
|
|
|
|
|
|
_EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv);
|
|
|
|
assert(disp->Extensions.ANDROID_native_fence_sync);
|
|
|
|
ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
2015-05-12 17:14:31 +01:00
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2010-05-07 03:01:35 +01:00
|
|
|
eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
|
2017-08-08 16:17:13 +01:00
|
|
|
EGLint numRects, const EGLint *rects)
|
2010-05-07 03:01:35 +01:00
|
|
|
{
|
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
|
|
|
|
2010-05-07 03:01:35 +01:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
|
|
|
|
2010-09-23 19:42:15 +01:00
|
|
|
if (!disp->Extensions.NOK_swap_region)
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_FALSE);
|
|
|
|
|
2010-05-07 03:01:35 +01:00
|
|
|
/* surface must be bound to current context in EGL 1.4 */
|
2010-10-23 05:52:26 +01:00
|
|
|
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
|
|
|
|
surf != ctx->DrawSurface)
|
2010-05-07 03:01:35 +01:00
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
|
|
|
|
|
2010-09-23 19:42:15 +01:00
|
|
|
ret = drv->API.SwapBuffersRegionNOK(drv, disp, surf, numRects, rects);
|
2010-05-07 03:01:35 +01:00
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2010-06-04 19:28:59 +01:00
|
|
|
|
2015-05-12 16:34:57 +01:00
|
|
|
static EGLImage EGLAPIENTRY
|
2010-06-04 19:28:59 +01:00
|
|
|
eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLImage *img;
|
2015-05-12 16:34:57 +01:00
|
|
|
EGLImage ret;
|
2010-06-04 19:28:59 +01:00
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2010-06-04 19:28:59 +01:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR, drv);
|
2010-09-23 19:42:15 +01:00
|
|
|
if (!disp->Extensions.MESA_drm_image)
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_NO_IMAGE_KHR);
|
2010-06-04 19:28:59 +01:00
|
|
|
|
|
|
|
img = drv->API.CreateDRMImageMESA(drv, disp, attr_list);
|
2010-10-22 17:37:19 +01:00
|
|
|
ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
|
2010-06-04 19:28:59 +01:00
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2015-05-12 16:34:57 +01:00
|
|
|
eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
|
2017-08-08 16:17:13 +01:00
|
|
|
EGLint *name, EGLint *handle, EGLint *stride)
|
2010-06-04 19:28:59 +01:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLImage *img = _eglLookupImage(image, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
|
|
|
|
|
2010-06-04 19:28:59 +01:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
2010-09-23 19:42:15 +01:00
|
|
|
assert(disp->Extensions.MESA_drm_image);
|
|
|
|
|
2010-06-04 19:28:59 +01:00
|
|
|
if (!img)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.ExportDRMImageMESA(drv, disp, img, name, handle, stride);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2011-02-21 15:22:34 +00:00
|
|
|
|
|
|
|
struct wl_display;
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2011-02-21 15:22:34 +00:00
|
|
|
eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2011-02-21 15:22:34 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
|
|
|
assert(disp->Extensions.WL_bind_wayland_display);
|
|
|
|
|
|
|
|
if (!display)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2011-02-21 15:22:34 +00:00
|
|
|
eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2011-02-21 15:22:34 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
|
|
|
assert(disp->Extensions.WL_bind_wayland_display);
|
|
|
|
|
|
|
|
if (!display)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
2012-07-05 21:43:04 +01:00
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2013-07-18 13:11:25 +01:00
|
|
|
eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer,
|
2012-07-05 21:43:04 +01:00
|
|
|
EGLint attribute, EGLint *value)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2012-07-05 21:43:04 +01:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
|
|
|
assert(disp->Extensions.WL_bind_wayland_display);
|
|
|
|
|
|
|
|
if (!buffer)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.QueryWaylandBufferWL(drv, disp, buffer, attribute, value);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
2011-12-14 20:24:09 +00:00
|
|
|
|
2015-07-10 11:22:13 +01:00
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static struct wl_buffer * EGLAPIENTRY
|
2015-05-12 16:34:57 +01:00
|
|
|
eglCreateWaylandBufferFromImageWL(EGLDisplay dpy, EGLImage image)
|
2013-10-28 15:07:03 +00:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLImage *img;
|
|
|
|
_EGLDriver *drv;
|
|
|
|
struct wl_buffer *ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_FALSE);
|
|
|
|
|
2013-10-28 15:07:03 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, NULL, drv);
|
2017-05-15 16:14:15 +01:00
|
|
|
if (!disp->Extensions.WL_create_wayland_buffer_from_image)
|
|
|
|
RETURN_EGL_EVAL(disp, NULL);
|
2013-10-28 15:07:03 +00:00
|
|
|
|
|
|
|
img = _eglLookupImage(image, disp);
|
|
|
|
|
|
|
|
if (!img)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, NULL);
|
|
|
|
|
|
|
|
ret = drv->API.CreateWaylandBufferFromImageWL(drv, disp, img);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
2011-12-14 20:24:09 +00:00
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2011-12-14 20:24:09 +00:00
|
|
|
eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface,
|
|
|
|
EGLint x, EGLint y, EGLint width, EGLint height)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
|
|
|
|
2011-12-14 20:24:09 +00:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
|
|
|
|
|
|
|
if (!disp->Extensions.NV_post_sub_buffer)
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.PostSubBufferNV(drv, disp, surf, x, y, width, height);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
2014-05-06 20:10:57 +01:00
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2014-05-06 20:10:57 +01:00
|
|
|
eglGetSyncValuesCHROMIUM(EGLDisplay display, EGLSurface surface,
|
|
|
|
EGLuint64KHR *ust, EGLuint64KHR *msc,
|
|
|
|
EGLuint64KHR *sbc)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(display);
|
|
|
|
_EGLSurface *surf = _eglLookupSurface(surface, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
|
|
|
|
|
2014-05-06 20:10:57 +01:00
|
|
|
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
|
|
|
|
if (!disp->Extensions.CHROMIUM_sync_control)
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_FALSE);
|
|
|
|
|
|
|
|
if (!ust || !msc || !sbc)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.GetSyncValuesCHROMIUM(disp, surf, ust, msc, sbc);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
2014-03-03 03:57:16 +00:00
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2015-05-12 16:34:57 +01:00
|
|
|
eglExportDMABUFImageQueryMESA(EGLDisplay dpy, EGLImage image,
|
2014-03-03 03:57:16 +00:00
|
|
|
EGLint *fourcc, EGLint *nplanes,
|
2015-05-05 00:10:34 +01:00
|
|
|
EGLuint64KHR *modifiers)
|
2014-03-03 03:57:16 +00:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLImage *img = _eglLookupImage(image, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
|
|
|
|
|
2014-03-03 03:57:16 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
|
|
|
assert(disp->Extensions.MESA_image_dma_buf_export);
|
|
|
|
|
|
|
|
if (!img)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.ExportDMABUFImageQueryMESA(drv, disp, img, fourcc, nplanes,
|
|
|
|
modifiers);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
2015-05-12 16:34:57 +01:00
|
|
|
eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
|
2014-03-03 03:57:16 +00:00
|
|
|
int *fds, EGLint *strides, EGLint *offsets)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLImage *img = _eglLookupImage(image, disp);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(disp, EGL_OBJECT_IMAGE_KHR, img, EGL_FALSE);
|
|
|
|
|
2014-03-03 03:57:16 +00:00
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
|
|
|
assert(disp->Extensions.MESA_image_dma_buf_export);
|
|
|
|
|
|
|
|
if (!img)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
|
|
|
|
|
|
|
ret = drv->API.ExportDMABUFImageMESA(drv, disp, img, fds, strides, offsets);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
2015-05-11 23:43:48 +01:00
|
|
|
|
2016-09-12 22:51:22 +01:00
|
|
|
static EGLint EGLAPIENTRY
|
|
|
|
eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
|
2017-08-08 16:17:13 +01:00
|
|
|
EGLLabelKHR label)
|
2016-09-12 22:51:22 +01:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp = NULL;
|
|
|
|
_EGLResourceType type;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
|
|
|
|
|
|
|
|
if (objectType == EGL_OBJECT_THREAD_KHR) {
|
|
|
|
_EGLThreadInfo *t = _eglGetCurrentThread();
|
|
|
|
|
|
|
|
if (!_eglIsCurrentThreadDummy()) {
|
|
|
|
t->Label = label;
|
|
|
|
return EGL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC);
|
|
|
|
}
|
|
|
|
|
|
|
|
disp = _eglLockDisplay(dpy);
|
|
|
|
if (disp == NULL)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_BAD_DISPLAY);
|
|
|
|
|
|
|
|
if (objectType == EGL_OBJECT_DISPLAY_KHR) {
|
|
|
|
if (dpy != (EGLDisplay) object)
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
|
|
|
|
|
|
|
|
disp->Label = label;
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (objectType) {
|
|
|
|
case EGL_OBJECT_CONTEXT_KHR:
|
|
|
|
type = _EGL_RESOURCE_CONTEXT;
|
|
|
|
break;
|
|
|
|
case EGL_OBJECT_SURFACE_KHR:
|
|
|
|
type = _EGL_RESOURCE_SURFACE;
|
|
|
|
break;
|
|
|
|
case EGL_OBJECT_IMAGE_KHR:
|
|
|
|
type = _EGL_RESOURCE_IMAGE;
|
|
|
|
break;
|
|
|
|
case EGL_OBJECT_SYNC_KHR:
|
|
|
|
type = _EGL_RESOURCE_SYNC;
|
|
|
|
break;
|
|
|
|
case EGL_OBJECT_STREAM_KHR:
|
|
|
|
default:
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_eglCheckResource(object, type, disp)) {
|
|
|
|
_EGLResource *res = (_EGLResource *) object;
|
|
|
|
|
|
|
|
res->Label = label;
|
|
|
|
RETURN_EGL_EVAL(disp, EGL_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
|
|
|
|
}
|
|
|
|
|
|
|
|
static EGLint EGLAPIENTRY
|
|
|
|
eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
|
2017-08-08 16:17:13 +01:00
|
|
|
const EGLAttrib *attrib_list)
|
2016-09-12 22:51:22 +01:00
|
|
|
{
|
|
|
|
unsigned int newEnabled;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
|
|
|
|
|
|
|
|
mtx_lock(_eglGlobal.Mutex);
|
|
|
|
|
|
|
|
newEnabled = _eglGlobal.debugTypesEnabled;
|
|
|
|
if (attrib_list != NULL) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
|
2017-09-07 17:03:53 +01:00
|
|
|
switch (attrib_list[i]) {
|
|
|
|
case EGL_DEBUG_MSG_CRITICAL_KHR:
|
|
|
|
case EGL_DEBUG_MSG_ERROR_KHR:
|
|
|
|
case EGL_DEBUG_MSG_WARN_KHR:
|
|
|
|
case EGL_DEBUG_MSG_INFO_KHR:
|
2016-09-12 22:51:22 +01:00
|
|
|
if (attrib_list[i + 1])
|
|
|
|
newEnabled |= DebugBitFromType(attrib_list[i]);
|
|
|
|
else
|
|
|
|
newEnabled &= ~DebugBitFromType(attrib_list[i]);
|
2017-09-07 17:03:53 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// On error, set the last error code, call the current
|
|
|
|
// debug callback, and return the error code.
|
|
|
|
mtx_unlock(_eglGlobal.Mutex);
|
|
|
|
_eglReportError(EGL_BAD_ATTRIBUTE, NULL,
|
|
|
|
"Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
|
|
|
|
return EGL_BAD_ATTRIBUTE;
|
2016-09-12 22:51:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (callback != NULL) {
|
|
|
|
_eglGlobal.debugCallback = callback;
|
|
|
|
_eglGlobal.debugTypesEnabled = newEnabled;
|
|
|
|
} else {
|
|
|
|
_eglGlobal.debugCallback = NULL;
|
|
|
|
_eglGlobal.debugTypesEnabled = _EGL_DEBUG_BIT_CRITICAL | _EGL_DEBUG_BIT_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
mtx_unlock(_eglGlobal.Mutex);
|
|
|
|
return EGL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
|
|
|
|
{
|
|
|
|
_EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_BAD_ALLOC);
|
|
|
|
|
|
|
|
mtx_lock(_eglGlobal.Mutex);
|
|
|
|
|
2017-09-07 17:03:53 +01:00
|
|
|
switch (attribute) {
|
|
|
|
case EGL_DEBUG_MSG_CRITICAL_KHR:
|
|
|
|
case EGL_DEBUG_MSG_ERROR_KHR:
|
|
|
|
case EGL_DEBUG_MSG_WARN_KHR:
|
|
|
|
case EGL_DEBUG_MSG_INFO_KHR:
|
|
|
|
if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
|
|
|
|
*value = EGL_TRUE;
|
|
|
|
else
|
|
|
|
*value = EGL_FALSE;
|
|
|
|
break;
|
|
|
|
case EGL_DEBUG_CALLBACK_KHR:
|
|
|
|
*value = (EGLAttrib) _eglGlobal.debugCallback;
|
|
|
|
break;
|
|
|
|
default:
|
2016-09-12 22:51:22 +01:00
|
|
|
mtx_unlock(_eglGlobal.Mutex);
|
|
|
|
_eglReportError(EGL_BAD_ATTRIBUTE, NULL,
|
2017-08-08 16:17:13 +01:00
|
|
|
"Invalid attribute 0x%04lx", (unsigned long) attribute);
|
2016-09-12 22:51:22 +01:00
|
|
|
return EGL_FALSE;
|
2017-09-07 17:03:53 +01:00
|
|
|
}
|
2016-09-12 22:51:22 +01:00
|
|
|
|
|
|
|
mtx_unlock(_eglGlobal.Mutex);
|
|
|
|
return EGL_TRUE;
|
|
|
|
}
|
|
|
|
|
2017-02-21 23:56:52 +00:00
|
|
|
static int
|
|
|
|
_eglFunctionCompare(const void *key, const void *elem)
|
|
|
|
{
|
|
|
|
const char *procname = key;
|
|
|
|
const struct _egl_entrypoint *entrypoint = elem;
|
|
|
|
return strcmp(procname, entrypoint->name);
|
|
|
|
}
|
|
|
|
|
2017-05-30 12:53:38 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglQueryDmaBufFormatsEXT(EGLDisplay dpy, EGLint max_formats,
|
|
|
|
EGLint *formats, EGLint *num_formats)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
|
|
|
|
|
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
|
|
|
|
|
|
|
ret = drv->API.QueryDmaBufFormatsEXT(drv, disp, max_formats, formats,
|
|
|
|
num_formats);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2017-05-30 12:53:39 +01:00
|
|
|
static EGLBoolean EGLAPIENTRY
|
|
|
|
eglQueryDmaBufModifiersEXT(EGLDisplay dpy, EGLint format, EGLint max_modifiers,
|
|
|
|
EGLuint64KHR *modifiers, EGLBoolean *external_only,
|
|
|
|
EGLint *num_modifiers)
|
|
|
|
{
|
|
|
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
|
|
|
_EGLDriver *drv;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
_EGL_FUNC_START(NULL, EGL_NONE, NULL, EGL_FALSE);
|
|
|
|
|
|
|
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
|
|
|
|
|
|
|
ret = drv->API.QueryDmaBufModifiersEXT(drv, disp, format, max_modifiers,
|
|
|
|
modifiers, external_only,
|
|
|
|
num_modifiers);
|
|
|
|
|
|
|
|
RETURN_EGL_EVAL(disp, ret);
|
|
|
|
}
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
__eglMustCastToProperFunctionPointerType EGLAPIENTRY
|
|
|
|
eglGetProcAddress(const char *procname)
|
|
|
|
{
|
2017-02-21 23:56:52 +00:00
|
|
|
static const struct _egl_entrypoint egl_functions[] = {
|
2017-02-21 23:56:47 +00:00
|
|
|
#define EGL_ENTRYPOINT(f) { .name = #f, .function = (_EGLProc) f },
|
2017-02-21 23:56:49 +00:00
|
|
|
#include "eglentrypoint.h"
|
2017-02-21 23:56:47 +00:00
|
|
|
#undef EGL_ENTRYPOINT
|
2015-05-11 23:43:48 +01:00
|
|
|
};
|
2017-02-21 23:56:52 +00:00
|
|
|
_EGLProc ret = NULL;
|
2015-05-11 23:43:48 +01:00
|
|
|
|
|
|
|
if (!procname)
|
|
|
|
RETURN_EGL_SUCCESS(NULL, NULL);
|
|
|
|
|
2016-09-12 22:50:40 +01:00
|
|
|
_EGL_FUNC_START(NULL, EGL_NONE, NULL, NULL);
|
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
if (strncmp(procname, "egl", 3) == 0) {
|
2017-02-21 23:56:52 +00:00
|
|
|
const struct _egl_entrypoint *entrypoint =
|
|
|
|
bsearch(procname,
|
|
|
|
egl_functions, ARRAY_SIZE(egl_functions),
|
|
|
|
sizeof(egl_functions[0]),
|
|
|
|
_eglFunctionCompare);
|
|
|
|
if (entrypoint)
|
|
|
|
ret = entrypoint->function;
|
2015-05-11 23:43:48 +01:00
|
|
|
}
|
2017-02-21 23:56:52 +00:00
|
|
|
|
2015-05-11 23:43:48 +01:00
|
|
|
if (!ret)
|
|
|
|
ret = _eglGetDriverProc(procname);
|
|
|
|
|
|
|
|
RETURN_EGL_SUCCESS(NULL, ret);
|
|
|
|
}
|
2016-03-03 14:59:48 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
_eglLockDisplayInterop(EGLDisplay dpy, EGLContext context,
|
|
|
|
_EGLDisplay **disp, _EGLDriver **drv,
|
|
|
|
_EGLContext **ctx)
|
|
|
|
{
|
|
|
|
|
|
|
|
*disp = _eglLockDisplay(dpy);
|
|
|
|
if (!*disp || !(*disp)->Initialized || !(*disp)->Driver) {
|
|
|
|
if (*disp)
|
|
|
|
_eglUnlockDisplay(*disp);
|
|
|
|
return MESA_GLINTEROP_INVALID_DISPLAY;
|
|
|
|
}
|
|
|
|
|
|
|
|
*drv = (*disp)->Driver;
|
|
|
|
|
|
|
|
*ctx = _eglLookupContext(context, *disp);
|
|
|
|
if (!*ctx ||
|
|
|
|
((*ctx)->ClientAPI != EGL_OPENGL_API &&
|
|
|
|
(*ctx)->ClientAPI != EGL_OPENGL_ES_API)) {
|
|
|
|
_eglUnlockDisplay(*disp);
|
|
|
|
return MESA_GLINTEROP_INVALID_CONTEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return MESA_GLINTEROP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-11-02 17:59:22 +00:00
|
|
|
PUBLIC int
|
2016-03-03 14:59:48 +00:00
|
|
|
MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
|
2016-05-30 10:56:33 +01:00
|
|
|
struct mesa_glinterop_device_info *out)
|
2016-03-03 14:59:48 +00:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp;
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLContext *ctx;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
|
|
|
|
if (ret != MESA_GLINTEROP_SUCCESS)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (drv->API.GLInteropQueryDeviceInfo)
|
|
|
|
ret = drv->API.GLInteropQueryDeviceInfo(disp, ctx, out);
|
|
|
|
else
|
|
|
|
ret = MESA_GLINTEROP_UNSUPPORTED;
|
|
|
|
|
|
|
|
_eglUnlockDisplay(disp);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-11-02 17:59:22 +00:00
|
|
|
PUBLIC int
|
2016-03-03 14:59:48 +00:00
|
|
|
MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
|
2016-05-30 10:56:33 +01:00
|
|
|
struct mesa_glinterop_export_in *in,
|
|
|
|
struct mesa_glinterop_export_out *out)
|
2016-03-03 14:59:48 +00:00
|
|
|
{
|
|
|
|
_EGLDisplay *disp;
|
|
|
|
_EGLDriver *drv;
|
|
|
|
_EGLContext *ctx;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = _eglLockDisplayInterop(dpy, context, &disp, &drv, &ctx);
|
|
|
|
if (ret != MESA_GLINTEROP_SUCCESS)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (drv->API.GLInteropExportObject)
|
|
|
|
ret = drv->API.GLInteropExportObject(disp, ctx, in, out);
|
|
|
|
else
|
|
|
|
ret = MESA_GLINTEROP_UNSUPPORTED;
|
|
|
|
|
|
|
|
_eglUnlockDisplay(disp);
|
|
|
|
return ret;
|
|
|
|
}
|