From 587933c16132d880a06ff99bd087e64a3a04975e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sat, 25 Jan 2020 14:33:20 -0500 Subject: devdraw: use global drawlk instead of per-client Setting up for a real window system. --- src/cmd/devdraw/devdraw.c | 26 ++++++++++++++------------ src/cmd/devdraw/devdraw.h | 5 +++-- src/cmd/devdraw/mac-screen.m | 7 +++---- 3 files changed, 20 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/cmd/devdraw/devdraw.c b/src/cmd/devdraw/devdraw.c index 6269dfda..234cdf1b 100644 --- a/src/cmd/devdraw/devdraw.c +++ b/src/cmd/devdraw/devdraw.c @@ -14,6 +14,8 @@ #include #include "devdraw.h" +QLock drawlk; + static int drawuninstall(Client*, int); static Memimage* drawinstall(Client*, int, Memimage*, DScreen*); static void drawfreedimage(Client*, DImage*); @@ -47,14 +49,14 @@ gfx_replacescreenimage(Client *c, Memimage *m) */ Memimage *om; - qlock(&c->drawlk); + qlock(&drawlk); om = c->screenimage; c->screenimage = m; m->screenref = 1; if(om && --om->screenref == 0){ _freememimage(om); } - qunlock(&c->drawlk); + qunlock(&drawlk); gfx_mouseresized(c); } @@ -142,9 +144,9 @@ addflush(Client *c, Rectangle r) // and gfx thread might be blocked on drawlk trying to install a new screen // during a resize. rpc_gfxdrawunlock(); - qunlock(&c->drawlk); + qunlock(&drawlk); c->impl->rpc_flush(c, fr); - qlock(&c->drawlk); + qlock(&drawlk); rpc_gfxdrawlock(); } } @@ -187,9 +189,9 @@ drawflush(Client *c) // and gfx thread might be blocked on drawlk trying to install a new screen // during a resize. rpc_gfxdrawunlock(); - qunlock(&c->drawlk); + qunlock(&drawlk); c->impl->rpc_flush(c, r); - qlock(&c->drawlk); + qlock(&drawlk); rpc_gfxdrawlock(); } } @@ -614,7 +616,7 @@ drawcoord(uchar *p, uchar *maxp, int oldx, int *newx) int draw_dataread(Client *cl, void *a, int n) { - qlock(&cl->drawlk); + qlock(&drawlk); if(cl->readdata == nil){ werrstr("no draw data"); goto err; @@ -627,11 +629,11 @@ draw_dataread(Client *cl, void *a, int n) memmove(a, cl->readdata, cl->nreaddata); free(cl->readdata); cl->readdata = nil; - qunlock(&cl->drawlk); + qunlock(&drawlk); return n; err: - qunlock(&cl->drawlk); + qunlock(&drawlk); return -1; } @@ -656,7 +658,7 @@ draw_datawrite(Client *client, void *v, int n) Refreshfn reffn; Refx *refx; - qlock(&client->drawlk); + qlock(&drawlk); rpc_gfxdrawlock(); a = v; m = 0; @@ -1431,7 +1433,7 @@ draw_datawrite(Client *client, void *v, int n) } } rpc_gfxdrawunlock(); - qunlock(&client->drawlk); + qunlock(&drawlk); return oldn - n; Enodrawimage: @@ -1502,6 +1504,6 @@ Ebadarg: error: werrstr("%s", err); rpc_gfxdrawunlock(); - qunlock(&client->drawlk); + qunlock(&drawlk); return -1; } diff --git a/src/cmd/devdraw/devdraw.h b/src/cmd/devdraw/devdraw.h index 1dac2d50..261d04d1 100644 --- a/src/cmd/devdraw/devdraw.h +++ b/src/cmd/devdraw/devdraw.h @@ -56,6 +56,8 @@ struct ClientImpl void (*rpc_flush)(Client*, Rectangle); }; +extern QLock drawlk; + struct Client { int rfd; @@ -69,10 +71,9 @@ struct Client char* wsysid; - // drawlk protects the draw data structures. + // drawlk protects the draw data structures for all clients. // It can be acquired by an RPC thread or a graphics thread // but must not be held on one thread while waiting for the other. - QLock drawlk; /*Ref r;*/ DImage* dimage[NHASH]; CScreen* cscreen; diff --git a/src/cmd/devdraw/mac-screen.m b/src/cmd/devdraw/mac-screen.m index 9454be05..ad9c029e 100644 --- a/src/cmd/devdraw/mac-screen.m +++ b/src/cmd/devdraw/mac-screen.m @@ -39,7 +39,6 @@ static uint msec(void); static void rpc_resizeimg(Client*); static void rpc_resizewindow(Client*, Rectangle); -static void rpc_serve(Client*); static void rpc_setcursor(Client*, Cursor*, Cursor2*); static void rpc_setlabel(Client*, char*); static void rpc_setmouse(Client*, Point); @@ -496,17 +495,17 @@ rpc_flush(Client *client, Rectangle r) if(!rectclip(&r, Rect(0, 0, self.dlayer.texture.width, self.dlayer.texture.height)) || !rectclip(&r, self.img->r)) return; - // self.client->drawlk protects the pixel data in self.img. + // drawlk protects the pixel data in self.img. // In addition to avoiding a technical data race, // the lock avoids drawing partial updates, which makes // animations like sweeping windows much less flickery. - qlock(&self.client->drawlk); + qlock(&drawlk); [self.dlayer.texture replaceRegion:MTLRegionMake2D(r.min.x, r.min.y, Dx(r), Dy(r)) mipmapLevel:0 withBytes:byteaddr(self.img, Pt(r.min.x, r.min.y)) bytesPerRow:self.img->width*sizeof(u32int)]; - qunlock(&self.client->drawlk); + qunlock(&drawlk); NSRect nr = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r)); dispatch_time_t time; -- cgit v1.2.3