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

Reply via email to