devdraw: use global drawlk instead of per-client
Setting up for a real window system.
This commit is contained in:
parent
94d381ec9d
commit
587933c161
3 changed files with 20 additions and 18 deletions
|
|
@ -14,6 +14,8 @@
|
||||||
#include <drawfcall.h>
|
#include <drawfcall.h>
|
||||||
#include "devdraw.h"
|
#include "devdraw.h"
|
||||||
|
|
||||||
|
QLock drawlk;
|
||||||
|
|
||||||
static int drawuninstall(Client*, int);
|
static int drawuninstall(Client*, int);
|
||||||
static Memimage* drawinstall(Client*, int, Memimage*, DScreen*);
|
static Memimage* drawinstall(Client*, int, Memimage*, DScreen*);
|
||||||
static void drawfreedimage(Client*, DImage*);
|
static void drawfreedimage(Client*, DImage*);
|
||||||
|
|
@ -47,14 +49,14 @@ gfx_replacescreenimage(Client *c, Memimage *m)
|
||||||
*/
|
*/
|
||||||
Memimage *om;
|
Memimage *om;
|
||||||
|
|
||||||
qlock(&c->drawlk);
|
qlock(&drawlk);
|
||||||
om = c->screenimage;
|
om = c->screenimage;
|
||||||
c->screenimage = m;
|
c->screenimage = m;
|
||||||
m->screenref = 1;
|
m->screenref = 1;
|
||||||
if(om && --om->screenref == 0){
|
if(om && --om->screenref == 0){
|
||||||
_freememimage(om);
|
_freememimage(om);
|
||||||
}
|
}
|
||||||
qunlock(&c->drawlk);
|
qunlock(&drawlk);
|
||||||
gfx_mouseresized(c);
|
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
|
// and gfx thread might be blocked on drawlk trying to install a new screen
|
||||||
// during a resize.
|
// during a resize.
|
||||||
rpc_gfxdrawunlock();
|
rpc_gfxdrawunlock();
|
||||||
qunlock(&c->drawlk);
|
qunlock(&drawlk);
|
||||||
c->impl->rpc_flush(c, fr);
|
c->impl->rpc_flush(c, fr);
|
||||||
qlock(&c->drawlk);
|
qlock(&drawlk);
|
||||||
rpc_gfxdrawlock();
|
rpc_gfxdrawlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -187,9 +189,9 @@ drawflush(Client *c)
|
||||||
// and gfx thread might be blocked on drawlk trying to install a new screen
|
// and gfx thread might be blocked on drawlk trying to install a new screen
|
||||||
// during a resize.
|
// during a resize.
|
||||||
rpc_gfxdrawunlock();
|
rpc_gfxdrawunlock();
|
||||||
qunlock(&c->drawlk);
|
qunlock(&drawlk);
|
||||||
c->impl->rpc_flush(c, r);
|
c->impl->rpc_flush(c, r);
|
||||||
qlock(&c->drawlk);
|
qlock(&drawlk);
|
||||||
rpc_gfxdrawlock();
|
rpc_gfxdrawlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -614,7 +616,7 @@ drawcoord(uchar *p, uchar *maxp, int oldx, int *newx)
|
||||||
int
|
int
|
||||||
draw_dataread(Client *cl, void *a, int n)
|
draw_dataread(Client *cl, void *a, int n)
|
||||||
{
|
{
|
||||||
qlock(&cl->drawlk);
|
qlock(&drawlk);
|
||||||
if(cl->readdata == nil){
|
if(cl->readdata == nil){
|
||||||
werrstr("no draw data");
|
werrstr("no draw data");
|
||||||
goto err;
|
goto err;
|
||||||
|
|
@ -627,11 +629,11 @@ draw_dataread(Client *cl, void *a, int n)
|
||||||
memmove(a, cl->readdata, cl->nreaddata);
|
memmove(a, cl->readdata, cl->nreaddata);
|
||||||
free(cl->readdata);
|
free(cl->readdata);
|
||||||
cl->readdata = nil;
|
cl->readdata = nil;
|
||||||
qunlock(&cl->drawlk);
|
qunlock(&drawlk);
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
qunlock(&cl->drawlk);
|
qunlock(&drawlk);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -656,7 +658,7 @@ draw_datawrite(Client *client, void *v, int n)
|
||||||
Refreshfn reffn;
|
Refreshfn reffn;
|
||||||
Refx *refx;
|
Refx *refx;
|
||||||
|
|
||||||
qlock(&client->drawlk);
|
qlock(&drawlk);
|
||||||
rpc_gfxdrawlock();
|
rpc_gfxdrawlock();
|
||||||
a = v;
|
a = v;
|
||||||
m = 0;
|
m = 0;
|
||||||
|
|
@ -1431,7 +1433,7 @@ draw_datawrite(Client *client, void *v, int n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rpc_gfxdrawunlock();
|
rpc_gfxdrawunlock();
|
||||||
qunlock(&client->drawlk);
|
qunlock(&drawlk);
|
||||||
return oldn - n;
|
return oldn - n;
|
||||||
|
|
||||||
Enodrawimage:
|
Enodrawimage:
|
||||||
|
|
@ -1502,6 +1504,6 @@ Ebadarg:
|
||||||
error:
|
error:
|
||||||
werrstr("%s", err);
|
werrstr("%s", err);
|
||||||
rpc_gfxdrawunlock();
|
rpc_gfxdrawunlock();
|
||||||
qunlock(&client->drawlk);
|
qunlock(&drawlk);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ struct ClientImpl
|
||||||
void (*rpc_flush)(Client*, Rectangle);
|
void (*rpc_flush)(Client*, Rectangle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern QLock drawlk;
|
||||||
|
|
||||||
struct Client
|
struct Client
|
||||||
{
|
{
|
||||||
int rfd;
|
int rfd;
|
||||||
|
|
@ -69,10 +71,9 @@ struct Client
|
||||||
|
|
||||||
char* wsysid;
|
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
|
// 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.
|
// but must not be held on one thread while waiting for the other.
|
||||||
QLock drawlk;
|
|
||||||
/*Ref r;*/
|
/*Ref r;*/
|
||||||
DImage* dimage[NHASH];
|
DImage* dimage[NHASH];
|
||||||
CScreen* cscreen;
|
CScreen* cscreen;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ static uint msec(void);
|
||||||
|
|
||||||
static void rpc_resizeimg(Client*);
|
static void rpc_resizeimg(Client*);
|
||||||
static void rpc_resizewindow(Client*, Rectangle);
|
static void rpc_resizewindow(Client*, Rectangle);
|
||||||
static void rpc_serve(Client*);
|
|
||||||
static void rpc_setcursor(Client*, Cursor*, Cursor2*);
|
static void rpc_setcursor(Client*, Cursor*, Cursor2*);
|
||||||
static void rpc_setlabel(Client*, char*);
|
static void rpc_setlabel(Client*, char*);
|
||||||
static void rpc_setmouse(Client*, Point);
|
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))
|
if(!rectclip(&r, Rect(0, 0, self.dlayer.texture.width, self.dlayer.texture.height)) || !rectclip(&r, self.img->r))
|
||||||
return;
|
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,
|
// In addition to avoiding a technical data race,
|
||||||
// the lock avoids drawing partial updates, which makes
|
// the lock avoids drawing partial updates, which makes
|
||||||
// animations like sweeping windows much less flickery.
|
// animations like sweeping windows much less flickery.
|
||||||
qlock(&self.client->drawlk);
|
qlock(&drawlk);
|
||||||
[self.dlayer.texture
|
[self.dlayer.texture
|
||||||
replaceRegion:MTLRegionMake2D(r.min.x, r.min.y, Dx(r), Dy(r))
|
replaceRegion:MTLRegionMake2D(r.min.x, r.min.y, Dx(r), Dy(r))
|
||||||
mipmapLevel:0
|
mipmapLevel:0
|
||||||
withBytes:byteaddr(self.img, Pt(r.min.x, r.min.y))
|
withBytes:byteaddr(self.img, Pt(r.min.x, r.min.y))
|
||||||
bytesPerRow:self.img->width*sizeof(u32int)];
|
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));
|
NSRect nr = NSMakeRect(r.min.x, r.min.y, Dx(r), Dy(r));
|
||||||
dispatch_time_t time;
|
dispatch_time_t time;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue