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

List:       kde-commits
Subject:    koffice/krita/image
From:       Dmitry Kazakov <dimula73 () gmail ! com>
Date:       2010-10-26 16:55:04
Message-ID: 20101026165504.ABEA6AC899 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1190024 by dkazakov:

Made good cache for KisMask's projection

Usage of a QThreadStorage was a bad idea, because it works badly in
case the lifetime of an object is shorter that a lifetime of a
thread (the storage data leaks in the case).So i decided to use our
own KisLocklessStack for this purpose.

BUG:249343


 M  +22 -16    kis_mask.cc  


--- trunk/koffice/krita/image/kis_mask.cc #1190023:1190024
@@ -34,32 +34,33 @@
 #include "kis_image.h"
 #include "kis_layer.h"
 
+#include "tiles3/kis_lockless_stack.h"
+
 struct KisMask::Private {
-    class PerThreadPaintDevice {
+    class CachedPaintDevice {
     public:
-        KisPaintDeviceSP device(KisPaintDeviceSP projection) {
-            if(!m_storage.hasLocalData()) {
-                // XXX: this leaks!
-                m_storage.setLocalData(new KisPaintDeviceSP(new \
KisPaintDevice(projection->colorSpace()))); +        KisPaintDeviceSP \
getDevice(KisPaintDeviceSP prototype) { +            KisPaintDeviceSP device;
+
+            if(!m_stack.pop(device)) {
+                device = new KisPaintDevice(prototype->colorSpace());
             }
-            KisPaintDeviceSP device = *m_storage.localData();
-            device->prepareClone(projection);
 
+            device->prepareClone(prototype);
             return device;
         }
 
-        ~PerThreadPaintDevice() {
-            // In case current thread used the storage too...
-            if(m_storage.hasLocalData()) {
-                m_storage.setLocalData(0);
+        void putDevice(KisPaintDeviceSP device) {
+            device->clear();
+            m_stack.push(device);
             }
-        }
+
     private:
-        QThreadStorage<KisPaintDeviceSP *> m_storage;
+        KisLocklessStack<KisPaintDeviceSP> m_stack;
     };
 
     mutable KisSelectionSP selection;
-    PerThreadPaintDevice paintDeviceCache;
+    CachedPaintDevice paintDeviceCache;
 };
 
 KisMask::KisMask(const QString & name)
@@ -195,7 +196,7 @@
         if(!m_d->selection->selectedRect().intersects(rc))
             return;
 
-        KisPaintDeviceSP cacheDevice = m_d->paintDeviceCache.device(projection);
+        KisPaintDeviceSP cacheDevice = m_d->paintDeviceCache.getDevice(projection);
 
         QRect updatedRect = decorateRect(projection, cacheDevice, rc);
 
@@ -204,13 +205,18 @@
         gc.setOpacity(opacity());
         gc.setSelection(m_d->selection);
         gc.bitBlt(updatedRect.topLeft(), cacheDevice, updatedRect);
+
+        m_d->paintDeviceCache.putDevice(cacheDevice);
+
     } else {
-        KisPaintDeviceSP cacheDevice = m_d->paintDeviceCache.device(projection);
+        KisPaintDeviceSP cacheDevice = m_d->paintDeviceCache.getDevice(projection);
         cacheDevice->makeCloneFromRough(projection, rc);
         projection->clear(rc);
 
         // FIXME: how about opacity and compositeOp?
         decorateRect(cacheDevice, projection, rc);
+
+        m_d->paintDeviceCache.putDevice(cacheDevice);
     }
 }
 


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

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