
2010/4/7 Alexandre Prokoudine <alexandre.prokoudine@...400...>:
On 4/7/10, Krzysztof Kosiński wrote:
Hello
Here's my Cairo rendering proposal. I made it public so that all people can comment.
Alas, no. Signing in is still required :)
AFAIK you can sign in using your Gmail account. In any case, here's a copy-pasted version
Title: Cairo rendering for Inkscape Student: Krzysztof Kosinski
Inkscape uses its own rendering library, called libnr, when rendering graphics on the screen and exporting bitmaps. This library is slow, single-threaded and does not have any hardware acceleration.
This proposal is about converting Inkscape's rendering subsystem to Cairo. Using the hardware-accelerated cairo-gl backend and OpenCL-based filters will be investigated. The goal is to substantially improve rendering performance, so that very complex drawings can be edited easily.
Description
Rendering in Inkscape is done on two levels. The canvas widget, SPCanvas, is a regular GTK widget, which appears to be derived from the old Gnome Canvas. It is used to render visual editing aids, like the page border and control points. One of its items, NRArena, renders the content of the document. NRArena shows a tree of NRArenaItems by rendering them into garbage collected memory buffers called NRPixBlocks and then painting them onto the Cairo context of the SPCanvas widget.
This project will aim at refactoring the NRArenaItem hierarchy and porting it from NRPixBlock-based drawing to Cairo operations. Shapes will be drawn directly on the target context, or composited using the minimum possible number of intermediate surfaces. Implementation Details
* 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. * 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. * 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. * 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. * 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. * 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. * 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. * 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. * Once cairo-gl rendering is accomplished, I will try to implement one of the filters using OpenCL and its OpenGL interoperability feature [2]. Filter sources will be rendered into OpenGL memory objects, and the output will be computed into another OpenGL memory object using an OpenCL kernel. I have very little knowledge of OpenGL and OpenCL, so I estimate that my chances of completing this particular goal are rather low; therefore I do not include it in the list of deliverables.
Schedule
Before the program begins:
* Read Inkscape's source code. (I'm already doing this.) * Read the available Cairo documentation and run some example programs to get a good grasp of the API. * Read OpenCL and OpenGL documentation to determine whether I have some chances of implementing an OpenCL-based filter. Use the information to influence filter rendering design.
First half of the program. I will be completing my BSc thesis in chemistry, so some of these might spill over into the second half:
* Refactor 2Geom's Path and PathVector classes: Path should use boost::ptr_vector, and PathVector should be renamed to PathSequence and be implicitly shared. Make any necessary changes to the SVGPathSink API. Use them to reimplement 2Geom->Cairo path conversion. * Convert NRArena hierarchy to C++ and implement the memory management strategy. * Convert shapes to Cairo drawing operations. Introduce caching of Cairo resources where feasible. * Implement the backwards compatibility solution for filters.
Second half of the program:
* Complete the conversion to Cairo. * Benchmark the performance of the new renderer and introduce optimizations / additional caching when necessary. * Prototype cairo-gl support. * Prototype an OpenCL filter working either on OpenGL memory objects or Cairo image surfaces. * Write documentation. * Commit to trunk. * Bugfix.
Deliverables
* On-screen rendering uses Cairo. * Rendering performance is improved. * NRArena object hierarchy uses C++. * Documentation of new NRArena APIs. * (Optional) Legacy libnr geometry code is removed. * (Optional) cairo-gl backend is used when available.
References [1] http://www.cairographics.org/news/cairo-1.9.6/ [2] http://developer.amd.com/support/KnowledgeBase/Lists/KnowledgeBase/DispForm....
Regards, Krzysztof