[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