[Spice-commits] server/dcc-encoders.c server/dcc-encoders.h server/display-channel.c server/display-channel.h server/red_worker.c

Frediano Ziglio fziglio at kemper.freedesktop.org
Mon Nov 23 06:22:30 PST 2015


 server/dcc-encoders.c    |   25 ++++++++
 server/dcc-encoders.h    |    3 -
 server/display-channel.c |  106 +++++++++++++++++++++++++++++++++++++
 server/display-channel.h |    6 ++
 server/red_worker.c      |  134 ++---------------------------------------------
 5 files changed, 145 insertions(+), 129 deletions(-)

New commits:
commit 4acf97cae1ce9cfc59a8826b3f604c84241929d7
Author: Marc-André Lureau <marcandre.lureau at gmail.com>
Date:   Thu Sep 26 22:53:57 2013 +0200

    worker: move display_channel_free_some
    
    Author:    Marc-André Lureau <marcandre.lureau at gmail.com>
    Acked-by: Fabiano Fidêncio <fabiano at fidencio.org>

diff --git a/server/dcc-encoders.c b/server/dcc-encoders.c
index f5e4dc5..24064a8 100644
--- a/server/dcc-encoders.c
+++ b/server/dcc-encoders.c
@@ -517,6 +517,31 @@ void dcc_free_glz_drawable(DisplayChannelClient *dcc, RedGlzDrawable *drawable)
     }
 }
 
+/*
+ * Remove from the global lz dictionary some glz_drawables that have no reference to
+ * Drawable (their qxl drawables are released too).
+ * NOTE - the caller should prevent encoding using the dictionary during the operation
+ */
+int dcc_free_some_independent_glz_drawables(DisplayChannelClient *dcc)
+{
+    RingItem *ring_link;
+    int n = 0;
+
+    if (!dcc) {
+        return 0;
+    }
+    ring_link = ring_get_head(&dcc->glz_drawables);
+    while ((n < RED_RELEASE_BUNCH_SIZE) && (ring_link != NULL)) {
+        RedGlzDrawable *glz_drawable = SPICE_CONTAINEROF(ring_link, RedGlzDrawable, link);
+        ring_link = ring_next(&dcc->glz_drawables, ring_link);
+        if (!glz_drawable->drawable) {
+            dcc_free_glz_drawable(dcc, glz_drawable);
+            n++;
+        }
+    }
+    return n;
+}
+
 void dcc_free_glz_drawables_to_free(DisplayChannelClient* dcc)
 {
     RingItem *ring_link;
diff --git a/server/dcc-encoders.h b/server/dcc-encoders.h
index 6c19cf4..05fd29e 100644
--- a/server/dcc-encoders.h
+++ b/server/dcc-encoders.h
@@ -36,13 +36,13 @@ typedef struct RedCompressBuf RedCompressBuf;
 typedef struct GlzDrawableInstanceItem GlzDrawableInstanceItem;
 typedef struct RedGlzDrawable RedGlzDrawable;
 
-
 void             dcc_encoders_init                           (DisplayChannelClient *dcc);
 void             dcc_encoders_free                           (DisplayChannelClient *dcc);
 void             dcc_free_glz_drawable_instance              (DisplayChannelClient *dcc,
                                                               GlzDrawableInstanceItem *item);
 void             dcc_free_glz_drawable                       (DisplayChannelClient *dcc,
                                                               RedGlzDrawable *drawable);
+int              dcc_free_some_independent_glz_drawables     (DisplayChannelClient *dcc);
 void             dcc_free_glz_drawables                      (DisplayChannelClient *dcc);
 void             dcc_free_glz_drawables_to_free              (DisplayChannelClient* dcc);
 void             dcc_freeze_glz                              (DisplayChannelClient *dcc);
@@ -157,5 +157,6 @@ struct RedGlzDrawable {
     DisplayChannelClient *dcc;
 };
 
+#define RED_RELEASE_BUNCH_SIZE 64
 
 #endif /* DCC_ENCODERS_H_ */
diff --git a/server/display-channel.c b/server/display-channel.c
index d455a0d..f443dd0 100644
--- a/server/display-channel.c
+++ b/server/display-channel.c
@@ -873,3 +873,109 @@ void display_channel_free_glz_drawables(DisplayChannel *display)
         dcc_free_glz_drawables(dcc);
     }
 }
