2 * Copyright © 2001 Keith Packard
4 * Partly based on code that is Copyright © The XFree86 Project Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty.
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
25 #ifdef HAVE_DIX_CONFIG_H
26 #include <dix-config.h>
32 #include <xorgVersion.h>
37 static void uxa_composite_fallback_pict_desc(PicturePtr pict, char *string,
45 snprintf(string, n, "None");
49 if (pict->pDrawable == NULL) {
50 snprintf(string, n, "source-only");
54 switch (pict->format) {
56 snprintf(format, 20, "ARGB8888");
59 snprintf(format, 20, "XRGB8888");
62 snprintf(format, 20, "RGB565 ");
65 snprintf(format, 20, "RGB555 ");
68 snprintf(format, 20, "A8 ");
71 snprintf(format, 20, "A1 ");
74 snprintf(format, 20, "0x%x", (int)pict->format);
78 loc = uxa_drawable_is_offscreen(pict->pDrawable) ? 's' : 'm';
80 snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
81 pict->pDrawable->height, pict->repeat ? " R" : "");
83 snprintf(string, n, "%p:%c fmt %s (%s)%s",
84 pict->pDrawable, loc, format, size,
85 pict->alphaMap ? " with alpha map" :"");
89 op_to_string(CARD8 op)
92 #define C(x) case PictOp##x: return #x
109 * Operators only available in version 0.2
111 #if RENDER_MAJOR >= 1 || RENDER_MINOR >= 2
116 C(DisjointOverReverse);
118 C(DisjointInReverse);
120 C(DisjointOutReverse);
122 C(DisjointAtopReverse);
129 C(ConjointOverReverse);
131 C(ConjointInReverse);
133 C(ConjointOutReverse);
135 C(ConjointAtopReverse);
140 * Operators only available in version 0.11
142 #if RENDER_MAJOR >= 1 || RENDER_MINOR >= 11
159 default: return "garbage";
165 uxa_print_composite_fallback(const char *func, CARD8 op,
166 PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
168 uxa_screen_t *uxa_screen = uxa_get_screen(pDst->pDrawable->pScreen);
169 char srcdesc[40], maskdesc[40], dstdesc[40];
171 if (! uxa_screen->fallback_debug)
174 /* Limit the noise if fallbacks are expected. */
175 if (uxa_screen->force_fallback)
178 uxa_composite_fallback_pict_desc(pSrc, srcdesc, 40);
179 uxa_composite_fallback_pict_desc(pMask, maskdesc, 40);
180 uxa_composite_fallback_pict_desc(pDst, dstdesc, 40);
182 ErrorF("Composite fallback at %s:\n"
188 func, op_to_string (op), srcdesc, maskdesc, dstdesc,
189 uxa_screen->swappedOut ? "swapped out" : "normal");
192 Bool uxa_op_reads_destination(CARD8 op)
194 /* FALSE (does not read destination) is the list of ops in the protocol
195 * document with "0" in the "Fb" column and no "Ab" in the "Fa" column.
196 * That's just Clear and Src. ReduceCompositeOp() will already have
197 * converted con/disjoint clear/src to Clear or Src.
209 uxa_get_pixel_from_rgba(CARD32 * pixel,
216 int rbits, bbits, gbits, abits;
217 int rshift, bshift, gshift, ashift;
219 rbits = PICT_FORMAT_R(format);
220 gbits = PICT_FORMAT_G(format);
221 bbits = PICT_FORMAT_B(format);
222 abits = PICT_FORMAT_A(format);
224 abits = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits);
226 if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
227 *pixel = alpha >> (16 - abits);
231 if (!PICT_FORMAT_COLOR(format))
234 if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
237 rshift = gshift + gbits;
238 ashift = rshift + rbits;
239 } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
242 bshift = gshift + gbits;
243 ashift = bshift + bbits;
244 #if XORG_VERSION_CURRENT >= 10699900
245 } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
248 gshift = rshift + rbits;
249 bshift = gshift + gbits;
256 *pixel |= (blue >> (16 - bbits)) << bshift;
257 *pixel |= (green >> (16 - gbits)) << gshift;
258 *pixel |= (red >> (16 - rbits)) << rshift;
259 *pixel |= (alpha >> (16 - abits)) << ashift;
265 uxa_get_rgba_from_pixel(CARD32 pixel,
272 int rbits, bbits, gbits, abits;
273 int rshift, bshift, gshift, ashift;
275 rbits = PICT_FORMAT_R(format);
276 gbits = PICT_FORMAT_G(format);
277 bbits = PICT_FORMAT_B(format);
278 abits = PICT_FORMAT_A(format);
280 if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
281 rshift = gshift = bshift = ashift = 0;
282 } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
285 rshift = gshift + gbits;
286 ashift = rshift + rbits;
287 } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
290 bshift = gshift + gbits;
291 ashift = bshift + bbits;
292 #if XORG_VERSION_CURRENT >= 10699900
293 } else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
297 rshift = PICT_FORMAT_BPP(format) - (rbits+gbits+bbits);
298 gshift = rshift + rbits;
299 bshift = gshift + gbits;
306 *red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits);
308 *red |= *red >> rbits;
315 *green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits);
317 *green |= *green >> gbits;
324 *blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits);
326 *blue |= *blue >> bbits;
334 ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits);
336 *alpha |= *alpha >> abits;
346 uxa_get_color_for_pixmap (PixmapPtr pixmap,
351 CARD16 red, green, blue, alpha;
353 *pixel = uxa_get_pixmap_first_pixel(pixmap);
355 if (src_format != dst_format) {
356 if (!uxa_get_rgba_from_pixel(*pixel,
357 &red, &green, &blue, &alpha,
361 if (!uxa_get_pixel_from_rgba(pixel,
362 red, green, blue, alpha,
371 uxa_try_driver_solid_fill(PicturePtr pSrc,
375 INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
377 uxa_screen_t *uxa_screen = uxa_get_screen(pDst->pDrawable->pScreen);
381 int dst_off_x, dst_off_y;
382 PixmapPtr pSrcPix = NULL, pDstPix;
385 if (uxa_screen->info->check_solid && !uxa_screen->info->check_solid(pDst->pDrawable, GXcopy, FB_ALLONES))
388 pDstPix = uxa_get_offscreen_pixmap(pDst->pDrawable, &dst_off_x, &dst_off_y);
392 xDst += pDst->pDrawable->x;
393 yDst += pDst->pDrawable->y;
395 if (pSrc->pDrawable) {
396 pSrcPix = uxa_get_drawable_pixmap(pSrc->pDrawable);
397 xSrc += pSrc->pDrawable->x;
398 ySrc += pSrc->pDrawable->y;
401 if (!miComputeCompositeRegion(®ion, pSrc, NULL, pDst,
402 xSrc, ySrc, 0, 0, xDst, yDst,
407 if (! uxa_get_color_for_pixmap (pSrcPix, pSrc->format, pDst->format, &pixel)) {
408 REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
412 SourcePict *source = pSrc->pSourcePict;
413 PictSolidFill *solid = &source->solidFill;
415 if (source == NULL || source->type != SourcePictTypeSolidFill) {
416 REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
420 if (pDst->format == PICT_a8r8g8b8) {
421 pixel = solid->color;
422 } else if (pDst->format == PICT_x8r8g8b8) {
423 pixel = solid->color | 0xff000000;
425 CARD16 red, green, blue, alpha;
427 if (!uxa_get_rgba_from_pixel(solid->color,
428 &red, &green, &blue, &alpha,
430 !uxa_get_pixel_from_rgba(&pixel,
431 red, green, blue, alpha,
433 REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
439 if (!(*uxa_screen->info->prepare_solid)
440 (pDstPix, GXcopy, FB_ALLONES, pixel)) {
441 REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
445 REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y);
447 nbox = REGION_NUM_RECTS(®ion);
448 pbox = REGION_RECTS(®ion);
451 (*uxa_screen->info->solid) (pDstPix, pbox->x1, pbox->y1,
456 (*uxa_screen->info->done_solid) (pDstPix);
458 REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
463 uxa_picture_for_pixman_format(ScreenPtr screen,
464 pixman_format_code_t format,
465 int width, int height)
471 if (format == PIXMAN_a1)
474 /* fill alpha if unset */
475 if (PIXMAN_FORMAT_A(format) == 0)
476 format = PIXMAN_a8r8g8b8;
478 pixmap = screen->CreatePixmap(screen, width, height,
479 PIXMAN_FORMAT_DEPTH(format),
480 UXA_CREATE_PIXMAP_FOR_MAP);
484 if (!uxa_pixmap_is_offscreen(pixmap)) {
485 screen->DestroyPixmap(pixmap);
489 picture = CreatePicture(0, &pixmap->drawable,
490 PictureMatchFormat(screen,
491 PIXMAN_FORMAT_DEPTH(format),
493 0, 0, serverClient, &error);
494 screen->DestroyPixmap(pixmap);
498 ValidatePicture(picture);
504 uxa_picture_from_pixman_image(ScreenPtr screen,
505 pixman_image_t * image,
506 pixman_format_code_t format)
508 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
513 width = pixman_image_get_width(image);
514 height = pixman_image_get_height(image);
516 picture = uxa_picture_for_pixman_format(screen, format,
521 if (uxa_screen->info->put_image &&
522 ((picture->pDrawable->depth << 24) | picture->format) == format &&
523 uxa_screen->info->put_image((PixmapPtr)picture->pDrawable,
526 (char *)pixman_image_get_data(image),
527 pixman_image_get_stride(image)))
530 pixmap = GetScratchPixmapHeader(screen, width, height,
531 PIXMAN_FORMAT_DEPTH(format),
532 PIXMAN_FORMAT_BPP(format),
533 pixman_image_get_stride(image),
534 pixman_image_get_data(image));
536 FreePicture(picture, 0);
540 if (((picture->pDrawable->depth << 24) | picture->format) == format) {
543 gc = GetScratchGC(PIXMAN_FORMAT_DEPTH(format), screen);
545 FreeScratchPixmapHeader(pixmap);
546 FreePicture(picture, 0);
549 ValidateGC(picture->pDrawable, gc);
551 (*gc->ops->CopyArea) (&pixmap->drawable, picture->pDrawable,
552 gc, 0, 0, width, height, 0, 0);
559 src = CreatePicture(0, &pixmap->drawable,
560 PictureMatchFormat(screen,
561 PIXMAN_FORMAT_DEPTH(format),
563 0, 0, serverClient, &error);
565 FreeScratchPixmapHeader(pixmap);
566 FreePicture(picture, 0);
569 ValidatePicture(src);
571 if (uxa_prepare_access(picture->pDrawable, UXA_ACCESS_RW)) {
572 fbComposite(PictOpSrc, src, NULL, picture,
573 0, 0, 0, 0, 0, 0, width, height);
574 uxa_finish_access(picture->pDrawable);
579 FreeScratchPixmapHeader(pixmap);
585 uxa_create_solid(ScreenPtr screen, uint32_t color)
589 XID repeat = RepeatNormal;
592 pixmap = (*screen->CreatePixmap)(screen, 1, 1, 32,
593 UXA_CREATE_PIXMAP_FOR_MAP);
597 if (!uxa_prepare_access((DrawablePtr)pixmap, UXA_ACCESS_RW)) {
598 (*screen->DestroyPixmap)(pixmap);
601 *((uint32_t *)pixmap->devPrivate.ptr) = color;
602 uxa_finish_access((DrawablePtr)pixmap);
604 picture = CreatePicture(0, &pixmap->drawable,
605 PictureMatchFormat(screen, 32, PICT_a8r8g8b8),
606 CPRepeat, &repeat, serverClient, &error);
607 (*screen->DestroyPixmap)(pixmap);
613 uxa_solid_clear(ScreenPtr screen)
615 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
618 if (!uxa_screen->solid_clear) {
619 uxa_screen->solid_clear = uxa_create_solid(screen, 0);
620 if (!uxa_screen->solid_clear)
623 picture = uxa_screen->solid_clear;
628 uxa_acquire_solid(ScreenPtr screen, SourcePict *source)
630 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
631 PictSolidFill *solid = &source->solidFill;
635 if ((solid->color >> 24) == 0) {
636 picture = uxa_solid_clear(screen);
641 } else if (solid->color == 0xff000000) {
642 if (!uxa_screen->solid_black) {
643 uxa_screen->solid_black = uxa_create_solid(screen, 0xff000000);
644 if (!uxa_screen->solid_black)
647 picture = uxa_screen->solid_black;
649 } else if (solid->color == 0xffffffff) {
650 if (!uxa_screen->solid_white) {
651 uxa_screen->solid_white = uxa_create_solid(screen, 0xffffffff);
652 if (!uxa_screen->solid_white)
655 picture = uxa_screen->solid_white;
659 for (i = 0; i < uxa_screen->solid_cache_size; i++) {
660 if (uxa_screen->solid_cache[i].color == solid->color) {
661 picture = uxa_screen->solid_cache[i].picture;
666 picture = uxa_create_solid(screen, solid->color);
670 if (uxa_screen->solid_cache_size == UXA_NUM_SOLID_CACHE) {
671 i = rand() % UXA_NUM_SOLID_CACHE;
672 FreePicture(uxa_screen->solid_cache[i].picture, 0);
674 uxa_screen->solid_cache_size++;
676 uxa_screen->solid_cache[i].picture = picture;
677 uxa_screen->solid_cache[i].color = solid->color;
685 uxa_acquire_pattern(ScreenPtr pScreen,
687 pixman_format_code_t format,
688 INT16 x, INT16 y, CARD16 width, CARD16 height)
692 if (pSrc->pSourcePict) {
693 SourcePict *source = pSrc->pSourcePict;
694 if (source->type == SourcePictTypeSolidFill)
695 return uxa_acquire_solid (pScreen, source);
698 pDst = uxa_picture_for_pixman_format(pScreen, format, width, height);
702 if (uxa_prepare_access(pDst->pDrawable, UXA_ACCESS_RW)) {
703 fbComposite(PictOpSrc, pSrc, NULL, pDst,
704 x, y, 0, 0, 0, 0, width, height);
705 uxa_finish_access(pDst->pDrawable);
708 FreePicture(pDst, 0);
714 transform_is_integer_translation(PictTransformPtr t, int *tx, int *ty)
721 if (t->matrix[0][0] != IntToxFixed(1) ||
722 t->matrix[0][1] != 0 ||
723 t->matrix[1][0] != 0 ||
724 t->matrix[1][1] != IntToxFixed(1) ||
725 t->matrix[2][0] != 0 ||
726 t->matrix[2][1] != 0 ||
727 t->matrix[2][2] != IntToxFixed(1))
730 if (xFixedFrac(t->matrix[0][2]) != 0 ||
731 xFixedFrac(t->matrix[1][2]) != 0)
734 *tx = xFixedToInt(t->matrix[0][2]);
735 *ty = xFixedToInt(t->matrix[1][2]);
740 uxa_render_picture(ScreenPtr screen,
742 pixman_format_code_t format,
744 CARD16 width, CARD16 height)
749 /* XXX we need a mechanism for the card to choose the fallback format */
751 /* force alpha channel in case source does not entirely cover the extents */
752 if (PIXMAN_FORMAT_A(format) == 0)
753 format = PIXMAN_a8r8g8b8; /* available on all hardware */
755 picture = uxa_picture_for_pixman_format(screen, format, width, height);
759 if (uxa_prepare_access(picture->pDrawable, UXA_ACCESS_RW)) {
760 if (uxa_prepare_access(src->pDrawable, UXA_ACCESS_RO)) {
762 fbComposite(PictOpSrc, src, NULL, picture,
763 x, y, 0, 0, 0, 0, width, height);
764 uxa_finish_access(src->pDrawable);
766 uxa_finish_access(picture->pDrawable);
770 FreePicture(picture, 0);
778 drawable_contains (DrawablePtr drawable, int x, int y, int w, int h)
783 if (x + w > drawable->width)
786 if (y + h > drawable->height)
793 uxa_acquire_drawable(ScreenPtr pScreen,
796 CARD16 width, CARD16 height,
797 INT16 * out_x, INT16 * out_y)
805 depth = pSrc->pDrawable->depth;
806 if (!transform_is_integer_translation(pSrc->transform, &tx, &ty) ||
807 !drawable_contains(pSrc->pDrawable, x + tx, y + ty, width, height) ||
809 pSrc->filter == PictFilterConvolution) {
810 /* XXX extract the sample extents and do the transformation on the GPU */
811 pDst = uxa_render_picture(pScreen, pSrc,
812 pSrc->format | (BitsPerPixel(pSrc->pDrawable->depth) << 24),
813 x, y, width, height);
819 if (width == pSrc->pDrawable->width && height == pSrc->pDrawable->height) {
820 *out_x = x + pSrc->pDrawable->x;
821 *out_y = y + pSrc->pDrawable->y;
826 pPixmap = pScreen->CreatePixmap(pScreen,
827 width, height, depth,
828 CREATE_PIXMAP_USAGE_SCRATCH);
832 /* Skip the copy if the result remains in memory and not a bo */
833 if (!uxa_pixmap_is_offscreen(pPixmap)) {
834 pScreen->DestroyPixmap(pPixmap);
838 pGC = GetScratchGC(depth, pScreen);
840 pScreen->DestroyPixmap(pPixmap);
844 ValidateGC(&pPixmap->drawable, pGC);
845 pGC->ops->CopyArea(pSrc->pDrawable, &pPixmap->drawable, pGC,
846 x + tx, y + ty, width, height, 0, 0);
849 pDst = CreatePicture(0, &pPixmap->drawable,
850 PictureMatchFormat(pScreen, depth, pSrc->format),
851 0, 0, serverClient, &error);
852 pScreen->DestroyPixmap(pPixmap);
856 ValidatePicture(pDst);
858 pDst->componentAlpha = pSrc->componentAlpha;
865 uxa_acquire_picture(ScreenPtr screen,
867 pixman_format_code_t format,
869 CARD16 width, CARD16 height,
870 INT16 * out_x, INT16 * out_y)
872 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
874 if (uxa_screen->info->check_composite_texture &&
875 uxa_screen->info->check_composite_texture(screen, src)) {
876 if (src->pDrawable) {
877 *out_x = x + src->pDrawable->x;
878 *out_y = y + src->pDrawable->y;
886 if (src->pDrawable) {
889 dst = uxa_acquire_drawable(screen, src,
895 if (uxa_screen->info->check_composite_texture &&
896 !uxa_screen->info->check_composite_texture(screen, dst)) {
907 return uxa_acquire_pattern(screen, src,
908 format, x, y, width, height);
912 uxa_acquire_source(ScreenPtr screen,
915 CARD16 width, CARD16 height,
916 INT16 * out_x, INT16 * out_y)
918 return uxa_acquire_picture (screen, pict,
926 uxa_acquire_mask(ScreenPtr screen,
929 INT16 width, INT16 height,
930 INT16 * out_x, INT16 * out_y)
932 return uxa_acquire_picture (screen, pict,
940 _pixman_region_init_rectangles(pixman_region16_t *region,
945 pixman_box16_t stack_boxes[64], *boxes = stack_boxes;
949 if (num_rects > sizeof(stack_boxes) / sizeof(stack_boxes[0])) {
950 boxes = malloc(sizeof(pixman_box16_t) * num_rects);
955 for (i = 0; i < num_rects; i++) {
956 boxes[i].x1 = rects[i].x + tx;
957 boxes[i].y1 = rects[i].y + ty;
958 boxes[i].x2 = rects[i].x + tx + rects[i].width;
959 boxes[i].y2 = rects[i].y + ty + rects[i].height;
962 ret = pixman_region_init_rects(region, boxes, num_rects);
964 if (boxes != stack_boxes)
971 uxa_solid_rects (CARD8 op,
977 ScreenPtr screen = dst->pDrawable->pScreen;
978 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
979 PixmapPtr dst_pixmap, src_pixmap = NULL;
980 pixman_region16_t region;
981 pixman_box16_t *boxes, *extents;
986 if (!pixman_region_not_empty(dst->pCompositeClip))
992 dst_pixmap = uxa_get_offscreen_pixmap(dst->pDrawable, &dst_x, &dst_y);
996 if (!_pixman_region_init_rectangles(®ion,
998 dst->pDrawable->x, dst->pDrawable->y))
1001 if (!pixman_region_intersect(®ion, ®ion, dst->pCompositeClip)) {
1002 pixman_region_fini(®ion);
1006 pixman_region_translate(®ion, dst_x, dst_y);
1007 boxes = pixman_region_rectangles(®ion, &num_boxes);
1008 extents = pixman_region_extents (®ion);
1010 if (op == PictOpClear)
1011 color->red = color->green = color->blue = color->alpha = 0;
1012 if (color->alpha >= 0xff00 && op == PictOpOver) {
1013 color->alpha = 0xffff;
1017 /* Using GEM, the relocation costs outweigh the advantages of the blitter */
1018 if (num_boxes == 1 && (op == PictOpSrc || op == PictOpClear)) {
1022 if (uxa_screen->info->check_solid &&
1023 !uxa_screen->info->check_solid(&dst_pixmap->drawable, GXcopy, FB_ALLONES))
1026 if (!uxa_get_pixel_from_rgba(&pixel,
1034 if (!uxa_screen->info->prepare_solid(dst_pixmap, GXcopy, FB_ALLONES, pixel))
1037 while (num_boxes--) {
1038 uxa_screen->info->solid(dst_pixmap,
1039 boxes->x1, boxes->y1,
1040 boxes->x2, boxes->y2);
1044 uxa_screen->info->done_solid(dst_pixmap);
1048 src = CreateSolidPicture(0, color, &error);
1052 if (!uxa_screen->info->check_composite(op, src, NULL, dst,
1053 extents->x2 - extents->x1,
1054 extents->y2 - extents->y1)) {
1055 if (op == PictOpSrc || op == PictOpClear) {
1056 FreePicture(src, 0);
1063 if (!uxa_screen->info->check_composite_texture ||
1064 !uxa_screen->info->check_composite_texture(screen, src)) {
1066 int src_off_x, src_off_y;
1068 solid = uxa_acquire_solid(screen, src->pSourcePict);
1071 FreePicture(src, 0);
1074 src_pixmap = uxa_get_offscreen_pixmap(src->pDrawable,
1075 &src_off_x, &src_off_y);
1080 if (!uxa_screen->info->prepare_composite(op, src, NULL, dst, src_pixmap, NULL, dst_pixmap))
1083 while (num_boxes--) {
1084 uxa_screen->info->composite(dst_pixmap,
1088 boxes->x2 - boxes->x1,
1089 boxes->y2 - boxes->y1);
1093 uxa_screen->info->done_composite(dst_pixmap);
1094 FreePicture(src, 0);
1097 /* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must
1098 * manually append the damaged regions ourselves.
1100 pixman_region_translate(®ion, -dst_x, -dst_y);
1101 DamageRegionAppend(dst->pDrawable, ®ion);
1103 pixman_region_fini(®ion);
1107 FreePicture(src, 0);
1109 pixman_region_fini(®ion);
1111 uxa_screen->SavedCompositeRects(op, dst, color, num_rects, rects);
1115 uxa_try_driver_composite(CARD8 op,
1119 INT16 xSrc, INT16 ySrc,
1120 INT16 xMask, INT16 yMask,
1121 INT16 xDst, INT16 yDst,
1122 CARD16 width, CARD16 height)
1124 ScreenPtr screen = pDst->pDrawable->pScreen;
1125 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
1129 int xDst_copy, yDst_copy;
1130 int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
1131 PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
1132 PicturePtr localSrc, localMask = NULL;
1133 PicturePtr localDst = pDst;
1135 if (uxa_screen->info->check_composite &&
1136 !(*uxa_screen->info->check_composite) (op, pSrc, pMask, pDst, width, height))
1139 if (uxa_screen->info->check_composite_target &&
1140 !uxa_screen->info->check_composite_target(uxa_get_drawable_pixmap(pDst->pDrawable))) {
1141 int depth = pDst->pDrawable->depth;
1146 pixmap = uxa_get_drawable_pixmap(pDst->pDrawable);
1147 if (uxa_screen->info->check_copy &&
1148 !uxa_screen->info->check_copy(pixmap, pixmap, GXcopy, FB_ALLONES))
1151 pixmap = screen->CreatePixmap(screen,
1152 width, height, depth,
1153 CREATE_PIXMAP_USAGE_SCRATCH);
1157 gc = GetScratchGC(depth, screen);
1159 screen->DestroyPixmap(pixmap);
1163 ValidateGC(&pixmap->drawable, gc);
1164 gc->ops->CopyArea(pDst->pDrawable, &pixmap->drawable, gc,
1165 xDst, yDst, width, height, 0, 0);
1168 xDst_copy = xDst; xDst = 0;
1169 yDst_copy = yDst; yDst = 0;
1171 localDst = CreatePicture(0, &pixmap->drawable,
1172 PictureMatchFormat(screen, depth, pDst->format),
1173 0, 0, serverClient, &error);
1174 screen->DestroyPixmap(pixmap);
1179 ValidatePicture(localDst);
1183 uxa_get_offscreen_pixmap(localDst->pDrawable, &dst_off_x, &dst_off_y);
1185 if (localDst != pDst)
1186 FreePicture(localDst, 0);
1190 xDst += localDst->pDrawable->x;
1191 yDst += localDst->pDrawable->y;
1193 localSrc = uxa_acquire_source(screen, pSrc,
1198 if (localDst != pDst)
1199 FreePicture(localDst, 0);
1204 localMask = uxa_acquire_mask(screen, pMask,
1209 if (localSrc != pSrc)
1210 FreePicture(localSrc, 0);
1211 if (localDst != pDst)
1212 FreePicture(localDst, 0);
1218 if (!miComputeCompositeRegion(®ion, localSrc, localMask, localDst,
1219 xSrc, ySrc, xMask, yMask, xDst, yDst,
1221 if (localSrc != pSrc)
1222 FreePicture(localSrc, 0);
1223 if (localMask && localMask != pMask)
1224 FreePicture(localMask, 0);
1225 if (localDst != pDst)
1226 FreePicture(localDst, 0);
1231 if (localSrc->pDrawable) {
1232 pSrcPix = uxa_get_offscreen_pixmap(localSrc->pDrawable,
1233 &src_off_x, &src_off_y);
1235 REGION_UNINIT(screen, ®ion);
1237 if (localSrc != pSrc)
1238 FreePicture(localSrc, 0);
1239 if (localMask && localMask != pMask)
1240 FreePicture(localMask, 0);
1241 if (localDst != pDst)
1242 FreePicture(localDst, 0);
1251 if (localMask->pDrawable) {
1252 pMaskPix = uxa_get_offscreen_pixmap(localMask->pDrawable,
1253 &mask_off_x, &mask_off_y);
1255 REGION_UNINIT(screen, ®ion);
1257 if (localSrc != pSrc)
1258 FreePicture(localSrc, 0);
1259 if (localMask && localMask != pMask)
1260 FreePicture(localMask, 0);
1261 if (localDst != pDst)
1262 FreePicture(localDst, 0);
1271 if (!(*uxa_screen->info->prepare_composite)
1272 (op, localSrc, localMask, localDst, pSrcPix, pMaskPix, pDstPix)) {
1273 REGION_UNINIT(screen, ®ion);
1275 if (localSrc != pSrc)
1276 FreePicture(localSrc, 0);
1277 if (localMask && localMask != pMask)
1278 FreePicture(localMask, 0);
1279 if (localDst != pDst)
1280 FreePicture(localDst, 0);
1286 xMask = xMask + mask_off_x - xDst;
1287 yMask = yMask + mask_off_y - yDst;
1290 xSrc = xSrc + src_off_x - xDst;
1291 ySrc = ySrc + src_off_y - yDst;
1293 nbox = REGION_NUM_RECTS(®ion);
1294 pbox = REGION_RECTS(®ion);
1296 (*uxa_screen->info->composite) (pDstPix,
1301 pbox->x1 + dst_off_x,
1302 pbox->y1 + dst_off_y,
1303 pbox->x2 - pbox->x1,
1304 pbox->y2 - pbox->y1);
1307 (*uxa_screen->info->done_composite) (pDstPix);
1309 REGION_UNINIT(screen, ®ion);
1311 if (localSrc != pSrc)
1312 FreePicture(localSrc, 0);
1313 if (localMask && localMask != pMask)
1314 FreePicture(localMask, 0);
1316 if (localDst != pDst) {
1319 gc = GetScratchGC(pDst->pDrawable->depth, screen);
1321 ValidateGC(pDst->pDrawable, gc);
1322 gc->ops->CopyArea(localDst->pDrawable, pDst->pDrawable, gc,
1323 0, 0, width, height, xDst_copy, yDst_copy);
1327 FreePicture(localDst, 0);
1334 * uxa_try_magic_two_pass_composite_helper implements PictOpOver using two passes of
1335 * simpler operations PictOpOutReverse and PictOpAdd. Mainly used for component
1336 * alpha and limited 1-tmu cards.
1338 * From http://anholt.livejournal.com/32058.html:
1340 * The trouble is that component-alpha rendering requires two different sources
1341 * for blending: one for the source value to the blender, which is the
1342 * per-channel multiplication of source and mask, and one for the source alpha
1343 * for multiplying with the destination channels, which is the multiplication
1344 * of the source channels by the mask alpha. So the equation for Over is:
1346 * dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A
1347 * dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R
1348 * dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G
1349 * dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B
1351 * But we can do some simpler operations, right? How about PictOpOutReverse,
1352 * which has a source factor of 0 and dest factor of (1 - source alpha). We
1353 * can get the source alpha value (srca.X = src.A * mask.X) out of the texture
1354 * blenders pretty easily. So we can do a component-alpha OutReverse, which
1357 * dst.A = 0 + (1 - (src.A * mask.A)) * dst.A
1358 * dst.R = 0 + (1 - (src.A * mask.R)) * dst.R
1359 * dst.G = 0 + (1 - (src.A * mask.G)) * dst.G
1360 * dst.B = 0 + (1 - (src.A * mask.B)) * dst.B
1362 * OK. And if an op doesn't use the source alpha value for the destination
1363 * factor, then we can do the channel multiplication in the texture blenders
1364 * to get the source value, and ignore the source alpha that we wouldn't use.
1365 * We've supported this in the Radeon driver for a long time. An example would
1366 * be PictOpAdd, which does:
1368 * dst.A = src.A * mask.A + dst.A
1369 * dst.R = src.R * mask.R + dst.R
1370 * dst.G = src.G * mask.G + dst.G
1371 * dst.B = src.B * mask.B + dst.B
1373 * Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right
1376 * dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A)
1377 * dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R)
1378 * dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G)
1379 * dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B)
1383 uxa_try_magic_two_pass_composite_helper(CARD8 op,
1387 INT16 xSrc, INT16 ySrc,
1388 INT16 xMask, INT16 yMask,
1389 INT16 xDst, INT16 yDst,
1390 CARD16 width, CARD16 height)
1392 ScreenPtr screen = pDst->pDrawable->pScreen;
1393 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
1394 PicturePtr localDst = pDst;
1395 int xDst_copy, yDst_copy;
1397 assert(op == PictOpOver);
1399 if (uxa_screen->info->check_composite &&
1400 (!(*uxa_screen->info->check_composite) (PictOpOutReverse, pSrc,
1401 pMask, pDst, width, height)
1402 || !(*uxa_screen->info->check_composite) (PictOpAdd, pSrc, pMask,
1403 pDst, width, height))) {
1407 if (uxa_screen->info->check_composite_target &&
1408 !uxa_screen->info->check_composite_target(uxa_get_drawable_pixmap(pDst->pDrawable))) {
1409 int depth = pDst->pDrawable->depth;
1414 pixmap = uxa_get_drawable_pixmap(pDst->pDrawable);
1415 if (uxa_screen->info->check_copy &&
1416 !uxa_screen->info->check_copy(pixmap, pixmap, GXcopy, FB_ALLONES))
1419 pixmap = screen->CreatePixmap(screen,
1420 width, height, depth,
1421 CREATE_PIXMAP_USAGE_SCRATCH);
1425 gc = GetScratchGC(depth, screen);
1427 screen->DestroyPixmap(pixmap);
1431 ValidateGC(&pixmap->drawable, gc);
1432 gc->ops->CopyArea(pDst->pDrawable, &pixmap->drawable, gc,
1433 xDst, yDst, width, height, 0, 0);
1436 xDst_copy = xDst; xDst = 0;
1437 yDst_copy = yDst; yDst = 0;
1439 localDst = CreatePicture(0, &pixmap->drawable,
1440 PictureMatchFormat(screen, depth, pDst->format),
1441 0, 0, serverClient, &error);
1442 screen->DestroyPixmap(pixmap);
1447 ValidatePicture(localDst);
1450 /* Now, we think we should be able to accelerate this operation. First,
1451 * composite the destination to be the destination times the source alpha
1454 uxa_composite(PictOpOutReverse, pSrc, pMask, localDst,
1460 /* Then, add in the source value times the destination alpha factors (1.0).
1462 uxa_composite(PictOpAdd, pSrc, pMask, localDst,
1468 if (localDst != pDst) {
1471 gc = GetScratchGC(pDst->pDrawable->depth, screen);
1473 ValidateGC(pDst->pDrawable, gc);
1474 gc->ops->CopyArea(localDst->pDrawable, pDst->pDrawable, gc,
1475 0, 0, width, height, xDst_copy, yDst_copy);
1479 FreePicture(localDst, 0);
1486 compatible_formats (CARD8 op, PicturePtr dst, PicturePtr src)
1488 if (op == PictOpSrc) {
1489 if (src->format == dst->format)
1492 /* Is the destination an alpha-less version of source? */
1493 if (dst->format == PICT_FORMAT(PICT_FORMAT_BPP(src->format),
1494 PICT_FORMAT_TYPE(src->format),
1496 PICT_FORMAT_R(src->format),
1497 PICT_FORMAT_G(src->format),
1498 PICT_FORMAT_B(src->format)))
1501 /* XXX xrgb is promoted to argb during image upload... */
1503 if (dst->format == PICT_a8r8g8b8 && src->format == PICT_x8r8g8b8)
1506 } else if (op == PictOpOver) {
1507 if (PICT_FORMAT_A(src->format))
1510 return src->format == dst->format;
1517 uxa_composite(CARD8 op,
1521 INT16 xSrc, INT16 ySrc,
1522 INT16 xMask, INT16 yMask,
1523 INT16 xDst, INT16 yDst,
1524 CARD16 width, CARD16 height)
1526 uxa_screen_t *uxa_screen = uxa_get_screen(pDst->pDrawable->pScreen);
1528 Bool saveSrcRepeat = pSrc->repeat;
1529 Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
1533 if (uxa_screen->swappedOut || uxa_screen->force_fallback)
1536 if (!uxa_drawable_is_offscreen(pDst->pDrawable))
1539 if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
1542 /* Remove repeat in source if useless */
1543 if (pSrc->pDrawable && pSrc->repeat && pSrc->filter != PictFilterConvolution &&
1544 transform_is_integer_translation(pSrc->transform, &tx, &ty) &&
1545 (pSrc->pDrawable->width > 1 || pSrc->pDrawable->height > 1) &&
1546 drawable_contains(pSrc->pDrawable, xSrc + tx, ySrc + ty, width, height))
1550 if (op == PictOpClear) {
1551 PicturePtr clear = uxa_solid_clear(pDst->pDrawable->pScreen);
1553 uxa_try_driver_solid_fill(clear, pDst,
1556 width, height) == 1)
1560 if (pSrc->pDrawable == NULL) {
1561 if (pSrc->pSourcePict) {
1562 SourcePict *source = pSrc->pSourcePict;
1563 if (source->type == SourcePictTypeSolidFill) {
1564 if (op == PictOpSrc ||
1565 (op == PictOpOver &&
1566 (source->solidFill.color & 0xff000000) == 0xff000000)) {
1567 ret = uxa_try_driver_solid_fill(pSrc, pDst,
1576 } else if (pSrc->pDrawable->width == 1 &&
1577 pSrc->pDrawable->height == 1 &&
1579 (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format)))) {
1580 ret = uxa_try_driver_solid_fill(pSrc, pDst,
1586 } else if (compatible_formats (op, pDst, pSrc) &&
1587 pSrc->filter != PictFilterConvolution &&
1588 transform_is_integer_translation(pSrc->transform, &tx, &ty)) {
1589 if (!pSrc->repeat &&
1590 drawable_contains(pSrc->pDrawable,
1591 xSrc + tx, ySrc + ty,
1593 xDst += pDst->pDrawable->x;
1594 yDst += pDst->pDrawable->y;
1595 xSrc += pSrc->pDrawable->x + tx;
1596 ySrc += pSrc->pDrawable->y + ty;
1598 if (!miComputeCompositeRegion
1599 (®ion, pSrc, pMask, pDst, xSrc, ySrc,
1600 xMask, yMask, xDst, yDst, width, height))
1603 uxa_copy_n_to_n(pSrc->pDrawable,
1604 pDst->pDrawable, NULL,
1605 REGION_RECTS(®ion),
1606 REGION_NUM_RECTS(®ion),
1607 xSrc - xDst, ySrc - yDst, FALSE,
1609 REGION_UNINIT(pDst->pDrawable->pScreen,
1612 } else if (pSrc->repeat && pSrc->repeatType == RepeatNormal &&
1613 pSrc->pDrawable->type == DRAWABLE_PIXMAP) {
1616 /* Let's see if the driver can do the repeat
1619 if (uxa_screen->info->prepare_composite) {
1620 ret = uxa_try_driver_composite(op, pSrc,
1630 /* Now see if we can use
1631 * uxa_fill_region_tiled()
1633 xDst += pDst->pDrawable->x;
1634 yDst += pDst->pDrawable->y;
1635 xSrc += pSrc->pDrawable->x + tx;
1636 ySrc += pSrc->pDrawable->y + ty;
1638 if (!miComputeCompositeRegion
1639 (®ion, pSrc, pMask, pDst, xSrc, ySrc,
1640 xMask, yMask, xDst, yDst, width, height))
1643 /* pattern origin is the point in the
1644 * destination drawable
1645 * corresponding to (0,0) in the source */
1646 patOrg.x = xDst - xSrc;
1647 patOrg.y = yDst - ySrc;
1649 ret = uxa_fill_region_tiled(pDst->pDrawable,
1653 FB_ALLONES, GXcopy);
1655 REGION_UNINIT(pDst->pDrawable->pScreen,
1664 /* Remove repeat in mask if useless */
1665 if (pMask && pMask->pDrawable && pMask->repeat &&
1666 pMask->filter != PictFilterConvolution &&
1667 transform_is_integer_translation(pMask->transform, &tx, &ty) &&
1668 (pMask->pDrawable->width > 1 || pMask->pDrawable->height > 1) &&
1669 drawable_contains(pMask->pDrawable, xMask + tx, yMask + ty, width, height))
1672 if (uxa_screen->info->prepare_composite) {
1676 uxa_try_driver_composite(op, pSrc, pMask, pDst, xSrc, ySrc,
1677 xMask, yMask, xDst, yDst, width,
1682 /* For generic masks and solid src pictures, mach64 can do
1683 * Over in two passes, similar to the component-alpha case.
1688 pSrc->pDrawable->width == 1 &&
1689 pSrc->pDrawable->height == 1 &&
1692 pSrc->pSourcePict->type == SourcePictTypeSolidFill :
1695 /* If we couldn't do the Composite in a single pass, and it
1696 * was a component-alpha Over, see if we can do it in two
1697 * passes with an OutReverse and then an Add.
1699 if (ret == -1 && op == PictOpOver && pMask &&
1700 (pMask->componentAlpha || isSrcSolid)) {
1702 uxa_try_magic_two_pass_composite_helper(op, pSrc,
1715 uxa_print_composite_fallback("uxa_composite",
1716 op, pSrc, pMask, pDst);
1718 uxa_check_composite(op, pSrc, pMask, pDst, xSrc, ySrc,
1719 xMask, yMask, xDst, yDst, width, height);
1722 pSrc->repeat = saveSrcRepeat;
1724 pMask->repeat = saveMaskRepeat;
1729 * Same as miCreateAlphaPicture, except it uses uxa_check_poly_fill_rect instead
1730 * of PolyFillRect to initialize the pixmap after creating it, to prevent
1731 * the pixmap from being migrated.
1733 * See the comments about uxa_trapezoids and uxa_triangles.
1736 uxa_create_alpha_picture(ScreenPtr pScreen,
1738 PictFormatPtr pPictFormat, CARD16 width, CARD16 height)
1741 PicturePtr pPicture;
1744 if (width > 32767 || height > 32767)
1748 if (pDst->polyEdge == PolyEdgeSharp)
1749 pPictFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
1751 pPictFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
1756 pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
1758 UXA_CREATE_PIXMAP_FOR_MAP);
1761 pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat,
1762 0, 0, serverClient, &error);
1763 (*pScreen->DestroyPixmap) (pPixmap);
1768 uxa_check_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
1769 PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
1770 int ntrap, xTrapezoid * traps)
1772 ScreenPtr screen = dst->pDrawable->pScreen;
1775 PixmapPtr scratch = NULL;
1781 pixman_image_t *image;
1782 pixman_format_code_t format;
1785 xDst = traps[0].left.p1.x >> 16;
1786 yDst = traps[0].left.p1.y >> 16;
1788 miTrapezoidBounds (ntrap, traps, &bounds);
1789 if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
1792 width = bounds.x2 - bounds.x1;
1793 height = bounds.y2 - bounds.y1;
1795 format = maskFormat->format |
1796 (BitsPerPixel(maskFormat->depth) << 24);
1798 pixman_image_create_bits(format, width, height, NULL, 0);
1802 for (; ntrap; ntrap--, traps++)
1803 pixman_rasterize_trapezoid(image,
1804 (pixman_trapezoid_t *) traps,
1805 -bounds.x1, -bounds.y1);
1808 scratch = GetScratchPixmapHeader(screen, width, height,
1809 PIXMAN_FORMAT_DEPTH(format),
1810 PIXMAN_FORMAT_BPP(format),
1811 pixman_image_get_stride(image),
1812 pixman_image_get_data(image));
1814 pixman_image_unref(image);
1818 mask = CreatePicture(0, &scratch->drawable,
1819 PictureMatchFormat(screen,
1820 PIXMAN_FORMAT_DEPTH(format),
1822 0, 0, serverClient, &error);
1824 FreeScratchPixmapHeader(scratch);
1825 pixman_image_unref(image);
1829 xRel = bounds.x1 + xSrc - xDst;
1830 yRel = bounds.y1 + ySrc - yDst;
1831 CompositePicture(op, src, mask, dst,
1834 bounds.x1, bounds.y1,
1836 FreePicture(mask, 0);
1838 FreeScratchPixmapHeader(scratch);
1839 pixman_image_unref(image);
1841 if (dst->polyEdge == PolyEdgeSharp)
1842 maskFormat = PictureMatchFormat(screen, 1, PICT_a1);
1844 maskFormat = PictureMatchFormat(screen, 8, PICT_a8);
1846 for (; ntrap; ntrap--, traps++)
1847 uxa_check_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, 1, traps);
1852 * uxa_trapezoids is essentially a copy of miTrapezoids that uses
1853 * uxa_create_alpha_picture instead of miCreateAlphaPicture.
1855 * The problem with miCreateAlphaPicture is that it calls PolyFillRect
1856 * to initialize the contents after creating the pixmap, which
1857 * causes the pixmap to be moved in for acceleration. The subsequent
1858 * call to RasterizeTrapezoid won't be accelerated however, which
1859 * forces the pixmap to be moved out again.
1861 * uxa_create_alpha_picture avoids this roundtrip by using
1862 * uxa_check_poly_fill_rect to initialize the contents.
1865 uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
1866 PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
1867 int ntrap, xTrapezoid * traps)
1869 ScreenPtr screen = dst->pDrawable->pScreen;
1870 uxa_screen_t *uxa_screen = uxa_get_screen(screen);
1874 if (uxa_screen->swappedOut || uxa_screen->force_fallback) {
1875 uxa_check_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps);
1879 direct = op == PictOpAdd && miIsSolidAlpha(src);
1880 if (maskFormat || direct) {
1881 miTrapezoidBounds(ntrap, traps, &bounds);
1883 if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
1888 * Check for solid alpha add
1891 DrawablePtr pDraw = dst->pDrawable;
1892 PixmapPtr pixmap = uxa_get_drawable_pixmap(pDraw);
1895 uxa_get_drawable_deltas(pDraw, pixmap, &xoff, &yoff);
1900 if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
1901 PictureScreenPtr ps = GetPictureScreen(screen);
1903 for (; ntrap; ntrap--, traps++)
1904 (*ps->RasterizeTrapezoid) (dst, traps, 0, 0);
1905 uxa_finish_access(pDraw);
1907 } else if (maskFormat) {
1908 PixmapPtr scratch = NULL;
1913 pixman_image_t *image;
1914 pixman_format_code_t format;
1916 xDst = traps[0].left.p1.x >> 16;
1917 yDst = traps[0].left.p1.y >> 16;
1919 width = bounds.x2 - bounds.x1;
1920 height = bounds.y2 - bounds.y1;
1922 format = maskFormat->format |
1923 (BitsPerPixel(maskFormat->depth) << 24);
1925 pixman_image_create_bits(format, width, height, NULL, 0);
1929 for (; ntrap; ntrap--, traps++)
1930 pixman_rasterize_trapezoid(image,
1931 (pixman_trapezoid_t *) traps,
1932 -bounds.x1, -bounds.y1);
1933 if (uxa_drawable_is_offscreen(dst->pDrawable)) {
1934 mask = uxa_picture_from_pixman_image(screen, image, format);
1938 scratch = GetScratchPixmapHeader(screen, width, height,
1939 PIXMAN_FORMAT_DEPTH(format),
1940 PIXMAN_FORMAT_BPP(format),
1941 pixman_image_get_stride(image),
1942 pixman_image_get_data(image));
1943 mask = CreatePicture(0, &scratch->drawable,
1944 PictureMatchFormat(screen,
1945 PIXMAN_FORMAT_DEPTH(format),
1947 0, 0, serverClient, &error);
1951 FreeScratchPixmapHeader(scratch);
1952 pixman_image_unref(image);
1956 xRel = bounds.x1 + xSrc - xDst;
1957 yRel = bounds.y1 + ySrc - yDst;
1958 CompositePicture(op, src, mask, dst,
1961 bounds.x1, bounds.y1,
1963 FreePicture(mask, 0);
1966 FreeScratchPixmapHeader(scratch);
1967 pixman_image_unref(image);
1969 if (dst->polyEdge == PolyEdgeSharp)
1970 maskFormat = PictureMatchFormat(screen, 1, PICT_a1);
1972 maskFormat = PictureMatchFormat(screen, 8, PICT_a8);
1973 for (; ntrap; ntrap--, traps++)
1974 uxa_trapezoids(op, src, dst, maskFormat, xSrc, ySrc,
1980 * uxa_triangles is essentially a copy of miTriangles that uses
1981 * uxa_create_alpha_picture instead of miCreateAlphaPicture.
1983 * The problem with miCreateAlphaPicture is that it calls PolyFillRect
1984 * to initialize the contents after creating the pixmap, which
1985 * causes the pixmap to be moved in for acceleration. The subsequent
1986 * call to AddTriangles won't be accelerated however, which forces the pixmap
1987 * to be moved out again.
1989 * uxa_create_alpha_picture avoids this roundtrip by using
1990 * uxa_check_poly_fill_rect to initialize the contents.
1993 uxa_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
1994 PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
1995 int ntri, xTriangle * tris)
1997 ScreenPtr pScreen = pDst->pDrawable->pScreen;
1998 PictureScreenPtr ps = GetPictureScreen(pScreen);
2000 Bool direct = op == PictOpAdd && miIsSolidAlpha(pSrc);
2002 if (maskFormat || direct) {
2003 miTriangleBounds(ntri, tris, &bounds);
2005 if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
2010 * Check for solid alpha add
2013 DrawablePtr pDraw = pDst->pDrawable;
2014 if (uxa_prepare_access(pDraw, UXA_ACCESS_RW)) {
2015 (*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
2016 uxa_finish_access(pDraw);
2018 } else if (maskFormat) {
2019 PicturePtr pPicture;
2022 int width = bounds.x2 - bounds.x1;
2023 int height = bounds.y2 - bounds.y1;
2027 xDst = tris[0].p1.x >> 16;
2028 yDst = tris[0].p1.y >> 16;
2030 pPicture = uxa_create_alpha_picture(pScreen, pDst, maskFormat,
2035 /* Clear the alpha picture to 0. */
2036 pGC = GetScratchGC(pPicture->pDrawable->depth, pScreen);
2038 FreePicture(pPicture, 0);
2041 ValidateGC(pPicture->pDrawable, pGC);
2045 rect.height = height;
2046 uxa_check_poly_fill_rect(pPicture->pDrawable, pGC, 1, &rect);
2049 if (uxa_prepare_access(pPicture->pDrawable, UXA_ACCESS_RW)) {
2050 (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1,
2052 uxa_finish_access(pPicture->pDrawable);
2055 xRel = bounds.x1 + xSrc - xDst;
2056 yRel = bounds.y1 + ySrc - yDst;
2057 CompositePicture(op, pSrc, pPicture, pDst,
2058 xRel, yRel, 0, 0, bounds.x1, bounds.y1,
2059 bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
2060 FreePicture(pPicture, 0);
2062 if (pDst->polyEdge == PolyEdgeSharp)
2063 maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
2065 maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
2067 for (; ntri; ntri--, tris++)
2068 uxa_triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1,