Hello all
I will limit myself to two possibilities of a GSoC project for this year: Cairo rendering and SP layer improvements. I think they have the biggest potential impact. This mail discusses the first one.
In order to use Cairo rendering in Inkscape, we need a Cairo-based canvas widget to replace the current SPCanvas / NRArena. They appear to be originally derived from GnomeCanvas. Canvas widgets are a rather common beast in the FOSS world, so even if we decide none of the existing ones are satisfactory for us, we have a large body of work from which we can derive inspiration.
This page has links to several existing canvas implementations. I have not analyzed all of them yet, but will keep you informed about any important http://live.gnome.org/ProjectRidley/CanvasOverview
Here are some requirements for our canvas. 0. Based on Cairo. 1. Model/view split: objects displayed on the canvas can exist without it. 2. Widgetless rendering: it should be possible to render completely in memory, for example for console-mode PDF export. 3. No excessive ties to Inkscape - implemented as a library, perhaps using a few well-defined portions of the existing codebase (e.g. 2geom). 4. Canvas primitives should be sufficient to render SVG.
There are many things to discuss, but here's the first one: Tiling reduces the area of the screen that needs to be redrawn, but increases the number of drawing operations. We could instead have a tile-less system that would compute the affected bounding box and redraw it in one go, instead of redrawing many tiles. What do you think?
Regards, Krzysztof
On 3/19/10, Krzysztof Kosiński wrote:
This page has links to several existing canvas implementations. I have not analyzed all of them yet, but will keep you informed about any important http://live.gnome.org/ProjectRidley/CanvasOverview
What I can say about GooCanvas is that is certainly had some limitations in the past, but there is a new active developer who's been adding useful features to it (IIRC, clipping paths and text on path were added recently) and the bonus is that some of Inkscape developers here met this guy in 2007 in Montreal at LGM. He is mostly known as the guy who reverse engineered CDR files :) He needs GooCanvas for his diagramming application. So if you go GooCanvas way, you can be sure you'll have collaboration.
Alexandre
On Fri, 2010-03-19 at 03:25 +0100, Krzysztof Kosiński wrote:
Here are some requirements for our canvas. 0. Based on Cairo.
- Model/view split: objects displayed on the canvas can exist without it.
- Widgetless rendering: it should be possible to render completely in
memory, for example for console-mode PDF export. 3. No excessive ties to Inkscape - implemented as a library, perhaps using a few well-defined portions of the existing codebase (e.g. 2geom). 4. Canvas primitives should be sufficient to render SVG.
I recall Ted previously mentioning us potentially going the route of Clutter for the canvas. It is not based on Cairo, but has Cairo support. I'm not necessarily promoting it's use, but figured I would bring up what I recall from previous discussions.
Cheers, Josh
On Thu, 2010-03-18 at 21:10 -0700, Joshua A. Andler wrote:
On Fri, 2010-03-19 at 03:25 +0100, Krzysztof Kosiński wrote:
Here are some requirements for our canvas. 0. Based on Cairo.
- Model/view split: objects displayed on the canvas can exist without it.
- Widgetless rendering: it should be possible to render completely in
memory, for example for console-mode PDF export. 3. No excessive ties to Inkscape - implemented as a library, perhaps using a few well-defined portions of the existing codebase (e.g. 2geom). 4. Canvas primitives should be sufficient to render SVG.
I recall Ted previously mentioning us potentially going the route of Clutter for the canvas. It is not based on Cairo, but has Cairo support. I'm not necessarily promoting it's use, but figured I would bring up what I recall from previous discussions.
One of the reasons I was thinking Clutter might be a reasonable option is that we could have the video card to the final composition. I am *NOT* advocating doing all the compositing as I don't think that's reasonable to expect. But, I think that we could do some amount of optimization by having the layer above and below the active layer rendered and cached, while the current layer gets updated. Then the video card could compose those three together.
Now, this doesn't preclude the change to Cairo, as Cairo would be used to build the tiles or textures for Clutter.
WRT the overall project: I'm worried it's too big for a SoC project. I think that it would be best to focus the project.
--Ted
Krzysztof Kosiński wrote:
Hello all
I will limit myself to two possibilities of a GSoC project for this year: Cairo rendering and SP layer improvements. I think they have the biggest potential impact. This mail discusses the first one.
In order to use Cairo rendering in Inkscape, we need a Cairo-based canvas widget to replace the current SPCanvas / NRArena. They appear to be originally derived from GnomeCanvas. Canvas widgets are a rather common beast in the FOSS world, so even if we decide none of the existing ones are satisfactory for us, we have a large body of work from which we can derive inspiration.
This page has links to several existing canvas implementations. I have not analyzed all of them yet, but will keep you informed about any important http://live.gnome.org/ProjectRidley/CanvasOverview
Here are some requirements for our canvas. 0. Based on Cairo.
- Model/view split: objects displayed on the canvas can exist without it.
- Widgetless rendering: it should be possible to render completely in
memory, for example for console-mode PDF export. 3. No excessive ties to Inkscape - implemented as a library, perhaps using a few well-defined portions of the existing codebase (e.g. 2geom). 4. Canvas primitives should be sufficient to render SVG.
There are many things to discuss, but here's the first one: Tiling reduces the area of the screen that needs to be redrawn, but increases the number of drawing operations. We could instead have a tile-less system that would compute the affected bounding box and redraw it in one go, instead of redrawing many tiles. What do you think?
Hi Krzysztof
I would like to ask what you mean by tiling. Is it a Cairo thing or is it about rendering performance (out of Cairo)?
Regards Vangelis __________________________________________________ �������������� Yahoo!; ���������� �� ���������� �������� (spam); �� Yahoo! Mail �������� ��� �������� ������ ��������� ���� ��� ����������� ��������� http://mail.yahoo.gr
W dniu 20 marca 2010 18:16 użytkownik Vangelis Katsikaros <vkatsikaros@...1244...> napisał:
Hi Krzysztof
I would like to ask what you mean by tiling. Is it a Cairo thing or is it about rendering performance (out of Cairo)?
Regards Vangelis
Regardless of the rendering system, we can split the canvas into several rectangular regions of the same size called tiles. When something changes, we redraw only the affected tiles. It may either reduce or improve performance: When the change affects a small number of ties, the amount of computation required to redraw them is lower.
However, if there are too many tiles, a lot of them are affected. We need to repeat the drawing commands for each tile. We end up sending a lot of commands, while redrawing the whole screen at once would do it in a much lower number of commands.
Regards, Krzysztof
Krzysztof Kosiński wrote:
W dniu 20 marca 2010 18:16 użytkownik Vangelis Katsikaros <vkatsikaros@...1244...> napisał:
Hi Krzysztof
I would like to ask what you mean by tiling. Is it a Cairo thing or is it about rendering performance (out of Cairo)?
Regards Vangelis
Regardless of the rendering system, we can split the canvas into several rectangular regions of the same size called tiles. When something changes, we redraw only the affected tiles. It may either reduce or improve performance: When the change affects a small number of ties, the amount of computation required to redraw them is lower.
However, if there are too many tiles, a lot of them are affected. We need to repeat the drawing commands for each tile. We end up sending a lot of commands, while redrawing the whole screen at once would do it in a much lower number of commands.
When you say canvas you mean the whole svg area (parts that are inside and outside the user's viewport) or only what is visible in the user's viewport?
<note> I use the word *viewport*, in order to describe the part of the part of the canvas, the user sees in his window. If there is a more appropriate gtk name, let me know. </note>
I see two different issues: a) rendering shapes that intersect with the user's viewport. This is needed when the user moves the viewport or changes zoom level. b) from the shapes, that intersect with the user's viewport, rendering only the ones that have been updated. This is needed when the user keeps the viewport still but makes edits on the shapes.
I would like to do the a) part (GSOC or not) and I'll know in the next 2 weeks if it can fit the GSOC timeline (ongoing MSc thesis and some other work).
Regards Vangelis __________________________________________________ �������������� Yahoo!; ���������� �� ���������� �������� (spam); �� Yahoo! Mail �������� ��� �������� ������ ��������� ���� ��� ����������� ��������� http://mail.yahoo.gr
W dniu 21 marca 2010 12:25 użytkownik Vangelis Katsikaros <vkatsikaros@...1244...> napisał:
When you say canvas you mean the whole svg area (parts that are inside and outside the user's viewport) or only what is visible in the user's viewport?
Tiling is generally on canvas, not on the viewport; otherwise you would have to redraw on scrolling.
I see two different issues: a) rendering shapes that intersect with the user's viewport. This is needed when the user moves the viewport or changes zoom level.
The old renderer already does this, by checking the bounding box of the item against the tile. It's in sp-canvas.cpp:874.
b) from the shapes, that intersect with the user's viewport, rendering only the ones that have been updated. This is needed when the user keeps the viewport still but makes edits on the shapes.
I think this won't make a big difference. Drawing solid non-transparent shapes is very fast, and it's the only case where you can apply this optimization. In other cases you have to redraw unchanged shapes as well. For example when you edit a semi-transparent path that's above another path, you have to draw them both - unless you have a pre-rendered image of the underlying path saved somewhere.
Regards, Krzysztof
Bulia: it's obvious that the current canvas does all this, but I mentioned those requirements in case we wanted to replace it with an external library.
Follow up with some details.
1. Currently there are actually two different canvas, with one drawing into an item of the other: SPCanvas uses a special item, SPCanvasArena, to display an NRArena with all NRArenaItems. I think this could be unified and NRArena should be just a group.
2. Every canvas and arena item can receive events. This is useful when implementing control points, but not for much else, and causes some slowdown when there are many complex paths, because on nearly every motion event the item under the cursor needs to be recalculated. I recall that when I profiled for slowdown in the new node tool, there was a nontrivial amount of time spent in children of pick_item on motion events. While the node tool obviously needs to do this, other tools like the selector don't - they only need to find the item under cursor on clicks. I propose to only pass events to items derived from a specific subclass, that register themselves in a geometric query structure when added to the canvas.
3. In case this project is too ambitious for GSoC, its scope can be reduced so that NRArena rendering is converted to use Cairo operations. Right now graphics are rendered into NRPixblocks.
Regards, Krzysztof
W dniu 24 marca 2010 02:59 użytkownik Krzysztof Kosiński <tweenk.pl@...400...> napisał:
- Every canvas and arena item can receive events. This is useful when
implementing control points, but not for much else, and causes some slowdown when there are many complex paths, because on nearly every motion event the item under the cursor needs to be recalculated. I recall that when I profiled for slowdown in the new node tool, there was a nontrivial amount of time spent in children of pick_item on motion events. While the node tool obviously needs to do this, other tools like the selector don't - they only need to find the item under cursor on clicks. I propose to only pass events to items derived from a specific subclass, that register themselves in a geometric query structure when added to the canvas.
I guess this was too technical... translation to plain English: if we don't pass events to SPItems, we don't need to determine which item is under the cursor on every motion event. Doing this takes up about 20% of the time in the node tool, so we speed up things a bit. Control points (aka knots) would still receive events, because their canvas item would be derived from a special event-receiving class.
Events on SPItems are handled by "item handlers" in event contexts. As far as I know, most of them don't do anything interesting. Equivalent functionality can be obtained by calling sp_event_context_find_item in the event context's root handler.
Regards, Krzysztof
2010/3/23 Krzysztof Kosiński <tweenk.pl@...400...>:
- Currently there are actually two different canvas, with one drawing
into an item of the other: SPCanvas uses a special item, SPCanvasArena, to display an NRArena with all NRArenaItems. I think this could be unified and NRArena should be just a group.
I'm not sure it is a good idea. The canvas and arena being different classes is very logical (image itself vs. auxiliary editing aids) and practically useful (those that only need a rendition of SVG can only create an arena and never worry about the canvas with its tiling machinery). Yes, there's some similarity between them, but not much, and a lot more subtle differences that would be a nightmare to reconciliate.
- Every canvas and arena item can receive events. This is useful when
implementing control points, but not for much else, and causes some slowdown when there are many complex paths, because on nearly every motion event the item under the cursor needs to be recalculated. I recall that when I profiled for slowdown in the new node tool, there was a nontrivial amount of time spent in children of pick_item on motion events. While the node tool obviously needs to do this, other tools like the selector don't - they only need to find the item under cursor on clicks.
No, actually it tracks it all the time because it changes the cursor over selectable objects, via enter/leave signals.
I propose to only pass events to items derived from a specific subclass, that register themselves in a geometric query structure when added to the canvas.
I agree some canvas items can be safely made insensitive to events, for example selection rectangle (if it's not already). But I doubt we will gain much performance on this - most canvas and arena items still have to be sensitive.
- In case this project is too ambitious for GSoC, its scope can be
reduced so that NRArena rendering is converted to use Cairo operations. Right now graphics are rendered into NRPixblocks.
Exactly, this was always my idea for this project since the very start. I can be your mentor again :) I'm not much of a guru on rendering and rasterization as such, but I have spent quite some time in arena/canvas code.
W dniu 24 marca 2010 15:29 użytkownik bulia byak <buliabyak@...400...> napisał:
2010/3/23 Krzysztof Kosiński <tweenk.pl@...400...>:
- Currently there are actually two different canvas, with one drawing
into an item of the other: SPCanvas uses a special item, SPCanvasArena, to display an NRArena with all NRArenaItems. I think this could be unified and NRArena should be just a group.
I'm not sure it is a good idea. The canvas and arena being different classes is very logical (image itself vs. auxiliary editing aids) and practically useful (those that only need a rendition of SVG can only create an arena and never worry about the canvas with its tiling machinery). Yes, there's some similarity between them, but not much, and a lot more subtle differences that would be a nightmare to reconciliate.
I would solve this as follows:
1. The canvas defines some interfaces, e.g. Renderable, RenderableShape, RenderableImage, etc. These would define methods needed to render the thing. Renderable would have one method - render(), that would take a Cairo context and output it to the given Cairo context. RenderableShape would be a subclass of Renderable which implements the render() method for shapes, and instead has more specific methods like: Geom::PathVector getShape() Inkscape::Canvas::Paint getPaint() boost::shared_ptrInkscape::Canvas::Renderable getMask() Inkscape::Canvas::Filter getFilter()...
RenderableImage would have: Glib::RefPtrGdk::Pixbuf getPixbuf()
RenderableGroup would recurse into its children.
2. Those interfaces have various implementations: ones that are not bound to the XML, which work like current SPCanvasItems, and ones that do, which work like SPItems. This way we can maintain the CanvasItem / SPItem split while keeping the renderer oblivious of it, so that controls and SVG are rendered with he same high fidelity. (For example, right now control points are unaliased.)
3. Tiled rendering would be an option of the canvas widget; it's as simple as passing a different bounding box to render the root group.
- Every canvas and arena item can receive events. This is useful when
implementing control points, but not for much else, and causes some slowdown when there are many complex paths, because on nearly every motion event the item under the cursor needs to be recalculated. I recall that when I profiled for slowdown in the new node tool, there was a nontrivial amount of time spent in children of pick_item on motion events. While the node tool obviously needs to do this, other tools like the selector don't - they only need to find the item under cursor on clicks.
No, actually it tracks it all the time because it changes the cursor over selectable objects, via enter/leave signals.
I think it can be done using sp_event_context_find_item; this way picking the item under the cursor would be only done on demand.
- In case this project is too ambitious for GSoC, its scope can be
reduced so that NRArena rendering is converted to use Cairo operations. Right now graphics are rendered into NRPixblocks.
Exactly, this was always my idea for this project since the very start. I can be your mentor again :) I'm not much of a guru on rendering and rasterization as such, but I have spent quite some time in arena/canvas code.
I think some cleansing could be done simultaneously: 1. Get rid of NRObject. It's essentially an inferior clone of GType which is used inside NRArena. 2. Get rid of remaining NR geometry code. 3. Get rid of SPCurve and replace it with a shared copy-on-write Geom::PathVector (which should be renamed to Geom::PathSequence). 4. Expand the SVGPathSink functionality in 2Geom, so that feeding paths to Cairo is done using this nice interface.
Regards, Krzysztof
2010/3/27 Krzysztof Kosiński <tweenk.pl@...400...>:
- Those interfaces have various implementations: ones that are not
bound to the XML, which work like current SPCanvasItems, and ones that do, which work like SPItems. This way we can maintain the CanvasItem / SPItem split while keeping the renderer oblivious of it, so that controls and SVG are rendered with he same high fidelity. (For example, right now control points are unaliased.)
And I honestly consider this lack of antialiasing an advantage - this makes it easy to visually distinguish objects from editing aids.
I think some cleansing could be done simultaneously:
- Get rid of NRObject. It's essentially an inferior clone of GType
which is used inside NRArena. 2. Get rid of remaining NR geometry code. 3. Get rid of SPCurve and replace it with a shared copy-on-write Geom::PathVector (which should be renamed to Geom::PathSequence). 4. Expand the SVGPathSink functionality in 2Geom, so that feeding paths to Cairo is done using this nice interface.
These are good objectives, if you can do this in addition to the cairo rendering it will be great. But for the canvas/arena unification I'm still unconvinced that it will give any advantages, and in any case it seems like a too big piece of work to stuff into one GSoC. Let's limit this year's work to cairofication and discuss this project later.
2010/3/18 Krzysztof Kosiński <tweenk.pl@...400...>:
Here are some requirements for our canvas. 0. Based on Cairo.
- Model/view split: objects displayed on the canvas can exist without it.
NRArenaItems do exist separately, all cairo stuff should definitely be under them.
- Widgetless rendering: it should be possible to render completely in
memory, for example for console-mode PDF export.
Our NRArena satisfies this, and indeed is used for things other than the main editing area.
- No excessive ties to Inkscape - implemented as a library, perhaps
using a few well-defined portions of the existing codebase (e.g. 2geom).
Sounds nice, but would be quite difficult to extract the arena stuff from Inkscape.
- Canvas primitives should be sufficient to render SVG.
They obviously are now, since we render it :)
There are many things to discuss, but here's the first one: Tiling reduces the area of the screen that needs to be redrawn, but increases the number of drawing operations. We could instead have a tile-less system that would compute the affected bounding box and redraw it in one go, instead of redrawing many tiles. What do you think?
The reason for redrawing tiles is improving interactivity at the cost of increasing render time. Since Inkscape is single-threaded, we need ways to interrupt rendering and respond to user actions. For this, the renderer runs a main loop iteration after each tile, potentially cancelling this render if the user did something that needs redraw, such as zoom. Another reason is that tiles allow Inkscape to show parts of the image before other parts are ready, and thus allow the user to quickly take a decision on what to do next, without waiting for the whole screen to finish; for this, tile rendering always starts with the point where your mouse cursor is (i.e. where you work) and spreads from it outwards. The performance cost of rendering separate tiles is real, for example each tile covering a path should do its own path calculations, and some of them are inevitably done on the entire path even if you're redrawing only one tile. However, this cost can be reduced by smart cashing of calculation-intensive data associated with objects.
participants (6)
-
Alexandre Prokoudine
-
bulia byak
-
Joshua A. Andler
-
Krzysztof Kosiński
-
Ted Gould
-
Vangelis Katsikaros