[Spice-devel] [PATCH] Limiting video streaming to the primary surface. freedesktop bug #28088.

Yonit Halperin yhalperi at redhat.com
Sat Aug 21 23:17:22 PDT 2010


---
 server/red_worker.c |   47 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/server/red_worker.c b/server/red_worker.c
index cbfe405..ef9aa53 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1516,7 +1516,10 @@ static inline void red_destroy_surface(RedWorker *worker, uint32_t surface_id)
 
     if (!--surface->refs) {
 #ifdef STREAM_TRACE
-        red_reset_stream_trace(worker);
+        // only primary surface streams are supported
+        if (surface_id == 0) {
+            red_reset_stream_trace(worker);
+        }
 #endif
         if (surface->context.canvas) {
             surface->context.canvas->ops->destroy(surface->context.canvas);
@@ -2504,6 +2507,7 @@ static inline void red_stop_stream_gracefully(RedWorker *worker, Stream *stream)
 #endif
 
 #ifdef STREAM_TRACE
+// region should be a primary surface region
 static void red_detach_streams_behind(RedWorker *worker, QRegion *region)
 {
     Ring *ring = &worker->streams;
@@ -2559,6 +2563,11 @@ static void red_streams_update_clip(RedWorker *worker, Drawable *drawable)
         return;
     }
 
+    // only primary surface streams are supported
+    if (drawable->surface_id != 0) {
+        return;
+    }
+
     ring = &worker->streams;
     item = ring_get_head(ring);
 
@@ -3262,10 +3271,12 @@ static inline int red_current_add(RedWorker *worker, Ring *ring, Drawable *drawa
         red_streams_update_clip(worker, drawable);
     } else {
 #ifdef STREAM_TRACE
-        red_detach_streams_behind(worker, &drawable->tree_item.base.rgn);
+        if (drawable->surface_id == 0) {
+            red_detach_streams_behind(worker, &drawable->tree_item.base.rgn);
 #else
-        red_stop_streams_behind(worker, &drawable->tree_item.base.rgn);
+            red_stop_streams_behind(worker, &drawable->tree_item.base.rgn);
 #endif
+        }
     }
     region_destroy(&exclude_rgn);
     __current_add_drawable(worker, drawable, ring);
@@ -3416,11 +3427,15 @@ static inline int red_current_add_with_shadow(RedWorker *worker, Ring *ring, Dra
     worker->current_size++;
     // item and his shadow must initially be placed in the same container.
     // for now putting them on root.
+
+    // only primary surface streams are supported
+    if (item->surface_id == 0) {
 #ifdef STREAM_TRACE
-    red_detach_streams_behind(worker, &shadow->base.rgn);
+        red_detach_streams_behind(worker, &shadow->base.rgn);
 #else
-    red_stop_streams_behind(worker, &shadow->base.rgn);
+        red_stop_streams_behind(worker, &shadow->base.rgn);
 #endif
+    }
     ring_add(ring, &shadow->base.siblings_link);
     __current_add_drawable(worker, item, ring);
     if (item->tree_item.effect == QXL_EFFECT_OPAQUE) {
@@ -3434,11 +3449,13 @@ static inline int red_current_add_with_shadow(RedWorker *worker, Ring *ring, Dra
         region_destroy(&exclude_rgn);
         red_streams_update_clip(worker, item);
     } else {
+        if (item->surface_id == 0) {
 #ifdef STREAM_TRACE
-        red_detach_streams_behind(worker, &item->tree_item.base.rgn);
+            red_detach_streams_behind(worker, &item->tree_item.base.rgn);
 #else
-        red_stop_streams_behind(worker, &item->tree_item.base.rgn);
+            red_stop_streams_behind(worker, &item->tree_item.base.rgn);
 #endif
+        }
     }
     stat_add(&worker->add_stat, start_time);
     return TRUE;
@@ -3459,6 +3476,11 @@ static inline void red_update_streamable(RedWorker *worker, Drawable *drawable,
         return;
     }
 
+    // only primary surface streams are supported
+    if (drawable->surface_id != 0) {
+        return;
+    }
+
     if (drawable->tree_item.effect != QXL_EFFECT_OPAQUE ||
                                         red_drawable->type != QXL_DRAW_COPY ||
                                         red_drawable->u.copy.rop_descriptor != SPICE_ROPD_OP_PUT) {
@@ -3753,6 +3775,17 @@ static inline int red_handle_surfaces_dependencies(RedWorker *worker, Drawable *
         if (drawable->surfaces_dest[x] != drawable->surface_id) {
             add_to_surface_dependency(worker, drawable->surfaces_dest[x],
                                       &drawable->depend_items[x], drawable);
+
+            if (drawable->surfaces_dest[x] == 0) {
+                QRegion depend_region;
+                region_init(&depend_region);
+                region_add(&depend_region, &drawable->red_drawable->surfaces_rects[x]);
+#ifdef STREAM_TRACE
+                red_detach_streams_behind(worker, &depend_region);
+#else
+                red_stop_streams_behind(worker, &depend_region);
+#endif
+            }
         }
     }
 
-- 
1.7.1.1



More information about the Spice-devel mailing list