threading in in krita

Boudewijn Rempt boud at valdyas.org
Tue Mar 31 20:48:00 CEST 2009


We're in a mess, right now. One of the goals of Krita 2.0 was to 
use threading to make sure we make optimal use of multicode processors
and keep the user interface responsive. Here's an analysis of where we
are: next up, a design for 2.1.


--- 1.6 ---

In Krita 1.6, we used threading in the following places:

 * in the resource server, for loading resources like brushes
 * in the filters gallery, for preparing the thumbnails
 * in the scale visitor, only we called KisScaleWorker::run, not
start, so it never got threaded


--- 2.0 ---


---- threadweaver ----


In Krita 2.0, threading is generally based on ThreadWeaver. We use or
used ThreadWeaver directly in:

 * KisProjection: when we still used the top-down recomposition
strategy, KisProjection used ThreadWeaver to tile the areas that were
to be recomposited. This failed because every layer needed to keep
track of dirty areas, and there was no way to make this threadsafe,
not even using QRegion. However, I have patch that re-enables threaded
recomposition, but this breaks on what looks like a bug in ThreadWeaver.

 * KisThreadedApplicator: this takes a paint device and (optionally)
divides it into areas and applies a KisJob to it. Only filters
currently use this. Right now, a job in KisThreadedApplicator cannot
be cancelled, and the way filters use it isn't safe, because
KisFilterHandler can be entered before the theaded applicator is done.
Because of a clash with KoUpdater, we need to disable this for all
filters for 2.0 :-(.
 
 * Colorspace conversion: there is a ConversionJob that could be used
to multi-thread the conversion of a single run of pixels from one
colorspace to another. This isn't used at all, and should probably be
converted to use KisThreadedApplicator anyway. I've svn rm'ed it now.

 * We used to use ThreadWeaver to recompute the thumbnails in the
filters gallery, however that got replaced by lazy creation of
thumbnails in KisFiltersModel. (At least, I hope it's lazy!)


---- KoAction ----


There is also KoAction. KoAction is a ThreadWeaver-based class that
executes a certain bit of code in a thread in threadweaver. It can
take care of progress updates, gui updates but not cancelling of
long-running actions.

We have wrapped KoAction in KisNodeAction, which locks the node (with
setSystemLocked) before starting the action. KisNodeAction isn't used
anywhere, and I have svn rm'd it.

We did not use KoAction anywhere else, except indirectly through
KoProgressUpdater.


---- KoProgressUpdater ---


KoProgressUpdater is only used in Krita (extensively, to report
progress of tasks with subtasks, like tiled filters) and in
KoPrintingDialog. The goal of KoProgressUpdater is to make it safe to
update one progress bar widget from multiple non-gui threads. Using
KoProgressUpdater does not make your task execute in a thread:
whenever you increase the progress, a KoAction is executed (well,
scheduled, the KoAction api is a bit confusing here) that, when
ThreadWeaver executes the scheduled action assembles the total
progress from all subtasks and updates the widget.  I think I've got an 
idea on how to remove the threading from KoProgressUpdater and still 
make it work correctly, though


---- QThread(Pool) ----


We use QThread and QThreadPool directly in the following cases:

 * deferred painting. The Freehand tool queues paint actions and
executes them in a QThread.

 * resource loading (like patterns, paintop presets and brushes)

 * swapping out of tiles (but only in the new tiles backend, which
isn't enabled by default because filters crash with it)
 
 * tile compressor: this compressed old tiles, like undo information.
It isn't enabled by default.

 * histogram calculation in the histogram docker.


-- 
Boudewijn Rempt | http://www.valdyas.org


More information about the kimageshop mailing list