summaryrefslogtreecommitdiff
path: root/uxa/uxa-render.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-03-06 15:49:04 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2010-03-16 10:53:29 +0000
commitd6b7f96fde1add92fd11f5a75869ae6fc688bf77 (patch)
treeb1be185b912e456396850e0bacc4514e13f79785 /uxa/uxa-render.c
parent910fd171a00227025abc8bcc286a740f5bae895b (diff)
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>
Diffstat (limited to 'uxa/uxa-render.c')
-rw-r--r--uxa/uxa-render.c117
1 files changed, 44 insertions, 73 deletions
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index e70a8450..ca46a2a9 100644
--- a/uxa/uxa-render.c
+++ b/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);
+ }
+ ValidateGC(pPicture->pDrawable, pGC);
- (*pGC->ops->CopyArea) (&pPixmap->drawable, pPicture->pDrawable,
- pGC, 0, 0, width, height, 0, 0);
+ (*pGC->ops->CopyArea) (&pPixmap->drawable, pPicture->pDrawable,
+ pGC, 0, 0, width, height, 0, 0);
- FreeScratchGC(pGC);
+ 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);
+ }
FreeScratchPixmapHeader(pPixmap);
return pPicture;