Rework window construction - only recreate surface when necessary
Signed-off-by: Andreas Pokorny <andreas.pokorny@canonical.com>
This commit is contained in:
parent
83471052cf
commit
5a8af1af75
@ -83,7 +83,7 @@ GdkCursor *_gdk_mir_cursor_new_for_name (GdkDisplay *display, const gchar *name)
|
|||||||
|
|
||||||
const gchar *_gdk_mir_cursor_get_name (GdkCursor *cursor);
|
const gchar *_gdk_mir_cursor_get_name (GdkCursor *cursor);
|
||||||
|
|
||||||
GdkWindowImpl *_gdk_mir_window_impl_new (void);
|
GdkWindowImpl *_gdk_mir_window_impl_new (GdkDisplay *display, GdkWindow *window, GdkWindowAttr *attributes, gint attributes_mask);
|
||||||
|
|
||||||
void _gdk_mir_window_impl_set_surface_state (GdkMirWindowImpl *impl, MirSurfaceState state);
|
void _gdk_mir_window_impl_set_surface_state (GdkMirWindowImpl *impl, MirSurfaceState state);
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ gdk_mir_display_create_window_impl (GdkDisplay *display,
|
|||||||
|
|
||||||
if (attributes->wclass == GDK_INPUT_OUTPUT)
|
if (attributes->wclass == GDK_INPUT_OUTPUT)
|
||||||
{
|
{
|
||||||
window->impl = _gdk_mir_window_impl_new ();
|
window->impl = _gdk_mir_window_impl_new (display, window, attributes, attributes_mask);
|
||||||
window->impl_window = window;
|
window->impl_window = window;
|
||||||
}
|
}
|
||||||
else /* attributes->wclass == GDK_INPUT_ONLY */
|
else /* attributes->wclass == GDK_INPUT_ONLY */
|
||||||
|
@ -257,7 +257,6 @@ gdk_mir_screen_get_root_window (GdkScreen *screen)
|
|||||||
get_screen_size (GDK_MIR_SCREEN (screen)->display_config, &width, &height);
|
get_screen_size (GDK_MIR_SCREEN (screen)->display_config, &width, &height);
|
||||||
|
|
||||||
s->root_window = _gdk_display_create_window (s->display);
|
s->root_window = _gdk_display_create_window (s->display);
|
||||||
s->root_window->impl = _gdk_mir_window_impl_new ();
|
|
||||||
s->root_window->impl_window = s->root_window;
|
s->root_window->impl_window = s->root_window;
|
||||||
s->root_window->visual = s->visual;
|
s->root_window->visual = s->visual;
|
||||||
s->root_window->window_type = GDK_WINDOW_ROOT;
|
s->root_window->window_type = GDK_WINDOW_ROOT;
|
||||||
@ -269,6 +268,7 @@ gdk_mir_screen_get_root_window (GdkScreen *screen)
|
|||||||
s->root_window->width = width;
|
s->root_window->width = width;
|
||||||
s->root_window->height = height;
|
s->root_window->height = height;
|
||||||
s->root_window->viewable = TRUE;
|
s->root_window->viewable = TRUE;
|
||||||
|
s->root_window->impl = _gdk_mir_window_impl_new (s->display, s->root_window, NULL, 0);
|
||||||
|
|
||||||
return s->root_window;
|
return s->root_window;
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,12 @@ struct _GdkMirWindowImpl
|
|||||||
gdouble y;
|
gdouble y;
|
||||||
guint button_state;
|
guint button_state;
|
||||||
|
|
||||||
|
GdkDisplay *display;
|
||||||
|
|
||||||
/* Surface being rendered to (only exists when window visible) */
|
/* Surface being rendered to (only exists when window visible) */
|
||||||
MirSurface *surface;
|
MirSurface *surface;
|
||||||
MirBufferStream *buffer_stream;
|
MirBufferStream *buffer_stream;
|
||||||
|
MirBufferUsage buffer_usage;
|
||||||
|
|
||||||
/* Cairo context for current frame */
|
/* Cairo context for current frame */
|
||||||
cairo_surface_t *cairo_surface;
|
cairo_surface_t *cairo_surface;
|
||||||
@ -94,6 +97,7 @@ struct _GdkMirWindowImplClass
|
|||||||
G_DEFINE_TYPE (GdkMirWindowImpl, gdk_mir_window_impl, GDK_TYPE_WINDOW_IMPL)
|
G_DEFINE_TYPE (GdkMirWindowImpl, gdk_mir_window_impl, GDK_TYPE_WINDOW_IMPL)
|
||||||
|
|
||||||
static cairo_surface_t *gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window);
|
static cairo_surface_t *gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window);
|
||||||
|
static void ensure_surface (GdkWindow *window);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drop_cairo_surface (GdkWindow *window)
|
drop_cairo_surface (GdkWindow *window)
|
||||||
@ -104,9 +108,16 @@ drop_cairo_surface (GdkWindow *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GdkWindowImpl *
|
GdkWindowImpl *
|
||||||
_gdk_mir_window_impl_new (void)
|
_gdk_mir_window_impl_new (GdkDisplay *display, GdkWindow *window, GdkWindowAttr *attributes, gint attributes_mask)
|
||||||
{
|
{
|
||||||
return g_object_new (GDK_TYPE_MIR_WINDOW_IMPL, NULL);
|
GdkMirWindowImpl *impl = g_object_new (GDK_TYPE_MIR_WINDOW_IMPL, NULL);
|
||||||
|
|
||||||
|
impl->display = display;
|
||||||
|
|
||||||
|
if (attributes && attributes_mask & GDK_WA_TYPE_HINT)
|
||||||
|
impl->type_hint = attributes->type_hint;
|
||||||
|
|
||||||
|
return (GdkWindowImpl *) impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -179,10 +190,8 @@ event_cb (MirSurface *surface,
|
|||||||
_gdk_mir_event_source_queue (context, event);
|
_gdk_mir_event_source_queue (context, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ensure_surface (GdkWindow *window);
|
static MirSurfaceSpec *
|
||||||
|
create_window_type_spec (GdkDisplay *display,
|
||||||
static MirSurface *
|
|
||||||
create_mir_surface (GdkDisplay *display,
|
|
||||||
GdkWindow *parent,
|
GdkWindow *parent,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
@ -193,14 +202,11 @@ create_mir_surface (GdkDisplay *display,
|
|||||||
MirEdgeAttachment edge,
|
MirEdgeAttachment edge,
|
||||||
MirBufferUsage buffer_usage)
|
MirBufferUsage buffer_usage)
|
||||||
{
|
{
|
||||||
MirSurface *parent_surface = NULL;
|
|
||||||
MirSurfaceSpec *spec;
|
|
||||||
MirConnection *connection;
|
|
||||||
MirPixelFormat format;
|
MirPixelFormat format;
|
||||||
MirSurface *surface;
|
MirSurface *parent_surface = NULL;
|
||||||
|
MirConnection *connection = gdk_mir_display_get_mir_connection (display);
|
||||||
MirRectangle real_rect;
|
MirRectangle real_rect;
|
||||||
|
|
||||||
connection = gdk_mir_display_get_mir_connection (display);
|
|
||||||
format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
|
format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
|
||||||
|
|
||||||
if (parent && parent->impl)
|
if (parent && parent->impl)
|
||||||
@ -245,17 +251,16 @@ create_mir_surface (GdkDisplay *display,
|
|||||||
{
|
{
|
||||||
case GDK_WINDOW_TYPE_HINT_DIALOG:
|
case GDK_WINDOW_TYPE_HINT_DIALOG:
|
||||||
case GDK_WINDOW_TYPE_HINT_DOCK:
|
case GDK_WINDOW_TYPE_HINT_DOCK:
|
||||||
spec = mir_connection_create_spec_for_dialog (connection,
|
return mir_connection_create_spec_for_dialog (connection,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format);
|
format);
|
||||||
break;
|
|
||||||
case GDK_WINDOW_TYPE_HINT_MENU:
|
case GDK_WINDOW_TYPE_HINT_MENU:
|
||||||
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
|
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
|
||||||
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
|
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
|
||||||
case GDK_WINDOW_TYPE_HINT_TOOLBAR:
|
case GDK_WINDOW_TYPE_HINT_TOOLBAR:
|
||||||
case GDK_WINDOW_TYPE_HINT_COMBO:
|
case GDK_WINDOW_TYPE_HINT_COMBO:
|
||||||
spec = mir_connection_create_spec_for_menu (connection,
|
return mir_connection_create_spec_for_menu (connection,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
@ -265,16 +270,15 @@ create_mir_surface (GdkDisplay *display,
|
|||||||
break;
|
break;
|
||||||
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
|
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
|
||||||
case GDK_WINDOW_TYPE_HINT_UTILITY:
|
case GDK_WINDOW_TYPE_HINT_UTILITY:
|
||||||
spec = mir_connection_create_spec_for_modal_dialog (connection,
|
return mir_connection_create_spec_for_modal_dialog (connection,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
parent_surface);
|
parent_surface);
|
||||||
break;
|
|
||||||
case GDK_WINDOW_TYPE_HINT_DND:
|
case GDK_WINDOW_TYPE_HINT_DND:
|
||||||
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
|
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
|
||||||
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
|
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
|
||||||
spec = mir_connection_create_spec_for_tooltip (connection,
|
return mir_connection_create_spec_for_tooltip (connection,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
@ -284,19 +288,47 @@ create_mir_surface (GdkDisplay *display,
|
|||||||
case GDK_WINDOW_TYPE_HINT_NORMAL:
|
case GDK_WINDOW_TYPE_HINT_NORMAL:
|
||||||
case GDK_WINDOW_TYPE_HINT_DESKTOP:
|
case GDK_WINDOW_TYPE_HINT_DESKTOP:
|
||||||
default:
|
default:
|
||||||
spec = mir_connection_create_spec_for_normal_surface (connection,
|
return mir_connection_create_spec_for_normal_surface (connection,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format);
|
format);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mir_surface_spec_set_name (spec, g_get_prgname ());
|
static MirSurfaceSpec*
|
||||||
mir_surface_spec_set_buffer_usage (spec, buffer_usage);
|
create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
|
||||||
surface = mir_surface_create_sync (spec);
|
{
|
||||||
|
MirSurfaceSpec *spec = NULL;
|
||||||
|
|
||||||
|
spec = create_window_type_spec (impl->display,
|
||||||
|
impl->transient_for,
|
||||||
|
impl->transient_x, impl->transient_y,
|
||||||
|
window->width, window->height,
|
||||||
|
impl->type_hint,
|
||||||
|
impl->has_rect ? &impl->rect : NULL,
|
||||||
|
impl->has_rect ? impl->edge : mir_edge_attachment_any,
|
||||||
|
impl->buffer_usage);
|
||||||
|
|
||||||
|
mir_surface_spec_set_buffer_usage (spec, impl->buffer_usage);
|
||||||
|
|
||||||
|
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_surface_spec (GdkWindow *window)
|
||||||
|
{
|
||||||
|
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
||||||
|
MirSurfaceSpec *spec;
|
||||||
|
|
||||||
|
if (!impl->surface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spec = create_spec (window, impl);
|
||||||
|
|
||||||
|
mir_surface_apply_spec (impl->surface, spec);
|
||||||
mir_surface_spec_release (spec);
|
mir_surface_spec_release (spec);
|
||||||
|
impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
|
||||||
return surface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkDevice *
|
static GdkDevice *
|
||||||
@ -350,6 +382,7 @@ ensure_surface_full (GdkWindow *window,
|
|||||||
{
|
{
|
||||||
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
||||||
GdkMirWindowReference *window_ref;
|
GdkMirWindowReference *window_ref;
|
||||||
|
MirSurfaceSpec *spec;
|
||||||
|
|
||||||
if (impl->surface)
|
if (impl->surface)
|
||||||
return;
|
return;
|
||||||
@ -358,17 +391,13 @@ ensure_surface_full (GdkWindow *window,
|
|||||||
* https://bugs.launchpad.net/mir/+bug/1324100
|
* https://bugs.launchpad.net/mir/+bug/1324100
|
||||||
*/
|
*/
|
||||||
window_ref = _gdk_mir_event_source_get_window_reference (window);
|
window_ref = _gdk_mir_event_source_get_window_reference (window);
|
||||||
|
impl->buffer_usage = buffer_usage;
|
||||||
|
|
||||||
impl->surface = create_mir_surface (gdk_window_get_display (window),
|
spec = create_spec (window, impl);
|
||||||
impl->transient_for,
|
|
||||||
impl->transient_x,
|
impl->surface = mir_surface_create_sync (spec);
|
||||||
impl->transient_y,
|
|
||||||
window->width,
|
mir_surface_spec_release(spec);
|
||||||
window->height,
|
|
||||||
impl->type_hint,
|
|
||||||
impl->has_rect ? &impl->rect : NULL,
|
|
||||||
impl->has_rect ? impl->edge : mir_edge_attachment_any,
|
|
||||||
buffer_usage);
|
|
||||||
impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
|
impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
|
||||||
|
|
||||||
/* FIXME: can't make an initial resize event */
|
/* FIXME: can't make an initial resize event */
|
||||||
@ -393,7 +422,8 @@ ensure_surface_full (GdkWindow *window,
|
|||||||
static void
|
static void
|
||||||
ensure_surface (GdkWindow *window)
|
ensure_surface (GdkWindow *window)
|
||||||
{
|
{
|
||||||
ensure_surface_full (window, window->gl_paint_context ?
|
ensure_surface_full (window,
|
||||||
|
window->gl_paint_context ?
|
||||||
mir_buffer_usage_hardware :
|
mir_buffer_usage_hardware :
|
||||||
mir_buffer_usage_software);
|
mir_buffer_usage_software);
|
||||||
}
|
}
|
||||||
@ -458,6 +488,8 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
|
|||||||
return impl->cairo_surface;
|
return impl->cairo_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensure_surface (window);
|
||||||
|
|
||||||
/* Transient windows get rendered into a buffer and copied onto their parent */
|
/* Transient windows get rendered into a buffer and copied onto their parent */
|
||||||
if (window->gl_paint_context)
|
if (window->gl_paint_context)
|
||||||
{
|
{
|
||||||
@ -466,8 +498,6 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
|
|||||||
}
|
}
|
||||||
else if (impl->visible)
|
else if (impl->visible)
|
||||||
{
|
{
|
||||||
ensure_surface (window);
|
|
||||||
|
|
||||||
mir_buffer_stream_get_graphics_region (mir_surface_get_buffer_stream (impl->surface), ®ion);
|
mir_buffer_stream_get_graphics_region (mir_surface_get_buffer_stream (impl->surface), ®ion);
|
||||||
|
|
||||||
switch (region.pixel_format)
|
switch (region.pixel_format)
|
||||||
@ -565,6 +595,7 @@ gdk_mir_window_impl_show (GdkWindow *window,
|
|||||||
//g_printerr ("gdk_mir_window_impl_show window=%p\n", window);
|
//g_printerr ("gdk_mir_window_impl_show window=%p\n", window);
|
||||||
|
|
||||||
impl->visible = TRUE;
|
impl->visible = TRUE;
|
||||||
|
set_surface_state (impl, mir_surface_state_restored);
|
||||||
|
|
||||||
/* Make sure there's a surface to see */
|
/* Make sure there's a surface to see */
|
||||||
ensure_surface (window);
|
ensure_surface (window);
|
||||||
@ -586,7 +617,8 @@ gdk_mir_window_impl_hide (GdkWindow *window)
|
|||||||
|
|
||||||
impl->cursor_inside = FALSE;
|
impl->cursor_inside = FALSE;
|
||||||
impl->visible = FALSE;
|
impl->visible = FALSE;
|
||||||
ensure_no_surface (window);
|
|
||||||
|
set_surface_state (impl, mir_surface_state_hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -597,7 +629,8 @@ gdk_mir_window_impl_withdraw (GdkWindow *window)
|
|||||||
|
|
||||||
impl->cursor_inside = FALSE;
|
impl->cursor_inside = FALSE;
|
||||||
impl->visible = FALSE;
|
impl->visible = FALSE;
|
||||||
ensure_no_surface (window);
|
|
||||||
|
set_surface_state (impl, mir_surface_state_hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -649,7 +682,14 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
|
|||||||
g_printerr ("\n");
|
g_printerr ("\n");
|
||||||
*/
|
*/
|
||||||
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
|
||||||
gboolean recreate_surface = FALSE;
|
|
||||||
|
/* If resize requested then rebuild surface */
|
||||||
|
if (width >= 0 && (window->width != width || window->height != height))
|
||||||
|
{
|
||||||
|
/* We accept any resize */
|
||||||
|
window->width = width;
|
||||||
|
window->height = height;
|
||||||
|
}
|
||||||
|
|
||||||
/* Transient windows can move wherever they want */
|
/* Transient windows can move wherever they want */
|
||||||
if (with_move)
|
if (with_move)
|
||||||
@ -659,24 +699,9 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
|
|||||||
impl->has_rect = FALSE;
|
impl->has_rect = FALSE;
|
||||||
impl->transient_x = x;
|
impl->transient_x = x;
|
||||||
impl->transient_y = y;
|
impl->transient_y = y;
|
||||||
recreate_surface = TRUE;
|
update_surface_spec (window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If resize requested then rebuild surface */
|
|
||||||
if (width >= 0)
|
|
||||||
{
|
|
||||||
/* We accept any resize */
|
|
||||||
window->width = width;
|
|
||||||
window->height = height;
|
|
||||||
recreate_surface = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (recreate_surface && impl->surface)
|
|
||||||
{
|
|
||||||
ensure_no_surface (window);
|
|
||||||
ensure_surface (window);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MirEdgeAttachment
|
static MirEdgeAttachment
|
||||||
@ -948,7 +973,7 @@ gdk_mir_window_impl_set_type_hint (GdkWindow *window,
|
|||||||
if (hint != impl->type_hint)
|
if (hint != impl->type_hint)
|
||||||
{
|
{
|
||||||
impl->type_hint = hint;
|
impl->type_hint = hint;
|
||||||
ensure_no_surface (window);
|
update_surface_spec (window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1573,7 +1598,7 @@ _gdk_mir_window_get_egl_surface (GdkWindow *window,
|
|||||||
ensure_surface_full (window, mir_buffer_usage_hardware);
|
ensure_surface_full (window, mir_buffer_usage_hardware);
|
||||||
|
|
||||||
egl_display = _gdk_mir_display_get_egl_display (gdk_window_get_display (window));
|
egl_display = _gdk_mir_display_get_egl_display (gdk_window_get_display (window));
|
||||||
egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (mir_surface_get_buffer_stream (impl->surface));
|
egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (impl->buffer_stream);
|
||||||
|
|
||||||
impl->egl_surface =
|
impl->egl_surface =
|
||||||
eglCreateWindowSurface (egl_display, config, egl_window, NULL);
|
eglCreateWindowSurface (egl_display, config, egl_window, NULL);
|
||||||
@ -1598,7 +1623,7 @@ _gdk_mir_window_get_dummy_egl_surface (GdkWindow *window,
|
|||||||
|
|
||||||
display = gdk_window_get_display (window);
|
display = gdk_window_get_display (window);
|
||||||
egl_display = _gdk_mir_display_get_egl_display (display);
|
egl_display = _gdk_mir_display_get_egl_display (display);
|
||||||
egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (mir_surface_get_buffer_stream (impl->surface));
|
egl_window = (EGLNativeWindowType) mir_buffer_stream_get_egl_native_window (impl->buffer_stream);
|
||||||
|
|
||||||
impl->dummy_egl_surface =
|
impl->dummy_egl_surface =
|
||||||
eglCreateWindowSurface (egl_display, config, egl_window, NULL);
|
eglCreateWindowSurface (egl_display, config, egl_window, NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user