[Cogl] [PATCH 1/3] Support window resizing in the SDL 2 winsys
Robert Bragg
robert at sixbynine.org
Tue Nov 20 14:48:22 PST 2012
This looks good to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
- Robert
On Tue, Nov 20, 2012 at 6:53 PM, Neil Roberts <neil at linux.intel.com> wrote:
> The SDL2 winsys will now set the SDL_WINDOW_RESIZABLE flag on the
> window before creating it if the resizable property is set on the
> onscreen. Note that there doesn't appear to be a way in SDL to change
> the flag later so unlike the other winsyses it will only take affect
> if it is set before allocating the framebuffer.
>
> The winsys now registers a callback for SDL events so that it can
> report window size changes back to the application.
> ---
> cogl/winsys/cogl-winsys-sdl2.c | 109
> ++++++++++++++++++++++++++++++++++++++++-
> examples/cogl-sdl2-hello.c | 4 ++
> 2 files changed, 111 insertions(+), 2 deletions(-)
>
> diff --git a/cogl/winsys/cogl-winsys-sdl2.c
> b/cogl/winsys/cogl-winsys-sdl2.c
> index 4c0583b..3ae0962 100644
> --- a/cogl/winsys/cogl-winsys-sdl2.c
> +++ b/cogl/winsys/cogl-winsys-sdl2.c
> @@ -53,13 +53,19 @@ typedef struct _CoglDisplaySdl2
> {
> SDL_Window *dummy_window;
> SDL_GLContext *context;
> + CoglBool pending_resize_notify;
> } CoglDisplaySdl2;
>
> typedef struct _CoglOnscreenSdl2
> {
> SDL_Window *window;
> + CoglBool pending_resize_notify;
> } CoglOnscreenSdl2;
>
> +/* The key used to store a pointer to the CoglOnscreen in an
> + * SDL_Window */
> +#define COGL_SDL_WINDOW_DATA_KEY "cogl-onscreen"
> +
> static CoglFuncPtr
> _cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,
> const char *name,
> @@ -258,6 +264,47 @@ error:
> return FALSE;
> }
>
> +static CoglFilterReturn
> +sdl_event_filter_cb (SDL_Event *event, void *data)
> +{
> + if (event->type == SDL_WINDOWEVENT &&
> + event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
> + {
> + CoglContext *context = data;
> + CoglDisplay *display = context->display;
> + CoglDisplaySdl2 *sdl_display = display->winsys;
> + float width = event->window.data1;
> + float height = event->window.data2;
> + CoglFramebuffer *framebuffer;
> + CoglOnscreenSdl2 *sdl_onscreen;
> + SDL_Window *window;
> +
> + window = SDL_GetWindowFromID (event->window.windowID);
> +
> + if (window == NULL)
> + return COGL_FILTER_CONTINUE;
> +
> + framebuffer = SDL_GetWindowData (window, COGL_SDL_WINDOW_DATA_KEY);
> +
> + if (framebuffer == NULL || framebuffer->context != context)
> + return COGL_FILTER_CONTINUE;
> +
> + _cogl_framebuffer_winsys_update_size (framebuffer, width, height);
> +
> + sdl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
> +
> + /* We only want to notify that a resize happened when the
> + application calls cogl_context_dispatch so instead of immediately
> + notifying we'll set a flag to remember to notify later */
> + sdl_display->pending_resize_notify = TRUE;
> + sdl_onscreen->pending_resize_notify = TRUE;
> +
> + return COGL_FILTER_CONTINUE;
> + }
> +
> + return COGL_FILTER_CONTINUE;
> +}
> +
> static CoglBool
> _cogl_winsys_context_init (CoglContext *context, CoglError **error)
> {
> @@ -277,12 +324,23 @@ _cogl_winsys_context_init (CoglContext *context,
> CoglError **error)
> COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE,
> TRUE);
>
> + _cogl_renderer_add_native_filter (renderer,
> + (CoglNativeFilterFunc)
> sdl_event_filter_cb,
> + context);
> +
> return TRUE;
> }
>
> static void
> _cogl_winsys_context_deinit (CoglContext *context)
> {
> + CoglRenderer *renderer = context->display->renderer;
> +
> + _cogl_renderer_remove_native_filter (renderer,
> + (CoglNativeFilterFunc)
> + sdl_event_filter_cb,
> + context);
> +
> g_free (context->winsys);
> }
>
> @@ -346,15 +404,22 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
> CoglOnscreenSdl2 *sdl_onscreen;
> SDL_Window *window;
> int width, height;
> + SDL_WindowFlags flags;
>
> width = cogl_framebuffer_get_width (framebuffer);
> height = cogl_framebuffer_get_height (framebuffer);
>
> + flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
> +
> + /* The resizable property on SDL window apparently can only be set
> + * on creation */
> + if (onscreen->resizable)
> + flags |= SDL_WINDOW_RESIZABLE;
> +
> window = SDL_CreateWindow ("" /* title */,
> 0, 0, /* x/y */
> width, height,
> - SDL_WINDOW_OPENGL |
> - SDL_WINDOW_HIDDEN);
> + flags);
>
> if (window == NULL)
> {
> @@ -365,6 +430,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
> return FALSE;
> }
>
> + SDL_SetWindowData (window, COGL_SDL_WINDOW_DATA_KEY, onscreen);
> +
> onscreen->winsys = g_slice_new (CoglOnscreenSdl2);
> sdl_onscreen = onscreen->winsys;
> sdl_onscreen->window = window;
> @@ -406,6 +473,42 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen
> *onscreen,
> SDL_HideWindow (sdl_onscreen->window);
> }
>
> +static void
> +flush_pending_notifications_cb (void *data,
> + void *user_data)
> +{
> + CoglFramebuffer *framebuffer = data;
> +
> + if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
> + {
> + CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
> + CoglOnscreenSdl2 *sdl_onscreen = onscreen->winsys;
> +
> + if (sdl_onscreen->pending_resize_notify)
> + {
> + _cogl_onscreen_notify_resize (onscreen);
> + sdl_onscreen->pending_resize_notify = FALSE;
> + }
> + }
> +}
> +
> +static void
> +_cogl_winsys_poll_dispatch (CoglContext *context,
> + const CoglPollFD *poll_fds,
> + int n_poll_fds)
> +{
> + CoglDisplay *display = context->display;
> + CoglDisplaySdl2 *sdl_display = display->winsys;
> +
> + if (sdl_display->pending_resize_notify)
> + {
> + g_list_foreach (context->framebuffers,
> + flush_pending_notifications_cb,
> + NULL);
> + sdl_display->pending_resize_notify = FALSE;
> + }
> +}
> +
> const CoglWinsysVtable *
> _cogl_winsys_sdl_get_vtable (void)
> {
> @@ -438,6 +541,8 @@ _cogl_winsys_sdl_get_vtable (void)
> _cogl_winsys_onscreen_update_swap_throttled;
> vtable.onscreen_set_visibility =
> _cogl_winsys_onscreen_set_visibility;
>
> + vtable.poll_dispatch = _cogl_winsys_poll_dispatch;
> +
> vtable_inited = TRUE;
> }
>
> diff --git a/examples/cogl-sdl2-hello.c b/examples/cogl-sdl2-hello.c
> index 972e7e1..0370460 100644
> --- a/examples/cogl-sdl2-hello.c
> +++ b/examples/cogl-sdl2-hello.c
> @@ -99,6 +99,10 @@ main (int argc, char **argv)
> data.center_y = 0.0f;
> data.quit = FALSE;
>
> + /* In SDL2, setting resizable only works before allocating the
> + * onscreen */
> + cogl_onscreen_set_resizable (onscreen, TRUE);
> +
> cogl_onscreen_show (onscreen);
>
> data.triangle = cogl_primitive_new_p2c4 (ctx,
> COGL_VERTICES_MODE_TRIANGLES,
> --
> 1.7.11.3.g3c3efa5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/cogl/attachments/20121120/233a8167/attachment.html>
More information about the Cogl
mailing list