[cogl/wip/wayland-compositor: 8/18] Add _cogl_egl_texture_2d_new_from_image API



commit 0f2a82dd60fd06553a3e3b514867d26d9a07995e
Author: Robert Bragg <robert linux intel com>
Date:   Tue May 24 22:34:10 2011 +0100

    Add _cogl_egl_texture_2d_new_from_image API
    
    This adds an internal texture_2d constructor that can wrap an EGLImage
    as a CoglTexture2D. The plan is to utilize this for texture-from-pixmap
    support with EGL as well as creating textures from wayland buffers.

 cogl/Makefile.am                                |   15 +++++--
 cogl/cogl-context-private.h                     |    1 +
 cogl/cogl-internal.h                            |    5 ++
 cogl/cogl-renderer.c                            |    4 +-
 cogl/cogl-texture-2d-private.h                  |   13 ++++++
 cogl/cogl-texture-2d.c                          |   48 +++++++++++++++++++++++
 cogl/cogl-texture.h                             |    3 +-
 cogl/driver/gl/cogl-feature-functions-gl.h      |   12 ++++++
 cogl/driver/gl/cogl-gl.c                        |    7 +++-
 cogl/driver/gles/cogl-feature-functions-gles.h  |   12 ++++++
 cogl/driver/gles/cogl-gles.c                    |    7 +++-
 cogl/winsys/cogl-winsys-egl-feature-functions.h |   17 ++++++++
 cogl/winsys/cogl-winsys-egl-private.h           |   46 ++++++++++++++++++++++
 cogl/winsys/cogl-winsys-egl.c                   |   31 +++++++++++++++
 14 files changed, 210 insertions(+), 11 deletions(-)
---
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 75d7d72..705e066 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -339,23 +339,28 @@ cogl_sources_c += \
 endif
 if SUPPORT_EGL_PLATFORM_POWERVR_X11
 cogl_sources_c += \
-	$(srcdir)/winsys/cogl-winsys-egl.c
+	$(srcdir)/winsys/cogl-winsys-egl.c \
+	$(srcdir)/winsys/cogl-winsys-egl-private.h
 endif
 if SUPPORT_EGL_PLATFORM_POWERVR_NULL
 cogl_sources_c += \
-       $(srcdir)/winsys/cogl-winsys-egl.c
+       $(srcdir)/winsys/cogl-winsys-egl.c \
+       $(srcdir)/winsys/cogl-winsys-egl-private.h
 endif
 if SUPPORT_EGL_PLATFORM_GDL
 cogl_sources_c += \
-       $(srcdir)/winsys/cogl-winsys-egl.c
+       $(srcdir)/winsys/cogl-winsys-egl.c \
+       $(srcdir)/winsys/cogl-winsys-egl-private.h
 endif
 if SUPPORT_EGL_PLATFORM_WAYLAND
 cogl_sources_c += \
-       $(srcdir)/winsys/cogl-winsys-egl.c
+       $(srcdir)/winsys/cogl-winsys-egl.c \
+       $(srcdir)/winsys/cogl-winsys-egl-private.h
 endif
 if SUPPORT_EGL_PLATFORM_ANDROID
 cogl_sources_c += \
-       $(srcdir)/winsys/cogl-winsys-egl.c
+       $(srcdir)/winsys/cogl-winsys-egl.c \
+       $(srcdir)/winsys/cogl-winsys-egl-private.h
 endif
 
 EXTRA_DIST += stb_image.c
diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
index 2cf1be5..2bc6528 100644
--- a/cogl/cogl-context-private.h
+++ b/cogl/cogl-context-private.h
@@ -65,6 +65,7 @@ struct _CoglContext
 
   /* Features cache */
   CoglFeatureFlags feature_flags;
+  CoglPrivateFeatureFlags private_feature_flags;
 
   CoglHandle        default_pipeline;
   CoglHandle        default_layer_0;
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h
index eba62bf..9f197e0 100644
--- a/cogl/cogl-internal.h
+++ b/cogl/cogl-internal.h
@@ -126,6 +126,11 @@ typedef enum { /*< prefix=COGL_DRIVER_ERROR >*/
   COGL_DRIVER_ERROR_INVALID_VERSION
 } CoglDriverError;
 
