From 70598b9113a9356674a842ca3786c6ee02de1cb9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 19 Jul 2011 00:07:10 +0200 Subject: Clean up some commented-out code (bzr r10347.1.16) --- src/display/canvas-arena.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index dd4a4ed5c..4c105cd09 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -199,12 +199,8 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) { + // todo: handle NR_ARENA_ITEM_RENDER_NO_CACHE SPCanvasArena *arena = SP_CANVAS_ARENA (item); - //SPCanvas *canvas = item->canvas; - - //nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, - // NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER, - // NR_ARENA_ITEM_STATE_NONE); Geom::OptIntRect r = buf->rect; if (!r || r->hasZeroArea()) return; @@ -221,11 +217,8 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) cairo_save(buf->ct); cairo_translate(buf->ct, -r->left(), -r->top()); - //cairo_rectangle(buf->ct, r->left(), r->top(), r->width(), r->height()); - //cairo_clip(buf->ct); cairo_set_source_surface(buf->ct, arena->cache, arena->cache_area.left(), arena->cache_area.top()); cairo_paint(buf->ct); - //nr_arena_item_invoke_render (buf->ct, arena->root, &area, NULL, 0); cairo_restore(buf->ct); } -- cgit v1.2.3 From 328fad57dbfb65e3bd31062021d5cc3081e68515 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 22 Jul 2011 04:09:27 +0200 Subject: Replace direct use of Cairo contexts and surfaces in the rendering tree with wrappers which keep some extra information about the surface, amd NRRect and NRRectL use with Geom::Rect and Geom::IntRect. Should simplify implementing filter primitive subregions. (bzr r10347.1.17) --- src/display/canvas-arena.cpp | 61 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 30 deletions(-) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 4c105cd09..1d5cfe826 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -19,6 +19,8 @@ #include "display/nr-arena-group.h" #include "display/canvas-arena.h" #include "display/cairo-utils.h" +#include "display/drawing-context.h" +#include "display/drawing-surface.h" enum { ARENA_EVENT, @@ -161,12 +163,15 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned guint reset; reset = (flags & SP_CANVAS_UPDATE_AFFINE)? NR_ARENA_ITEM_STATE_ALL : NR_ARENA_ITEM_STATE_NONE; - nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset); + nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset); - item->x1 = arena->root->bbox.x0 - 1; - item->y1 = arena->root->bbox.y0 - 1; - item->x2 = arena->root->bbox.x1 + 1; - item->y2 = arena->root->bbox.y1 + 1; + Geom::OptIntRect b = arena->root->bbox; + if (b) { + item->x1 = b->left() - 1; + item->y1 = b->top() - 1; + item->x2 = b->right() + 1; + item->y2 = b->bottom() + 1; + } if (arena->cursor) { /* Mess with enter/leave notifiers */ @@ -228,27 +233,23 @@ static void sp_canvas_arena_render_cache (SPCanvasItem *item, Geom::IntRect cons Geom::OptIntRect r = Geom::intersect(arena->cache_area, area); if (!r || r->hasZeroArea()) return; // nothing to do - - cairo_t *ct = cairo_create(arena->cache); - cairo_translate(ct, -arena->cache_area.left(), -arena->cache_area.top()); - - // clear area to paint - cairo_rectangle(ct, area.left(), area.top(), area.width(), area.height()); - cairo_clip(ct); - cairo_save(ct); - cairo_set_source_rgba(ct, 0,0,0,0); - cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); - cairo_paint(ct); - cairo_restore(ct); - - NRRectL nr_area(r); - nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, + Inkscape::DrawingSurface cache(arena->cache, arena->cache_area.min()); + Inkscape::DrawingContext ct(cache); + + ct.rectangle(area); + ct.clip(); + + { Inkscape::DrawingContext::Save save(ct); + ct.setSource(0,0,0,0); + ct.setOperator(CAIRO_OPERATOR_SOURCE); + ct.paint(); + } + + nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER, NR_ARENA_ITEM_STATE_NONE); - nr_arena_item_invoke_render (ct, arena->root, &nr_area, NULL, 0); - - cairo_destroy(ct); + nr_arena_item_invoke_render (ct, arena->root, *r, 0); } static void @@ -267,7 +268,7 @@ sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_ { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, + nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); @@ -367,7 +368,7 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->crossing.x, event->crossing.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); + nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); arena->active = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); if (arena->active) nr_object_ref ((NRObject *) arena->active); ret = sp_canvas_arena_send_event (arena, event); @@ -388,7 +389,7 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->motion.x, event->motion.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); + nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); if (new_arena != arena->active) { GdkEventCrossing ec; @@ -474,10 +475,10 @@ sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, NRR g_return_if_fail (ca != NULL); g_return_if_fail (SP_IS_CANVAS_ARENA (ca)); - cairo_t *ct = cairo_create(surface); - cairo_translate(ct, -r.x0, -r.y0); - nr_arena_item_invoke_render (ct, ca->root, &r, NULL, 0); - cairo_destroy(ct); + Geom::OptIntRect area = r.upgrade_2geom(); + if (!area) return; + Inkscape::DrawingContext ct(surface, area->min()); + nr_arena_item_invoke_render (ct, ca->root, *area, 0); } -- cgit v1.2.3 From 905b8a96963f78358abfd109c0c49758c6fe4e9d Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 28 Jul 2011 07:04:08 +0200 Subject: Per-item render cache. Cache some offscreen data to facilitate smoother navigation. (bzr r10347.1.20) --- src/display/canvas-arena.cpp | 125 ++++--------------------------------------- 1 file changed, 10 insertions(+), 115 deletions(-) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 1d5cfe826..0f653a258 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -33,10 +33,8 @@ static void sp_canvas_arena_destroy(GtkObject *object); static void sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf); -static void sp_canvas_arena_render_cache (SPCanvasItem *item, Geom::IntRect const &area); -static void sp_canvas_arena_dirty_cache (SPCanvasArena *arena, NRRectL *area); static double sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static void sp_canvas_arena_visible_area_changed (SPCanvasItem *item, Geom::IntRect const &old_area, Geom::IntRect const &new_area); +static void sp_canvas_arena_viewbox_changed (SPCanvasItem *item, Geom::IntRect const &new_area); static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event); static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event); @@ -98,7 +96,7 @@ sp_canvas_arena_class_init (SPCanvasArenaClass *klass) item_class->render = sp_canvas_arena_render; item_class->point = sp_canvas_arena_point; item_class->event = sp_canvas_arena_event; - item_class->visible_area_changed = sp_canvas_arena_visible_area_changed; + item_class->viewbox_changed = sp_canvas_arena_viewbox_changed; } static void @@ -110,11 +108,9 @@ sp_canvas_arena_init (SPCanvasArena *arena) arena->arena->canvasarena = arena; arena->root = NRArenaGroup::create(arena->arena); nr_arena_group_set_transparent (NR_ARENA_GROUP (arena->root), TRUE); + nr_arena_item_set_cache(arena->root, true); arena->active = NULL; - arena->cache = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - arena->cache_area = Geom::IntRect::from_xywh(0,0,1,1); - arena->dirty = cairo_region_create(); nr_active_object_add_listener ((NRActiveObject *) arena->arena, (NRObjectEventVector *) &carenaev, sizeof (carenaev), arena); } @@ -140,11 +136,6 @@ sp_canvas_arena_destroy (GtkObject *object) nr_object_unref ((NRObject *) arena->arena); arena->arena = NULL; } - if (arena->cache) { - cairo_surface_destroy(arena->cache); - arena->cache = NULL; - } - cairo_region_destroy(arena->dirty); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -209,42 +200,8 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) Geom::OptIntRect r = buf->rect; if (!r || r->hasZeroArea()) return; - - cairo_rectangle_int_t crect; - crect.x = r->left(); - crect.y = r->top(); - crect.width = r->width(); - crect.height = r->height(); - if (cairo_region_contains_rectangle(arena->dirty, &crect) != CAIRO_REGION_OVERLAP_OUT) { - sp_canvas_arena_render_cache(item, *r); - cairo_region_subtract_rectangle(arena->dirty, &crect); - } - - cairo_save(buf->ct); - cairo_translate(buf->ct, -r->left(), -r->top()); - cairo_set_source_surface(buf->ct, arena->cache, arena->cache_area.left(), arena->cache_area.top()); - cairo_paint(buf->ct); - cairo_restore(buf->ct); -} - -static void sp_canvas_arena_render_cache (SPCanvasItem *item, Geom::IntRect const &area) -{ - SPCanvasArena *arena = SP_CANVAS_ARENA (item); - - Geom::OptIntRect r = Geom::intersect(arena->cache_area, area); - if (!r || r->hasZeroArea()) return; // nothing to do - - Inkscape::DrawingSurface cache(arena->cache, arena->cache_area.min()); - Inkscape::DrawingContext ct(cache); - ct.rectangle(area); - ct.clip(); - - { Inkscape::DrawingContext::Save save(ct); - ct.setSource(0,0,0,0); - ct.setOperator(CAIRO_OPERATOR_SOURCE); - ct.paint(); - } + Inkscape::DrawingContext ct(buf->ct, r->min()); nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER, @@ -252,17 +209,6 @@ static void sp_canvas_arena_render_cache (SPCanvasItem *item, Geom::IntRect cons nr_arena_item_invoke_render (ct, arena->root, *r, 0); } -static void -sp_canvas_arena_dirty_cache (SPCanvasArena *arena, NRRectL *area) -{ - cairo_rectangle_int_t rect; - rect.x = area->x0; - rect.y = area->y0; - rect.width = area->x1 - area->x0; - rect.height = area->y1 - area->y0; - cairo_region_union_rectangle(arena->dirty, &rect); -} - static double sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item) { @@ -285,64 +231,14 @@ sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_ } static void -sp_canvas_arena_visible_area_changed (SPCanvasItem *item, Geom::IntRect const &old_area, Geom::IntRect const &new_area) +sp_canvas_arena_viewbox_changed (SPCanvasItem *item, Geom::IntRect const &new_area) { SPCanvasArena *arena = SP_CANVAS_ARENA(item); - - cairo_surface_t *new_cache = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - new_area.width(), new_area.height()); - cairo_t *ct = cairo_create(new_cache); - cairo_set_source_surface(ct, arena->cache, old_area.left() - new_area.left(), old_area.top() - new_area.top()); - cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); - cairo_paint(ct); - cairo_destroy(ct); - cairo_surface_destroy(arena->cache); - arena->cache = new_cache; - arena->cache_area = new_area; - - cairo_rectangle_int_t crect; - crect.x = new_area.left(); - crect.y = new_area.top(); - crect.width = new_area.width(); - crect.height = new_area.height(); - cairo_region_intersect_rectangle(arena->dirty, &crect); - - // invalidate newly exposed areas - /* - * +----------------------+ - * | top strip | - * +-------+------+-------+ - * | | | | - * | left | old | right | - * | strip | area | strip | - * | | | | - * +-------+------+-------+ - * | bottom strip | - * +----------------------+ - */ - - // top strip - if (new_area.top() < old_area.top()) { - NRRectL top_strip(new_area.left(), new_area.top(), new_area.right(), old_area.top()); - sp_canvas_arena_dirty_cache(arena, &top_strip); - } - // left strip - if (new_area.left() < old_area.left()) { - NRRectL left_strip(new_area.left(), std::max(new_area.top(), old_area.top()), - old_area.left(), std::min(new_area.bottom(), old_area.bottom())); - sp_canvas_arena_dirty_cache(arena, &left_strip); - } - // right strip - if (new_area.right() > old_area.right()) { - NRRectL right_strip(old_area.right(), std::max(new_area.top(), old_area.top()), - new_area.right(), std::min(new_area.bottom(), old_area.bottom())); - sp_canvas_arena_dirty_cache(arena, &right_strip); - } - // bottom strip - if (new_area.bottom() > old_area.bottom()) { - NRRectL bottom_strip(new_area.left(), old_area.bottom(), new_area.right(), new_area.bottom()); - sp_canvas_arena_dirty_cache(arena, &bottom_strip); - } + // make the cache limit larger than screen to facilitate smooth scrolling + Geom::IntRect expanded = new_area; + Geom::IntPoint expansion(new_area.width()/2, new_area.height()/2); + expanded.expandBy(expansion); + nr_arena_set_cache_limit(arena->arena, expanded); } static gint @@ -445,7 +341,6 @@ static void sp_canvas_arena_request_render (NRArena */*arena*/, NRRectL *area, void *data) { if (!area) return; - sp_canvas_arena_dirty_cache (SP_CANVAS_ARENA(data), area); sp_canvas_request_redraw (SP_CANVAS_ITEM (data)->canvas, area->x0, area->y0, area->x1, area->y1); } -- cgit v1.2.3 From 4dd33aa4d5c57706c7f64f63391174954160a308 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 6 Aug 2011 14:18:32 +0200 Subject: Rewrite NRArenaItem hierarchy into C++ (bzr r10347.1.21) --- src/display/canvas-arena.cpp | 95 ++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 51 deletions(-) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 0f653a258..81416fefb 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -16,12 +16,15 @@ #include "display/sp-canvas-util.h" #include "helper/sp-marshal.h" #include "display/nr-arena.h" -#include "display/nr-arena-group.h" #include "display/canvas-arena.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" +#include "display/drawing-item.h" +#include "display/drawing-group.h" #include "display/drawing-surface.h" +using namespace Inkscape; + enum { ARENA_EVENT, LAST_SIGNAL @@ -31,6 +34,7 @@ static void sp_canvas_arena_class_init(SPCanvasArenaClass *klass); static void sp_canvas_arena_init(SPCanvasArena *group); static void sp_canvas_arena_destroy(GtkObject *object); +static void sp_canvas_arena_item_deleted(SPCanvasArena *arena, Inkscape::DrawingItem *item); static void sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf); static double sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); @@ -39,7 +43,7 @@ static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event); static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event); -static void sp_canvas_arena_request_update (NRArena *arena, NRArenaItem *item, void *data); +static void sp_canvas_arena_request_update (NRArena *arena, DrawingItem *item, void *data); static void sp_canvas_arena_request_render (NRArena *arena, NRRectL *area, void *data); NRArenaEventVector carenaev = { @@ -105,10 +109,16 @@ sp_canvas_arena_init (SPCanvasArena *arena) arena->sticky = FALSE; arena->arena = NRArena::create(); + nr_object_ref(arena->arena); arena->arena->canvasarena = arena; - arena->root = NRArenaGroup::create(arena->arena); - nr_arena_group_set_transparent (NR_ARENA_GROUP (arena->root), TRUE); - nr_arena_item_set_cache(arena->root, true); + arena->arena->item_deleted.connect( + sigc::bind<0>( + sigc::ptr_fun(&sp_canvas_arena_item_deleted), + arena)); + + arena->root = new DrawingGroup(arena->arena); + arena->root->setPickChildren(true); + arena->root->setCached(true); arena->active = NULL; @@ -120,22 +130,11 @@ sp_canvas_arena_destroy (GtkObject *object) { SPCanvasArena *arena = SP_CANVAS_ARENA (object); - if (arena->active) { - nr_object_unref ((NRObject *) arena->active); - arena->active = NULL; - } - - if (arena->root) { - nr_arena_item_unref (arena->root); - arena->root = NULL; - } - - if (arena->arena) { - nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena); + delete arena->root; - nr_object_unref ((NRObject *) arena->arena); - arena->arena = NULL; - } + nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena); + nr_object_unref ((NRObject *) arena->arena); + arena->arena = NULL; if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -149,14 +148,12 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned if (((SPCanvasItemClass *) parent_class)->update) (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags); - arena->gc.transform = affine; + arena->ctx.ctm = affine; - guint reset; - reset = (flags & SP_CANVAS_UPDATE_AFFINE)? NR_ARENA_ITEM_STATE_ALL : NR_ARENA_ITEM_STATE_NONE; + unsigned reset = flags & SP_CANVAS_UPDATE_AFFINE ? DrawingItem::STATE_ALL : 0; + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_ALL, reset); - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset); - - Geom::OptIntRect b = arena->root->bbox; + Geom::OptIntRect b = arena->root->visualBounds(); if (b) { item->x1 = b->left() - 1; item->y1 = b->top() - 1; @@ -166,7 +163,7 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned if (arena->cursor) { /* Mess with enter/leave notifiers */ - NRArenaItem *new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); + DrawingItem *new_arena = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); if (new_arena != arena->active) { GdkEventCrossing ec; ec.window = GTK_WIDGET (item->canvas)->window; @@ -180,10 +177,7 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned ec.type = GDK_LEAVE_NOTIFY; sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); } - /* fixme: This is not optimal - better track ::destroy (Lauris) */ - if (arena->active) nr_object_unref ((NRObject *) arena->active); arena->active = new_arena; - if (arena->active) nr_object_ref ((NRObject *) arena->active); if (arena->active) { ec.type = GDK_ENTER_NOTIFY; sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); @@ -192,6 +186,14 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned } } +static void +sp_canvas_arena_item_deleted(SPCanvasArena *arena, Inkscape::DrawingItem *item) +{ + if (arena->active == item) { + arena->active = NULL; + } +} + static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) { @@ -203,10 +205,8 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) Inkscape::DrawingContext ct(buf->ct, r->min()); - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, - NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER, - NR_ARENA_ITEM_STATE_NONE); - nr_arena_item_invoke_render (ct, arena->root, *r, 0); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_ALL, 0); + arena->root->render(ct, *r, 0); } static double @@ -214,11 +214,8 @@ sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_ { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, - NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_PICK, - NR_ARENA_ITEM_STATE_NONE); - - NRArenaItem *picked = nr_arena_item_invoke_pick (arena->root, p, arena->arena->delta, arena->sticky); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); + DrawingItem *picked = arena->root->pick(p, arena->arena->delta, arena->sticky); arena->picked = picked; @@ -244,7 +241,7 @@ sp_canvas_arena_viewbox_changed (SPCanvasItem *item, Geom::IntRect const &new_ar static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) { - NRArenaItem *new_arena; + Inkscape::DrawingItem *new_arena; /* fixme: This sucks, we have to handle enter/leave notifiers */ SPCanvasArena *arena = SP_CANVAS_ARENA (item); @@ -256,7 +253,6 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) if (!arena->cursor) { if (arena->active) { //g_warning ("Cursor entered to arena with already active item"); - nr_object_unref ((NRObject *) arena->active); } arena->cursor = TRUE; @@ -264,9 +260,8 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->crossing.x, event->crossing.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); - arena->active = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); - if (arena->active) nr_object_ref ((NRObject *) arena->active); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); + arena->active = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); ret = sp_canvas_arena_send_event (arena, event); } break; @@ -274,7 +269,6 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) case GDK_LEAVE_NOTIFY: if (arena->cursor) { ret = sp_canvas_arena_send_event (arena, event); - if (arena->active) nr_object_unref ((NRObject *) arena->active); arena->active = NULL; arena->cursor = FALSE; } @@ -285,8 +279,8 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->motion.x, event->motion.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - nr_arena_item_invoke_update (arena->root, Geom::IntRect::infinite(), &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); - new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); + arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); + new_arena = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); if (new_arena != arena->active) { GdkEventCrossing ec; ec.window = event->motion.window; @@ -300,9 +294,7 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) ec.type = GDK_LEAVE_NOTIFY; ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); } - if (arena->active) nr_object_unref ((NRObject *) arena->active); arena->active = new_arena; - if (arena->active) nr_object_ref ((NRObject *) arena->active); if (arena->active) { ec.type = GDK_ENTER_NOTIFY; ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); @@ -332,7 +324,7 @@ sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event) } static void -sp_canvas_arena_request_update (NRArena */*arena*/, NRArenaItem */*item*/, void *data) +sp_canvas_arena_request_update (NRArena */*arena*/, DrawingItem */*item*/, void *data) { sp_canvas_item_request_update (SP_CANVAS_ITEM (data)); } @@ -373,7 +365,8 @@ sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, NRR Geom::OptIntRect area = r.upgrade_2geom(); if (!area) return; Inkscape::DrawingContext ct(surface, area->min()); - nr_arena_item_invoke_render (ct, ca->root, *area, 0); + ca->root->update(Geom::IntRect::infinite(), ca->ctx, DrawingItem::STATE_ALL, 0); + ca->root->render(ct, *area, 0); } -- cgit v1.2.3 From 75976ea07dba9b97186667524d0a76603de416af Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 7 Aug 2011 12:53:12 +0200 Subject: Rewrite NRArena -> Inkscape::Drawing. Call render and update methods on the Drawing rather than on the root DrawingItem. (bzr r10347.1.25) --- src/display/canvas-arena.cpp | 82 ++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 44 deletions(-) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 81416fefb..6026ebd3f 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -15,7 +15,6 @@ #include "display/display-forward.h" #include "display/sp-canvas-util.h" #include "helper/sp-marshal.h" -#include "display/nr-arena.h" #include "display/canvas-arena.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" @@ -43,14 +42,8 @@ static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event); static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event); -static void sp_canvas_arena_request_update (NRArena *arena, DrawingItem *item, void *data); -static void sp_canvas_arena_request_render (NRArena *arena, NRRectL *area, void *data); - -NRArenaEventVector carenaev = { - {NULL}, - sp_canvas_arena_request_update, - sp_canvas_arena_request_render -}; +static void sp_canvas_arena_request_update (SPCanvasArena *ca, DrawingItem *item); +static void sp_canvas_arena_request_render (SPCanvasArena *ca, Geom::IntRect const &area); static SPCanvasItemClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; @@ -108,21 +101,27 @@ sp_canvas_arena_init (SPCanvasArena *arena) { arena->sticky = FALSE; - arena->arena = NRArena::create(); - nr_object_ref(arena->arena); - arena->arena->canvasarena = arena; - arena->arena->item_deleted.connect( + new (&arena->drawing) Inkscape::Drawing(arena); + + Inkscape::DrawingGroup *root = new DrawingGroup(arena->drawing); + root->setPickChildren(true); + root->setCached(true); + arena->drawing.setRoot(root); + + arena->drawing.signal_request_update.connect( + sigc::bind<0>( + sigc::ptr_fun(&sp_canvas_arena_request_update), + arena)); + arena->drawing.signal_request_render.connect( + sigc::bind<0>( + sigc::ptr_fun(&sp_canvas_arena_request_render), + arena)); + arena->drawing.signal_item_deleted.connect( sigc::bind<0>( sigc::ptr_fun(&sp_canvas_arena_item_deleted), arena)); - arena->root = new DrawingGroup(arena->arena); - arena->root->setPickChildren(true); - arena->root->setCached(true); - arena->active = NULL; - - nr_active_object_add_listener ((NRActiveObject *) arena->arena, (NRObjectEventVector *) &carenaev, sizeof (carenaev), arena); } static void @@ -130,11 +129,7 @@ sp_canvas_arena_destroy (GtkObject *object) { SPCanvasArena *arena = SP_CANVAS_ARENA (object); - delete arena->root; - - nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena); - nr_object_unref ((NRObject *) arena->arena); - arena->arena = NULL; + arena->drawing.~Drawing(); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -151,9 +146,9 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned arena->ctx.ctm = affine; unsigned reset = flags & SP_CANVAS_UPDATE_AFFINE ? DrawingItem::STATE_ALL : 0; - arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_ALL, reset); + arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_ALL, reset); - Geom::OptIntRect b = arena->root->visualBounds(); + Geom::OptIntRect b = arena->drawing.root()->visualBounds(); if (b) { item->x1 = b->left() - 1; item->y1 = b->top() - 1; @@ -163,7 +158,7 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned if (arena->cursor) { /* Mess with enter/leave notifiers */ - DrawingItem *new_arena = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); + DrawingItem *new_arena = arena->drawing.pick(arena->c, arena->drawing.delta, arena->sticky); if (new_arena != arena->active) { GdkEventCrossing ec; ec.window = GTK_WIDGET (item->canvas)->window; @@ -205,8 +200,8 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) Inkscape::DrawingContext ct(buf->ct, r->min()); - arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_ALL, 0); - arena->root->render(ct, *r, 0); + arena->drawing.update(Geom::IntRect::infinite(), arena->ctx); + arena->drawing.render(ct, *r); } static double @@ -214,8 +209,8 @@ sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_ { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); - DrawingItem *picked = arena->root->pick(p, arena->arena->delta, arena->sticky); + arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK); + DrawingItem *picked = arena->drawing.pick(p, arena->drawing.delta, arena->sticky); arena->picked = picked; @@ -235,7 +230,7 @@ sp_canvas_arena_viewbox_changed (SPCanvasItem *item, Geom::IntRect const &new_ar Geom::IntRect expanded = new_area; Geom::IntPoint expansion(new_area.width()/2, new_area.height()/2); expanded.expandBy(expansion); - nr_arena_set_cache_limit(arena->arena, expanded); + arena->drawing.setCacheLimit(expanded); } static gint @@ -260,8 +255,8 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->crossing.x, event->crossing.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); - arena->active = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); + arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); + arena->active = arena->drawing.pick(arena->c, arena->drawing.delta, arena->sticky); ret = sp_canvas_arena_send_event (arena, event); } break; @@ -279,8 +274,8 @@ sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) arena->c = Geom::Point(event->motion.x, event->motion.y); /* fixme: Not sure abut this, but seems the right thing (Lauris) */ - arena->root->update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK, 0); - new_arena = arena->root->pick(arena->c, arena->arena->delta, arena->sticky); + arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK); + new_arena = arena->drawing.pick(arena->c, arena->drawing.delta, arena->sticky); if (new_arena != arena->active) { GdkEventCrossing ec; ec.window = event->motion.window; @@ -324,16 +319,16 @@ sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event) } static void -sp_canvas_arena_request_update (NRArena */*arena*/, DrawingItem */*item*/, void *data) +sp_canvas_arena_request_update (SPCanvasArena *ca, DrawingItem */*item*/) { - sp_canvas_item_request_update (SP_CANVAS_ITEM (data)); + sp_canvas_item_request_update (SP_CANVAS_ITEM (ca)); } static void -sp_canvas_arena_request_render (NRArena */*arena*/, NRRectL *area, void *data) +sp_canvas_arena_request_render (SPCanvasArena *ca, Geom::IntRect const &area) { - if (!area) return; - sp_canvas_request_redraw (SP_CANVAS_ITEM (data)->canvas, area->x0, area->y0, area->x1, area->y1); + SPCanvas *canvas = SP_CANVAS_ITEM (ca)->canvas; + sp_canvas_request_redraw (canvas, area.left(), area.top(), area.right(), area.bottom()); } void @@ -365,11 +360,10 @@ sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, NRR Geom::OptIntRect area = r.upgrade_2geom(); if (!area) return; Inkscape::DrawingContext ct(surface, area->min()); - ca->root->update(Geom::IntRect::infinite(), ca->ctx, DrawingItem::STATE_ALL, 0); - ca->root->render(ct, *area, 0); + ca->drawing.update(Geom::IntRect::infinite(), ca->ctx); + ca->drawing.render(ct, *area); } - /* Local Variables: mode:c++ -- cgit v1.2.3 From f336c94939e9740501835b2584ad9a3160ac6d51 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 9 Aug 2011 03:14:07 +0200 Subject: Initial autocache work (bzr r10347.1.26) --- src/display/canvas-arena.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 6026ebd3f..b254a55c8 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -105,7 +105,7 @@ sp_canvas_arena_init (SPCanvasArena *arena) Inkscape::DrawingGroup *root = new DrawingGroup(arena->drawing); root->setPickChildren(true); - root->setCached(true); + root->setCached(true, true); arena->drawing.setRoot(root); arena->drawing.signal_request_update.connect( -- cgit v1.2.3 From dc713ea50efc5fd3f041db05ff92d31a3a54dc5b Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 16 Aug 2011 06:04:53 +0200 Subject: Add user preference for rendering cache size (bzr r10347.1.34) --- src/display/canvas-arena.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index b254a55c8..ac2704895 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -21,6 +21,7 @@ #include "display/drawing-item.h" #include "display/drawing-group.h" #include "display/drawing-surface.h" +#include "preferences.h" using namespace Inkscape; @@ -48,6 +49,22 @@ static void sp_canvas_arena_request_render (SPCanvasArena *ca, Geom::IntRect con static SPCanvasItemClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; +struct CacheBudgetObserver : public Inkscape::Preferences::Observer { + CacheBudgetObserver(SPCanvasArena *arena) + : Inkscape::Preferences::Observer("/options/renderingcache/size") + , _arena(arena) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Inkscape::Preferences::Entry v = prefs->getEntry(observed_path); + notify(v); + prefs->addObserver(*this); + } + void notify(Preferences::Entry const &v) { + _arena->drawing.setCacheBudget((1 << 20) * v.getIntLimited(128, 0, 4096)); + } + SPCanvasArena *_arena; +}; + GType sp_canvas_arena_get_type (void) { @@ -102,6 +119,7 @@ sp_canvas_arena_init (SPCanvasArena *arena) arena->sticky = FALSE; new (&arena->drawing) Inkscape::Drawing(arena); + arena->observer = new CacheBudgetObserver(arena); Inkscape::DrawingGroup *root = new DrawingGroup(arena->drawing); root->setPickChildren(true); @@ -129,6 +147,7 @@ sp_canvas_arena_destroy (GtkObject *object) { SPCanvasArena *arena = SP_CANVAS_ARENA (object); + delete arena->observer; arena->drawing.~Drawing(); if (GTK_OBJECT_CLASS (parent_class)->destroy) -- cgit v1.2.3 From 969504cc521a5116e1b1b8ea9e0355f69e6c93eb Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Thu, 25 Aug 2011 20:33:10 +0200 Subject: Reduce default rendering cache size to 64 MiB (bzr r10347.1.39) --- src/display/canvas-arena.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'src/display/canvas-arena.cpp') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index ac2704895..4688a58e3 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -49,18 +49,23 @@ static void sp_canvas_arena_request_render (SPCanvasArena *ca, Geom::IntRect con static SPCanvasItemClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; -struct CacheBudgetObserver : public Inkscape::Preferences::Observer { - CacheBudgetObserver(SPCanvasArena *arena) - : Inkscape::Preferences::Observer("/options/renderingcache/size") +struct CachePrefObserver : public Inkscape::Preferences::Observer { + CachePrefObserver(SPCanvasArena *arena) + : Inkscape::Preferences::Observer("/options/renderingcache") , _arena(arena) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::Preferences::Entry v = prefs->getEntry(observed_path); - notify(v); + std::vector v = prefs->getAllEntries(observed_path); + for (unsigned i=0; iaddObserver(*this); } void notify(Preferences::Entry const &v) { - _arena->drawing.setCacheBudget((1 << 20) * v.getIntLimited(128, 0, 4096)); + Glib::ustring name = v.getEntryName(); + if (name == "size") { + _arena->drawing.setCacheBudget((1 << 20) * v.getIntLimited(64, 0, 4096)); + } } SPCanvasArena *_arena; }; @@ -119,13 +124,13 @@ sp_canvas_arena_init (SPCanvasArena *arena) arena->sticky = FALSE; new (&arena->drawing) Inkscape::Drawing(arena); - arena->observer = new CacheBudgetObserver(arena); Inkscape::DrawingGroup *root = new DrawingGroup(arena->drawing); root->setPickChildren(true); - root->setCached(true, true); arena->drawing.setRoot(root); + arena->observer = new CachePrefObserver(arena); + arena->drawing.signal_request_update.connect( sigc::bind<0>( sigc::ptr_fun(&sp_canvas_arena_request_update), -- cgit v1.2.3