egl: Add support for EGL_KHR_reusable_sync.
Individual drivers still need to support and enable the extension.
This commit is contained in:
@@ -26,7 +26,8 @@ HEADERS = \
|
||||
eglmutex.h \
|
||||
eglscreen.h \
|
||||
eglstring.h \
|
||||
eglsurface.h
|
||||
eglsurface.h \
|
||||
eglsync.h
|
||||
|
||||
SOURCES = \
|
||||
eglapi.c \
|
||||
@@ -44,7 +45,8 @@ SOURCES = \
|
||||
eglmode.c \
|
||||
eglscreen.c \
|
||||
eglstring.c \
|
||||
eglsurface.c
|
||||
eglsurface.c \
|
||||
eglsync.c
|
||||
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
|
@@ -68,6 +68,7 @@
|
||||
#include "eglscreen.h"
|
||||
#include "eglmode.h"
|
||||
#include "eglimage.h"
|
||||
#include "eglsync.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -126,6 +127,8 @@
|
||||
#define _EGL_CHECK_MODE(disp, m, ret, drv) \
|
||||
_EGL_CHECK_OBJECT(disp, Mode, m, ret, drv)
|
||||
|
||||
#define _EGL_CHECK_SYNC(disp, s, ret, drv) \
|
||||
_EGL_CHECK_OBJECT(disp, Sync, s, ret, drv)
|
||||
|
||||
|
||||
static INLINE _EGLDriver *
|
||||
@@ -185,6 +188,26 @@ _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
|
||||
}
|
||||
|
||||
|
||||
#ifdef EGL_KHR_reusable_sync
|
||||
|
||||
|
||||
static INLINE _EGLDriver *
|
||||
_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;
|
||||
}
|
||||
|
||||
|
||||
#endif /* EGL_KHR_reusable_sync */
|
||||
|
||||
|
||||
#ifdef EGL_MESA_screen_surface
|
||||
|
||||
|
||||
@@ -1245,6 +1268,90 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
|
||||
#ifdef EGL_KHR_reusable_sync
|
||||
|
||||
|
||||
EGLSyncKHR EGLAPIENTRY
|
||||
eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||
_EGLDriver *drv;
|
||||
_EGLSync *sync;
|
||||
EGLSyncKHR ret;
|
||||
|
||||
_EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv);
|
||||
|
||||
sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list);
|
||||
ret = (sync) ? _eglLinkSync(sync, disp) : EGL_NO_SYNC_KHR;
|
||||
|
||||
RETURN_EGL_EVAL(disp, ret);
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean EGLAPIENTRY
|
||||
eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||
_EGLSync *s = _eglLookupSync(sync, disp);
|
||||
_EGLDriver *drv;
|
||||
EGLBoolean ret;
|
||||
|
||||
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
||||
_eglUnlinkSync(s);
|
||||
ret = drv->API.DestroySyncKHR(drv, disp, s);
|
||||
|
||||
RETURN_EGL_EVAL(disp, ret);
|
||||
}
|
||||
|
||||
|
||||
EGLint EGLAPIENTRY
|
||||
eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||
_EGLSync *s = _eglLookupSync(sync, disp);
|
||||
_EGLDriver *drv;
|
||||
EGLint ret;
|
||||
|
||||
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
||||
ret = drv->API.ClientWaitSyncKHR(drv, disp, s, flags, timeout);
|
||||
|
||||
RETURN_EGL_EVAL(disp, ret);
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean EGLAPIENTRY
|
||||
eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||
_EGLSync *s = _eglLookupSync(sync, disp);
|
||||
_EGLDriver *drv;
|
||||
EGLBoolean ret;
|
||||
|
||||
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
||||
ret = drv->API.SignalSyncKHR(drv, disp, s, mode);
|
||||
|
||||
RETURN_EGL_EVAL(disp, ret);
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean EGLAPIENTRY
|
||||
eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||
_EGLSync *s = _eglLookupSync(sync, disp);
|
||||
_EGLDriver *drv;
|
||||
EGLBoolean ret;
|
||||
|
||||
_EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv);
|
||||
ret = drv->API.GetSyncAttribKHR(drv, disp, s, attribute, value);
|
||||
|
||||
RETURN_EGL_EVAL(disp, ret);
|
||||
}
|
||||
|
||||
|
||||
#endif /* EGL_KHR_reusable_sync */
|
||||
|
||||
|
||||
#ifdef EGL_NOK_swap_region
|
||||
|
||||
EGLBoolean EGLAPIENTRY
|
||||
|
@@ -76,6 +76,16 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo
|
||||
typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
|
||||
#ifdef EGL_KHR_reusable_sync
|
||||
typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list);
|
||||
typedef EGLBoolean (*DestroySyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
|
||||
typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTimeKHR timeout);
|
||||
typedef EGLBoolean (*SignalSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLenum mode);
|
||||
typedef EGLBoolean (*GetSyncAttribKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint attribute, EGLint *value);
|
||||
#endif /* EGL_KHR_reusable_sync */
|
||||
|
||||
|
||||
#ifdef EGL_NOK_swap_region
|
||||
typedef EGLBoolean (*SwapBuffersRegionNOK_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLint numRects, const EGLint *rects);
|
||||
#endif
|
||||
@@ -138,6 +148,14 @@ struct _egl_api
|
||||
DestroyImageKHR_t DestroyImageKHR;
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
#ifdef EGL_KHR_reusable_sync
|
||||
CreateSyncKHR_t CreateSyncKHR;
|
||||
DestroySyncKHR_t DestroySyncKHR;
|
||||
ClientWaitSyncKHR_t ClientWaitSyncKHR;
|
||||
SignalSyncKHR_t SignalSyncKHR;
|
||||
GetSyncAttribKHR_t GetSyncAttribKHR;
|
||||
#endif /* EGL_KHR_reusable_sync */
|
||||
|
||||
#ifdef EGL_NOK_swap_region
|
||||
SwapBuffersRegionNOK_t SwapBuffersRegionNOK;
|
||||
#endif
|
||||
|
@@ -24,6 +24,7 @@ enum _egl_resource_type {
|
||||
_EGL_RESOURCE_CONTEXT,
|
||||
_EGL_RESOURCE_SURFACE,
|
||||
_EGL_RESOURCE_IMAGE,
|
||||
_EGL_RESOURCE_SYNC,
|
||||
|
||||
_EGL_NUM_RESOURCES
|
||||
};
|
||||
@@ -53,6 +54,7 @@ struct _egl_extensions
|
||||
EGLBoolean MESA_screen_surface;
|
||||
EGLBoolean MESA_copy_context;
|
||||
EGLBoolean MESA_drm_display;
|
||||
|
||||
EGLBoolean KHR_image_base;
|
||||
EGLBoolean KHR_image_pixmap;
|
||||
EGLBoolean KHR_vg_parent_image;
|
||||
@@ -60,9 +62,13 @@ struct _egl_extensions
|
||||
EGLBoolean KHR_gl_texture_cubemap_image;
|
||||
EGLBoolean KHR_gl_texture_3D_image;
|
||||
EGLBoolean KHR_gl_renderbuffer_image;
|
||||
|
||||
EGLBoolean KHR_reusable_sync;
|
||||
|
||||
EGLBoolean KHR_surfaceless_gles1;
|
||||
EGLBoolean KHR_surfaceless_gles2;
|
||||
EGLBoolean KHR_surfaceless_opengl;
|
||||
|
||||
EGLBoolean NOK_swap_region;
|
||||
EGLBoolean NOK_texture_from_pixmap;
|
||||
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "eglstring.h"
|
||||
#include "eglsurface.h"
|
||||
#include "eglimage.h"
|
||||
#include "eglsync.h"
|
||||
#include "eglmutex.h"
|
||||
|
||||
#if defined(_EGL_OS_UNIX)
|
||||
@@ -722,6 +723,14 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
|
||||
drv->API.CreateImageKHR = _eglCreateImageKHR;
|
||||
drv->API.DestroyImageKHR = _eglDestroyImageKHR;
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
#ifdef EGL_KHR_reusable_sync
|
||||
drv->API.CreateSyncKHR = _eglCreateSyncKHR;
|
||||
drv->API.DestroySyncKHR = _eglDestroySyncKHR;
|
||||
drv->API.ClientWaitSyncKHR = _eglClientWaitSyncKHR;
|
||||
drv->API.SignalSyncKHR = _eglSignalSyncKHR;
|
||||
drv->API.GetSyncAttribKHR = _eglGetSyncAttribKHR;
|
||||
#endif /* EGL_KHR_reusable_sync */
|
||||
}
|
||||
|
||||
|
||||
|
@@ -97,6 +97,8 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
|
||||
_EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image);
|
||||
_EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
|
||||
|
||||
_EGL_CHECK_EXTENSION(KHR_reusable_sync);
|
||||
|
||||
_EGL_CHECK_EXTENSION(KHR_surfaceless_gles1);
|
||||
_EGL_CHECK_EXTENSION(KHR_surfaceless_gles2);
|
||||
_EGL_CHECK_EXTENSION(KHR_surfaceless_opengl);
|
||||
|
121
src/egl/main/eglsync.c
Normal file
121
src/egl/main/eglsync.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "eglsync.h"
|
||||
#include "eglcurrent.h"
|
||||
#include "egllog.h"
|
||||
|
||||
|
||||
#ifdef EGL_KHR_reusable_sync
|
||||
|
||||
|
||||
/**
|
||||
* Parse the list of sync attributes and return the proper error code.
|
||||
*/
|
||||
static EGLint
|
||||
_eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list)
|
||||
{
|
||||
EGLint i, err = EGL_SUCCESS;
|
||||
|
||||
if (!attrib_list)
|
||||
return EGL_SUCCESS;
|
||||
|
||||
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
|
||||
EGLint attr = attrib_list[i++];
|
||||
EGLint val = attrib_list[i];
|
||||
|
||||
switch (attr) {
|
||||
default:
|
||||
(void) val;
|
||||
err = EGL_BAD_ATTRIBUTE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err != EGL_SUCCESS) {
|
||||
_eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean
|
||||
_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
|
||||
const EGLint *attrib_list)
|
||||
{
|
||||
EGLint err;
|
||||
|
||||
if (!(type == EGL_SYNC_REUSABLE_KHR && dpy->Extensions.KHR_reusable_sync))
|
||||
return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR");
|
||||
|
||||
memset(sync, 0, sizeof(*sync));
|
||||
|
||||
sync->Resource.Display = dpy;
|
||||
|
||||
sync->Type = type;
|
||||
sync->SyncStatus = EGL_UNSIGNALED_KHR;
|
||||
|
||||
err = _eglParseSyncAttribList(sync, attrib_list);
|
||||
if (err != EGL_SUCCESS)
|
||||
return _eglError(err, "eglCreateSyncKHR");
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
_EGLSync *
|
||||
_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy,
|
||||
EGLenum type, const EGLint *attrib_list)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean
|
||||
_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
|
||||
{
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
EGLint
|
||||
_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
|
||||
EGLint flags, EGLTimeKHR timeout)
|
||||
{
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean
|
||||
_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
|
||||
EGLenum mode)
|
||||
{
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean
|
||||
_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
|
||||
EGLint attribute, EGLint *value)
|
||||
{
|
||||
if (!value)
|
||||
return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs");
|
||||
|
||||
switch (attribute) {
|
||||
case EGL_SYNC_TYPE_KHR:
|
||||
*value = sync->Type;
|
||||
break;
|
||||
case EGL_SYNC_STATUS_KHR:
|
||||
*value = sync->SyncStatus;
|
||||
break;
|
||||
default:
|
||||
return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR");
|
||||
break;
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#endif /* EGL_KHR_reusable_sync */
|
119
src/egl/main/eglsync.h
Normal file
119
src/egl/main/eglsync.h
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef EGLSYNC_INCLUDED
|
||||
#define EGLSYNC_INCLUDED
|
||||
|
||||
|
||||
#include "egltypedefs.h"
|
||||
#include "egldisplay.h"
|
||||
|
||||
|
||||
#ifdef EGL_KHR_reusable_sync
|
||||
|
||||
|
||||
/**
|
||||
* "Base" class for device driver syncs.
|
||||
*/
|
||||
struct _egl_sync
|
||||
{
|
||||
/* A sync is a display resource */
|
||||
_EGLResource Resource;
|
||||
|
||||
EGLenum Type;
|
||||
EGLenum SyncStatus;
|
||||
};
|
||||
|
||||
|
||||
PUBLIC EGLBoolean
|
||||
_eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type,
|
||||
const EGLint *attrib_list);
|
||||
|
||||
|
||||
extern _EGLSync *
|
||||
_eglCreateSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy,
|
||||
EGLenum type, const EGLint *attrib_list);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglDestroySyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
|
||||
|
||||
|
||||
extern EGLint
|
||||
_eglClientWaitSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
|
||||
EGLint flags, EGLTimeKHR timeout);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglSignalSyncKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
|
||||
EGLenum mode);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
|
||||
EGLint attribute, EGLint *value);
|
||||
|
||||
|
||||
/**
|
||||
* Link a sync to a display and return the handle of the link.
|
||||
* The handle can be passed to client directly.
|
||||
*/
|
||||
static INLINE EGLSyncKHR
|
||||
_eglLinkSync(_EGLSync *sync, _EGLDisplay *dpy)
|
||||
{
|
||||
_eglLinkResource(&sync->Resource, _EGL_RESOURCE_SYNC, dpy);
|
||||
return (EGLSyncKHR) sync;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unlink a linked sync from its display.
|
||||
*/
|
||||
static INLINE void
|
||||
_eglUnlinkSync(_EGLSync *sync)
|
||||
{
|
||||
_eglUnlinkResource(&sync->Resource, _EGL_RESOURCE_SYNC);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lookup a handle to find the linked sync.
|
||||
* Return NULL if the handle has no corresponding linked sync.
|
||||
*/
|
||||
static INLINE _EGLSync *
|
||||
_eglLookupSync(EGLSyncKHR handle, _EGLDisplay *dpy)
|
||||
{
|
||||
_EGLSync *sync = (_EGLSync *) handle;
|
||||
if (!dpy || !_eglCheckResource((void *) sync, _EGL_RESOURCE_SYNC, dpy))
|
||||
sync = NULL;
|
||||
return sync;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the handle of a linked sync, or EGL_NO_SYNC_KHR.
|
||||
*/
|
||||
static INLINE EGLSyncKHR
|
||||
_eglGetSyncHandle(_EGLSync *sync)
|
||||
{
|
||||
_EGLResource *res = (_EGLResource *) sync;
|
||||
return (res && _eglIsResourceLinked(res)) ?
|
||||
(EGLSyncKHR) sync : EGL_NO_SYNC_KHR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the sync is linked to a display.
|
||||
*
|
||||
* The link is considered a reference to the sync (the display is owning the
|
||||
* sync). Drivers should not destroy a sync when it is linked.
|
||||
*/
|
||||
static INLINE EGLBoolean
|
||||
_eglIsSyncLinked(_EGLSync *sync)
|
||||
{
|
||||
_EGLResource *res = (_EGLResource *) sync;
|
||||
return (res && _eglIsResourceLinked(res));
|
||||
}
|
||||
|
||||
|
||||
#endif /* EGL_KHR_reusable_sync */
|
||||
|
||||
|
||||
#endif /* EGLSYNC_INCLUDED */
|
@@ -32,6 +32,8 @@ typedef struct _egl_screen _EGLScreen;
|
||||
|
||||
typedef struct _egl_surface _EGLSurface;
|
||||
|
||||
typedef struct _egl_sync _EGLSync;
|
||||
|
||||
typedef struct _egl_thread_info _EGLThreadInfo;
|
||||
|
||||
#endif /* EGLTYPEDEFS_INCLUDED */
|
||||
|
Reference in New Issue
Block a user