ref: acd4f18114be3776e711136609cf23099f0818b2
parent: 9fda8c6d9d2723116d9ecfc8f62d3ae2ac1308ea
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Aug 22 15:38:06 EDT 2022
audio/zuke: faster redraw without flashing - XRGB32 with backing image
--- a/sys/src/cmd/audio/zuke/zuke.c
+++ b/sys/src/cmd/audio/zuke/zuke.c
@@ -82,6 +82,7 @@
static Image *cover;
static Channel *playc;
static Channel *redrawc;
+static Image *back;
static Mousectl *mctl;
static Keyboardctl *kctl;
static int colwidth[10];
@@ -302,85 +303,89 @@
uvlong dur, msec;
char tmp[32];
- lockdisplay(display);
+ if(back == nil || Dx(screen->r) != Dx(back->r) || Dy(screen->r) != Dy(back->r)){
+ freeimage(back);
+ back = allocimage(display, Rpt(ZP,subpt(screen->r.max, screen->r.min)), XRGB32, 0, DNofill);
+ }
+
updatescrollsz();
scroll = CLAMP(scroll, 0, pl->n - scrollsz);
- left = screen->r.min.x;
+ left = back->r.min.x;
if(scrollsz < pl->n) /* adjust for scrollbar */
left += Scrollwidth + 1;
if(full){
- draw(screen, screen->r, colors[Dback].im, nil, ZP);
+ draw(back, back->r, colors[Dback].im, nil, ZP);
adjustcolumns();
if(scrollsz < pl->n){ /* scrollbar */
- p.x = sp.x = screen->r.min.x + Scrollwidth;
- p.y = screen->r.min.y;
- sp.y = screen->r.max.y;
- line(screen, p, sp, Endsquare, Endsquare, 0, colors[Dflow].im, ZP);
+ p.x = sp.x = back->r.min.x + Scrollwidth;
+ p.y = back->r.min.y;
+ sp.y = back->r.max.y;
+ line(back, p, sp, Endsquare, Endsquare, 0, colors[Dflow].im, ZP);
- r = screen->r;
+ r = back->r;
r.max.x = r.min.x + Scrollwidth - 1;
r.min.x += 1;
if(scroll < 1)
scrollcenter = 0;
else
- scrollcenter = (Dy(screen->r)-Scrollheight*5/4)*scroll / (pl->n - scrollsz);
+ scrollcenter = (Dy(back->r)-Scrollheight*5/4)*scroll / (pl->n - scrollsz);
r.min.y += scrollcenter + Scrollheight/4;
r.max.y = r.min.y + Scrollheight;
- draw(screen, r, colors[Dblow].im, nil, ZP);
+ draw(back, r, colors[Dblow].im, nil, ZP);
}
p.x = sp.x = left;
p.y = 0;
- sp.y = screen->r.max.y;
+ sp.y = back->r.max.y;
for(i = 0; cols[i+1] != 0; i++){
p.x += colwidth[i] + 4;
sp.x = p.x;
- line(screen, p, sp, Endsquare, Endsquare, 0, colors[Dflow].im, ZP);
+ line(back, p, sp, Endsquare, Endsquare, 0, colors[Dflow].im, ZP);
p.x += 4;
}
sp.x = sp.y = 0;
p.x = left + 2;
- p.y = screen->r.min.y + 2;
+ p.y = back->r.min.y + 2;
for(i = scroll; i < pl->n; i++, p.y += f->height){
if(i < 0)
continue;
- if(p.y > screen->r.max.y)
+ if(p.y > back->r.max.y)
break;
if(pcur == i){
sel.min.x = left;
sel.min.y = p.y;
- sel.max.x = screen->r.max.x;
+ sel.max.x = back->r.max.x;
sel.max.y = p.y + f->height;
- draw(screen, sel, colors[Dbinv].im, nil, ZP);
+ draw(back, sel, colors[Dbinv].im, nil, ZP);
col = colors[Dfinv].im;
}else{
col = colors[Dfmed].im;
}
- sel = screen->r;
+ sel = back->r;
p.x = left + 2 + 3;
for(j = 0; cols[j] != 0; j++){
sel.max.x = p.x + colwidth[j];
- replclipr(screen, 0, sel);
- string(screen, p, col, sp, f, getcol(getmeta(i), cols[j]));
+ replclipr(back, 0, sel);
+ string(back, p, col, sp, f, getcol(getmeta(i), cols[j]));
p.x += colwidth[j] + 8;
}
- replclipr(screen, 0, screen->r);
+ replclipr(back, 0, back->r);
if(pcurplaying == i){
Point rightp, leftp;
leftp.y = rightp.y = p.y - 1;
leftp.x = left;
- rightp.x = screen->r.max.x;
- line(screen, leftp, rightp, 0, 0, 0, colors[Dflow].im, sp);
+ rightp.x = back->r.max.x;
+ line(back, leftp, rightp, 0, 0, 0, colors[Dflow].im, sp);
leftp.y = rightp.y = p.y + f->height;
- line(screen, leftp, rightp, 0, 0, 0, colors[Dflow].im, sp);
+ line(back, leftp, rightp, 0, 0, 0, colors[Dflow].im, sp);
}
}
}
@@ -413,28 +418,28 @@
w = stringwidth(f, tmp);
snprint(tmp, sizeof(tmp), "%s%d%%", shuffle != nil ? "∫ " : "", volume);
}
- r = screen->r;
+ r = back->r;
right = r.max.x - w - 4;
r.min.x = left;
r.min.y = r.max.y - f->height - 4;
if(pcurplaying < 0 || dur == 0)
r.min.x = right;
- draw(screen, r, colors[Dblow].im, nil, ZP);
+ draw(back, r, colors[Dblow].im, nil, ZP);
p = addpt(Pt(r.max.x-stringwidth(f, tmp)-4, r.min.y), Pt(2, 2));
r.max.x = right;
- string(screen, p, colors[Dfhigh].im, sp, f, tmp);
+ string(back, p, colors[Dfhigh].im, sp, f, tmp);
sel = r;
if(cover != nil && full){
r.max.x = r.min.x;
- r.min.x = screen->r.max.x - cover->r.max.x - 8;
- draw(screen, r, colors[Dblow].im, nil, ZP);
- r = screen->r;
+ r.min.x = back->r.max.x - cover->r.max.x - 8;
+ draw(back, r, colors[Dblow].im, nil, ZP);
+ r = back->r;
r.min.x = r.max.x - cover->r.max.x - 8;
r.min.y = r.max.y - cover->r.max.y - 8 - f->height - 4;
r.max.y = r.min.y + cover->r.max.y + 8;
- draw(screen, r, colors[Dblow].im, nil, ZP);
- draw(screen, insetrect(r, 4), cover, nil, ZP);
+ draw(back, r, colors[Dblow].im, nil, ZP);
+ draw(back, insetrect(r, 4), cover, nil, ZP);
}
/* seek bar */
@@ -441,14 +446,14 @@
seekbar = ZR;
if(pcurplaying >= 0 && dur > 0){
r = insetrect(sel, 3);
- draw(screen, r, colors[Dback].im, nil, ZP);
+ draw(back, r, colors[Dback].im, nil, ZP);
seekbar = r;
r.max.x = r.min.x + Dx(r) * (double)msec / (double)dur;
- draw(screen, r, colors[Dbmed].im, nil, ZP);
+ draw(back, r, colors[Dbmed].im, nil, ZP);
}
+ draw(screen, screen->r, back, nil, ZP);
flushimage(display, 1);
- unlockdisplay(display);
}
static void
@@ -1158,8 +1163,6 @@
Scrollwidth = MAX(14, stringwidth(f, "#"));
Scrollheight = MAX(16, f->height);
Coversz = MAX(64, stringwidth(f, "∫ 00:00:00/00:00:00 100%"));
- unlockdisplay(display);
- display->locking = 1;
if((mctl = initmouse(nil, screen)) == nil)
sysfatal("initmouse: %r");
if((kctl = initkeyboard(nil)) == nil)
@@ -1175,7 +1178,7 @@
proccreate(redrawproc, nil, 8192);
for(n = 0; n < Numcolors; n++)
- colors[n].im = allocimage(display, Rect(0,0,1,1), RGB24, 1, colors[n].rgb<<8 | 0xff);
+ colors[n].im = allocimage(display, Rect(0,0,1,1), XRGB32, 1, colors[n].rgb<<8 | 0xff);
srand(time(0));
pcurplaying = -1;