[cogl/wip/mir: 5/7] mir: update the framebuffer size on resize events



commit a948c25116bf5adae0b6f485e3c856cdf61e1202
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Mon Nov 17 17:47:23 2014 +0100

    mir: update the framebuffer size on resize events
    
    We need to use a mutex as mir handles these on
    different threads, also using an event idle prevents
    to get initialization errors on cogl side.

 cogl/winsys/cogl-winsys-egl-mir.c |   91 +++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)
---
diff --git a/cogl/winsys/cogl-winsys-egl-mir.c b/cogl/winsys/cogl-winsys-egl-mir.c
index 4866d34..ee31177 100644
--- a/cogl/winsys/cogl-winsys-egl-mir.c
+++ b/cogl/winsys/cogl-winsys-egl-mir.c
@@ -63,6 +63,10 @@ typedef struct _CoglOnscreenMir
 {
   MirSurface *mir_surface;
   MirSurfaceState last_state;
+
+  gint last_width;
+  gint last_height;
+  GMutex mir_event_lock;
 } CoglOnscreenMir;
 
 
@@ -299,6 +303,84 @@ _cogl_winsys_egl_context_init (CoglContext *context,
   return TRUE;
 }
 
+static void
+flush_pending_resize_notifications_cb (void *data,
+                                       void *user_data)
+{
+  CoglFramebuffer *framebuffer = data;
+
+  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+    {
+      CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+      CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+      CoglOnscreenMir *mir_onscreen = egl_onscreen->platform;
+
+      g_mutex_lock (&mir_onscreen->mir_event_lock);
+
+      if (egl_onscreen->pending_resize_notify)
+        {
+          gint w = mir_onscreen->last_width;
+          gint h = mir_onscreen->last_height;
+
+          _cogl_framebuffer_winsys_update_size (framebuffer, w, h);
+          _cogl_onscreen_notify_resize (onscreen);
+
+          egl_onscreen->pending_resize_notify = FALSE;
+        }
+
+      g_mutex_unlock (&mir_onscreen->mir_event_lock);
+    }
+}
+
+static void
+flush_pending_resize_notifications_idle (void *user_data)
+{
+  CoglContext *context = user_data;
+  CoglRenderer *renderer = context->display->renderer;
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+
+  /* This needs to be disconnected before invoking the callbacks in
+   * case the callbacks cause it to be queued again */
+  _cogl_closure_disconnect (egl_renderer->resize_notify_idle);
+  egl_renderer->resize_notify_idle = NULL;
+
+  g_list_foreach (context->framebuffers,
+                  flush_pending_resize_notifications_cb,
+                  NULL);
+}
+
+static void _mir_surface_event_cb(MirSurface* surface, MirEvent const* event, void* data)
+{
+  CoglOnscreen *onscreen = data;
+
+  if (event->type == mir_event_type_resize)
+    {
+      CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+      CoglContext *context = framebuffer->context;
+      CoglRenderer *renderer = context->display->renderer;
+      CoglRendererEGL *egl_renderer = renderer->winsys;
+      CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+      CoglOnscreenMir *mir_onscreen = egl_onscreen->platform;
+
+      g_mutex_lock (&mir_onscreen->mir_event_lock);
+
+      egl_onscreen->pending_resize_notify = TRUE;
+      mir_onscreen->last_width = event->resize.width;
+      mir_onscreen->last_height = event->resize.height;
+
+      if (!egl_renderer->resize_notify_idle)
+      {
+        egl_renderer->resize_notify_idle =
+          _cogl_poll_renderer_add_idle (renderer,
+                                        flush_pending_resize_notifications_idle,
+                                        context,
+                                        NULL);
+      }
+
+      g_mutex_unlock (&mir_onscreen->mir_event_lock);
+    }
+}
+
 static CoglBool
 _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
                                 EGLConfig egl_config,
@@ -313,6 +395,7 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
   CoglRendererMir *mir_renderer = egl_renderer->platform;
   MirEGLNativeWindowType mir_egl_native_window;
   MirSurfaceParameters surfaceparm;
+  MirEventDelegate event_handler;
 
   mir_onscreen = g_slice_new0 (CoglOnscreenMir);
   egl_onscreen->platform = mir_onscreen;
@@ -359,6 +442,13 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
 
   mir_onscreen->last_state = mir_surface_get_state (mir_onscreen->mir_surface);
 
+  if (!mir_surface_is_valid (onscreen->foreign_surface))
+  {
+    event_handler.callback = _mir_surface_event_cb;
+    event_handler.context = onscreen;
+    mir_surface_set_event_handler (mir_onscreen->mir_surface, &event_handler);
+  }
+
   return TRUE;
 }
 
@@ -370,6 +460,7 @@ _cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen)
 
   if (mir_onscreen->mir_surface && !onscreen->foreign_surface)
     {
+      mir_surface_set_event_handler (mir_onscreen->mir_surface, NULL);
       mir_surface_release (mir_onscreen->mir_surface, NULL, NULL);
       mir_onscreen->mir_surface = NULL;
     }


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