From pixman (Jeff Muizelaar)

Fix up the fast-path compositing operators; those are useful for
    sources without alpha, but can't be used for sources with
    alpha. Also, replaced fbCompositeSrcSrc_nxn with call to fbBlt as
    this function must handle 1, 4, 8, 16, 24, 32 bpp objects. Would
    be nice to optimize fbBlt for common cases involving 8, 16, 24 and
    32bpp.

    From Keith Packard.
This commit is contained in:
Soren Sandmann Pedersen 2007-04-24 14:46:59 -04:00
parent fde4a5adf0
commit 2d9a7a7687
2 changed files with 373 additions and 335 deletions

View File

@ -64,20 +64,6 @@ fbOver (CARD32 x, CARD32 y)
return m|n|o|p; return m|n|o|p;
} }
static CARD32
fbIn24 (CARD32 x, CARD8 y)
{
CARD16 a = y;
CARD16 t;
CARD32 m,n,o,p;
m = FbInU(x,0,a,t);
n = FbInU(x,8,a,t);
o = FbInU(x,16,a,t);
p = (y << 24);
return m|n|o|p;
}
CARD32 CARD32
fbOver24 (CARD32 x, CARD32 y) fbOver24 (CARD32 x, CARD32 y)
{ {
@ -107,22 +93,34 @@ fbIn (CARD32 x, CARD8 y)
#define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d))) #define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d)))
#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \ /*
dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \ * This macro does src IN mask OVER dst when src and dst are 0888.
drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ * If src has alpha, this will not work
*destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ */
#define inOver0888(alpha, source, destval, dest) { \
CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \
CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
dest =((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
}
/*
* This macro does src IN mask OVER dst when src and dst are 0565 and
* mask is a 5-bit alpha value. Again, if src has alpha, this will not
* work.
*/
#define inOver0565(alpha, source, destval, dest) { \
CARD16 dstrb = destval & 0xf81f; CARD16 dstg = destval & 0x7e0; \
CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
dest = ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5) + dstg) & 0x7e0)); \
}
#define inOver2x0565(alpha, source, destval, dest) { \
CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg = (destval & 0xf81f07e0)>>5; \
CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \
dest = ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5) + dstg)<<5) & 0xf81f07e0)); \
}
#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \
dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \
drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
*destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \
// Note: this macro expects 6 bits of alpha, not 8!
#define fastCombine0565(alpha, source, destval, destptr) { \
CARD16 dstrb = destval & 0xf81f; CARD16 dstg = destval & 0x7e0; \
CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
destptr= ((((drb>>6) + dstrb)&0xf81f) | (((dg>>6) + dstg) & 0x7e0)); \
}
#if IMAGE_BYTE_ORDER == LSBFirst #if IMAGE_BYTE_ORDER == LSBFirst
#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \ #define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \
@ -150,6 +148,7 @@ fbIn (CARD32 x, CARD8 y)
#define readPackedDest(where) readPacked(where,wd,workingiDest,widst) #define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
#define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; *wodst++=workingoDest; } #define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; *wodst++=workingoDest; }
#endif #endif
/* /*
* Naming convention: * Naming convention:
* *
@ -310,7 +309,6 @@ fbCompositeSolidMask_nx8x0888 (CARD8 op,
{ {
CARD32 src, srca, srcia; CARD32 src, srca, srcia;
CARD8 *dstLine, *dst, *edst; CARD8 *dstLine, *dst, *edst;
CARD32 d;
CARD8 *maskLine, *mask, m; CARD8 *maskLine, *mask, m;
FbStride dstStride, maskStride; FbStride dstStride, maskStride;
CARD16 w; CARD16 w;
@ -332,7 +330,7 @@ fbCompositeSolidMask_nx8x0888 (CARD8 op,
while (height--) while (height--)
{ {
// fixme: cleanup unused /* fixme: cleanup unused */
unsigned int wt,wd; unsigned int wt,wd;
CARD32 workingiDest; CARD32 workingiDest;
CARD32 *widst; CARD32 *widst;
@ -407,61 +405,152 @@ fbCompositeSolidMask_nx8x0565 (CARD8 op,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height)
{ {
CARD32 src, srca,na, rsrca; CARD32 src, srca8, srca5;
CARD16 *dstLine, *dst; CARD16 *dstLine, *dst;
CARD16 d; CARD16 d;
CARD8 *maskLine, *mask, m; CARD32 t;
FbStride dstStride, maskStride; CARD8 *maskLine, *mask, m;
CARD16 w,src16; FbStride dstStride, maskStride;
CARD16 w,src16;
fbComposeGetSolid(pSrc, src, pDst->format);
src16 = cvt8888to0565(src);
rsrca = src >> 24;
srca=rsrca>>2;
if (src == 0)
return;
fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
while (height--) fbComposeGetSolid(pSrc, src, pDst->format);
{
dst = dstLine;
dstLine += dstStride;
mask = maskLine; if (src == 0)
maskLine += maskStride; return;
w = width;
srca8 = (src >> 24);
srca5 = (srca8 >> 3);
src16 = cvt8888to0565(src);
fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
while (height--)
{
dst = dstLine;
dstLine += dstStride;
mask = maskLine;
maskLine += maskStride;
w = width;
while (w--) while (w--)
{ {
m = *mask++; m = *mask++;
if (m == 0xff) if (m == 0)
{ dst++;
if (srca == 0xff) else if (srca5 == (0xff >> 3))
{ {
*dst=src16; if (m == 0xff)
} *dst++ = src16;
else else
{ {
d = *dst; d = *dst;
fastCombine0565(srca, src16, d, *dst++); m >>= 3;
} inOver0565 (m, src16, d, *dst++);
} }
else if (m) }
{ else
na=(rsrca*(int)m)>>10; {
d = *dst; d = *dst;
fastCombine0565(na, src16, d, *dst++); if (m == 0xff)
} {
else t = fbOver24 (src, cvt0565to0888 (d));
dst++; }
} else
} {
t = fbIn (src, m);
t = fbOver (t, cvt0565to0888 (d));
}
*dst++ = cvt8888to0565 (t);
}
}
}
fbFinishAccess (pMask->pDrawable); fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable); fbFinishAccess (pDst->pDrawable);
} }
static void
fbCompositeSolidMask_nx8888x0565 (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
{
CARD32 src, srca8, srca5;
CARD16 *dstLine, *dst;
CARD16 d;
CARD32 *maskLine, *mask;
CARD32 t;
CARD8 m;
FbStride dstStride, maskStride;
CARD16 w, src16;
fbComposeGetSolid(pSrc, src, pDst->format);
if (src == 0)
return;
srca8 = src >> 24;
srca5 = srca8 >> 3;
src16 = cvt8888to0565(src);
fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
while (height--)
{
dst = dstLine;
dstLine += dstStride;
mask = maskLine;
maskLine += maskStride;
w = width;
while (w--)
{
m = *mask++ >> 24;
if (m == 0)
dst++;
else if (srca5 == (0xff >> 3))
{
if (m == 0xff)
*dst++ = src16;
else
{
d = *dst;
m >>= 3;
inOver0565 (m, src16, d, *dst++);
}
}
else
{
if (m == 0xff)
{
d = *dst;
t = fbOver24 (src, cvt0565to0888 (d));
*dst++ = cvt8888to0565 (t);
}
else
{
d = *dst;
t = fbIn (src, m);
t = fbOver (t, cvt0565to0888 (d));
*dst++ = cvt8888to0565 (t);
}
}
}
}
}
void void
fbCompositeSolidMask_nx8888x0565C (CARD8 op, fbCompositeSolidMask_nx8888x0565C (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
@ -516,14 +605,14 @@ fbCompositeSolidMask_nx8888x0565C (CARD8 op,
else else
{ {
d = READ(dst); d = READ(dst);
d = fbOver24 (src, cvt0565to8888(d)); d = fbOver24 (src, cvt0565to0888(d));
WRITE(dst, cvt8888to0565(d)); WRITE(dst, cvt8888to0565(d));
} }
} }
else if (ma) else if (ma)
{ {
d = READ(dst); d = READ(dst);
d = cvt0565to8888(d); d = cvt0565to0888(d);
FbInOverC (src, srca, ma, d, 0, m); FbInOverC (src, srca, ma, d, 0, m);
FbInOverC (src, srca, ma, d, 8, n); FbInOverC (src, srca, ma, d, 8, n);
FbInOverC (src, srca, ma, d, 16, o); FbInOverC (src, srca, ma, d, 16, o);
@ -682,7 +771,7 @@ fbCompositeSrc_8888x0565 (CARD8 op,
else else
{ {
d = READ(dst); d = READ(dst);
d = fbOver24 (s, cvt0565to8888(d)); d = fbOver24 (s, cvt0565to0888(d));
} }
WRITE(dst, cvt8888to0565(d)); WRITE(dst, cvt8888to0565(d));
} }
@ -694,6 +783,7 @@ fbCompositeSrc_8888x0565 (CARD8 op,
fbFinishAccess (pSrc->pDrawable); fbFinishAccess (pSrc->pDrawable);
} }
#if 0
void void
fbCompositeSrc_0565x0565 (CARD8 op, fbCompositeSrc_0565x0565 (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
@ -732,6 +822,7 @@ fbCompositeSrc_0565x0565 (CARD8 op,
fbFinishAccess (pDst->pDrawable); fbFinishAccess (pDst->pDrawable);
fbFinishAccess (pSrc->pDrawable); fbFinishAccess (pSrc->pDrawable);
} }
#endif
void void
fbCompositeSrcAdd_8000x8000 (CARD8 op, fbCompositeSrcAdd_8000x8000 (CARD8 op,
@ -964,6 +1055,19 @@ fbCompositeSolidMask_nx1xn (CARD8 op,
/* /*
* Apply a constant alpha value in an over computation * Apply a constant alpha value in an over computation
*/ */
static void
fbCompositeSrcSrc_nxn (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
static void static void
fbCompositeTrans_0565xnx0565(CARD8 op, fbCompositeTrans_0565xnx0565(CARD8 op,
@ -985,19 +1089,19 @@ fbCompositeTrans_0565xnx0565(CARD8 op,
CARD16 w; CARD16 w;
FbBits mask; FbBits mask;
CARD8 maskAlpha; CARD8 maskAlpha;
CARD16 s_16, d_16, r_16; CARD16 s_16, d_16;
CARD32 s_32, d_32, i_32, r_32; CARD32 s_32, d_32;
fbComposeGetSolid (pMask, mask, pDst->format); fbComposeGetSolid (pMask, mask, pDst->format);
maskAlpha = mask >> 26; maskAlpha = mask >> 27;
if (!maskAlpha) if (!maskAlpha)
return; return;
if (maskAlpha == 0xff) if (maskAlpha == 0xff)
{ {
fbCompositeSrc_0565x0565 (op, pSrc, pMask, pDst, fbCompositeSrcSrc_nxn (PictOpSrc, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst, xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height); width, height);
return; return;
} }
@ -1005,55 +1109,70 @@ fbCompositeTrans_0565xnx0565(CARD8 op,
fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
while (height--) while (height--)
{ {
CARD32 *isrc; CARD32 *isrc, *idst;
dst = dstLine; dst = dstLine;
dstLine += dstStride; dstLine += dstStride;
src = srcLine; src = srcLine;
srcLine += srcStride; srcLine += srcStride;
w = width; w = width;
if(((int)src&1)==1) if(((int)src&1)==1)
{ {
s_16 = *src++; s_16 = *src++;
d_16 = *dst; d_16 = *dst;
fastCombine0565(maskAlpha, s_16, d_16, *dst++); inOver0565(maskAlpha, s_16, d_16, *dst++);
w--; w--;
} }
isrc=(CARD32 *)src; isrc=(CARD32 *)src;
while (w>1) if(((int)dst&1)==0)
{ {
s_32=*isrc++; idst=(CARD32 *)dst;
while (w>1)
{
s_32 = *isrc++;
d_32 = *idst;
inOver2x0565(maskAlpha, s_32, d_32, *idst++);
w-=2;
}
dst=(CARD16 *)idst;
}
else
{
while (w > 1)
{
s_32 = *isrc++;
#if IMAGE_BYTE_ORDER == LSBFirst #if IMAGE_BYTE_ORDER == LSBFirst
s_16=s_32&0xffff; s_16=s_32&0xffff;
#else #else
s_16=s_32>>16; s_16=s_32>>16;
#endif #endif
d_16 = *dst; d_16 = *dst;
fastCombine0565(maskAlpha, s_16, d_16, *dst++); inOver0565 (maskAlpha, s_16, d_16, *dst++);
#if IMAGE_BYTE_ORDER == LSBFirst #if IMAGE_BYTE_ORDER == LSBFirst
s_16=s_32>>16; s_16=s_32>>16;
#else #else
s_16=s_32&0xffff; s_16=s_32&0xffff;
#endif #endif
d_16 = *dst; d_16 = *dst;
fastCombine0565(maskAlpha, s_16, d_16, *dst++); inOver0565(maskAlpha, s_16, d_16, *dst++);
w-=2; w-=2;
} }
src=(CARD16 *)isrc; }
if(w!=0) src=(CARD16 *)isrc;
{ if(w!=0)
s_16 = *src; {
d_16 = *dst; s_16 = *src;
fastCombine0565(maskAlpha, s_16, d_16, *dst); d_16 = *dst;
} inOver0565(maskAlpha, s_16, d_16, *dst);
} }
}
fbFinishAccess (pSrc->pDrawable); fbFinishAccess (pSrc->pDrawable);
fbFinishAccess (pDst->pDrawable); fbFinishAccess (pDst->pDrawable);
} }
// macros for "i can't believe it's not fast" packed pixel handling /* macros for "i can't believe it's not fast" packed pixel handling */
#define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha) #define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha)
static void static void
fbCompositeTrans_0888xnx0888(CARD8 op, fbCompositeTrans_0888xnx0888(CARD8 op,
@ -1082,140 +1201,105 @@ fbCompositeTrans_0888xnx0888(CARD8 op,
if (!maskAlpha) if (!maskAlpha)
return; return;
//if (maskAlpha == 0xff) /*
//{ if (maskAlpha == 0xff)
//fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst, {
// xSrc, ySrc, xMask, yMask, xDst, yDst, fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
// width, height); xSrc, ySrc, xMask, yMask, xDst, yDst,
//return; width, height);
//} return;
}
*/
fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3); fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3);
fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
{ {
unsigned int ws,wt,wd,ww; unsigned int ws,wt;
CARD32 workingSource; CARD32 workingSource;
CARD32 *wsrc; CARD32 *wsrc, *wdst, *widst;
CARD32 rs,gs,bs; CARD32 rs, rd, nd;
CARD32 rd,gd,bd; CARD8 *isrc;
CARD32 workingiDest,workingoDest; /* are xSrc and xDst at the same alignment? if not, we need to be complicated :) */
CARD32 *widst,*wodst; /* if(0==0) */
if( (((xSrc*3)&3)!=((xDst*3)&3)) || ((srcStride&3)!=(dstStride&3)))
// are xSrc and xDst at the same alignment? if not, we need to be complicated :)
//if(0==0)
if( (((xSrc*3)&3)!=((xDst*3)&3)) || (srcStride&3)!=0 || (dstStride&3)!=0)
{ {
while (height--) while (height--)
{ {
idst=dst = dstLine; dst = dstLine;
dstLine += dstStride; dstLine += dstStride;
src = srcLine; isrc = src = srcLine;
srcLine += srcStride; srcLine += srcStride;
w = width*3; w = width*3;
setupPackedReader(wd,wt,idst,widst,workingiDest); setupPackedReader(ws,wt,isrc,wsrc,workingSource);
ww=(int)dst;
wt=ww&3; /* get to word aligned */
dst-=wt;
wodst=(CARD32 *)dst;
workingoDest=*wodst;
ww=4-wt;
#if IMAGE_BYTE_ORDER == LSBFirst
workingoDest<<=(8*(ww+1));
#else
workingoDest>>=(8*(ww+1));
#endif
// get to word aligned
switch(!(int)src&3) switch(!(int)src&3)
{ {
case 1: case 1:
readPackedDest(rd); readPackedSource(rs);
rd=alphamaskCombine24(*src++, rd)>>8; /* *dst++=alphamaskCombine24(rs, *dst)>>8; */
writePacked(rd); rd=*dst; /* make gcc happy. hope it doens't cost us too much performance*/
w--; if(w==0) break; *dst++=alphamaskCombine24(rs, rd)>>8;
w--; if(w==0) break;
case 2: case 2:
readPackedDest(rd); readPackedSource(rs);
rd=alphamaskCombine24(*src++, rd)>>8; rd=*dst;
writePacked(rd); *dst++=alphamaskCombine24(rs, rd)>>8;
w--; if(w==0) break; w--; if(w==0) break;
case 3: case 3:
readPackedDest(rd); readPackedSource(rs);
rd=alphamaskCombine24(*src++, rd)>>8; rd=*dst;
writePacked(rd); *dst++=alphamaskCombine24(rs, rd)>>8;
w--; if(w==0) break; w--; if(w==0) break;
} }
wsrc=(CARD32 *)src; wdst=(CARD32 *)dst;
while (w>3) while (w>3)
{ {
rs=*wsrc++; rs=*wsrc++;
// FIXME: write a version of readPackedDest() which /* FIXME: write a special readPackedWord macro, which knows how to
// can collect 4 bytes at once if we're on a boundry (which we're * halfword combine
// actually guarenteed not to be in this version, but do it anyhow), and can */
// collect as 2 16bit words on a 2byte boundry, and then use the 32bit combine here
#if IMAGE_BYTE_ORDER == LSBFirst #if IMAGE_BYTE_ORDER == LSBFirst
readPackedDest(rd); rd=*wdst;
rd=alphamaskCombine24(rs&0xff, rd)>>8; readPackedSource(nd);
writePacked(rd); readPackedSource(rs);
nd|=rs<<8;
readPackedDest(rd); readPackedSource(rs);
rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8; nd|=rs<<16;
writePacked(rd); readPackedSource(rs);
nd|=rs<<24;
readPackedDest(rd); #else
rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8; readPackedSource(nd);
writePacked(rd); nd<<=24;
readPackedSource(rs);
readPackedDest(rd); nd|=rs<<16;
rd=alphamaskCombine24(rs>>24, rd)>>8; readPackedSource(rs);
writePacked(rd); nd|=rs<<8;
#else readPackedSource(rs);
readPackedDest(rd); nd|=rs;
rd=alphamaskCombine24(rs>>24, rd)>>8; #endif
writePacked(rd); inOver0888(maskAlpha, nd, rd, *wdst++);
readPackedDest(rd);
rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8;
writePacked(rd);
readPackedDest(rd);
rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8;
writePacked(rd);
readPackedDest(rd);
rd=alphamaskCombine24(rs&0xff, rd)>>8;
writePacked(rd);
#endif
w-=4; w-=4;
} }
src=(CARD8 *)wsrc; src=(CARD8 *)wdst;
switch(w) switch(w)
{ {
case 3: case 3:
readPackedDest(rd); readPackedSource(rs);
rd=alphamaskCombine24(*src++, rd)>>8; rd=*dst;
writePacked(rd); *dst++=alphamaskCombine24(rs, rd)>>8;
case 2: case 2:
readPackedDest(rd); readPackedSource(rs);
rd=alphamaskCombine24(*src++, rd)>>8; rd=*dst;
writePacked(rd); *dst++=alphamaskCombine24(rs, rd)>>8;
case 1: case 1:
readPackedDest(rd); readPackedSource(rs);
rd=alphamaskCombine24(*src++, rd)>>8; rd=*dst;
writePacked(rd); *dst++=alphamaskCombine24(rs, rd)>>8;
}
dst=(CARD8 *)wodst;
switch(ww)
{
case 1:
dst[2]=(workingoDest>>8)&0xff;
case 2:
dst[1]=(workingoDest>>16)&0xff;
case 3:
dst[0]=workingoDest>>24;
} }
} }
} }
@ -1228,7 +1312,7 @@ fbCompositeTrans_0888xnx0888(CARD8 op,
src = srcLine; src = srcLine;
srcLine += srcStride; srcLine += srcStride;
w = width*3; w = width*3;
// get to word aligned /* get to word aligned */
switch(!(int)src&3) switch(!(int)src&3)
{ {
case 1: case 1:
@ -1246,13 +1330,11 @@ fbCompositeTrans_0888xnx0888(CARD8 op,
} }
wsrc=(CARD32 *)src; wsrc=(CARD32 *)src;
widst=(CARD32 *)dst; widst=(CARD32 *)dst;
register CARD32 t1, t2, t3, t4;
while(w>3) while(w>3)
{ {
rs = *wsrc++; rs = *wsrc++;
rd = *widst; rd = *widst;
fastcombine32(maskAlpha, rs, rd, widst, t1, t2, t3, t4); inOver0888 (maskAlpha, rs, rd, *widst++);
w-=4; w-=4;
} }
src=(CARD8 *)wsrc; src=(CARD8 *)wsrc;
@ -1300,80 +1382,29 @@ fbCompositeSrcSrc_nxn (CARD8 op,
int dstXoff, dstYoff; int dstXoff, dstYoff;
int srcBpp; int srcBpp;
int dstBpp; int dstBpp;
// these need to be signed now!
int iwidth=width;
int iheight=height;
Bool reverse = FALSE; Bool reverse = FALSE;
Bool upsidedown = FALSE; Bool upsidedown = FALSE;
int initialWidth=width;
int initialX=xDst; fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
fbBlt (src + (ySrc + srcYoff) * srcStride,
srcStride,
(xSrc + srcXoff) * srcBpp,
// FIXME: this is possibly the worst piece of code I've ever written. dst + (yDst + dstYoff) * dstStride,
// My main objection to it, is that it is incrfedibly slow in a few cases, due to the dstStride,
// call-per-repeat structure of it - the *correct* solution is to implement (xDst + dstXoff) * dstBpp,
// repeat into fbBlt(), but that's a nontrivial job, and it's far more
// important to get the "requireRepeat" stuff implented functionally
// first, *then* make it fast.
// -- jj
Bool srcRepeat=pSrc->repeat;
CARD32 srcHeight=pSrc->pDrawable->height;
CARD32 srcWidth=pSrc->pDrawable->width;
fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
if(srcRepeat) (width) * dstBpp,
{ (height),
xSrc%=srcWidth;
ySrc%=srcHeight; GXcopy,
} FB_ALLONES,
dstBpp,
while(iheight>0)
{ reverse,
int wheight=iheight; upsidedown);
if(wheight>(srcHeight-ySrc))
wheight=(srcHeight-ySrc);
iwidth=initialWidth;
xDst=initialX;
while(iwidth>0)
{
int wwidth=iwidth;
if(wwidth>(srcWidth-xSrc))
wwidth=(srcWidth-xSrc);
fbBlt (src + (ySrc + srcYoff) * srcStride,
srcStride,
(xSrc + srcXoff) * srcBpp,
dst + (yDst + dstYoff) * dstStride,
dstStride,
(xDst + dstXoff) * dstBpp,
(wwidth) * dstBpp,
(wheight),
GXcopy,
FB_ALLONES,
dstBpp,
reverse,
upsidedown);
if(!srcRepeat)
iwidth=0;
else
{
xDst+=wwidth;
iwidth-=wwidth;
}
}
if(!srcRepeat)
iheight=0;
else
{
yDst+=wheight;
iheight-=wheight;
}
}
fbFinishAccess(pSrc->pDrawable); fbFinishAccess(pSrc->pDrawable);
fbFinishAccess(pDst->pDrawable); fbFinishAccess(pDst->pDrawable);
@ -1530,6 +1561,16 @@ fbComposite (CARD8 op,
break; break;
} }
} }
else
{
switch (pDst->format) {
case PICT_r5g6b5:
func = fbCompositeSolidMask_nx8888x0565;
break;
default:
break;
}
}
break; break;
case PICT_a8b8g8r8: case PICT_a8b8g8r8:
if (pMask->componentAlpha) { if (pMask->componentAlpha) {
@ -1555,6 +1596,16 @@ fbComposite (CARD8 op,
break; break;
} }
} }
else
{
switch (pDst->format) {
case PICT_b5g6r5:
func = fbCompositeSolidMask_nx8888x0565;
break;
default:
break;
}
}
break; break;
case PICT_a1: case PICT_a1:
switch (pDst->format) { switch (pDst->format) {
@ -1722,7 +1773,20 @@ fbComposite (CARD8 op,
} }
else if (! srcRepeat) else if (! srcRepeat)
{ {
switch (pSrc->format) { /*
* Formats without alpha bits are just Copy with Over
*/
if (pSrc->format == pDst->format && !PICT_FORMAT_A(pSrc->format))
{
#ifdef USE_MMX
if (fbHaveMMX() &&
(pSrc->format == PICT_x8r8g8b8 || pSrc->format == PICT_x8b8g8r8))
func = fbCompositeCopyAreammx;
else
#endif
func = fbCompositeSrcSrc_nxn;
}
else switch (pSrc->format) {
case PICT_a8r8g8b8: case PICT_a8r8g8b8:
switch (pDst->format) { switch (pDst->format) {
case PICT_a8r8g8b8: case PICT_a8r8g8b8:
@ -1800,24 +1864,6 @@ fbComposite (CARD8 op,
break; break;
} }
break; break;
case PICT_r5g6b5:
switch (pDst->format) {
case PICT_r5g6b5:
func = fbCompositeSrc_0565x0565;
break;
default:
break;
}
break;
case PICT_b5g6r5:
switch (pDst->format) {
case PICT_b5g6r5:
func = fbCompositeSrc_0565x0565;
break;
default:
break;
}
break;
default: default:
break; break;
} }
@ -1908,14 +1954,6 @@ fbComposite (CARD8 op,
n = REGION_NUM_RECTS (&region); n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region); pbox = REGION_RECTS (&region);
// FIXME: this is bascially a "white list" of composites that work
// with repeat until they are all implented. Once that's done, we
// remove the checks below entirely
if(func==fbCompositeSrcSrc_nxn)
{
srcRepeat=maskRepeat=FALSE;
}
while (n--) while (n--)
{ {
h = pbox->y2 - pbox->y1; h = pbox->y2 - pbox->y1;

View File

@ -121,7 +121,7 @@ fbCanGetSolid(PicturePtr pict)
break; \ break; \
case 16: \ case 16: \
(bits) = READ((CARD16 *) __bits__); \ (bits) = READ((CARD16 *) __bits__); \
(bits) = cvt0565to8888(bits); \ (bits) = cvt0565to0888(bits); \
break; \ break; \
case 8: \ case 8: \
(bits) = READ((CARD8 *) __bits__); \ (bits) = READ((CARD8 *) __bits__); \
@ -161,7 +161,7 @@ fbCanGetSolid(PicturePtr pict)
#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \ #define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
(((s) >> 5) & 0x07e0) | \ (((s) >> 5) & 0x07e0) | \
(((s) >> 8) & 0xf800)) (((s) >> 8) & 0xf800))
#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ #define cvt0565to0888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))