OSDN Git Service

egl: Add support for EGL_KHR_image_base.
authorChia-I Wu <olvaffe@gmail.com>
Sat, 15 Aug 2009 14:58:13 +0000 (22:58 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Mon, 14 Sep 2009 05:39:18 +0000 (13:39 +0800)
Individual drivers still need to implement the API hooks.

src/egl/main/Makefile
src/egl/main/eglapi.c
src/egl/main/eglapi.h
src/egl/main/eglclient.c [new file with mode: 0644]
src/egl/main/eglclient.h [new file with mode: 0644]
src/egl/main/egldisplay.h
src/egl/main/egldriver.c
src/egl/main/eglimage.c [new file with mode: 0644]
src/egl/main/eglimage.h [new file with mode: 0644]
src/egl/main/eglmisc.c
src/egl/main/egltypedefs.h

index c951b07..1fc51e9 100644 (file)
@@ -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 \
index 29617b7..d39266f 100644 (file)
@@ -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 */
index 6081e58..c2c4339 100644 (file)
@@ -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 (file)
index 0000000..8426301
--- /dev/null
@@ -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 (file)
index 0000000..0158664
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef EGLCLIENT_INCLUDED
+#define EGLCLIENT_INCLUDED
+
+
+#include "egltypedefs.h"
+
+
+extern void *
+_eglClientGetImageData(EGLImageKHR image);
+
+
+#endif /* EGLCLIENT_INCLUDED */
index 6575fdf..cf103b3 100644 (file)
@@ -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;
 };
 
 
index 87786e3..89e04a7 100644 (file)
@@ -19,6 +19,7 @@
 #include "eglscreen.h"
 #include "eglstring.h"
 #include "eglsurface.h"
+#include "eglimage.h"
 
 #if defined(_EGL_PLATFORM_X)
 #include <dlfcn.h>
@@ -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 (file)
index 0000000..dc1c728
--- /dev/null
@@ -0,0 +1,104 @@
+#include <assert.h>
+
+#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 (file)
index 0000000..3a96028
--- /dev/null
@@ -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 */
index b37213f..f40321b 100644 (file)
@@ -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);
 }
 
index 4461440..b632171 100644 (file)
@@ -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);