+
+static bool free_one_drawable(DisplayChannel *display, int force_glz_free)
+{
+    RingItem *ring_item = ring_get_tail(&display->current_list);
+    Drawable *drawable;
+    Container *container;
+
+    if (!ring_item) {
+        return FALSE;
+    }
+
+    drawable = SPICE_CONTAINEROF(ring_item, Drawable, list_link);
+    if (force_glz_free) {
+        RingItem *glz_item, *next_item;
+        RedGlzDrawable *glz;
+        DRAWABLE_FOREACH_GLZ_SAFE(drawable, glz_item, next_item, glz) {
+            dcc_free_glz_drawable(glz->dcc, glz);
+        }
+    }
+    drawable_draw(display, drawable);
+    container = drawable->tree_item.base.container;
+
+    current_remove_drawable(display, drawable);
+    container_cleanup(container);
+    return TRUE;
+}
+
+void display_channel_current_flush(DisplayChannel *display, int surface_id)
+{
+    while (!ring_is_empty(&display->surfaces[surface_id].current_list)) {
+        free_one_drawable(display, FALSE);
+    }
+    current_remove_all(display, surface_id);
+}
+
+void display_channel_free_some(DisplayChannel *display)
+{
+    int n = 0;
+    DisplayChannelClient *dcc;
+    RingItem *item, *next;
+
+    spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", display->drawable_count,
+                display->red_drawable_count, display->glz_drawable_count);
+    FOREACH_DCC(display, item, next, dcc) {
+        GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
+
+        if (glz_dict) {
+            // encoding using the dictionary is prevented since the following operations might
+            // change the dictionary
+            pthread_rwlock_wrlock(&glz_dict->encode_lock);
+            n = dcc_free_some_independent_glz_drawables(dcc);
+        }
+    }
+
+    while (!ring_is_empty(&display->current_list) && n++ < RED_RELEASE_BUNCH_SIZE) {
+        free_one_drawable(display, TRUE);
+    }
+
+    FOREACH_DCC(display, item, next, dcc) {
+        GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
+
+        if (glz_dict) {
+            pthread_rwlock_unlock(&glz_dict->encode_lock);
+        }
+    }
+}
+
+static Drawable* drawable_try_new(DisplayChannel *display)
+{
+    Drawable *drawable;
+
+    if (!display->free_drawables)
+        return NULL;
+
+    drawable = &display->free_drawables->u.drawable;
+    display->free_drawables = display->free_drawables->u.next;
+    display->drawable_count++;
+
+    return drawable;
+}
+
+Drawable *display_channel_drawable_try_new(DisplayChannel *display,
+                                           int group_id, int process_commands_generation)
+{
+    Drawable *drawable;
+
+    while (!(drawable = drawable_try_new(display))) {
+        if (!free_one_drawable(display, FALSE))
+            return NULL;
+    }
+
+    bzero(drawable, sizeof(Drawable));
+    drawable->refs = 1;
+    drawable->creation_time = red_get_monotonic_time();
+    ring_item_init(&drawable->list_link);
+    ring_item_init(&drawable->surface_list_link);
+    ring_item_init(&drawable->tree_item.base.siblings_link);
+    drawable->tree_item.base.type = TREE_ITEM_TYPE_DRAWABLE;
+    region_init(&drawable->tree_item.base.rgn);
+    ring_init(&drawable->pipes);
+    ring_init(&drawable->glz_ring);
+    drawable->process_commands_generation = process_commands_generation;
+    drawable->group_id = group_id;
+
+    return drawable;
+}
diff --git a/server/display-channel.h b/server/display-channel.h
index 03834fa..29c1151 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -257,11 +257,15 @@ typedef struct SurfaceDestroyItem {
 } SurfaceDestroyItem;
 
 
+void                       display_channel_free_some                 (DisplayChannel *display);
 void                       display_channel_set_stream_video          (DisplayChannel *display,
                                                                       int stream_video);
 int                        display_channel_get_streams_timeout       (DisplayChannel *display);
 void                       display_channel_compress_stats_print      (const DisplayChannel *display);
 void                       display_channel_compress_stats_reset      (DisplayChannel *display);
+Drawable *                 display_channel_drawable_try_new          (DisplayChannel *display,
+                                                                      int group_id,
+                                                                      int process_commands_generation);
 void                       display_channel_drawable_unref            (DisplayChannel *display, Drawable *drawable);
 void                       display_channel_surface_unref             (DisplayChannel *display,
                                                                       uint32_t surface_id);
@@ -399,5 +403,7 @@ void red_pipes_remove_drawable(Drawable *drawable);
 void dcc_add_drawable(DisplayChannelClient *dcc, Drawable *drawable);
 void current_remove(DisplayChannel *display, TreeItem *item);
 void detach_streams_behind(DisplayChannel *display, QRegion *region, Drawable *drawable);
