From b61bd286bc27bf791be52dfc74af628c5969318d Mon Sep 17 00:00:00 2001 From: Marc-André Lureau Date: Fri, 27 Sep 2013 15:06:57 +0200 Subject: worker: move display_channel_draw Acked-by: Frediano Ziglio --- server/red_worker.c | 155 ---------------------------------------------------- 1 file changed, 155 deletions(-) (limited to 'server/red_worker.c') diff --git a/server/red_worker.c b/server/red_worker.c index 235b6eec..19ee4e67 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -936,161 +936,6 @@ static void image_surface_init(DisplayChannel *display) display->image_surfaces.ops = &image_surfaces_ops; } -static void surface_update_dest(RedSurface *surface, const SpiceRect *area) -{ - SpiceCanvas *canvas = surface->context.canvas; - int stride = surface->context.stride; - uint8_t *line_0 = surface->context.line_0; - - if (surface->context.canvas_draws_on_surface) - return; - - int h = area->bottom - area->top; - if (h == 0) - return; - - spice_return_if_fail(stride < 0); - - uint8_t *dest = line_0 + (area->top * stride) + area->left * sizeof(uint32_t); - dest += (h - 1) * stride; - canvas->ops->read_bits(canvas, dest, -stride, area); -} - -/* - Renders drawables for updating the requested area, but only drawables that are older - than 'last' (exclusive). -*/ -void display_channel_draw_till(DisplayChannel *display, const SpiceRect *area, int surface_id, - Drawable *last) -{ - RedSurface *surface; - Drawable *surface_last = NULL; - Ring *ring; - RingItem *ring_item; - Drawable *now; - QRegion rgn; - - spice_assert(last); - spice_assert(ring_item_is_linked(&last->list_link)); - - surface = &display->surfaces[surface_id]; - - if (surface_id != last->surface_id) { - // find the nearest older drawable from the appropriate surface - ring = &display->current_list; - ring_item = &last->list_link; - while ((ring_item = ring_next(ring, ring_item))) { - now = SPICE_CONTAINEROF(ring_item, Drawable, list_link); - if (now->surface_id == surface_id) { - surface_last = now; - break; - } - } - } else { - ring_item = ring_next(&surface->current_list, &last->surface_list_link); - if (ring_item) { - surface_last = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link); - } - } - - if (!surface_last) { - return; - } - - ring = &surface->current_list; - ring_item = &surface_last->surface_list_link; - - region_init(&rgn); - region_add(&rgn, area); - - // find the first older drawable that intersects with the area - do { - now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link); - if (region_intersects(&rgn, &now->tree_item.base.rgn)) { - surface_last = now; - break; - } - } while ((ring_item = ring_next(ring, ring_item))); - - region_destroy(&rgn); - - if (!surface_last) { - return; - } - - do { - Container *container; - - ring_item = ring_get_tail(&surface->current_list); - now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link); - now->refs++; - container = now->tree_item.base.container; - current_remove_drawable(display, now); - container_cleanup(container); - /* drawable_draw may call display_channel_draw for the surfaces 'now' depends on. Notice, - that it is valid to call display_channel_draw in this case and not display_channel_draw_till: - It is impossible that there was newer item then 'last' in one of the surfaces - that display_channel_draw is called for, Otherwise, 'now' would have already been rendered. - See the call for red_handle_depends_on_target_surface in red_process_draw */ - drawable_draw(display, now); - display_channel_drawable_unref(display, now); - } while (now != surface_last); - surface_update_dest(surface, area); -} - -void display_channel_draw(DisplayChannel *display, const SpiceRect *area, int surface_id) -{ - RedSurface *surface; - Ring *ring; - RingItem *ring_item; - QRegion rgn; - Drawable *last; - Drawable *now; - spice_debug("surface %d: area ==>", surface_id); - rect_debug(area); - - spice_return_if_fail(surface_id >= 0 && surface_id < NUM_SURFACES); - spice_return_if_fail(area); - spice_return_if_fail(area->left >= 0 && area->top >= 0 && - area->left < area->right && area->top < area->bottom); - - surface = &display->surfaces[surface_id]; - - last = NULL; - ring = &surface->current_list; - ring_item = ring; - - region_init(&rgn); - region_add(&rgn, area); - while ((ring_item = ring_next(ring, ring_item))) { - now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link); - if (region_intersects(&rgn, &now->tree_item.base.rgn)) { - last = now; - break; - } - } - region_destroy(&rgn); - - if (!last) { - surface_update_dest(surface, area); - return; - } - - do { - Container *container; - - ring_item = ring_get_tail(&surface->current_list); - now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link); - now->refs++; - container = now->tree_item.base.container; - current_remove_drawable(display, now); - container_cleanup(container); - drawable_draw(display, now); - display_channel_drawable_unref(display, now); - } while (now != last); - surface_update_dest(surface, area); -} - static int red_process_cursor(RedWorker *worker, uint32_t max_pipe_size, int *ring_is_empty) { QXLCommandExt ext_cmd; -- cgit