From: Frank Huang <[email protected]> *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 are displayed well *FreeDesktop Bugzilla #28352
Signed-off-by: Frank Huang <[email protected]> --- src/lx_exa.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/lx_exa.c b/src/lx_exa.c index 223569f..db73088 100644 --- a/src/lx_exa.c +++ b/src/lx_exa.c @@ -669,13 +669,21 @@ 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) */ @@ -920,6 +928,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)) ) @@ -1051,11 +1099,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, + 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; @@ -1097,6 +1153,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 == PictOpSrc)) + break; } else { opWidth = ((dstX + width) - opX) > exaScratch.srcWidth ? exaScratch.srcWidth : (dstX + width) - opX; @@ -1106,6 +1165,8 @@ 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
