diff options
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/g4x_render.c | 3 | ||||
-rw-r--r-- | src/sna/gen2_render.c | 10 | ||||
-rw-r--r-- | src/sna/gen3_render.c | 3 | ||||
-rw-r--r-- | src/sna/gen4_render.c | 3 | ||||
-rw-r--r-- | src/sna/gen5_render.c | 3 | ||||
-rw-r--r-- | src/sna/gen6_render.c | 3 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 3 | ||||
-rw-r--r-- | src/sna/sna_render.c | 145 | ||||
-rw-r--r-- | src/sna/sna_render.h | 3 |
9 files changed, 123 insertions, 53 deletions
diff --git a/src/sna/g4x_render.c b/src/sna/g4x_render.c index 9de8340a..f92a33a7 100644 --- a/src/sna/g4x_render.c +++ b/src/sna/g4x_render.c @@ -1927,7 +1927,8 @@ g4x_composite_picture(struct sna *sna, channel->card_format = g4x_get_card_format(picture->format); if (channel->card_format == -1) return sna_render_picture_convert(sna, picture, channel, pixmap, - x, y, w, h, dst_x, dst_y); + x, y, w, h, dst_x, dst_y, + false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) return sna_render_picture_extract(sna, picture, channel, diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c index 9663dff5..31074af0 100644 --- a/src/sna/gen2_render.c +++ b/src/sna/gen2_render.c @@ -1304,7 +1304,8 @@ static bool gen2_check_card_format(struct sna *sna, PicturePtr picture, struct sna_composite_channel *channel, - int x, int y, int w, int h) + int x, int y, int w, int h, + bool *fixup_alpha) { uint32_t format = picture->format; unsigned int i; @@ -1324,10 +1325,12 @@ gen2_check_card_format(struct sna *sna, return true; } + *fixup_alpha = true; return false; } } + *fixup_alpha = false; return false; } @@ -1343,6 +1346,7 @@ gen2_composite_picture(struct sna *sna, PixmapPtr pixmap; uint32_t color; int16_t dx, dy; + bool fixup_alpha; DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n", __FUNCTION__, x, y, w, h, dst_x, dst_y)); @@ -1417,9 +1421,9 @@ gen2_composite_picture(struct sna *sna, } else channel->transform = picture->transform; - if (!gen2_check_card_format(sna, picture, channel, x, y, w ,h)) + if (!gen2_check_card_format(sna, picture, channel, x, y, w ,h, &fixup_alpha)) return sna_render_picture_convert(sna, picture, channel, pixmap, - x, y, w, h, dst_x, dst_y); + x, y, w, h, dst_x, dst_y, fixup_alpha); channel->pict_format = picture->format; if (too_large(pixmap->drawable.width, pixmap->drawable.height)) diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c index f0f0a487..9dcdfcdb 100644 --- a/src/sna/gen3_render.c +++ b/src/sna/gen3_render.c @@ -2402,7 +2402,8 @@ gen3_composite_picture(struct sna *sna, if (!gen3_composite_channel_set_format(channel, picture->format) && !gen3_composite_channel_set_xformat(picture, channel, x, y, w, h)) return sna_render_picture_convert(sna, picture, channel, pixmap, - x, y, w, h, dst_x, dst_y); + x, y, w, h, dst_x, dst_y, + false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: pixmap too large (%dx%d), extracting (%d, %d)x(%d,%d)\n", diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 057192d8..5134bb92 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -1918,7 +1918,8 @@ gen4_composite_picture(struct sna *sna, channel->card_format = gen4_get_card_format(picture->format); if (channel->card_format == -1) return sna_render_picture_convert(sna, picture, channel, pixmap, - x, y, w, h, dst_x, dst_y); + x, y, w, h, dst_x, dst_y, + false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) return sna_render_picture_extract(sna, picture, channel, diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index b49b25ea..31f6f216 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -1936,7 +1936,8 @@ gen5_composite_picture(struct sna *sna, channel->card_format = gen5_get_card_format(picture->format); if (channel->card_format == -1) return sna_render_picture_convert(sna, picture, channel, pixmap, - x, y, w, h, dst_x, dst_y); + x, y, w, h, dst_x, dst_y, + false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) return sna_render_picture_extract(sna, picture, channel, diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index fbe0951d..6cc1a7db 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -2274,7 +2274,8 @@ gen6_composite_picture(struct sna *sna, channel->card_format = gen6_get_card_format(picture->format); if (channel->card_format == (unsigned)-1) return sna_render_picture_convert(sna, picture, channel, pixmap, - x, y, w, h, dst_x, dst_y); + x, y, w, h, dst_x, dst_y, + false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__, diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index 3bec5df8..a106a185 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -2386,7 +2386,8 @@ gen7_composite_picture(struct sna *sna, channel->card_format = gen7_get_card_format(picture->format); if (channel->card_format == (unsigned)-1) return sna_render_picture_convert(sna, picture, channel, pixmap, - x, y, w, h, dst_x, dst_y); + x, y, w, h, dst_x, dst_y, + false); if (too_large(pixmap->drawable.width, pixmap->drawable.height)) { DBG(("%s: extracting from pixmap %dx%d\n", __FUNCTION__, diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index c534f612..0a2856e3 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -1637,11 +1637,10 @@ sna_render_picture_convert(struct sna *sna, PixmapPtr pixmap, int16_t x, int16_t y, int16_t w, int16_t h, - int16_t dst_x, int16_t dst_y) + int16_t dst_x, int16_t dst_y, + bool fixup_alpha) { - pixman_image_t *src, *dst; BoxRec box; - void *ptr; #if NO_CONVERT return -1; @@ -1691,52 +1690,113 @@ sna_render_picture_convert(struct sna *sna, return 0; } - if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) - return 0; + if (fixup_alpha && is_gpu(&pixmap->drawable)) { + ScreenPtr screen = pixmap->drawable.pScreen; + PixmapPtr tmp; + PicturePtr src, dst; + int error; - src = pixman_image_create_bits(picture->format, - pixmap->drawable.width, - pixmap->drawable.height, - pixmap->devPrivate.ptr, - pixmap->devKind); - if (!src) - return 0; + assert(PICT_FORMAT_BPP(picture->format) == pixmap->drawable.bitsPerPixel); + channel->pict_format = PICT_FORMAT(PICT_FORMAT_BPP(picture->format), + PICT_FORMAT_TYPE(picture->format), + PICT_FORMAT_BPP(picture->format) - PIXMAN_FORMAT_DEPTH(picture->format), + PICT_FORMAT_R(picture->format), + PICT_FORMAT_G(picture->format), + PICT_FORMAT_B(picture->format)); - if (PICT_FORMAT_RGB(picture->format) == 0) { - channel->pict_format = PIXMAN_a8; - DBG(("%s: converting to a8 from %08x\n", + DBG(("%s: converting to %08x from %08x using composite alpha-fixup\n", __FUNCTION__, picture->format)); + + tmp = screen->CreatePixmap(screen, w, h, pixmap->drawable.bitsPerPixel, 0); + if (tmp == NULL) + return 0; + + dst = CreatePicture(0, &tmp->drawable, + PictureMatchFormat(screen, + pixmap->drawable.bitsPerPixel, + channel->pict_format), + 0, NULL, serverClient, &error); + if (dst == NULL) { + screen->DestroyPixmap(tmp); + return 0; + } + + src = CreatePicture(0, &pixmap->drawable, + PictureMatchFormat(screen, + pixmap->drawable.depth, + picture->format), + 0, NULL, serverClient, &error); + if (dst == NULL) { + FreePicture(dst, 0); + screen->DestroyPixmap(tmp); + return 0; + } + + ValidatePicture(src); + ValidatePicture(dst); + + sna_composite(PictOpSrc, src, NULL, dst, + box.x1, box.y1, + 0, 0, + 0, 0, + w, h); + FreePicture(dst, 0); + FreePicture(src, 0); + + channel->bo = sna_pixmap_get_bo(tmp); + kgem_bo_reference(channel->bo); + screen->DestroyPixmap(tmp); } else { - channel->pict_format = PIXMAN_a8r8g8b8; - DBG(("%s: converting to a8r8g8b8 from %08x\n", - __FUNCTION__, picture->format)); - } + pixman_image_t *src, *dst; + void *ptr; - channel->bo = kgem_create_buffer_2d(&sna->kgem, - w, h, PIXMAN_FORMAT_BPP(channel->pict_format), - KGEM_BUFFER_WRITE_INPLACE, - &ptr); - if (!channel->bo) { - pixman_image_unref(src); - return 0; - } + if (!sna_pixmap_move_to_cpu(pixmap, MOVE_READ)) + return 0; - dst = pixman_image_create_bits(channel->pict_format, - w, h, ptr, channel->bo->pitch); - if (!dst) { - kgem_bo_destroy(&sna->kgem, channel->bo); + src = pixman_image_create_bits(picture->format, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->devPrivate.ptr, + pixmap->devKind); + if (!src) + return 0; + + if (PICT_FORMAT_RGB(picture->format) == 0) { + channel->pict_format = PIXMAN_a8; + DBG(("%s: converting to a8 from %08x\n", + __FUNCTION__, picture->format)); + } else { + channel->pict_format = PIXMAN_a8r8g8b8; + DBG(("%s: converting to a8r8g8b8 from %08x\n", + __FUNCTION__, picture->format)); + } + + channel->bo = kgem_create_buffer_2d(&sna->kgem, + w, h, PIXMAN_FORMAT_BPP(channel->pict_format), + KGEM_BUFFER_WRITE_INPLACE, + &ptr); + if (!channel->bo) { + pixman_image_unref(src); + return 0; + } + + dst = pixman_image_create_bits(channel->pict_format, + w, h, ptr, channel->bo->pitch); + if (!dst) { + kgem_bo_destroy(&sna->kgem, channel->bo); + pixman_image_unref(src); + return 0; + } + + pixman_image_composite(PictOpSrc, src, NULL, dst, + box.x1, box.y1, + 0, 0, + 0, 0, + w, h); + pixman_image_unref(dst); pixman_image_unref(src); - return 0; } - pixman_image_composite(PictOpSrc, src, NULL, dst, - box.x1, box.y1, - 0, 0, - 0, 0, - w, h); - pixman_image_unref(dst); - pixman_image_unref(src); - channel->width = w; channel->height = h; @@ -1745,11 +1805,10 @@ sna_render_picture_convert(struct sna *sna, channel->offset[0] = x - dst_x - box.x1; channel->offset[1] = y - dst_y - box.y1; - DBG(("%s: offset=(%d, %d), size=(%d, %d) ptr[0]=%08x\n", + DBG(("%s: offset=(%d, %d), size=(%d, %d)\n", __FUNCTION__, channel->offset[0], channel->offset[1], - channel->width, channel->height, - *(uint32_t*)ptr)); + channel->width, channel->height)); return 1; } diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index 97b92226..e9ec2ba0 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -691,7 +691,8 @@ sna_render_picture_convert(struct sna *sna, PixmapPtr pixmap, int16_t x, int16_t y, int16_t w, int16_t h, - int16_t dst_x, int16_t dst_y); + int16_t dst_x, int16_t dst_y, + bool fixup_alpha); inline static void sna_render_composite_redirect_init(struct sna_composite_op *op) { |