ref: c8f028cd961e69e9af52b66175897ca5f26e3839
parent: 22bca74feebe60c2059c931861c8b9ee567c6c50
author: qwx <qwx@sciops.net>
date: Sat Jan 11 18:20:23 EST 2025
fix races: don't use separate drawproc for nothing
--- a/chunk.c
+++ b/chunk.c
@@ -410,6 +410,7 @@
d->norris = l;
d->from = d->off;
d->to = d->from + sz;
+ /* FIXME: get rid of indirection */
*d = newdot(d);
return 0;
}
--- a/cmd.c
+++ b/cmd.c
@@ -157,7 +157,7 @@
dot.to = dot.from + cd.totalsz;
qunlock(&lsync);
reader = -1;
- redraw(1);
+ refresh(Drawall);
threadexits(nil);
}
--- a/draw.c
+++ b/draw.c
@@ -5,7 +5,10 @@
#include "dat.h"
#include "fns.h"
+/* FIXME: clean up, now that we're just using alt; ddot vs rdot, dot */
+
QLock lsync;
+Channel *drawc;
int samptime;
enum{
@@ -24,7 +27,7 @@
static usize views, viewe, viewmax, linepos;
static int bgscalyl, bgscalyr;
static double bgscalf;
-static Channel *drawc, *sampc;
+static Channel *sampc;
static usize T;
static int sampwidth = 1; /* pixels per sample */
static double zoom = 1.0;
@@ -32,6 +35,7 @@
static int working;
static vlong slen;
static s16int *graph[2];
+static Dot ddot;
#define Rrate (1000.0 / 60.0)
@@ -78,7 +82,7 @@
usize p;
p = va_arg(fmt->args, usize);
- if(p > dot.totalsz)
+ if(p > ddot.totalsz)
return fmtstrcpy(fmt, "-∞");
b2t(p, &th, &tm, &ts, &tμ);
if(samptime)
@@ -111,7 +115,7 @@
usize p, off;
Chunk *c;
- c = p2c(views, &off, &dot);
+ c = p2c(views, &off, &ddot);
for(p=views-off; p<viewe; p+=c->len, c=c->right){
if(p == 0)
continue;
@@ -123,10 +127,10 @@
rendermarks(void)
{
renderchunks();
- renderpos(dot.from, col[Cloop], 0);
- renderpos(dot.to, col[Cloop], 0);
- if(dot.off != dot.from)
- renderpos(dot.off, col[Cins], 0);
+ renderpos(ddot.from, col[Cloop], 0);
+ renderpos(ddot.to, col[Cloop], 0);
+ if(ddot.off != ddot.from)
+ renderpos(ddot.off, col[Cins], 0);
}
static void
@@ -188,7 +192,7 @@
draw(screen, statr, col[Cbg], nil, ZP);
seprint(s, s+sizeof s, "%sT=%zd @ %τ",
stereo ? "" : chan==0?"Left ":"Right ",
- T / Sampsz, dot.cur);
+ T / Sampsz, ddot.cur);
p = string(screen, statr.min, col[Ctext], ZP, font, s);
if(bound == Bstart){
b[0] = "[";
@@ -200,55 +204,34 @@
b[2] = "]";
}
seprint(s, s+sizeof s, " %sfrom %τ%sto %τ%s",
- b[0], dot.from, b[1], dot.to, b[2]);
+ b[0], ddot.from, b[1], ddot.to, b[2]);
p = string(screen, p, col[Cloop], ZP, font, s);
- if(dot.off != dot.from && dot.off >= 0){
- seprint(s, s+sizeof s, " last %τ", dot.off);
+ if(ddot.off != ddot.from && ddot.off >= 0){
+ seprint(s, s+sizeof s, " last %τ", ddot.off);
p = string(screen, p, col[Cins], ZP, font, s);
}
statr.max.x = p.x;
}
-static void
-drawproc(void*)
+void
+paint(int what)
{
- int what;
- long Δt;
- double t0, t;
-
- threadsetname("drawer");
- t0 = nsec() / 1000000.0 + Rrate;
- for(;;){
- what = Drawrender;
- if(nbrecv(drawc, &what) < 0){
- fprint(2, "drawproc: %r\n");
- break;
- }
- lockdisplay(display);
- if((what & Drawrender) != 0 || stalerender || working){
- if(!working)
- stalerender = 0;
- render();
- draw(screen, rectaddpt(view->r, screen->r.min), view, nil, ZP);
- }else
- erasemark(linepos);
- renderpos(dot.cur, col[Cline], 1);
- linepos = dot.cur;
- drawstat();
- flushimage(display, 1);
- unlockdisplay(display);
- t = nsec() / 1000000.0;
- Δt = t0 - t;
- if(Δt > 0)
- sleep(Δt);
- else{
- Δt = -Δt;
- t0 += Δt - Δt % (long)Rrate;
- }
- t0 += Rrate;
- }
+ ddot = dot;
+ lockdisplay(display);
+ if((what & Drawrender) != 0 || stalerender || working){
+ if(!working)
+ stalerender = 0;
+ render();
+ draw(screen, rectaddpt(view->r, screen->r.min), view, nil, ZP);
+ }else
+ erasemark(linepos);
+ renderpos(ddot.cur, col[Cline], 1);
+ linepos = ddot.cur;
+ drawstat();
+ flushimage(display, 1);
+ unlockdisplay(display);
}
-
+
/* throttling of draw requests happens here */
void
refresh(int what)
@@ -350,11 +333,11 @@
usize span;
lockdisplay(display);
- T = (vlong)(dot.totalsz / zoom / Dx(screen->r)) & ~3;
+ T = (vlong)(ddot.totalsz / zoom / Dx(screen->r)) & ~3;
if(T < Sampsz)
T = Sampsz;
span = Dx(screen->r) * T;
- viewmax = dot.totalsz - span;
+ viewmax = ddot.totalsz - span;
if(views > viewmax)
views = viewmax;
viewe = views + span;
@@ -368,10 +351,12 @@
{
Dot d;
+ ddot = dot;
resetview(all);
if(paused)
refresh(Drawall);
- d = dot;
+
+ d = ddot;
d.from = d.cur = views;
d.to = viewe;
nbsend(sampc, &d);
@@ -388,8 +373,8 @@
z = zoom * pow(1.025, Δz);
if(z < 1.0)
z = 1.0;
- else if(z > (dot.totalsz / Sampsz) / Dx(screen->r))
- z = (dot.totalsz / Sampsz) / Dx(screen->r);
+ else if(z > (ddot.totalsz / Sampsz) / Dx(screen->r))
+ z = (ddot.totalsz / Sampsz) / Dx(screen->r);
if(z == zoom)
return;
zoom = z;
@@ -408,8 +393,8 @@
if(from < 0)
from = 0;
from &= ~3;
- if(to >= dot.totalsz)
- to = dot.totalsz;
+ if(to >= ddot.totalsz)
+ to = ddot.totalsz;
to &= ~3;
if((to - from) / Sampsz < Dx(screen->r)){
werrstr("range too small");
@@ -417,7 +402,7 @@
}
views = from;
viewe = to;
- zoom = (double)dot.totalsz / (to - from);
+ zoom = (double)ddot.totalsz / (to - from);
redraw(0);
return 0;
}
@@ -456,12 +441,13 @@
to &= ~3;
if(from >= to)
return;
- dot.from = from;
- dot.to = to;
+ ddot.from = from;
+ ddot.to = to;
/* advance may desync and reset it again */
- if(dot.cur < from || dot.cur >= to)
- dot.cur = from;
- dot.off = -1;
+ if(ddot.cur < from || ddot.cur >= to)
+ ddot.cur = from;
+ ddot.off = -1;
+ dot = ddot;
stalerender = 1;
refresh(Drawrender);
}
@@ -470,11 +456,12 @@
setjump(vlong off)
{
off &= ~3;
- if(off < dot.from || off > dot.to - Sampsz){
+ if(off < ddot.from || off > ddot.to - Sampsz){
werrstr("cannot jump outside of loop bounds");
return -1;
}
- dot.off = dot.cur = off;
+ ddot.off = ddot.cur = off;
+ dot = ddot;
stalerender = 1;
refresh(Drawrender);
return 0;
@@ -484,14 +471,14 @@
setloop(vlong off)
{
off &= ~3;
- if(off < 0 || off > dot.totalsz){
+ if(off < 0 || off > ddot.totalsz){
werrstr("invalid range");
return -1;
}
if(bound == Bstart)
- setrange(off, dot.to);
+ setrange(off, ddot.to);
else
- setrange(dot.from, off);
+ setrange(ddot.from, off);
return 0;
}
@@ -519,11 +506,10 @@
col[Cloop] = eallocimage(Rect(0,0,1,1), 1, 0x8888CCFF);
col[Cchunk] = eallocimage(Rect(0,0,1,1), 1, 0xEE0000FF);
}
- if((drawc = chancreate(sizeof(int), 0)) == nil
+ if((drawc = chancreate(sizeof(int), 8)) == nil
|| (sampc = chancreate(sizeof(Dot), 2)) == nil)
sysfatal("chancreate: %r");
redraw(1);
- if(proccreate(sampler, nil, mainstacksize) < 0
- || proccreate(drawproc, nil, mainstacksize) < 0)
+ if(proccreate(sampler, nil, mainstacksize) < 0)
sysfatal("proccreate: %r");
}
--- a/fns.h
+++ b/fns.h
@@ -23,7 +23,9 @@
int setjump(vlong);
vlong ss2view(int);
vlong view2ss(int);
+void reset(int);
void redraw(int);
+void paint(int);
void initdrw(int);
void advance(usize);
Chunk* p2c(usize, usize*, Dot*);
--- a/pplay.c
+++ b/pplay.c
@@ -8,6 +8,7 @@
#include "fns.h"
extern QLock lsync;
+extern Channel *drawc;
int stereo, chan;
int debug, paused, notriob;
@@ -129,7 +130,7 @@
void
threadmain(int argc, char **argv)
{
- int i, pid;
+ int i, what, pid;
char *p;
Mouse m, mo;
Channel *waitc;
@@ -167,7 +168,7 @@
if(proccreate(aproc, nil, 16*1024) < 0)
sysfatal("threadcreate: %r");
toggleplay();
- waitc = threadwaitchan();
+ waitc = threadwaitchan(); /* FIXME: unused?? */
enum{
Aresize,
Amouse,
@@ -174,6 +175,7 @@
Akey,
Apid,
Await,
+ Adraw,
};
Alt a[] = {
[Aresize] {mc->resizec, nil, CHANRCV},
@@ -181,6 +183,7 @@
[Akey] {kc->c, &r, CHANRCV},
[Apid] {pidc, &pid, CHANRCV},
[Await] {waitc, &w, CHANRCV},
+ [Adraw] {drawc, &what, CHANRCV},
{nil, nil, CHANEND}
};
for(;;){
@@ -265,6 +268,8 @@
fprint(2, "phase error -- no such pid %d\n", w->pid);
nslots++;
free(w);
+ case Adraw:
+ paint(what);
break;
}
}