
Hi Krzysztof,
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 called "tiling".
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 happens).
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 acceleration.
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 future plans.
* 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 [1]. 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.