[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    koffice/krita/ui
From:       Cyrille Berger <cyb () lepi ! org>
Date:       2010-11-11 23:02:30
Message-ID: 20101111230230.4B10EAC89E () svn ! kde ! org
[Download RAW message or body]

SVN commit 1195758 by berger:

Compute preview of filters in threads. This fix UI blocking issues.

BUG: 243691


 M  +41 -3     kis_bookmarked_filter_configurations_model.cc  
 M  +3 -0      kis_bookmarked_filter_configurations_model.h  
 M  +39 -9     kis_filters_model.cc  
 M  +3 -0      kis_filters_model.h  


--- trunk/koffice/krita/ui/kis_bookmarked_filter_configurations_model.cc \
#1195757:1195758 @@ -17,7 +17,11 @@
  */
 
 #include "kis_bookmarked_filter_configurations_model.h"
+
+#include <QFutureWatcher>
 #include <QPixmap>
+#include <QSignalMapper>
+#include <QtConcurrentRun>
 
 #include <filter/kis_filter.h>
 #include <filter/kis_filter_configuration.h>
@@ -27,6 +31,8 @@
     KisPaintDeviceSP thumb;
     KisFilterSP filter;
     QHash<int, QImage> previewCache;
+    QSignalMapper* previewCacheWatcher;
+    QHash<int, QFutureWatcher<QImage>*> previewCacheFutureWatcher;
 };
 
 KisBookmarkedFilterConfigurationsModel::KisBookmarkedFilterConfigurationsModel(KisPaintDeviceSP \
thumb, KisFilterSP filter) @@ -34,23 +40,45 @@
 {
     d->thumb = thumb;
     d->filter = filter;
+    d->previewCacheWatcher = new QSignalMapper(this);
+    connect(d->previewCacheWatcher, SIGNAL(mapped(int)), SLOT(previewUpdated(int)));
 }
 
 KisBookmarkedFilterConfigurationsModel::~KisBookmarkedFilterConfigurationsModel()
 {
+    foreach(QFutureWatcher<QImage>* watcher, d->previewCacheFutureWatcher)
+    {
+      watcher->cancel();
+      delete watcher;
+    }
     delete d;
 }
 
+QImage generatePreview(const KisFilter* filter, KisPaintDeviceSP thumb, \
KisFilterConfiguration* config) +{
+    KisPaintDeviceSP target = new KisPaintDevice(*thumb);
+    filter->process(target, QRect(0, 0, 100, 100), config);
+    return target->convertToQImage(0);
+}
+
 QVariant KisBookmarkedFilterConfigurationsModel::data(const QModelIndex &index, int \
role) const  {
     if (!index.isValid()) {
         return QVariant();
     }
     if (role == Qt::DecorationRole) {
+        if (!flags(index).testFlag(Qt::ItemIsEnabled)) return QVariant();
         if (!d->previewCache.contains(index.row())) {
-            KisPaintDeviceSP target = new KisPaintDevice(*d->thumb);
-            d->filter->process(target, QRect(0, 0, 100, 100), configuration(index));
-            d->previewCache[index.row()] = target->convertToQImage(0);
+            
+            QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>();
+            connect(watcher, SIGNAL(finished()), d->previewCacheWatcher, \
SLOT(map())); +            watcher->setFuture(QtConcurrent::run(generatePreview, \
d->filter, d->thumb, configuration(index))); +            
+            d->previewCacheWatcher->setMapping(watcher, index.row());
+            
+            d->previewCacheFutureWatcher[index.row()] = watcher;
+            
+            d->previewCache[index.row()] = QImage();
         }
         return d->previewCache[index.row()];
     } else {
@@ -64,3 +92,13 @@
     if (config) return config;
     return d->filter->defaultConfiguration(d->thumb);
 }
+
+void KisBookmarkedFilterConfigurationsModel::previewUpdated(int i)
+{
+  d->previewCache[i] = d->previewCacheFutureWatcher[i]->result();
+  delete d->previewCacheFutureWatcher[i];
+  d->previewCacheFutureWatcher.remove(i);
+  emit dataChanged(createIndex(i,0), createIndex(i,0));
+}
+
+#include "kis_bookmarked_filter_configurations_model.moc"
--- trunk/koffice/krita/ui/kis_bookmarked_filter_configurations_model.h \
#1195757:1195758 @@ -30,6 +30,7 @@
  */
 class KisBookmarkedFilterConfigurationsModel : public \
KisBookmarkedConfigurationsModel  {
+    Q_OBJECT
 public:
     /**
      * @param thumb a 100x100 thumbnail used to preview the filters
@@ -46,6 +47,8 @@
      * @return the filter configuration
      */
     KisFilterConfiguration* configuration(const QModelIndex &index) const;
+private slots:
+    void previewUpdated(int i);
 private:
     struct Private;
     Private* const d;
--- trunk/koffice/krita/ui/kis_filters_model.cc #1195757:1195758
@@ -20,7 +20,11 @@
  */
 
 #include "kis_filters_model.h"
+
+#include <QFutureWatcher>
 #include <QPixmap>
+#include <QSignalMapper>
+#include <QtConcurrentRun>
 
 #include <filter/kis_filter.h>
 #include <filter/kis_filter_registry.h>
@@ -66,6 +70,9 @@
     QList<QString> categoriesKeys;
     KisPaintDeviceSP thumb;
     QHash<const KisFilter*, QImage> previewCache;
+    QSignalMapper* previewCacheWatcher;
+    QHash<int, QFutureWatcher<QImage>*> previewCacheFutureWatcher;
+    QHash<int, const KisFilter*> filterToWatcher;
 };
 
 KisFiltersModel::KisFiltersModel(KisPaintDeviceSP thumb) : d(new Private)
@@ -88,6 +95,8 @@
         d->categories[ filter->menuCategory().id()].filters.append(filt);
     }
     qSort(d->categoriesKeys);
