Let's get it going :) Below are my comments on your plan.
First of all, something you likely already know: in outline mode, all
reandering is already by cairo image surfaces. Obviously it ignores
the more difficult points of stroking, opacity, transparency,
patterns, filters, etc. etc., but at least the basic infrastructure is
there, and you can build from it. Please try to contain your
refactoring urge, and don't break things that already work, unless you
have good reasons :)
> * Rendering tree pruning. Currently there are two levels of
> pruning done in NRArena. The first is tiling - the canvas is split
> into several smaller rectangles that are painted independently. This
> improves interactivity at the cost of some drawing artifacts and
> slower overall redraw. The second is simple bounding box based
> pruning, where objects that don't intersect with the drawing area are
> not drawn. In my project, I will drop tiling (it introduces artifacts,
> and is likely to degrade performance in hardware accelerated
> scenarios), and will instead introduce a pruning system based on dirty
> rectangles. After each change to the document, the dirty rectangle
> (the minimum area of the screen that needs redrawing) will be
> computed. The computed rectangle (bounding box) will be passed to the
> rendering functions, and objects whose bounding boxes don't intersect
> with the redraw area will be skipped.
I think there's confusion here. First, all the tiling is in Canvas
layer, not Arena layer, so if you limit your work to arena items, you
will not affect tiled rendering at all.
Second, I would like to explain some details on the canvas tiling, so
as to prevent confusion of terms. There are two mechanisms that can be
One is that the visible screen is divided into square 16x16 tiles, but
it does not mean that each such tile is painted separately. Instead,
these tiles are quanta of dirtying the canvas: if you dirty a single
pixel, the entire 16x16 tile it belongs to is dirtied. The goal of
this is to prevent too small dirtied areas and to accumulate many
small dirtying events into a few larger events (because obviously, if
you request to dirty a pixel in an already dirtied tile, nothing
The other mechanism divides the area-to-paint into buffers, and paints
each buffer completely separately, returning to the main event loop
after each buffer so that redraw can be interrupted. The size of these
buffers depends on mode: 256K bytes in normal mode and 1M in outline
mode (these are the values I found optimal after testing; divide by 4
to get the number of pixels in a buffer). These buffers divide the
area to paint into strips along the longer side of the area to paint
(i.e. horizontal if the area is mode wide than tall), and the width of
these strips is calculated from the size of the area and the size of
the buffer; these strips are painted starting from the one in which
the mouse cursor is, and spreading outwards from it. Buffer boundaries
have no coordination with 16x16 tiles, but they just go until
interrupted or until covering all dirtied area.
All this is on top of the simple "don't render this object if it's
outside the currently painted buffer" logic which is indeed in arena
items that you will have to work with in your project. Both these
mechanisms - canvas tiles and canvas buffers - have their purposes in
life, and both have been tweaked for performance extensively. Please
understand very well how they work and don't try to change or abandon
them unless you have a _very_ clear idea of what and why you're doing
> * Memory management. NRArena uses the Boehm garbage collector.
> This is sometimes poorly compatible with Cairo. I will introduce an
> explicit memory management strategy based on smart pointers and/or
> rigorously specified ownership semantics.
I think I would much prefer a rigorous ownership semantics option.
Arena items live easily definable lives and I don't really see why
anything more complex might have been necessary. One issue I recall is
that arena items hold pointers to the same SPStyle objects as their
parent SPObjects, which I think was a problem resulting in memory
leaks and other bugs (please contact Mentalguy for more on that, he's
the best person to know about all that).
> * Caching. Initially, no caching of rasterized graphics will be
> done, but the new NRArena classes will be written in a way that
> doesn't preclude introducing it later. Caching rasterized data is
> unlikely to give any performance boost when using hardware
I think caching, if done properly, will give a huge interactivity
gain. Right now, when you move a canvas item such as a handle or node,
objects underneath it have to be redrawn (within the touched 16x16
tiles) starting from scratch - tesselating, stroking, filling, etc.,
even if they didn't change, which is one of the major contributors to
the "feeling of slow". If these redraws can be pulled from a cache, it
will feel much more responsive I think.
> * Intermediate results. Some SVG features, like masks and filters,
> require rendering intermediate results for compositing. Image surfaces
> (kept in main memory) or offscreen native surfaces will be used for
> this purpose.
The problem with image surface is that it's never going to be really
fast - it's just software rendering. And a problem with offscreen GL
surface, as you said, is that it may not be available everywhere.
Please weigh these alternatives carefully before committing to one of
them. It might help to contact Cairo people for their insights and
> * Filters. Filter implementations will be converted to use Cairo
> image surfaces via direct data manipulation. I do not expect to
> encounter too many problems with this conversion, since the only thing
> that will change is the way the memory is accessed and possibly the
> order of channels in image data.
Yes, I think if you properly redesign NRPixBuffers as adaptors for
cairo surface buffers, there will be very little, if anything at all,
to change in the filter code.
> * Text. Text rendering will use Pango-Cairo. An effort will be
> made to access fonts only through Pango. This will enable us to remove
> the dependency on fontconfig in the Windows port, and use Pango's
> native Windows fonts support in the future.
Text rendering in outline mode is already done by cairo - it gets
pathvector for the glyphs and renders it as path. PLEASE keep this
approach and try to change as little as possible in text and font
code: this is outside the scope of the project and is very sensitive
area where a lot of testing is needed. Also, this approach should make
it easier to deal with paths and text uniformly when it comes to
stroking, gradients, etc., which is what SVG requires.
> * Refactoring. Inkscape's 0.49 release cycle will be focused on
> removing deprecated code and rewriting exisint code for better
> understandability and correctness. As part of that effort, in addition
> to NRArena C++ conversion, I will remove as much legacy libnr geometry
> code as possible by converting it to 2Geom and introducing additional
> 2Geom functions or classes when necessary.
Changing linbr to 2geom should be OK, but please to be as careful as
possible with other code :)
> * Hardware acceleration strategy. Cairo provides support for
> OpenGL-based harware acceleration using the experimental (as of 1.9.6)
> cairo-gl backend . This appears to be the best option for hardware
> acceleration. After I finish the Cairo renderer, I will attempt to
> make it use cairo-gl surfaces when available. My initial research
> suggests that the best way of achieving this is by using GtkGLExt
> combined with GLX.
Here I'm not knowledgeable to advise anything, but please try to
contact cairo guys for deeper perspectives on this.
One final note: please try to keep both new and old rendering
functioning together for as long as possible, with an easy way to
switch between them (ideally without restart), so that the new
renderer can be quickly checked for correctness and speed. This is a
critical point in ensuring a smooth transition! Also, this will be
another reason to limit refactoring to the necessary minimum, so as to
not disable the old rendering code unless absolutely unavoidable.
Inkscape. Draw Freely.