+typedef enum
+{
+  COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE = 1L<<0
+} CoglPrivateFeatureFlags;
+
 gboolean
 _cogl_check_extension (const char *name, const char *ext);
 
diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c
index d2badc8..0793870 100644
--- a/cogl/cogl-renderer.c
+++ b/cogl/cogl-renderer.c
@@ -40,13 +40,11 @@
 #include "cogl-display-private.h"
 #include "cogl-winsys-private.h"
 #include "cogl-winsys-stub-private.h"
+#include "cogl-winsys-egl-private.h"
 
 #ifdef COGL_HAS_GLX_SUPPORT
 extern const CoglWinsysVtable *_cogl_winsys_glx_get_vtable (void);
 #endif
-#ifdef COGL_HAS_EGL_SUPPORT
-extern const CoglWinsysVtable *_cogl_winsys_egl_get_vtable (void);
-#endif
 #ifdef COGL_HAS_WGL_SUPPORT
 extern const CoglWinsysVtable *_cogl_winsys_wgl_get_vtable (void);
 #endif
diff --git a/cogl/cogl-texture-2d-private.h b/cogl/cogl-texture-2d-private.h
index d05b342..97fee07 100644
--- a/cogl/cogl-texture-2d-private.h
+++ b/cogl/cogl-texture-2d-private.h
@@ -61,6 +61,19 @@ _cogl_texture_2d_new_from_bitmap (CoglBitmap      *bmp,
                                   CoglPixelFormat  internal_format,
                                   GError         **error);
 
+#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
+/* NB: The reason we require the width, height and format to be passed
+ * even though they may seem redundant is because GLES 1/2 don't
+ * provide a way to query these properties. */
+CoglTexture2D *
+_cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
+                                     int width,
+                                     int height,
+                                     CoglPixelFormat format,
+                                     EGLImageKHR image,
+                                     GError **error);
+#endif
+
 /*
  * _cogl_texture_2d_externally_modified:
  * @handle: A handle to a 2D texture
diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c
index 178bfc8..9f2e550 100644
--- a/cogl/cogl-texture-2d.c
+++ b/cogl/cogl-texture-2d.c
@@ -39,6 +39,7 @@
 #include "cogl-journal-private.h"
 #include "cogl-pipeline-opengl-private.h"
 #include "cogl-framebuffer-private.h"
+#include "cogl-winsys-egl-private.h"
 
 #include <string.h>
 #include <math.h>
@@ -493,6 +494,53 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
   return _cogl_texture_2d_handle_new (tex_2d);
 }
 
+#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base)
+/* NB: The reason we require the width, height and format to be passed
+ * even though they may seem redundant is because GLES 1/2 don't
+ * provide a way to query these properties. */
+CoglTexture2D *
+_cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
+                                     int width,
+                                     int height,
+                                     CoglPixelFormat format,
+                                     EGLImageKHR image,
+                                     GError **error)
+{
+  CoglTexture2D *tex_2d;
+  GLenum gl_error;
+
+  g_return_val_if_fail (_cogl_context_get_winsys (ctx) ==
+                        _cogl_winsys_egl_get_vtable (),
+                        NULL);
+
+  g_return_val_if_fail (ctx->private_feature_flags &
+                        COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE,
+                        NULL);
+
+  tex_2d = _cogl_texture_2d_create_base (width, height, COGL_TEXTURE_NONE,
+                                         format);
+
+  _cogl_texture_driver_gen (GL_TEXTURE_2D, 1, &tex_2d->gl_texture);
+  _cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
+                                   tex_2d->gl_texture,
+                                   FALSE);
+
+  while ((gl_error = glGetError ()) != GL_NO_ERROR)
+    ;
+  ctx->drv.pf_glEGLImageTargetTexture2D (GL_TEXTURE_2D, image);
+  if (glGetError () != GL_NO_ERROR)
+    {
+      g_set_error (error,
+                   COGL_TEXTURE_ERROR,
+                   COGL_TEXTURE_ERROR_BAD_PARAMETER,
+                   "Could not create a CoglTexture2D from a given EGLImage");
+      return NULL;
+    }
+
+  return _cogl_texture_2d_handle_new (tex_2d);
+}
+#endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */
+
 void
 _cogl_texture_2d_externally_modified (CoglHandle handle)
 {
diff --git a/cogl/cogl-texture.h b/cogl/cogl-texture.h
index 288a25b..93c1c3c 100644
--- a/cogl/cogl-texture.h
+++ b/cogl/cogl-texture.h
@@ -66,7 +66,8 @@ G_BEGIN_DECLS
  */
 typedef enum {
   COGL_TEXTURE_ERROR_SIZE,
-  COGL_TEXTURE_ERROR_FORMAT
+  COGL_TEXTURE_ERROR_FORMAT,
+  COGL_TEXTURE_ERROR_BAD_PARAMETER
 } CoglTextureError;
 
 GQuark cogl_texture_error_quark (void);
diff --git a/cogl/driver/gl/cogl-feature-functions-gl.h b/cogl/driver/gl/cogl-feature-functions-gl.h
index e26e4e9..734c76d 100644
--- a/cogl/driver/gl/cogl-feature-functions-gl.h
+++ b/cogl/driver/gl/cogl-feature-functions-gl.h
@@ -421,3 +421,15 @@ COGL_FEATURE_BEGIN (point_sprites, 2, 0,
                     COGL_FEATURE_POINT_SPRITE,
                     0)
 COGL_FEATURE_END ()
+COGL_FEATURE_BEGIN (EGL_image, 255, 255,
+                    "OES\0",
+                    "EGL_image\0",
+                    0,
+                    COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE)
+COGL_FEATURE_FUNCTION (void, glEGLImageTargetTexture2D,
+                       (GLenum           target,
+                        GLeglImageOES    image))
+COGL_FEATURE_FUNCTION (void, glEGLImageTargetRenderbufferStorage,
+                       (GLenum           target,
+                        GLeglImageOES    image))
+COGL_FEATURE_END ()
diff --git a/cogl/driver/gl/cogl-gl.c b/cogl/driver/gl/cogl-gl.c
index ce81a6a..a0c0198 100644
--- a/cogl/driver/gl/cogl-gl.c
+++ b/cogl/driver/gl/cogl-gl.c
@@ -155,6 +155,7 @@ static const CoglFeatureData cogl_feature_data[] =
 void
 _cogl_gl_update_features (CoglContext *context)
 {
+  CoglPrivateFeatureFlags private_flags = 0;
   CoglFeatureFlags flags = 0;
   const char *gl_extensions;
   int max_clip_planes = 0;
@@ -212,8 +213,12 @@ _cogl_gl_update_features (CoglContext *context)
                              gl_major, gl_minor,
                              gl_extensions,
                              context))
