summaryrefslogtreecommitdiff
path: root/driver/xf86-video-geode/src/lx_exa.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/xf86-video-geode/src/lx_exa.c')
-rw-r--r--driver/xf86-video-geode/src/lx_exa.c1226
1 files changed, 651 insertions, 575 deletions
diff --git a/driver/xf86-video-geode/src/lx_exa.c b/driver/xf86-video-geode/src/lx_exa.c
index ef90d6b17..60edd1b30 100644
--- a/driver/xf86-video-geode/src/lx_exa.c
+++ b/driver/xf86-video-geode/src/lx_exa.c
@@ -61,8 +61,7 @@ do { \
#define GEODE_FALLBACK(x) return FALSE
#endif
-static const struct exa_format_t
-{
+static const struct exa_format_t {
int exa;
int bpp;
int fmt;
@@ -89,15 +88,13 @@ static const struct exa_format_t
#define COMP_TYPE_TWOPASS 3
#define COMP_TYPE_ROTATE 5
-static struct
-{
+static struct {
int type;
unsigned int srcOffset;
unsigned int srcPitch;
unsigned int srcBpp;
unsigned int srcWidth, srcHeight;
- PixmapPtr srcPixmap;
unsigned int srcColor;
int op;
@@ -135,10 +132,10 @@ static int
lx_fill_flags(int x0, int y0, int w, int h, int rop)
{
int x1 = x0 + w, y1 = y0 + h;
- int n = ((rop ^ (rop >> 1)) & 0x55) == 0 || /* no dst */
- x0 >= lx1 || y0 >= ly1 || /* rght/below */
- x1 <= lx0 || y1 <= ly0 ? /* left/above */
- 0 : CIMGP_BLTFLAGS_HAZARD;
+ int n = ((rop ^ (rop >> 1)) & 0x55) == 0 || /* no dst */
+ x0 >= lx1 || y0 >= ly1 || /* rght/below */
+ x1 <= lx0 || y1 <= ly0 ? /* left/above */
+ 0 : CIMGP_BLTFLAGS_HAZARD;
lx0 = x0;
ly0 = y0;
@@ -155,11 +152,11 @@ lx_copy_flags(int x0, int y0, int x1, int y1, int w, int h, int rop)
/* dst not hazzard and src not hazzard */
int n = (((rop ^ (rop >> 1)) & 0x55) == 0 ||
- x1 >= lx1 || y1 >= ly1 ||
- x2 <= lx0 || y2 <= ly0) &&
- (((rop ^ (rop >> 2)) & 0x33) == 0 ||
- x0 >= lx1 || y0 >= ly1 ||
- x0 + w <= lx0 || y0 + h <= ly0) ? 0 : CIMGP_BLTFLAGS_HAZARD;
+ x1 >= lx1 || y1 >= ly1 ||
+ x2 <= lx0 || y2 <= ly0) &&
+ (((rop ^ (rop >> 2)) & 0x33) == 0 ||
+ x0 >= lx1 || y0 >= ly1 ||
+ x0 + w <= lx0 || y0 + h <= ly0) ? 0 : CIMGP_BLTFLAGS_HAZARD;
lx0 = x1;
ly0 = y1;
@@ -176,8 +173,9 @@ lx_copy_flags(int x0, int y0, int x1, int y1, int w, int h, int rop)
/* exaGetPixelFromRGBA (exa_render.c) */
static Bool
-_GetPixelFromRGBA(CARD32 * pixel,
- CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, CARD32 format)
+_GetPixelFromRGBA(CARD32 *pixel,
+ CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha,
+ CARD32 format)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
@@ -185,7 +183,7 @@ _GetPixelFromRGBA(CARD32 * pixel,
*pixel = 0;
if (!PICT_FORMAT_COLOR(format))
- return FALSE;
+ return FALSE;
rbits = PICT_FORMAT_R(format);
gbits = PICT_FORMAT_G(format);
@@ -193,15 +191,16 @@ _GetPixelFromRGBA(CARD32 * pixel,
abits = PICT_FORMAT_A(format);
if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
- bshift = 0;
- gshift = bbits;
- rshift = gshift + gbits;
- ashift = rshift + rbits;
- } else { /* PICT_TYPE_ABGR */
- rshift = 0;
- gshift = rbits;
- bshift = gshift + gbits;
- ashift = bshift + bbits;
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ }
+ else { /* PICT_TYPE_ABGR */
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
}
*pixel |= (blue >> (16 - bbits)) << bshift;
@@ -216,14 +215,14 @@ _GetPixelFromRGBA(CARD32 * pixel,
static Bool
_GetRGBAFromPixel(CARD32 pixel,
- CARD16 * red,
- CARD16 * green, CARD16 * blue, CARD16 * alpha, CARD32 format)
+ CARD16 *red,
+ CARD16 *green, CARD16 *blue, CARD16 *alpha, CARD32 format)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
if (!PICT_FORMAT_COLOR(format))
- return FALSE;
+ return FALSE;
rbits = PICT_FORMAT_R(format);
gbits = PICT_FORMAT_G(format);
@@ -231,43 +230,45 @@ _GetRGBAFromPixel(CARD32 pixel,
abits = PICT_FORMAT_A(format);
if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
- bshift = 0;
- gshift = bbits;
- rshift = gshift + gbits;
- ashift = rshift + rbits;
- } else { /* PICT_TYPE_ABGR */
- rshift = 0;
- gshift = rbits;
- bshift = gshift + gbits;
- ashift = bshift + bbits;
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ }
+ else { /* PICT_TYPE_ABGR */
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
}
*red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits);
while (rbits < 16) {
- *red |= *red >> rbits;
- rbits <<= 1;
+ *red |= *red >> rbits;
+ rbits <<= 1;
}
*green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits);
while (gbits < 16) {
- *green |= *green >> gbits;
- gbits <<= 1;
+ *green |= *green >> gbits;
+ gbits <<= 1;
}
*blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits);
while (bbits < 16) {
- *blue |= *blue >> bbits;
- bbits <<= 1;
+ *blue |= *blue >> bbits;
+ bbits <<= 1;
}
if (abits) {
- *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits);
- while (abits < 16) {
- *alpha |= *alpha >> abits;
- abits <<= 1;
- }
- } else
- *alpha = 0xffff;
+ *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits);
+ while (abits < 16) {
+ *alpha |= *alpha >> abits;
+ abits <<= 1;
+ }
+ }
+ else
+ *alpha = 0xffff;
return TRUE;
}
@@ -283,6 +284,7 @@ lx_get_source_color(PixmapPtr pSrc, int srcFormat, int dstFormat)
* exaGetPixmapFirstPixel, so this should be adjusted so
* the stall isn't run needlessly
*/
+ /* FIXME: xserver-1.4 with a supposed fix for this is really old, so kill the stall? */
gp_wait_until_idle();
in = exaGetPixmapFirstPixel(pSrc);
@@ -305,7 +307,7 @@ lx_prepare_solid(PixmapPtr pxMap, int alu, Pixel planemask, Pixel fg)
gp_set_raster_operation(op);
if (planemask != ~0U)
- gp_set_solid_pattern(planemask);
+ gp_set_solid_pattern(planemask);
exaScratch.op = op;
@@ -321,8 +323,7 @@ lx_do_solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2)
{
int bpp = (pxMap->drawable.bitsPerPixel + 7) / 8;
int pitch = exaGetPixmapPitch(pxMap);
- unsigned int offset =
- exaGetPixmapOffset(pxMap) + (pitch * y1) + (bpp * x1);
+ unsigned int offset = exaGetPixmapOffset(pxMap) + (pitch * y1) + (bpp * x1);
gp_declare_blt(lx_fill_flags(x1, y1, x2 - x1, y2 - y1, exaScratch.op));
gp_pattern_fill(offset, x2 - x1, y2 - y1);
@@ -330,7 +331,7 @@ lx_do_solid(PixmapPtr pxMap, int x1, int y1, int x2, int y2)
static Bool
lx_prepare_copy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
- int alu, Pixel planemask)
+ int alu, Pixel planemask)
{
int dpitch = exaGetPixmapPitch(pxDst);
int op = (planemask == ~0U) ? SDfn[alu] : SDfn_PM[alu];
@@ -341,7 +342,7 @@ lx_prepare_copy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
gp_set_raster_operation(op);
if (planemask != ~0U)
- gp_set_solid_pattern(planemask);
+ gp_set_solid_pattern(planemask);
exaScratch.srcOffset = exaGetPixmapOffset(pxSrc);
exaScratch.srcPitch = exaGetPixmapPitch(pxSrc);
@@ -356,27 +357,25 @@ lx_prepare_copy(PixmapPtr pxSrc, PixmapPtr pxDst, int dx, int dy,
static void
lx_do_copy(PixmapPtr pxDst, int srcX, int srcY,
- int dstX, int dstY, int w, int h)
+ int dstX, int dstY, int w, int h)
{
int dstBpp = (pxDst->drawable.bitsPerPixel + 7) / 8;
int dstPitch = exaGetPixmapPitch(pxDst);
unsigned int srcOffset, dstOffset;
int flags = 0;
- gp_declare_blt(lx_copy_flags(srcX, srcY, dstX, dstY, w, h,
- exaScratch.op));
+ gp_declare_blt(lx_copy_flags(srcX, srcY, dstX, dstY, w, h, exaScratch.op));
srcOffset = exaScratch.srcOffset + (exaScratch.srcPitch * srcY) +
- (exaScratch.srcBpp) * srcX;
+ (exaScratch.srcBpp) * srcX;
- dstOffset = exaGetPixmapOffset(pxDst) +
- (dstPitch * dstY) + (dstBpp * dstX);
+ dstOffset = exaGetPixmapOffset(pxDst) + (dstPitch * dstY) + (dstBpp * dstX);
if (dstX > srcX)
- flags |= CIMGP_NEGXDIR;
+ flags |= CIMGP_NEGXDIR;
if (dstY > srcY)
- flags |= CIMGP_NEGYDIR;
+ flags |= CIMGP_NEGYDIR;
gp_screen_to_screen_blt(dstOffset, srcOffset, w, h, flags);
}
@@ -403,8 +402,7 @@ PictOpAtop
PictOpXor
*/
-struct blend_ops_t
-{
+struct blend_ops_t {
int operation;
int type;
int channel;
@@ -413,57 +411,59 @@ struct blend_ops_t
{
CIMGP_ALPHA_TIMES_A, CIMGP_CONSTANT_ALPHA, CIMGP_CHANNEL_A_SOURCE}, {
},
- /* PictOpSrc */
+ /* PictOpSrc */
{
CIMGP_ALPHA_TIMES_A, CIMGP_ALPHA_EQUALS_ONE, CIMGP_CHANNEL_A_SOURCE}, {
},
- /* PictOpDst */
+ /* PictOpDst */
{
CIMGP_ALPHA_TIMES_A, CIMGP_ALPHA_EQUALS_ONE, CIMGP_CHANNEL_A_DEST}, {
},
- /* PictOpOver */
+ /* PictOpOver */
{
CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE}, {
CIMGP_ALPHA_TIMES_A, CIMGP_CONVERTED_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* PictOpOverReverse */
+ /* PictOpOverReverse */
{
CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST}, {
CIMGP_ALPHA_TIMES_A, CIMGP_CONVERTED_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* PictOpIn */
+ /* PictOpIn */
{
CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE}, {
CIMGP_ALPHA_TIMES_A, CIMGP_CONVERTED_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* PictOpInReverse */
+ /* PictOpInReverse */
{
CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_DEST}, {
CIMGP_ALPHA_TIMES_A, CIMGP_CONVERTED_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* PictOpOut */
+ /* PictOpOut */
{
CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST}, {
CIMGP_ALPHA_TIMES_A, CIMGP_CONVERTED_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* PictOpOutReverse */
+ /* PictOpOutReverse */
{
CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE}, {
CIMGP_ALPHA_TIMES_A, CIMGP_CONVERTED_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* SrcAtop */
+ /* SrcAtop */
{
CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_DEST}, {
CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* SrcAtopReverse */
+ /* SrcAtopReverse */
{
CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE}, {
CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST},
- /* Xor */
+ /* Xor */
{
CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE}, {
CIMGP_BETA_TIMES_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE},
- /* PictOpAdd */
+ /* PictOpAdd */
{
CIMGP_A_PLUS_BETA_B, CIMGP_CONSTANT_ALPHA, CIMGP_CHANNEL_A_SOURCE}, {
}
};
+#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof((a)) / (sizeof(*(a))))
+#endif
static const struct exa_format_t *
lx_get_format(PicturePtr p)
@@ -472,8 +472,8 @@ lx_get_format(PicturePtr p)
unsigned int format = p->format;
for (i = 0; i < ARRAY_SIZE(lx_exa_formats); i++)
- if (lx_exa_formats[i].exa == format)
- return (&lx_exa_formats[i]);
+ if (lx_exa_formats[i].exa == format)
+ return (&lx_exa_formats[i]);
return NULL;
}
@@ -492,10 +492,9 @@ lx_process_transform(PicturePtr pSrc)
* translate coordinates */
if (t->matrix[0][0] == 0 &&
- t->matrix[0][1] == 0 &&
- t->matrix[1][0] == 0 && t->matrix[1][1] == 0) {
- exaScratch.transform = pSrc->transform;
- return TRUE;
+ t->matrix[0][1] == 0 && t->matrix[1][0] == 0 && t->matrix[1][1] == 0) {
+ exaScratch.transform = pSrc->transform;
+ return TRUE;
}
/* Otherwise, see if this is a simple
@@ -503,7 +502,7 @@ lx_process_transform(PicturePtr pSrc)
* we have to punt back to software */
if (t->matrix[2][2] != F(1))
- return FALSE;
+ return FALSE;
/* The rotate matrix looks like this:
* [ cos X -sin x
@@ -517,22 +516,22 @@ lx_process_transform(PicturePtr pSrc)
*/
if ((c0 != c1) || (s0 != -s1))
- return FALSE;
+ return FALSE;
/* Now, figure out what angle we want - we
* can only accelerate right angle rotations,
* so this turns into an easy set of if statements */
if (c0 == F(1) && s1 == F(0))
- exaScratch.rotate = RR_Rotate_0;
+ exaScratch.rotate = RR_Rotate_0;
else if (c0 == F(0) && s1 == F(1))
- exaScratch.rotate = RR_Rotate_90;
+ exaScratch.rotate = RR_Rotate_90;
else if (c0 == F(-1) && s1 == F(0))
- exaScratch.rotate = RR_Rotate_180;
+ exaScratch.rotate = RR_Rotate_180;
else if (c0 == F(0) && s1 == F(-1))
- exaScratch.rotate = RR_Rotate_270;
+ exaScratch.rotate = RR_Rotate_270;
else
- return FALSE;
+ return FALSE;
exaScratch.transform = pSrc->transform;
@@ -546,30 +545,41 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst)
const struct exa_format_t *srcFmt, *dstFmt;
if (op > PictOpAdd)
- GEODE_FALLBACK(("Operation %d is not supported\n", op));
+ GEODE_FALLBACK(("Operation %d is not supported\n", op));
+
+ /* XXX - don't know if we can do any hwaccel on solid fills or gradient types in generic cases */
+ if (pMsk && pMsk->pSourcePict)
+ GEODE_FALLBACK(("%s are not supported as a mask\n",
+ pMsk->pSourcePict->type ==
+ SourcePictTypeSolidFill ? "Solid pictures" :
+ "Gradients"));
+
+ if (pSrc->pSourcePict && pSrc->pSourcePict->type != SourcePictTypeSolidFill)
+ GEODE_FALLBACK(("Gradients are not supported as the source\n"));
+
+ if (pMsk && op == PictOpAdd)
+ GEODE_FALLBACK(("PictOpAdd with mask is not supported\n"));
/* FIXME: Meet this conditions from the debug for PictOpAdd.
* Any Other possibilities? Add a judge for the future supplement */
if (op == PictOpAdd && pSrc->format == PICT_a8r8g8b8 &&
- pDst->format == PICT_a8 && !pMsk)
- return TRUE;
+ pDst->format == PICT_a8)
+ return TRUE;
if (op == PictOpAdd && pSrc->format == PICT_x8r8g8b8 &&
- pDst->format == PICT_a8 && !pMsk)
- return TRUE;
+ pDst->format == PICT_a8)
+ return TRUE;
if (op == PictOpAdd && pSrc->format == PICT_r5g6b5 &&
- pDst->format == PICT_a8 && !pMsk)
- return TRUE;
+ pDst->format == PICT_a8)
+ return TRUE;
if (usesPasses(op)) {
- if (pGeode->exaBfrOffset == 0 || !pMsk)
- GEODE_FALLBACK(("Multipass operation requires off-screen buffer\n"));
+ /* FIXME: Slightly misleading fallback msg when !pMsk */
+ if (pGeode->exaBfrOffset == 0 || !pMsk)
+ GEODE_FALLBACK(("Multipass operation requires off-screen buffer\n"));
}
- if (pMsk && op == PictOpAdd)
- GEODE_FALLBACK(("PictOpAdd with mask is not supported\n"));
-
/* Check that the filter matches what we support */
switch (pSrc->filter) {
@@ -577,18 +587,14 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst)
case PictFilterFast:
case PictFilterGood:
case PictFilterBest:
- break;
+ break;
default:
- GEODE_FALLBACK(("Bilinear or convolution filters are not supported\n"));
+ GEODE_FALLBACK(("Bilinear or convolution filters are not supported\n"));
}
if (pMsk && pMsk->transform)
- GEODE_FALLBACK(("Mask transforms are not supported\n"));
-
- /* XXX - don't know if we can do any hwaccel on solid fills or gradient types */
- if (pSrc->pSourcePict || (pMsk && pMsk->pSourcePict))
- GEODE_FALLBACK(("Solid fills or gradient types are not supported\n"));
+ GEODE_FALLBACK(("Mask transforms are not supported\n"));
/* Keep an eye out for source rotation transforms - those we can
* do something about */
@@ -597,74 +603,81 @@ lx_check_composite(int op, PicturePtr pSrc, PicturePtr pMsk, PicturePtr pDst)
exaScratch.transform = NULL;
if (pSrc->transform && !lx_process_transform(pSrc))
- GEODE_FALLBACK(("Transform operation is non-trivial\n"));
+ GEODE_FALLBACK(("Transform operation is non-trivial\n"));
/* XXX - I don't understand PICT_a8 enough - so I'm punting */
if ((op != PictOpAdd) && (pSrc->format == PICT_a8 ||
- pDst->format == PICT_a8))
- GEODE_FALLBACK(("PICT_a8 as src or dst format is unsupported\n"));
+ pDst->format == PICT_a8))
+ GEODE_FALLBACK(("PICT_a8 as src or dst format is unsupported\n"));
if (pMsk && op != PictOpClear) {
- struct blend_ops_t *opPtr = &lx_alpha_ops[op * 2];
- int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1;
-
- /* Direction 0 indicates src->dst, 1 indiates dst->src */
- if (((direction == 0) && (pSrc->pDrawable->bitsPerPixel < 16)) ||
- ((direction == 1) && (pDst->pDrawable->bitsPerPixel < 16))) {
- ErrorF("Mask blending unsupported with <16bpp\n");
- return FALSE;
- }
- if (pMsk->format != PICT_a8 && pMsk->format != PICT_a4)
- GEODE_FALLBACK(("Masks can be only done with a 8bpp or 4bpp depth\n"));
-
- /* The pSrc should be 1x1 pixel if the pMsk is not zero */
- if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1)
- GEODE_FALLBACK(("pSrc should be 1x1 pixel if pMsk is not zero\n"));
- /* FIXME: In lx_prepare_composite, there are no variables to record the
- * one pixel source's width and height when the mask is not zero.
- * That will lead to bigger region to render instead of one pixel in lx
- * _do_composite, so we should fallback currently to avoid this */
- if (!pSrc->repeat)
- GEODE_FALLBACK(("FIXME: unzero mask might lead to bigger rendering region than 1x1 pixels\n"));
+ struct blend_ops_t *opPtr = &lx_alpha_ops[op * 2];
+ int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1;
+
+ /* Direction 0 indicates src->dst, 1 indicates dst->src */
+ if (((direction == 0) &&
+ (pSrc->pDrawable && pSrc->pDrawable->bitsPerPixel < 16)) ||
+ ((direction == 1) && (pDst->pDrawable->bitsPerPixel < 16))) {
+ ErrorF("Mask blending unsupported with <16bpp\n");
+ return FALSE;
+ }
+ if (pMsk->format != PICT_a8 && pMsk->format != PICT_a4)
+ GEODE_FALLBACK(("Masks can be only done with a 8bpp or 4bpp depth\n"));
+
+ /* The pSrc should be 1x1 pixel if the pMsk is not zero */
+ if (pSrc->pDrawable &&
+ (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1))
+ GEODE_FALLBACK(("pSrc should be 1x1 pixel if pMsk is not zero\n"));
+ /* FIXME: In lx_prepare_composite, there are no variables to record the
+ * one pixel source's width and height when the mask is not zero.
+ * That will lead to bigger region to render instead of one pixel in lx
+ * _do_composite, so we should fallback currently to avoid this */
+ /* Not an issue for solid pictures, because we'll treat it as 1x1R too */
+ if (!pSrc->repeat &&
+ !(pSrc->pSourcePict &&
+ pSrc->pSourcePict->type == SourcePictTypeSolidFill)) {
+ GEODE_FALLBACK(("FIXME: unzero mask might lead to bigger rendering region than 1x1 pixels\n"));
+ }
+ }
+ else {
+ if (pSrc->pSourcePict)
+ GEODE_FALLBACK(("Solid source pictures without a mask are not supported\n"));
}
/* Get the formats for the source and destination */
- if ((srcFmt = lx_get_format(pSrc)) == NULL) {
- ErrorF("EXA: Invalid source format %x\n", pSrc->format);
- return FALSE;
- }
+ if ((srcFmt = lx_get_format(pSrc)) == NULL)
+ GEODE_FALLBACK(("Unsupported source format %x\n", pSrc->format));
- if ((dstFmt = lx_get_format(pDst)) == NULL) {
- ErrorF("EXA: Invalid destination format %x\n", pDst->format);
- return FALSE;
- }
+ if ((dstFmt = lx_get_format(pDst)) == NULL)
+ GEODE_FALLBACK(("Unsupported destination format %x\n", pDst->format));
/* Make sure operations that need alpha bits have them */
/* If a mask is enabled, the alpha will come from there */
if (!pMsk && (!srcFmt->alphabits && usesSrcAlpha(op)))
- GEODE_FALLBACK(("Operation requires src alpha, but alphabits is unset\n"));
+ GEODE_FALLBACK(("Operation requires src alpha, but alphabits is unset\n"));
if (!pMsk && (!dstFmt->alphabits && usesDstAlpha(op)))
- GEODE_FALLBACK(("Operation requires dst alpha, but alphabits is unset\n"));
+ GEODE_FALLBACK(("Operation requires dst alpha, but alphabits is unset\n"));
/* FIXME: See a way around this! */
if (srcFmt->alphabits == 0 && dstFmt->alphabits != 0)
- GEODE_FALLBACK(("src_alphabits=0, dst_alphabits!=0\n"));
+ GEODE_FALLBACK(("src_alphabits=0, dst_alphabits!=0\n"));
/* If this is a rotate operation, then make sure the src and dst
* formats are the same */
if (exaScratch.rotate != RR_Rotate_0 && srcFmt != dstFmt) {
- ErrorF("EXA: Unable to rotate and convert formats at the same time\n");
- return FALSE;
+ ErrorF("EXA: Unable to rotate and convert formats at the same time\n");
+ return FALSE;
}
return TRUE;
}
static Bool
lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk,
- PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk, PixmapPtr pxDst)
+ PicturePtr pDst, PixmapPtr pxSrc, PixmapPtr pxMsk,
+ PixmapPtr pxDst)
{
GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
const struct exa_format_t *srcFmt, *dstFmt;
@@ -676,60 +689,64 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk,
/* Set up the scratch buffer with the information we need */
- exaScratch.srcFormat = (struct exa_format_t *)srcFmt;
- exaScratch.dstFormat = (struct exa_format_t *)dstFmt;
+ exaScratch.srcFormat = (struct exa_format_t *) srcFmt;
+ exaScratch.dstFormat = (struct exa_format_t *) dstFmt;
exaScratch.op = op;
exaScratch.repeat = pSrc->repeat;
exaScratch.bufferOffset = pGeode->exaBfrOffset;
if (pMsk && op != PictOpClear) {
- /* Get the source color */
- /* If the op is PictOpOver(or PictOpOutReverse, PictOpInReverse,
- * PictOpIn, PictOpOut, PictOpOverReverse), we should get the
- * ARGB32 source format */
-
- if ((op == PictOpOver || op == PictOpOutReverse || op ==
- PictOpInReverse || op == PictOpIn || op == PictOpOut ||
- op == PictOpOverReverse) && (srcFmt->alphabits != 0))
- exaScratch.srcColor = exaGetPixmapFirstPixel(pxSrc);
- else if ((op == PictOpOver || op == PictOpOutReverse || op ==
- PictOpInReverse || op == PictOpIn || op == PictOpOut ||
- op == PictOpOverReverse) &&
- (srcFmt->alphabits == 0))
- exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format,
- PICT_a8r8g8b8);
- else
- exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format,
- pDst->format);
-
- /* Save off the info we need (reuse the source values to save space) */
-
- exaScratch.type = COMP_TYPE_MASK;
- exaScratch.maskrepeat = pMsk->repeat;
-
- exaScratch.srcOffset = exaGetPixmapOffset(pxMsk);
- exaScratch.srcPitch = exaGetPixmapPitch(pxMsk);
- exaScratch.srcBpp = (pxMsk->drawable.bitsPerPixel + 7) / 8;
-
- exaScratch.srcWidth = pMsk->pDrawable->width;
- exaScratch.srcHeight = pMsk->pDrawable->height;
-
- /* Flag to indicate if this a 8BPP or a 4BPP mask */
- exaScratch.fourBpp = (pxMsk->drawable.bitsPerPixel == 4) ? 1 : 0;
- } else {
- if (usesPasses(op))
- exaScratch.type = COMP_TYPE_TWOPASS;
- else if (exaScratch.rotate != RR_Rotate_0)
- exaScratch.type = COMP_TYPE_ROTATE;
- else
- exaScratch.type = COMP_TYPE_ONEPASS;
-
- exaScratch.srcOffset = exaGetPixmapOffset(pxSrc);
- exaScratch.srcPitch = exaGetPixmapPitch(pxSrc);
- exaScratch.srcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
-
- exaScratch.srcWidth = pSrc->pDrawable->width;
- exaScratch.srcHeight = pSrc->pDrawable->height;
+ /* Get the source color */
+ if (pSrc->pSourcePict) {
+ exaScratch.srcColor = pSrc->pSourcePict->solidFill.color;
+ }
+ else {
+ /* If the op is PictOpOver(or PictOpOutReverse, PictOpInReverse,
+ * PictOpIn, PictOpOut, PictOpOverReverse), we should get the
+ * ARGB32 source format */
+
+ if ((op == PictOpOver || op == PictOpOutReverse || op ==
+ PictOpInReverse || op == PictOpIn || op == PictOpOut ||
+ op == PictOpOverReverse) && (srcFmt->alphabits != 0))
+ exaScratch.srcColor = exaGetPixmapFirstPixel(pxSrc);
+ else if ((op == PictOpOver || op == PictOpOutReverse || op ==
+ PictOpInReverse || op == PictOpIn || op == PictOpOut ||
+ op == PictOpOverReverse) && (srcFmt->alphabits == 0))
+ exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format,
+ PICT_a8r8g8b8);
+ else
+ exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format,
+ pDst->format);
+ }
+
+ /* Save off the info we need (reuse the source values to save space) */
+ exaScratch.type = COMP_TYPE_MASK;
+ exaScratch.maskrepeat = pMsk->repeat;
+
+ exaScratch.srcOffset = exaGetPixmapOffset(pxMsk);
+ exaScratch.srcPitch = exaGetPixmapPitch(pxMsk);
+ exaScratch.srcBpp = (pxMsk->drawable.bitsPerPixel + 7) / 8;
+
+ exaScratch.srcWidth = pMsk->pDrawable->width;
+ exaScratch.srcHeight = pMsk->pDrawable->height;
+
+ /* Flag to indicate if this a 8BPP or a 4BPP mask */
+ exaScratch.fourBpp = (pxMsk->drawable.bitsPerPixel == 4) ? 1 : 0;
+ }
+ else {
+ if (usesPasses(op))
+ exaScratch.type = COMP_TYPE_TWOPASS;
+ else if (exaScratch.rotate != RR_Rotate_0)
+ exaScratch.type = COMP_TYPE_ROTATE;
+ else
+ exaScratch.type = COMP_TYPE_ONEPASS;
+
+ exaScratch.srcOffset = exaGetPixmapOffset(pxSrc);
+ exaScratch.srcPitch = exaGetPixmapPitch(pxSrc);
+ exaScratch.srcBpp = (pxSrc->drawable.bitsPerPixel + 7) / 8;
+
+ exaScratch.srcWidth = pSrc->pDrawable->width;
+ exaScratch.srcHeight = pSrc->pDrawable->height;
}
return TRUE;
@@ -742,21 +759,21 @@ lx_get_bpp_from_format(int format)
switch (format) {
case CIMGP_SOURCE_FMT_8_8_8_8:
case CIMGP_SOURCE_FMT_32BPP_BGR:
- return 32;
+ return 32;
case CIMGP_SOURCE_FMT_4_4_4_4:
- return 12;
+ return 12;
case CIMGP_SOURCE_FMT_0_5_6_5:
case CIMGP_SOURCE_FMT_16BPP_BGR:
- return 16;
+ return 16;
case CIMGP_SOURCE_FMT_1_5_5_5:
case CIMGP_SOURCE_FMT_15BPP_BGR:
- return 15;
+ return 15;
case CIMGP_SOURCE_FMT_3_3_2:
- return 8;
+ return 8;
}
return 0;
@@ -771,11 +788,11 @@ static void
lx_set_source_format(int srcFormat, int dstFormat)
{
if (!(srcFormat & 0x10) && (dstFormat & 0x10))
- gp_set_source_format(srcFormat | 0x10);
+ gp_set_source_format(srcFormat | 0x10);
else if ((srcFormat & 0x10) && (dstFormat & 0x10))
- gp_set_source_format(srcFormat & ~0x10);
+ gp_set_source_format(srcFormat & ~0x10);
else
- gp_set_source_format(srcFormat);
+ gp_set_source_format(srcFormat);
}
/* If we are converting colors and we need the channel A alpha,
@@ -787,7 +804,7 @@ static inline int
get_op_type(struct exa_format_t *src, struct exa_format_t *dst, int type)
{
return (type == CIMGP_CHANNEL_A_ALPHA &&
- src->alphabits != dst->alphabits) ? CIMGP_CONVERTED_ALPHA : type;
+ src->alphabits != dst->alphabits) ? CIMGP_CONVERTED_ALPHA : type;
}
/* Note - this is the preferred onepass method. The other will remain
@@ -803,8 +820,8 @@ get_op_type(struct exa_format_t *src, struct exa_format_t *dst, int type)
static void
lx_composite_onepass_add_a8(PixmapPtr pxDst, unsigned long dstOffset,
- unsigned long srcOffset, int width, int height, int opX, int opY,
- int srcX, int srcY)
+ unsigned long srcOffset, int width, int height,
+ int opX, int opY, int srcX, int srcY)
{
struct blend_ops_t *opPtr;
int apply, type;
@@ -821,46 +838,50 @@ lx_composite_onepass_add_a8(PixmapPtr pxDst, unsigned long dstOffset,
gp_wait_until_idle();
if (opX % 4 == 0 && srcX % 4 == 0) {
- /* HW acceleration */
- opPtr = &lx_alpha_ops[exaScratch.op * 2];
- apply = CIMGP_APPLY_BLEND_TO_ALL;
- gp_declare_blt(0);
- gp_set_bpp(32);
- gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch);
- gp_set_source_format(8);
- type = opPtr->type;
- gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, apply, 0);
- gp_screen_to_screen_convert(dstOffset, srcOffset, width / 4, height, 0);
- /* Calculate the pixels in the tail of each line */
- for (j = srcY; j < srcY + height; j++)
- for (i = srcX + (width / 4) * 4; i < srcX + width; i++) {
- srcOffset = GetSrcOffset(i, j);
- optempX = opX + i - srcX;
- optempY = opY + j - srcY;
- dstOffset = pixmapOffset + pixmapPitch * optempY +
- calBitsPixel * optempX;
- *(cim_fb_ptr + dstOffset) = (*(cim_fb_ptr + srcOffset)
- + *(cim_fb_ptr + dstOffset) <= 0xff) ?
- *(cim_fb_ptr + srcOffset) + *(cim_fb_ptr + dstOffset) : 0xff;
- }
- } else {
- for (j = srcY; j < srcY + height; j++)
- for (i = srcX; i < srcX + width; i++) {
- srcOffset = GetSrcOffset(i, j);
- optempX = opX + i - srcX;
- optempY = opY + j - srcY;
- dstOffset = pixmapOffset + pixmapPitch * optempY +
- calBitsPixel * optempX;
- *(cim_fb_ptr + dstOffset) = (*(cim_fb_ptr + srcOffset) +
- *(cim_fb_ptr + dstOffset) <= 0xff) ?
- *(cim_fb_ptr + srcOffset) + *(cim_fb_ptr + dstOffset) : 0xff;
- }
+ /* HW acceleration */
+ opPtr = &lx_alpha_ops[exaScratch.op * 2];
+ apply = CIMGP_APPLY_BLEND_TO_ALL;
+ gp_declare_blt(0);
+ gp_set_bpp(32);
+ gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch);
+ gp_set_source_format(8);
+ type = opPtr->type;
+ gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, apply,
+ 0);
+ gp_screen_to_screen_convert(dstOffset, srcOffset, width / 4, height, 0);
+ /* Calculate the pixels in the tail of each line */
+ for (j = srcY; j < srcY + height; j++)
+ for (i = srcX + (width / 4) * 4; i < srcX + width; i++) {
+ srcOffset = GetSrcOffset(i, j);
+ optempX = opX + i - srcX;
+ optempY = opY + j - srcY;
+ dstOffset = pixmapOffset + pixmapPitch * optempY +
+ calBitsPixel * optempX;
+ *(cim_fb_ptr + dstOffset) = (*(cim_fb_ptr + srcOffset)
+ + *(cim_fb_ptr + dstOffset) <=
+ 0xff) ? *(cim_fb_ptr + srcOffset) +
+ *(cim_fb_ptr + dstOffset) : 0xff;
+ }
+ }
+ else {
+ for (j = srcY; j < srcY + height; j++)
+ for (i = srcX; i < srcX + width; i++) {
+ srcOffset = GetSrcOffset(i, j);
+ optempX = opX + i - srcX;
+ optempY = opY + j - srcY;
+ dstOffset = pixmapOffset + pixmapPitch * optempY +
+ calBitsPixel * optempX;
+ *(cim_fb_ptr + dstOffset) = (*(cim_fb_ptr + srcOffset) +
+ *(cim_fb_ptr + dstOffset) <=
+ 0xff) ? *(cim_fb_ptr + srcOffset) +
+ *(cim_fb_ptr + dstOffset) : 0xff;
+ }
}
}
static void
lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset,
- unsigned long srcOffset, int width, int height)
+ unsigned long srcOffset, int width, int height)
{
struct blend_ops_t *opPtr;
int apply, type;
@@ -868,18 +889,16 @@ lx_composite_onepass(PixmapPtr pxDst, unsigned long dstOffset,
opPtr = &lx_alpha_ops[exaScratch.op * 2];
apply = (exaScratch.dstFormat->alphabits != 0 &&
- exaScratch.srcFormat->alphabits != 0) ?
- CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB;
+ exaScratch.srcFormat->alphabits != 0) ?
+ CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB;
gp_declare_blt(0);
gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch);
- lx_set_source_format(exaScratch.srcFormat->fmt,
- exaScratch.dstFormat->fmt);
+ lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.dstFormat->fmt);
- type =
- get_op_type(exaScratch.srcFormat, exaScratch.dstFormat, opPtr->type);
+ type = get_op_type(exaScratch.srcFormat, exaScratch.dstFormat, opPtr->type);
gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, apply, 0);
@@ -894,14 +913,12 @@ lx_composite_all_black(unsigned long srcOffset, int width, int height)
opPtr = &lx_alpha_ops[0];
apply = (exaScratch.srcFormat->alphabits != 0) ?
- CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB;
+ CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB;
gp_declare_blt(0);
gp_set_bpp(lx_get_bpp_from_format(exaScratch.srcFormat->fmt));
gp_set_strides(exaScratch.srcPitch, exaScratch.srcPitch);
- lx_set_source_format(exaScratch.srcFormat->fmt,
- exaScratch.srcFormat->fmt);
- type =
- get_op_type(exaScratch.srcFormat, exaScratch.srcFormat, opPtr->type);
+ lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.srcFormat->fmt);
+ type = get_op_type(exaScratch.srcFormat, exaScratch.srcFormat, opPtr->type);
gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, apply, 0);
gp_screen_to_screen_convert(srcOffset, srcOffset, width, height, 0);
@@ -909,7 +926,7 @@ lx_composite_all_black(unsigned long srcOffset, int width, int height)
static void
lx_composite_onepass_special(PixmapPtr pxDst, int width, int height, int opX,
- int opY, int srcX, int srcY)
+ int opY, int srcX, int srcY)
{
struct blend_ops_t *opPtr;
int apply, type;
@@ -921,65 +938,69 @@ lx_composite_onepass_special(PixmapPtr pxDst, int width, int height, int opX,
optempY = opY;
/* Make sure srcX and srcY are in source region */
- srcX = ((srcX % (int)exaScratch.srcWidth) + (int)exaScratch.srcWidth)
- % (int)exaScratch.srcWidth;
- srcY = ((srcY % (int)exaScratch.srcHeight) + (int)exaScratch.srcHeight)
- % (int)exaScratch.srcHeight;
+ srcX = ((srcX % (int) exaScratch.srcWidth) + (int) exaScratch.srcWidth)
+ % (int) exaScratch.srcWidth;
+ srcY = ((srcY % (int) exaScratch.srcHeight) + (int) exaScratch.srcHeight)
+ % (int) exaScratch.srcHeight;
opWidth = exaScratch.srcWidth - srcX;
- opHeight = exaScratch.srcHeight - srcY;
+ opHeight = exaScratch.srcHeight - srcY;
srcOffset = GetSrcOffset(srcX, srcY);
if (width < opWidth)
- opWidth = width;
+ opWidth = width;
if (height < opHeight)
- opHeight = height;
+ opHeight = height;
while (1) {
- gp_wait_until_idle();
- dstOffset = GetPixmapOffset(pxDst, optempX, optempY);
- opPtr = &lx_alpha_ops[exaScratch.op * 2];
- apply = (exaScratch.dstFormat->alphabits != 0 &&
- exaScratch.srcFormat->alphabits != 0) ?
- CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB;
- gp_declare_blt(0);
- gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
- gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch);
- lx_set_source_format(exaScratch.srcFormat->fmt,
- exaScratch.dstFormat->fmt);
- type = get_op_type(exaScratch.srcFormat, exaScratch.dstFormat,
- opPtr->type);
- gp_set_alpha_operation(opPtr->operation, type, opPtr->channel,
- apply, 0);
- gp_screen_to_screen_convert(dstOffset, srcOffset, opWidth, opHeight, 0);
-
- optempX += opWidth;
- if (optempX >= opX + width) {
- optempX = opX;
- optempY += opHeight;
- if (optempY >= opY + height)
- break;
- }
- if (optempX == opX) {
- srcOffset = GetSrcOffset(srcX, 0);
- opWidth = ((opX + width) - optempX) > (exaScratch.srcWidth - srcX)
- ? (exaScratch.srcWidth - srcX) : ((opX + width) - optempX);
- opHeight = ((opY + height) - optempY) > exaScratch.srcHeight
- ? exaScratch.srcHeight : ((opY + height) - optempY);
- } else if (optempY == opY) {
- srcOffset = GetSrcOffset(0, srcY);
- opWidth = ((opX + width) - optempX) > exaScratch.srcWidth
- ? exaScratch.srcWidth : ((opX + width) - optempX);
- opHeight = ((opY + height) - optempY) > (exaScratch.srcHeight -
- srcY) ? (exaScratch.srcHeight - srcY) : ((opY + height) - optempY);
- } else {
- srcOffset = GetSrcOffset(0, 0);
- opWidth = ((opX + width) - optempX) > exaScratch.srcWidth
- ? exaScratch.srcWidth : ((opX + width) - optempX);
- opHeight = ((opY + height) - optempY) > exaScratch.srcHeight
- ? exaScratch.srcHeight : ((opY + height) - optempY);
- }
+ gp_wait_until_idle();
+ dstOffset = GetPixmapOffset(pxDst, optempX, optempY);
+ opPtr = &lx_alpha_ops[exaScratch.op * 2];
+ apply = (exaScratch.dstFormat->alphabits != 0 &&
+ exaScratch.srcFormat->alphabits != 0) ?
+ CIMGP_APPLY_BLEND_TO_ALL : CIMGP_APPLY_BLEND_TO_RGB;
+ gp_declare_blt(0);
+ gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
+ gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch);
+ lx_set_source_format(exaScratch.srcFormat->fmt,
+ exaScratch.dstFormat->fmt);
+ type = get_op_type(exaScratch.srcFormat, exaScratch.dstFormat,
+ opPtr->type);
+ gp_set_alpha_operation(opPtr->operation, type, opPtr->channel,
+ apply, 0);
+ gp_screen_to_screen_convert(dstOffset, srcOffset, opWidth, opHeight, 0);
+
+ optempX += opWidth;
+ if (optempX >= opX + width) {
+ optempX = opX;
+ optempY += opHeight;
+ if (optempY >= opY + height)
+ break;
+ }
+ if (optempX == opX) {
+ srcOffset = GetSrcOffset(srcX, 0);
+ opWidth = ((opX + width) - optempX) > (exaScratch.srcWidth - srcX)
+ ? (exaScratch.srcWidth - srcX) : ((opX + width) - optempX);
+ opHeight = ((opY + height) - optempY) > exaScratch.srcHeight
+ ? exaScratch.srcHeight : ((opY + height) - optempY);
+ }
+ else if (optempY == opY) {
+ srcOffset = GetSrcOffset(0, srcY);
+ opWidth = ((opX + width) - optempX) > exaScratch.srcWidth
+ ? exaScratch.srcWidth : ((opX + width) - optempX);
+ opHeight = ((opY + height) - optempY) > (exaScratch.srcHeight -
+ srcY)
+ ? (exaScratch.srcHeight - srcY) : ((opY + height)
+ - optempY);
+ }
+ else {
+ srcOffset = GetSrcOffset(0, 0);
+ opWidth = ((opX + width) - optempX) > exaScratch.srcWidth
+ ? exaScratch.srcWidth : ((opX + width) - optempX);
+ opHeight = ((opY + height) - optempY) > exaScratch.srcHeight
+ ? exaScratch.srcHeight : ((opY + height) - optempY);
+ }
}
}
@@ -987,7 +1008,7 @@ lx_composite_onepass_special(PixmapPtr pxDst, int width, int height, int opX,
static void
lx_composite_multipass(PixmapPtr pxDst, unsigned long dstOffset,
- unsigned long srcOffset, int width, int height)
+ unsigned long srcOffset, int width, int height)
{
struct blend_ops_t *opPtr;
int sbpp = lx_get_bpp_from_format(exaScratch.srcFormat->fmt);
@@ -1008,7 +1029,7 @@ lx_composite_multipass(PixmapPtr pxDst, unsigned long dstOffset,
gp_set_raster_operation(0xCC);
gp_set_strides(exaScratch.srcPitch, exaGetPixmapPitch(pxDst));
gp_screen_to_screen_convert(exaScratch.bufferOffset, dstOffset,
- width, height, 0);
+ width, height, 0);
/* Do the first blend from the source to the scratch buffer */
@@ -1020,40 +1041,38 @@ lx_composite_multipass(PixmapPtr pxDst, unsigned long dstOffset,
opPtr = &lx_alpha_ops[exaScratch.op * 2];
apply = (exaScratch.srcFormat->alphabits == 0) ?
- CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL;
+ CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL;
/* If we're destroying the source alpha bits, then make sure we
* use the alpha before the color conversion
*/
gp_screen_to_screen_blt(exaScratch.bufferOffset, srcOffset, width, height,
- 0);
+ 0);
/* Finally, do the second blend back to the destination */
opPtr = &lx_alpha_ops[(exaScratch.op * 2) + 1];
apply = (exaScratch.dstFormat->alphabits == 0) ?
- CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL;
+ CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL;
gp_declare_blt(CIMGP_BLTFLAGS_HAZARD);
gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
- lx_set_source_format(exaScratch.srcFormat->fmt,
- exaScratch.dstFormat->fmt);
+ lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.dstFormat->fmt);
- type =
- get_op_type(exaScratch.srcFormat, exaScratch.dstFormat, opPtr->type);
+ type = get_op_type(exaScratch.srcFormat, exaScratch.dstFormat, opPtr->type);
gp_set_alpha_operation(opPtr->operation, type, opPtr->channel, apply, 0);
gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset,
- width, height, 0);
+ width, height, 0);
}
static void
lx_composite_rotate(PixmapPtr pxDst, unsigned long dstOffset,
- unsigned int srcOffset, int width, int height)
+ unsigned int srcOffset, int width, int height)
{
int degrees = 0;
@@ -1061,8 +1080,7 @@ lx_composite_rotate(PixmapPtr pxDst, unsigned long dstOffset,
gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
gp_set_strides(exaGetPixmapPitch(pxDst), exaScratch.srcPitch);
- lx_set_source_format(exaScratch.srcFormat->fmt,
- exaScratch.dstFormat->fmt);
+ lx_set_source_format(exaScratch.srcFormat->fmt, exaScratch.dstFormat->fmt);
gp_set_raster_operation(0xCC);
@@ -1071,14 +1089,14 @@ lx_composite_rotate(PixmapPtr pxDst, unsigned long dstOffset,
switch (exaScratch.rotate) {
case RR_Rotate_90:
- degrees = 270;
- break;
+ degrees = 270;
+ break;
case RR_Rotate_180:
- degrees = 180;
- break;
+ degrees = 180;
+ break;
case RR_Rotate_270:
- degrees = 90;
- break;
+ degrees = 90;
+ break;
}
gp_rotate_blt(dstOffset, srcOffset, width, height, degrees);
@@ -1086,7 +1104,7 @@ lx_composite_rotate(PixmapPtr pxDst, unsigned long dstOffset,
static void
lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset,
- unsigned int maskOffset, int width, int height)
+ unsigned int maskOffset, int width, int height)
{
struct blend_ops_t *opPtr = &lx_alpha_ops[exaScratch.op * 2];
@@ -1098,13 +1116,14 @@ lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset,
gp_set_solid_source(exaScratch.srcColor);
gp_blend_mask_blt(dstOffset, 0, width, height, maskOffset,
- exaScratch.srcPitch, opPtr->operation, exaScratch.fourBpp);
+ exaScratch.srcPitch, opPtr->operation,
+ exaScratch.fourBpp);
}
static void
lx_do_composite_mask_two_pass(PixmapPtr pxDst, unsigned long dstOffset,
- unsigned int maskOffset, int width, int height, int opX, int opY,
- xPointFixed srcPoint)
+ unsigned int maskOffset, int width, int height,
+ int opX, int opY, xPointFixed srcPoint)
{
int apply, type;
struct blend_ops_t *opPtr;
@@ -1120,62 +1139,64 @@ lx_do_composite_mask_two_pass(PixmapPtr pxDst, unsigned long dstOffset,
* of the Pitch(stride) parameter, so we use maximun width of mask picture.
* that is to say it is a scanline rendering process */
if (width * height * 4 > DEFAULT_EXA_SCRATCH_BFRSZ) {
- opWidth = width;
- opHeight = DEFAULT_EXA_SCRATCH_BFRSZ / (width * 4);
- } else {
- opWidth = width;
- opHeight = height;
+ opWidth = width;
+ opHeight = DEFAULT_EXA_SCRATCH_BFRSZ / (width * 4);
+ }
+ else {
+ opWidth = width;
+ opHeight = height;
}
while (1) {
- /* Wait until the GP is idle - this will ensure that the scratch buffer
- * isn't occupied */
-
- gp_wait_until_idle();
-
- /* Copy the source to the scratch buffer, and do a src * mask raster
- * operation */
-
- gp_declare_blt(0);
- opPtr = &lx_alpha_ops[(exaScratch.op * 2) + 1];
- gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8);
- gp_set_strides(opWidth * 4, exaScratch.srcPitch);
- gp_set_bpp(lx_get_bpp_from_format(CIMGP_SOURCE_FMT_8_8_8_8));
- gp_set_solid_source(exaScratch.srcColor);
- gp_blend_mask_blt(exaScratch.bufferOffset, 0, opWidth, opHeight,
- maskOffset, exaScratch.srcPitch, opPtr->operation,
- exaScratch.fourBpp);
-
- /* Do a relative operation(refer rendercheck ops.c), and copy the
- * operation result to destination */
-
- gp_declare_blt(CIMGP_BLTFLAGS_HAZARD);
- opPtr = &lx_alpha_ops[exaScratch.op * 2];
- apply = (exaScratch.dstFormat->alphabits == 0) ?
- CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL;
- gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8);
- gp_set_strides(exaGetPixmapPitch(pxDst), opWidth * 4);
- gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
- type = CIMGP_CONVERTED_ALPHA;
- gp_set_alpha_operation(opPtr->operation, type, opPtr->channel,
- apply, 0);
- gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset,
- opWidth, opHeight, 0);
-
- if (width * height * 4 > DEFAULT_EXA_SCRATCH_BFRSZ) {
- /* Finish the rendering */
- if (opoverY + opHeight == opY + height)
- break;
- /* Recalculate the Dest and Mask rendering start point */
- srcPoint.y = srcPoint.y + F(opHeight);
- opoverY = opoverY + opHeight;
- if (opoverY + opHeight > opY + height)
- opHeight = opY + height - opoverY;
- dstOffset = GetPixmapOffset(pxDst, opoverX, opoverY);
- maskOffset = GetSrcOffset(I(srcPoint.x), I(srcPoint.y));
- } else
- break;
+ /* Wait until the GP is idle - this will ensure that the scratch buffer
+ * isn't occupied */
+
+ gp_wait_until_idle();
+
+ /* Copy the source to the scratch buffer, and do a src * mask raster
+ * operation */
+
+ gp_declare_blt(0);
+ opPtr = &lx_alpha_ops[(exaScratch.op * 2) + 1];
+ gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8);
+ gp_set_strides(opWidth * 4, exaScratch.srcPitch);
+ gp_set_bpp(lx_get_bpp_from_format(CIMGP_SOURCE_FMT_8_8_8_8));
+ gp_set_solid_source(exaScratch.srcColor);
+ gp_blend_mask_blt(exaScratch.bufferOffset, 0, opWidth, opHeight,
+ maskOffset, exaScratch.srcPitch, opPtr->operation,
+ exaScratch.fourBpp);
+
+ /* Do a relative operation(refer rendercheck ops.c), and copy the
+ * operation result to destination */
+
+ gp_declare_blt(CIMGP_BLTFLAGS_HAZARD);
+ opPtr = &lx_alpha_ops[exaScratch.op * 2];
+ apply = (exaScratch.dstFormat->alphabits == 0) ?
+ CIMGP_APPLY_BLEND_TO_RGB : CIMGP_APPLY_BLEND_TO_ALL;
+ gp_set_source_format(CIMGP_SOURCE_FMT_8_8_8_8);
+ gp_set_strides(exaGetPixmapPitch(pxDst), opWidth * 4);
+ gp_set_bpp(lx_get_bpp_from_format(exaScratch.dstFormat->fmt));
+ type = CIMGP_CONVERTED_ALPHA;
+ gp_set_alpha_operation(opPtr->operation, type, opPtr->channel,
+ apply, 0);
+ gp_screen_to_screen_convert(dstOffset, exaScratch.bufferOffset,
+ opWidth, opHeight, 0);
+
+ if (width * height * 4 > DEFAULT_EXA_SCRATCH_BFRSZ) {
+ /* Finish the rendering */
+ if (opoverY + opHeight == opY + height)
+ break;
+ /* Recalculate the Dest and Mask rendering start point */
+ srcPoint.y = srcPoint.y + F(opHeight);
+ opoverY = opoverY + opHeight;
+ if (opoverY + opHeight > opY + height)
+ opHeight = opY + height - opoverY;
+ dstOffset = GetPixmapOffset(pxDst, opoverX, opoverY);
+ maskOffset = GetSrcOffset(I(srcPoint.x), I(srcPoint.y));
+ }
+ else
+ break;
}
}
@@ -1189,7 +1210,7 @@ transformPoint(PictTransform * t, xPointFixed * point)
v.vector[2] = xFixed1;
if (t != NULL)
- PictureTransformPoint(t, &v);
+ PictureTransformPoint(t, &v);
point->x = v.vector[0];
point->y = v.vector[1];
@@ -1197,7 +1218,7 @@ transformPoint(PictTransform * t, xPointFixed * point)
static void
lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
- int maskY, int dstX, int dstY, int width, int height)
+ int maskY, int dstX, int dstY, int width, int height)
{
unsigned int dstOffset, srcOffset = 0;
@@ -1211,11 +1232,12 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
/* Transform the source coordinates */
if (exaScratch.type == COMP_TYPE_MASK) {
- srcPoint.x = F(maskX);
- srcPoint.y = F(maskY);
- } else {
- srcPoint.x = F(srcX);
- srcPoint.y = F(srcY);
+ srcPoint.x = F(maskX);
+ srcPoint.y = F(maskY);
+ }
+ else {
+ srcPoint.x = F(srcX);
+ srcPoint.y = F(srcY);
}
/* srcX, srcY point to the upper right side of the bounding box
@@ -1225,26 +1247,26 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
switch (exaScratch.rotate) {
case RR_Rotate_270:
- srcPoint.x += F(width);
+ srcPoint.x += F(width);
- opWidth = height;
- opHeight = width;
- break;
+ opWidth = height;
+ opHeight = width;
+ break;
case RR_Rotate_180:
- srcPoint.x += F(width);
- srcPoint.y += F(height);
+ srcPoint.x += F(width);
+ srcPoint.y += F(height);
- srcX += width;
- srcY += height;
- break;
+ srcX += width;
+ srcY += height;
+ break;
case RR_Rotate_90:
- srcPoint.y += F(height);
+ srcPoint.y += F(height);
- opWidth = height;
- opHeight = width;
- break;
+ opWidth = height;
+ opHeight = width;
+ break;
}
transformPoint(exaScratch.transform, &srcPoint);
@@ -1252,13 +1274,13 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
/* Adjust the point to fit into the pixmap */
if (I(srcPoint.x) < 0) {
- opWidth += I(srcPoint.x);
- srcPoint.x = F(0);
+ opWidth += I(srcPoint.x);
+ srcPoint.x = F(0);
}
if (I(srcPoint.y) < 0) {
- opHeight += I(srcPoint.y);
- srcPoint.y = F(0);
+ opHeight += I(srcPoint.y);
+ srcPoint.y = F(0);
}
/* Get the source point offset position */
@@ -1278,166 +1300,220 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX,
* exaScratch.srcWidth and exaScratch.srcHeight */
if (exaScratch.type == COMP_TYPE_MASK) {
- if ((exaScratch.srcWidth - maskX) < opWidth)
- opWidth = exaScratch.srcWidth - maskX;
- if ((exaScratch.srcHeight - maskY) < opHeight)
- opHeight = exaScratch.srcHeight - maskY;
- } else {
- if (exaScratch.type == COMP_TYPE_ONEPASS) {
- /* This is the condition srcX or/and srcY is/are out of source
- * region */
- if (((srcX >= 0 && srcY >= exaScratch.srcHeight)
- || (srcX >= exaScratch.srcWidth && srcY >= 0)) &&
- (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) {
- if (exaScratch.repeat == 1) {
- opWidth = width;
- opHeight = height;
- } else {
- if (exaScratch.op == PictOpOver)
- return ;
- else {
- exaScratch.op = PictOpClear;
- opWidth = width;
- opHeight = height;
- }
- }
- /* This is the condition srcX or/and srcY is/are in the source
- * region */
- } else if (srcX >= 0 && srcY >= 0 &&
- (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) {
- if (exaScratch.repeat == 1) {
- opWidth = width;
- opHeight = height;
- } else {
- if ((exaScratch.srcWidth - srcX) < opWidth)
- opWidth = exaScratch.srcWidth - srcX;
- if ((exaScratch.srcHeight - srcY) < opHeight)
- opHeight = exaScratch.srcHeight - srcY;
- }
- /* This is the condition srcX or/and srcY is/are negative */
- } else if ((srcX < 0 || srcY < 0) &&
- (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) {
- if (exaScratch.repeat == 1) {
- opWidth = width;
- opHeight = height;
- } else {
- /* Have not met this condition till now */
- return ;
- }
- } else {
- if (exaScratch.srcWidth < opWidth)
- opWidth = exaScratch.srcWidth;
- if (exaScratch.srcHeight < opHeight)
- opHeight = exaScratch.srcHeight;
- }
- } else {
- if (exaScratch.rotate == RR_Rotate_180) {
- } else {
- if ((exaScratch.srcWidth - srcY) < opWidth)
- opWidth = exaScratch.srcWidth - srcY;
- if ((exaScratch.srcHeight - srcX) < opHeight)
- opHeight = exaScratch.srcHeight - srcX;
- }
- }
+ if ((exaScratch.srcWidth - maskX) < opWidth)
+ opWidth = exaScratch.srcWidth - maskX;
+ if ((exaScratch.srcHeight - maskY) < opHeight)
+ opHeight = exaScratch.srcHeight - maskY;
+ }
+ else {
+ if (exaScratch.type == COMP_TYPE_ONEPASS) {
+ /* This is the condition srcX or/and srcY is/are out of source
+ * region */
+ if (((srcY >= 0 && srcY >= exaScratch.srcHeight)
+ || (srcX >= 0 && srcX >= exaScratch.srcWidth)) &&
+ (exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)) {
+ if (exaScratch.repeat == 1) {
+ opWidth = width;
+ opHeight = height;
+ }
+ else {
+ if (exaScratch.op == PictOpOver)
+ return;
+ else {
+ exaScratch.op = PictOpClear;
+ opWidth = width;
+ opHeight = height;
+ }
+ }
+ /* This is the condition srcX or/and srcY is/are in the source
+ * region */
+ }
+ else if (srcX >= 0 && srcY >= 0 &&
+ (exaScratch.op == PictOpOver ||
+ exaScratch.op == PictOpSrc)) {
+ if (exaScratch.repeat == 1) {
+ opWidth = width;
+ opHeight = height;
+ }
+ else {
+ if ((exaScratch.srcWidth - srcX) < opWidth)
+ opWidth = exaScratch.srcWidth - srcX;
+ if ((exaScratch.srcHeight - srcY) < opHeight)
+ opHeight = exaScratch.srcHeight - srcY;
+ }
+ /* This is the condition srcX or/and srcY is/are negative */
+ }
+ else if ((srcX < 0 || srcY < 0) &&
+ (exaScratch.op == PictOpOver ||
+ exaScratch.op == PictOpSrc)) {
+ if (exaScratch.repeat == 1) {
+ opWidth = width;
+ opHeight = height;
+ }
+ else {
+ /* FIXME: We can't support negative srcX/Y for all corner cases in
+ * a sane way without a bit bigger refactoring. So as to avoid
+ * gross misrenderings (e.g missing tray icons) in current real-world
+ * applications, just shift destination appropriately for now and
+ * ignore out of bounds source pixmap zero-vector handling. This is
+ * actually correct for PictOpOver, but PictOpSrc out of bounds regions
+ * should be blacked out, but aren't - without this workaround however
+ * it'd be simply all black instead, which is probably worse till a full
+ * clean solution solves it for all cases. */
+ if (srcX < 0) {
+ opX -= srcX;
+ srcX = 0;
+ }
+
+ if (srcY < 0) {
+ opY -= srcY;
+ srcY = 0;
+ }
+
+ /* EXA has taken care of adjusting srcWidth if it gets cut on the right */
+ width = opWidth = exaScratch.srcWidth;
+ /* EXA has taken care of adjusting srcHeight if it gets cut on the bottom */
+ height = opHeight = exaScratch.srcHeight;
+ }
+ }
+ else {
+ if (exaScratch.srcWidth < opWidth)
+ opWidth = exaScratch.srcWidth;
+ if (exaScratch.srcHeight < opHeight)
+ opHeight = exaScratch.srcHeight;
+ }
+ }
+ else {
+ if (exaScratch.rotate == RR_Rotate_180) {
+ }
+ else {
+ if ((exaScratch.srcWidth - srcY) < opWidth)
+ opWidth = exaScratch.srcWidth - srcY;
+ if ((exaScratch.srcHeight - srcX) < opHeight)
+ opHeight = exaScratch.srcHeight - srcX;
+ }
+ }
}
while (1) {
- dstOffset = GetPixmapOffset(pxDst, opX, opY);
-
- switch (exaScratch.type) {
-
- case COMP_TYPE_MASK:{
- if (exaScratch.op == PictOpOver || exaScratch.op ==
- PictOpOutReverse || exaScratch.op == PictOpInReverse ||
- exaScratch.op == PictOpIn || exaScratch.op == PictOpOut ||
- exaScratch.op == PictOpOverReverse)
- lx_do_composite_mask_two_pass(pxDst, dstOffset,
- srcOffset, opWidth, opHeight, opX, opY, srcPoint);
- else
- lx_do_composite_mask(pxDst, dstOffset, srcOffset,
- opWidth, opHeight);
- }
- break;
-
- case COMP_TYPE_ONEPASS:
- if ((exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)
- && (exaScratch.repeat == 1)) {
- lx_composite_onepass_special(pxDst, opWidth, opHeight, opX, opY,
- srcX, srcY);
- return ;
- } else if ((exaScratch.op == PictOpAdd) && (exaScratch.srcFormat->exa
- == PICT_a8) && (exaScratch.dstFormat->exa == PICT_a8))
- lx_composite_onepass_add_a8(pxDst, dstOffset, srcOffset,
- opWidth, opHeight, opX, opY, srcX, srcY);
- else
- lx_composite_onepass(pxDst, dstOffset, srcOffset, opWidth,
- opHeight);
- break;
-
- case COMP_TYPE_TWOPASS:
- lx_composite_multipass(pxDst, dstOffset, srcOffset, opWidth,
- opHeight);
-
- case COMP_TYPE_ROTATE:
- lx_composite_rotate(pxDst, dstOffset, srcOffset, opWidth,
- opHeight);
- break;
- }
-
- opX += opWidth;
-
- if (opX >= dstX + width) {
- opX = dstX;
- opY += opHeight;
-
- if (opY >= dstY + height)
- break;
- }
-
- /* FIXME: Please add the code to handle the condition when the maskX
- * and maskY coordinate are negative or greater than
- * exaScratch.srcWidth and exaScratch.srcHeight */
-
- if (exaScratch.type == COMP_TYPE_MASK) {
- opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth - maskX)
- ? (exaScratch.srcWidth - maskX) : (dstX + width) - opX;
- opHeight = ((dstY + height) - opY) > (exaScratch.srcHeight - maskY)
- ? (exaScratch.srcHeight - maskY) : (dstY + height) - opY;
- /* All black out of the mask */
- if (!exaScratch.maskrepeat)
- exaScratch.srcColor = 0x0;
- } else {
- if (exaScratch.type == COMP_TYPE_ONEPASS) {
- if (srcX >= 0 && srcY >= 0 && (exaScratch.op == PictOpOver ||
- exaScratch.op == PictOpSrc || exaScratch.op ==
- PictOpClear)) {
- opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth -
- srcX) ? (exaScratch.srcWidth - srcX) : (dstX + width)
- - opX;
- opHeight = ((dstY + height) - opY) >
- (exaScratch.srcHeight - srcY) ?
- (exaScratch.srcHeight - srcY) : (dstY + height) - opY;
- } else {
- opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ?
- exaScratch.srcWidth : (dstX + width) - opX;
- opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ?
- exaScratch.srcHeight : (dstY + height) - opY;
- }
- } else {
- opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth - srcY)
- ? (exaScratch.srcWidth - srcY) : (dstX + width) - opX;
- opHeight = ((dstY + height) - opY) > (exaScratch.srcHeight - srcX
- ) ? (exaScratch.srcHeight - srcX) : (dstY + height) - opY;
- }
- /* All black out of the source */
- if (!exaScratch.repeat && (exaScratch.type == COMP_TYPE_ONEPASS)) {
- lx_composite_all_black(srcOffset, exaScratch.srcWidth,
- exaScratch.srcHeight);
- }
- if (!exaScratch.repeat && (exaScratch.type == COMP_TYPE_ROTATE))
- break;
- }
+ dstOffset = GetPixmapOffset(pxDst, opX, opY);
+
+ switch (exaScratch.type) {
+
+ case COMP_TYPE_MASK:{
+ if (exaScratch.op == PictOpOver || exaScratch.op ==
+ PictOpOutReverse || exaScratch.op == PictOpInReverse ||
+ exaScratch.op == PictOpIn || exaScratch.op == PictOpOut ||
+ exaScratch.op == PictOpOverReverse)
+ lx_do_composite_mask_two_pass(pxDst, dstOffset,
+ srcOffset, opWidth, opHeight, opX,
+ opY, srcPoint);
+ else
+ lx_do_composite_mask(pxDst, dstOffset, srcOffset,
+ opWidth, opHeight);
+ }
+ break;
+
+ case COMP_TYPE_ONEPASS:
+ if ((exaScratch.op == PictOpOver || exaScratch.op == PictOpSrc)
+ && (exaScratch.repeat == 1)) {
+ lx_composite_onepass_special(pxDst, opWidth, opHeight, opX, opY,
+ srcX, srcY);
+ return;
+ }
+ else if ((exaScratch.op == PictOpAdd) && (exaScratch.srcFormat->exa
+ == PICT_a8) &&
+ (exaScratch.dstFormat->exa == PICT_a8))
+ lx_composite_onepass_add_a8(pxDst, dstOffset, srcOffset,
+ opWidth, opHeight, opX, opY, srcX,
+ srcY);
+ else
+ lx_composite_onepass(pxDst, dstOffset, srcOffset, opWidth,
+ opHeight);
+ break;
+
+ case COMP_TYPE_TWOPASS:
+ lx_composite_multipass(pxDst, dstOffset, srcOffset, opWidth,
+ opHeight);
+
+ case COMP_TYPE_ROTATE:
+ lx_composite_rotate(pxDst, dstOffset, srcOffset, opWidth, opHeight);
+ break;
+ }
+
+ opX += opWidth;
+
+ if (opX >= dstX + width) {
+ opX = dstX;
+ opY += opHeight;
+
+ if (opY >= dstY + height)
+ break;
+ }
+
+ /* FIXME: Please add the code to handle the condition when the maskX
+ * and maskY coordinate are negative or greater than
+ * exaScratch.srcWidth and exaScratch.srcHeight */
+
+ if (exaScratch.type == COMP_TYPE_MASK) {
+ opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth - maskX)
+ ? (exaScratch.srcWidth - maskX) : (dstX + width) - opX;
+ opHeight = ((dstY + height) - opY) > (exaScratch.srcHeight - maskY)
+ ? (exaScratch.srcHeight - maskY) : (dstY + height) - opY;
+ /* All black out of the mask */
+ if (!exaScratch.maskrepeat)
+ exaScratch.srcColor = 0x0;
+ }
+ else {
+ if (exaScratch.type == COMP_TYPE_ONEPASS) {
+ if (srcX >= 0 && srcY >= 0 && (exaScratch.op == PictOpOver ||
+ exaScratch.op == PictOpSrc ||
+ exaScratch.op == PictOpClear)) {
+ opWidth =
+ ((dstX + width) - opX) >
+ (exaScratch.srcWidth - srcX) ? (exaScratch.srcWidth -
+ srcX) : (dstX + width)
+ - opX;
+ opHeight = ((dstY + height) - opY) >
+ (exaScratch.srcHeight - srcY) ?
+ (exaScratch.srcHeight - srcY) : (dstY + height) - opY;
+ }
+ else {
+ opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ?
+ exaScratch.srcWidth : (dstX + width) - opX;
+ opHeight = ((dstY + height) - opY) > exaScratch.srcHeight ?
+ exaScratch.srcHeight : (dstY + height) - opY;
+ }
+ }
+ else {
+ opWidth = ((dstX + width) - opX) > (exaScratch.srcWidth - srcY)
+ ? (exaScratch.srcWidth - srcY) : (dstX + width) - opX;
+ opHeight =
+ ((dstY + height) - opY) >
+ (exaScratch.srcHeight - srcX) ? (exaScratch.srcHeight -
+ srcX) : (dstY + height) -
+ opY;
+ }
+ /* All black out of the source */
+ if (!exaScratch.repeat && (exaScratch.type == COMP_TYPE_ONEPASS)) {
+ /* FIXME: We black out the source here, so that any further regions
+ * in the loop get handled as a source that's a zero-vector (as
+ * defined for out-of-bounds from source pixmap for RepeatModeNone),
+ * but this will likely interfere with cases where srcX and/or srcY
+ * is negative - as opposed to e.g width being larger than srcWidth,
+ * which is exercised in rendercheck (always rectangle in top-left
+ * corner).
+ * Additionally it forces the drawing into tiles of srcWidth/srcHeight
+ * for non-repeat modes too, where we don't really need to tile it like
+ * this and could draw the out of bound regions all at once (or at most
+ * in 4 operations without the big loop). */
+ lx_composite_all_black(srcOffset, exaScratch.srcWidth,
+ exaScratch.srcHeight);
+ }
+ if (!exaScratch.repeat && (exaScratch.type == COMP_TYPE_ROTATE))
+ break;
+ }
}
}
@@ -1455,7 +1531,7 @@ lx_done(PixmapPtr ptr)
#if 0
static void
lx_upload_to_screen(PixmapPtr pxDst, int x, int y, int w, int h,
- char *src, int src_pitch)
+ char *src, int src_pitch)
{
GeodeRec *pGeode = GEODEPTR_FROM_PIXMAP(pxDst);
int dst_pitch = exaGetPixmapPitch(pxDst);
@@ -1464,32 +1540,32 @@ lx_upload_to_screen(PixmapPtr pxDst, int x, int y, int w, int h,
char *dst;
int offset = exaGetPixmapOffset(pxDst);
- dst = (char *)(pGeode->FBBase + offset + (y * dst_pitch) + (x * cpp));
+ dst = (char *) (pGeode->FBBase + offset + (y * dst_pitch) + (x * cpp));
int i;
for (i = 0; i < h; i++) {
- memcpy(dst, src, w * cpp);
- dst += dst_pitch;
- src += src_pitch;
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
}
}
#endif
-#if EXA_VERSION_MINOR >= 2
+#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 2)
static Bool
lx_exa_pixmap_is_offscreen(PixmapPtr pPixmap)
{
- ScrnInfoPtr pScrni = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ ScrnInfoPtr pScrni = xf86ScreenToScrn(pPixmap->drawable.pScreen);
GeodeRec *pGeode = GEODEPTR(pScrni);
- void *start = (void *)(pGeode->FBBase);
+ void *start = (void *) (pGeode->FBBase);
void *end =
- (void *)(pGeode->FBBase + pGeode->offscreenStart +
- pGeode->offscreenSize);
+ (void *) (pGeode->FBBase + pGeode->offscreenStart +
+ pGeode->offscreenSize);
- if ((void *)pPixmap->devPrivate.ptr >= start &&
- (void *)pPixmap->devPrivate.ptr < end)
- return TRUE;
+ if ((void *) pPixmap->devPrivate.ptr >= start &&
+ (void *) pPixmap->devPrivate.ptr < end)
+ return TRUE;
return FALSE;
}
@@ -1499,7 +1575,7 @@ lx_exa_pixmap_is_offscreen(PixmapPtr pPixmap)
Bool
LXExaInit(ScreenPtr pScreen)
{
- ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum];
+ ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen);
GeodeRec *pGeode = GEODEPTR(pScrni);
ExaDriverPtr pExa = pGeode->pExa;
@@ -1523,7 +1599,7 @@ LXExaInit(ScreenPtr pScreen)
pExa->DoneComposite = lx_done;
//pExa->UploadToScreen = lx_upload_to_screen;
-#if EXA_VERSION_MINOR >= 2
+#if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 2)
pExa->PixmapIsOffscreen = lx_exa_pixmap_is_offscreen;
#endif