+void drawable_draw(DisplayChannel *display, Drawable *item);
+void current_remove_all(DisplayChannel *display, int surface_id);
 
 #endif /* DISPLAY_CHANNEL_H_ */
diff --git a/server/red_worker.c b/server/red_worker.c
index 63e7d25..2a7b415 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -152,13 +152,11 @@ typedef struct BitmapData {
 
 static inline int validate_surface(DisplayChannel *display, uint32_t surface_id);
 
-static void drawable_draw(DisplayChannel *display, Drawable *item);
 static void red_update_area(DisplayChannel *display, const SpiceRect *area, int surface_id);
 static void red_update_area_till(DisplayChannel *display, const SpiceRect *area, int surface_id,
                                  Drawable *last);
 static inline void display_begin_send_message(RedChannelClient *rcc);
 static void dcc_release_glz(DisplayChannelClient *dcc);
-static int red_display_free_some_independent_glz_drawables(DisplayChannelClient *dcc);
 static void display_channel_client_release_item_before_push(DisplayChannelClient *dcc,
                                                             PipeItem *item);
 static void display_channel_client_release_item_after_push(DisplayChannelClient *dcc,
@@ -300,7 +298,6 @@ static inline int validate_surface(DisplayChannel *display, uint32_t surface_id)
     return 1;
 }
 
-
 static inline void red_handle_drawable_surfaces_client_synced(
                         DisplayChannelClient *dcc, Drawable *drawable)
 {
@@ -473,20 +470,6 @@ static void common_release_recv_buf(RedChannelClient *rcc, uint16_t type, uint32
 }
 
 
-static Drawable* drawable_try_new(DisplayChannel *display)
-{
-    Drawable *drawable;
-
-    if (!display->free_drawables)
-        return NULL;
-
-    drawable = &display->free_drawables->u.drawable;
-    display->free_drawables = display->free_drawables->u.next;
-    display->drawable_count++;
-
-    return drawable;
-}
-
 static void drawable_free(DisplayChannel *display, Drawable *drawable)
 {
     ((_Drawable *)drawable)->u.next = display->free_drawables;
@@ -678,7 +661,7 @@ void current_remove(DisplayChannel *display, TreeItem *item)
     }
 }
 
-static void current_remove_all(DisplayChannel *display, int surface_id)
+void current_remove_all(DisplayChannel *display, int surface_id)
 {
     Ring *ring = &display->surfaces[surface_id].current;
     RingItem *ring_item;
@@ -1048,31 +1031,6 @@ static inline int red_handle_self_bitmap(RedWorker *worker, Drawable *drawable)
     return TRUE;
 }
 
-static bool free_one_drawable(DisplayChannel *display, int force_glz_free)
-{
-    RingItem *ring_item = ring_get_tail(&display->current_list);
-    Drawable *drawable;
-    Container *container;
-
-    if (!ring_item) {
-        return FALSE;
-    }
-    drawable = SPICE_CONTAINEROF(ring_item, Drawable, list_link);
-    if (force_glz_free) {
-        RingItem *glz_item, *next_item;
-        RedGlzDrawable *glz;
-        DRAWABLE_FOREACH_GLZ_SAFE(drawable, glz_item, next_item, glz) {
-            dcc_free_glz_drawable(glz->dcc, glz);
-        }
-    }
-    drawable_draw(display, drawable);
-    container = drawable->tree_item.base.container;
-
-    current_remove_drawable(display, drawable);
-    container_cleanup(container);
-    return TRUE;
-}
-
 static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *red_drawable,
                               uint32_t group_id)
 {
@@ -1090,29 +1048,17 @@ static Drawable *get_drawable(RedWorker *worker, uint8_t effect, RedDrawable *re
         }
     }
 
-    while (!(drawable = drawable_try_new(display))) {
-        if (!free_one_drawable(display, FALSE))
-            return NULL;
+    drawable = display_channel_drawable_try_new(display, group_id, worker->process_commands_generation);
+    if (!drawable) {
+        return NULL;
     }
 
-    bzero(drawable, sizeof(Drawable));
-    drawable->refs = 1;
-    drawable->creation_time = red_get_monotonic_time();
-    ring_item_init(&drawable->list_link);
-    ring_item_init(&drawable->surface_list_link);
-    ring_item_init(&drawable->tree_item.base.siblings_link);
-    drawable->tree_item.base.type = TREE_ITEM_TYPE_DRAWABLE;
-    region_init(&drawable->tree_item.base.rgn);
     drawable->tree_item.effect = effect;
     drawable->red_drawable = red_drawable_ref(red_drawable);
-    drawable->group_id = group_id;
 
     drawable->surface_id = red_drawable->surface_id;
     memcpy(drawable->surface_deps, red_drawable->surface_deps, sizeof(drawable->surface_deps));
-    ring_init(&drawable->pipes);
-    ring_init(&drawable->glz_ring);
 
-    drawable->process_commands_generation = worker->process_commands_generation;
     return drawable;
 }
 
