[cogl/cogl-1.18] mir: add public method to resize a cogl onscreen



commit 6aaeab046099a30f10ecaa84de0a75194342e5f6
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Fri Nov 21 18:00:10 2014 +0100

    mir: add public method to resize a cogl onscreen
    
    This will internally recreate a new surface with proper parameters

 cogl/cogl-onscreen.h              |   23 ++++++++-
 cogl/winsys/cogl-winsys-egl-mir.c |   99 ++++++++++++++++++++++++++++++++++---
 2 files changed, 113 insertions(+), 9 deletions(-)
---
diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
index 99a9365..98b89d2 100644
--- a/cogl/cogl-onscreen.h
+++ b/cogl/cogl-onscreen.h
@@ -282,7 +282,7 @@ cogl_mir_onscreen_get_surface (CoglOnscreen *onscreen);
  *
  * This function must be called before @onscreen is allocated.
  *
- * Returns: whether @surface has been marked as been set as surface or not.
+ * Returns: whether @surface has been set as surface or not.
  *
  * Since: 1.18
  * Stability: unstable
@@ -290,6 +290,27 @@ cogl_mir_onscreen_get_surface (CoglOnscreen *onscreen);
 CoglBool
 cogl_mir_onscreen_set_foreign_surface (CoglOnscreen *onscreen,
                                        struct MirSurface *surface);
