On Mon, 2015-11-23 at 17:01 +0000, Frediano Ziglio wrote: > From: Marc-André Lureau <marcandre.lureau@xxxxxxxxx> > > --- > server/display-channel.c | 236 ++++++++++++++++++++++++++++++++++++++++++++ > server/display-channel.h | 8 ++ > server/red_worker.c | 251 +--------------------------------------------- > - > 3 files changed, 248 insertions(+), 247 deletions(-) > > diff --git a/server/display-channel.c b/server/display-channel.c > index ba7f443..5e75019 100644 > --- a/server/display-channel.c > +++ b/server/display-channel.c > @@ -1000,6 +1000,22 @@ static Drawable* drawable_try_new(DisplayChannel > *display) > return drawable; > } > > +static void drawable_free(DisplayChannel *display, Drawable *drawable) > +{ > + ((_Drawable *)drawable)->u.next = display->free_drawables; > + display->free_drawables = (_Drawable *)drawable; > +} > + > +void drawables_init(DisplayChannel *display) > +{ > + int i; > + > + display->free_drawables = NULL; > + for (i = 0; i < NUM_DRAWABLES; i++) { > + drawable_free(display, &display->drawables[i].u.drawable); > + } > +} > + > Drawable *display_channel_drawable_try_new(DisplayChannel *display, > int group_id, int > process_commands_generation) > { > @@ -1025,3 +1041,223 @@ Drawable > *display_channel_drawable_try_new(DisplayChannel *display, > > return drawable; > } > + > +static void depended_item_remove(DependItem *item) > +{ > + spice_return_if_fail(item->drawable); > + spice_return_if_fail(ring_item_is_linked(&item->ring_item)); > + > + item->drawable = NULL; > + ring_remove(&item->ring_item); > +} > + > +static void drawable_remove_dependencies(DisplayChannel *display, Drawable > *drawable) > +{ > + int x; > + int surface_id; > + > + for (x = 0; x < 3; ++x) { > + surface_id = drawable->surface_deps[x]; > + if (surface_id != -1 && drawable->depend_items[x].drawable) { > + depended_item_remove(&drawable->depend_items[x]); > + } > + } > +} > + > +static void drawable_unref_surface_deps(DisplayChannel *display, Drawable > *drawable) > +{ > + int x; > + int surface_id; > + > + for (x = 0; x < 3; ++x) { > + surface_id = drawable->surface_deps[x]; > + if (surface_id == -1) { > + continue; > + } > + display_channel_surface_unref(display, surface_id); > + } > +} > + > +void display_channel_drawable_unref(DisplayChannel *display, Drawable > *drawable) > +{ > + RingItem *item, *next; > + > + if (--drawable->refs != 0) > + return; > + > + spice_warn_if_fail(!drawable->tree_item.shadow); > + spice_warn_if_fail(ring_is_empty(&drawable->pipes)); > + > + if (drawable->stream) { > + detach_stream(display, drawable->stream, TRUE); > + } > + region_destroy(&drawable->tree_item.base.rgn); > + > + drawable_remove_dependencies(display, drawable); > + drawable_unref_surface_deps(display, drawable); > + display_channel_surface_unref(display, drawable->surface_id); > + > + RING_FOREACH_SAFE(item, next, &drawable->glz_ring) { > + SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable = > NULL; > + ring_remove(item); > + } > + if (drawable->red_drawable) { > + red_drawable_unref(COMMON_CHANNEL(display)->worker, drawable > ->red_drawable, drawable->group_id); > + } > + drawable_free(display, drawable); > + display->drawable_count--; > +} > + > +static void drawable_deps_draw(DisplayChannel *display, Drawable *drawable) > +{ > + int x; > + int surface_id; > + > + for (x = 0; x < 3; ++x) { > + surface_id = drawable->surface_deps[x]; > + if (surface_id != -1 && drawable->depend_items[x].drawable) { > + depended_item_remove(&drawable->depend_items[x]); > + display_channel_draw(display, &drawable->red_drawable > ->surfaces_rects[x], surface_id); > + } > + } > +} > + > +void drawable_draw(DisplayChannel *display, Drawable *drawable) > +{ > + RedSurface *surface; > + SpiceCanvas *canvas; > + SpiceClip clip = drawable->red_drawable->clip; > + > + drawable_deps_draw(display, drawable); > + > + surface = &display->surfaces[drawable->surface_id]; > + canvas = surface->context.canvas; > + spice_return_if_fail(canvas); > + > + image_cache_aging(&display->image_cache); > + > + region_add(&surface->draw_dirty_region, &drawable->red_drawable->bbox); > + > + switch (drawable->red_drawable->type) { > + case QXL_DRAW_FILL: { > + SpiceFill fill = drawable->red_drawable->u.fill; > + SpiceImage img1, img2; > + image_cache_localize_brush(&display->image_cache, &fill.brush, > &img1); > + image_cache_localize_mask(&display->image_cache, &fill.mask, &img2); > + canvas->ops->draw_fill(canvas, &drawable->red_drawable->bbox, > + &clip, &fill); > + break; > + } > + case QXL_DRAW_OPAQUE: { > + SpiceOpaque opaque = drawable->red_drawable->u.opaque; > + SpiceImage img1, img2, img3; > + image_cache_localize_brush(&display->image_cache, &opaque.brush, > &img1); > + image_cache_localize(&display->image_cache, &opaque.src_bitmap, > &img2, drawable); > + image_cache_localize_mask(&display->image_cache, &opaque.mask, > &img3); > + canvas->ops->draw_opaque(canvas, &drawable->red_drawable->bbox, > &clip, &opaque); > + break; > + } > + case QXL_DRAW_COPY: { > + SpiceCopy copy = drawable->red_drawable->u.copy; > + SpiceImage img1, img2; > + image_cache_localize(&display->image_cache, ©.src_bitmap, &img1, > drawable); > + image_cache_localize_mask(&display->image_cache, ©.mask, &img2); > + canvas->ops->draw_copy(canvas, &drawable->red_drawable->bbox, > + &clip, ©); > + break; > + } > + case QXL_DRAW_TRANSPARENT: { > + SpiceTransparent transparent = drawable->red_drawable->u.transparent; > + SpiceImage img1; > + image_cache_localize(&display->image_cache, &transparent.src_bitmap, > &img1, drawable); > + canvas->ops->draw_transparent(canvas, > + &drawable->red_drawable->bbox, &clip, > &transparent); > + break; > + } > + case QXL_DRAW_ALPHA_BLEND: { > + SpiceAlphaBlend alpha_blend = drawable->red_drawable->u.alpha_blend; > + SpiceImage img1; > + image_cache_localize(&display->image_cache, &alpha_blend.src_bitmap, > &img1, drawable); > + canvas->ops->draw_alpha_blend(canvas, > + &drawable->red_drawable->bbox, &clip, > &alpha_blend); > + break; > + } > + case QXL_COPY_BITS: { > + canvas->ops->copy_bits(canvas, &drawable->red_drawable->bbox, > + &clip, &drawable->red_drawable > ->u.copy_bits.src_pos); > + break; > + } > + case QXL_DRAW_BLEND: { > + SpiceBlend blend = drawable->red_drawable->u.blend; > + SpiceImage img1, img2; > + image_cache_localize(&display->image_cache, &blend.src_bitmap, &img1, > drawable); > + image_cache_localize_mask(&display->image_cache, &blend.mask, &img2); > + canvas->ops->draw_blend(canvas, &drawable->red_drawable->bbox, > + &clip, &blend); > + break; > + } > + case QXL_DRAW_BLACKNESS: { > + SpiceBlackness blackness = drawable->red_drawable->u.blackness; > + SpiceImage img1; > + image_cache_localize_mask(&display->image_cache, &blackness.mask, > &img1); > + canvas->ops->draw_blackness(canvas, > + &drawable->red_drawable->bbox, &clip, > &blackness); > + break; > + } > + case QXL_DRAW_WHITENESS: { > + SpiceWhiteness whiteness = drawable->red_drawable->u.whiteness; > + SpiceImage img1; > + image_cache_localize_mask(&display->image_cache, &whiteness.mask, > &img1); > + canvas->ops->draw_whiteness(canvas, > + &drawable->red_drawable->bbox, &clip, > &whiteness); > + break; > + } > + case QXL_DRAW_INVERS: { > + SpiceInvers invers = drawable->red_drawable->u.invers; > + SpiceImage img1; > + image_cache_localize_mask(&display->image_cache, &invers.mask, > &img1); > + canvas->ops->draw_invers(canvas, > + &drawable->red_drawable->bbox, &clip, > &invers); > + break; > + } > + case QXL_DRAW_ROP3: { > + SpiceRop3 rop3 = drawable->red_drawable->u.rop3; > + SpiceImage img1, img2, img3; > + image_cache_localize_brush(&display->image_cache, &rop3.brush, > &img1); > + image_cache_localize(&display->image_cache, &rop3.src_bitmap, &img2, > drawable); > + image_cache_localize_mask(&display->image_cache, &rop3.mask, &img3); > + canvas->ops->draw_rop3(canvas, &drawable->red_drawable->bbox, > + &clip, &rop3); > + break; > + } > + case QXL_DRAW_COMPOSITE: { > + SpiceComposite composite = drawable->red_drawable->u.composite; > + SpiceImage src, mask; > + image_cache_localize(&display->image_cache, &composite.src_bitmap, > &src, drawable); > + if (composite.mask_bitmap) > + image_cache_localize(&display->image_cache, > &composite.mask_bitmap, &mask, drawable); > + canvas->ops->draw_composite(canvas, &drawable->red_drawable->bbox, > + &clip, &composite); > + break; > + } > + case QXL_DRAW_STROKE: { > + SpiceStroke stroke = drawable->red_drawable->u.stroke; > + SpiceImage img1; > + image_cache_localize_brush(&display->image_cache, &stroke.brush, > &img1); > + canvas->ops->draw_stroke(canvas, > + &drawable->red_drawable->bbox, &clip, > &stroke); > + break; > + } > + case QXL_DRAW_TEXT: { > + SpiceText text = drawable->red_drawable->u.text; > + SpiceImage img1, img2; > + image_cache_localize_brush(&display->image_cache, &text.fore_brush, > &img1); > + image_cache_localize_brush(&display->image_cache, &text.back_brush, > &img2); > + canvas->ops->draw_text(canvas, &drawable->red_drawable->bbox, > + &clip, &text); > + break; > + } > + default: > + spice_warning("invalid type"); > + } > +} > diff --git a/server/display-channel.h b/server/display-channel.h > index e624a6b..391e4ab 100644 > --- a/server/display-channel.h > +++ b/server/display-channel.h > @@ -251,6 +251,13 @@ typedef struct UpgradeItem { > } UpgradeItem; > > > +void display_channel_draw > (DisplayChannel *display, > + const > SpiceRect *area, > + int > surface_id); > +void display_channel_draw_till > (DisplayChannel *display, > + const > SpiceRect *area, > + int > surface_id, > + > Drawable *last); > void display_channel_free_some > (DisplayChannel *display); > void display_channel_set_stream_video > (DisplayChannel *display, > int > stream_video); > @@ -395,5 +402,6 @@ 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); > +void drawables_init(DisplayChannel *display); > > #endif /* DISPLAY_CHANNEL_H_ */ > diff --git a/server/red_worker.c b/server/red_worker.c > index 65d5dea..9ac7e29 100644 > --- a/server/red_worker.c > +++ b/server/red_worker.c > @@ -137,9 +137,6 @@ typedef struct BitmapData { > > static inline int validate_surface(DisplayChannel *display, uint32_t > surface_id); > > -static void display_channel_draw(DisplayChannel *display, const SpiceRect > *area, int surface_id); > -static void display_channel_draw_till(DisplayChannel *display, const > SpiceRect *area, int surface_id, > - Drawable *last); > static inline void display_begin_send_message(RedChannelClient *rcc); > static void red_create_surface(DisplayChannel *display, uint32_t surface_id, > uint32_t width, > uint32_t height, int32_t stride, uint32_t > format, > @@ -251,24 +248,6 @@ static void common_release_recv_buf(RedChannelClient > *rcc, uint16_t type, uint32 > } > } > > - > -static void drawable_free(DisplayChannel *display, Drawable *drawable) > -{ > - ((_Drawable *)drawable)->u.next = display->free_drawables; > - display->free_drawables = (_Drawable *)drawable; > -} > - > -static void drawables_init(DisplayChannel *display) > -{ > - int i; > - > - display->free_drawables = NULL; > - for (i = 0; i < NUM_DRAWABLES; i++) { > - drawable_free(display, &display->drawables[i].u.drawable); > - } > -} > - > - > static inline void set_surface_release_info(QXLReleaseInfoExt > *release_info_ext, > QXLReleaseInfo *release_info, > uint32_t group_id) > { > @@ -292,69 +271,6 @@ void red_drawable_unref(RedWorker *worker, RedDrawable > *red_drawable, > free(red_drawable); > } > > -static void remove_depended_item(DependItem *item) > -{ > - spice_assert(item->drawable); > - spice_assert(ring_item_is_linked(&item->ring_item)); > - item->drawable = NULL; > - ring_remove(&item->ring_item); > -} > - > -static void drawable_unref_surface_deps(DisplayChannel *display, Drawable > *drawable) > -{ > - int x; > - int surface_id; > - > - for (x = 0; x < 3; ++x) { > - surface_id = drawable->surface_deps[x]; > - if (surface_id == -1) { > - continue; > - } > - display_channel_surface_unref(display, surface_id); > - } > -} > - > -static void drawable_remove_dependencies(DisplayChannel *display, Drawable > *drawable) > -{ > - int x; > - int surface_id; > - > - for (x = 0; x < 3; ++x) { > - surface_id = drawable->surface_deps[x]; > - if (surface_id != -1 && drawable->depend_items[x].drawable) { > - remove_depended_item(&drawable->depend_items[x]); > - } > - } > -} > - > -void display_channel_drawable_unref(DisplayChannel *display, Drawable > *drawable) > -{ > - RingItem *item, *next; > - > - if (--drawable->refs != 0) > - return; > - > - spice_warn_if_fail(!drawable->tree_item.shadow); > - spice_warn_if_fail(ring_is_empty(&drawable->pipes)); > - > - if (drawable->stream) { > - detach_stream(display, drawable->stream, TRUE); > - } > - region_destroy(&drawable->tree_item.base.rgn); > - > - drawable_remove_dependencies(display, drawable); > - drawable_unref_surface_deps(display, drawable); > - display_channel_surface_unref(display, drawable->surface_id); > - > - RING_FOREACH_SAFE(item, next, &drawable->glz_ring) { > - SPICE_CONTAINEROF(item, RedGlzDrawable, drawable_link)->drawable = > NULL; > - ring_remove(item); > - } > - red_drawable_unref(COMMON_CHANNEL(display)->worker, drawable > ->red_drawable, drawable->group_id); > - drawable_free(display, drawable); > - display->drawable_count--; > -} > - > static void display_stream_trace_add_drawable(DisplayChannel *display, > Drawable *item) > { > ItemTrace *trace; > @@ -374,25 +290,6 @@ static void > display_stream_trace_add_drawable(DisplayChannel *display, Drawable > trace->dest_area = item->red_drawable->bbox; > } > > -static void surface_flush(DisplayChannel *display, int surface_id, SpiceRect > *rect) > -{ > - display_channel_draw(display, rect, surface_id); > -} > - > -static void red_flush_source_surfaces(DisplayChannel *display, Drawable > *drawable) > -{ > - int x; > - int surface_id; > - > - for (x = 0; x < 3; ++x) { > - surface_id = drawable->surface_deps[x]; > - if (surface_id != -1 && drawable->depend_items[x].drawable) { > - remove_depended_item(&drawable->depend_items[x]); > - surface_flush(display, surface_id, &drawable->red_drawable > ->surfaces_rects[x]); > - } > - } > -} > - > void current_remove_drawable(DisplayChannel *display, Drawable *item) > { > /* todo: move all to unref? */ > @@ -843,7 +740,7 @@ static inline int > red_handle_depends_on_target_surface(DisplayChannel *display, > Drawable *drawable; > DependItem *depended_item = SPICE_CONTAINEROF(ring_item, DependItem, > ring_item); > drawable = depended_item->drawable; > - surface_flush(display, drawable->surface_id, &drawable->red_drawable > ->bbox); > + display_channel_draw(display, &drawable->red_drawable->bbox, drawable > ->surface_id); > } > > return TRUE; > @@ -1039,146 +936,6 @@ static void image_surface_init(DisplayChannel *display) > display->image_surfaces.ops = &image_surfaces_ops; > } > > -void drawable_draw(DisplayChannel *display, Drawable *drawable) > -{ > - RedSurface *surface; > - SpiceCanvas *canvas; > - SpiceClip clip = drawable->red_drawable->clip; > - > - red_flush_source_surfaces(display, drawable); > - > - surface = &display->surfaces[drawable->surface_id]; > - canvas = surface->context.canvas; > - spice_return_if_fail(canvas); > - > - image_cache_aging(&display->image_cache); > - > - region_add(&surface->draw_dirty_region, &drawable->red_drawable->bbox); > - > - switch (drawable->red_drawable->type) { > - case QXL_DRAW_FILL: { > - SpiceFill fill = drawable->red_drawable->u.fill; > - SpiceImage img1, img2; > - image_cache_localize_brush(&display->image_cache, &fill.brush, > &img1); > - image_cache_localize_mask(&display->image_cache, &fill.mask, &img2); > - canvas->ops->draw_fill(canvas, &drawable->red_drawable->bbox, > - &clip, &fill); > - break; > - } > - case QXL_DRAW_OPAQUE: { > - SpiceOpaque opaque = drawable->red_drawable->u.opaque; > - SpiceImage img1, img2, img3; > - image_cache_localize_brush(&display->image_cache, &opaque.brush, > &img1); > - image_cache_localize(&display->image_cache, &opaque.src_bitmap, > &img2, drawable); > - image_cache_localize_mask(&display->image_cache, &opaque.mask, > &img3); > - canvas->ops->draw_opaque(canvas, &drawable->red_drawable->bbox, > &clip, &opaque); > - break; > - } > - case QXL_DRAW_COPY: { > - SpiceCopy copy = drawable->red_drawable->u.copy; > - SpiceImage img1, img2; > - image_cache_localize(&display->image_cache, ©.src_bitmap, &img1, > drawable); > - image_cache_localize_mask(&display->image_cache, ©.mask, &img2); > - canvas->ops->draw_copy(canvas, &drawable->red_drawable->bbox, > - &clip, ©); > - break; > - } > - case QXL_DRAW_TRANSPARENT: { > - SpiceTransparent transparent = drawable->red_drawable->u.transparent; > - SpiceImage img1; > - image_cache_localize(&display->image_cache, &transparent.src_bitmap, > &img1, drawable); > - canvas->ops->draw_transparent(canvas, > - &drawable->red_drawable->bbox, &clip, > &transparent); > - break; > - } > - case QXL_DRAW_ALPHA_BLEND: { > - SpiceAlphaBlend alpha_blend = drawable->red_drawable->u.alpha_blend; > - SpiceImage img1; > - image_cache_localize(&display->image_cache, &alpha_blend.src_bitmap, > &img1, drawable); > - canvas->ops->draw_alpha_blend(canvas, > - &drawable->red_drawable->bbox, &clip, > &alpha_blend); > - break; > - } > - case QXL_COPY_BITS: { > - canvas->ops->copy_bits(canvas, &drawable->red_drawable->bbox, > - &clip, &drawable->red_drawable > ->u.copy_bits.src_pos); > - break; > - } > - case QXL_DRAW_BLEND: { > - SpiceBlend blend = drawable->red_drawable->u.blend; > - SpiceImage img1, img2; > - image_cache_localize(&display->image_cache, &blend.src_bitmap, &img1, > drawable); > - image_cache_localize_mask(&display->image_cache, &blend.mask, &img2); > - canvas->ops->draw_blend(canvas, &drawable->red_drawable->bbox, > - &clip, &blend); > - break; > - } > - case QXL_DRAW_BLACKNESS: { > - SpiceBlackness blackness = drawable->red_drawable->u.blackness; > - SpiceImage img1; > - image_cache_localize_mask(&display->image_cache, &blackness.mask, > &img1); > - canvas->ops->draw_blackness(canvas, > - &drawable->red_drawable->bbox, &clip, > &blackness); > - break; > - } > - case QXL_DRAW_WHITENESS: { > - SpiceWhiteness whiteness = drawable->red_drawable->u.whiteness; > - SpiceImage img1; > - image_cache_localize_mask(&display->image_cache, &whiteness.mask, > &img1); > - canvas->ops->draw_whiteness(canvas, > - &drawable->red_drawable->bbox, &clip, > &whiteness); > - break; > - } > - case QXL_DRAW_INVERS: { > - SpiceInvers invers = drawable->red_drawable->u.invers; > - SpiceImage img1; > - image_cache_localize_mask(&display->image_cache, &invers.mask, > &img1); > - canvas->ops->draw_invers(canvas, > - &drawable->red_drawable->bbox, &clip, > &invers); > - break; > - } > - case QXL_DRAW_ROP3: { > - SpiceRop3 rop3 = drawable->red_drawable->u.rop3; > - SpiceImage img1, img2, img3; > - image_cache_localize_brush(&display->image_cache, &rop3.brush, > &img1); > - image_cache_localize(&display->image_cache, &rop3.src_bitmap, &img2, > drawable); > - image_cache_localize_mask(&display->image_cache, &rop3.mask, &img3); > - canvas->ops->draw_rop3(canvas, &drawable->red_drawable->bbox, > - &clip, &rop3); > - break; > - } > - case QXL_DRAW_COMPOSITE: { > - SpiceComposite composite = drawable->red_drawable->u.composite; > - SpiceImage src, mask; > - image_cache_localize(&display->image_cache, &composite.src_bitmap, > &src, drawable); > - if (composite.mask_bitmap) > - image_cache_localize(&display->image_cache, > &composite.mask_bitmap, &mask, drawable); > - canvas->ops->draw_composite(canvas, &drawable->red_drawable->bbox, > - &clip, &composite); > - break; > - } > - case QXL_DRAW_STROKE: { > - SpiceStroke stroke = drawable->red_drawable->u.stroke; > - SpiceImage img1; > - image_cache_localize_brush(&display->image_cache, &stroke.brush, > &img1); > - canvas->ops->draw_stroke(canvas, > - &drawable->red_drawable->bbox, &clip, > &stroke); > - break; > - } > - case QXL_DRAW_TEXT: { > - SpiceText text = drawable->red_drawable->u.text; > - SpiceImage img1, img2; > - image_cache_localize_brush(&display->image_cache, &text.fore_brush, > &img1); > - image_cache_localize_brush(&display->image_cache, &text.back_brush, > &img2); > - canvas->ops->draw_text(canvas, &drawable->red_drawable->bbox, > - &clip, &text); > - break; > - } > - default: > - spice_warning("invalid type"); > - } > -} > - > static void validate_area(DisplayChannel *display, const SpiceRect *area, > uint32_t surface_id) > { > RedSurface *surface; > @@ -1205,8 +962,8 @@ static void validate_area(DisplayChannel *display, const > SpiceRect *area, uint32 > Renders drawables for updating the requested area, but only drawables > that are older > than 'last' (exclusive). > */ > -static void display_channel_draw_till(DisplayChannel *display, const > SpiceRect *area, int surface_id, > - Drawable *last) > +void display_channel_draw_till(DisplayChannel *display, const SpiceRect > *area, int surface_id, > + Drawable *last) > { > RedSurface *surface; > Drawable *surface_last = NULL; > @@ -1283,7 +1040,7 @@ static void display_channel_draw_till(DisplayChannel > *display, const SpiceRect * > validate_area(display, area, surface_id); > } > > -static void display_channel_draw(DisplayChannel *display, const SpiceRect > *area, int surface_id) > +void display_channel_draw(DisplayChannel *display, const SpiceRect *area, int > surface_id) > { > RedSurface *surface; > Ring *ring; Acked-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel