From 018665d7a3ae8cb642880176d415f57fc178c299 Mon Sep 17 00:00:00 2001
From: rathnor <rathnor>
Date: Thu, 9 Oct 2003 16:48:09 +0000
Subject: drawing optimisations and fixes

---
 ChangeLog                |  6 +++++
 src/Container.cc         |  8 +++---
 src/FbTk/Color.hh        | 12 ++++-----
 src/FbTk/GContext.cc     | 64 ++++++++----------------------------------------
 src/FbTk/GContext.hh     | 63 +++++++++++++++++++++++++++++++++++------------
 src/FbTk/ImageControl.cc | 29 ++++++++++++++++++----
 src/FbTk/ImageControl.hh | 21 ++++++++++++++--
 src/FbWinFrame.cc        | 13 ++++++----
 src/IconbarTool.cc       |  8 +++---
 src/fluxbox.cc           |  9 ++++---
 10 files changed, 135 insertions(+), 98 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c8ba7fb..e8ef7ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 (Format: Year/Month/Day)
 Changes for 0.9.6:
+*03/10/10:
+  * Various drawing-related optimisations and bug fixes (Simon)
+    - fixes toolbar random colour flicker on workspace change
+    - speeds up pixmap rendering a little (inlining and friends!)
+    FbWinFrame.cc GContext.hh/cc Color.hh ImageControl.hh/cc 
+    IconbarTool.cc fluxbox.cc Container.cc
 *03/10/08:
   * fluxbox-generate_menu update from Han
     - replace getopts with portable workaround
diff --git a/src/Container.cc b/src/Container.cc
index d1d9fd7..5b985eb 100644
--- a/src/Container.cc
+++ b/src/Container.cc
@@ -20,7 +20,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Container.cc,v 1.4 2003/09/15 20:13:24 fluxgen Exp $
+// $Id: Container.cc,v 1.5 2003/10/09 16:48:09 rathnor Exp $
 
 #include "FbTk/Button.hh"
 #include "Container.hh"
