On Thursday 16 October 2008, Aaron J. Seigo wrote:
> On Wednesday 15 October 2008, Marco Martin wrote:
> > On Wednesday 15 October 2008, Aaron J. Seigo wrote:
> > > On Wednesday 15 October 2008, Marco Martin wrote:
> > > > with a kconfigroup? would make sense?
> > >
> > > it's the easy answer, so i'd say: "let's go for it".
> > >
> > > we can benchmark it once it is in place and working. changing the cache
> > > implementation will be an easy task after we have it there in the first
> > > place.
> > >
> > > i'll commit my changes shortly here then, once i figure out the problem
> > > with the applet backgrounds
> >
> > still very rough and probably wrong in many points posting here because
> > i'm too tired right now to think, probably tomorrow will come up with a
> > slightly better version :)
> >
> > Cheers,
> > Marco Martin
>
> it's a good start =) some (probably fatigue induced) issues like:
>
> + ? ? ? ? ? ?if (!found) {
> + ? ? ? ? ? ? ? ?return QRect();
> + ? ? ? ? ? ?} else if (rect.isValid()) {
> + ? ? ? ? ? ? ? ?return rect;
> + ? ? ? ? ? ?}
> +
>
> should probably be:
>
> if (found && rect.isValid()) {
>      return rect
> }

uhm, i think it's right at least how findInRectsCache work, because right now 
it returns false only when we are sure the element does not exist, so when is 
true and the rect not valid is still to be checked...
i know it's not intuitive, but don't know how to make it more intuitive, we 
would need a new boolean type with true, false and "who knows" values :) (well 
for cache hits could make sense, we could even do it... like InCache 
NotInCache and NotExistent)

> though even then ... it might not be worth checking if isValid() so non-
> existent elements would also be covered.
>
> but yeah, you're on the right track ... once this is in i'll do some more
> measurements and see where we get =)
>
> i'm also going to make the Image wallpaper plugin use a (separate) cache as
> well i think so we don't have to re-process the wallpaper images everytime.
> i also think i'm going to try to make the Image wallpaper plugin use fewer
> threads when more than one is loaded....


Index: theme.h
===================================================================
--- theme.h	(revision 872133)
+++ theme.h	(working copy)
@@ -192,6 +192,10 @@
          **/
         void insertIntoCache(const QString& key, const QPixmap& pix);
 
+        bool findInRectsCache(const QString &image, const QString &element, QRectF &rect) const;
+        void insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect);
+        void invalidateRectsCache(const QString& image);
+
     Q_SIGNALS:
         /**
          * Emitted when the user changes the theme. SVGs should be reloaded at
Index: svg.cpp
===================================================================
--- svg.cpp	(revision 872133)
+++ svg.cpp	(working copy)
@@ -81,6 +81,12 @@
         {
             bool isThemed = !QDir::isAbsolutePath(imagePath);
 
+            if (isThemed == themed &&
+                ((themed && themePath == imagePath) ||
+                 (!themed && path == imagePath))) {
+                return false;
+            }
+
             // lets check to see if we're already set to this file
             if (isThemed == themed &&
                 ((themed && themePath == imagePath) ||
@@ -218,32 +224,31 @@
 
         QSize elementSize(const QString &elementId)
         {
-            createRenderer();
-
-            if (!renderer->elementExists(elementId)) {
-                return QSize(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();
+            return elementRect(elementId).size().toSize();
         }
 
         QRectF elementRect(const QString &elementId)
         {
+            QRectF rect;
+            bool found = Theme::defaultTheme()->findInRectsCache(themePath, elementId, rect);
+
+            if (!found) {
+                return QRect();
+            } else if (rect.isValid()) {
+                return rect;
+            }
+
             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);
+            Theme::defaultTheme()->insertIntoRectsCache(themePath, elementId, elementRect);
+
+            return elementRect;
         }
 
         QMatrix matrixForElement(const QString &elementId)
@@ -376,11 +381,14 @@
 
 void Svg::resize(const QSizeF &size)
 {
+    Theme::defaultTheme()->invalidateRectsCache(d->themePath);
     d->size = size;
 }
 
 void Svg::resize()
 {
+    Theme::defaultTheme()->invalidateRectsCache(d->themePath);
+
     if (d->renderer) {
         d->size = d->renderer->defaultSize();
     } else {
@@ -400,12 +408,16 @@
 
 bool Svg::hasElement(const QString &elementId) const
 {
+    QRectF elementRect;
+
     if (d->path.isNull() && d->themePath.isNull()) {
         return false;
+    } else if ( !Theme::defaultTheme()->findInRectsCache(d->themePath, elementId, elementRect)) {
+        return false;
+    } else {
+        d->createRenderer();
+        return d->renderer->elementExists(elementId);
     }
-
-    d->createRenderer();
-    return d->renderer->elementExists(elementId);
 }
 
 QString Svg::elementAtPoint(const QPoint &point) const
Index: theme.cpp
===================================================================
--- theme.cpp	(revision 872133)
+++ theme.cpp	(working copy)
@@ -110,6 +110,8 @@
     int defaultWallpaperWidth;
     int defaultWallpaperHeight;
     KPixmapCache pixmapCache;
+    KSharedConfigPtr svgElementsCache;
+    QHash<QString, QList<QString> > invalidElements;
 
 #ifdef Q_WS_X11
     KSelectionWatcher *compositeWatch;
@@ -297,6 +299,11 @@
         }
     }
 
+
+    QString svgElementsFile = KStandardDirs::locateLocal("cache", "plasma-svgelements-"+themeName);
+    d->invalidElements.clear();
+    d->svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
+
     emit themeChanged();
 }
 
@@ -492,6 +499,38 @@
     d->pixmapCache.insert(key, pix);
 }
 
+bool Theme::findInRectsCache(const QString &image, const QString &element, QRectF &rect) const
+{
+    KConfigGroup imageGroup(d->svgElementsCache, image);
+    rect = imageGroup.readEntry(element, QRectF());
+
+    if (!d->invalidElements.contains(image)) {
+        d->invalidElements[image] = imageGroup.readEntry("invalidGroups", QStringList());
+    }
+
+    return !d->invalidElements[image].contains(element);
 }
 
+void Theme::insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect)
+{
+    KConfigGroup imageGroup(d->svgElementsCache, image);
+    if (rect.isValid()) {
+        imageGroup.writeEntry(element, rect);
+    } else {
+        d->invalidElements[image].append(element);
+        if (d->invalidElements[image].count() > 1000) {
+            d->invalidElements[image].pop_front();
+        }
+        imageGroup.writeEntry("invalidElements", d->invalidElements[image]);
+    }
+}
+
+void Theme::invalidateRectsCache(const QString& image)
+{
+    KConfigGroup imageGroup(d->svgElementsCache, image);
+    imageGroup.deleteGroup();
+}
+
+}
+
 #include <theme.moc>
_______________________________________________
Plasma-devel mailing list
Plasma-devel@kde.org
https://mail.kde.org/mailman/listinfo/plasma-devel

Reply via email to