[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