summaryrefslogtreecommitdiff
path: root/med.c
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-05-23 21:26:19 +0000
committerrodri <rgl@antares-labs.eu>2024-05-23 21:26:19 +0000
commitcbfa17d446effcfc1e7d17aed624af8f098370f1 (patch)
tree526394c2dc24503b18a676a742187a648365b269 /med.c
parent22edbd9f543509ab129ba03af92baed79139e07f (diff)
download3dee-cbfa17d446effcfc1e7d17aed624af8f098370f1.tar.gz
3dee-cbfa17d446effcfc1e7d17aed624af8f098370f1.tar.bz2
3dee-cbfa17d446effcfc1e7d17aed624af8f098370f1.zip
get rid of rendering latency by decoupling it from i/o.
i was using a single alternator to mux both i/o and drawing in a single proc, and avoid locking. the problem is that it causes a fight to break up every time there's any input (steady 100Hz) or a lot of drawing requests from the renderer (up to 60Hz.) i added a drawproc to handle exclusively drawing requests, and a drawing lock for UI widgets that kidnap the display.
Diffstat (limited to 'med.c')
-rw-r--r--med.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/med.c b/med.c
index 670997a..0e49f44 100644
--- a/med.c
+++ b/med.c
@@ -76,6 +76,7 @@ Entity *subject;
Model *model;
Shadertab *shader;
QLock scenelk;
+QLock drawlk;
Mouse om;
Quaternion orient = {1,0,0,0};
@@ -466,11 +467,11 @@ redraw(void)
}
void
-drawproc(void *)
+renderproc(void *)
{
uvlong t0, Δt;
- threadsetname("drawproc");
+ threadsetname("renderproc");
t0 = nsec();
for(;;){
@@ -492,6 +493,18 @@ drawproc(void *)
}
void
+drawproc(void *)
+{
+ threadsetname("drawproc");
+
+ for(;;)
+ if(recv(drawc, nil) && canqlock(&drawlk)){
+ redraw();
+ qunlock(&drawlk);
+ }
+}
+
+void
lmb(void)
{
if((om.buttons^mctl->buttons) == 0)
@@ -516,6 +529,7 @@ mmb(void)
};
static Menu menu = { .item = items };
+ qlock(&drawlk);
switch(menuhit(2, mctl, &menu, _screen)){
case TSNEAREST:
tsampler = neartexsampler;
@@ -526,35 +540,50 @@ mmb(void)
case QUIT:
threadexitsall(nil);
}
+ qunlock(&drawlk);
nbsend(drawc, nil);
}
static char *
genrmbmenuitem(int idx)
{
+ static char *items[] = {
+ "",
+ "add cube",
+ nil
+ };
if(idx < nelem(shadertab))
return shadertab[idx].name;
- else if(idx == nelem(shadertab))
- return "";
- else if(idx == nelem(shadertab)+1)
- return "add cube";
- return nil;
+ idx -= nelem(shadertab);
+ return items[idx];
}
void
rmb(void)
{
+ enum {
+ SP,
+ ADDCUBE,
+ };
static Menu menu = { .gen = genrmbmenuitem };
int idx;
+ qlock(&drawlk);
idx = menuhit(3, mctl, &menu, _screen);
if(idx < 0)
- return;
+ goto nohit;
if(idx < nelem(shadertab)){
shader = &shadertab[idx];
memset(&cam.stats, 0, sizeof(cam.stats));
- }else if(idx == nelem(shadertab)+1)
+ }
+ idx -= nelem(shadertab);
+ switch(idx){
+ case ADDCUBE:
addcube();
+ break;
+ }
+nohit:
+ qunlock(&drawlk);
nbsend(drawc, nil);
}
@@ -763,22 +792,21 @@ threadmain(int argc, char *argv[])
proccreate(kbdproc, nil, mainstacksize);
proccreate(keyproc, keyc, mainstacksize);
+ proccreate(renderproc, nil, mainstacksize);
proccreate(drawproc, nil, mainstacksize);
for(;;){
- enum {MOUSE, RESIZE, KEY, DRAW};
+ enum {MOUSE, RESIZE, KEY};
Alt a[] = {
{mctl->c, &mctl->Mouse, CHANRCV},
{mctl->resizec, nil, CHANRCV},
{keyc, nil, CHANRCV},
- {drawc, nil, CHANRCV},
{nil, nil, CHANEND}
};
switch(alt(a)){
case MOUSE: mouse(); break;
case RESIZE: resize(); break;
case KEY: handlekeys(); break;
- case DRAW: redraw(); break;
}
}
}