add rendercolor class, with a cache of gcs for the colors
This commit is contained in:
parent
cfd8f9a658
commit
0348a2f3ab
9 changed files with 145 additions and 7 deletions
|
@ -37,3 +37,4 @@ rendertexture.lo
|
||||||
rendertest
|
rendertest
|
||||||
renderstyle.lo
|
renderstyle.lo
|
||||||
rendercontrol.lo
|
rendercontrol.lo
|
||||||
|
rendercolor.lo
|
||||||
|
|
|
@ -9,7 +9,7 @@ INCLUDES= -I../src
|
||||||
noinst_LTLIBRARIES=libotk.la
|
noinst_LTLIBRARIES=libotk.la
|
||||||
|
|
||||||
libotk_la_SOURCES=rendercontrol.cc truerendercontrol.cc surface.cc \
|
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 \
|
color.cc display.cc font.cc gccache.cc image.cc \
|
||||||
property.cc imagecontrol.cc rect.cc screeninfo.cc \
|
property.cc imagecontrol.cc rect.cc screeninfo.cc \
|
||||||
texture.cc timer.cc style.cc \
|
texture.cc timer.cc style.cc \
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "widget.hh"
|
#include "widget.hh"
|
||||||
#include "timer.hh"
|
#include "timer.hh"
|
||||||
#include "property.hh"
|
#include "property.hh"
|
||||||
|
#include "rendercolor.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#ifdef HAVE_STDLIB_H
|
#ifdef HAVE_STDLIB_H
|
||||||
|
@ -32,6 +33,7 @@ Application::Application(int argc, char **argv)
|
||||||
const ScreenInfo *s_info = _display.screenInfo(DefaultScreen(*_display));
|
const ScreenInfo *s_info = _display.screenInfo(DefaultScreen(*_display));
|
||||||
|
|
||||||
Timer::initialize();
|
Timer::initialize();
|
||||||
|
RenderColor::initialize();
|
||||||
Property::initialize();
|
Property::initialize();
|
||||||
_img_ctrl = new ImageControl(s_info, True, 4, 5, 200);
|
_img_ctrl = new ImageControl(s_info, True, 4, 5, 200);
|
||||||
_style_conf = new Configuration(False);
|
_style_conf = new Configuration(False);
|
||||||
|
@ -45,6 +47,7 @@ Application::~Application()
|
||||||
delete _style_conf;
|
delete _style_conf;
|
||||||
delete _img_ctrl;
|
delete _img_ctrl;
|
||||||
delete _style;
|
delete _style;
|
||||||
|
RenderColor::destroy();
|
||||||
Timer::destroy();
|
Timer::destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
83
otk/rendercolor.cc
Normal file
83
otk/rendercolor.cc
Normal file
|
@ -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<unsigned long, RenderColor::CacheItem*> *RenderColor::_cache = 0;
|
||||||
|
|
||||||
|
void RenderColor::initialize()
|
||||||
|
{
|
||||||
|
_cache = new std::map<unsigned long, CacheItem*>[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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
otk/rendercolor.hh
Normal file
45
otk/rendercolor.hh
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
|
||||||
|
#ifndef __rendercolor_hh
|
||||||
|
#define __rendercolor_hh
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace otk {
|
||||||
|
|
||||||
|
class RenderColor {
|
||||||
|
struct CacheItem {
|
||||||
|
GC gc;
|
||||||
|
int count;
|
||||||
|
CacheItem(GC g) : gc(g), count(0) {}
|
||||||
|
};
|
||||||
|
static std::map<unsigned long, CacheItem*> *_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
|
|
@ -7,7 +7,7 @@
|
||||||
#include "surface.hh"
|
#include "surface.hh"
|
||||||
#include "display.hh"
|
#include "display.hh"
|
||||||
#include "screeninfo.hh"
|
#include "screeninfo.hh"
|
||||||
#include "gccache.hh"
|
#include "rendercolor.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
@ -28,13 +28,12 @@ Surface::~Surface()
|
||||||
destroyObjects();
|
destroyObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Surface::setPixmap(const Color &color)
|
void Surface::setPixmap(const RenderColor &color)
|
||||||
{
|
{
|
||||||
if (_pixmap == None)
|
if (_pixmap == None)
|
||||||
createObjects();
|
createObjects();
|
||||||
|
|
||||||
Pen p(color);
|
XFillRectangle(**display, _pixmap, color.gc(), 0, 0,
|
||||||
XFillRectangle(**display, _pixmap, p.gc(), 0, 0,
|
|
||||||
_size.x(), _size.y());
|
_size.x(), _size.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ extern "C" {
|
||||||
namespace otk {
|
namespace otk {
|
||||||
|
|
||||||
class ScreenInfo;
|
class ScreenInfo;
|
||||||
|
class RenderColor;
|
||||||
|
|
||||||
class Surface {
|
class Surface {
|
||||||
int _screen;
|
int _screen;
|
||||||
|
@ -26,7 +27,7 @@ protected:
|
||||||
void destroyObjects();
|
void destroyObjects();
|
||||||
|
|
||||||
void setPixmap(XImage *image);
|
void setPixmap(XImage *image);
|
||||||
void setPixmap(const Color &color);
|
void setPixmap(const RenderColor &color);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Surface(int screen, const Point &size);
|
Surface(int screen, const Point &size);
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "screeninfo.hh"
|
#include "screeninfo.hh"
|
||||||
#include "surface.hh"
|
#include "surface.hh"
|
||||||
|
|
||||||
|
#include "rendercolor.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#ifdef HAVE_STDLIB_H
|
#ifdef HAVE_STDLIB_H
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
@ -127,7 +129,8 @@ void TrueRenderControl::drawBackground(Surface& sf,
|
||||||
|
|
||||||
im->data = (char*) data;
|
im->data = (char*) data;
|
||||||
|
|
||||||
sf.setPixmap(im);
|
// sf.setPixmap(im);
|
||||||
|
sf.setPixmap(RenderColor(_screen, 0xff, 0xff, 0));
|
||||||
|
|
||||||
delete [] im->data;
|
delete [] im->data;
|
||||||
im->data = NULL;
|
im->data = NULL;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "otk/assassin.hh"
|
#include "otk/assassin.hh"
|
||||||
#include "otk/property.hh"
|
#include "otk/property.hh"
|
||||||
#include "otk/util.hh"
|
#include "otk/util.hh"
|
||||||
|
#include "otk/rendercolor.hh"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
|
@ -126,6 +127,7 @@ Openbox::Openbox(int argc, char **argv)
|
||||||
// anything that died while we were restarting won't give us a SIGCHLD
|
// anything that died while we were restarting won't give us a SIGCHLD
|
||||||
while (waitpid(-1, NULL, WNOHANG) > 0);
|
while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||||
|
|
||||||
|
otk::RenderColor::initialize();
|
||||||
otk::Timer::initialize();
|
otk::Timer::initialize();
|
||||||
otk::Property::initialize();
|
otk::Property::initialize();
|
||||||
_actions = new Actions();
|
_actions = new Actions();
|
||||||
|
@ -208,6 +210,7 @@ Openbox::~Openbox()
|
||||||
//otk::display->destroy();
|
//otk::display->destroy();
|
||||||
|
|
||||||
otk::Timer::destroy();
|
otk::Timer::destroy();
|
||||||
|
otk::RenderColor::destroy();
|
||||||
|
|
||||||
if (_restart) {
|
if (_restart) {
|
||||||
if (!_restart_prog.empty()) {
|
if (!_restart_prog.empty()) {
|
||||||
|
|
Loading…
Reference in a new issue