egl: Add support for EGL_KHR_image.
Individual drivers still need to implement the API hooks.
This commit is contained in:
@@ -19,6 +19,7 @@ HEADERS = \
|
||||
egldisplay.h \
|
||||
egldriver.h \
|
||||
eglglobals.h \
|
||||
eglimage.h \
|
||||
egllog.h \
|
||||
eglmisc.h \
|
||||
eglmode.h \
|
||||
@@ -36,6 +37,7 @@ SOURCES = \
|
||||
egldisplay.c \
|
||||
egldriver.c \
|
||||
eglglobals.c \
|
||||
eglimage.c \
|
||||
egllog.c \
|
||||
eglmisc.c \
|
||||
eglmode.c \
|
||||
|
@@ -65,6 +65,7 @@
|
||||
#include "eglconfig.h"
|
||||
#include "eglscreen.h"
|
||||
#include "eglmode.h"
|
||||
#include "eglimage.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -700,6 +701,10 @@ eglGetProcAddress(const char *procname)
|
||||
{ "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
|
||||
{ "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
|
||||
#endif /* EGL_MESA_screen_surface */
|
||||
#ifdef EGL_KHR_image_base
|
||||
{ "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
|
||||
{ "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
|
||||
#endif /* EGL_KHR_image_base */
|
||||
{ NULL, NULL }
|
||||
};
|
||||
EGLint i;
|
||||
@@ -995,3 +1000,52 @@ eglReleaseThread(void)
|
||||
|
||||
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
|
||||
|
||||
#ifdef EGL_KHR_image_base
|
||||
|
||||
|
||||
EGLImageKHR
|
||||
eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
|
||||
EGLClientBuffer buffer, const EGLint *attr_list)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLContext *context = _eglLookupContext(ctx, disp);
|
||||
_EGLDriver *drv;
|
||||
_EGLImage *img;
|
||||
|
||||
drv = _eglCheckDisplay(disp, __FUNCTION__);
|
||||
if (!drv)
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
if (!context && ctx != EGL_NO_CONTEXT) {
|
||||
_eglError(EGL_BAD_CONTEXT, __FUNCTION__);
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
img = drv->API.CreateImageKHR(drv,
|
||||
disp, context, target, buffer, attr_list);
|
||||
if (img)
|
||||
return _eglLinkImage(img, disp);
|
||||
else
|
||||
return EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLImage *img = _eglLookupImage(image, disp);
|
||||
_EGLDriver *drv;
|
||||
|
||||
drv = _eglCheckDisplay(disp, __FUNCTION__);
|
||||
if (!drv)
|
||||
return EGL_FALSE;
|
||||
if (!img)
|
||||
return _eglError(EGL_BAD_PARAMETER, __FUNCTION__);
|
||||
|
||||
_eglUnlinkImage(img);
|
||||
return drv->API.DestroyImageKHR(drv, disp, img);
|
||||
}
|
||||
|
||||
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
@@ -69,6 +69,11 @@ typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDis
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
|
||||
|
||||
#ifdef EGL_KHR_image_base
|
||||
typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list);
|
||||
typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
|
||||
#endif /* EGL_KHR_image_base */
|
||||
|
||||
|
||||
/**
|
||||
* The API dispatcher jumps through these functions
|
||||
@@ -104,7 +109,7 @@ struct _egl_api
|
||||
WaitNative_t WaitNative;
|
||||
GetProcAddress_t GetProcAddress;
|
||||
|
||||
/* EGL_MESA_screen extension */
|
||||
#ifdef EGL_MESA_screen_surface
|
||||
ChooseModeMESA_t ChooseModeMESA;
|
||||
GetModesMESA_t GetModesMESA;
|
||||
GetModeAttribMESA_t GetModeAttribMESA;
|
||||
@@ -117,10 +122,16 @@ struct _egl_api
|
||||
QueryScreenSurfaceMESA_t QueryScreenSurfaceMESA;
|
||||
QueryScreenModeMESA_t QueryScreenModeMESA;
|
||||
QueryModeStringMESA_t QueryModeStringMESA;
|
||||
#endif /* EGL_MESA_screen_surface */
|
||||
|
||||
#ifdef EGL_VERSION_1_2
|
||||
CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer;
|
||||
#endif
|
||||
|
||||
#ifdef EGL_KHR_image_base
|
||||
CreateImageKHR_t CreateImageKHR;
|
||||
DestroyImageKHR_t DestroyImageKHR;
|
||||
#endif /* EGL_KHR_image_base */
|
||||
};
|
||||
|
||||
#endif /* EGLAPI_INCLUDED */
|
||||
|
@@ -8,6 +8,7 @@
|
||||
enum _egl_resource_type {
|
||||
_EGL_RESOURCE_CONTEXT,
|
||||
_EGL_RESOURCE_SURFACE,
|
||||
_EGL_RESOURCE_IMAGE,
|
||||
|
||||
_EGL_NUM_RESOURCES
|
||||
};
|
||||
@@ -30,6 +31,8 @@ struct _egl_extensions
|
||||
{
|
||||
EGLBoolean MESA_screen_surface;
|
||||
EGLBoolean MESA_copy_context;
|
||||
EGLBoolean KHR_image_base;
|
||||
EGLBoolean KHR_image_pixmap;
|
||||
|
||||
char String[_EGL_MAX_EXTENSIONS_LEN];
|
||||
};
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include "eglscreen.h"
|
||||
#include "eglstring.h"
|
||||
#include "eglsurface.h"
|
||||
#include "eglimage.h"
|
||||
|
||||
#if defined(_EGL_PLATFORM_POSIX)
|
||||
#include <dlfcn.h>
|
||||
@@ -545,6 +546,11 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
|
||||
#ifdef EGL_VERSION_1_2
|
||||
drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
|
||||
#ifdef EGL_KHR_image_base
|
||||
drv->API.CreateImageKHR = _eglCreateImageKHR;
|
||||
drv->API.DestroyImageKHR = _eglDestroyImageKHR;
|
||||
#endif /* EGL_KHR_image_base */
|
||||
}
|
||||
|
||||
|
||||
|
51
src/egl/main/eglimage.c
Normal file
51
src/egl/main/eglimage.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "eglimage.h"
|
||||
#include "egldisplay.h"
|
||||
|
||||
|
||||
#ifdef EGL_KHR_image_base
|
||||
|
||||
|
||||
EGLBoolean
|
||||
_eglInitImage(_EGLDriver *drv, _EGLImage *img, const EGLint *attrib_list)
|
||||
{
|
||||
EGLint i;
|
||||
|
||||
img->Preserved = EGL_FALSE;
|
||||
|
||||
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
|
||||
switch (attrib_list[i]) {
|
||||
case EGL_IMAGE_PRESERVED_KHR:
|
||||
i++;
|
||||
img->Preserved = attrib_list[i];
|
||||
break;
|
||||
default:
|
||||
/* not an error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
_EGLImage *
|
||||
_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
|
||||
EGLenum target, EGLClientBuffer buffer,
|
||||
const EGLint *attr_list)
|
||||
{
|
||||
/* driver should override this function */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
EGLBoolean
|
||||
_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image)
|
||||
{
|
||||
/* driver should override this function */
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
#endif /* EGL_KHR_image_base */
|
95
src/egl/main/eglimage.h
Normal file
95
src/egl/main/eglimage.h
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef EGLIMAGE_INCLUDED
|
||||
#define EGLIMAGE_INCLUDED
|
||||
|
||||
|
||||
#include "egltypedefs.h"
|
||||
#include "egldisplay.h"
|
||||
|
||||
|
||||
/**
|
||||
* "Base" class for device driver images.
|
||||
*/
|
||||
struct _egl_image
|
||||
{
|
||||
/* An image is a display resource */
|
||||
_EGLResource Resource;
|
||||
|
||||
EGLBoolean Preserved;
|
||||
};
|
||||
|
||||
|
||||
PUBLIC EGLBoolean
|
||||
_eglInitImage(_EGLDriver *drv, _EGLImage *img, const EGLint *attrib_list);
|
||||
|
||||
|
||||
extern _EGLImage *
|
||||
_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
|
||||
EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list);
|
||||
|
||||
|
||||
extern EGLBoolean
|
||||
_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
|
||||
|
||||
|
||||
/**
|
||||
* Link an image to a display and return the handle of the link.
|
||||
* The handle can be passed to client directly.
|
||||
*/
|
||||
static INLINE EGLImageKHR
|
||||
_eglLinkImage(_EGLImage *img, _EGLDisplay *dpy)
|
||||
{
|
||||
_eglLinkResource(&img->Resource, _EGL_RESOURCE_IMAGE, dpy);
|
||||
return (EGLImageKHR) img;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unlink a linked image from its display.
|
||||
* Accessing an unlinked image should generate EGL_BAD_PARAMETER error.
|
||||
*/
|
||||
static INLINE void
|
||||
_eglUnlinkImage(_EGLImage *img)
|
||||
{
|
||||
_eglUnlinkResource(&img->Resource, _EGL_RESOURCE_IMAGE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lookup a handle to find the linked image.
|
||||
* Return NULL if the handle has no corresponding linked image.
|
||||
*/
|
||||
static INLINE _EGLImage *
|
||||
_eglLookupImage(EGLImageKHR image, _EGLDisplay *dpy)
|
||||
{
|
||||
_EGLResource *res = (_EGLResource *) image;
|
||||
_EGLImage *img = (_EGLImage *) image;
|
||||
if (!res || !dpy || !_eglCheckResource(res, _EGL_RESOURCE_IMAGE, dpy))
|
||||
img = NULL;
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the handle of a linked image, or EGL_NO_IMAGE_KHR.
|
||||
*/
|
||||
static INLINE EGLImageKHR
|
||||
_eglGetImageHandle(_EGLImage *img)
|
||||
{
|
||||
_EGLResource *res = (_EGLResource *) img;
|
||||
return (res && _eglIsResourceLinked(res)) ?
|
||||
(EGLImageKHR) img : EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the image is linked to a display.
|
||||
*/
|
||||
static INLINE EGLBoolean
|
||||
_eglIsImageLinked(_EGLImage *img)
|
||||
{
|
||||
_EGLResource *res = (_EGLResource *) img;
|
||||
return (res && _eglIsResourceLinked(res));
|
||||
}
|
||||
|
||||
|
||||
#endif /* EGLIMAGE_INCLUDED */
|
@@ -54,6 +54,14 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
|
||||
strcat(exts, "EGL_MESA_screen_surface ");
|
||||
if (dpy->Extensions.MESA_copy_context)
|
||||
strcat(exts, "EGL_MESA_copy_context ");
|
||||
|
||||
if (dpy->Extensions.KHR_image_base)
|
||||
strcat(exts, "EGL_KHR_image_base ");
|
||||
if (dpy->Extensions.KHR_image_pixmap)
|
||||
strcat(exts, "EGL_KHR_image_pixmap ");
|
||||
if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
|
||||
strcat(exts, "EGL_KHR_image ");
|
||||
|
||||
assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN);
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,8 @@ typedef struct _egl_driver _EGLDriver;
|
||||
|
||||
typedef struct _egl_extensions _EGLExtensions;
|
||||
|
||||
typedef struct _egl_image _EGLImage;
|
||||
|
||||
typedef struct _egl_mode _EGLMode;
|
||||
|
||||
typedef struct _egl_resource _EGLResource;
|
||||
|
Reference in New Issue
Block a user