2010/4/26 Krzysztof KosiĆski <tweenk.pl@...400...>:
It's not necessary to switch to the Illustrator method (which by the way I find very hard to justify). What I wanted is to redraw everything in one go. It would make the renderer less responsive, but I intended that to be overcome by the speed increase from hardware acceleration.
Please don't do that. No matter how fast is renderer, there will always be documents for which it's not fast enough. Especially since our format is SVG, where it takes just minutes to write a script generating a document with thousands of objects.
Obviously there are two conflicting goals:
- Respond to user actions as quickly as possible.
- Do not show a partially redrawn screen.
I really don't see why 2 is a goal at all. If the renderer becomes as fast as you seem to imply, then this partial render will be simply impossible to notice! On the other hand, if it _can_ be noticed, it means the rendering is not fast enough, and we need to spend all effort on achieving goal 1.
First, I would make the renderer reasonably interruptible. Then I would set a configurable threshold, say 20ms, for what should be considered "instantaneous". On every redraw I set a 20ms timer. If the timer expires before I'm done, I throw away whatever I was doing, split the image into 4 tiles and start over. When drawing each tile I set a timer as well, and I progressively reduce the tile size as the timers expire before I'm done, until I hit some minimum tile size at which expiring timers do not cause a tile shrink. I would keep rendering at that tiling level as long as the redraw of each tile takes more than 1/4 of the time limit.
Oh. Are you really suggesting to do all this during interactive work? Did you make an estimate of how much time this would waste in the worst case? And why all this waste - just for the sake of "all at once" redraw?
On the other hand, some kind of adaptive buffer sizing may be beneficial indeed. But it must go in the opposite direction - and never discard anything. Namely: time the render of each buffer; if it was rendered fast enough, double the size of the next buffer (i.e. render two buffers at once); if it was rendered slow, halve the next buffer until some fixed minimum is reached. This strategy may reduce the overall number of buffer strips on the screen and perhaps speed it up somewhat without damaging interactivity too much.
Another reason this approach is better than yours is that for your proposal to work, you need a way to be able to stop the actual render at a given time. There's no guarantee Cairo will allow you to do that. If it _were_ possible to "pause" rendering at a given time, retrieve the partial results and then resume the render from this place _without_ the renderer losing its setup and path data, then it would be the ideal solution for us - we would have fine-grained interactive response and no time wasted on setting up buffers, re-tesselating paths, etc. But I really doubt Cairo will be that nice :)
The action of pruning invisible objects is useful in itself. If it could be done without rendering, only by considering the geometry and style of the objects, we could add it to "Vacuum defs" (which should be named "Clean up document" and do a few things more than it does at present, for example remove broken references).
That might be a useful function, but it is not very relevant to "vacuum defs", and even more offtopic in this discussion :)