[Spice-devel] [PATCH spice-gtk 05/10] display: keep a reference to the primary surface

Yonit Halperin yhalperi at redhat.com
Mon Sep 9 13:26:41 PDT 2013


ack
On 09/08/2013 02:59 PM, Marc-André Lureau wrote:
> Avoid hard-coding surface 0 as being primary, although in practice it
> always is so far. Also a lot of lookups are primary, so add a shortcut
> for this special case (~30% apparently), it shows some small lookup
> speedup.
>
> before:
> real     0m5.008s
> user     0m3.253s
> sys      0m2.015s
>
> after:
> real    0m4.930s
> user    0m3.133s
> sys     0m2.027s
> ---
>   gtk/channel-display.c | 28 +++++++++++++++-------------
>   1 file changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/gtk/channel-display.c b/gtk/channel-display.c
> index 979ce7b..03ae535 100644
> --- a/gtk/channel-display.c
> +++ b/gtk/channel-display.c
> @@ -67,6 +67,7 @@
>
>   struct _SpiceDisplayChannelPrivate {
>       GHashTable                  *surfaces;
> +    display_surface             *primary;
>       display_cache               *images;
>       display_cache               *palettes;
>       SpiceImageCache             image_cache;
> @@ -180,13 +181,11 @@ static void spice_display_get_property(GObject    *object,
>
>       switch (prop_id) {
>       case PROP_WIDTH: {
> -        display_surface *surface = find_surface(c, 0);
> -        g_value_set_uint(value, surface ? surface->width : 0);
> +        g_value_set_uint(value, c->primary ? c->primary->width : 0);
>           break;
>       }
>       case PROP_HEIGHT: {
> -        display_surface *surface = find_surface(c, 0);
> -        g_value_set_uint(value, surface ? surface->height : 0);
> +        g_value_set_uint(value, c->primary ? c->primary->height : 0);
>           break;
>       }
>       case PROP_MONITORS: {
> @@ -739,18 +738,16 @@ static int create_canvas(SpiceChannel *channel, display_surface *surface)
>       SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
>
>       if (surface->primary) {
> -        display_surface *primary = find_surface(c, 0);
> -
> -        if (primary) {
> -            if (primary->width == surface->width &&
> -                primary->height == surface->height) {
> +        if (c->primary) {
> +            if (c->primary->width == surface->width &&
> +                c->primary->height == surface->height) {
>                   CHANNEL_DEBUG(channel, "Reusing existing primary surface");
>                   return 0;
>               }
>
>               emit_main_context(channel, SPICE_DISPLAY_PRIMARY_DESTROY);
>
> -            g_hash_table_remove(c->surfaces, 0);
> +            g_hash_table_remove(c->surfaces, GINT_TO_POINTER(c->primary->surface_id));
>           }
>
>           CHANNEL_DEBUG(channel, "Create primary canvas");
> @@ -803,6 +800,8 @@ static int create_canvas(SpiceChannel *channel, display_surface *surface)
>       g_hash_table_insert(c->surfaces, GINT_TO_POINTER(surface->surface_id), surface);
>
>       if (surface->primary) {
> +        g_warn_if_fail(c->primary == NULL);
> +        c->primary = surface;
>           emit_main_context(channel, SPICE_DISPLAY_PRIMARY_CREATE,
>                             surface->format, surface->width, surface->height,
>                             surface->stride, surface->shmid, surface->data);
> @@ -847,6 +846,9 @@ static void destroy_canvas(display_surface *surface)
>
>   static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32 surface_id)
>   {
> +    if (c->primary && c->primary->surface_id == surface_id)
> +        return c->primary;
> +
>       return g_hash_table_lookup(c->surfaces, GINT_TO_POINTER(surface_id));
>   }
>
> @@ -944,10 +946,9 @@ static void display_handle_mode(SpiceChannel *channel, SpiceMsgIn *in)
>   static void display_handle_mark(SpiceChannel *channel, SpiceMsgIn *in)
>   {
>       SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    display_surface *surface = find_surface(c, 0);
>
>       CHANNEL_DEBUG(channel, "%s", __FUNCTION__);
> -    g_return_if_fail(surface != NULL);
> +    g_return_if_fail(c->primary != NULL);
>   #ifdef EXTRA_CHECKS
>       g_warn_if_fail(c->mark == FALSE);
>   #endif
> @@ -960,7 +961,7 @@ static void display_handle_mark(SpiceChannel *channel, SpiceMsgIn *in)
>   static void display_handle_reset(SpiceChannel *channel, SpiceMsgIn *in)
>   {
>       SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
> -    display_surface *surface = find_surface(c, 0);
> +    display_surface *surface = c->primary;
>
>       CHANNEL_DEBUG(channel, "%s: TODO detach_from_screen", __FUNCTION__);
>
> @@ -1784,6 +1785,7 @@ static void display_handle_surface_destroy(SpiceChannel *channel, SpiceMsgIn *in
>           if (id != 0 && c->mark_false_event_id == 0) {
>               c->mark_false_event_id = g_timeout_add_seconds(1, display_mark_false, channel);
>           }
> +        c->primary = NULL;
>           emit_main_context(channel, SPICE_DISPLAY_PRIMARY_DESTROY);
>       }
>
>



More information about the Spice-devel mailing list