summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-04-11 20:56:59 +0000
committercinap_lenrek <cinap_lenrek@localhost>2011-04-11 20:56:59 +0000
commit632defb65612ae342358a4effc5ae71c8d90b8b8 (patch)
tree73fd1ef6439f860482b9ffca78bcc5997a2958a0
parent45bab89362ebe122d60d5e9b1e2b949b26168db3 (diff)
vesa-changes
-rw-r--r--sys/src/9/pc/devvga.c5
-rw-r--r--sys/src/9/pc/screen.c181
-rw-r--r--sys/src/9/pc/vga.c105
-rw-r--r--sys/src/9/pc/vgavesa.c19
-rw-r--r--sys/src/9/port/devdraw.c61
-rw-r--r--sys/src/cmd/aux/vga/main.c8
-rw-r--r--sys/src/cmd/aux/vga/vesa.c353
-rw-r--r--sys/src/cmd/aux/vga/vesadb.c20
-rw-r--r--sys/src/libmemdraw/draw.c182
-rw-r--r--sys/src/libmemdraw/load.c7
10 files changed, 547 insertions, 394 deletions
diff --git a/sys/src/9/pc/devvga.c b/sys/src/9/pc/devvga.c
index ae28fdd79..8cd2f9583 100644
--- a/sys/src/9/pc/devvga.c
+++ b/sys/src/9/pc/devvga.c
@@ -368,11 +368,6 @@ vgactl(Cmdbuf *cb)
if(screenaperture(size, align) < 0)
error("not enough free address space");
return;
-/*
- case CMmemset:
- memset((void*)strtoul(cb->f[1], 0, 0), atoi(cb->f[2]), atoi(cb->f[3]));
- return;
-*/
case CMblank:
drawblankscreen(1);
diff --git a/sys/src/9/pc/screen.c b/sys/src/9/pc/screen.c
index d1d4ae729..b585c36ce 100644
--- a/sys/src/9/pc/screen.c
+++ b/sys/src/9/pc/screen.c
@@ -19,7 +19,6 @@ Point ZP = {0, 0};
Rectangle physgscreenr;
-Memdata gscreendata;
Memimage *gscreen;
VGAscr vgascreen[1];
@@ -40,13 +39,18 @@ Cursor arrow = {
int didswcursorinit;
-static void *softscreen;
-
int
-screensize(int x, int y, int z, ulong chan)
+screensize(int x, int y, int, ulong chan)
{
VGAscr *scr;
- void *oldsoft;
+
+ qlock(&drawlock);
+ if(waserror()){
+ qunlock(&drawlock);
+ nexterror();
+ }
+
+ memimageinit();
lock(&vgascreenlock);
if(waserror()){
@@ -54,54 +58,51 @@ screensize(int x, int y, int z, ulong chan)
nexterror();
}
- memimageinit();
scr = &vgascreen[0];
- oldsoft = softscreen;
+ scr->gscreendata = nil;
+ scr->gscreen = nil;
+ if(gscreen){
+ freememimage(gscreen);
+ gscreen = nil;
+ }
if(scr->paddr == 0){
- int width = (x*z)/BI2WD;
- void *p;
-
- p = xalloc(width*BY2WD*y);
- if(p == nil)
- error("no memory for vga soft screen");
- gscreendata.bdata = softscreen = p;
+ gscreen = allocmemimage(Rect(0,0,x,y), chan);
if(scr->dev && scr->dev->page){
scr->vaddr = KADDR(VGAMEM());
scr->apsize = 1<<16;
}
scr->useflush = 1;
- }
- else{
- gscreendata.bdata = scr->vaddr;
+ }else{
+ static Memdata md;
+
+ md.ref = 1;
+ md.bdata = scr->vaddr;
+ gscreen = allocmemimaged(Rect(0,0,x,y), chan, &md);
scr->useflush = scr->dev && scr->dev->flush;
}
-
- scr->gscreen = nil;
- if(gscreen)
- freememimage(gscreen);
- gscreen = allocmemimaged(Rect(0,0,x,y), chan, &gscreendata);
if(gscreen == nil)
error("no memory for vga memimage");
- vgaimageinit(chan);
scr->palettedepth = 6; /* default */
- scr->gscreendata = &gscreendata;
scr->memdefont = getmemdefont();
scr->gscreen = gscreen;
+ scr->gscreendata = gscreen->data;
physgscreenr = gscreen->r;
+
+ vgaimageinit(chan);
+
unlock(&vgascreenlock);
poperror();
- if(oldsoft)
- xfree(oldsoft);
-
- memimagedraw(gscreen, gscreen->r, memblack, ZP, nil, ZP, S);
- flushmemscreen(gscreen->r);
+ drawcmap();
if(didswcursorinit)
swcursorinit();
- drawcmap();
+
+ qunlock(&drawlock);
+ poperror();
+
return 0;
}
@@ -152,8 +153,17 @@ attachscreen(Rectangle* r, ulong* chan, int* d, int* width, int *softscreen)
*chan = scr->gscreen->chan;
*d = scr->gscreen->depth;
*width = scr->gscreen->width;
- *softscreen = scr->useflush;
-
+ if(scr->gscreendata->allocd){
+ /*
+ * we use a memimage as softscreen. devdraw will create its own
+ * screen image on the backing store of that image. when our gscreen
+ * and devdraws screenimage gets freed, the imagedata will
+ * be released.
+ */
+ *softscreen = 0xa110c;
+ scr->gscreendata->ref++;
+ } else
+ *softscreen = scr->useflush ? 1 : 0;
return scr->gscreendata->bdata;
}
@@ -168,12 +178,12 @@ flushmemscreen(Rectangle r)
int y, len, incs, off, page;
scr = &vgascreen[0];
+ if(scr->gscreen == nil || scr->useflush == 0)
+ return;
if(scr->dev && scr->dev->flush){
scr->dev->flush(scr, r);
return;
}
- if(scr->gscreen == nil || scr->useflush == 0)
- return;
if(scr->dev == nil || scr->dev->page == nil)
return;
@@ -185,7 +195,6 @@ flushmemscreen(Rectangle r)
switch(scr->gscreen->depth){
default:
len = 0;
- panic("flushmemscreen: depth\n");
break;
case 8:
len = Dx(r);
@@ -358,36 +367,31 @@ hwdraw(Memdrawparam *par)
{
VGAscr *scr;
Memimage *dst, *src, *mask;
+ Memdata *scrd;
int m;
- if(hwaccel == 0)
- return 0;
-
scr = &vgascreen[0];
- if((dst=par->dst) == nil || dst->data == nil)
+ scrd = scr->gscreendata;
+ if(scr->gscreen == nil || scrd == nil)
return 0;
- if((src=par->src) == nil || src->data == nil)
+ if((dst = par->dst) == nil || dst->data == nil)
return 0;
- if((mask=par->mask) == nil || mask->data == nil)
- return 0;
-
+ if((src = par->src) && src->data == nil)
+ src = nil;
+ if((mask = par->mask) && mask->data == nil)
+ mask = nil;
if(scr->cur == &swcursor){
- /*
- * always calling swcursorhide here doesn't cure
- * leaving cursor tracks nor failing to refresh menus
- * with the latest libmemdraw/draw.c.
- */
- if(dst->data->bdata == gscreendata.bdata)
+ if(dst->data->bdata == scrd->bdata)
swcursoravoid(par->r);
- if(src->data->bdata == gscreendata.bdata)
+ if(src && src->data->bdata == scrd->bdata)
swcursoravoid(par->sr);
- if(mask->data->bdata == gscreendata.bdata)
+ if(mask && mask->data->bdata == scrd->bdata)
swcursoravoid(par->mr);
}
-
- if(dst->data->bdata != gscreendata.bdata)
+ if(hwaccel == 0)
+ return 0;
+ if(dst->data->bdata != scrd->bdata || src == nil || mask == nil)
return 0;
-
if(scr->fill==nil && scr->scroll==nil)
return 0;
@@ -607,29 +611,6 @@ swcursordraw(void)
swvisible = 1;
}
-/*
- * Need to lock drawlock for ourselves.
- */
-void
-swenable(VGAscr*)
-{
- swenabled = 1;
- if(canqlock(&drawlock)){
- swcursordraw();
- qunlock(&drawlock);
- }
-}
-
-void
-swdisable(VGAscr*)
-{
- swenabled = 0;
- if(canqlock(&drawlock)){
- swcursorhide();
- qunlock(&drawlock);
- }
-}
-
void
swload(VGAscr*, Cursor *curs)
{
@@ -693,7 +674,7 @@ swcursorclock(void)
void
swcursorinit(void)
{
- static int init, warned;
+ static int init;
VGAscr *scr;
didswcursorinit = 1;
@@ -701,42 +682,56 @@ swcursorinit(void)
init = 1;
addclock0link(swcursorclock, 10);
}
- scr = &vgascreen[0];
- if(scr==nil || scr->gscreen==nil)
- return;
- if(scr->dev == nil || scr->dev->linear == nil){
- if(!warned){
- print("cannot use software cursor on non-linear vga screen\n");
- warned = 1;
- }
+ scr = &vgascreen[0];
+ if(scr->gscreen==nil)
return;
- }
if(swback){
freememimage(swback);
freememimage(swmask);
freememimage(swmask1);
freememimage(swimg);
- freememimage(swimg1);
+ 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){
+ if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil)
print("software cursor: allocmemimage fails");
- return;
- }
-
+ memfillcolor(swback, DTransparent);
memfillcolor(swmask, DOpaque);
memfillcolor(swmask1, DOpaque);
memfillcolor(swimg, DBlack);
memfillcolor(swimg1, DBlack);
}
+/*
+ * Need to lock drawlock for ourselves.
+ */
+void
+swenable(VGAscr *scr)
+{
+ swenabled = 1;
+ if(canqlock(&drawlock)){
+ swload(scr, &arrow);
+ swcursordraw();
+ qunlock(&drawlock);
+ }
+}
+
+void
+swdisable(VGAscr*)
+{
+ swenabled = 0;
+ if(canqlock(&drawlock)){
+ swcursorhide();
+ qunlock(&drawlock);
+ }
+}
+
VGAcur swcursor =
{
"soft",
diff --git a/sys/src/9/pc/vga.c b/sys/src/9/pc/vga.c
index 587d8c185..265b8455e 100644
--- a/sys/src/9/pc/vga.c
+++ b/sys/src/9/pc/vga.c
@@ -12,8 +12,8 @@
#include <cursor.h>
#include "screen.h"
-static Memimage* back;
static Memimage *conscol;
+static Memimage *back;
static Point curpos;
static Rectangle window;
@@ -23,25 +23,10 @@ Lock vgascreenlock;
int drawdebug;
void
-vgaimageinit(ulong chan)
+vgaimageinit(ulong)
{
- if(back == nil){
- back = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
- if(back == nil)
- panic("back alloc"); /* RSC BUG */
- back->flags |= Frepl;
- back->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
- memfillcolor(back, DBlack);
- }
-
- if(conscol == nil){
- conscol = allocmemimage(Rect(0,0,1,1), chan); /* RSC BUG */
- if(conscol == nil)
- panic("conscol alloc"); /* RSC BUG */
- conscol->flags |= Frepl;
- conscol->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
- memfillcolor(conscol, DWhite);
- }
+ conscol = memblack;
+ back = memwhite;
}
static void
@@ -69,13 +54,11 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
int h, w, pos;
Rectangle r;
-// drawdebug = 1;
if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)])
xp = xbuf;
h = scr->memdefont->height;
switch(buf[0]){
-
case '\n':
if(curpos.y+h >= window.max.y){
vgascroll(scr);
@@ -100,7 +83,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
pos = 4-(pos%4);
*xp++ = curpos.x;
r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y + h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
+ memimagedraw(scr->gscreen, r, back, ZP, nil, ZP, S);
curpos.x += pos*w;
break;
@@ -109,7 +92,7 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
break;
xp--;
r = Rect(*xp, curpos.y, curpos.x, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, ZP, S);
+ memimagedraw(scr->gscreen, r, back, r.min, nil, ZP, S);
combinerect(flushr, r);
curpos.x = *xp;
break;
@@ -126,12 +109,11 @@ vgascreenputc(VGAscr* scr, char* buf, Rectangle *flushr)
*xp++ = curpos.x;
r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
+ memimagedraw(scr->gscreen, r, back, r.min, nil, ZP, S);
memimagestring(scr->gscreen, curpos, conscol, ZP, scr->memdefont, buf);
combinerect(flushr, r);
curpos.x += w;
}
-// drawdebug = 0;
}
static void
@@ -184,19 +166,61 @@ vgascreenputs(char* s, int n)
unlock(&vgascreenlock);
}
+static Memimage*
+mkcolor(Memimage *screen, ulong color)
+{
+ Memimage *i;
+
+ if(i = allocmemimage(Rect(0,0,1,1), screen->chan)){
+ i->flags |= Frepl;
+ i->clipr = screen->r;
+ memfillcolor(i, color);
+ }
+ return i;
+}
+
void
vgascreenwin(VGAscr* scr)
{
- int h, w;
+ Memimage *i;
+ Rectangle r;
+ Point p;
+ int h;
+ qlock(&drawlock);
+
h = scr->memdefont->height;
- w = scr->memdefont->info[' '].width;
+ r = scr->gscreen->r;
+
+ if(i = mkcolor(scr->gscreen, 0x444488FF)){
+ memimagedraw(scr->gscreen, r, i, ZP, nil, ZP, S);
+ freememimage(i);
+ }
+
+ window = insetrect(r, 20);
+ memimagedraw(scr->gscreen, window, conscol, ZP, memopaque, ZP, S);
+ window = insetrect(window, 4);
+ memimagedraw(scr->gscreen, window, back, ZP, memopaque, ZP, S);
+
+ if(i = mkcolor(scr->gscreen, 0xAAAAAAFF)){
+ memimagedraw(scr->gscreen, Rect(window.min.x, window.min.y,
+ window.max.x, window.min.y+h+5+6), i, ZP, nil, ZP, S);
+ freememimage(i);
- window = insetrect(scr->gscreen->r, 48);
- window.max.x = window.min.x+((window.max.x-window.min.x)/w)*w;
- window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
+ window = insetrect(window, 5);
+ p = addpt(window.min, Pt(10, 0));
+ memimagestring(scr->gscreen, p, memblack, ZP, scr->memdefont, " Plan 9 Console ");
+ window.min.y += h+6;
+ } else
+ window = insetrect(window, 5);
+
+ window.max.y = window.min.y+(Dy(window)/h)*h;
curpos = window.min;
+ flushmemscreen(r);
+
+ qunlock(&drawlock);
+
screenputs = vgascreenputs;
}
@@ -240,24 +264,3 @@ addvgaseg(char *name, ulong pa, ulong size)
seg.size = size;
addphysseg(&seg);
}
-
-void
-cornerstring(char *s)
-{
- int h, w;
- VGAscr *scr;
- Rectangle r;
- Point p;
-
- scr = &vgascreen[0];
- if(scr->vaddr == nil || screenputs != vgascreenputs)
- return;
- p = memsubfontwidth(scr->memdefont, s);
- w = p.x;
- h = scr->memdefont->height;
-
- r = Rect(0, 0, w, h);
- memimagedraw(scr->gscreen, r, back, back->r.min, nil, back->r.min, S);
- memimagestring(scr->gscreen, r.min, conscol, ZP, scr->memdefont, s);
-// flushmemscreen(r);
-}
diff --git a/sys/src/9/pc/vgavesa.c b/sys/src/9/pc/vgavesa.c
index 3fe1bfb17..c2ea65138 100644
--- a/sys/src/9/pc/vgavesa.c
+++ b/sys/src/9/pc/vgavesa.c
@@ -62,15 +62,19 @@ vbecall(Ureg *u)
nexterror();
}
pa = PADDR(RMBUF);
- /* TODO: check read and write return values */
- devtab[cmem->type]->write(cmem, modebuf, sizeof modebuf, pa);
- u->trap = 0x10;
- devtab[creg->type]->write(creg, u, sizeof *u, 0);
+ if(devtab[cmem->type]->write(cmem, modebuf, sizeof(modebuf), pa) != sizeof(modebuf))
+ error("write modebuf");
- devtab[creg->type]->read(creg, u, sizeof *u, 0);
+ u->trap = 0x10;
+ if(devtab[creg->type]->write(creg, u, sizeof(*u), 0) != sizeof(*u))
+ error("write ureg");
+ if(devtab[creg->type]->read(creg, u, sizeof(*u), 0) != sizeof(*u))
+ error("read ureg");
if((u->ax&0xFFFF) != 0x004F)
error("vesa bios error");
- devtab[cmem->type]->read(cmem, modebuf, sizeof modebuf, pa);
+
+ if(devtab[cmem->type]->read(cmem, modebuf, sizeof(modebuf), pa) != sizeof(modebuf))
+ error("read modebuf");
poperror();
cclose(creg);
@@ -124,7 +128,7 @@ vesalinear(VGAscr *scr, int, int)
Pcidev *pci;
if(hardscreen) {
- scr->vaddr = 0;
+ scr->vaddr = hardscreen;
scr->paddr = scr->apsize = 0;
return;
}
@@ -180,7 +184,6 @@ vesalinear(VGAscr *scr, int, int)
if(Usesoftscreen){
hardscreen = scr->vaddr;
- scr->vaddr = 0;
scr->paddr = scr->apsize = 0;
}
}
diff --git a/sys/src/9/port/devdraw.c b/sys/src/9/port/devdraw.c
index d11ab05a2..017942194 100644
--- a/sys/src/9/port/devdraw.c
+++ b/sys/src/9/port/devdraw.c
@@ -365,9 +365,8 @@ addflush(Rectangle r)
int abb, ar, anbb;
Rectangle nbb;
- if(sdraw.softscreen==0 || !rectclip(&r, screenimage->r))
+ if(sdraw.softscreen==0 || screenimage == nil || !rectclip(&r, screenimage->r))
return;
-
if(flushrect.min.x >= flushrect.max.x){
flushrect = r;
waste = 0;
@@ -413,13 +412,7 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
combinerect(&flushrect, r);
return;
}
- /* how can this happen? -rsc, dec 12 2002 */
- if(dst == 0){
- print("nil dstflush\n");
- return;
- }
- l = dst->layer;
- if(l == nil)
+ if(screenimage == nil || dst == nil || (l = dst->layer) == nil)
return;
do{
if(l->screen->image->data != screenimage->data)
@@ -433,7 +426,7 @@ dstflush(int dstid, Memimage *dst, Rectangle r)
void
drawflush(void)
{
- if(flushrect.min.x < flushrect.max.x)
+ if(screenimage && flushrect.min.x < flushrect.max.x)
flushmemscreen(flushrect);
flushrect = Rect(10000, 10000, -10000, -10000);
}
@@ -676,12 +669,10 @@ drawfreedimage(DImage *dimage)
drawfreedimage(dimage->fromname);
goto Return;
}
-// if(dimage->image == screenimage) /* don't free the display */
-// goto Return;
ds = dimage->dscreen;
if(ds){
l = dimage->image;
- if(l->data == screenimage->data)
+ if(screenimage && l->data == screenimage->data)
addflush(l->layer->screenr);
if(l->layer->refreshfn == drawrefresh) /* else true owner will clean up */
free(l->layer->refreshptr);
@@ -929,26 +920,36 @@ makescreenimage(void)
Memdata *md;
Memimage *i;
Rectangle r;
+ uchar *data;
- md = malloc(sizeof *md);
- if(md == nil)
- return nil;
- md->allocd = 1;
- md->base = nil;
- md->bdata = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen);
- if(md->bdata == nil){
- free(md);
- return nil;
- }
- md->ref = 1;
- i = allocmemimaged(r, chan, md);
- if(i == nil){
- free(md);
+ if((data = attachscreen(&r, &chan, &depth, &width, &sdraw.softscreen)) == nil)
return nil;
+ if(sdraw.softscreen == 0xa110c){
+ /* hack: softscreen is memimage. */
+ md = *((Memdata**)(data - sizeof(ulong) - sizeof(Memdata*)));
+
+ assert(md->bdata == data);
+ assert(md->ref > 1);
+ assert(md->allocd);
+
+ if((i = allocmemimaged(r, chan, md)) == nil){
+ md->ref--;
+ return nil;
+ }
+ }else{
+ if((md = malloc(sizeof *md)) == nil)
+ return nil;
+ md->allocd = 1;
+ md->base = nil;
+ md->bdata = data;
+ md->ref = 1;
+ if((i = allocmemimaged(r, chan, md)) == nil){
+ free(md);
+ return nil;
+ }
}
i->width = width;
i->clipr = r;
-
di = allocdimage(i);
if(di == nil){
freememimage(i); /* frees md */
@@ -1859,7 +1860,7 @@ drawmesg(Client *client, void *av, int n)
if(pp == nil)
error(Enomem);
doflush = 0;
- if(dstid==0 || (dst->layer && dst->layer->screen->image->data == screenimage->data))
+ if(dstid==0 || (screenimage && dst->layer && dst->layer->screen->image->data == screenimage->data))
doflush = 1; /* simplify test in loop */
ox = oy = 0;
esize = 0;
@@ -2048,7 +2049,7 @@ drawmesg(Client *client, void *av, int n)
memltofrontn(lp, nw);
else
memltorearn(lp, nw);
- if(lp[0]->layer->screen->image->data == screenimage->data)
+ if(screenimage && lp[0]->layer->screen->image->data == screenimage->data)
for(j=0; j<nw; j++)
addflush(lp[j]->layer->screenr);
ll = drawlookup(client, BGLONG(a+1+1+2), 1);
diff --git a/sys/src/cmd/aux/vga/main.c b/sys/src/cmd/aux/vga/main.c
index 77d6ba979..2d3c6a3e7 100644
--- a/sys/src/cmd/aux/vga/main.c
+++ b/sys/src/cmd/aux/vga/main.c
@@ -158,7 +158,7 @@ main(int argc, char** argv)
{
char *bios, buf[256], sizeb[256], *p, *vsize, *psize;
char *type, *vtype;
- int fd, virtual, len;
+ int virtual, len;
Ctlr *ctlr;
Vga *vga;
@@ -455,12 +455,6 @@ main(int argc, char** argv)
else
vgactlw("hwgc", vga->hwgc->name);
- /* might as well initialize the cursor */
- if((fd = open("/dev/cursor", OWRITE)) >= 0){
- write(fd, buf, 0);
- close(fd);
- }
-
if(vga->virtx != vga->mode->x || vga->virty != vga->mode->y){
sprint(buf, "%dx%d", vga->mode->x, vga->mode->y);
vgactlw("actualsize", buf);
diff --git a/sys/src/cmd/aux/vga/vesa.c b/sys/src/cmd/aux/vga/vesa.c
index 4a4c362b8..6df1f8345 100644
--- a/sys/src/cmd/aux/vga/vesa.c
+++ b/sys/src/cmd/aux/vga/vesa.c
@@ -31,8 +31,8 @@ struct Vbe
struct Vmode
{
- char name[32];
- char chan[32];
+ char size[Namelen+1];
+ char chan[Namelen+1];
int id;
int attr; /* flags */
int bpl;
@@ -89,7 +89,9 @@ enum {
#define PLONG(p, v) (p)[0] = (v); (p)[1] = (v)>>8; (p)[2] = (v)>>16; (p)[3] = (v)>>24
static Vbe *vbe;
-static Edid edid;
+static Edid *edid;
+
+extern Mode *vesamodes[];
Vbe *mkvbe(void);
int vbecheck(Vbe*);
@@ -116,6 +118,7 @@ dbvesa(Vga* vga)
fprint(2, "dbvesa: %r\n");
return 0;
}
+
vga->link = alloc(sizeof(Ctlr));
*vga->link = vesa;
vga->vesa = vga->link;
@@ -129,32 +132,38 @@ dbvesa(Vga* vga)
}
Mode*
-dbvesamode(char *mode)
+dbvesamode(char *size)
{
- int i;
+ int i, width;
uchar *p, *ep;
+ Attr *a;
Vmode vm;
Mode *m;
+ Modelist *l;
if(vbe == nil)
return nil;
- p = vbemodes(vbe);
- if(p == nil)
- return nil;
- for(ep=p+1024; (p[0]!=0xFF || p[1]!=0xFF) && p<ep; p+=2){
- if(vbemodeinfo(vbe, WORD(p), &vm) < 0)
- continue;
- if(strcmp(vm.name, mode) == 0)
+ if(strncmp(size, "0x", 2) == 0){
+ if(vbemodeinfo(vbe, strtol(size+2, nil, 16), &vm) == 0)
goto havemode;
- }
- if(1){
- fprint(2, "warning: scanning for unoffered vesa modes\n");
- for(i=0x100; i<0x200; i++){
- if(vbemodeinfo(vbe, i, &vm) < 0)
- continue;
- if(strcmp(vm.name, mode) == 0)
- goto havemode;
+ }else{
+ if(p = vbemodes(vbe)){
+ for(ep=p+1024; (p[0]!=0xFF || p[1]!=0xFF) && p<ep; p+=2){
+ if(vbemodeinfo(vbe, WORD(p), &vm) < 0)
+ continue;
+ if(strcmp(vm.size, size) == 0)
+ goto havemode;
+ }
+ }
+ if(1){
+ fprint(2, "warning: scanning for unoffered vesa modes\n");
+ for(i=0x100; i<0x200; i++){
+ if(vbemodeinfo(vbe, i, &vm) < 0)
+ continue;
+ if(strcmp(vm.size, size) == 0)
+ goto havemode;
+ }
}
}
werrstr("no such vesa mode");
@@ -162,13 +171,8 @@ dbvesamode(char *mode)
havemode:
m = alloc(sizeof(Mode));
- strcpy(m->type, "vesa");
- strcpy(m->size, vm.name);
- strcpy(m->chan, vm.chan);
- m->frequency = 100;
m->x = vm.dx;
m->y = vm.dy;
- m->z = vm.depth;
m->ht = m->x;
m->shb = m->x;
m->ehb = m->x;
@@ -177,11 +181,49 @@ havemode:
m->vt = m->y;
m->vrs = m->y;
m->vre = m->y;
+ m->frequency = m->ht * m->vt * 60;
+
+ /* get default monitor timing */
+ for(i=0; vesamodes[i]; i++){
+ if(vesamodes[i]->x != vm.dx || vesamodes[i]->y != vm.dy)
+ continue;
+ *m = *vesamodes[i];
+ break;
+ }
+ if(edid){
+ for(l = edid->modelist; l; l = l->next){
+ if(l->x != vm.dx || l->y != vm.dy)
+ continue;
+ *m = *((Mode*)l);
+ break;
+ }
+ }
+
+ strcpy(m->type, "vesa");
+ strcpy(m->size, vm.size);
+ strcpy(m->chan, vm.chan);
+ m->z = vm.depth;
+
+ a = alloc(sizeof(Attr));
+ a->attr = "id";
+ a->val = alloc(32);
+ sprint(a->val, "0x%x", vm.id);
+
+ a->next = nil;
+ m->attr = a;
+
+ /* account for framebuffer stride */
+ width = vm.bpl * 8 / m->z;
+ if(width > m->x){
+ a = alloc(sizeof(Attr));
+ a->attr = "virtx";
+ a->val = alloc(32);
+ sprint(a->val, "%d", width);
+
+ a->next = m->attr;
+ m->attr = a;
+ }
- m->attr = alloc(sizeof(Attr));
- m->attr->attr = "id";
- m->attr->val = alloc(32);
- sprint(m->attr->val, "0x%x", vm.id);
return m;
}
@@ -194,7 +236,20 @@ snarf(Vga* vga, Ctlr* ctlr)
vga->vesa = ctlr;
vbesnarf(vbe, vga);
vga->linear = 1;
- ctlr->flag |= Hlinear|Ulinear;
+ ctlr->flag |= Hlinear|Ulinear|Fsnarf;
+}
+
+static void
+options(Vga *vga, Ctlr *ctlr)
+{
+ char *v;
+
+ if(v = dbattr(vga->mode->attr, "virtx")){
+ vga->virtx = atoi(v);
+ vga->virty = vga->mode->y;
+ vga->panning = 0;
+ }
+ ctlr->flag |= Foptions;
}
static void
@@ -233,18 +288,14 @@ dump(Vga*, Ctlr*)
for(i=0x100; i<0x1FF; i++)
if(!did[i])
vbeprintmodeinfo(vbe, i, " (unoffered)");
-
-
- if(vbeddcedid(vbe, &edid) < 0)
- fprint(2, "warning: reading edid: %r\n");
- else
- printedid(&edid);
+ if(edid)
+ printedid(edid);
}
Ctlr vesa = {
"vesa", /* name */
snarf, /* snarf */
- 0, /* options */
+ options, /* options */
0, /* init */
load, /* load */
dump, /* dump */
@@ -273,19 +324,34 @@ static Flag capabilityflag[] = {
0
};
+enum {
+ AttrSupported = 1<<0,
+ AttrTTY = 1<<2,
+ AttrColor = 1<<3,
+ AttrGraphics = 1<<4,
+ AttrNotVGA = 1<<5,
+ AttrNotWinVGA = 1<<6,
+ AttrLinear = 1<<7,
+ AttrDoublescan = 1<<8,
+ AttrInterlace = 1<<9,
+ AttrTriplebuf = 1<<10,
+ AttrStereo = 1<<11,
+ AttrDualAddr = 1<<12,
+};
+
static Flag modeattributesflags[] = {
- 1<<0, "supported",
- 1<<2, "tty",
- 1<<3, "color",
- 1<<4, "graphics",
- 1<<5, "not-vga",
- 1<<6, "no-windowed-vga",
- 1<<7, "linear",
- 1<<8, "double-scan",
- 1<<9, "interlace",
- 1<<10, "triple-buffer",
- 1<<11, "stereoscopic",
- 1<<12, "dual-start-addr",
+ AttrSupported, "supported",
+ AttrTTY, "tty",
+ AttrColor, "color",
+ AttrGraphics, "graphics",
+ AttrNotVGA, "not-vga",
+ AttrNotWinVGA, "no-windowed-vga",
+ AttrLinear, "linear",
+ AttrDoublescan, "double-scan",
+ AttrInterlace, "interlace",
+ AttrTriplebuf, "triple-buffer",
+ AttrStereo, "stereoscopic",
+ AttrDualAddr, "dual-start-addr",
0
};
@@ -302,10 +368,29 @@ static Flag directcolorflags[] = {
0
};
+enum {
+ ModText = 0,
+ ModCGA,
+ ModHercules,
+ ModPlanar,
+ ModPacked,
+ ModNonChain4,
+ ModDirect,
+ ModYUV,
+};
+
static char *modelstr[] = {
- "text", "cga", "hercules", "planar", "packed", "non-chain4", "direct", "YUV"
+ [ModText] "text",
+ [ModCGA] "cga",
+ [ModHercules] "hercules",
+ [ModPlanar] "planar",
+ [ModPacked] "packed",
+ [ModNonChain4] "non-chain4",
+ [ModDirect] "direct",
+ [ModYUV] "YUV",
};
+
static void
printflags(Flag *f, int b)
{
@@ -402,8 +487,12 @@ vbecheck(Vbe *vbe)
strcpy((char*)p, "VBE2");
if(vbecall(vbe, &u) < 0)
return -1;
- if(memcmp(p, "VESA", 4) != 0 || p[5] < 2){
- werrstr("invalid vesa signature %.4H %.4H\n", p, p+4);
+ if(memcmp(p, "VESA", 4)){
+ werrstr("invalid vesa signature %.4H\n", p);
+ return -1;
+ }
+ if(p[5] < 2){
+ werrstr("invalid vesa version: %.4H\n", p+4);
return -1;
}
return 0;
@@ -422,6 +511,13 @@ vbesnarf(Vbe *vbe, Vga *vga)
if(memcmp(p, "VESA", 4) != 0 || p[5] < 2)
return -1;
vga->apz = WORD(p+18)*0x10000UL;
+ if(edid == nil){
+ edid = alloc(sizeof(Edid));
+ if(vbeddcedid(vbe, edid) < 0){
+ free(edid);
+ edid = nil;
+ }
+ }
return 0;
}
@@ -474,11 +570,9 @@ vbemodes(Vbe *vbe)
int
vbemodeinfo(Vbe *vbe, int id, Vmode *m)
{
- int o;
- ulong d, c, x;
uchar *p;
- char tmp[sizeof m->chan];
Ureg u;
+ int mod;
p = vbesetup(vbe, &u, 0x4F01);
u.cx = id;
@@ -487,11 +581,31 @@ vbemodeinfo(Vbe *vbe, int id, Vmode *m)
m->id = id;
m->attr = WORD(p);
+ if(!(m->attr & AttrSupported))
+ goto Unsupported;
+ if(!(m->attr & AttrGraphics))
+ goto Unsupported;
+ if(!(m->attr & AttrLinear))
+ goto Unsupported;
m->bpl = WORD(p+16);
m->dx = WORD(p+18);
m->dy = WORD(p+20);
m->depth = p[25];
- m->model = p[27] < nelem(modelstr) ? modelstr[p[27]] : "unknown";
+ if((m->dx * m->dy * m->depth) <= 0)
+ goto Unsupported;
+ mod = p[27];
+ switch(mod){
+ default:
+ Unsupported:
+ werrstr("mode unsupported");
+ return -1;
+ case ModCGA:
+ case ModHercules:
+ case ModPacked:
+ case ModDirect:
+ m->model = modelstr[mod];
+ break;
+ }
m->r = p[31];
m->g = p[33];
m->b = p[35];
@@ -502,44 +616,49 @@ vbemodeinfo(Vbe *vbe, int id, Vmode *m)
m->xo = p[38];
m->directcolor = p[39];
m->paddr = LONG(p+40);
- snprint(m->name, sizeof m->name, "%dx%dx%d",
- m->dx, m->dy, m->depth);
- if(m->depth <= 8) {
- snprint(m->chan, sizeof m->chan, "m%d", m->depth);
- return 0;
- }
- m->xo = m->x = 0;
- d = 1 << (m->depth - 1);
- d |= d - 1;
- c = ((1<<m->r)-1) << m->ro;
- c |= ((1<<m->g)-1) << m->go;
- c |= ((1<<m->b)-1) << m->bo;
- x = d ^ c;
- if(x != 0){
- for(; (x & 1) == 0; x >>= 1)
- m->xo++;
- for(; x & 1; x >>= 1)
- m->x++;
- }
+ snprint(m->size, sizeof m->size, "%dx%dx%d", m->dx, m->dy, m->depth);
+ if(m->depth <= 8)
+ snprint(m->chan, sizeof m->chan, "%c%d",
+ (m->attr & AttrColor) ? 'm' : 'k', m->depth);
+ else {
+ int o;
+ ulong d, c, x;
+
+ m->xo = m->x = 0;
+ d = 1<<m->depth-1;
+ d |= d-1;
+ c = ((1<<m->r)-1) << m->ro;
+ c |= ((1<<m->g)-1) << m->go;
+ c |= ((1<<m->b)-1) << m->bo;
+ if(x = d ^ c){
+ for(; (x & 1) == 0; x >>= 1)
+ m->xo++;
+ for(; (x & 1) == 1; x >>= 1)
+ m->x++;
+ }
- m->chan[0] = o = 0;
- while(o < m->depth){
- if(m->r && m->ro == o){
- snprint(tmp, sizeof tmp, "r%d%s", m->r, m->chan);
- o += m->r;
- }else if(m->g && m->go == o){
- snprint(tmp, sizeof tmp, "g%d%s", m->g, m->chan);
- o += m->g;
- }else if(m->b && m->bo == o){
- snprint(tmp, sizeof tmp, "b%d%s", m->b, m->chan);
- o += m->b;
- }else if(m->x && m->xo == o){
- snprint(tmp, sizeof tmp, "x%d%s", m->x, m->chan);
- o += m->x;
- }else
- break;
- strncpy(m->chan, tmp, sizeof m->chan);
+ o = 0;
+ m->chan[0] = 0;
+ while(o < m->depth){
+ char tmp[sizeof m->chan];
+
+ if(m->r && m->ro == o){
+ snprint(tmp, sizeof tmp, "r%d%s", m->r, m->chan);
+ o += m->r;
+ }else if(m->g && m->go == o){
+ snprint(tmp, sizeof tmp, "g%d%s", m->g, m->chan);
+ o += m->g;
+ }else if(m->b && m->bo == o){
+ snprint(tmp, sizeof tmp, "b%d%s", m->b, m->chan);
+ o += m->b;
+ }else if(m->x && m->xo == o){
+ snprint(tmp, sizeof tmp, "x%d%s", m->x, m->chan);
+ o += m->x;
+ }else
+ break;
+ strncpy(m->chan, tmp, sizeof m->chan);
+ }
}
return 0;
}
@@ -549,13 +668,11 @@ vbeprintmodeinfo(Vbe *vbe, int id, char *suffix)
{
Vmode m;
- if(vbemodeinfo(vbe, id, &m) < 0){
- // Bprint(&stdout, "vesa: cannot get mode 0x%ux: %r\n", id);
+ if(vbemodeinfo(vbe, id, &m) < 0)
return;
- }
printitem("vesa", "mode");
Bprint(&stdout, "0x%ux %s %s %s%s\n",
- m.id, m.name, m.chan, m.model, suffix);
+ m.id, m.size, m.chan, m.model, suffix);
}
int
@@ -572,33 +689,12 @@ vbegetmode(Vbe *vbe)
int
vbesetmode(Vbe *vbe, int id)
{
- uchar *p;
Ureg u;
- p = vbesetup(vbe, &u, 0x4F02);
- if(id != 3)
- id |= 3<<14; /* graphics: use linear, do not clear */
+ vbesetup(vbe, &u, 0x4F02);
u.bx = id;
- USED(p);
- /*
- * can set mode specifics (ht hss hse vt vss vse 0 clockhz refreshhz):
- *
- u.bx |= 1<<11;
- n = atoi(argv[2]); PWORD(p, n); p+=2;
- n = atoi(argv[3]); PWORD(p, n); p+=2;
- n = atoi(argv[4]); PWORD(p, n); p+=2;
- n = atoi(argv[5]); PWORD(p, n); p+=2;
- n = atoi(argv[6]); PWORD(p, n); p+=2;
- n = atoi(argv[7]); PWORD(p, n); p+=2;
- *p++ = atoi(argv[8]);
- n = atoi(argv[9]); PLONG(p, n); p += 4;
- n = atoi(argv[10]); PWORD(p, n); p += 2;
- if(p != vbe.buf+19){
- fprint(2, "prog error\n");
- return;
- }
- *
- */
+ if(id != 3)
+ u.bx |= 3<<14; /* graphics: use linear, do not clear */
return vbecall(vbe, &u);
}
@@ -679,8 +775,16 @@ printedid(Edid *e)
for(l=e->modelist; l; l=l->next){
printitem("edid", l->name);
- Bprint(&stdout, "\n\t\tclock=%g\n\t\tshb=%d ehb=%d ht=%d\n\t\tvrs=%d vre=%d vt=%d\n\t\thsync=%c vsync=%c %s\n",
- l->frequency/1.e6, l->shb, l->ehb, l->ht, l->vrs, l->vre, l->vt, l->hsync?l->hsync:'?', l->vsync?l->vsync:'?', l->interlace?"interlace=v" : "");
+ Bprint(&stdout, "\n\t\tclock=%g\n"
+ "\t\tshb=%d ehb=%d ht=%d\n"
+ "\t\tvrs=%d vre=%d vt=%d\n"
+ "\t\thsync=%c vsync=%c %s\n",
+ l->frequency/1.e6,
+ l->shb, l->ehb, l->ht,
+ l->vrs, l->vre, l->vt,
+ l->hsync?l->hsync:'?',
+ l->vsync?l->vsync:'?',
+ l->interlace?"interlace=v" : "");
}
}
@@ -690,9 +794,8 @@ addmode(Modelist *l, Mode m)
int rr;
Modelist **lp;
-//m.z = 8; // BUG
rr = (m.frequency+m.ht*m.vt/2)/(m.ht*m.vt);
- snprint(m.name, sizeof m.name, "%dx%dx%d@%dHz", m.x, m.y, m.z, rr);
+ snprint(m.name, sizeof m.name, "%dx%d@%dHz", m.x, m.y, rr);
if(m.shs == 0)
m.shs = m.shb;
@@ -832,8 +935,6 @@ decodedtb(Mode *m, uchar *p)
return 0;
}
-extern Mode *vesamodes[];
-
int
vesalookup(Mode *m, char *name)
{
diff --git a/sys/src/cmd/aux/vga/vesadb.c b/sys/src/cmd/aux/vga/vesadb.c
index c7aaeebc0..53e461258 100644
--- a/sys/src/cmd/aux/vga/vesadb.c
+++ b/sys/src/cmd/aux/vga/vesadb.c
@@ -1,4 +1,4 @@
-/* this file was automatically generated from vesa.txt */
+// DO NOT EDIT; this file is automatically generated from vesa.txt
#include <u.h>
#include <libc.h>
@@ -6,16 +6,14 @@
#include "pci.h"
#include "vga.h"
-/*
- * VESA Monitor Timing Standard mode definitions as per
- * VESA and Industry Standards and Guidelines for Computer
- * Display Monitor Timing, Version 1.0, Revision 0.8, 17 September 1998.
- *
- * See /public/doc/vesa/dmtv1r08.pdf.
- *
- * This might go back into vgadb at some point. It's here mainly
- * so that people don't change it, and so that we can run without vgadb.
- */
+// VESA Monitor Timing Standard mode definitions as per
+// VESA and Industry Standards and Guidelines for Computer
+// Display Monitor Timing, Version 1.0, Revision 0.8, 17 September 1998.
+//
+// See /lib/vesa/dmtv1r08.pdf.
+//
+// This might go back into vgadb at some point. It's here mainly
+// so that people don't change it, and so that we can run without vgadb.
static Mode vesa640x480x60 = {
.name = "640x480@60Hz",
diff --git a/sys/src/libmemdraw/draw.c b/sys/src/libmemdraw/draw.c
index 1987c7713..574d597db 100644
--- a/sys/src/libmemdraw/draw.c
+++ b/sys/src/libmemdraw/draw.c
@@ -12,22 +12,34 @@ static int tablesbuilt;
#define RGB2K(r,g,b) ((156763*(r)+307758*(g)+59769*(b))>>19)
/*
- * for 0 ≤ x ≤ 255*255, (x*0x0101+0x100)>>16 is a perfect approximation.
- * for 0 ≤ x < (1<<16), x/255 = ((x+1)*0x0101)>>16 is a perfect approximation.
- * the last one is perfect for all up to 1<<16, avoids a multiply, but requires a rathole.
+ * For 16-bit values, x / 255 == (t = x+1, (t+(t>>8)) >> 8).
+ * We add another 127 to round to the nearest value rather
+ * than truncate.
+ *
+ * CALCxy does x bytewise calculations on y input images (x=1,4; y=1,2).
+ * CALC2x does two parallel 16-bit calculations on y input images (y=1,2).
*/
-/* #define DIV255(x) (((x)*257+256)>>16) */
-#define DIV255(x) ((((x)+1)*257)>>16)
-/* #define DIV255(x) (tmp=(x)+1, (tmp+(tmp>>8))>>8) */
+#define CALC11(a, v, tmp) \
+ (tmp=(a)*(v)+128, (tmp+(tmp>>8))>>8)
+
+#define CALC12(a1, v1, a2, v2, tmp) \
+ (tmp=(a1)*(v1)+(a2)*(v2)+128, (tmp+(tmp>>8))>>8)
+
+#define MASK 0xFF00FF
+
+#define CALC21(a, vvuu, tmp) \
+ (tmp=(a)*(vvuu)+0x00800080, ((tmp+((tmp>>8)&MASK))>>8)&MASK)
-#define MUL(x, y, t) (t = (x)*(y)+128, (t+(t>>8))>>8)
-#define MASK13 0xFF00FF00
-#define MASK02 0x00FF00FF
-#define MUL13(a, x, t) (t = (a)*(((x)&MASK13)>>8)+128, ((t+((t>>8)&MASK02))>>8)&MASK02)
-#define MUL02(a, x, t) (t = (a)*(((x)&MASK02)>>0)+128, ((t+((t>>8)&MASK02))>>8)&MASK02)
-#define MUL0123(a, x, s, t) ((MUL13(a, x, s)<<8)|MUL02(a, x, t))
+#define CALC41(a, rgba, tmp1, tmp2) \
+ (CALC21(a, rgba & MASK, tmp1) | \
+ (CALC21(a, (rgba>>8)&MASK, tmp2)<<8))
-#define MUL2(u, v, x, y) (t = (u)*(v)+(x)*(y)+256, (t+(t>>8))>>8)
+#define CALC22(a1, vvuu1, a2, vvuu2, tmp) \
+ (tmp=(a1)*(vvuu1)+(a2)*(vvuu2)+0x00800080, ((tmp+((tmp>>8)&MASK))>>8)&MASK)
+
+#define CALC42(a1, rgba1, a2, rgba2, tmp1, tmp2) \
+ (CALC22(a1, rgba1 & MASK, a2, rgba2 & MASK, tmp1) | \
+ (CALC22(a1, (rgba1>>8) & MASK, a2, (rgba2>>8) & MASK, tmp2)<<8))
static void mktables(void);
typedef int Subdraw(Memdrawparam*);
@@ -803,41 +815,85 @@ alphacalc0(Buffer bdst, Buffer b1, Buffer b2, int dx, int grey, int op)
return bdst;
}
+/*
+ * Do the channels in the buffers match enough
+ * that we can do word-at-a-time operations
+ * on the pixels?
+ */
+static int
+chanmatch(Buffer *bdst, Buffer *bsrc)
+{
+ uchar *drgb, *srgb;
+
+ /*
+ * first, r, g, b must be in the same place
+ * in the rgba word.
+ */
+ drgb = (uchar*)bdst->rgba;
+ srgb = (uchar*)bsrc->rgba;
+ if(bdst->red - drgb != bsrc->red - srgb
+ || bdst->blu - drgb != bsrc->blu - srgb
+ || bdst->grn - drgb != bsrc->grn - srgb)
+ return 0;
+
+ /*
+ * that implies alpha is in the same place,
+ * if it is there at all (it might be == &ones).
+ * if the destination is &ones, we can scribble
+ * over the rgba slot just fine.
+ */
+ if(bdst->alpha == &ones)
+ return 1;
+
+ /*
+ * if the destination is not ones but the src is,
+ * then the simultaneous calculation will use
+ * bogus bytes from the src's rgba. no good.
+ */
+ if(bsrc->alpha == &ones)
+ return 0;
+
+ /*
+ * otherwise, alphas are in the same place.
+ */
+ return 1;
+}
+
static Buffer
alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
{
Buffer obdst;
int fd, sadelta;
int i, sa, ma, q;
- ulong s, t;
+ ulong t, t1;
obdst = bdst;
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
- q = bsrc.delta == 4 && bdst.delta == 4;
+ q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
for(i=0; i<dx; i++){
sa = *bsrc.alpha;
ma = *bmask.alpha;
- fd = MUL(sa, ma, t);
+ fd = CALC11(sa, ma, t);
if(op == DoutS)
fd = 255-fd;
if(grey){
- *bdst.grey = MUL(fd, *bdst.grey, t);
+ *bdst.grey = CALC11(fd, *bdst.grey, t);
bsrc.grey += bsrc.delta;
bdst.grey += bdst.delta;
}else{
if(q){
- *bdst.rgba = MUL0123(fd, *bdst.rgba, s, t);
+ *bdst.rgba = CALC41(fd, *bdst.rgba, t, t1);
bsrc.rgba++;
bdst.rgba++;
bsrc.alpha += sadelta;
bmask.alpha += bmask.delta;
continue;
}
- *bdst.red = MUL(fd, *bdst.red, t);
- *bdst.grn = MUL(fd, *bdst.grn, t);
- *bdst.blu = MUL(fd, *bdst.blu, t);
+ *bdst.red = CALC11(fd, *bdst.red, t);
+ *bdst.grn = CALC11(fd, *bdst.grn, t);
+ *bdst.blu = CALC11(fd, *bdst.blu, t);
bsrc.red += bsrc.delta;
bsrc.blu += bsrc.delta;
bsrc.grn += bsrc.delta;
@@ -846,7 +902,7 @@ alphacalc14(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
bdst.grn += bdst.delta;
}
if(bdst.alpha != &ones){
- *bdst.alpha = MUL(fd, *bdst.alpha, t);
+ *bdst.alpha = CALC11(fd, *bdst.alpha, t);
bdst.alpha += bdst.delta;
}
bmask.alpha += bmask.delta;
@@ -861,11 +917,11 @@ alphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
Buffer obdst;
int fs, sadelta;
int i, ma, da, q;
- ulong s, t;
+ ulong t, t1;
obdst = bdst;
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
- q = bsrc.delta == 4 && bdst.delta == 4;
+ q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
for(i=0; i<dx; i++){
ma = *bmask.alpha;
@@ -874,24 +930,24 @@ alphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
da = 255-da;
fs = ma;
if(op != S)
- fs = MUL(fs, da, t);
+ fs = CALC11(fs, da, t);
if(grey){
- *bdst.grey = MUL(fs, *bsrc.grey, t);
+ *bdst.grey = CALC11(fs, *bsrc.grey, t);
bsrc.grey += bsrc.delta;
bdst.grey += bdst.delta;
}else{
if(q){
- *bdst.rgba = MUL0123(fs, *bsrc.rgba, s, t);
+ *bdst.rgba = CALC41(fs, *bsrc.rgba, t, t1);
bsrc.rgba++;
bdst.rgba++;
bmask.alpha += bmask.delta;
bdst.alpha += bdst.delta;
continue;
}
- *bdst.red = MUL(fs, *bsrc.red, t);
- *bdst.grn = MUL(fs, *bsrc.grn, t);
- *bdst.blu = MUL(fs, *bsrc.blu, t);
+ *bdst.red = CALC11(fs, *bsrc.red, t);
+ *bdst.grn = CALC11(fs, *bsrc.grn, t);
+ *bdst.blu = CALC11(fs, *bsrc.blu, t);
bsrc.red += bsrc.delta;
bsrc.blu += bsrc.delta;
bsrc.grn += bsrc.delta;
@@ -900,7 +956,7 @@ alphacalc2810(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
bdst.grn += bdst.delta;
}
if(bdst.alpha != &ones){
- *bdst.alpha = MUL(fs, *bsrc.alpha, t);
+ *bdst.alpha = CALC11(fs, *bsrc.alpha, t);
bdst.alpha += bdst.delta;
}
bmask.alpha += bmask.delta;
@@ -915,35 +971,35 @@ alphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
Buffer obdst;
int fs, fd, sadelta;
int i, sa, ma, da, q;
- ulong s, t, u, v;
+ ulong t, t1;
obdst = bdst;
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
- q = bsrc.delta == 4 && bdst.delta == 4;
+ q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
for(i=0; i<dx; i++){
sa = *bsrc.alpha;
ma = *bmask.alpha;
da = *bdst.alpha;
if(op == SatopD)
- fs = MUL(ma, da, t);
+ fs = CALC11(ma, da, t);
else
- fs = MUL(ma, 255-da, t);
+ fs = CALC11(ma, 255-da, t);
if(op == DoverS)
fd = 255;
else{
- fd = MUL(sa, ma, t);
+ fd = CALC11(sa, ma, t);
if(op != DatopS)
fd = 255-fd;
}
if(grey){
- *bdst.grey = MUL(fs, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
+ *bdst.grey = CALC12(fs, *bsrc.grey, fd, *bdst.grey, t);
bsrc.grey += bsrc.delta;
bdst.grey += bdst.delta;
}else{
if(q){
- *bdst.rgba = MUL0123(fs, *bsrc.rgba, s, t)+MUL0123(fd, *bdst.rgba, u, v);
+ *bdst.rgba = CALC42(fs, *bsrc.rgba, fd, *bdst.rgba, t, t1);
bsrc.rgba++;
bdst.rgba++;
bsrc.alpha += sadelta;
@@ -951,9 +1007,9 @@ alphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
bdst.alpha += bdst.delta;
continue;
}
- *bdst.red = MUL(fs, *bsrc.red, s)+MUL(fd, *bdst.red, t);
- *bdst.grn = MUL(fs, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
- *bdst.blu = MUL(fs, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
+ *bdst.red = CALC12(fs, *bsrc.red, fd, *bdst.red, t);
+ *bdst.grn = CALC12(fs, *bsrc.grn, fd, *bdst.grn, t);
+ *bdst.blu = CALC12(fs, *bsrc.blu, fd, *bdst.blu, t);
bsrc.red += bsrc.delta;
bsrc.blu += bsrc.delta;
bsrc.grn += bsrc.delta;
@@ -962,7 +1018,7 @@ alphacalc3679(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
bdst.grn += bdst.delta;
}
if(bdst.alpha != &ones){
- *bdst.alpha = MUL(fs, sa, s)+MUL(fd, da, t);
+ *bdst.alpha = CALC12(fs, sa, fd, da, t);
bdst.alpha += bdst.delta;
}
bmask.alpha += bmask.delta;
@@ -988,34 +1044,34 @@ alphacalc11(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
Buffer obdst;
int fd, sadelta;
int i, sa, ma, q;
- ulong s, t, u, v;
+ ulong t, t1;
USED(op);
obdst = bdst;
sadelta = bsrc.alpha == &ones ? 0 : bsrc.delta;
- q = bsrc.delta == 4 && bdst.delta == 4;
+ q = bsrc.delta == 4 && bdst.delta == 4 && chanmatch(&bdst, &bsrc);
for(i=0; i<dx; i++){
sa = *bsrc.alpha;
ma = *bmask.alpha;
- fd = 255-MUL(sa, ma, t);
+ fd = 255-CALC11(sa, ma, t);
if(grey){
- *bdst.grey = MUL(ma, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
+ *bdst.grey = CALC12(ma, *bsrc.grey, fd, *bdst.grey, t);
bsrc.grey += bsrc.delta;
bdst.grey += bdst.delta;
}else{
if(q){
- *bdst.rgba = MUL0123(ma, *bsrc.rgba, s, t)+MUL0123(fd, *bdst.rgba, u, v);
+ *bdst.rgba = CALC42(ma, *bsrc.rgba, fd, *bdst.rgba, t, t1);
bsrc.rgba++;
bdst.rgba++;
bsrc.alpha += sadelta;
bmask.alpha += bmask.delta;
continue;
}
- *bdst.red = MUL(ma, *bsrc.red, s)+MUL(fd, *bdst.red, t);
- *bdst.grn = MUL(ma, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
- *bdst.blu = MUL(ma, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
+ *bdst.red = CALC12(ma, *bsrc.red, fd, *bdst.red, t);
+ *bdst.grn = CALC12(ma, *bsrc.grn, fd, *bdst.grn, t);
+ *bdst.blu = CALC12(ma, *bsrc.blu, fd, *bdst.blu, t);
bsrc.red += bsrc.delta;
bsrc.blu += bsrc.delta;
bsrc.grn += bsrc.delta;
@@ -1024,7 +1080,7 @@ alphacalc11(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
bdst.grn += bdst.delta;
}
if(bdst.alpha != &ones){
- *bdst.alpha = MUL(ma, sa, s)+MUL(fd, *bdst.alpha, t);
+ *bdst.alpha = CALC12(ma, sa, fd, *bdst.alpha, t);
bdst.alpha += bdst.delta;
}
bmask.alpha += bmask.delta;
@@ -1080,7 +1136,7 @@ alphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
Buffer obdst;
int fd;
int i, ma;
- ulong s, t;
+ ulong t;
USED(op);
obdst = bdst;
@@ -1090,13 +1146,13 @@ alphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
fd = 255-ma;
if(grey){
- *bdst.grey = MUL(ma, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
+ *bdst.grey = CALC12(ma, *bsrc.grey, fd, *bdst.grey, t);
bsrc.grey += bsrc.delta;
bdst.grey += bdst.delta;
}else{
- *bdst.red = MUL(ma, *bsrc.red, s)+MUL(fd, *bdst.red, t);
- *bdst.grn = MUL(ma, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
- *bdst.blu = MUL(ma, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
+ *bdst.red = CALC12(ma, *bsrc.red, fd, *bdst.red, t);
+ *bdst.grn = CALC12(ma, *bsrc.grn, fd, *bdst.grn, t);
+ *bdst.blu = CALC12(ma, *bsrc.blu, fd, *bdst.blu, t);
bsrc.red += bsrc.delta;
bsrc.blu += bsrc.delta;
bsrc.grn += bsrc.delta;
@@ -1105,7 +1161,7 @@ alphacalcS(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
bdst.grn += bdst.delta;
}
if(bdst.alpha != &ones){
- *bdst.alpha = ma+MUL(fd, *bdst.alpha, t);
+ *bdst.alpha = ma+CALC11(fd, *bdst.alpha, t);
bdst.alpha += bdst.delta;
}
bmask.alpha += bmask.delta;
@@ -1154,7 +1210,7 @@ boolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
Buffer obdst;
int fs, fd;
int i, ma, da, zero;
- ulong s, t;
+ ulong t;
obdst = bdst;
zero = !(op&1);
@@ -1171,16 +1227,16 @@ boolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
if(grey){
if(ma)
- *bdst.grey = MUL(fs, *bsrc.grey, s)+MUL(fd, *bdst.grey, t);
+ *bdst.grey = CALC12(fs, *bsrc.grey, fd, *bdst.grey, t);
else if(zero)
*bdst.grey = 0;
bsrc.grey += bsrc.delta;
bdst.grey += bdst.delta;
}else{
if(ma){
- *bdst.red = MUL(fs, *bsrc.red, s)+MUL(fd, *bdst.red, t);
- *bdst.grn = MUL(fs, *bsrc.grn, s)+MUL(fd, *bdst.grn, t);
- *bdst.blu = MUL(fs, *bsrc.blu, s)+MUL(fd, *bdst.blu, t);
+ *bdst.red = CALC12(fs, *bsrc.red, fd, *bdst.red, t);
+ *bdst.grn = CALC12(fs, *bsrc.grn, fd, *bdst.grn, t);
+ *bdst.blu = CALC12(fs, *bsrc.blu, fd, *bdst.blu, t);
}
else if(zero)
*bdst.red = *bdst.grn = *bdst.blu = 0;
@@ -1194,7 +1250,7 @@ boolcalc236789(Buffer bdst, Buffer bsrc, Buffer bmask, int dx, int grey, int op)
bmask.alpha += bmask.delta;
if(bdst.alpha != &ones){
if(ma)
- *bdst.alpha = fs+MUL(fd, da, t);
+ *bdst.alpha = fs+CALC11(fd, da, t);
else if(zero)
*bdst.alpha = 0;
bdst.alpha += bdst.delta;
diff --git a/sys/src/libmemdraw/load.c b/sys/src/libmemdraw/load.c
index 5095c15c3..984efa958 100644
--- a/sys/src/libmemdraw/load.c
+++ b/sys/src/libmemdraw/load.c
@@ -7,10 +7,17 @@ int
loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata)
{
int y, l, lpart, rpart, mx, m, mr;
+ Memdrawparam par;
uchar *q;
if(!rectinrect(r, i->r))
return -1;
+
+ memset(&par, 0, sizeof par);
+ par.dst = i;
+ par.r = r;
+ hwdraw(&par);
+
l = bytesperline(r, i->depth);
if(ndata < l*Dy(r))
return -1;