[Spice-devel] [RFC v4 27/62] server/red_worker: move streams from RedWorker to Surfaces
Alon Levy
alevy at redhat.com
Tue Apr 26 03:54:52 PDT 2011
Now Surfaces will keep a copy of the current video streams. This is
again just a technical move, no functional changes.
---
server/red_worker.c | 157 +++++++++++++++++++++++++++------------------------
1 files changed, 83 insertions(+), 74 deletions(-)
diff --git a/server/red_worker.c b/server/red_worker.c
index 30a829e..1c9bf1c 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -820,6 +820,10 @@ struct Surfaces {
uint32_t n_surfaces;
SpiceImageSurfaces image_surfaces;
+ Stream streams_buf[NUM_STREAMS];
+ Stream *free_streams;
+ Ring streams;
+
#ifdef PIPE_DEBUG
uint32_t last_id;
#endif
@@ -871,9 +875,6 @@ typedef struct RedWorker {
uint32_t mouse_mode;
uint32_t streaming_video;
- Stream streams_buf[NUM_STREAMS];
- Stream *free_streams;
- Ring streams;
ItemTrace items_trace[NUM_TRACE_ITEMS];
uint32_t next_item_trace;
@@ -932,9 +933,10 @@ static void red_update_area_surfaces(RedWorker *worker, Surfaces *surfaces,
static void red_release_cursor(RedWorker *worker, CursorItem *cursor);
static inline void release_drawable(RedWorker *worker, Surfaces *surfaces, Drawable *item);
static void red_display_release_stream(DisplayChannel *display, StreamAgent *agent);
-static inline void red_detach_stream(RedWorker *worker, Stream *stream);
-static void red_stop_stream(RedWorker *worker, Stream *stream);
-static inline void red_stream_maintenance(RedWorker *worker, Drawable *candidate, Drawable *sect);
+static inline void red_detach_stream(Surfaces *surfaces, Stream *stream);
+static void red_stop_stream(RedWorker *worker, Surfaces *surfaces, Stream *stream);
+static inline void red_stream_maintenance(RedWorker *worker,
+ Surfaces *surfaces, Drawable *candidate, Drawable *sect);
static inline void display_begin_send_message(RedChannelClient *rcc, SpiceMarshaller *base_marshaller);
static void red_release_pixmap_cache(DisplayChannel *channel);
static void red_release_glz(DisplayChannel *channel);
@@ -1581,7 +1583,7 @@ static inline void current_remove_drawable(RedWorker *worker, Surfaces *surfaces
surfaces->transparent_count--;
}
if (item->stream) {
- red_detach_stream(worker, item->stream);
+ red_detach_stream(surfaces, item->stream);
} else {
red_add_item_trace(worker, item);
}
@@ -1865,7 +1867,8 @@ static inline int __contained_by(RedWorker *worker, TreeItem *item, Ring *ring)
return FALSE;
}
-static inline void __exclude_region(RedWorker *worker, Ring *ring, TreeItem *item, QRegion *rgn,
+static inline void __exclude_region(RedWorker *worker, Surfaces *surfaces,
+ Ring *ring, TreeItem *item, QRegion *rgn,
Ring **top_ring, Drawable *frame_candidate)
{
QRegion and_rgn;
@@ -1905,7 +1908,7 @@ static inline void __exclude_region(RedWorker *worker, Ring *ring, TreeItem *ite
} else {
if (frame_candidate) {
Drawable *drawable = SPICE_CONTAINEROF(draw, Drawable, tree_item);
- red_stream_maintenance(worker, frame_candidate, drawable);
+ red_stream_maintenance(worker, surfaces, frame_candidate, drawable);
}
region_exclude(&draw->base.rgn, &and_rgn);
}
@@ -1959,7 +1962,7 @@ static void exclude_region(RedWorker *worker, Surfaces *surfaces, Ring *ring,
if (region_intersects(rgn, &now->rgn)) {
print_base_item("EXCLUDE2", now);
- __exclude_region(worker, ring, now, rgn, &top_ring, frame_candidate);
+ __exclude_region(worker, surfaces, ring, now, rgn, &top_ring, frame_candidate);
print_base_item("EXCLUDE3", now);
if (region_is_empty(&now->rgn)) {
@@ -2117,24 +2120,24 @@ static int is_same_drawable(RedWorker *worker, Drawable *d1, Drawable *d2)
}
}
-static inline void red_free_stream(RedWorker *worker, Stream *stream)
+static inline void red_free_stream(Surfaces *surfaces, Stream *stream)
{
- stream->next = worker->free_streams;
- worker->free_streams = stream;
+ stream->next = surfaces->free_streams;
+ surfaces->free_streams = stream;
}
-static void red_release_stream(RedWorker *worker, Stream *stream)
+static void red_release_stream(Surfaces *surfaces, Stream *stream)
{
if (!--stream->refs) {
ASSERT(!ring_item_is_linked(&stream->link));
if (stream->mjpeg_encoder) {
mjpeg_encoder_destroy(stream->mjpeg_encoder);
}
- red_free_stream(worker, stream);
+ red_free_stream(surfaces, stream);
}
}
-static inline void red_detach_stream(RedWorker *worker, Stream *stream)
+static inline void red_detach_stream(Surfaces *surfaces, Stream *stream)
{
ASSERT(stream->current && stream->current->stream);
ASSERT(stream->current->stream == stream);
@@ -2208,7 +2211,7 @@ static void red_display_release_stream_clip(DisplayChannel* channel, StreamClipI
}
}
-static void red_attach_stream(RedWorker *worker, Drawable *drawable, Stream *stream)
+static void red_attach_stream(RedWorker *worker, Surfaces *surfaces, Drawable *drawable, Stream *stream)
{
DisplayChannel *channel;
ASSERT(!drawable->stream && !stream->current);
@@ -2218,7 +2221,7 @@ static void red_attach_stream(RedWorker *worker, Drawable *drawable, Stream *str
stream->last_time = drawable->creation_time;
if ((channel = worker->display_channel)) {
- StreamAgent *agent = &channel->stream_agents[stream - worker->streams_buf];
+ StreamAgent *agent = &channel->stream_agents[stream - surfaces->streams_buf];
if (!region_is_equal(&agent->vis_region, &drawable->tree_item.base.rgn)) {
region_destroy(&agent->vis_region);
region_clone(&agent->vis_region, &drawable->tree_item.base.rgn);
@@ -2227,7 +2230,7 @@ static void red_attach_stream(RedWorker *worker, Drawable *drawable, Stream *str
}
}
-static void red_stop_stream(RedWorker *worker, Stream *stream)
+static void red_stop_stream(RedWorker *worker, Surfaces *surfaces, Stream *stream)
{
DisplayChannel *channel;
ASSERT(ring_item_is_linked(&stream->link));
@@ -2235,14 +2238,14 @@ static void red_stop_stream(RedWorker *worker, Stream *stream)
if ((channel = worker->display_channel)) {
StreamAgent *stream_agent;
- stream_agent = &channel->stream_agents[stream - worker->streams_buf];
+ stream_agent = &channel->stream_agents[stream - surfaces->streams_buf];
region_clear(&stream_agent->vis_region);
ASSERT(!pipe_item_is_linked(&stream_agent->destroy_item));
stream->refs++;
red_channel_client_pipe_add(channel->common.base.rcc, &stream_agent->destroy_item);
}
ring_remove(&stream->link);
- red_release_stream(worker, stream);
+ red_release_stream(surfaces, stream);
}
static inline void red_detach_stream_gracefully(RedWorker *worker, Stream *stream)
@@ -2266,13 +2269,14 @@ static inline void red_detach_stream_gracefully(RedWorker *worker, Stream *strea
region_ret_rects(&upgrade_item->drawable->tree_item.base.rgn, upgrade_item->rects->rects, n_rects);
red_channel_client_pipe_add(channel->common.base.rcc, &upgrade_item->base);
}
- red_detach_stream(worker, stream);
+ red_detach_stream(&worker->surfaces, stream);
}
// region should be a primary surface region
static void red_detach_streams_behind(RedWorker *worker, QRegion *region)
{
- Ring *ring = &worker->streams;
+ Surfaces *surfaces = &worker->surfaces;
+ Ring *ring = &surfaces->streams;
RingItem *item = ring_get_head(ring);
DisplayChannel *channel = worker->display_channel;
@@ -2281,7 +2285,7 @@ static void red_detach_streams_behind(RedWorker *worker, QRegion *region)
item = ring_next(ring, item);
if (channel) {
- StreamAgent *agent = &channel->stream_agents[stream - worker->streams_buf];
+ StreamAgent *agent = &channel->stream_agents[stream - surfaces->streams_buf];
if (region_intersects(&agent->vis_region, region)) {
region_clear(&agent->vis_region);
push_stream_clip(channel, agent);
@@ -2291,7 +2295,7 @@ static void red_detach_streams_behind(RedWorker *worker, QRegion *region)
}
} else if (stream->current && region_intersects(&stream->current->tree_item.base.rgn,
region)) {
- red_detach_stream(worker, stream);
+ red_detach_stream(surfaces, stream);
}
}
}
@@ -2299,6 +2303,7 @@ static void red_detach_streams_behind(RedWorker *worker, QRegion *region)
static void red_streams_update_clip(RedWorker *worker, Drawable *drawable)
{
DisplayChannel *channel = worker->display_channel;
+ Surfaces *surfaces = &worker->surfaces;
Ring *ring;
RingItem *item;
@@ -2311,7 +2316,7 @@ static void red_streams_update_clip(RedWorker *worker, Drawable *drawable)
return;
}
- ring = &worker->streams;
+ ring = &surfaces->streams;
item = ring_get_head(ring);
while (item) {
@@ -2320,7 +2325,7 @@ static void red_streams_update_clip(RedWorker *worker, Drawable *drawable)
item = ring_next(ring, item);
- agent = &channel->stream_agents[stream - worker->streams_buf];
+ agent = &channel->stream_agents[stream - surfaces->streams_buf];
if (stream->current == drawable) {
continue;
@@ -2333,10 +2338,10 @@ static void red_streams_update_clip(RedWorker *worker, Drawable *drawable)
}
}
-static inline unsigned int red_get_streams_timout(RedWorker *worker)
+static inline unsigned int red_get_streams_timout(Surfaces *surfaces)
{
unsigned int timout = -1;
- Ring *ring = &worker->streams;
+ Ring *ring = &surfaces->streams;
RingItem *item = ring;
struct timespec time;
@@ -2356,9 +2361,9 @@ static inline unsigned int red_get_streams_timout(RedWorker *worker)
return timout;
}
-static inline void red_handle_streams_timout(RedWorker *worker)
+static inline void red_handle_streams_timout(RedWorker *worker, Surfaces *surfaces)
{
- Ring *ring = &worker->streams;
+ Ring *ring = &surfaces->streams;
struct timespec time;
RingItem *item;
@@ -2372,7 +2377,7 @@ static inline void red_handle_streams_timout(RedWorker *worker)
if (stream->current) {
red_detach_stream_gracefully(worker, stream);
}
- red_stop_stream(worker, stream);
+ red_stop_stream(worker, &worker->surfaces, stream);
}
}
}
@@ -2380,17 +2385,17 @@ static inline void red_handle_streams_timout(RedWorker *worker)
static void red_display_release_stream(DisplayChannel *display, StreamAgent *agent)
{
ASSERT(agent->stream);
- red_release_stream(display->common.worker, agent->stream);
+ red_release_stream(&display->common.worker->surfaces, agent->stream);
}
-static inline Stream *red_alloc_stream(RedWorker *worker)
+static inline Stream *red_alloc_stream(Surfaces *surfaces)
{
Stream *stream;
- if (!worker->free_streams) {
+ if (!surfaces->free_streams) {
return NULL;
}
- stream = worker->free_streams;
- worker->free_streams = worker->free_streams->next;
+ stream = surfaces->free_streams;
+ surfaces->free_streams = surfaces->free_streams->next;
return stream;
}
@@ -2415,7 +2420,7 @@ static int get_bit_rate(RedWorker *worker,
static void red_display_create_stream(DisplayChannel *display, Stream *stream)
{
- StreamAgent *agent = &display->stream_agents[stream - display->common.worker->streams_buf];
+ StreamAgent *agent = &display->stream_agents[stream - display->common.worker->surfaces.streams_buf];
stream->refs++;
ASSERT(region_is_empty(&agent->vis_region));
if (stream->current) {
@@ -2432,6 +2437,7 @@ static void red_display_create_stream(DisplayChannel *display, Stream *stream)
static void red_create_stream(RedWorker *worker, Drawable *drawable)
{
+ Surfaces *surfaces = &worker->surfaces;
Stream *stream;
SpiceRect* src_rect;
int stream_width;
@@ -2439,7 +2445,7 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable)
ASSERT(!drawable->stream);
- if (!(stream = red_alloc_stream(worker))) {
+ if (!(stream = red_alloc_stream(surfaces))) {
return;
}
@@ -2450,7 +2456,7 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable)
stream->mjpeg_encoder = mjpeg_encoder_new(stream_width, stream_height);
- ring_add(&worker->streams, &stream->link);
+ ring_add(&surfaces->streams, &stream->link);
stream->current = drawable;
stream->last_time = drawable->creation_time;
stream->width = src_rect->right - src_rect->left;
@@ -2471,7 +2477,7 @@ static void red_create_stream(RedWorker *worker, Drawable *drawable)
static void red_disply_start_streams(DisplayChannel *display_channel)
{
- Ring *ring = &display_channel->common.worker->streams;
+ Ring *ring = &display_channel->common.worker->surfaces.streams;
RingItem *item = ring;
while ((item = ring_next(ring, item))) {
@@ -2485,7 +2491,7 @@ static void red_display_init_streams(DisplayChannel *display)
int i;
for (i = 0; i < NUM_STREAMS; i++) {
StreamAgent *agent = &display->stream_agents[i];
- agent->stream = &display->common.worker->streams_buf[i];
+ agent->stream = &display->common.worker->surfaces.streams_buf[i];
region_init(&agent->vis_region);
red_channel_pipe_item_init(&display->common.base,
&agent->create_item, PIPE_ITEM_TYPE_STREAM_CREATE);
@@ -2503,16 +2509,16 @@ static void red_display_destroy_streams(DisplayChannel *display)
}
}
-static void red_init_streams(RedWorker *worker)
+static void red_init_streams(Surfaces *surfaces)
{
int i;
- ring_init(&worker->streams);
- worker->free_streams = NULL;
+ ring_init(&surfaces->streams);
+ surfaces->free_streams = NULL;
for (i = 0; i < NUM_STREAMS; i++) {
- Stream *stream = &worker->streams_buf[i];
+ Stream *stream = &surfaces->streams_buf[i];
ring_item_init(&stream->link);
- red_free_stream(worker, stream);
+ red_free_stream(surfaces, stream);
}
}
@@ -2590,7 +2596,7 @@ static int display_channel_is_low_bandwidth(DisplayChannel *display_channel)
return FALSE;
}
-static inline void pre_stream_item_swap(RedWorker *worker, Stream *stream)
+static inline void pre_stream_item_swap(RedWorker *worker, Surfaces *surfaces, Stream *stream)
{
ASSERT(stream->current);
@@ -2598,7 +2604,7 @@ static inline void pre_stream_item_swap(RedWorker *worker, Stream *stream)
return;
}
- int index = stream - worker->streams_buf;
+ int index = stream - surfaces->streams_buf;
StreamAgent *agent = &worker->display_channel->stream_agents[index];
if (pipe_item_is_linked(&stream->current->pipe_item)) {
@@ -2687,7 +2693,8 @@ static int red_stream_add_frame(RedWorker* worker, Drawable *frame_drawable,
return FALSE;
}
-static inline void red_stream_maintenance(RedWorker *worker, Drawable *candidate, Drawable *prev)
+static inline void red_stream_maintenance(RedWorker *worker,
+ Surfaces *surfaces, Drawable *candidate, Drawable *prev)
{
Stream *stream;
@@ -2700,10 +2707,10 @@ static inline void red_stream_maintenance(RedWorker *worker, Drawable *candidate
}
if ((stream = prev->stream)) {
- pre_stream_item_swap(worker, stream);
- red_detach_stream(worker, stream);
+ pre_stream_item_swap(worker, surfaces, stream);
+ red_detach_stream(surfaces, stream);
prev->streamable = FALSE; //prevent item trace
- red_attach_stream(worker, candidate, stream);
+ red_attach_stream(worker, surfaces, candidate, stream);
} else {
red_stream_add_frame(worker, candidate,
prev->frames_count,
@@ -2745,7 +2752,7 @@ static inline int red_current_add_equal(RedWorker *worker, Surfaces *surfaces,
if (item->effect == QXL_EFFECT_OPAQUE) {
int add_after = !!other_drawable->stream && is_drawable_independent_from_surfaces(drawable);
- red_stream_maintenance(worker, drawable, other_drawable);
+ red_stream_maintenance(worker, surfaces, drawable, other_drawable);
__current_add_drawable(worker, surfaces, drawable, &other->siblings_link);
if (add_after) {
red_pipe_add_drawable_after(worker, drawable, other_drawable);
@@ -2783,7 +2790,7 @@ static inline int red_current_add_equal(RedWorker *worker, Surfaces *surfaces,
return FALSE;
}
-static inline void red_use_stream_trace(RedWorker *worker, Drawable *drawable)
+static inline void red_use_stream_trace(RedWorker *worker, Surfaces *surfaces, Drawable *drawable)
{
ItemTrace *trace;
ItemTrace *trace_end;
@@ -2794,8 +2801,7 @@ static inline void red_use_stream_trace(RedWorker *worker, Drawable *drawable)
return;
}
-
- ring = &worker->streams;
+ ring = &surfaces->streams;
item = ring_get_head(ring);
while (item) {
@@ -2807,7 +2813,7 @@ static inline void red_use_stream_trace(RedWorker *worker, Drawable *drawable)
&stream->dest_area,
stream->last_time,
stream)) {
- red_attach_stream(worker, drawable, stream);
+ red_attach_stream(worker, surfaces, drawable, stream);
return;
}
item = ring_next(ring, item);
@@ -2830,14 +2836,14 @@ static inline void red_use_stream_trace(RedWorker *worker, Drawable *drawable)
static void red_reset_stream_trace(RedWorker *worker, Surfaces *surfaces)
{
- Ring *ring = &worker->streams;
+ Ring *ring = &surfaces->streams;
RingItem *item = ring_get_head(ring);
while (item) {
Stream *stream = SPICE_CONTAINEROF(item, Stream, link);
item = ring_next(ring, item);
if (!stream->current) {
- red_stop_stream(worker, stream);
+ red_stop_stream(worker, surfaces, stream);
} else {
red_printf("attached stream");
}
@@ -2950,7 +2956,7 @@ static inline int red_current_add(RedWorker *worker, Surfaces *surfaces,
if (item->effect == QXL_EFFECT_OPAQUE) {
region_or(&exclude_rgn, &item->base.rgn);
exclude_region(worker, surfaces, ring, exclude_base, &exclude_rgn, NULL, drawable);
- red_use_stream_trace(worker, drawable);
+ red_use_stream_trace(worker, surfaces, drawable);
red_streams_update_clip(worker, drawable);
} else {
if (drawable->surface_id == 0) {
@@ -7543,6 +7549,7 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
Stream *stream = drawable->stream;
SpiceImage *image;
RedWorker* worker;
+ Surfaces *surfaces;
uint8_t *frame;
size_t frame_stride;
int n;
@@ -7551,13 +7558,14 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
ASSERT(drawable->red_drawable->type == QXL_DRAW_COPY);
worker = display_channel->common.worker;
+ surfaces = &worker->surfaces;
image = drawable->red_drawable->u.copy.src_bitmap;
if (image->descriptor.type != SPICE_IMAGE_TYPE_BITMAP) {
return FALSE;
}
- StreamAgent *agent = &display_channel->stream_agents[stream - worker->streams_buf];
+ StreamAgent *agent = &display_channel->stream_agents[stream - surfaces->streams_buf];
uint64_t time_now = red_now();
if (time_now - agent->last_send_time < (1000 * 1000 * 1000) / agent->fps) {
agent->frames--;
@@ -7571,21 +7579,21 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
case SPICE_BITMAP_FMT_32BIT:
if (!red_rgb32bpp_to_24(worker, &drawable->red_drawable->u.copy.src_area,
&image->u.bitmap, frame, frame_stride,
- stream - worker->streams_buf, stream)) {
+ stream - surfaces->streams_buf, stream)) {
return FALSE;
}
break;
case SPICE_BITMAP_FMT_16BIT:
if (!red_rgb16bpp_to_24(worker, &drawable->red_drawable->u.copy.src_area,
&image->u.bitmap, frame, frame_stride,
- stream - worker->streams_buf, stream)) {
+ stream - surfaces->streams_buf, stream)) {
return FALSE;
}
break;
case SPICE_BITMAP_FMT_24BIT:
if (!red_rgb24bpp_to_24(worker, &drawable->red_drawable->u.copy.src_area,
&image->u.bitmap, frame, frame_stride,
- stream - worker->streams_buf, stream)) {
+ stream - surfaces->streams_buf, stream)) {
return FALSE;
}
break;
@@ -7614,7 +7622,7 @@ static inline int red_marshall_stream_data(RedChannelClient *rcc,
SpiceMsgDisplayStreamData stream_data;
- stream_data.id = stream - worker->streams_buf;
+ stream_data.id = stream - surfaces->streams_buf;
stream_data.multi_media_time = drawable->red_drawable->mm_time;
stream_data.data_size = n;
spice_marshall_msg_display_stream_data(base_marshaller, &stream_data);
@@ -9704,14 +9712,14 @@ static inline void handle_dev_destroy_surfaces(RedWorker *worker)
//to handle better
for (i = 0; i < NUM_SURFACES; ++i) {
if (surfaces->surfaces[i].context.canvas) {
- destroy_surface_wait(worker, &worker->surfaces, i);
+ destroy_surface_wait(worker, surfaces, i);
if (surfaces->surfaces[i].context.canvas) {
red_destroy_surface(worker, surfaces, i);
}
ASSERT(!surfaces->surfaces[i].context.canvas);
}
}
- ASSERT(ring_is_empty(&worker->streams));
+ ASSERT(ring_is_empty(&surfaces->streams));
red_wait_outgoing_item((RedChannel *)worker->cursor_channel);
if (worker->cursor_channel) {
@@ -9779,6 +9787,7 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker)
{
RedWorkerMessage message;
uint32_t surface_id;
+ Surfaces *surfaces = &worker->surfaces;
receive_data(worker->channel, &surface_id, sizeof(uint32_t));
@@ -9800,9 +9809,9 @@ static inline void handle_dev_destroy_primary_surface(RedWorker *worker)
}
flush_all_qxl_commands(worker);
- destroy_surface_wait(worker, &worker->surfaces, 0);
- red_destroy_surface(worker, &worker->surfaces, 0);
- ASSERT(ring_is_empty(&worker->streams));
+ destroy_surface_wait(worker, surfaces, 0);
+ red_destroy_surface(worker, surfaces, 0);
+ ASSERT(ring_is_empty(&surfaces->streams));
ASSERT(!worker->surfaces.surfaces[surface_id].context.canvas);
@@ -10116,7 +10125,7 @@ static void red_init(RedWorker *worker, WorkerInitData *init_data)
image_cache_init(&worker->image_cache);
drawables_init(worker);
cursor_items_init(worker);
- red_init_streams(worker);
+ red_init_streams(&worker->surfaces);
stat_init(&worker->add_stat, add_stat_name);
stat_init(&worker->exclude_stat, exclude_stat_name);
stat_init(&worker->__exclude_stat, __exclude_stat_name);
@@ -10179,9 +10188,9 @@ void *red_worker_main(void *arg)
struct epoll_event *event;
struct epoll_event *end;
- worker.epoll_timeout = MIN(red_get_streams_timout(&worker), worker.epoll_timeout);
+ worker.epoll_timeout = MIN(red_get_streams_timout(&worker.surfaces), worker.epoll_timeout);
num_events = epoll_wait(worker.epoll, events, MAX_EPOLL_SOURCES, worker.epoll_timeout);
- red_handle_streams_timout(&worker);
+ red_handle_streams_timout(&worker, &worker.surfaces);
if (worker.display_channel && worker.display_channel->glz_dict) {
/* during migration, in the dest, the display channel can be initialized
--
1.7.4.4
More information about the Spice-devel
mailing list