From 9e9a4cf4711e72a5eba81476205392097b107e07 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 15 Aug 2009 22:58:13 +0800 Subject: egl: Add support for EGL_KHR_image_base. Individual drivers still need to implement the API hooks. --- src/egl/main/Makefile | 4 ++ src/egl/main/eglapi.c | 51 ++++++++++++++++++++++ src/egl/main/eglapi.h | 13 +++++- src/egl/main/eglclient.c | 21 +++++++++ src/egl/main/eglclient.h | 12 ++++++ src/egl/main/egldisplay.h | 5 +++ src/egl/main/egldriver.c | 6 +++ src/egl/main/eglimage.c | 104 +++++++++++++++++++++++++++++++++++++++++++++ src/egl/main/eglimage.h | 93 ++++++++++++++++++++++++++++++++++++++++ src/egl/main/eglmisc.c | 6 +++ src/egl/main/egltypedefs.h | 2 + 11 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 src/egl/main/eglclient.c create mode 100644 src/egl/main/eglclient.h create mode 100644 src/egl/main/eglimage.c create mode 100644 src/egl/main/eglimage.h diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index c951b070f1..1fc51e930e 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -7,6 +7,7 @@ include $(TOP)/configs/current INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES) HEADERS = \ + eglclient.h \ eglcompiler.h \ eglconfig.h \ eglconfigutil.h \ @@ -16,6 +17,7 @@ HEADERS = \ egldisplay.h \ egldriver.h \ eglglobals.h \ + eglimage.h \ egllog.h \ eglmisc.h \ eglmode.h \ @@ -26,6 +28,7 @@ HEADERS = \ SOURCES = \ eglapi.c \ + eglclient.c \ eglconfig.c \ eglconfigutil.c \ eglcontext.c \ @@ -33,6 +36,7 @@ SOURCES = \ egldisplay.c \ egldriver.c \ eglglobals.c \ + eglimage.c \ egllog.c \ eglmisc.c \ eglmode.c \ diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 29617b7aff..d39266fda3 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -41,6 +41,7 @@ #include "eglconfig.h" #include "eglscreen.h" #include "eglmode.h" +#include "eglimage.h" /** @@ -644,6 +645,10 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))() { "eglReleaseThread", (_EGLProc) eglReleaseThread }, { "eglWaitClient", (_EGLProc) eglWaitClient }, #endif /* EGL_VERSION_1_2 */ +#ifdef EGL_KHR_image_base + { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, + { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, +#endif /* EGL_KHR_image_base */ { NULL, NULL } }; EGLint i; @@ -968,3 +973,49 @@ eglWaitClient(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__); + + return drv->API.DestroyImageKHR(drv, disp, img); +} + + +#endif /* EGL_KHR_image_base */ diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index 6081e58892..c2c4339294 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -70,6 +70,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 @@ -105,7 +110,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; @@ -118,11 +123,17 @@ struct _egl_api QueryScreenSurfaceMESA_t QueryScreenSurfaceMESA; QueryScreenModeMESA_t QueryScreenModeMESA; QueryModeStringMESA_t QueryModeStringMESA; +#endif /* EGL_MESA_screen_surface */ #ifdef EGL_VERSION_1_2 WaitClient_t WaitClient; CreatePbufferFromClientBuffer_t CreatePbufferFromClientBuffer; #endif + +#ifdef EGL_KHR_image_base + CreateImageKHR_t CreateImageKHR; + DestroyImageKHR_t DestroyImageKHR; +#endif /* EGL_KHR_image_base */ }; #endif /* EGLAPI_INCLUDED */ diff --git a/src/egl/main/eglclient.c b/src/egl/main/eglclient.c new file mode 100644 index 0000000000..8426301948 --- /dev/null +++ b/src/egl/main/eglclient.c @@ -0,0 +1,21 @@ +/** + * Functions that client APIs can call. + */ + + +#include "eglcurrent.h" +#include "egldisplay.h" +#include "eglimage.h" +#include "eglclient.h" + + +/** + * Return the opaque client data of an image. + */ +void * +_eglClientGetImageData(EGLImageKHR image) +{ + _EGLDisplay *dpy = _eglGetCurrentDisplay(); + _EGLImage *img = _eglLookupImage(image, dpy); + return (img) ? img->ClientData : NULL; +} diff --git a/src/egl/main/eglclient.h b/src/egl/main/eglclient.h new file mode 100644 index 0000000000..0158664936 --- /dev/null +++ b/src/egl/main/eglclient.h @@ -0,0 +1,12 @@ +#ifndef EGLCLIENT_INCLUDED +#define EGLCLIENT_INCLUDED + + +#include "egltypedefs.h" + + +extern void * +_eglClientGetImageData(EGLImageKHR image); + + +#endif /* EGLCLIENT_INCLUDED */ diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 6575fdf198..cf103b35c6 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -14,6 +14,9 @@ struct _egl_extensions { EGLBoolean MESA_screen_surface; EGLBoolean MESA_copy_context; + EGLBoolean KHR_image; + EGLBoolean KHR_image_base; + EGLBoolean KHR_image_pixmap; char String[_EGL_MAX_EXTENSIONS_LEN]; }; @@ -50,6 +53,8 @@ struct _egl_display /* lists of linked contexts and surface */ _EGLContext *ContextList; _EGLSurface *SurfaceList; + + _EGLImage *ImageList; }; diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 87786e36bb..89e04a7130 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -19,6 +19,7 @@ #include "eglscreen.h" #include "eglstring.h" #include "eglsurface.h" +#include "eglimage.h" #if defined(_EGL_PLATFORM_X) #include @@ -404,6 +405,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 */ } diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c new file mode 100644 index 0000000000..dc1c728320 --- /dev/null +++ b/src/egl/main/eglimage.c @@ -0,0 +1,104 @@ +#include + +#include "eglimage.h" +#include "egldisplay.h" + +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; +} + + +EGLImageKHR +_eglLinkImage(_EGLImage *img, _EGLDisplay *dpy) +{ + img->Display = dpy; + img->Next = dpy->ImageList; + dpy->ImageList = img; + return (EGLImageKHR) img; +} + + +void +_eglUnlinkImage(_EGLImage *img) +{ + _EGLImage *prev; + + prev = img->Display->ImageList; + if (prev != img) { + while (prev) { + if (prev->Next == img) + break; + prev = prev->Next; + } + assert(prev); + prev->Next = img->Next; + } + else { + img->Display->ImageList = img->Next; + } + + img->Next = NULL; + img->Display = NULL; +} + + +#ifndef _EGL_SKIP_HANDLE_CHECK + + +/** + * Return EGL_TRUE if the given handle is a valid handle to an image. + */ +EGLBoolean +_eglCheckImageHandle(EGLImageKHR img, _EGLDisplay *dpy) +{ + _EGLImage *cur = NULL; + + if (dpy) + cur = dpy->ImageList; + while (cur) { + if (cur == (_EGLImage *) img) { + assert(cur->Display == dpy); + break; + } + cur = cur->Next; + } + return (cur != NULL); +} + + +#endif /* _EGL_SKIP_HANDLE_CHECK */ diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h new file mode 100644 index 0000000000..3a96028e3d --- /dev/null +++ b/src/egl/main/eglimage.h @@ -0,0 +1,93 @@ +#ifndef EGLIMAGE_INCLUDED +#define EGLIMAGE_INCLUDED + + +#include "egltypedefs.h" + + +/** + * "Base" class for device driver images. + */ +struct _egl_image +{ + /* Client data that client APIs and the driver agree on */ + void *ClientData; + + /* Managed by EGLDisplay for linking */ + _EGLDisplay *Display; + _EGLImage *Next; + + EGLBoolean Preserved; +}; + + +extern 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); + + +extern EGLImageKHR +_eglLinkImage(_EGLImage *img, _EGLDisplay *dpy); + + +extern void +_eglUnlinkImage(_EGLImage *img); + + +#ifndef _EGL_SKIP_HANDLE_CHECK + + +extern EGLBoolean +_eglCheckImageHandle(EGLImageKHR img, _EGLDisplay *dpy); + + +#else + + +/** + * Perform a quick check on the handle. + */ +static INLINE EGLBoolean +_eglCheckImageHandle(EGLImageKHR img, _EGLDisplay *dpy) +{ + _EGLImage *i = (_EGLImage *) img; + return (dpy && i && i->Display == dpy); +} + + +#endif + + +/** + * 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) +{ + _EGLImage *img = (_EGLImage *) image; + if (!_eglCheckImageHandle(img, dpy)) + img = NULL; + return img; +} + + +/** + * Return the handle of a linked image. + */ +static INLINE EGLImageKHR +_eglGetImageHandle(_EGLImage *img) +{ + return (EGLImageKHR) ((img && img->Display) ? img : EGL_NO_IMAGE_KHR); +} + + +#endif /* EGLIMAGE_INCLUDED */ diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c index b37213faf1..f40321b1df 100644 --- a/src/egl/main/eglmisc.c +++ b/src/egl/main/eglmisc.c @@ -54,6 +54,12 @@ _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) + strcat(exts, "EGL_KHR_image "); + if (dpy->Extensions.KHR_image_base) + strcat(exts, "EGL_KHR_image_base "); + if (dpy->Extensions.KHR_image_pixmap) + strcat(exts, "EGL_KHR_image_pixmap "); assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN); } diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index 4461440b9b..b6321716d3 100644 --- a/src/egl/main/egltypedefs.h +++ b/src/egl/main/egltypedefs.h @@ -28,6 +28,8 @@ typedef struct _egl_surface _EGLSurface; typedef struct _egl_thread_info _EGLThreadInfo; +typedef struct _egl_image _EGLImage; + typedef _EGLDriver *(*_EGLMain_t)(const char *args); -- cgit v1.2.3