+
+/**
+ * cogl_mir_onscreen_resize:
+ * @onscreen: A #CoglOnscreen framebuffer
+ * @width: The desired width of the framebuffer
+ * @height: The desired height of the framebuffer
+ *
+ * Resizes the backbuffer of the given @onscreen framebuffer to the
+ * given size.
+ *
+ * Note that if some drawing commands have been applied to the
+ * framebuffer since the last swap buffers then the resize will be
+ * queued and will only take effect in the next swap buffers.
+ *
+ * Since: 1.18
+ * Stability: unstable
+ */
+void
+cogl_mir_onscreen_resize (CoglOnscreen *onscreen,
+                          int           width,
+                          int           height);
 #endif /* COGL_HAS_EGL_PLATFORM_MIR_SUPPORT */
 
 /**
diff --git a/cogl/winsys/cogl-winsys-egl-mir.c b/cogl/winsys/cogl-winsys-egl-mir.c
index c958cfc..fd2fe53 100644
--- a/cogl/winsys/cogl-winsys-egl-mir.c
+++ b/cogl/winsys/cogl-winsys-egl-mir.c
@@ -64,8 +64,9 @@ typedef struct _CoglOnscreenMir
   MirSurface *mir_surface;
   MirSurfaceState last_state;
 
-  int last_width;
-  int last_height;
+  CoglBool requested_resize;
+  int requested_width;
+  int requested_height;
   GMutex mir_event_lock;
 } CoglOnscreenMir;
 
@@ -410,7 +411,7 @@ _cogl_winsys_egl_cleanup_context (CoglDisplay *display)
 
   if (mir_display->dummy_mir_surface)
     {
-      mir_surface_release (mir_display->dummy_mir_surface, NULL, NULL);
+      mir_surface_release_sync (mir_display->dummy_mir_surface);
       mir_display->dummy_mir_surface = NULL;
     }
 }
@@ -444,8 +445,8 @@ flush_pending_resize_notifications_cb (void *data,
 
       if (egl_onscreen->pending_resize_notify)
         {
-          int w = mir_onscreen->last_width;
-          int h = mir_onscreen->last_height;
+          int w = mir_onscreen->requested_width;
+          int h = mir_onscreen->requested_height;
 
           _cogl_framebuffer_winsys_update_size (framebuffer, w, h);
           _cogl_onscreen_notify_resize (onscreen);
@@ -490,8 +491,8 @@ static void _mir_surface_event_cb(MirSurface* surface, MirEvent const* event, vo
       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;
+      mir_onscreen->requested_width = event->resize.width;
+      mir_onscreen->requested_height = event->resize.height;
 
       if (!egl_renderer->resize_notify_idle)
       {
@@ -588,7 +589,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_surface_release_sync (mir_onscreen->mir_surface);
       mir_onscreen->mir_surface = NULL;
     }
 
@@ -626,6 +627,42 @@ _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
   mir_surface_set_state (mir_onscreen->mir_surface, new_state);
 }
 
+static void
+mir_surface_recreate (CoglOnscreen *onscreen)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+  CoglOnscreenMir *mir_onscreen = egl_onscreen->platform;
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+  winsys->onscreen_deinit (onscreen);
+
+  _cogl_framebuffer_winsys_update_size (framebuffer,
+                                        mir_onscreen->requested_width,
+                                        mir_onscreen->requested_height);
+
+  winsys->onscreen_init (onscreen, NULL);
+  _cogl_onscreen_notify_resize (onscreen);
+
+  mir_onscreen->requested_resize = FALSE;
+}
+
+static void
+_cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
+                                                const int *rectangles,
+                                                int n_rectangles)
+{
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+  CoglOnscreenMir *mir_onscreen = egl_onscreen->platform;
+
+  if (mir_onscreen->requested_resize)
+    mir_surface_recreate (onscreen);
+
+  parent_vtable->onscreen_swap_buffers_with_damage (onscreen,
+                                                    rectangles,
+                                                    n_rectangles);
+}
+
 CoglBool
 cogl_mir_renderer_set_foreign_connection (CoglRenderer *renderer,
                                           MirConnection *connection)
@@ -665,6 +702,7 @@ cogl_mir_onscreen_set_foreign_surface (CoglOnscreen *onscreen,
   CoglFramebuffer *fb;
   MirSurfaceParameters parameters;
 
+  _COGL_RETURN_VAL_IF_FAIL (cogl_is_onscreen (surface), FALSE);
   _COGL_RETURN_VAL_IF_FAIL (mir_surface_is_valid (surface), FALSE);
 
   fb = COGL_FRAMEBUFFER (onscreen);
@@ -683,14 +721,57 @@ cogl_mir_onscreen_get_surface (CoglOnscreen *onscreen)
   CoglOnscreenEGL *egl_onscreen;
   CoglOnscreenMir *mir_onscreen;
 
+  _COGL_RETURN_VAL_IF_FAIL (cogl_is_onscreen (onscreen), NULL);
   cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), NULL);
 
   egl_onscreen = onscreen->winsys;
   mir_onscreen = egl_onscreen->platform;
 
+  _COGL_RETURN_VAL_IF_FAIL (mir_surface_is_valid (mir_onscreen->mir_surface), NULL);
+
   return mir_onscreen->mir_surface;
 }
 
+void
+cogl_mir_onscreen_resize (CoglOnscreen *onscreen,
+                          int           width,
+                          int           height)
+{
+  CoglFramebuffer *framebuffer;
+  CoglOnscreenEGL *egl_onscreen;
+  CoglOnscreenMir *mir_onscreen;
+
+  _COGL_RETURN_VAL_IF_FAIL (cogl_is_onscreen (onscreen), NULL);
+
+  framebuffer = COGL_FRAMEBUFFER (onscreen);
+
+  if (cogl_framebuffer_get_width (framebuffer) == width &&
+      cogl_framebuffer_get_height (framebuffer) == height)
+    {
+      return;
+    }
+
+  if (!framebuffer->allocated)
+    {
+      _cogl_framebuffer_winsys_update_size (framebuffer, width, height);
+      _cogl_onscreen_notify_resize (onscreen);
+    }
+  else
+    {
+      egl_onscreen = onscreen->winsys;
+      mir_onscreen = egl_onscreen->platform;
+
+      g_mutex_lock (&mir_onscreen->mir_event_lock);
+      mir_onscreen->requested_resize = TRUE;
+      mir_onscreen->requested_width = width;
+      mir_onscreen->requested_height = height;
+      g_mutex_unlock (&mir_onscreen->mir_event_lock);
+
+      if (!framebuffer->mid_scene)
+        mir_surface_recreate (onscreen);
+    }
+}
+
 static const CoglWinsysEGLVtable
 _cogl_winsys_egl_vtable =
   {
@@ -725,6 +806,8 @@ _cogl_winsys_egl_mir_get_vtable (void)
 
       vtable.onscreen_set_visibility =
         _cogl_winsys_onscreen_set_visibility;
+      vtable.onscreen_swap_buffers_with_damage =
+        _cogl_winsys_onscreen_swap_buffers_with_damage;
 
       vtable_inited = TRUE;
     }


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