[Panel-devel] rfc: Plasma::Theme and Plasma::Svg

Matt Broadstone mbroadst at gmail.com
Tue Mar 6 20:27:18 CET 2007


On 3/6/07, Aaron J. Seigo <aseigo at kde.org> wrote:
> hey all..
>
> looking at the use patterns in ksysguard, krunner and now plasma for QSvg this
> seems to be the common approach:
>
> - load the svg from disk
> - on paint, render the svg into a pixmap and hold on to that, blit the pixmap
> - on resize, mark the cached pixmap as dirty, causing a re-render on next
> paint
>
> this is because rendering svg obviously takes more time than simply blitting
> an image
>
> the other concern is that QSvg can take a good amount of memory to build the
> render tree, etc.. so sharing renderers is a good idea; and deleting them
> when not needed anymore is even better.
>
> there are two other assumptions that went into my thinking on this that
> reflect the current state of panels and desktop widgets in kde and other
> desktops:
>
>  - items will be long-lived but rarely change size
>  - many items will share identical graphical elements, e.g. widget and button
> backgrounds
>
> i sat down last night and put together a design that will provide for these
> use cases to avoid duplicating this pattern over and over in the code.
>
> Plasma::Svg will provide the following public methods:
>
> - Svg(const QString& imagePath, const QSize& size)
>         constructor that takes a path to be used with Plasma::Theme
> - paint( QPainter*, const QRect& )
>         pretty obvious =)
> - resize( int width, int height )
>         also pretty obvious
> - resize( const QSize& size )
>         even more obvious ;)
>
> so one would simply do:
>
> Plasma::Svg* bg = Plasma::Svg( "dialog/background", QSize( 400, 250 ) );
>
> and in the paint method:
>
> QPainter p( this );
> bg->paint( &p, rect() )
>
> to facilitate this, Plasma::Theme will be changed to provide a singleton
> pattern, e.g. Theme* self().
>
> what i haven't decided yet, is whether we should check the rect in paint()
> against the current size and assume that if the rect != rect() that a resize
> is implied. the usual case will be to call resize() in the painting item's
> resizeEvent() however, so i don't know if this will buy us anything in
> practice. at this point i'm taking a wait-and-see-approach on that.
>
> the pixmaps will be stored in a QPixmapCache for use throughout the app.
> therefore, if more than one instance of the same Plasma::Theme image path
> with the same rendering size is available, there should be no need to hit
> disk, parse or render the svg. woo! item keys will be constructed this way:
>
>   ${IMAGE_PATH}_${WIDTH}_${HEIGHT}
>
> internally, Plasma::Svg will have a ref-counted shared struct of data
> containing:
>
>  - refcount on the QPixmapCache entry
>  - QSvgRenderer. this should prevent multiple instantiations of the renderer.
>
> profiling should later show if/when/how the shared renderer should be
> instantiated and removed. e.g. it may make sense to create the renderer and
> after a certain amount of time w/out calls to resize to delete it to conserve
> memory.
>
Are we to continue using QAtomic for refcounting or are we going to
move over to using KShared?

Also, it might be cool if Plasma::Svg could just be a QPaintDevice so
we could use it just like a QImage/QPixmap with all of this
checking/caching/refcounting going on behind the scene.. Right now
though this solution helps manage all the reuse involved with our svg
images, it still provides the somewhat unintuitive api of svgrenderer
(the whole calling paint/render on some other class to paint the
image, instead of the more intuitive approach: just paint the image
class itself). Just my two cents.

Otherwise, sounds great.


-- Matt


> --
> Aaron J. Seigo
> humru othro a kohnu se
> GPG Fingerprint: 8B8B 2209 0C6F 7C47 B1EA  EE75 D6B7 2EB1 A7F1 DB43
>
> Full time KDE developer sponsored by Trolltech (http://www.trolltech.com)
>
> _______________________________________________
> Panel-devel mailing list
> Panel-devel at kde.org
> https://mail.kde.org/mailman/listinfo/panel-devel
>
>
>


More information about the Panel-devel mailing list