gRC *gRC::instance=0;
-gRC::gRC(): queue(2048), queuelock(MAXSIZE)
+gRC::gRC(): queue(2048), m_notify_pump(eApp, 0), queuelock(MAXSIZE)
{
ASSERT(!instance);
instance=this;
queuelock.lock(MAXSIZE);
+ CONNECT(m_notify_pump.recv_msg, gRC::recv_notify);
#ifndef SYNC_PAINT
int res = pthread_create(&the_thread, 0, thread_wrapper, this);
if (res)
eFatal("RC thread couldn't be created");
else
- eDebug("RC thread createted successfully");
+ eDebug("RC thread created successfully");
#endif
}
void *gRC::thread()
{
+ int need_notify = 0;
#ifndef SYNC_PAINT
while (1)
#else
gOpcode& o(queue.current());
if (o.opcode==gOpcode::shutdown)
break;
- o.dc->exec(&o);
+ if (o.opcode==gOpcode::notify)
+ need_notify = 1;
+ else
+ o.dc->exec(&o);
o.dc->Release();
queue.dequeue();
+
+ if ((!queue.size()) && need_notify)
+ {
+ need_notify = 0;
+ m_notify_pump.send(1);
+ }
}
#ifndef SYNC_PAINT
pthread_exit(0);
return 0;
}
+void gRC::recv_notify(const int &i)
+{
+ notify();
+}
+
gRC *gRC::getInstance()
{
return instance;
m_rc->submit(o);
}
+void gPainter::setBackgroundColor(const gRGB &color)
+{
+ gOpcode o;
+ o.opcode = gOpcode::setBackgroundColorRGB;
+ o.dc = m_dc.grabRef();
+ o.parm.setColorRGB = new gOpcode::para::psetColorRGB;
+ o.parm.setColorRGB->color = color;
+
+ m_rc->submit(o);
+}
+
+void gPainter::setForegroundColor(const gRGB &color)
+{
+ gOpcode o;
+ o.opcode = gOpcode::setForegroundColorRGB;
+ o.dc = m_dc.grabRef();
+ o.parm.setColorRGB = new gOpcode::para::psetColorRGB;
+ o.parm.setColorRGB->color = color;
+
+ m_rc->submit(o);
+}
+
void gPainter::setFont(gFont *font)
{
gOpcode o;
void gPainter::blit(gPixmap *pixmap, ePoint pos, const eRect &clip, int flags)
{
gOpcode o;
-
+
+ ASSERT(pixmap);
+
o.opcode=gOpcode::blit;
o.dc = m_dc.grabRef();
pixmap->AddRef();
o.parm.blit->pixmap = pixmap;
o.parm.blit->position = pos;
o.parm.blit->clip = clip;
- o.flags=flags;
+ o.parm.blit->flags=flags;
m_rc->submit(o);
}
m_rc->submit(o);
}
+void gPainter::setPalette(gPixmap *source)
+{
+ ASSERT(source);
+ setPalette(source->surface->clut.data, source->surface->clut.start, source->surface->clut.colors);
+}
+
void gPainter::mergePalette(gPixmap *target)
{
gOpcode o;
- o.opcode=gOpcode::mergePalette;
+ o.opcode = gOpcode::mergePalette;
o.dc = m_dc.grabRef();
target->AddRef();
+ o.parm.mergePalette = new gOpcode::para::pmergePalette;
o.parm.mergePalette->target = target;
m_rc->submit(o);
}
void gPainter::flush()
{
+ gOpcode o;
+ o.opcode = gOpcode::flush;
+ o.dc = m_dc.grabRef();
+ m_rc->submit(o);
+}
+
+void gPainter::waitVSync()
+{
+ gOpcode o;
+ o.opcode = gOpcode::waitVSync;
+ o.dc = m_dc.grabRef();
+ m_rc->submit(o);
+}
+
+void gPainter::flip()
+{
+ gOpcode o;
+ o.opcode = gOpcode::flip;
+ o.dc = m_dc.grabRef();
+ m_rc->submit(o);
+}
+
+void gPainter::notify()
+{
+ gOpcode o;
+ o.opcode = gOpcode::notify;
+ o.dc = m_dc.grabRef();
+ m_rc->submit(o);
}
void gPainter::end()
{
+ gOpcode o;
+ o.opcode = gOpcode::flush;
+ o.dc = m_dc.grabRef();
+ m_rc->submit(o);
}
gDC::gDC()
m_foreground_color = o->parm.setColor->color;
delete o->parm.setColor;
break;
+ case gOpcode::setBackgroundColorRGB:
+ m_background_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color);
+ delete o->parm.setColorRGB;
+ break;
+ case gOpcode::setForegroundColorRGB:
+ m_foreground_color = m_pixmap->surface->clut.findColor(o->parm.setColorRGB->color);
+ delete o->parm.setColorRGB;
+ break;
case gOpcode::setFont:
m_current_font = o->parm.setFont->font;
o->parm.setFont->font->Release();
case gOpcode::renderText:
{
ePtr<eTextPara> para = new eTextPara(o->parm.renderText->area);
+ int flags = o->parm.renderText->flags;
assert(m_current_font);
para->setFont(m_current_font);
- para->renderString(o->parm.renderText->text, 0);
+ para->renderString(o->parm.renderText->text, (flags & gPainter::RT_WRAP) ? RS_WRAP : 0);
- if (o->parm.renderText->flags & gPainter::RT_HALIGN_RIGHT)
+ if (flags & gPainter::RT_HALIGN_RIGHT)
para->realign(eTextPara::dirRight);
- else if (o->parm.renderText->flags & gPainter::RT_HALIGN_CENTER)
+ else if (flags & gPainter::RT_HALIGN_CENTER)
para->realign(eTextPara::dirCenter);
- else if (o->parm.renderText->flags & gPainter::RT_HALIGN_BLOCK)
+ else if (flags & gPainter::RT_HALIGN_BLOCK)
para->realign(eTextPara::dirBlock);
ePoint offset = m_current_offset;
if (o->parm.renderText->flags & gPainter::RT_VALIGN_CENTER)
{
eRect bbox = para->getBoundBox();
- offset += ePoint(0, (o->parm.renderText->area.height() - bbox.height()) / 2);
+ int vcentered_top = (o->parm.renderText->area.height() - bbox.height()) / 2;
+ int correction = vcentered_top - bbox.top();
+ offset += ePoint(0, correction);
}
para->blit(*this, offset, getRGB(m_background_color), getRGB(m_foreground_color));
delete o->parm.renderText;
case gOpcode::blit:
{
gRegion clip;
- if (!o->parm.blit->clip.valid())
+ // this code should be checked again but i'm too tired now
+
+ o->parm.blit->position += m_current_offset;
+
+ if (o->parm.blit->clip.valid())
{
- clip.intersect(gRegion(o->parm.blit->clip), clip);
+ o->parm.blit->clip.moveBy(m_current_offset);
+ clip.intersect(gRegion(o->parm.blit->clip), m_current_clip);
} else
clip = m_current_clip;
+
m_pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, clip, o->parm.blit->flags);
o->parm.blit->pixmap->Release();
delete o->parm.blit;
delete o->parm.setPalette;
break;
case gOpcode::mergePalette:
-#if 0
- pixmap->mergePalette(*o->parm.blit->pixmap);
- o->parm.blit->pixmap->unlock();
- delete o->parm.blit;
-#endif
- break;
+ m_pixmap->mergePalette(*o->parm.mergePalette->target);
+ o->parm.mergePalette->target->Release();
+ delete o->parm.mergePalette;
+ break;
case gOpcode::line:
{
ePoint start = o->parm.line->start + m_current_offset, end = o->parm.line->end + m_current_offset;
break;
case gOpcode::setClip:
o->parm.clip->region.moveBy(m_current_offset);
- m_current_clip = o->parm.clip->region & eRect(ePoint(0, 0), m_pixmap->getSize());
+ m_current_clip = o->parm.clip->region & eRect(ePoint(0, 0), m_pixmap->size());
delete o->parm.clip;
break;
case gOpcode::popClip:
m_current_offset = o->parm.setOffset->value;
delete o->parm.setOffset;
break;
+ case gOpcode::waitVSync:
+ break;
+ case gOpcode::flip:
+ break;
+ case gOpcode::flush:
+ break;
default:
eFatal("illegal opcode %d. expect memory leak!", o->opcode);
}
DEFINE_REF(gDC);
eAutoInitPtr<gRC> init_grc(eAutoInitNumbers::graphic, "gRC");
-