*Fix the PictOpOver blend_ops struct. The PictOpOver operation is Src + (1-a) * Dest. So change from CIMGP_ALPHA_A_PLUS_BETA_B to CIMGP_A_PLUS_BETA_B. And add one pass operation to do the Src * (alpha of Mask) if there is a mask *Convert the source format in lx_prepare_composite if it is not ARGB32 when doing the first pass *Add a function lx_do_composite_mask_opover to handle the PictOpOver operation, the first pass is to do the Src * (alpha of Mask), the second pass is to do the Src + (1-a) * Dest. *Progressbar, scrollbar and button display well with this patch *Still firefox has rendering wrong with this patch *See Free Desktop Bugzilla #28352
Signed-off-by: Frank Huang <[email protected]> --- src/lx_exa.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/lx_exa.c b/src/lx_exa.c index 5bec11d..64c8b40 100644 --- a/src/lx_exa.c +++ b/src/lx_exa.c @@ -409,13 +409,12 @@ struct blend_ops_t }, /* PictOpOver */ { - CIMGP_ALPHA_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_SOURCE}, - { - }, + 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 */ { - CIMGP_ALPHA_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST}, { - }, + CIMGP_A_PLUS_BETA_B, CIMGP_CHANNEL_A_ALPHA, CIMGP_CHANNEL_A_DEST}, { + CIMGP_ALPHA_TIMES_A, CIMGP_CONVERTED_ALPHA, CIMGP_CHANNEL_A_DEST}, /* PictOpIn */ { CIMGP_ALPHA_TIMES_A, CIMGP_CHANNEL_B_ALPHA, CIMGP_CHANNEL_A_SOURCE}, { @@ -674,13 +673,22 @@ lx_prepare_composite(int op, PicturePtr pSrc, PicturePtr pMsk, int direction = (opPtr->channel == CIMGP_CHANNEL_A_SOURCE) ? 0 : 1; /* Get the source color */ + /* If the op is PictOpOver, we should get the ARGB32 source format */ - if (direction == 0) + if (op == PictOpOver && (srcFmt->alphabits != 0)) + exaScratch.srcColor = exaGetPixmapFirstPixel(pxSrc); + else if (op == PictOpOver && (srcFmt->alphabits == 0)) exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format, - pDst->format); - else - exaScratch.srcColor = lx_get_source_color(pxDst, pDst->format, - pSrc->format); + PICT_a8r8g8b8); + else { + if (direction == 0) + exaScratch.srcColor = lx_get_source_color(pxSrc, pSrc->format, + pDst->format); + else + exaScratch.srcColor = lx_get_source_color(pxDst, pDst->format, + pSrc->format); + } + /* Save off the info we need (reuse the source values to save space) */ @@ -925,6 +933,46 @@ lx_do_composite_mask(PixmapPtr pxDst, unsigned long dstOffset, exaScratch.srcPitch, opPtr->operation, exaScratch.fourBpp); } +static void +lx_do_composite_mask_opover(PixmapPtr pxDst, unsigned long dstOffset, + unsigned int maskOffset, int width, int height) +{ + int apply, type; + struct blend_ops_t *opPtr; + + /* 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(exaScratch.srcPitch * 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, width, height, maskOffset, + exaScratch.srcPitch, opPtr->operation, exaScratch.fourBpp); + + /* Do a PictOpOver operation(src + (1-a) * dst), 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), exaScratch.srcPitch * 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, width, + height, 0); +} + #define GetPixmapOffset(px, x, y) ( exaGetPixmapOffset((px)) + \ (exaGetPixmapPitch((px)) * (y)) + \ ((((px)->drawable.bitsPerPixel + 7) / 8) * (x)) ) @@ -1056,11 +1104,19 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, if (direction == 1) { dstOffset = GetPixmapOffset(exaScratch.srcPixmap, opX, opY); - lx_do_composite_mask(exaScratch.srcPixmap, dstOffset, - srcOffset, opWidth, opHeight); + if (exaScratch.op == PictOpOver) + lx_do_composite_mask_opover(exaScratch.srcPixmap, + dstOffset, srcOffset, opWidth, opHeight); + else + lx_do_composite_mask(exaScratch.srcPixmap, dstOffset, + srcOffset, opWidth, opHeight); } else { - lx_do_composite_mask(pxDst, dstOffset, srcOffset, opWidth, - opHeight); + if (exaScratch.op == PictOpOver) + lx_do_composite_mask_opover(pxDst, dstOffset, + srcOffset, opWidth, opHeight); + else + lx_do_composite_mask(pxDst, dstOffset, srcOffset, + opWidth, opHeight); } } break; @@ -1102,6 +1158,9 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, exaScratch.type = COMP_TYPE_ONEPASS; exaScratch.op = PictOpClear; } + if (exaScratch.repeat && (!exaScratch.maskrepeat) && + (exaScratch.op == PictOpOver)) + break; } else { opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ? exaScratch.srcWidth : (dstX + width) - opX; @@ -1111,6 +1170,9 @@ lx_do_composite(PixmapPtr pxDst, int srcX, int srcY, int maskX, exaScratch.type = COMP_TYPE_ONEPASS; exaScratch.op = PictOpClear; } + if ((!exaScratch.repeat) && (exaScratch.op == PictOpOver)) + break; + } } } -- 1.7.1 _______________________________________________ Xorg-driver-geode mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-driver-geode
