[cogl/wip/android: 10/13] android: Add support for an EGL/Android winsys



commit 841e81b509795eac619ee7296c55c01b521842a4
Author: Damien Lespiau <damien lespiau intel com>
Date:   Mon May 16 16:43:30 2011 +0100

    android: Add support for an EGL/Android winsys
    
    The native window type of the EGL/Android winsys is ANativeWinow*. The
    Android NDK gives you a pointer to this ANativeWindow and you just need
    to configure that window using the EGLConfig you are choosing when
    creating the context.
    
    This means you have to know the ANativeWindow* window before creating
    the context. This is solved here by just having a global variable you
    can set with cogl_android_set_native_window() before creating the
    context. This is a bit ugly though, and it conceptually belongs to the
    OnScreen creation to know which ANativeWindow* to use. This would need a
    "lazy context creation" mechanism, waiting for the user to create the
    OnScreen to initialize the GL context.

 cogl/Makefile.am              |    4 ++
 cogl/cogl-context.h           |    8 ++++
 cogl/winsys/cogl-winsys-egl.c |   75 +++++++++++++++++++++++++++++++++++++++--
 configure.ac                  |   21 +++++++++++
 4 files changed, 105 insertions(+), 3 deletions(-)
---
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index de07dcd..86f5754 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -344,6 +344,10 @@ if SUPPORT_EGL_PLATFORM_WAYLAND
 cogl_sources_c += \
        $(srcdir)/winsys/cogl-winsys-egl.c
 endif
+if SUPPORT_EGL_PLATFORM_ANDROID
+cogl_sources_c += \
+       $(srcdir)/winsys/cogl-winsys-egl.c
+endif
 if SUPPORT_STUB
 cogl_sources_c += \
        $(srcdir)/winsys/cogl-winsys-stub.c
diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h
index bce47f1..7a6276d 100644
--- a/cogl/cogl-context.h
+++ b/cogl/cogl-context.h
@@ -33,6 +33,9 @@
 
 #include <cogl/cogl-defines.h>
 #include <cogl/cogl-display.h>
+#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
+#include <android/native_window.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -68,6 +71,11 @@ EGLDisplay
 cogl_context_egl_get_egl_display (CoglContext *context);
 #endif
 
+#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
+void
+cogl_android_set_native_window (ANativeWindow *window);
+#endif
+
 G_END_DECLS
 
 #endif /* __COGL_CONTEXT_H__ */
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index 7cd32d7..ef06a39 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -48,6 +48,10 @@
 #include <wayland-egl.h>
 #endif
 
+#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
+#include <android/native_window.h>
+#endif
+
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -111,7 +115,8 @@ typedef struct _CoglDisplayEGL
   struct wl_egl_window *wayland_egl_native_window;
   EGLSurface dummy_surface;
 #elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
-      defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT)
+      defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) || \
+      defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
   EGLSurface egl_surface;
   int egl_surface_width;
   int egl_surface_height;
@@ -206,6 +211,16 @@ initialize_function_table (CoglRenderer *renderer)
 #include "cogl-winsys-egl-feature-functions.h"
 }
 
+#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
+static ANativeWindow *android_native_window;
+
+void
+cogl_android_set_native_window (ANativeWindow *window)
+{
+  android_native_window = window;
+}
+#endif
+
 #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
 static CoglOnscreen *
 find_onscreen_for_xid (CoglContext *context, guint32 xid)
@@ -749,6 +764,58 @@ try_create_context (CoglDisplay *display,
       goto fail;
     }
 
+#elif defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
+  {
+    EGLint format;
+
+    if (android_native_window == NULL)
+      {
+        error_message = "No ANativeWindow window specified with "
+          "cogl_android_set_native_window()";
+        goto fail;
+      }
+
+    /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
+     * guaranteed to be accepted by ANativeWindow_setBuffersGeometry ().
+     * As soon as we picked a EGLConfig, we can safely reconfigure the
+     * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
+    eglGetConfigAttrib (edpy, config, EGL_NATIVE_VISUAL_ID, &format);
+
+    ANativeWindow_setBuffersGeometry (android_native_window,
+                                      0,
+                                      0,
+                                      format);
+
+    egl_display->egl_surface =
+      eglCreateWindowSurface (edpy,
+                              config,
+                              (NativeWindowType) android_native_window,
+                              NULL);
+    if (egl_display->egl_surface == EGL_NO_SURFACE)
+      {
+        error_message = "Unable to create EGL window surface";
+        goto fail;
+      }
+
+    if (!eglMakeCurrent (egl_renderer->edpy,
+                         egl_display->egl_surface,
+                         egl_display->egl_surface,
+                         egl_display->egl_context))
+      {
+        error_message = "Unable to eglMakeCurrent with egl surface";
+        goto fail;
+      }
+
+    eglQuerySurface (egl_renderer->edpy,
+                     egl_display->egl_surface,
+                     EGL_WIDTH,
+                     &egl_display->egl_surface_width);
+
+    eglQuerySurface (egl_renderer->edpy,
+                     egl_display->egl_surface,
+                     EGL_HEIGHT,
+                     &egl_display->egl_surface_height);
+  }
 #elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
 
   egl_display->egl_surface =
@@ -1223,7 +1290,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
 
   wl_surface_map_toplevel (egl_onscreen->wayland_surface);
 
-#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
+#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
+      defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
   if (egl_display->have_onscreen)
     {
       g_set_error (error, COGL_WINSYS_ERROR,
@@ -1332,7 +1400,8 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
                       egl_display->dummy_surface,
                       egl_display->egl_context);
       egl_context->current_surface = egl_display->dummy_surface;
-#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
+#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
+      defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
       return;
 #else
 #error "Unknown EGL platform"
diff --git a/configure.ac b/configure.ac
index 7583070..0ce5328 100644
--- a/configure.ac
+++ b/configure.ac
@@ -610,6 +610,27 @@ AS_IF([test "x$enable_wayland_egl_platform" == "xyes"],
 AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_WAYLAND,
                [test "x$enable_wayland_egl_platform" = "xyes"])
 
+dnl Android EGL platform
+AC_ARG_ENABLE(
+  [android-egl-platform],
+  [AC_HELP_STRING([--enable-android-egl-platform=@<:@no/yes@:>@], [Enable support for the Android egl platform @<:@default=no@:>@])],
+  [],
+  enable_android_egl_platform=no
+)
+AS_IF([test "x$enable_android_egl_platform" == "xyes"],
+      [
+        EGL_PLATFORM_COUNT=$((EGL_PLATFORM_COUNT+1))
+        NEED_EGL=yes
+        EGL_PLATFORMS="$EGL_PLATFORMS android"
+
+        AC_CHECK_HEADER([android/native_window.h],
+                        [],
+                        [AC_MSG_ERROR([Unable to locate android/native_window.h])])
+
+        COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT"
+      ])
+AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_ANDROID,
+               [test "x$enable_android_egl_platform" = "xyes"])
 
 dnl This should go last, since it's the default fallback and we need
 dnl to check the value of $EGL_PLATFORM_COUNT here.



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