+    d->previewCacheWatcher = new QSignalMapper(this);
+    connect(d->previewCacheWatcher, SIGNAL(mapped(int)), SLOT(previewUpdated(int)));
 }
 
 KisFiltersModel::~KisFiltersModel()
@@ -159,6 +168,13 @@
     return QModelIndex(); // categories don't have parents
 }
 
+QImage generatePreview(const KisFilter* filter, KisPaintDeviceSP thumb)
+{
+    KisPaintDeviceSP target = new KisPaintDevice(*thumb);
+    filter->process(target, QRect(0, 0, 100, 100), \
filter->defaultConfiguration(thumb)); +    return target->convertToQImage(0);
+}
+
 QVariant KisFiltersModel::data(const QModelIndex &index, int role) const
 {
     if (index.isValid()) {
@@ -167,17 +183,20 @@
             Private::Filter* filter = dynamic_cast<Private::Filter*>(node);
             if (filter) {
                 if (!d->previewCache.contains(filter->filter)) {
-                    KisPaintDeviceSP target = new KisPaintDevice(*d->thumb);
 
-                    QRect rc = target->exactBounds();
-                    dbgUI << "Previewing " << filter->name << " on: " << rc;
-                    KisConstProcessingInformation cpi(d->thumb, rc.topLeft());
-                    KisProcessingInformation cp(target, rc.topLeft());
+                    QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>();
+                    connect(watcher, SIGNAL(finished()), d->previewCacheWatcher, \
SLOT(map())); +                    \
watcher->setFuture(QtConcurrent::run(generatePreview, filter->filter, d->thumb));  
-                    filter->filter->process(cpi, cp, rc.size()/*QSize(100, 100)*/, \
                filter->filter->defaultConfiguration(d->thumb));
-                    dbgUI << "Resulting in: " << target->exactBounds();
-                    d->previewCache[ filter->filter ] = target->convertToQImage(0);
-                    dbgUI << "And in a qimage of size: " << d->previewCache[ \
filter->filter ].rect(); +                    int filterToWatcherId = \
d->filterToWatcher.count(); +                    
+                    d->filterToWatcher[filterToWatcherId] = filter->filter;
+                    
+                    d->previewCacheWatcher->setMapping(watcher, filterToWatcherId);
+                    
+                    d->previewCacheFutureWatcher[filterToWatcherId] = watcher;
+                    
+                    d->previewCache[filter->filter] = QImage();
                 }
                 return d->previewCache[ filter->filter ];
             } else {
@@ -203,3 +222,14 @@
         return Qt::ItemIsEnabled;
     }
 }
+
+void KisFiltersModel::previewUpdated(int i)
+{
+  const KisFilter* filter = d->filterToWatcher[i];
+  d->previewCache[filter] = d->previewCacheFutureWatcher[i]->result();
+  delete d->previewCacheFutureWatcher[i];
+  d->previewCacheFutureWatcher.remove(i);
+  emit dataChanged(indexForFilter(filter->id()), indexForFilter(filter->id()));
+}
+
+#include "kis_filters_model.moc"
--- trunk/koffice/krita/ui/kis_filters_model.h #1195757:1195758
@@ -33,6 +33,7 @@
  */
 class KisFiltersModel : public QAbstractItemModel
 {
+    Q_OBJECT
 public:
     KisFiltersModel(KisPaintDeviceSP thumb);
     ~KisFiltersModel();
@@ -44,6 +45,8 @@
     virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
     virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) \
const;  virtual Qt::ItemFlags flags(const QModelIndex & index) const;
+private slots:
+    void previewUpdated(int i);
 private:
     struct Private;
     Private* const d;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic