commit 587933c16132d880a06ff99bd087e64a3a04975e from: Russ Cox date: Mon May 18 03:24:29 2020 UTC devdraw: use global drawlk instead of per-client Setting up for a real window system. commit - 94d381ec9d579e5336f3817b68cf4d1a8a7333db commit + 587933c16132d880a06ff99bd087e64a3a04975e blob - 6269dfdaf11450560efbc0da3818aae3daf5401d blob + 234cdf1b2c73a25a49c2ae2790cabfc678bf3f91 --- src/cmd/devdraw/devdraw.c +++ 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; } blob - 1dac2d506f0ccd9d63dc2682cfc6a713db64f348 blob + 261d04d1efbaa3745c60131220fa30e4c678accb --- src/cmd/devdraw/devdraw.h +++ 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; blob - 9454be05d4cfd797629989c3f438b57a434f650b blob + ad9c029e7661de4d1c32ef63605f87bba1a1780e --- src/cmd/devdraw/mac-screen.m +++ 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;