-      flags |= cogl_feature_data[i].feature_flags;
+      {
+        private_flags |= cogl_feature_data[i].feature_flags_private;
+        flags |= cogl_feature_data[i].feature_flags;
+      }
 
   /* Cache features */
+  context->private_feature_flags |= private_flags;
   context->feature_flags |= flags;
 }
diff --git a/cogl/driver/gles/cogl-feature-functions-gles.h b/cogl/driver/gles/cogl-feature-functions-gles.h
index b70b13b..b14c935 100644
--- a/cogl/driver/gles/cogl-feature-functions-gles.h
+++ b/cogl/driver/gles/cogl-feature-functions-gles.h
@@ -139,3 +139,15 @@ COGL_FEATURE_FUNCTION (void *, glMapBuffer,
 COGL_FEATURE_FUNCTION (GLboolean, glUnmapBuffer,
                        (GLenum           target))
 COGL_FEATURE_END ()
+COGL_FEATURE_BEGIN (EGL_image, 255, 255,
+                    "OES\0",
+                    "EGL_image\0",
+                    0,
+                    COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE)
+COGL_FEATURE_FUNCTION (void, glEGLImageTargetTexture2D,
+                       (GLenum           target,
+                        eglImageOES      image))
+COGL_FEATURE_FUNCTION (void, glEGLImageTargetRenderbufferStorage,
+                       (GLenum           target,
+                        eglImageOES      image))
+COGL_FEATURE_END ()
diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c
index 080efeb..2013d3e 100644
--- a/cogl/driver/gles/cogl-gles.c
+++ b/cogl/driver/gles/cogl-gles.c
@@ -77,6 +77,7 @@ static const CoglFeatureData cogl_feature_data[] =
 void
 _cogl_gl_update_features (CoglContext *context)
 {
+  CoglPrivateFeatureFlags private_flags = 0;
   CoglFeatureFlags flags = 0;
   const char *gl_extensions;
 #ifndef HAVE_COGL_GLES2
@@ -129,8 +130,12 @@ _cogl_gl_update_features (CoglContext *context)
                              0, 0,
                              gl_extensions,
                              context))