@@ -128,7 +128,8 @@ void Container::removeItem(int index) {
 void Container::removeAll() {
     m_selected = 0;
     m_item_list.clear();
-    clear();
+    if (!m_update_lock)
+        clear();
 
 }
 
@@ -162,7 +163,8 @@ void Container::setSelected(int pos) {
 }
 
 void Container::exposeEvent(XExposeEvent &event) {
-    clearArea(event.x, event.y, event.width, event.height);
+    if (!m_update_lock)
+        clearArea(event.x, event.y, event.width, event.height);
 }
 
 void Container::repositionItems() {
diff --git a/src/FbTk/Color.hh b/src/FbTk/Color.hh
index f9c1600..b699dcc 100644
--- a/src/FbTk/Color.hh
+++ b/src/FbTk/Color.hh
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Color.hh,v 1.4 2003/05/10 13:29:13 fluxgen Exp $
+// $Id: Color.hh,v 1.5 2003/10/09 16:48:09 rathnor Exp $
 
 #ifndef FBTK_COLOR_HH
 #define FBTK_COLOR_HH
@@ -49,11 +49,11 @@ public:
     // TODO
     //Color &operator = (const Color &col_copy);
 	
-    bool isAllocated() const { return m_allocated; }
-    unsigned short red() const { return m_red; }
-    unsigned short green() const { return m_green; }
-    unsigned short blue() const { return m_blue; }
-    unsigned long pixel() const { return m_pixel; }
+    inline bool isAllocated() const { return m_allocated; }
+    inline unsigned short red() const { return m_red; }
+    inline unsigned short green() const { return m_green; }
+    inline unsigned short blue() const { return m_blue; }
+    inline unsigned long pixel() const { return m_pixel; }
 	
 private:
     void free();
diff --git a/src/FbTk/GContext.cc b/src/FbTk/GContext.cc
index f3fcaf4..6b41726 100644
--- a/src/FbTk/GContext.cc
+++ b/src/FbTk/GContext.cc
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: GContext.cc,v 1.3 2003/09/11 19:57:38 fluxgen Exp $
+// $Id: GContext.cc,v 1.4 2003/10/09 16:48:09 rathnor Exp $
 
 #include "GContext.hh"
 
@@ -32,74 +32,30 @@
 namespace FbTk {
 
 GContext::GContext(const FbTk::FbDrawable &drawable): 
-    m_gc(XCreateGC(FbTk::App::instance()->display(),
+    m_display(FbTk::App::instance()->display()),     
+    m_gc(XCreateGC(m_display,
                    drawable.drawable(),
                    0, 0)) {
     setGraphicsExposure(false);
 }
 
 GContext::GContext(Drawable drawable):
-    m_gc(XCreateGC(FbTk::App::instance()->display(),
+    m_display(FbTk::App::instance()->display()), 
+    m_gc(XCreateGC(m_display,
                    drawable,
-                   0, 0)) {
+                   0, 0))
+{
     setGraphicsExposure(false);
 }
 
 GContext::~GContext() {
     if (m_gc)
-        XFreeGC(FbTk::App::instance()->display(), m_gc);
-}
-
-void GContext::setForeground(const FbTk::Color &color) {
-    setForeground(color.pixel());
-}
-
-void GContext::setForeground(long pixel_value) {
-    XSetForeground(FbTk::App::instance()->display(), m_gc,
-                   pixel_value);
-}
-
-void GContext::setBackground(const FbTk::Color &color) {
-    setBackground(color.pixel());
-}
-
-void GContext::setBackground(long pixel_value) {
-    XSetBackground(FbTk::App::instance()->display(), m_gc,
-                   pixel_value);
+        XFreeGC(m_display, m_gc);
 }
 
 /// not implemented!
-void GContext::setFont(const FbTk::Font &font) {
+//void GContext::setFont(const FbTk::Font &font) {
     //!! TODO
-}
-
-void GContext::setFont(int fid) {
-    XSetFont(FbTk::App::instance()->display(), m_gc, fid);
-}
-void GContext::setClipMask(const FbTk::FbPixmap &mask) {
-    XSetClipMask(FbTk::App::instance()->display(), m_gc,
-                 mask.drawable());
-}
-
-void GContext::setClipOrigin(int x, int y) {
-    XSetClipOrigin(FbTk::App::instance()->display(), m_gc,
-                   x, y);
-}
-
-void GContext::setGraphicsExposure(bool flag) {
-    XSetGraphicsExposures(FbTk::App::instance()->display(), m_gc, 
-                          flag);
-}
-
-void GContext::setFunction(int func) {
-    XSetFunction(FbTk::App::instance()->display(), m_gc,
-                 func);
-}
-
-void GContext::setSubwindowMode(int mode) {
-    XSetSubwindowMode(FbTk::App::instance()->display(), m_gc,
-                      mode);
-}
-
+//}
 
 } // end namespace FbTk
diff --git a/src/FbTk/GContext.hh b/src/FbTk/GContext.hh
index 6175b2d..c192879 100644
--- a/src/FbTk/GContext.hh
+++ b/src/FbTk/GContext.hh
@@ -19,19 +19,20 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: GContext.hh,v 1.3 2003/09/11 19:57:38 fluxgen Exp $
+// $Id: GContext.hh,v 1.4 2003/10/09 16:48:09 rathnor Exp $
 
 #ifndef FBTK_GCONTEXT_HH
 #define FBTK_GCONTEXT_HH
 
+#include "Color.hh"
+#include "FbPixmap.hh"
+
 #include <X11/Xlib.h>
 
 namespace FbTk {
 
 class FbDrawable;
-class FbPixmap;
 class Font;
-class Color;
 
 /// wrapper for X GC
 class GContext {
@@ -43,23 +44,55 @@ public:
 
     virtual ~GContext();
 
-    void setForeground(const FbTk::Color &color);
-    void setForeground(long pixel_value);
-    void setBackground(const FbTk::Color &color);
-    void setBackground(long pixel_value);
+    inline void setForeground(const FbTk::Color &color) {
+        setForeground(color.pixel());
+    }
+
+    inline void setForeground(long pixel_value) {
+        XSetForeground(m_display, m_gc,
+                       pixel_value);
+    }
+
+    inline void setBackground(const FbTk::Color &color) {
+        setBackground(color.pixel());
+    }
+
+    inline void setBackground(long pixel_value) {
+        XSetBackground(m_display, m_gc, pixel_value);
+    }
+
     /// not implemented
-    void setFont(const FbTk::Font &font);
+    inline void setFont(const FbTk::Font &font) {}
+
     /// set font id
-    void setFont(int fid);
-    void setClipMask(const FbTk::FbPixmap &pm);
-    void setClipOrigin(int x, int y);
-    void setGraphicsExposure(bool value);
-    void setFunction(int func);
-    void setSubwindowMode(int mode);
+    inline void setFont(int fid) {
+        XSetFont(m_display, m_gc, fid);
+    }
+
+    inline void setClipMask(const FbTk::FbPixmap &mask) {
+        XSetClipMask(m_display, m_gc, mask.drawable());
+    }
+
+    inline void setClipOrigin(int x, int y) {
+        XSetClipOrigin(m_display, m_gc, x, y);
+    }
+
+    inline void setGraphicsExposure(bool value) {
+        XSetGraphicsExposures(m_display, m_gc, value);
+    }
+
+    inline void setFunction(int func) {
+        XSetFunction(m_display, m_gc, func);
+    }
+
+    inline void setSubwindowMode(int mode) {
+        XSetSubwindowMode(m_display, m_gc, mode);
+    }
 
-    GC gc() const { return m_gc; }
+    inline GC gc() const { return m_gc; }
 
 private:
+    Display *m_display; // worth caching
     GC m_gc;
 };
 
diff --git a/src/FbTk/ImageControl.cc b/src/FbTk/ImageControl.cc
index 915dc1c..2ceb106 100644
--- a/src/FbTk/ImageControl.cc
+++ b/src/FbTk/ImageControl.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: ImageControl.cc,v 1.5 2003/08/18 11:37:14 fluxgen Exp $
+// $Id: ImageControl.cc,v 1.6 2003/10/09 16:48:09 rathnor Exp $
 
 #include "ImageControl.hh"
 
@@ -152,6 +152,21 @@ ImageControl::~ImageControl() {
 Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
                                   unsigned long texture_type,
                                   const FbTk::Color &color, const FbTk::Color &color_to) const {
+    Cache tmp;
+    tmp.width = width;
+    tmp.height = height;
+    tmp.texture = texture_type;
+    tmp.pixel1 = color.pixel();
+    tmp.pixel2 = color_to.pixel();
+    CacheList::iterator it = cache.find(&tmp);
+    if (it == cache.end()) {
+        return None;
+    } else {
+        (*it)->count++;
+        return (*it)->pixmap;
+    }
+        
+    /*
     CacheList::iterator it = cache.begin();
     CacheList::iterator it_end = cache.end();
     for (; it != it_end; ++it) {
@@ -170,8 +185,8 @@ Pixmap ImageControl::searchCache(unsigned int width, unsigned int height,
             }
         }
     }
-
     return None;
+    */
 }
 
 
@@ -187,7 +202,7 @@ Pixmap ImageControl::renderImage(unsigned int width, unsigned int height,
     if (pixmap)
         return pixmap; // return cache item
 
-	// render new image
+    // render new image
     TextureRender image(*this, width, height, m_colors, m_num_colors);
     pixmap = image.render(texture);
 
@@ -208,7 +223,7 @@ Pixmap ImageControl::renderImage(unsigned int width, unsigned int height,
         else
             tmp->pixel2 = 0l;
 
-        cache.push_back(tmp); 
+        cache.insert(tmp); 
 
         if ((unsigned) cache.size() > cache_max)
             cleanCache();
@@ -355,9 +370,13 @@ void ImageControl::cleanCache() {
         Cache *tmp = (*it);
 
         if (tmp->count <= 0) {
+            CacheList::iterator tmp_it = it;
+            ++tmp_it;
             XFreePixmap(disp, tmp->pixmap);
-            it = cache.erase(it);
+            cache.erase(it);
             delete tmp;
+            tmp=0;
+            it = tmp_it;
             if (it == it_end) break;
         }
     }
diff --git a/src/FbTk/ImageControl.hh b/src/FbTk/ImageControl.hh
index c43c5a0..29c43d6 100644
--- a/src/FbTk/ImageControl.hh
+++ b/src/FbTk/ImageControl.hh
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: ImageControl.hh,v 1.4 2003/08/18 11:37:15 fluxgen Exp $
+// $Id: ImageControl.hh,v 1.5 2003/10/09 16:48:09 rathnor Exp $
 
 #ifndef	 FBTK_IMAGECONTROL_HH
 #define	 FBTK_IMAGECONTROL_HH
@@ -34,6 +34,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <list>
+#include <set>
 
 namespace FbTk {
 
@@ -114,9 +115,25 @@ private:
         unsigned int count, width, height;
         unsigned long pixel1, pixel2, texture;
     } Cache;
+
+    struct ltCacheEntry
+    {
+        bool operator()(const Cache* s1, const Cache* s2) const
+            {
+                return 
+                    (s1->width  < s2->width  || s1->width == s2->width && 
+                    (s1->height < s2->height || s1->height == s2->height &&
+                     (s1->texture < s2->texture || s1->texture == s2->texture &&
+                      s1->pixel1 < s2->pixel1 || s1->pixel1 == s2->pixel2 &&
+                      (s1->texture & FbTk::Texture::GRADIENT) &&
+                       s1->pixel2 < s2->pixel2)
+                        ));
+            }
+    };
+
 	
     unsigned long cache_max;
-    typedef std::list<Cache *> CacheList;
+    typedef std::set<Cache *, ltCacheEntry> CacheList;
 
     mutable CacheList cache;
     static bool s_timed_cache;
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc
index 09ce28e..ccbcaed 100644
--- a/src/FbWinFrame.cc
+++ b/src/FbWinFrame.cc
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: FbWinFrame.cc,v 1.58 2003/10/06 09:28:35 rathnor Exp $
+// $Id: FbWinFrame.cc,v 1.59 2003/10/09 16:48:09 rathnor Exp $
 
 #include "FbWinFrame.hh"
 
@@ -238,8 +238,8 @@ void FbWinFrame::setFocus(bool newvalue) {
 
     m_focused = newvalue;
 
-    renderTitlebar();
     renderButtons();
+    renderTitlebar();
     renderHandles();
 }
 
@@ -726,10 +726,10 @@ void FbWinFrame::redrawTitle() {
     }
 
     if (isVisible()) {
-        m_titlebar.clear();
-        m_titlebar.updateTransparent();
         m_label.clear();
         m_label.updateTransparent();
+        m_titlebar.clear();
+        m_titlebar.updateTransparent();
     }
 }
 
@@ -1004,6 +1004,7 @@ void FbWinFrame::setupButton(FbTk::Button &btn) {
 
 void FbWinFrame::render(const FbTk::Texture &tex, FbTk::Color &col, Pixmap &pm,
                         unsigned int w, unsigned int h) {
+
     Pixmap tmp = pm;
     if (tex.type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
         pm = None;
@@ -1051,6 +1052,7 @@ void FbWinFrame::getUnfocusPixmap(Pixmap &label_pm, Pixmap &title_pm,
 }
 
 void FbWinFrame::renderLabelButtons() {
+
     Pixmap label_pm = 0;
     Pixmap not_used_pm = 0;
     FbTk::Color label_color;
@@ -1126,7 +1128,8 @@ void FbWinFrame::renderButtonFocus(FbTk::TextButton &button) {
 }
 
 void FbWinFrame::renderButtonUnfocus(FbTk::TextButton &button) {
-   button.setGC(theme().labelTextUnfocusGC());
+
+    button.setGC(theme().labelTextUnfocusGC());
     button.setJustify(theme().justify());
     button.setBorderWidth(1);
     button.setAlpha(theme().alpha());
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc
index 34ca188..ee0d7cf 100644
--- a/src/IconbarTool.cc
+++ b/src/IconbarTool.cc
@@ -20,7 +20,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: IconbarTool.cc,v 1.13 2003/10/06 06:22:42 rathnor Exp $
+// $Id: IconbarTool.cc,v 1.14 2003/10/09 16:48:09 rathnor Exp $
 
 #include "IconbarTool.hh"
 
@@ -372,11 +372,11 @@ void IconbarTool::update(FbTk::Subject *subj) {
     }
 
     // unlock container and update graphics
+    renderTheme();
     m_icon_container.setUpdateLock(false);
-    m_icon_container.showSubwindows();
     m_icon_container.update();
-
-    renderTheme();
+    m_icon_container.showSubwindows();
+    
 }
 
 void IconbarTool::renderWindow(FluxboxWindow &win) {
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 957ea15..45ec6e7 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: fluxbox.cc,v 1.197 2003/10/06 09:55:36 rathnor Exp $
+// $Id: fluxbox.cc,v 1.198 2003/10/09 16:48:09 rathnor Exp $
 
 #include "fluxbox.hh"
 
@@ -614,10 +614,11 @@ Fluxbox::~Fluxbox() {
 }
 
 void Fluxbox::eventLoop() {
+    Display *disp = display();
     while (!m_shutdown) {
-        if (XPending(display())) {
+        if (XPending(disp)) {
             XEvent e;
-            XNextEvent(display(), &e);
+            XNextEvent(disp, &e);
 
             if (last_bad_window != None && e.xany.window == last_bad_window && 
                 e.type != DestroyNotify) { // we must let the actual destroys through
@@ -633,7 +634,7 @@ void Fluxbox::eventLoop() {
                 }
             }
         } else {
-            FbTk::Timer::updateTimers(ConnectionNumber(display())); //handle all timers
+            FbTk::Timer::updateTimers(ConnectionNumber(disp)); //handle all timers
         }
     }
 }
-- 
cgit v0.11.2