Fill alpha on xrgb images.
Do not try to fixup the alpha in the ff/shaders as this has the side-effect of overriding the alpha value of the border color, causing images to be padded with black rather than transparent. This can generate large and obnoxious visual artefacts. Fixes: Bug 17933 - x8r8g8b8 doesn't sample alpha=0 outside surface bounds http://bugs.freedesktop.org/show_bug.cgi?id=17933 and many related cairo test suite failures. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
910fd171a0
commit
d6b7f96fde
|
|
@ -491,43 +491,23 @@ i830_prepare_composite(int op, PicturePtr source_picture,
|
|||
* is a8, in which case src.G is what's written, and the other
|
||||
* channels are ignored.
|
||||
*/
|
||||
if (PICT_FORMAT_A(source_picture->format) != 0) {
|
||||
ablend |= TB0A_ARG1_SEL_TEXEL0;
|
||||
cblend |=
|
||||
TB0C_ARG1_SEL_TEXEL0 |
|
||||
TB0C_ARG1_REPLICATE_ALPHA;
|
||||
} else {
|
||||
ablend |= TB0A_ARG1_SEL_ONE;
|
||||
cblend |= TB0C_ARG1_SEL_ONE;
|
||||
}
|
||||
ablend |= TB0A_ARG1_SEL_TEXEL0;
|
||||
cblend |= TB0C_ARG1_SEL_TEXEL0 | TB0C_ARG1_REPLICATE_ALPHA;
|
||||
} else {
|
||||
if (PICT_FORMAT_A(source_picture->format) != 0) {
|
||||
ablend |= TB0A_ARG1_SEL_TEXEL0;
|
||||
} else {
|
||||
ablend |= TB0A_ARG1_SEL_ONE;
|
||||
}
|
||||
if (PICT_FORMAT_RGB(source_picture->format) != 0)
|
||||
cblend |= TB0C_ARG1_SEL_TEXEL0;
|
||||
else
|
||||
cblend |= TB0C_ARG1_SEL_ONE | TB0C_ARG1_INVERT; /* 0.0 */
|
||||
ablend |= TB0A_ARG1_SEL_TEXEL0;
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
if (dest_picture->format != PICT_a8 &&
|
||||
(mask_picture->componentAlpha &&
|
||||
PICT_FORMAT_RGB(mask_picture->format))) {
|
||||
cblend |= TB0C_ARG2_SEL_TEXEL1;
|
||||
} else {
|
||||
if (PICT_FORMAT_A(mask_picture->format) != 0)
|
||||
cblend |= TB0C_ARG2_SEL_TEXEL1 |
|
||||
TB0C_ARG2_REPLICATE_ALPHA;
|
||||
else
|
||||
cblend |= TB0C_ARG2_SEL_ONE;
|
||||
}
|
||||
if (PICT_FORMAT_A(mask_picture->format) != 0)
|
||||
ablend |= TB0A_ARG2_SEL_TEXEL1;
|
||||
else
|
||||
ablend |= TB0A_ARG2_SEL_ONE;
|
||||
cblend |= TB0C_ARG2_SEL_TEXEL1;
|
||||
if (dest_picture->format == PICT_a8 ||
|
||||
! mask_picture->componentAlpha ||
|
||||
! PICT_FORMAT_RGB(mask_picture->format))
|
||||
cblend |= TB0C_ARG2_REPLICATE_ALPHA;
|
||||
ablend |= TB0A_ARG2_SEL_TEXEL1;
|
||||
} else {
|
||||
cblend |= TB0C_ARG2_SEL_ONE;
|
||||
ablend |= TB0A_ARG2_SEL_ONE;
|
||||
|
|
|
|||
|
|
@ -237,6 +237,8 @@ i830_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
|
|||
case 32:
|
||||
/* RGB8888 */
|
||||
intel->BR[13] |= ((1 << 24) | (1 << 25));
|
||||
if (pixmap->drawable.depth == 24)
|
||||
fg |= 0xff000000;
|
||||
break;
|
||||
}
|
||||
intel->BR[16] = fg;
|
||||
|
|
@ -710,6 +712,33 @@ static Bool i830_uxa_put_image(PixmapPtr pixmap,
|
|||
GCPtr gc;
|
||||
Bool ret;
|
||||
|
||||
if (pixmap->drawable.depth == 24) {
|
||||
/* fill alpha channel */
|
||||
pixman_image_t *src_image, *dst_image;
|
||||
|
||||
src_image = pixman_image_create_bits (PIXMAN_x8r8g8b8,
|
||||
w, h,
|
||||
(uint32_t *) src, src_pitch);
|
||||
|
||||
dst_image = pixman_image_create_bits (PIXMAN_a8r8g8b8,
|
||||
w, h,
|
||||
(uint32_t *) src, src_pitch);
|
||||
|
||||
if (src_image && dst_image)
|
||||
pixman_image_composite (PictOpSrc,
|
||||
src_image, NULL, dst_image,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
w, h);
|
||||
|
||||
if (src_image)
|
||||
pixman_image_unref (src_image);
|
||||
|
||||
if (dst_image)
|
||||
pixman_image_unref (dst_image);
|
||||
}
|
||||
|
||||
if (x == 0 && y == 0 &&
|
||||
w == pixmap->drawable.width &&
|
||||
h == pixmap->drawable.height)
|
||||
|
|
|
|||
|
|
@ -385,8 +385,9 @@ i915_prepare_composite(int op, PicturePtr source_picture,
|
|||
source_picture->format,
|
||||
PICT_a8r8g8b8,
|
||||
&intel->render_source_solid))
|
||||
return FALSE;
|
||||
} else if (!intel_check_pitch_3d(source))
|
||||
intel->render_source_is_solid = FALSE;
|
||||
}
|
||||
if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
|
||||
return FALSE;
|
||||
|
||||
|
||||
|
|
@ -402,8 +403,9 @@ i915_prepare_composite(int op, PicturePtr source_picture,
|
|||
mask_picture->format,
|
||||
PICT_a8r8g8b8,
|
||||
&intel->render_mask_solid))
|
||||
return FALSE;
|
||||
} else if (!intel_check_pitch_3d(mask))
|
||||
intel->render_mask_is_solid = FALSE;
|
||||
}
|
||||
if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -475,7 +477,6 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
|
|||
{
|
||||
intel_screen_private *intel = intel_get_screen_private(scrn);
|
||||
int op = intel->i915_render_state.op;
|
||||
PicturePtr source_picture = intel->render_source_picture;
|
||||
PicturePtr mask_picture = intel->render_mask_picture;
|
||||
PicturePtr dest_picture = intel->render_dest_picture;
|
||||
PixmapPtr mask = intel->render_mask;
|
||||
|
|
@ -589,7 +590,6 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
|
|||
OUT_BATCH(0x00000000);
|
||||
}
|
||||
|
||||
OUT_BATCH(MI_NOOP);
|
||||
ADVANCE_BATCH();
|
||||
|
||||
{
|
||||
|
|
@ -629,10 +629,6 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
|
|||
i915_fs_texldp(FS_R0, FS_S0, FS_T0);
|
||||
}
|
||||
|
||||
/* If the texture lacks an alpha channel, force the alpha to 1. */
|
||||
if (PICT_FORMAT_A(source_picture->format) == 0)
|
||||
i915_fs_mov_masked(FS_R0, MASK_W, i915_fs_operand_one());
|
||||
|
||||
src_reg = FS_R0;
|
||||
}
|
||||
|
||||
|
|
@ -647,11 +643,6 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
|
|||
} else {
|
||||
i915_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t);
|
||||
}
|
||||
/* If the texture lacks an alpha channel, force the alpha to 1.
|
||||
*/
|
||||
if (PICT_FORMAT_A(mask_picture->format) == 0)
|
||||
i915_fs_mov_masked(FS_R1, MASK_W,
|
||||
i915_fs_operand_one());
|
||||
|
||||
mask_reg = FS_R1;
|
||||
}
|
||||
|
|
|
|||
119
uxa/uxa-render.c
119
uxa/uxa-render.c
|
|
@ -262,13 +262,15 @@ uxa_get_color_for_pixmap (PixmapPtr pixmap,
|
|||
|
||||
*pixel = uxa_get_pixmap_first_pixel(pixmap);
|
||||
|
||||
if (!uxa_get_rgba_from_pixel(*pixel, &red, &green, &blue, &alpha,
|
||||
src_format))
|
||||
if (src_format != dst_format) {
|
||||
if (!uxa_get_rgba_from_pixel(*pixel, &red, &green, &blue, &alpha,
|
||||
src_format))
|
||||
return FALSE;
|
||||
|
||||
if (!uxa_get_pixel_from_rgba(pixel, red, green, blue, alpha,
|
||||
dst_format))
|
||||
if (!uxa_get_pixel_from_rgba(pixel, red, green, blue, alpha,
|
||||
dst_format))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -364,6 +366,10 @@ uxa_picture_for_pixman_format(ScreenPtr pScreen,
|
|||
if (format == PIXMAN_a1)
|
||||
format = PIXMAN_a8;
|
||||
|
||||
/* fill alpha if unset */
|
||||
if (PIXMAN_FORMAT_A(format) == 0)
|
||||
format = PIXMAN_a8r8g8b8;
|
||||
|
||||
pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height,
|
||||
PIXMAN_FORMAT_DEPTH(format),
|
||||
UXA_CREATE_PIXMAP_FOR_MAP);
|
||||
|
|
@ -384,64 +390,6 @@ uxa_picture_for_pixman_format(ScreenPtr pScreen,
|
|||
return pPicture;
|
||||
}
|
||||
|
||||
/* In order to avoid fallbacks when using an a1 source/mask,
|
||||
* for example with non-antialiased trapezoids, we need to
|
||||
* expand the bitmap into an a8 Picture. We do so by using the generic
|
||||
* composition routines, which while may not be perfect is far faster
|
||||
* than causing a fallback.
|
||||
*/
|
||||
static PicturePtr
|
||||
uxa_picture_from_a1_pixman_image(ScreenPtr pScreen, pixman_image_t * image)
|
||||
{
|
||||
PicturePtr pPicture;
|
||||
PicturePtr pSrc;
|
||||
PixmapPtr pPixmap;
|
||||
int width, height;
|
||||
int error;
|
||||
|
||||
width = pixman_image_get_width(image);
|
||||
height = pixman_image_get_height(image);
|
||||
|
||||
pPicture = uxa_picture_for_pixman_format (pScreen, PIXMAN_a1,
|
||||
width, height);
|
||||
if (!pPicture)
|
||||
return 0;
|
||||
|
||||
pPixmap = GetScratchPixmapHeader(pScreen, width, height, 1, 1,
|
||||
pixman_image_get_stride(image),
|
||||
pixman_image_get_data(image));
|
||||
if (!pPixmap) {
|
||||
FreePicture(pPicture, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pSrc = CreatePicture(0, &pPixmap->drawable,
|
||||
PictureMatchFormat(pScreen, 1, PICT_a1),
|
||||
0, 0, serverClient, &error);
|
||||
if (!pSrc) {
|
||||
FreeScratchPixmapHeader(pPixmap);
|
||||
FreePicture(pPicture, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ValidatePicture(pSrc);
|
||||
|
||||
/* force the fallback path */
|
||||
if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
|
||||
fbComposite(PictOpSrc, pSrc, NULL, pPicture,
|
||||
0, 0, 0, 0, 0, 0, width, height);
|
||||
uxa_finish_access(pPicture->pDrawable);
|
||||
} else {
|
||||
FreePicture(pPicture, 0);
|
||||
pPicture = 0;
|
||||
}
|
||||
|
||||
FreePicture(pSrc, 0);
|
||||
FreeScratchPixmapHeader(pPixmap);
|
||||
|
||||
return pPicture;
|
||||
}
|
||||
|
||||
static PicturePtr
|
||||
uxa_picture_from_pixman_image(ScreenPtr pScreen,
|
||||
pixman_image_t * image,
|
||||
|
|
@ -449,12 +397,8 @@ uxa_picture_from_pixman_image(ScreenPtr pScreen,
|
|||
{
|
||||
PicturePtr pPicture;
|
||||
PixmapPtr pPixmap;
|
||||
GCPtr pGC;
|
||||
int width, height;
|
||||
|
||||
if (format == PICT_a1)
|
||||
return uxa_picture_from_a1_pixman_image(pScreen, image);
|
||||
|
||||
width = pixman_image_get_width(image);
|
||||
height = pixman_image_get_height(image);
|
||||
|
||||
|
|
@ -473,18 +417,45 @@ uxa_picture_from_pixman_image(ScreenPtr pScreen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
pGC = GetScratchGC(PIXMAN_FORMAT_DEPTH(format), pScreen);
|
||||
if (!pGC) {
|
||||
if (((pPicture->pDrawable->depth << 24) | pPicture->format) == format) {
|
||||
GCPtr pGC;
|
||||
|
||||
pGC = GetScratchGC(PIXMAN_FORMAT_DEPTH(format), pScreen);
|
||||
if (!pGC) {
|
||||
FreeScratchPixmapHeader(pPixmap);
|
||||
FreePicture(pPicture, 0);
|
||||
return 0;
|
||||
}
|
||||
ValidateGC(pPicture->pDrawable, pGC);
|
||||
|
||||
(*pGC->ops->CopyArea) (&pPixmap->drawable, pPicture->pDrawable,
|
||||
pGC, 0, 0, width, height, 0, 0);
|
||||
|
||||
FreeScratchGC(pGC);
|
||||
} else {
|
||||
PicturePtr pSrc;
|
||||
int error;
|
||||
|
||||
pSrc = CreatePicture(0, &pPixmap->drawable,
|
||||
PictureMatchFormat(pScreen,
|
||||
PIXMAN_FORMAT_DEPTH(format),
|
||||
format),
|
||||
0, 0, serverClient, &error);
|
||||
if (!pSrc) {
|
||||
FreeScratchPixmapHeader(pPixmap);
|
||||
FreePicture(pPicture, 0);
|
||||
return 0;
|
||||
}
|
||||
ValidatePicture(pSrc);
|
||||
|
||||
if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
|
||||
fbComposite(PictOpSrc, pSrc, NULL, pPicture,
|
||||
0, 0, 0, 0, 0, 0, width, height);
|
||||
uxa_finish_access(pPicture->pDrawable);
|
||||
}
|
||||
|
||||
FreePicture(pSrc, 0);
|
||||
}
|
||||
ValidateGC(pPicture->pDrawable, pGC);
|
||||
|
||||
(*pGC->ops->CopyArea) (&pPixmap->drawable, pPicture->pDrawable,
|
||||
pGC, 0, 0, width, height, 0, 0);
|
||||
|
||||
FreeScratchGC(pGC);
|
||||
FreeScratchPixmapHeader(pPixmap);
|
||||
|
||||
return pPicture;
|
||||
|
|
|
|||
Loading…
Reference in New Issue