Move the EGL Android winsys out of cogl-winsys-egl

This moves all of the code specific to the Android platform out of
cogl-winsys-egl. It is completely untested apart from that it
compiles using a dummy android/native_window.h header.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2011-12-13 13:09:34 +00:00
parent d70c764da6
commit 3a4dce0c53
3 changed files with 213 additions and 166 deletions

View File

@ -29,8 +29,197 @@
#include "config.h" #include "config.h"
#endif #endif
#include <android/native_window.h>
#include "cogl-winsys-egl-android-private.h" #include "cogl-winsys-egl-android-private.h"
#include "cogl-winsys-egl-private.h" #include "cogl-winsys-egl-private.h"
#include "cogl-renderer-private.h"
#include "cogl-framebuffer-private.h"
#include "cogl-onscreen-private.h"
#include "cogl-private.h"
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
typedef struct _CoglDisplayAndroid
{
int egl_surface_width;
int egl_surface_height;
gboolean have_onscreen;
} CoglDisplayAndroid;
static ANativeWindow *android_native_window;
void
cogl_android_set_native_window (ANativeWindow *window)
{
_cogl_init ();
android_native_window = window;
}
static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
{
CoglRendererEGL *egl_renderer = renderer->winsys;
eglTerminate (egl_renderer->edpy);
g_slice_free (CoglRendererEGL, egl_renderer);
}
static gboolean
_cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error)
{
CoglRendererEGL *egl_renderer;
renderer->winsys = g_slice_new0 (CoglRendererEGL);
egl_renderer = renderer->winsys;
egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable;
egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
goto error;
return TRUE;
error:
_cogl_winsys_renderer_disconnect (renderer);
return FALSE;
}
static gboolean
_cogl_winsys_egl_context_created (CoglDisplay *display,
GError **error)
{
CoglRenderer *renderer = display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys;
CoglDisplayEGL *egl_display = display->winsys;
CoglDisplayAndroid *android_display = egl_display->platform;
const char *error_message;
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 (egl_renderer->edpy,
egl_display->egl_config,
EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry (android_native_window,
0,
0,
format);
egl_display->egl_surface =
eglCreateWindowSurface (egl_renderer->edpy,
egl_display->egl_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,
&android_display->egl_surface_width);
eglQuerySurface (egl_renderer->edpy,
egl_display->egl_surface,
EGL_HEIGHT,
&android_display->egl_surface_height);
return TRUE;
fail:
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_CONTEXT,
"%s", error_message);
return FALSE;
}
static gboolean
_cogl_winsys_egl_display_setup (CoglDisplay *display,
GError **error)
{
CoglDisplayEGL *egl_display = display->winsys;
CoglDisplayAndroid *android_display;
android_display = g_slice_new0 (CoglDisplayAndroid);
egl_display->platform = android_display;
return TRUE;
}
static void
_cogl_winsys_egl_display_destroy (CoglDisplay *display)
{
CoglDisplayEGL *egl_display = display->winsys;
g_slice_free (CoglDisplayAndroid, egl_display->platform);
}
static gboolean
_cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
EGLConfig egl_config,
GError **error)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
CoglContext *context = framebuffer->context;
CoglDisplay *display = context->display;
CoglDisplayEGL *egl_display = display->winsys;
CoglDisplayAndroid *android_display = egl_display->platform;
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
if (android_display->have_onscreen)
{
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
"EGL platform only supports a single onscreen window");
return FALSE;
}
egl_onscreen->egl_surface = egl_display->egl_surface;
_cogl_framebuffer_winsys_update_size (framebuffer,
android_display->egl_surface_width,
android_display->egl_surface_height);
android_display->have_onscreen = TRUE;
return TRUE;
}
static const CoglWinsysEGLVtable
_cogl_winsys_egl_vtable =
{
.display_setup = _cogl_winsys_egl_display_setup,
.display_destroy = _cogl_winsys_egl_display_destroy,
.context_created = _cogl_winsys_egl_context_created,
.onscreen_init = _cogl_winsys_egl_onscreen_init,
};
const CoglWinsysVtable * const CoglWinsysVtable *
_cogl_winsys_egl_android_get_vtable (void) _cogl_winsys_egl_android_get_vtable (void)
@ -48,6 +237,9 @@ _cogl_winsys_egl_android_get_vtable (void)
vtable.id = COGL_WINSYS_ID_EGL_ANDROID; vtable.id = COGL_WINSYS_ID_EGL_ANDROID;
vtable.name = "EGL_ANDROID"; vtable.name = "EGL_ANDROID";
vtable.renderer_connect = _cogl_winsys_renderer_connect;
vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect;
vtable_inited = TRUE; vtable_inited = TRUE;
} }

