From 0348a2f3abd2334f5f5812c5fb45c1b4fffb46a5 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 20 Jan 2003 07:07:13 +0000 Subject: [PATCH] add rendercolor class, with a cache of gcs for the colors --- otk/.cvsignore | 1 + otk/Makefile.am | 2 +- otk/application.cc | 3 ++ otk/rendercolor.cc | 83 ++++++++++++++++++++++++++++++++++++++++ otk/rendercolor.hh | 45 ++++++++++++++++++++++ otk/surface.cc | 7 ++-- otk/surface.hh | 3 +- otk/truerendercontrol.cc | 5 ++- src/openbox.cc | 3 ++ 9 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 otk/rendercolor.cc create mode 100644 otk/rendercolor.hh diff --git a/otk/.cvsignore b/otk/.cvsignore index d46a65b5..3e85c1e5 100644 --- a/otk/.cvsignore +++ b/otk/.cvsignore @@ -37,3 +37,4 @@ rendertexture.lo rendertest renderstyle.lo rendercontrol.lo +rendercolor.lo diff --git a/otk/Makefile.am b/otk/Makefile.am index dd70fa79..643f4d2f 100644 --- a/otk/Makefile.am +++ b/otk/Makefile.am @@ -9,7 +9,7 @@ INCLUDES= -I../src noinst_LTLIBRARIES=libotk.la libotk_la_SOURCES=rendercontrol.cc truerendercontrol.cc surface.cc \ - rendertexture.cc renderstyle.cc \ + rendertexture.cc renderstyle.cc rendercolor.cc \ color.cc display.cc font.cc gccache.cc image.cc \ property.cc imagecontrol.cc rect.cc screeninfo.cc \ texture.cc timer.cc style.cc \ diff --git a/otk/application.cc b/otk/application.cc index f101a5a3..e325a582 100644 --- a/otk/application.cc +++ b/otk/application.cc @@ -9,6 +9,7 @@ #include "widget.hh" #include "timer.hh" #include "property.hh" +#include "rendercolor.hh" extern "C" { #ifdef HAVE_STDLIB_H @@ -32,6 +33,7 @@ Application::Application(int argc, char **argv) const ScreenInfo *s_info = _display.screenInfo(DefaultScreen(*_display)); Timer::initialize(); + RenderColor::initialize(); Property::initialize(); _img_ctrl = new ImageControl(s_info, True, 4, 5, 200); _style_conf = new Configuration(False); @@ -45,6 +47,7 @@ Application::~Application() delete _style_conf; delete _img_ctrl; delete _style; + RenderColor::destroy(); Timer::destroy(); } diff --git a/otk/rendercolor.cc b/otk/rendercolor.cc new file mode 100644 index 00000000..99dd3341 --- /dev/null +++ b/otk/rendercolor.cc @@ -0,0 +1,83 @@ +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif // HAVE_CONFIG_H + +#include "rendercolor.hh" +#include "display.hh" +#include "screeninfo.hh" + +namespace otk { + +std::map *RenderColor::_cache = 0; + +void RenderColor::initialize() +{ + _cache = new std::map[ScreenCount(**display)]; +} + +void RenderColor::destroy() +{ + delete [] _cache; +} + +RenderColor::RenderColor(int screen, unsigned char red, + unsigned char green, unsigned char blue) + : _screen(screen), + _red(red), + _green(green), + _blue(blue), + _gc(0) +{ + unsigned long color = _blue | _green << 8 | _red << 16; + + // try get a gc from the cache + CacheItem *item = _cache[_screen][color]; + + if (item) { + _gc = item->gc; + ++item->count; + } else { + XGCValues gcv; + + // allocate a color and GC from the server + const ScreenInfo *info = display->screenInfo(_screen); + + XColor xcol; // convert from 0-0xff to 0-0xffff + xcol.red = _red; xcol.red |= xcol.red << 8; + xcol.green = _green; xcol.green |= xcol.green << 8; + xcol.blue = _blue; xcol.blue |= xcol.blue << 8; + xcol.pixel = 0; + + if (! XAllocColor(**display, info->colormap(), &xcol)) { + fprintf(stderr, "RenderColor: color alloc error: rgb:%x/%x/%x\n", + _red, _green, _blue); + xcol.pixel = 0; + } + + gcv.foreground = xcol.pixel; + _gc = XCreateGC(**display, info->rootWindow(), GCForeground, &gcv); + assert(_gc); + + // insert into the cache + _cache[_screen][color] = new CacheItem(_gc); + } +} + +RenderColor::~RenderColor() +{ + unsigned long color = _blue | _green << 8 | _red << 16; + + CacheItem *item = _cache[_screen][color]; + assert(item); // it better be in the cache ... + + if (--item->count <= 0) { + // remove from the cache + XFreeGC(**display, _gc); + _cache[_screen][color] = 0; + delete item; + } +} + +} diff --git a/otk/rendercolor.hh b/otk/rendercolor.hh new file mode 100644 index 00000000..fbfe2aef --- /dev/null +++ b/otk/rendercolor.hh @@ -0,0 +1,45 @@ +// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- +#ifndef __rendercolor_hh +#define __rendercolor_hh + +extern "C" { +#include +} + +#include + +namespace otk { + +class RenderColor { + struct CacheItem { + GC gc; + int count; + CacheItem(GC g) : gc(g), count(0) {} + }; + static std::map *_cache; + + int _screen; + unsigned char _red; + unsigned char _green; + unsigned char _blue; + + GC _gc; + +public: + static void initialize(); + static void destroy(); + + RenderColor(int screen, unsigned char red, + unsigned char green, unsigned char blue); + virtual ~RenderColor(); + + inline int screen() const { return _screen; } + inline unsigned char red() const { return _red; } + inline unsigned char green() const { return _green; } + inline unsigned char blue() const { return _blue; } + inline GC gc() const { return _gc; } +}; + +} + +#endif // __rendercolor_hh diff --git a/otk/surface.cc b/otk/surface.cc index 99fa82b0..4f6ef386 100644 --- a/otk/surface.cc +++ b/otk/surface.cc @@ -7,7 +7,7 @@ #include "surface.hh" #include "display.hh" #include "screeninfo.hh" -#include "gccache.hh" +#include "rendercolor.hh" extern "C" { #include @@ -28,13 +28,12 @@ Surface::~Surface() destroyObjects(); } -void Surface::setPixmap(const Color &color) +void Surface::setPixmap(const RenderColor &color) { if (_pixmap == None) createObjects(); - Pen p(color); - XFillRectangle(**display, _pixmap, p.gc(), 0, 0, + XFillRectangle(**display, _pixmap, color.gc(), 0, 0, _size.x(), _size.y()); } diff --git a/otk/surface.hh b/otk/surface.hh index d325b393..18733517 100644 --- a/otk/surface.hh +++ b/otk/surface.hh @@ -14,6 +14,7 @@ extern "C" { namespace otk { class ScreenInfo; +class RenderColor; class Surface { int _screen; @@ -26,7 +27,7 @@ protected: void destroyObjects(); void setPixmap(XImage *image); - void setPixmap(const Color &color); + void setPixmap(const RenderColor &color); public: Surface(int screen, const Point &size); diff --git a/otk/truerendercontrol.cc b/otk/truerendercontrol.cc index bd413cff..dc52bc37 100644 --- a/otk/truerendercontrol.cc +++ b/otk/truerendercontrol.cc @@ -9,6 +9,8 @@ #include "screeninfo.hh" #include "surface.hh" +#include "rendercolor.hh" + extern "C" { #ifdef HAVE_STDLIB_H # include @@ -127,7 +129,8 @@ void TrueRenderControl::drawBackground(Surface& sf, im->data = (char*) data; - sf.setPixmap(im); +// sf.setPixmap(im); + sf.setPixmap(RenderColor(_screen, 0xff, 0xff, 0)); delete [] im->data; im->data = NULL; diff --git a/src/openbox.cc b/src/openbox.cc index 9642cd06..6436140d 100644 --- a/src/openbox.cc +++ b/src/openbox.cc @@ -14,6 +14,7 @@ #include "otk/assassin.hh" #include "otk/property.hh" #include "otk/util.hh" +#include "otk/rendercolor.hh" extern "C" { #include @@ -126,6 +127,7 @@ Openbox::Openbox(int argc, char **argv) // anything that died while we were restarting won't give us a SIGCHLD while (waitpid(-1, NULL, WNOHANG) > 0); + otk::RenderColor::initialize(); otk::Timer::initialize(); otk::Property::initialize(); _actions = new Actions(); @@ -208,6 +210,7 @@ Openbox::~Openbox() //otk::display->destroy(); otk::Timer::destroy(); + otk::RenderColor::destroy(); if (_restart) { if (!_restart_prog.empty()) { -- 2.45.2