patch for moving the calculation of image colours to a background thread

Dmitry Kazakov dimula73 at gmail.com
Sat Sep 18 08:00:45 CEST 2010


Ah, forgot to add kimageshop as a recipient. =)

---------- Forwarded message ----------
From: Dmitry Kazakov <>
Date: Sat, Sep 18, 2010 at 9:58 AM
Subject: Re: patch for moving the calculation of image colours to a
background thread
To: "Adam C." <>



On Sat, Sep 18, 2010 at 12:08 AM, Adam C. <> wrote:

> hi,
> here is the patch. i've never done something with multiple threads, so i'm
> completely green in that area.
>
> I need a call to KisImage::convertToQImage(..), which is quite slow,
> because it has to do much work on a big image. this is the reason i want it
> in a thread. otherwise it's not possible to update after every stroke. if we
> can replace it with something safer or faster, i'm fine with that of course.
>

1) Yes, convertToQImage() is too slow. I think we shouldn't do it for the
entire image every time. Just because it is very slow and inefficient.
2) convertToQImage() is not thread safe. It reads from
rootLayer->projection(), that can be in a random state at arbitrary moments
of time. In theory, you can wrap it into KisImage::lock()/unlock(), but that
wouldn't be a good idea, because all the updates will stop for a while.

I think you need to stick to one of the updater threads somehow. I see three
ways to do this:

1) You make a direct connection to KisImage::sigImageUpdated(rc) (
Qt::DirectConnection). Then you'll get threading and locking for granted.
You will have a guarantee of safe reads from @rc in a context of that
signal. But this method has a drawback: you need to guarantee somehow, that
your connection will be called *after*
KisCanvas2::startUpdateCanvasProjection(). In other case, recalculation of
colors would delay updates of the canvas, that is really a bad thing.

2) As an alternative, you can stick to a ui thread and do the job after
KisCanvas2::updateCanvasProjection() finished. You will know the updated
rect, but you will have access to a projection cache only. Actually, i don't
know whether it is possible to read from OpenGL textures, so i'm not sure
about this way.

3) Actually, i don't think it is absolutely important to update colors after
every single stroke, is it? We can update them after, say, 2 seconds of
inactivity. Every stroke made by user can reset the timer, so we will never
irritate him with this. So, how will it look like:

- you connect recalculation of colors to QTimer::timeout() (timeout is set
to 2 sec)
- connect (with auto connection) KisImage::sigImageUpdated(rc) to
QTimer::start()

then you have two options:
a) on every timeout, you call KisImage::lock(); KisImage::convertToQImage();
KisImage::unlock() and do your work in UI thread
b) more complicated, but more efficient way: you store a QRegion of dirty
rects and call convertToQImage() for them only.


As for me, i like 3,b) option :)

-- 
Dmitry Kazakov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.kde.org/pipermail/kimageshop/attachments/20100918/ebfbc39b/attachment.htm 


More information about the kimageshop mailing list