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.
This commit is contained in:
Damien Lespiau 2011-05-16 16:43:30 +01:00
parent bde6979c06
commit f436582114
4 changed files with 105 additions and 3 deletions

View File

@ -347,6 +347,10 @@ if SUPPORT_EGL_PLATFORM_WAYLAND
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c $(srcdir)/winsys/cogl-winsys-egl.c
endif endif
if SUPPORT_EGL_PLATFORM_ANDROID
cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-egl.c
endif
if SUPPORT_STUB if SUPPORT_STUB
cogl_sources_c += \ cogl_sources_c += \
$(srcdir)/winsys/cogl-winsys-stub.c $(srcdir)/winsys/cogl-winsys-stub.c

View File

@ -33,6 +33,9 @@
#include <cogl/cogl-defines.h> #include <cogl/cogl-defines.h>
#include <cogl/cogl-display.h> #include <cogl/cogl-display.h>
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
#include <android/native_window.h>
#endif
G_BEGIN_DECLS G_BEGIN_DECLS
@ -68,6 +71,11 @@ EGLDisplay
cogl_context_egl_get_egl_display (CoglContext *context); cogl_context_egl_get_egl_display (CoglContext *context);
#endif #endif
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
void
cogl_android_set_native_window (ANativeWindow *window);
#endif
G_END_DECLS G_END_DECLS
#endif /* __COGL_CONTEXT_H__ */ #endif /* __COGL_CONTEXT_H__ */

View File

@ -48,6 +48,10 @@
#include <wayland-egl.h> #include <wayland-egl.h>
#endif #endif
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
#include <android/native_window.h>
#endif
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -111,7 +115,8 @@ typedef struct _CoglDisplayEGL
struct wl_egl_window *wayland_egl_native_window; struct wl_egl_window *wayland_egl_native_window;
EGLSurface dummy_surface; EGLSurface 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_GDL_SUPPORT) defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) || \
defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
EGLSurface egl_surface; EGLSurface egl_surface;
int egl_surface_width; int egl_surface_width;
int egl_surface_height; int egl_surface_height;
@ -206,6 +211,16 @@ initialize_function_table (CoglRenderer *renderer)
#include "cogl-winsys-egl-feature-functions.h" #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 #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
static CoglOnscreen * static CoglOnscreen *
find_onscreen_for_xid (CoglContext *context, guint32 xid) find_onscreen_for_xid (CoglContext *context, guint32 xid)
@ -749,6 +764,58 @@ try_create_context (CoglDisplay *display,
goto fail; 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) #elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
egl_display->egl_surface = egl_display->egl_surface =
@ -1219,7 +1286,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
wl_surface_map_toplevel (egl_onscreen->wayland_surface); 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) if (egl_display->have_onscreen)
{ {
g_set_error (error, COGL_WINSYS_ERROR, g_set_error (error, COGL_WINSYS_ERROR,
@ -1328,7 +1396,8 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
egl_display->dummy_surface, egl_display->dummy_surface,
egl_display->egl_context); egl_display->egl_context);
egl_context->current_surface = egl_display->dummy_surface; 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; return;
#else #else
#error "Unknown EGL platform" #error "Unknown EGL platform"

View File

@ -610,6 +610,27 @@ AS_IF([test "x$enable_wayland_egl_platform" == "xyes"],
AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_WAYLAND, AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_WAYLAND,
[test "x$enable_wayland_egl_platform" = "xyes"]) [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 This should go last, since it's the default fallback and we need
dnl to check the value of $EGL_PLATFORM_COUNT here. dnl to check the value of $EGL_PLATFORM_COUNT here.