summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <mail@3v1n0.net>2014-11-21 18:00:10 +0100
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2014-11-21 18:00:10 +0100
commit6aaeab046099a30f10ecaa84de0a75194342e5f6 (patch)
treed761dbe15fce866eb4528d0988723f8d81aa1561
parentbd6bfccc4051d883b298001fd7bb8a58c359a420 (diff)
downloadcogl-6aaeab046099a30f10ecaa84de0a75194342e5f6.tar.gz
mir: add public method to resize a cogl onscreen
This will internally recreate a new surface with proper parameters
-rw-r--r--cogl/cogl-onscreen.h23
-rw-r--r--cogl/winsys/cogl-winsys-egl-mir.c99
2 files changed, 113 insertions, 9 deletions
diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
index 99a9365d..98b89d22 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 c958cfc6..fd2fe534 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;
}