gPixmap aufsetzt (und damit unbeschleunigt ist).
*/
+// for debugging use:
+//#define SYNC_PAINT
+#undef SYNC_PAINT
+
#include <pthread.h>
#include <stack>
#include <list>
-#include <lib/base/estring.h>
-#include <lib/base/ringbuffer.h>
-#include <lib/gdi/erect.h>
+#include <string>
#include <lib/base/elock.h>
+#include <lib/base/message.h>
+#include <lib/gdi/erect.h>
#include <lib/gdi/gpixmap.h>
-
+#include <lib/gdi/region.h>
+#include <lib/gdi/gfont.h>
+#include <lib/gdi/compositing.h>
class eTextPara;
{
enum Opcode
{
- begin,
-
renderText,
renderPara,
+ setFont,
- fill,
+ fill, fillRegion, clear,
blit,
setPalette,
line,
- clip,
+ setBackgroundColor,
+ setForegroundColor,
+
+ setBackgroundColorRGB,
+ setForegroundColorRGB,
+
+ setOffset,
+
+ setClip, addClip, popClip,
flush,
- end,
- shutdown
+ waitVSync,
+ flip,
+ notify,
+
+ enableSpinner, disableSpinner, incrementSpinner,
+
+ shutdown,
+
+ setCompositing,
} opcode;
+ gDC *dc;
union para
{
- struct pbegin
- {
- eRect area;
- pbegin(const eRect &area): area(area) { }
- } *begin;
-
- struct pfill
+ struct pfillRect
{
eRect area;
- gColor color;
- pfill(const eRect &area, gColor color): area(area), color(color) { }
} *fill;
+ struct pfillRegion
+ {
+ gRegion region;
+ } *fillRegion;
+
struct prenderText
{
- gFont font;
eRect area;
- eString text;
- gRGB foregroundColor, backgroundColor;
- prenderText(const gFont &font, const eRect &area, const eString &text, const gRGB &foregroundColor, const gRGB &backgroundColor):
- font(font), area(area), text(text), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
+ char *text;
+ int flags;
} *renderText;
struct prenderPara
{
ePoint offset;
eTextPara *textpara;
- gRGB foregroundColor, backgroundColor;
- prenderPara(const ePoint &offset, eTextPara *textpara, const gRGB &foregroundColor, const gRGB &backgroundColor)
- : offset(offset), textpara(textpara), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
} *renderPara;
+
+ struct psetFont
+ {
+ gFont *font;
+ } *setFont;
struct psetPalette
{
gPalette *palette;
- psetPalette(gPalette *palette): palette(palette) { }
} *setPalette;
struct pblit
{
- ePtr<gPixmap> pixmap;
- ePoint position;
+ gPixmap *pixmap;
+ int flags;
+ eRect position;
eRect clip;
- pblit(gPixmap *pixmap, const ePoint &position, const eRect &clip)
- : pixmap(pixmap), position(position), clip(clip) { }
} *blit;
struct pmergePalette
{
- ePtr<gPixmap> target;
- pmergePalette(gPixmap *target): target(target) { }
+ gPixmap *target;
} *mergePalette;
struct pline
{
ePoint start, end;
- gColor color;
- pline(const ePoint &start, const ePoint &end, gColor color): start(start), end(end), color(color) { }
} *line;
- struct pclip
+ struct psetClip
{
- eRect clip;
- pclip(const eRect &clip): clip(clip) { }
+ gRegion region;
} *clip;
+
+ struct psetColor
+ {
+ gColor color;
+ } *setColor;
+
+ struct psetColorRGB
+ {
+ gRGB color;
+ } *setColorRGB;
+
+ struct psetOffset
+ {
+ ePoint value;
+ int rel;
+ } *setOffset;
+
+ gCompositingData *setCompositing;
} parm;
-
- int flags;
-
- gDC *dc;
};
-class gRC
+#define MAXSIZE 2048
+
+ /* gRC is the singleton which controls the fifo and dispatches commands */
+class gRC: public iObject, public Object
{
+ DECLARE_REF(gRC);
+ friend class gPainter;
static gRC *instance;
-
+
+#ifndef SYNC_PAINT
static void *thread_wrapper(void *ptr);
pthread_t the_thread;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+#endif
void *thread();
+
+ gOpcode queue[MAXSIZE];
+ int rp, wp;
+
+ eFixedMessagePump<int> m_notify_pump;
+ void recv_notify(const int &i);
+
+ ePtr<gDC> m_spinner_dc;
+ int m_spinner_enabled;
- eLock queuelock;
+ void enableSpinner();
+ void disableSpinner();
- queueRingBuffer<gOpcode> queue;
+ ePtr<gCompositingData> m_compositing;
+
public:
gRC();
virtual ~gRC();
- void submit(const gOpcode &o)
- {
- static int collected=0;
- queue.enqueue(o);
- collected++;
- if (o.opcode==gOpcode::end)
- {
- queuelock.unlock(collected);
-#ifdef SYNC_PAINT
- thread();
-#endif
- collected=0;
- }
- }
+ void submit(const gOpcode &o);
- static gRC &getInstance();
+ Signal0<void> notify;
+
+ void setSpinnerDC(gDC *dc) { m_spinner_dc = dc; }
+
+ static gRC *getInstance();
};
+ /* gPainter is the user frontend, which in turn sends commands through gRC */
class gPainter
{
- gDC &dc;
- gRC &rc;
+ ePtr<gDC> m_dc;
+ ePtr<gRC> m_rc;
friend class gRC;
gOpcode *beginptr;
- /* paint states */
-// std::stack<eRect, std::list<eRect> > cliparea;
- std::stack<eRect> cliparea;
- gFont font;
- gColor foregroundColor, backgroundColor;
- ePoint logicalZero;
void begin(const eRect &rect);
void end();
public:
- gPainter(gDC &dc, eRect rect=eRect());
+ gPainter(gDC *dc, eRect rect=eRect());
virtual ~gPainter();
-
+
void setBackgroundColor(const gColor &color);
void setForegroundColor(const gColor &color);
- void setFont(const gFont &font);
+ void setBackgroundColor(const gRGB &color);
+ void setForegroundColor(const gRGB &color);
+
+ void setFont(gFont *font);
+ /* flags only THESE: */
+ enum
+ {
+ // todo, make mask. you cannot align both right AND center AND block ;)
+ RT_HALIGN_LEFT = 0, /* default */
+ RT_HALIGN_RIGHT = 1,
+ RT_HALIGN_CENTER = 2,
+ RT_HALIGN_BLOCK = 4,
+
+ RT_VALIGN_TOP = 0, /* default */
+ RT_VALIGN_CENTER = 8,
+ RT_VALIGN_BOTTOM = 16,
+
+ RT_WRAP = 32
+ };
void renderText(const eRect &position, const std::string &string, int flags=0);
- void renderPara(eTextPara ¶, ePoint offset=ePoint(0, 0));
+
+ void renderPara(eTextPara *para, ePoint offset=ePoint(0, 0));
void fill(const eRect &area);
+ void fill(const gRegion &area);
void clear();
-
- void gPainter::blit(gPixmap *pixmap, ePoint pos, eRect clip=eRect(), int flags=0)
+
+ enum
{
- gOpcode o;
- o.dc=&dc;
- o.opcode=gOpcode::blit;
- pos+=logicalZero;
- clip.moveBy(logicalZero.x(), logicalZero.y());
- o.parm.blit=new gOpcode::para::pblit(pixmap, pos, clip);
- o.flags=flags;
- rc.submit(o);
- }
+ BT_ALPHATEST = 1,
+ BT_ALPHABLEND = 2,
+ BT_SCALE = 4 /* will be automatically set by blitScale */
+ };
+
+ void blit(gPixmap *pixmap, ePoint pos, const eRect &clip=eRect(), int flags=0);
+ void blitScale(gPixmap *pixmap, const eRect &pos, const eRect &clip=eRect(), int flags=0, int aflags = BT_SCALE);
void setPalette(gRGB *colors, int start=0, int len=256);
+ void setPalette(gPixmap *source);
void mergePalette(gPixmap *target);
void line(ePoint start, ePoint end);
- void setLogicalZero(ePoint abs);
- void moveLogicalZero(ePoint rel);
- void resetLogicalZero();
+ void setOffset(ePoint abs);
+ void moveOffset(ePoint rel);
+ void resetOffset();
- void clip(eRect clip);
+ void resetClip(const gRegion &clip);
+ void clip(const gRegion &clip);
void clippop();
+ void waitVSync();
+ void flip();
+ void notify();
+ void setCompositing(gCompositingData *comp);
+
void flush();
};
-class gDC
-{
-protected:
- eLock dclock;
-public:
- virtual void exec(gOpcode *opcode)=0;
- virtual RESULT getPixmap(ePtr<gPixmap> &)=0;
- virtual eSize getSize()=0;
- virtual const eRect &getClip()=0;
- virtual gRGB getRGB(gColor col)=0;
- virtual ~gDC();
- void lock() { dclock.lock(1); }
- void unlock() { dclock.unlock(1); }
-};
-
-class gPixmapDC: public gDC
+class gDC: public iObject
{
+ DECLARE_REF(gDC);
protected:
- ePtr<gPixmap> pixmap;
- eRect clip;
+ ePtr<gPixmap> m_pixmap;
- void exec(gOpcode *opcode);
- gPixmapDC();
+ gColor m_foreground_color, m_background_color;
+ gRGB m_foreground_color_rgb, m_background_color_rgb;
+ ePtr<gFont> m_current_font;
+ ePoint m_current_offset;
+
+ std::stack<gRegion> m_clip_stack;
+ gRegion m_current_clip;
+
+ ePtr<gPixmap> m_spinner_saved, m_spinner_temp;
+ ePtr<gPixmap> *m_spinner_pic;
+ eRect m_spinner_pos;
+ int m_spinner_num, m_spinner_i;
public:
- gPixmapDC(gPixmap *pixmap);
- virtual ~gPixmapDC();
- RESULT getPixmap(ePtr<gPixmap> &ptr) { ptr = pixmap; return 0; }
+ virtual void exec(gOpcode *opcode);
+ gDC(gPixmap *pixmap);
+ gDC();
+ virtual ~gDC();
+ gRegion &getClip() { return m_current_clip; }
+ int getPixmap(ePtr<gPixmap> &pm) { pm = m_pixmap; return 0; }
gRGB getRGB(gColor col);
- const eRect &getClip() { return clip; }
- virtual eSize getSize() { return eSize(pixmap->x, pixmap->y); }
+ virtual eSize size() { return m_pixmap->size(); }
+ virtual int islocked() { return 0; }
+
+ void enableSpinner();
+ void disableSpinner();
+ void incrementSpinner();
+ void setSpinner(eRect pos, ePtr<gPixmap> *pic, int len);
};
#endif