[Panel-devel] Multi-threaded SVG Rendering has arrived...

Sean Harmer sh at theharmers.co.uk
Sun Nov 25 17:28:11 CET 2007


...subject to approval of course.

Hi Everyone,

Please find attached my latest patch to libplasma to enable SVG images to be 
rendered in separate threads. You will also find attached a patch againt 
plasma (the app) that modifies the panel and the analog clock to use the new 
features (more on this later).

OK here is what I've done. A few new classes have been introduced to 
libplasma:

SvgRendererCache - threadsafe cache of SharedSvgRenderer::Ptr's
SvgRendererThread - paints Svgs in its own thread
SvgThreadManager - looks after the queue of render jobs

These are internal to libplasma and are not exported at present. I don't know 
if anybody outside of libplasma would have a use for them so I've kept them 
internal. They are all d-pointered though just in case. :-)

I have also modified the following classes:

Svg - lots done in here :-)
SharedSvgRenderer - made threadsafe(r)

Basically Plasma::Svg now provides functions to render one element, 
render(const QString& elementId) and to render a specified set of elements, 
renderSet(const QSet<QString>& elementIds). The cause the emission of the 
signals svgRendered(int, elementId) and svgSetRendered(int) respectively.

It is possible to tell if an element is already in the pixmap cache with 
isRendered(const QString& elementId).

The various paint() functions will also cause requested Svg elements to be 
scheduled for rendering. If there is no cached pixmap ready, then paint will 
not paint anything. So you should connect to svgRendered() to trigger another 
repaint. This is the quick and dirty way of using the multithreading 
features.

To make more efficient use of the multithreading, you should take a look at 
panel.cpp in the second patch. This triggers a fresh rendering of the SVG 
elements from within constraintsUpdated. The panel class has been modified by 
adding a couple of bools to keep track of which parts of the Svg have been 
rendered. When all of the requisite parts are rendered into the Svg cache, 
then the paintBackground() function is allowed to proceed. 

A new paint function has been added to Plasma::Svg that allows painting a 
subset of the entire cached pixmap. This should allow certain 
containments/plasmoids to make more efficient use of Svg images by only 
painting the dirty area.

As mentioned in the earlier thread, SVG images that contain text must be 
rendered in the main thread as painting of text cannot be done outside of the 
main thread until Qt 4.4. For now there is a setHasText(bool) function on 
Plsama::Svg which forces main-thread rendering. This can be made into 
a "do-nothing" function for KDE 4.1 (Qt 4.4).

The SvgRendererCache singleton object is responsible for keeping around useful 
renderer objects. I have written this to accomodate a number of cache expiry 
policies (only 2 so far, and only one of those is currently implemented). At 
present, the default policy is MinimiseMemory. This causes a QTimer fired 
event to periodically check for renderers that have not been access for 
greater than an application-configurable time. The checking period is also 
application-configurable. You should hopefully see some debug output similar 
to the contents of the 3rd attachment when the rendering cache checks for 
unneeded renderers.

I hope all that makes sense. Please ask if you are not sure on anything. The 
apidox in Plasma::Svg should help.

Is this OK to commit now please? I know of the following things that need to 
be done:

* Review the caching of rendered pixmaps
* Make a slight improvement in the prioritisation of render jobs so that 
multiple threads are not contending to lock the same SharedSvgRenderer.
* Implement the MinimiseCPU cache policy in SvgRendererCache.
* Fixup other plasmoids to make proper use of these features.

Despite these remaining tasks I would like to get this into svn as this is now 
in a stable state (I don't know of any crashes); I am scared of accidentally 
breaking something whilst playing around with the queueing policy and the 
pixmap cacheing; it will allow others to help with modifying the plasmoids; 
and any bugs will be found more quickly.

Any thoughts or constructive criticism is greatfully welcome!

Kind regards,

Sean

ps If you managed to read all of that then well done! :D
-------------- next part --------------
A non-text attachment was scrubbed...
Name: svg-threading.patch.gz
Type: application/x-gzip
Size: 13434 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/panel-devel/attachments/20071125/d7d817bb/attachment-0002.gz 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: svg-threading-plasmoids.patch.gz
Type: application/x-gzip
Size: 2289 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/panel-devel/attachments/20071125/d7d817bb/attachment-0003.gz 
-------------- next part --------------
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers: Checking for unneeded renderers
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers: Checking "/home/kde-devel/kde/share/apps/desktoptheme/default/widgets/iconbutton.svg" : Age = 156 s
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers: Found renderer not accessed for > 120 seconds. Removing reference to: "/home/kde-devel/kde/share/apps/desktoptheme/default/widgets/iconbutton.svg"
plasma(19087) Plasma::SharedSvgRenderer::~SharedSvgRenderer: Leaving this world for a better one.
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers: Checking "/home/kde-devel/kde/share/apps/desktoptheme/default/widgets/panel-background.svg" : Age = 8 s
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers: Checking "/home/kde-devel/kde/share/apps/desktoptheme/default/widgets/background.svg" : Age = 159 s
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers: Found renderer not accessed for > 120 seconds. Removing reference to: "/home/kde-devel/kde/share/apps/desktoptheme/default/widgets/background.svg"
plasma(19087) Plasma::SharedSvgRenderer::~SharedSvgRenderer: Leaving this world for a better one.
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers: Renderer cache now contains:
plasma(19087) Plasma::SvgRendererCache::Private::checkForOldRenderers:   "/home/kde-devel/kde/share/apps/desktoptheme/default/widgets/panel-background.svg" : KSvgRenderer(0x75bda0) : 1


More information about the Panel-devel mailing list