ref: 5f4e2670b4d8eb3cd1faed9808c3d0747284a288
parent: 26e4a18e7060b0300f57f6592e3440b5e0a4aea1
author: Jacob Moody <moody@posixcafe.org>
date: Mon Sep 18 19:36:13 EDT 2023
eui: draw in seperate proc copied from doom.
--- a/sys/src/games/eui.c
+++ b/sys/src/games/eui.c
@@ -22,6 +22,9 @@
static int vwdx, vwdy, vwbpp;
static ulong vwchan;
static Image *fb;
+static Channel *conv, *sync[2];
+static uchar *screenconv[2];
+static int screenconvi;
struct Kfn{
Rune r;
@@ -188,6 +191,7 @@
{
Point p;
+ send(sync[0], nil);
if(!fixscale){
scale = Dx(screen->r) / vwdx;
if(Dy(screen->r) / vwdy < scale)
@@ -205,7 +209,12 @@
vwchan, scale > 1, 0);
free(pic);
pic = emalloc(vwdx * vwdy * vwbpp * scale);
- draw(screen, screen->r, bg, nil, ZP);
+ free(screenconv[0]);
+ free(screenconv[1]);
+ screenconv[0] = emalloc(vwdx * vwdy * vwbpp * scale);
+ screenconv[1] = emalloc(vwdx * vwdy * vwbpp * scale);
+ draw(screen, screen->r, bg, nil, ZP);
+ recv(sync[1], nil);
}
void
@@ -214,8 +223,10 @@
Mouse m;
if(nbrecvul(mc->resizec) > 0){
+ send(sync[0], nil);
if(getwindow(display, Refnone) < 0)
sysfatal("resize failed: %r");
+ recv(sync[1], nil);
screeninit();
}
if(discard)
@@ -223,29 +234,60 @@
;
}
-void
-flushscreen(void)
+static void
+screenproc(void*)
{
- if(scale == 1){
- loadimage(fb, fb->r, pic, vwdx * vwdy * vwbpp);
- draw(screen, picr, fb, nil, ZP);
- } else {
- Rectangle r;
- uchar *s;
- int w;
+ uchar *p;
+ enum { Draw, Sync1, Sync2 };
+ Alt alts[] = {
+ [Draw] {.c = conv, .v = &p, .op = CHANRCV},
+ [Sync1] {.c = sync[0], .op = CHANRCV},
+ [Sync2] {.c = sync[1], .op = CHANNOP},
+ {.op = CHANEND},
+ };
- s = pic;
- r = picr;
- w = vwdx * vwbpp * scale;
- while(r.min.y < picr.max.y){
- loadimage(fb, fb->r, s, w);
- s += w;
- r.max.y = r.min.y+scale;
- draw(screen, r, fb, nil, ZP);
- r.min.y = r.max.y;
+ for(;;) switch(alt(alts)){
+ case Draw:
+ if(scale == 1){
+ loadimage(fb, fb->r, p, vwdx * vwdy * vwbpp);
+ draw(screen, picr, fb, nil, ZP);
+ } else {
+ Rectangle r;
+ uchar *s;
+ int w;
+
+ s = p;
+ r = picr;
+ w = vwdx * vwbpp * scale;
+ while(r.min.y < picr.max.y){
+ loadimage(fb, fb->r, s, w);
+ s += w;
+ r.max.y = r.min.y+scale;
+ draw(screen, r, fb, nil, ZP);
+ r.min.y = r.max.y;
+ }
}
+ flushimage(display, 1);
+ break;
+ case Sync1:
+ alts[Draw].op = CHANNOP;
+ alts[Sync1].op = CHANNOP;
+ alts[Sync2].op = CHANSND;
+ break;
+ case Sync2:
+ alts[Draw].op = CHANRCV;
+ alts[Sync1].op = CHANRCV;
+ alts[Sync2].op = CHANNOP;
+ break;
}
- flushimage(display, 1);
+}
+
+void
+flushscreen(void)
+{
+ memmove(screenconv[screenconvi], pic, vwdx * vwdy * vwbpp * scale);
+ if(sendp(conv, screenconv[screenconvi]) > 0)
+ screenconvi = (screenconvi + 1) % 2;
if(profile)
timing();
}
@@ -324,5 +366,9 @@
proccreate(joyproc, nil, mainstacksize);
bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
scale = fixscale;
+ conv = chancreate(sizeof(uchar*), 0);
+ sync[0] = chancreate(1, 0);
+ sync[1] = chancreate(1, 0);
+ proccreate(screenproc, nil, mainstacksize);
screeninit();
}