Lines 947-1141
Link Here
|
947 |
out_x, out_y); |
947 |
out_x, out_y); |
948 |
} |
948 |
} |
949 |
|
949 |
|
950 |
static Bool |
|
|
951 |
_pixman_region_init_rectangles(pixman_region16_t *region, |
952 |
int num_rects, |
953 |
xRectangle *rects, |
954 |
int tx, int ty) |
955 |
{ |
956 |
pixman_box16_t stack_boxes[64], *boxes = stack_boxes; |
957 |
pixman_bool_t ret; |
958 |
int i; |
959 |
|
960 |
if (num_rects > sizeof(stack_boxes) / sizeof(stack_boxes[0])) { |
961 |
boxes = malloc(sizeof(pixman_box16_t) * num_rects); |
962 |
if (boxes == NULL) |
963 |
return FALSE; |
964 |
} |
965 |
|
966 |
for (i = 0; i < num_rects; i++) { |
967 |
boxes[i].x1 = rects[i].x + tx; |
968 |
boxes[i].y1 = rects[i].y + ty; |
969 |
boxes[i].x2 = rects[i].x + tx + rects[i].width; |
970 |
boxes[i].y2 = rects[i].y + ty + rects[i].height; |
971 |
} |
972 |
|
973 |
ret = pixman_region_init_rects(region, boxes, num_rects); |
974 |
|
975 |
if (boxes != stack_boxes) |
976 |
free(boxes); |
977 |
|
978 |
return ret; |
979 |
} |
980 |
|
981 |
void |
982 |
uxa_solid_rects (CARD8 op, |
983 |
PicturePtr dst, |
984 |
xRenderColor *color, |
985 |
int num_rects, |
986 |
xRectangle *rects) |
987 |
{ |
988 |
ScreenPtr screen = dst->pDrawable->pScreen; |
989 |
uxa_screen_t *uxa_screen = uxa_get_screen(screen); |
990 |
PixmapPtr dst_pixmap, src_pixmap = NULL; |
991 |
pixman_region16_t region; |
992 |
pixman_box16_t *boxes, *extents; |
993 |
PicturePtr src; |
994 |
int dst_x, dst_y; |
995 |
int num_boxes; |
996 |
|
997 |
if (!pixman_region_not_empty(dst->pCompositeClip)) |
998 |
return; |
999 |
|
1000 |
if (uxa_screen->info->flags & UXA_USE_GLAMOR) { |
1001 |
int ok; |
1002 |
|
1003 |
uxa_picture_prepare_access(dst, UXA_GLAMOR_ACCESS_RW); |
1004 |
ok = glamor_composite_rects_nf(op, dst, color, |
1005 |
num_rects, rects); |
1006 |
uxa_picture_finish_access(dst, UXA_GLAMOR_ACCESS_RW); |
1007 |
|
1008 |
if (!ok) |
1009 |
goto fallback; |
1010 |
|
1011 |
return; |
1012 |
} |
1013 |
|
1014 |
if (dst->alphaMap) |
1015 |
goto fallback; |
1016 |
|
1017 |
dst_pixmap = uxa_get_offscreen_pixmap(dst->pDrawable, &dst_x, &dst_y); |
1018 |
if (!dst_pixmap) |
1019 |
goto fallback; |
1020 |
|
1021 |
if (!_pixman_region_init_rectangles(®ion, |
1022 |
num_rects, rects, |
1023 |
dst->pDrawable->x, dst->pDrawable->y)) |
1024 |
goto fallback; |
1025 |
|
1026 |
if (!pixman_region_intersect(®ion, ®ion, dst->pCompositeClip)) { |
1027 |
pixman_region_fini(®ion); |
1028 |
return; |
1029 |
} |
1030 |
|
1031 |
pixman_region_translate(®ion, dst_x, dst_y); |
1032 |
boxes = pixman_region_rectangles(®ion, &num_boxes); |
1033 |
extents = pixman_region_extents (®ion); |
1034 |
|
1035 |
if (op == PictOpClear) |
1036 |
color->red = color->green = color->blue = color->alpha = 0; |
1037 |
if (color->alpha >= 0xff00 && op == PictOpOver) { |
1038 |
color->alpha = 0xffff; |
1039 |
op = PictOpSrc; |
1040 |
} |
1041 |
|
1042 |
/* Using GEM, the relocation costs outweigh the advantages of the blitter */ |
1043 |
if (num_boxes == 1 && (op == PictOpSrc || op == PictOpClear)) { |
1044 |
CARD32 pixel; |
1045 |
|
1046 |
try_solid: |
1047 |
if (uxa_screen->info->check_solid && |
1048 |
!uxa_screen->info->check_solid(&dst_pixmap->drawable, GXcopy, FB_ALLONES)) |
1049 |
goto err_region; |
1050 |
|
1051 |
if (!uxa_get_pixel_from_rgba(&pixel, |
1052 |
color->red, |
1053 |
color->green, |
1054 |
color->blue, |
1055 |
color->alpha, |
1056 |
dst->format)) |
1057 |
goto err_region; |
1058 |
|
1059 |
if (!uxa_screen->info->prepare_solid(dst_pixmap, GXcopy, FB_ALLONES, pixel)) |
1060 |
goto err_region; |
1061 |
|
1062 |
while (num_boxes--) { |
1063 |
uxa_screen->info->solid(dst_pixmap, |
1064 |
boxes->x1, boxes->y1, |
1065 |
boxes->x2, boxes->y2); |
1066 |
boxes++; |
1067 |
} |
1068 |
|
1069 |
uxa_screen->info->done_solid(dst_pixmap); |
1070 |
} else { |
1071 |
int error; |
1072 |
|
1073 |
src = CreateSolidPicture(0, color, &error); |
1074 |
if (!src) |
1075 |
goto err_region; |
1076 |
|
1077 |
if (!uxa_screen->info->check_composite(op, src, NULL, dst, |
1078 |
extents->x2 - extents->x1, |
1079 |
extents->y2 - extents->y1)) { |
1080 |
if (op == PictOpSrc || op == PictOpClear) { |
1081 |
FreePicture(src, 0); |
1082 |
goto try_solid; |
1083 |
} |
1084 |
|
1085 |
goto err_src; |
1086 |
} |
1087 |
|
1088 |
if (!uxa_screen->info->check_composite_texture || |
1089 |
!uxa_screen->info->check_composite_texture(screen, src)) { |
1090 |
PicturePtr solid; |
1091 |
int src_off_x, src_off_y; |
1092 |
|
1093 |
solid = uxa_acquire_solid(screen, src->pSourcePict); |
1094 |
if (!solid) |
1095 |
goto err_src; |
1096 |
FreePicture(src, 0); |
1097 |
|
1098 |
src = solid; |
1099 |
src_pixmap = uxa_get_offscreen_pixmap(src->pDrawable, |
1100 |
&src_off_x, &src_off_y); |
1101 |
if (!src_pixmap) |
1102 |
goto err_src; |
1103 |
} |
1104 |
|
1105 |
if (!uxa_screen->info->prepare_composite(op, src, NULL, dst, src_pixmap, NULL, dst_pixmap)) |
1106 |
goto err_src; |
1107 |
|
1108 |
while (num_boxes--) { |
1109 |
uxa_screen->info->composite(dst_pixmap, |
1110 |
0, 0, 0, 0, |
1111 |
boxes->x1, |
1112 |
boxes->y1, |
1113 |
boxes->x2 - boxes->x1, |
1114 |
boxes->y2 - boxes->y1); |
1115 |
boxes++; |
1116 |
} |
1117 |
|
1118 |
uxa_screen->info->done_composite(dst_pixmap); |
1119 |
FreePicture(src, 0); |
1120 |
} |
1121 |
|
1122 |
/* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must |
1123 |
* manually append the damaged regions ourselves. |
1124 |
*/ |
1125 |
pixman_region_translate(®ion, -dst_x, -dst_y); |
1126 |
DamageRegionAppend(dst->pDrawable, ®ion); |
1127 |
|
1128 |
pixman_region_fini(®ion); |
1129 |
return; |
1130 |
|
1131 |
err_src: |
1132 |
FreePicture(src, 0); |
1133 |
err_region: |
1134 |
pixman_region_fini(®ion); |
1135 |
fallback: |
1136 |
uxa_screen->SavedCompositeRects(op, dst, color, num_rects, rects); |
1137 |
} |
1138 |
|
1139 |
static int |
950 |
static int |
1140 |
uxa_try_driver_composite(CARD8 op, |
951 |
uxa_try_driver_composite(CARD8 op, |
1141 |
PicturePtr pSrc, |
952 |
PicturePtr pSrc, |