On 7 July 2013 08:55, Martin Renold <martin...@gmx.ch> wrote: > On Sat, Jul 06, 2013 at 07:28:53PM +0200, Jon Nordby wrote: > > I see that the paint and paint-rotated benchmarks have had a regression > > since 1.1 (due to GTK+3?). I pushed a commit which should help a bit, by > > caching the transformation matrix: > > > http://gitorious.org/mypaint/mypaint/commit/4b0cf83174cfe0ef3c796b497df913a8e06560da > > Thanks a lot! I was getting a bit desperate when fixing the display bugs > exposed by gtk3.9, and happy to have found a fix at all. The code before > fbec5171 (the benchmarked one) wouldn't have needed this caching, I think. >
> where most things are limited by how fast we can fetch tiles from the tile > > store, ie: _get_tile_numpy() in lib/tiledsurface.py > > If this is really the per-tile overhead adding up, we can just increase > MYPAINT_TILE_SIZE. But looks like _get_tile_numpy() is doing a lot more > than just fetching tiles. > Increasing the tile size is on option, but it will limit concurrency more (as multi-threading is done on a tile-by-tile basis). It may also lead to poorer > > Time spent in (and below) _get_tile_numpy() on my system: > > layerpaint_zoomed_out_5x: 48% > > brushengine_paint_hires: 35% > > paint_zoomed_out_5x: 52% > > Much more than I expected. I wonder if it could be all due to mip-mapping? > But then again, mip-mapping should happen only once per displayed frame, I > expected this to disappear in actual hi-res dabbing. > Well, because we always paint onto the surface which is mipmap level 0, when we are displaying zoomed out we have to. One way of avoiding this would be to paint at the same mipmap level as we are displaying, but this requires us to be able to re-render past strokes when user zooms in again. Tricky, but not impossible as we can now store paint operations efficiently (in an OperationQueue). I am attaching the callgraps (from tests/test_performance.py -c 1 -s TEST) here. layerpaint_zoomed_out_5x: http://i.imgur.com/OZcBjXG.png brushengine_paint_hires: http://i.imgur.com/qj1o5vO.png paint_zoomed_out_5x: http://i.imgur.com/e13IKV4.png As you can see there are three problem spots: 1. computing dirty mipmaps 2. marking tiles as dirty 3. time spent in get_tile_numpy itself 1) is something that we could improve through multi-threading, like we do with tiles while painting. This requires that we batch up the tiles to be processed and hand it over to C++, as one cannot call into Python from multiple threads concurrently. I attempted to do that, but due to added complexity on Python side, it turned out slower. http://gitorious.org/~jonnor/mypaint/jonnors-clone/commits/mipmap-cpp Alternative approaches to this would be appreciated. 2) Could maybe be improved by changing mark_mipmap_dirty to not be recursive, but instead just iterate over the list of mipmap surfaces and doing surface.tiledict[(tx, ty)] = mipmap_dirty_tile, on each? Hmm, or maybe we can return early in some cases. If a tile is the mipmap_dirty_tile, then sure all of the tiles above it will also be already, so no need to redo it? *goes to tests* 3) Perhaps avoding recursion could help here to? Apart from that I don't have many ideas... I am experiementing with moving all of this code into C/C++, so that no trip into Python is needed per-tile http://gitorious.org/~jonnor/mypaint/jonnors-clone/commits/tilestore-cpp This is also an exploration of how we can back the surface in MyPaint with something else than the current implementation (I am thinking GEGL here), as I am still not certain how to approach that. -- Jon Nordby - www.jonnor.com
_______________________________________________ Mypaint-discuss mailing list Mypaint-discuss@gna.org https://mail.gna.org/listinfo/mypaint-discuss