-      flags |= cogl_feature_data[i].feature_flags;
+      {
+        private_flags |= cogl_feature_data[i].feature_flags_private;
+        flags |= cogl_feature_data[i].feature_flags;
+      }
 
   /* Cache features */
+  context->private_feature_flags |= private_flags;
   context->feature_flags |= flags;
 }
diff --git a/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/winsys/cogl-winsys-egl-feature-functions.h
index 5a961ea..410f845 100644
--- a/cogl/winsys/cogl-winsys-egl-feature-functions.h
+++ b/cogl/winsys/cogl-winsys-egl-feature-functions.h
@@ -51,3 +51,20 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion,
                                EGLint numRects,
                                const EGLint *rects))
 COGL_WINSYS_FEATURE_END ()
+/* XXX: These macros can't handle falling back to looking for
+ * EGL_KHR_image if EGL_KHR_image_base and EGL_KHR_image_pixmap aren't
+ * found... */
+COGL_WINSYS_FEATURE_BEGIN (image_base,
+                           "KHR\0",
+                           "image_base\0",
+                           0)
+COGL_WINSYS_FEATURE_FUNCTION (EGLImageKHR, eglCreateImage,
+                              (EGLDisplay dpy,
+                               EGLContext ctx,
+                               EGLenum target,
+                               EGLClientBuffer buffer,
+                               const EGLint *attrib_list))
+COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroyImage,
+                              (EGLDisplay dpy,
+                               EGLImageKHR image))
+COGL_WINSYS_FEATURE_END ()
diff --git a/cogl/winsys/cogl-winsys-egl-private.h b/cogl/winsys/cogl-winsys-egl-private.h
new file mode 100644
index 0000000..dd2df8e
--- /dev/null
+++ b/cogl/winsys/cogl-winsys-egl-private.h
@@ -0,0 +1,46 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ */
+
+#ifndef __COGL_WINSYS_EGL_PRIVATE_H
+#define __COGL_WINSYS_EGL_PRIVATE_H
+
+#include "cogl-defines.h"
+#include "cogl-winsys-private.h"
+#include "cogl-context.h"
+
+const CoglWinsysVtable *
+_cogl_winsys_egl_get_vtable (void);
+
+#ifdef EGL_KHR_image_base
+EGLImageKHR
+_cogl_egl_create_image (CoglContext *ctx,
+                        EGLenum target,
+                        EGLClientBuffer buffer,
+                        const EGLint *attribs);
+
+void
+_cogl_egl_destroy_image (CoglContext *ctx,
+                         EGLImageKHR image);
+#endif
+
+#endif /* __COGL_WINSYS_EGL_PRIVATE_H */
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index 3af67c1..d2fa23d 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -1638,3 +1638,34 @@ cogl_wayland_onscreen_get_surface (CoglOnscreen *onscreen)
 }
 
 #endif /* COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT */
+
+#ifdef EGL_KHR_image_base
+EGLImageKHR
+_cogl_egl_create_image (CoglContext *ctx,
+                        EGLenum target,
+                        EGLClientBuffer buffer,
+                        const EGLint *attribs)
+{
+  CoglDisplayEGL *egl_display = ctx->display->winsys;
+  CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
+
+  g_return_val_if_fail (egl_renderer->pf_eglCreateImage, EGL_NO_IMAGE_KHR);
+
+  return egl_renderer->pf_eglCreateImage (egl_renderer->edpy,
+                                          egl_display->egl_context,
+                                          target,
+                                          buffer,
+                                          attribs);
+}
+
+void
+_cogl_egl_destroy_image (CoglContext *ctx,
+                         EGLImageKHR image)
+{
+  CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
+
+  g_return_if_fail (egl_renderer->pf_eglDestroyImage);
+
+  egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image);
+}
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]