@@ -1324,7 +1270,7 @@ static void image_surface_init(DisplayChannel *display)
     display->image_surfaces.ops = &image_surfaces_ops;
 }
 
-static void drawable_draw(DisplayChannel *display, Drawable *drawable)
+void drawable_draw(DisplayChannel *display, Drawable *drawable)
 {
     RedSurface *surface;
     SpiceCanvas *canvas;
@@ -1792,49 +1738,6 @@ static int red_process_commands(RedWorker *worker, uint32_t max_pipe_size, int *
     return n;
 }
 
-#define RED_RELEASE_BUNCH_SIZE 64
-
-static void red_free_some(RedWorker *worker)
-{
-    DisplayChannel *display = worker->display_channel;
-    int n = 0;
-    DisplayChannelClient *dcc;
-    RingItem *item, *next;
-
-    spice_debug("#draw=%d, #red_draw=%d, #glz_draw=%d", display->drawable_count,
-                display->red_drawable_count, display->glz_drawable_count);
-    FOREACH_DCC(worker->display_channel, item, next, dcc) {
-        GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
-
-        if (glz_dict) {
-            // encoding using the dictionary is prevented since the following operations might
-            // change the dictionary
-            pthread_rwlock_wrlock(&glz_dict->encode_lock);
-            n = red_display_free_some_independent_glz_drawables(dcc);
-        }
-    }
-
-    while (!ring_is_empty(&display->current_list) && n++ < RED_RELEASE_BUNCH_SIZE) {
-        free_one_drawable(display, TRUE);
-    }
-
-    FOREACH_DCC(worker->display_channel, item, next, dcc) {
-        GlzSharedDictionary *glz_dict = dcc ? dcc->glz_dict : NULL;
-
-        if (glz_dict) {
-            pthread_rwlock_unlock(&glz_dict->encode_lock);
-        }
-    }
-}
-
-void display_channel_current_flush(DisplayChannel *display, int surface_id)
-{
-    while (!ring_is_empty(&display->surfaces[surface_id].current_list)) {
-        free_one_drawable(display, FALSE);
-    }
-    current_remove_all(display, surface_id);
-}
-
 static void fill_base(SpiceMarshaller *base_marshaller, Drawable *drawable)
 {
     SpiceMsgDisplayBase base;
@@ -1846,31 +1749,6 @@ static void fill_base(SpiceMarshaller *base_marshaller, Drawable *drawable)
     spice_marshall_DisplayBase(base_marshaller, &base);
 }
 
-/*
- * Remove from the global lz dictionary some glz_drawables that have no reference to
- * Drawable (their qxl drawables are released too).
- * NOTE - the caller should prevent encoding using the dictionary during the operation
- */
-static int red_display_free_some_independent_glz_drawables(DisplayChannelClient *dcc)
-{
-    RingItem *ring_link;
-    int n = 0;
-
-    if (!dcc) {
-        return 0;
-    }
-    ring_link = ring_get_head(&dcc->glz_drawables);
-    while ((n < RED_RELEASE_BUNCH_SIZE) && (ring_link != NULL)) {
-        RedGlzDrawable *glz_drawable = SPICE_CONTAINEROF(ring_link, RedGlzDrawable, link);
-        ring_link = ring_next(&dcc->glz_drawables, ring_link);
-        if (!glz_drawable->drawable) {
-            dcc_free_glz_drawable(dcc, glz_drawable);
-            n++;
-        }
-    }
-    return n;
-}
-
 static inline void red_display_add_image_to_pixmap_cache(RedChannelClient *rcc,
                                                          SpiceImage *image, SpiceImage *io_image,
                                                          int is_lossy)
@@ -5828,7 +5706,7 @@ static void handle_dev_oom(void *opaque, void *payload)
         red_channel_push(&worker->display_channel->common.base);
     }
     if (worker->qxl->st->qif->flush_resources(worker->qxl) == 0) {
-        red_free_some(worker);
+        display_channel_free_some(worker->display_channel);
         worker->qxl->st->qif->flush_resources(worker->qxl);
     }
     spice_debug("OOM2 #draw=%u, #red_draw=%u, #glz_draw=%u current %u pipes %u",


More information about the Spice-commits mailing list