diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-04-14 16:28:54 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-04-14 16:28:54 +0200 |
commit | 3045d639691c893dfa3393f88289ad72cbcdd86e (patch) | |
tree | a9e85a6669b8c4ffbc9324cfc35394ceb1b129f9 /sys/src/9/omap | |
parent | 58e500f4a717a9faf912e503fa7ba9cbe71a84cc (diff) |
reduce software cursor flickering
the software cursor starts flickering and reacts bumby if a process
spends most of its time with drawlock acquired because the timer interrupt
thats supposed to redraw the cursor fails to acquire the lock at the time
the timer fires.
instead of trying to draw the cursor on the screen from a timer interrupt
30 times per second, devmouse now creates a process calling cursoron() and
cursoroff() when the cursor needs to be redrawn. this allows the swcursor
to schedule a redraw while holding the drawlock in swcursoravoid() and
cursoron()/cursoroff() are now able to wait for a qlock (drawlock) because
they get called from process context.
the overall responsiveness is also improved with this change as the cursor
redraw rate isnt limited to 30 times a second anymore.
Diffstat (limited to 'sys/src/9/omap')
-rw-r--r-- | sys/src/9/omap/beagle | 2 | ||||
-rw-r--r-- | sys/src/9/omap/screen.c | 167 | ||||
-rw-r--r-- | sys/src/9/omap/screen.h | 13 |
3 files changed, 24 insertions, 158 deletions
diff --git a/sys/src/9/omap/beagle b/sys/src/9/omap/beagle index 8852bd7d4..3dea87477 100644 --- a/sys/src/9/omap/beagle +++ b/sys/src/9/omap/beagle @@ -24,7 +24,7 @@ dev ether netif ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum inferno - draw screen + draw screen swcursor dss mouse diff --git a/sys/src/9/omap/screen.c b/sys/src/9/omap/screen.c index e47fd2821..f2ec47054 100644 --- a/sys/src/9/omap/screen.c +++ b/sys/src/9/omap/screen.c @@ -346,174 +346,33 @@ screenpower(int on) blankscreen(on == 0); } -/* - * called with drawlock locked for us, most of the time. - * kernel prints at inopportune times might mean we don't - * hold the lock, but memimagedraw is now reentrant so - * that should be okay: worst case we get cursor droppings. - */ -void -swcursorhide(void) -{ - if(swvisible == 0) - return; - if(swback == nil) - return; - swvisible = 0; - memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S); - flushmemscreen(swrect); -} - -void -swcursoravoid(Rectangle r) -{ - if(swvisible && rectXrect(r, swrect)) - swcursorhide(); -} - -void -swcursordraw(void) -{ - if(swvisible) - return; - if(swenabled == 0) - return; - if(swback == nil || swimg1 == nil || swmask1 == nil) - return; -// assert(!canqlock(&drawlock)); // assertion fails on omap - swvispt = swpt; - swvisvers = swvers; - swrect = rectaddpt(Rect(0,0,16,16), swvispt); - memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S); - memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD); - flushmemscreen(swrect); - swvisible = 1; -} - -int -cursoron(int dolock) -{ - if (dolock) - lock(&oscreen); - cursoroff(0); - swcursordraw(); - if (dolock) - unlock(&oscreen); - return 0; -} - void -cursoroff(int dolock) +cursoron(void) { - if (dolock) - lock(&oscreen); + qlock(&drawlock); + lock(&cursor); swcursorhide(); - if (dolock) - unlock(&oscreen); + swcursordraw(mousexy()); + unlock(&cursor); + qunlock(&drawlock); } void -swload(Cursor *curs) +cursoroff(void) { - uchar *ip, *mp; - int i, j, set, clr; - - if(!swimg || !swmask || !swimg1 || !swmask1) - return; - /* - * Build cursor image and mask. - * Image is just the usual cursor image - * but mask is a transparent alpha mask. - * - * The 16x16x8 memimages do not have - * padding at the end of their scan lines. - */ - ip = byteaddr(swimg, ZP); - mp = byteaddr(swmask, ZP); - for(i=0; i<32; i++){ - set = curs->set[i]; - clr = curs->clr[i]; - for(j=0x80; j; j>>=1){ - *ip++ = set&j ? 0x00 : 0xFF; - *mp++ = (clr|set)&j ? 0xFF : 0x00; - } - } - swoffset = curs->offset; - swvers++; - memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S); - memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S); + qlock(&drawlock); + lock(&cursor); + swcursorhide(); + unlock(&cursor); + qunlock(&drawlock); } /* called from devmouse */ void setcursor(Cursor* curs) { - cursoroff(1); oscreen.Cursor = *curs; - swload(curs); - cursoron(1); -} - -int -swmove(Point p) -{ - swpt = addpt(p, swoffset); - return 0; -} - -void -swcursorclock(void) -{ - int x; - - if(!swenabled) - return; - swmove(mousexy()); - if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers) - return; - - x = splhi(); - if(swenabled) - if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers) - if(canqlock(&drawlock)){ - swcursorhide(); - swcursordraw(); - qunlock(&drawlock); - } - splx(x); -} - -void -swcursorinit(void) -{ - static int init; - - if(!init){ - init = 1; - addclock0link(swcursorclock, 10); - } - if(swback){ - freememimage(swback); - freememimage(swmask); - freememimage(swmask1); - freememimage(swimg); - freememimage(swimg1); - } - - swback = allocmemimage(Rect(0,0,32,32), gscreen->chan); - swmask = allocmemimage(Rect(0,0,16,16), GREY8); - swmask1 = allocmemimage(Rect(0,0,16,16), GREY1); - swimg = allocmemimage(Rect(0,0,16,16), GREY8); - swimg1 = allocmemimage(Rect(0,0,16,16), GREY1); - if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){ - print("software cursor: allocmemimage fails\n"); - return; - } - - memfillcolor(swmask, DOpaque); - memfillcolor(swmask1, DOpaque); - memfillcolor(swimg, DBlack); - memfillcolor(swimg1, DBlack); + swcursorload(curs); } /* called from main and possibly later from devdss to change resolution */ diff --git a/sys/src/9/omap/screen.h b/sys/src/9/omap/screen.h index 6eff3649c..6083aea15 100644 --- a/sys/src/9/omap/screen.h +++ b/sys/src/9/omap/screen.h @@ -20,12 +20,13 @@ extern Point mousexy(void); extern void mouseaccelerate(int); extern void mouseresize(void); +extern void mouseredraw(void); /* screen.c */ extern uchar* attachscreen(Rectangle*, ulong*, int*, int*, int*); extern void flushmemscreen(Rectangle); -extern int cursoron(int); -extern void cursoroff(int); +extern void cursoron(void); +extern void cursoroff(void); extern void setcursor(Cursor*); extern int screensize(int, int, int, ulong); extern int screenaperture(int, int); @@ -49,6 +50,13 @@ extern QLock drawlock; #define ishwimage(i) 0 /* for ../port/devdraw.c */ +/* swcursor.c */ +void swcursorhide(void); +void swcursoravoid(Rectangle); +void swcursordraw(Point); +void swcursorload(Cursor *); +void swcursorinit(void); + /* for communication between devdss.c and screen.c */ enum { @@ -93,7 +101,6 @@ struct Settings { }; struct OScreen { - Lock; Cursor; Settings *settings; int open; |