View File

@ -112,11 +112,6 @@ typedef struct _CoglDisplayEGL
{ {
EGLContext egl_context; EGLContext egl_context;
EGLSurface dummy_surface; EGLSurface dummy_surface;
#if defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
int egl_surface_width;
int egl_surface_height;
gboolean have_onscreen;
#endif
EGLSurface egl_surface; EGLSurface egl_surface;
EGLConfig egl_config; EGLConfig egl_config;

View File

@ -43,10 +43,6 @@
#include "cogl-private.h" #include "cogl-private.h"
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
#include <android/native_window.h>
#endif
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
@ -104,26 +100,11 @@ _cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,
return ptr; return ptr;
} }
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
static ANativeWindow *android_native_window;
void
cogl_android_set_native_window (ANativeWindow *window)
{
_cogl_init ();
android_native_window = window;
}
#endif
static void static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) _cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
{ {
CoglRendererEGL *egl_renderer = renderer->winsys; /* This function must be overridden by a platform winsys */
g_assert_not_reached ();
eglTerminate (egl_renderer->edpy);
g_slice_free (CoglRendererEGL, egl_renderer);
} }
/* Updates all the function pointers */ /* Updates all the function pointers */
@ -176,31 +157,8 @@ static gboolean
_cogl_winsys_renderer_connect (CoglRenderer *renderer, _cogl_winsys_renderer_connect (CoglRenderer *renderer,
GError **error) GError **error)
{ {
CoglRendererEGL *egl_renderer; /* This function must be overridden by a platform winsys */
g_assert_not_reached ();
renderer->winsys = g_slice_new0 (CoglRendererEGL);
egl_renderer = renderer->winsys;
switch (renderer->winsys_vtable->id)
{
default:
g_warn_if_reached ();
goto error;
case COGL_WINSYS_ID_EGL_ANDROID:
egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
break;
}
if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
goto error;
return TRUE;
error:
_cogl_winsys_renderer_disconnect (renderer);
return FALSE;
} }
static void static void
@ -214,8 +172,7 @@ egl_attributes_from_framebuffer_config (CoglDisplay *display,
int i = 0; int i = 0;
/* Let the platform add attributes first */ /* Let the platform add attributes first */
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->add_config_attributes)
egl_renderer->platform_vtable->add_config_attributes)
i = egl_renderer->platform_vtable->add_config_attributes (display, i = egl_renderer->platform_vtable->add_config_attributes (display,
config, config,
attributes); attributes);
@ -293,8 +250,7 @@ try_create_context (CoglDisplay *display,
attribs[0] = EGL_NONE; attribs[0] = EGL_NONE;
/* Divert to the platform implementation if one is defined */ /* Divert to the platform implementation if one is defined */
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->try_create_context)
egl_renderer->platform_vtable->try_create_context)
return egl_renderer->platform_vtable-> return egl_renderer->platform_vtable->
try_create_context (display, attribs, error); try_create_context (display, attribs, error);
@ -327,71 +283,9 @@ try_create_context (CoglDisplay *display,
goto fail; goto fail;
} }
switch (renderer->winsys_vtable->id) if (egl_renderer->platform_vtable->context_created &&
{ !egl_renderer->platform_vtable->context_created (display, error))
default: return FALSE;
if (egl_renderer->platform_vtable &&
egl_renderer->platform_vtable->context_created &&
!egl_renderer->platform_vtable->context_created (display, error))
return FALSE;
break;
#ifdef COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT
case COGL_WINSYS_ID_EGL_ANDROID:
{
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);
}
break;
#endif
}
return TRUE; return TRUE;
@ -417,8 +311,7 @@ cleanup_context (CoglDisplay *display)
egl_display->egl_context = EGL_NO_CONTEXT; egl_display->egl_context = EGL_NO_CONTEXT;
} }
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->cleanup_context)
egl_renderer->platform_vtable->cleanup_context)
egl_renderer->platform_vtable->cleanup_context (display); egl_renderer->platform_vtable->cleanup_context (display);
} }
@ -457,8 +350,7 @@ _cogl_winsys_display_destroy (CoglDisplay *display)
cleanup_context (display); cleanup_context (display);
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->display_destroy)
egl_renderer->platform_vtable->display_destroy)
egl_renderer->platform_vtable->display_destroy (display); egl_renderer->platform_vtable->display_destroy (display);
g_slice_free (CoglDisplayEGL, display->winsys); g_slice_free (CoglDisplayEGL, display->winsys);
@ -489,8 +381,7 @@ _cogl_winsys_display_setup (CoglDisplay *display,
} }
#endif #endif
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->display_setup &&
egl_renderer->platform_vtable->display_setup &&
!egl_renderer->platform_vtable->display_setup (display, error)) !egl_renderer->platform_vtable->display_setup (display, error))
goto error; goto error;
@ -532,8 +423,7 @@ _cogl_winsys_context_init (CoglContext *context, GError **error)
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
} }
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->context_init &&
egl_renderer->platform_vtable->context_init &&
!egl_renderer->platform_vtable->context_init (context, error)) !egl_renderer->platform_vtable->context_init (context, error))
return FALSE; return FALSE;
@ -546,8 +436,7 @@ _cogl_winsys_context_deinit (CoglContext *context)
CoglRenderer *renderer = context->display->renderer; CoglRenderer *renderer = context->display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererEGL *egl_renderer = renderer->winsys;
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->context_deinit)
egl_renderer->platform_vtable->context_deinit)
egl_renderer->platform_vtable->context_deinit (context); egl_renderer->platform_vtable->context_deinit (context);
g_free (context->winsys); g_free (context->winsys);
@ -563,7 +452,6 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
CoglDisplayEGL *egl_display = display->winsys; CoglDisplayEGL *egl_display = display->winsys;
CoglRenderer *renderer = display->renderer; CoglRenderer *renderer = display->renderer;
CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererEGL *egl_renderer = renderer->winsys;
CoglOnscreenEGL *egl_onscreen;
EGLint attributes[MAX_EGL_CONFIG_ATTRIBS]; EGLint attributes[MAX_EGL_CONFIG_ATTRIBS];
EGLConfig egl_config; EGLConfig egl_config;
EGLint config_count = 0; EGLint config_count = 0;
@ -603,41 +491,14 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
} }
onscreen->winsys = g_slice_new0 (CoglOnscreenEGL); onscreen->winsys = g_slice_new0 (CoglOnscreenEGL);
egl_onscreen = onscreen->winsys;
switch (renderer->winsys_vtable->id) if (egl_renderer->platform_vtable->onscreen_init &&
!egl_renderer->platform_vtable->onscreen_init (onscreen,
egl_config,
error))
{ {
default: g_slice_free (CoglOnscreenEGL, onscreen->winsys);
if (egl_renderer->platform_vtable && return FALSE;
egl_renderer->platform_vtable->onscreen_init &&
!egl_renderer->platform_vtable->onscreen_init (onscreen,
egl_config,
error))
{
g_slice_free (CoglOnscreenEGL, onscreen->winsys);
return FALSE;
}
break;
#if defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
case COGL_WINSYS_ID_EGL_ANDROID:
if (egl_display->have_onscreen)
{
g_set_error (error, COGL_WINSYS_ERROR,
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
"EGL platform only supports a single onscreen window");
return FALSE;
}
egl_onscreen->egl_surface = egl_display->egl_surface;
_cogl_framebuffer_winsys_update_size (framebuffer,
egl_display->egl_surface_width,
egl_display->egl_surface_height);
egl_display->have_onscreen = TRUE;
break;
#endif
} }
return TRUE; return TRUE;
@ -663,8 +524,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
egl_onscreen->egl_surface = EGL_NO_SURFACE; egl_onscreen->egl_surface = EGL_NO_SURFACE;
} }
if (egl_renderer->platform_vtable && if (egl_renderer->platform_vtable->onscreen_deinit)
egl_renderer->platform_vtable->onscreen_deinit)
egl_renderer->platform_vtable->onscreen_deinit (onscreen); egl_renderer->platform_vtable->onscreen_deinit (onscreen);
g_slice_free (CoglOnscreenEGL, onscreen->winsys); g_slice_free (CoglOnscreenEGL, onscreen->winsys);