On Wednesday 15 October 2008, Marco Martin wrote:
> On Wednesday 15 October 2008, Aaron J. Seigo wrote:
> > hi ..
> >
> > doing some profiling with valgrind/massif, i noticed that a large amount
> > of start up processing and memory usage is spent in parsing SVGs.
> > surprise! ;)
> >
> > i introduced a KPixmapCache for on-disk caching to help prevent the need
> > to render from the source SVG over and over.
> >
> > i was able to squeeze ~1MB of RAM usage out by doing that. but we can be
> > even better ....
> >
> > right now what is kicking us in the teeth is accessing embedded hints in
> > the SVG file. turns out they are SUCH a great idea after all ;) at least
> > not when we don't cache them, resulting in unecessary parsing of the SVG.
> >
> > in particular, those include:
>
> will try the patch, i'm willing to do something aout it...
> i was thinking about a QHash of rects keps by Svg, so haselement is a check
> for the existence of the key elementRect fetches the value and elementsize
> its size
> the first time calles well, still suck, but inevitable...
> all the cache kiled on theme changed annd when the svg changes on disk how
> behave? hmmm...

ok, this patch is the idea, it seems to work, still has two problems dunno how 
relevant:
-when checking for element existence it computes the rect, a bit of a waste, 
but this way don't have to keep two separate caches for rect and for existence
-when checking for a non existent element it saves nothing because still 
invokes the renderer every time.. perhaps saving also a list of queried not 
existent elements? (maybe imited to a fixed number of elements say 100 to not 
make it grow forever)

Cheers,
Marco Martin


Index: svg.cpp
===================================================================
--- svg.cpp	(revision 870347)
+++ svg.cpp	(working copy)
@@ -226,32 +226,30 @@
 
         QSize elementSize(const QString &elementId)
         {
+            return elementRect(elementId).size().toSize();
+        }
+
+        QRectF elementRect(const QString &elementId)
+        {
+            if (elementRects.contains(elementId)) {
+                return elementRects[elementId];
+            }
+
             createRenderer();
 
             if (!renderer->elementExists(elementId)) {
-                return QSize(0, 0);
+                return QRect(0,0,0,0);
             }
 
-            QSizeF elementSize = renderer->boundsOnElement(elementId).size();
-            QSizeF naturalSize = renderer->defaultSize();
-            qreal dx = size.width() / naturalSize.width();
-            qreal dy = size.height() / naturalSize.height();
-            elementSize.scale(elementSize.width() * dx, elementSize.height() * dy,
-                              Qt::IgnoreAspectRatio);
-
-            return elementSize.toSize();
-        }
-
-        QRectF elementRect(const QString &elementId)
-        {
-            createRenderer();
             QRectF elementRect = renderer->boundsOnElement(elementId);
             QSizeF naturalSize = renderer->defaultSize();
             qreal dx = size.width() / naturalSize.width();
             qreal dy = size.height() / naturalSize.height();
 
-            return QRectF(elementRect.x() * dx, elementRect.y() * dy,
-                         elementRect.width() * dx, elementRect.height() * dy);
+            elementRect = QRectF(elementRect.x() * dx, elementRect.y() * dy,
+                                 elementRect.width() * dx, elementRect.height() * dy);
+            elementRects[elementId] = elementRect;
+            return elementRect;
         }
 
         QMatrix matrixForElement(const QString &elementId)
@@ -266,6 +264,8 @@
                 return;
             }
 
+            elementRects.clear();
+
             QString newPath = Theme::defaultTheme()->imagePath(themePath);
 
             if (path == newPath) {
@@ -308,6 +308,7 @@
         QString themePath;
         QString path;
         QList<QString> ids;
+        QHash<QString, QRectF> elementRects;
         QSizeF size;
         bool multipleImages;
         bool themed;
@@ -371,12 +372,14 @@
 
 void Svg::resize(const QSizeF &size)
 {
+    d->elementRects.clear();
     d->createRenderer();
     d->size = size;
 }
 
 void Svg::resize()
 {
+    d->elementRects.clear();
     d->createRenderer();
     d->size = d->renderer->defaultSize();
 }
@@ -393,8 +396,12 @@
 
 bool Svg::hasElement(const QString &elementId) const
 {
-    d->createRenderer();
-    return d->renderer->elementExists(elementId);
+    if (d->elementRects.contains(elementId)) {
+        return true;
+    } else {
+        d->elementRect(elementId);
+        return d->elementRects.contains(elementId);
+    }
 }
 
 QString Svg::elementAtPoint(const QPoint &point) const
_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to