largepixmap: Add transform/repeat/reflect/pad support.
This commit implement almost all the needed functions for the large pixmap support. It's almost complete. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
48916a23a9
commit
1d2d858b8d
|
@ -199,6 +199,89 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
|
||||||
return result_regions;
|
return result_regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* For the repeat pad mode, we can simply convert the region and
|
||||||
|
* let the out-of-box region can cover the needed edge of the source/mask
|
||||||
|
* Then apply a normal clip we can get what we want.
|
||||||
|
*/
|
||||||
|
static RegionPtr
|
||||||
|
_glamor_convert_pad_region(RegionPtr region, int w, int h)
|
||||||
|
{
|
||||||
|
RegionPtr pad_region;
|
||||||
|
int nrect;
|
||||||
|
BoxPtr box;
|
||||||
|
int overlap;
|
||||||
|
|
||||||
|
nrect = RegionNumRects(region);
|
||||||
|
box = RegionRects(region);
|
||||||
|
pad_region = RegionCreate(NULL, 4);
|
||||||
|
if (pad_region == NULL)
|
||||||
|
return NULL;
|
||||||
|
while(nrect--) {
|
||||||
|
BoxRec pad_box;
|
||||||
|
RegionRec temp_region;
|
||||||
|
pad_box = *box;
|
||||||
|
if (pad_box.x1 < 0 && pad_box.x2 <= 0)
|
||||||
|
pad_box.x2 = 1;
|
||||||
|
else if (pad_box.x1 >= w && pad_box.x2 > w)
|
||||||
|
pad_box.x1 = w - 1;
|
||||||
|
if (pad_box.y1 < 0 && pad_box.y2 <=0)
|
||||||
|
pad_box.y2 = 1;
|
||||||
|
else if (pad_box.y1 >= h && pad_box.y2 > h)
|
||||||
|
pad_box.y1 = h - 1;
|
||||||
|
RegionInitBoxes(&temp_region, &pad_box, 1);
|
||||||
|
RegionAppend(pad_region, &temp_region);
|
||||||
|
RegionUninit(&temp_region);
|
||||||
|
box++;
|
||||||
|
}
|
||||||
|
RegionValidate(pad_region, &overlap);
|
||||||
|
return pad_region;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For one type of large pixmap, its one direction is not exceed the
|
||||||
|
* size limitation, and in another word, on one direction it has only
|
||||||
|
* one block.
|
||||||
|
*
|
||||||
|
* This case of reflect repeating, we can optimize it and avoid repeat
|
||||||
|
* clip on that direction. We can just enlarge the repeat box and can
|
||||||
|
* cover all the dest region on that direction. But latter, we need to
|
||||||
|
* fixup the clipped result to get a correct coords for the subsequent
|
||||||
|
* processing. This function is to do the coords correction.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
static void
|
||||||
|
_glamor_largepixmap_reflect_fixup(short *xy1, short *xy2, int wh)
|
||||||
|
{
|
||||||
|
int odd1, odd2;
|
||||||
|
int c1, c2;
|
||||||
|
|
||||||
|
if (*xy2 - *xy1 > wh) {
|
||||||
|
*xy1 = 0;
|
||||||
|
*xy2 = wh;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
modulus(*xy1, wh, c1);
|
||||||
|
odd1 = ((*xy1 - c1) / wh) & 0x1;
|
||||||
|
modulus(*xy2, wh, c2);
|
||||||
|
odd2 = ((*xy2 - c2) / wh) & 0x1;
|
||||||
|
|
||||||
|
if (odd1 && odd2) {
|
||||||
|
*xy1 = wh - c2;
|
||||||
|
*xy2 = wh - c1;
|
||||||
|
} else if (odd1 && !odd2) {
|
||||||
|
*xy1 = 0;
|
||||||
|
*xy2 = MAX(c2, wh - c1);
|
||||||
|
} else if (!odd1 && odd2) {
|
||||||
|
*xy2 = wh;
|
||||||
|
*xy1 = MIN(c1, wh - c2);
|
||||||
|
} else {
|
||||||
|
*xy1 = c1;
|
||||||
|
*xy2 = c2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clip the boxes regards to each pixmap's block array.
|
* Clip the boxes regards to each pixmap's block array.
|
||||||
*
|
*
|
||||||
|
@ -207,9 +290,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
|
||||||
*
|
*
|
||||||
* @is_transform: if it is set, it has a transform matrix.
|
* @is_transform: if it is set, it has a transform matrix.
|
||||||
*
|
*
|
||||||
* XXX Not support repeatPad currently.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static glamor_pixmap_clipped_regions *
|
static glamor_pixmap_clipped_regions *
|
||||||
_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
_glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
RegionPtr region, int *n_region,
|
RegionPtr region, int *n_region,
|
||||||
|
@ -242,7 +323,16 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
|
|
||||||
pixmap_width = priv->base.pixmap->drawable.width;
|
pixmap_width = priv->base.pixmap->drawable.width;
|
||||||
pixmap_height = priv->base.pixmap->drawable.height;
|
pixmap_height = priv->base.pixmap->drawable.height;
|
||||||
if (repeat_type == 0) {
|
if (repeat_type == 0 || repeat_type == RepeatPad) {
|
||||||
|
RegionPtr saved_region = NULL;
|
||||||
|
if (repeat_type == RepeatPad) {
|
||||||
|
saved_region = region;
|
||||||
|
region = _glamor_convert_pad_region(saved_region, pixmap_width, pixmap_height);
|
||||||
|
if (region == NULL) {
|
||||||
|
*n_region = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
|
clipped_regions = __glamor_compute_clipped_regions(priv->block_w,
|
||||||
priv->block_h,
|
priv->block_h,
|
||||||
priv->block_wcnt,
|
priv->block_wcnt,
|
||||||
|
@ -251,10 +341,9 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
priv->base.pixmap->drawable.height,
|
priv->base.pixmap->drawable.height,
|
||||||
region, n_region, 0
|
region, n_region, 0
|
||||||
);
|
);
|
||||||
|
if (saved_region)
|
||||||
|
RegionDestroy(region);
|
||||||
return clipped_regions;
|
return clipped_regions;
|
||||||
} else if (repeat_type != RepeatNormal) {
|
|
||||||
*n_region = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
extent = RegionExtents(region);
|
extent = RegionExtents(region);
|
||||||
|
|
||||||
|
@ -329,8 +418,10 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
int shift_x;
|
int shift_x;
|
||||||
int shift_y;
|
int shift_y;
|
||||||
int saved_y1, saved_y2;
|
int saved_y1, saved_y2;
|
||||||
int x_idx = 0, y_idx = 0;
|
int x_idx = 0, y_idx = 0, saved_y_idx = 0;
|
||||||
RegionRec temp_region;
|
RegionRec temp_region;
|
||||||
|
BoxRec reflect_repeat_box;
|
||||||
|
BoxPtr valid_repeat_box;
|
||||||
|
|
||||||
shift_x = (extent->x1 / pixmap_width) * pixmap_width;
|
shift_x = (extent->x1 / pixmap_width) * pixmap_width;
|
||||||
shift_y = (extent->y1 / pixmap_height) * pixmap_height;
|
shift_y = (extent->y1 / pixmap_height) * pixmap_height;
|
||||||
|
@ -380,12 +471,108 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
|
||||||
RegionUninit(&repeat_region);
|
RegionUninit(&repeat_region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (repeat_type == RepeatReflect) {
|
||||||
|
saved_y1 = repeat_box.y1;
|
||||||
|
saved_y2 = repeat_box.y2;
|
||||||
|
saved_y_idx = y_idx;
|
||||||
|
for(; ; repeat_box.x1 += dx, repeat_box.x2 += dx)
|
||||||
|
{
|
||||||
|
repeat_box.y1 = saved_y1;
|
||||||
|
repeat_box.y2 = saved_y2;
|
||||||
|
y_idx = saved_y_idx;
|
||||||
|
reflect_repeat_box.x1 = (x_idx & 1) ?
|
||||||
|
((2 * x_idx + 1) * dx - repeat_box.x2) : repeat_box.x1;
|
||||||
|
reflect_repeat_box.x2 = (x_idx & 1) ?
|
||||||
|
((2 * x_idx + 1) * dx - repeat_box.x1) : repeat_box.x2;
|
||||||
|
valid_repeat_box = &reflect_repeat_box;
|
||||||
|
|
||||||
|
if (valid_repeat_box->x1 >= extent->x2)
|
||||||
|
break;
|
||||||
|
for( repeat_box.y1 = saved_y1, repeat_box.y2 = saved_y2;
|
||||||
|
;
|
||||||
|
repeat_box.y1 += dy, repeat_box.y2 += dy)
|
||||||
|
{
|
||||||
|
|
||||||
|
DEBUGF("x_idx %d y_idx %d dx %d dy %d\n", x_idx, y_idx, dx, dy);
|
||||||
|
DEBUGF("repeat box %d %d %d %d \n",
|
||||||
|
repeat_box.x1, repeat_box.y1, repeat_box.x2, repeat_box.y2);
|
||||||
|
|
||||||
|
if (priv->block_hcnt > 1) {
|
||||||
|
reflect_repeat_box.y1 = (y_idx & 1) ?
|
||||||
|
((2 * y_idx + 1) * dy - repeat_box.y2) : repeat_box.y1;
|
||||||
|
reflect_repeat_box.y2 = (y_idx & 1) ?
|
||||||
|
((2 * y_idx + 1) * dy - repeat_box.y1) : repeat_box.y2;
|
||||||
|
} else {
|
||||||
|
reflect_repeat_box.y1 = repeat_box.y1;
|
||||||
|
reflect_repeat_box.y2 = repeat_box.y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGF("valid_repeat_box x1 %d y1 %d \n",
|
||||||
|
valid_repeat_box->x1, valid_repeat_box->y1);
|
||||||
|
if (valid_repeat_box->y1 >= extent->y2)
|
||||||
|
break;
|
||||||
|
RegionInitBoxes(&repeat_region, valid_repeat_box, 1);
|
||||||
|
DEBUGF("start to clip repeat[reflect] region: \n");
|
||||||
|
DEBUGRegionPrint(&repeat_region);
|
||||||
|
RegionIntersect(&temp_region, &repeat_region, region);
|
||||||
|
DEBUGF("result:\n");
|
||||||
|
DEBUGRegionPrint(&temp_region);
|
||||||
|
if (is_transform && RegionNumRects(&temp_region)) {
|
||||||
|
BoxRec temp_box;
|
||||||
|
BoxPtr temp_extent;
|
||||||
|
temp_extent = RegionExtents(&temp_region);
|
||||||
|
if (priv->block_wcnt > 1) {
|
||||||
|
if (x_idx & 1) {
|
||||||
|
temp_box.x1 = ((2 * x_idx + 1)*dx - temp_extent->x2);
|
||||||
|
temp_box.x2 = ((2 * x_idx + 1)*dx - temp_extent->x1);
|
||||||
|
} else {
|
||||||
|
temp_box.x1 = temp_extent->x1;
|
||||||
|
temp_box.x2 = temp_extent->x2;
|
||||||
|
}
|
||||||
|
modulus(temp_box.x1, pixmap_width, temp_box.x1);
|
||||||
|
modulus(temp_box.x2, pixmap_width, temp_box.x2);
|
||||||
|
if (temp_box.x2 == 0) temp_box.x2 = pixmap_width;
|
||||||
|
} else {
|
||||||
|
temp_box.x1 = temp_extent->x1;
|
||||||
|
temp_box.x2 = temp_extent->x2;
|
||||||
|
_glamor_largepixmap_reflect_fixup(&temp_box.x1, &temp_box.x2, pixmap_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->block_hcnt > 1) {
|
||||||
|
if (y_idx & 1) {
|
||||||
|
temp_box.y1 = ((2 * y_idx + 1)*dy - temp_extent->y2);
|
||||||
|
temp_box.y2 = ((2 * y_idx + 1)*dy - temp_extent->y1);
|
||||||
|
} else {
|
||||||
|
temp_box.y1 = temp_extent->y1;
|
||||||
|
temp_box.y2 = temp_extent->y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
modulus(temp_box.y1, pixmap_height, temp_box.y1);
|
||||||
|
modulus(temp_box.y2, pixmap_height, temp_box.y2);
|
||||||
|
if (temp_box.y2 == 0) temp_box.y2 = pixmap_height;
|
||||||
|
} else {
|
||||||
|
temp_box.y1 = temp_extent->y1;
|
||||||
|
temp_box.y2 = temp_extent->y2;
|
||||||
|
_glamor_largepixmap_reflect_fixup(&temp_box.y1, &temp_box.y2, pixmap_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionInitBoxes(&temp_region, &temp_box, 1);
|
||||||
|
RegionTranslate(&temp_region, x_center_shift * pixmap_width, y_center_shift * pixmap_height);
|
||||||
|
DEBUGF("for transform result:\n");
|
||||||
|
DEBUGRegionPrint(&temp_region);
|
||||||
|
}
|
||||||
|
RegionAppend(current_region, &temp_region);
|
||||||
|
RegionUninit(&repeat_region);
|
||||||
|
y_idx++;
|
||||||
|
}
|
||||||
|
x_idx++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DEBUGF("dx %d dy %d \n", dx, dy);
|
DEBUGF("dx %d dy %d \n", dx, dy);
|
||||||
|
|
||||||
if (RegionNumRects(current_region)) {
|
if (RegionNumRects(current_region)) {
|
||||||
|
|
||||||
if ((right_shift != 0 || down_shift != 0))
|
if ((right_shift != 0 || down_shift != 0) && !(is_transform && repeat_type == RepeatReflect))
|
||||||
RegionTranslate(current_region,
|
RegionTranslate(current_region,
|
||||||
-right_shift * pixmap_width,
|
-right_shift * pixmap_width,
|
||||||
-down_shift * pixmap_height);
|
-down_shift * pixmap_height);
|
||||||
|
@ -411,6 +598,323 @@ glamor_compute_clipped_regions(glamor_pixmap_private *priv, RegionPtr region, in
|
||||||
return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0);
|
return _glamor_compute_clipped_regions(priv, region, n_region, repeat_type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX overflow still exist. maybe we need to change to use region32.
|
||||||
|
* by default. Or just use region32 for repeat cases?
|
||||||
|
**/
|
||||||
|
glamor_pixmap_clipped_regions *
|
||||||
|
glamor_compute_transform_clipped_regions(glamor_pixmap_private *priv, struct pixman_transform *transform,
|
||||||
|
RegionPtr region, int *n_region, int dx, int dy, int repeat_type)
|
||||||
|
{
|
||||||
|
BoxPtr temp_extent;
|
||||||
|
struct pixman_box32 temp_box;
|
||||||
|
struct pixman_box16 short_box;
|
||||||
|
RegionPtr temp_region;
|
||||||
|
glamor_pixmap_clipped_regions *ret;
|
||||||
|
|
||||||
|
temp_region = RegionCreate(NULL, 4);
|
||||||
|
temp_extent = RegionExtents(region);
|
||||||
|
DEBUGF("dest region \n");
|
||||||
|
DEBUGRegionPrint(region);
|
||||||
|
/* dx/dy may exceed MAX SHORT. we have to use
|
||||||
|
* a box32 to represent it.*/
|
||||||
|
temp_box.x1 = temp_extent->x1 + dx;
|
||||||
|
temp_box.x2 = temp_extent->x2 + dx;
|
||||||
|
temp_box.y1 = temp_extent->y1 + dy;
|
||||||
|
temp_box.y2 = temp_extent->y2 + dy;
|
||||||
|
|
||||||
|
DEBUGF("source box %d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2);
|
||||||
|
if (transform)
|
||||||
|
glamor_get_transform_extent_from_box(&temp_box, transform);
|
||||||
|
if (repeat_type == RepeatNone) {
|
||||||
|
if (temp_box.x1 < 0) temp_box.x1 = 0;
|
||||||
|
if (temp_box.y1 < 0) temp_box.y1 = 0;
|
||||||
|
temp_box.x2 = MIN(temp_box.x2, priv->base.pixmap->drawable.width);
|
||||||
|
temp_box.y2 = MIN(temp_box.y2, priv->base.pixmap->drawable.height);
|
||||||
|
}
|
||||||
|
/* Now copy back the box32 to a box16 box. */
|
||||||
|
short_box.x1 = temp_box.x1;
|
||||||
|
short_box.y1 = temp_box.y1;
|
||||||
|
short_box.x2 = temp_box.x2;
|
||||||
|
short_box.y2 = temp_box.y2;
|
||||||
|
RegionInitBoxes(temp_region, &short_box, 1);
|
||||||
|
DEBUGF("copy to temp source region \n");
|
||||||
|
DEBUGRegionPrint(temp_region);
|
||||||
|
ret = _glamor_compute_clipped_regions(priv,
|
||||||
|
temp_region,
|
||||||
|
n_region,
|
||||||
|
repeat_type,
|
||||||
|
1);
|
||||||
|
DEBUGF("n_regions = %d \n", *n_region);
|
||||||
|
RegionDestroy(temp_region);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* As transform and repeatpad mode.
|
||||||
|
* We may get a clipped result which in multipe regions.
|
||||||
|
* It's not easy to do a 2nd round clipping just as we do
|
||||||
|
* without transform/repeatPad. As it's not easy to reverse
|
||||||
|
* the 2nd round clipping result with a transform/repeatPad mode,
|
||||||
|
* or even impossible for some transformation.
|
||||||
|
*
|
||||||
|
* So we have to merge the fragmental region into one region
|
||||||
|
* if the clipped result cross the region boundary.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
glamor_merge_clipped_regions(glamor_pixmap_private *pixmap_priv, int repeat_type,
|
||||||
|
glamor_pixmap_clipped_regions *clipped_regions,
|
||||||
|
int *n_regions, int *need_clean_fbo)
|
||||||
|
{
|
||||||
|
BoxPtr temp_extent;
|
||||||
|
BoxRec temp_box, copy_box;
|
||||||
|
RegionPtr temp_region;
|
||||||
|
glamor_pixmap_private *temp_priv;
|
||||||
|
PixmapPtr temp_pixmap;
|
||||||
|
int overlap;
|
||||||
|
int i;
|
||||||
|
int pixmap_width, pixmap_height;
|
||||||
|
glamor_pixmap_private_large_t *priv;
|
||||||
|
|
||||||
|
priv = &pixmap_priv->large;
|
||||||
|
pixmap_width = priv->base.pixmap->drawable.width;
|
||||||
|
pixmap_height = priv->base.pixmap->drawable.height;
|
||||||
|
|
||||||
|
temp_region = RegionCreate(NULL, 4);
|
||||||
|
for(i = 0; i < *n_regions; i++)
|
||||||
|
{
|
||||||
|
DEBUGF("Region %d:\n", i);
|
||||||
|
DEBUGRegionPrint(clipped_regions[i].region);
|
||||||
|
RegionAppend(temp_region, clipped_regions[i].region);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegionValidate(temp_region, &overlap);
|
||||||
|
DEBUGF("temp region: \n");
|
||||||
|
DEBUGRegionPrint(temp_region);
|
||||||
|
temp_extent = RegionExtents(temp_region);
|
||||||
|
|
||||||
|
temp_box = *temp_extent;
|
||||||
|
|
||||||
|
DEBUGF("need copy region: \n");
|
||||||
|
DEBUGF("%d %d %d %d \n", temp_box.x1, temp_box.y1, temp_box.x2, temp_box.y2);
|
||||||
|
temp_pixmap = glamor_create_pixmap(priv->base.pixmap->drawable.pScreen,
|
||||||
|
temp_box.x2 - temp_box.x1,
|
||||||
|
temp_box.y2 - temp_box.y1,
|
||||||
|
priv->base.pixmap->drawable.depth,
|
||||||
|
GLAMOR_CREATE_PIXMAP_FIXUP);
|
||||||
|
if (temp_pixmap == NULL) {
|
||||||
|
assert(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_priv = glamor_get_pixmap_private(temp_pixmap);
|
||||||
|
assert(temp_priv->type != GLAMOR_TEXTURE_LARGE);
|
||||||
|
|
||||||
|
priv->box = temp_box;
|
||||||
|
if (temp_extent->x1 >= 0 && temp_extent->x2 <= pixmap_width
|
||||||
|
&& temp_extent->y1 >= 0 && temp_extent->y2 <= pixmap_height) {
|
||||||
|
int dx, dy;
|
||||||
|
copy_box.x1 = 0;
|
||||||
|
copy_box.y1 = 0;
|
||||||
|
copy_box.x2 = temp_extent->x2 - temp_extent->x1;
|
||||||
|
copy_box.y2 = temp_extent->y2 - temp_extent->y1;
|
||||||
|
dx = temp_extent->x1;
|
||||||
|
dy = temp_extent->y1;
|
||||||
|
glamor_copy_n_to_n(&priv->base.pixmap->drawable,
|
||||||
|
&temp_pixmap->drawable,
|
||||||
|
NULL, ©_box, 1, dx,
|
||||||
|
dy, 0, 0, 0, NULL);
|
||||||
|
// glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
|
||||||
|
// temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff00);
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < *n_regions; i++)
|
||||||
|
{
|
||||||
|
BoxPtr box;
|
||||||
|
int nbox;
|
||||||
|
box = REGION_RECTS(clipped_regions[i].region);
|
||||||
|
nbox = REGION_NUM_RECTS(clipped_regions[i].region);
|
||||||
|
while(nbox--) {
|
||||||
|
int dx, dy, c, d;
|
||||||
|
DEBUGF("box x1 %d y1 %d x2 %d y2 %d \n",
|
||||||
|
box->x1, box->y1, box->x2, box->y2);
|
||||||
|
modulus(box->x1, pixmap_width, c);
|
||||||
|
dx = c - (box->x1 - temp_box.x1);
|
||||||
|
copy_box.x1 = box->x1 - temp_box.x1;
|
||||||
|
copy_box.x2 = box->x2 - temp_box.x1;
|
||||||
|
|
||||||
|
modulus(box->y1, pixmap_height, d);
|
||||||
|
dy = d - (box->y1 - temp_box.y1);
|
||||||
|
copy_box.y1 = box->y1 - temp_box.y1;
|
||||||
|
copy_box.y2 = box->y2 - temp_box.y1;
|
||||||
|
|
||||||
|
DEBUGF("copying box %d %d %d %d, dx %d dy %d\n",
|
||||||
|
copy_box.x1, copy_box.y1, copy_box.x2,
|
||||||
|
copy_box.y2, dx, dy);
|
||||||
|
|
||||||
|
glamor_copy_n_to_n(&priv->base.pixmap->drawable,
|
||||||
|
&temp_pixmap->drawable,
|
||||||
|
NULL, ©_box, 1, dx,
|
||||||
|
dy, 0, 0, 0, NULL);
|
||||||
|
box++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//glamor_solid(temp_pixmap, 0, 0, temp_pixmap->drawable.width,
|
||||||
|
// temp_pixmap->drawable.height, GXcopy, 0xffffffff, 0xff);
|
||||||
|
}
|
||||||
|
/* The first region will be released at caller side. */
|
||||||
|
for(i = 1; i < *n_regions; i++)
|
||||||
|
RegionDestroy(clipped_regions[i].region);
|
||||||
|
RegionDestroy(temp_region);
|
||||||
|
priv->box = temp_box;
|
||||||
|
priv->base.fbo = glamor_pixmap_detach_fbo(temp_priv);
|
||||||
|
DEBUGF("priv box x1 %d y1 %d x2 %d y2 %d \n",
|
||||||
|
priv->box.x1, priv->box.y1, priv->box.x2, priv->box.y2);
|
||||||
|
glamor_destroy_pixmap(temp_pixmap);
|
||||||
|
*need_clean_fbo = 1;
|
||||||
|
*n_regions = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an expected transformed block width and block height,
|
||||||
|
*
|
||||||
|
* This function calculate a new block width and height which
|
||||||
|
* guarantee the transform result will not exceed the given
|
||||||
|
* block width and height.
|
||||||
|
*
|
||||||
|
* For large block width and height (> 2048), we choose a
|
||||||
|
* smaller new width and height and to reduce the cross region
|
||||||
|
* boundary and can avoid some overhead.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
Bool
|
||||||
|
glamor_get_transform_block_size(struct pixman_transform *transform,
|
||||||
|
int block_w, int block_h,
|
||||||
|
int *transformed_block_w,
|
||||||
|
int *transformed_block_h)
|
||||||
|
{
|
||||||
|
double a,b,c,d,e,f,g,h;
|
||||||
|
double scale;
|
||||||
|
int width, height;
|
||||||
|
a = pixman_fixed_to_double(transform->matrix[0][0]);
|
||||||
|
b = pixman_fixed_to_double(transform->matrix[0][1]);
|
||||||
|
c = pixman_fixed_to_double(transform->matrix[1][0]);
|
||||||
|
d = pixman_fixed_to_double(transform->matrix[1][1]);
|
||||||
|
scale = pixman_fixed_to_double(transform->matrix[2][2]);
|
||||||
|
if (block_w > 2048) {
|
||||||
|
/* For large block size, we shrink it to smaller box,
|
||||||
|
* thus latter we may get less cross boundary regions and
|
||||||
|
* thus can avoid some extra copy.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
width = block_w / 4;
|
||||||
|
height = block_h / 4;
|
||||||
|
} else {
|
||||||
|
width = block_w - 2;
|
||||||
|
height = block_h - 2;
|
||||||
|
}
|
||||||
|
e = a + b;
|
||||||
|
f = c + d;
|
||||||
|
|
||||||
|
g = a - b;
|
||||||
|
h = c - d;
|
||||||
|
|
||||||
|
e = MIN(block_w, floor(width * scale) / MAX(fabs(e), fabs(g)));
|
||||||
|
f = MIN(block_h, floor(height * scale) / MAX(fabs(f), fabs(h)));
|
||||||
|
*transformed_block_w = MIN(e, f) - 1;
|
||||||
|
*transformed_block_h = *transformed_block_w;
|
||||||
|
if (*transformed_block_w <= 0 || *transformed_block_h <= 0)
|
||||||
|
return FALSE;
|
||||||
|
DEBUGF("original block_w/h %d %d, fixed %d %d \n", block_w, block_h,
|
||||||
|
*transformed_block_w, *transformed_block_h);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VECTOR_FROM_POINT(p, x, y) \
|
||||||
|
p.v[0] = x; \
|
||||||
|
p.v[1] = y; \
|
||||||
|
p.v[2] = 1.0;
|
||||||
|
void
|
||||||
|
glamor_get_transform_extent_from_box(struct pixman_box32 *box,
|
||||||
|
struct pixman_transform *transform)
|
||||||
|
{
|
||||||
|
struct pixman_f_vector p0, p1, p2, p3;
|
||||||
|
float min_x, min_y, max_x, max_y;
|
||||||
|
|
||||||
|
struct pixman_f_transform ftransform;
|
||||||
|
|
||||||
|
VECTOR_FROM_POINT(p0, box->x1, box->y1)
|
||||||
|
VECTOR_FROM_POINT(p1, box->x2, box->y1)
|
||||||
|
VECTOR_FROM_POINT(p2, box->x2, box->y2)
|
||||||
|
VECTOR_FROM_POINT(p3, box->x1, box->y2)
|
||||||
|
|
||||||
|
pixman_f_transform_from_pixman_transform(&ftransform, transform);
|
||||||
|
pixman_f_transform_point(&ftransform, &p0);
|
||||||
|
pixman_f_transform_point(&ftransform, &p1);
|
||||||
|
pixman_f_transform_point(&ftransform, &p2);
|
||||||
|
pixman_f_transform_point(&ftransform, &p3);
|
||||||
|
|
||||||
|
min_x = MIN(p0.v[0], p1.v[0]);
|
||||||
|
min_x = MIN(min_x, p2.v[0]);
|
||||||
|
min_x = MIN(min_x, p3.v[0]);
|
||||||
|
|
||||||
|
min_y = MIN(p0.v[1], p1.v[1]);
|
||||||
|
min_y = MIN(min_y, p2.v[1]);
|
||||||
|
min_y = MIN(min_y, p3.v[1]);
|
||||||
|
|
||||||
|
max_x = MAX(p0.v[0], p1.v[0]);
|
||||||
|
max_x = MAX(max_x, p2.v[0]);
|
||||||
|
max_x = MAX(max_x, p3.v[0]);
|
||||||
|
|
||||||
|
max_y = MAX(p0.v[1], p1.v[1]);
|
||||||
|
max_y = MAX(max_y, p2.v[1]);
|
||||||
|
max_y = MAX(max_y, p3.v[1]);
|
||||||
|
box->x1 = floor(min_x) - 1;
|
||||||
|
box->y1 = floor(min_y) - 1;
|
||||||
|
box->x2 = ceil(max_x) + 1;
|
||||||
|
box->y2 = ceil(max_y) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_glamor_process_transformed_clipped_region(glamor_pixmap_private *priv,
|
||||||
|
int repeat_type,
|
||||||
|
glamor_pixmap_clipped_regions *clipped_regions,
|
||||||
|
int *n_regions, int *need_clean_fbo)
|
||||||
|
{
|
||||||
|
int shift_x, shift_y;
|
||||||
|
if (*n_regions != 1) {
|
||||||
|
/* Merge all source regions into one region. */
|
||||||
|
glamor_merge_clipped_regions(priv, repeat_type,
|
||||||
|
clipped_regions, n_regions,
|
||||||
|
need_clean_fbo);
|
||||||
|
} else {
|
||||||
|
SET_PIXMAP_FBO_CURRENT(priv,
|
||||||
|
clipped_regions[0].block_idx);
|
||||||
|
if (repeat_type == RepeatReflect || repeat_type == RepeatNormal) {
|
||||||
|
/* The required source areas are in one region,
|
||||||
|
* we need to shift the corresponding box's coords to proper position,
|
||||||
|
* thus we can calculate the relative coords correctly.*/
|
||||||
|
BoxPtr temp_box;
|
||||||
|
int rem;
|
||||||
|
temp_box = RegionExtents(clipped_regions[0].region);
|
||||||
|
modulus(temp_box->x1, priv->base.pixmap->drawable.width, rem);
|
||||||
|
shift_x = (temp_box->x1 - rem) / priv->base.pixmap->drawable.width;
|
||||||
|
modulus(temp_box->y1, priv->base.pixmap->drawable.height, rem);
|
||||||
|
shift_y = (temp_box->y1 - rem) / priv->base.pixmap->drawable.height;
|
||||||
|
|
||||||
|
if (shift_x != 0) {
|
||||||
|
priv->large.box.x1 += shift_x * priv->base.pixmap->drawable.width;
|
||||||
|
priv->large.box.x2 += shift_x * priv->base.pixmap->drawable.width;
|
||||||
|
}
|
||||||
|
if (shift_y != 0) {
|
||||||
|
priv->large.box.y1 += shift_y * priv->base.pixmap->drawable.height;
|
||||||
|
priv->large.box.y2 += shift_y * priv->base.pixmap->drawable.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
glamor_composite_largepixmap_region(CARD8 op,
|
glamor_composite_largepixmap_region(CARD8 op,
|
||||||
PicturePtr source,
|
PicturePtr source,
|
||||||
|
@ -448,21 +952,11 @@ glamor_composite_largepixmap_region(CARD8 op,
|
||||||
PixmapPtr mask_pixmap = NULL;
|
PixmapPtr mask_pixmap = NULL;
|
||||||
int ok = TRUE;
|
int ok = TRUE;
|
||||||
|
|
||||||
if (source_pixmap_priv) {
|
if (source_pixmap_priv)
|
||||||
source_pixmap = source_pixmap_priv->base.pixmap;
|
source_pixmap = source_pixmap_priv->base.pixmap;
|
||||||
if (source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
|
||||||
&& (source->transform
|
|
||||||
|| source->repeatType != RepeatNone))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask_pixmap_priv) {
|
if (mask_pixmap_priv)
|
||||||
mask_pixmap = mask_pixmap_priv->base.pixmap;
|
mask_pixmap = mask_pixmap_priv->base.pixmap;
|
||||||
if (mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE
|
|
||||||
&& (mask->transform
|
|
||||||
|| mask->repeatType != RepeatNone))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source->repeat)
|
if (source->repeat)
|
||||||
source_repeat_type = source->repeatType;
|
source_repeat_type = source->repeatType;
|
||||||
|
@ -477,10 +971,68 @@ glamor_composite_largepixmap_region(CARD8 op,
|
||||||
glamor_priv = dest_pixmap_priv->base.glamor_priv;
|
glamor_priv = dest_pixmap_priv->base.glamor_priv;
|
||||||
fixed_block_width = glamor_priv->max_fbo_size;
|
fixed_block_width = glamor_priv->max_fbo_size;
|
||||||
fixed_block_height = glamor_priv->max_fbo_size;
|
fixed_block_height = glamor_priv->max_fbo_size;
|
||||||
|
/* If we got an totally out-of-box region for a source or mask
|
||||||
|
* region without repeat, we need to set it as null_source and
|
||||||
|
* give it a solid color (0,0,0,0). */
|
||||||
|
null_source = 0;
|
||||||
|
null_mask = 0;
|
||||||
RegionTranslate(region, -dest->pDrawable->x,
|
RegionTranslate(region, -dest->pDrawable->x,
|
||||||
-dest->pDrawable->y);
|
-dest->pDrawable->y);
|
||||||
|
|
||||||
if (force_clip)
|
/* need to transform the dest region to the correct sourcei/mask region.
|
||||||
|
* it's a little complex, as one single edge of the
|
||||||
|
* target region may be transformed to cross a block boundary of the
|
||||||
|
* source or mask. Then it's impossible to handle it as usual way.
|
||||||
|
* We may have to split the original dest region to smaller region, and
|
||||||
|
* make sure each region's transformed region can fit into one texture,
|
||||||
|
* and then continue this loop again, and each time when a transformed region
|
||||||
|
* cross the bound, we need to copy it to a single pixmap and do the composition
|
||||||
|
* with the new pixmap. If the transformed region doesn't cross a source/mask's
|
||||||
|
* boundary then we don't need to copy.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (source_pixmap_priv
|
||||||
|
&& source->transform
|
||||||
|
&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
int source_transformed_block_width, source_transformed_block_height;
|
||||||
|
if (!glamor_get_transform_block_size(source->transform,
|
||||||
|
source_pixmap_priv->large.block_w,
|
||||||
|
source_pixmap_priv->large.block_h,
|
||||||
|
&source_transformed_block_width,
|
||||||
|
&source_transformed_block_height)) {
|
||||||
|
DEBUGF("source block size less than 1, fallback.\n");
|
||||||
|
RegionTranslate(region, dest->pDrawable->x,
|
||||||
|
dest->pDrawable->y);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fixed_block_width = min(fixed_block_width , source_transformed_block_width);
|
||||||
|
fixed_block_height = min(fixed_block_height , source_transformed_block_height);
|
||||||
|
DEBUGF("new source block size %d x %d \n", fixed_block_width, fixed_block_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask_pixmap_priv
|
||||||
|
&& mask->transform
|
||||||
|
&& mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
int mask_transformed_block_width, mask_transformed_block_height;
|
||||||
|
if (!glamor_get_transform_block_size(mask->transform,
|
||||||
|
mask_pixmap_priv->large.block_w,
|
||||||
|
mask_pixmap_priv->large.block_h,
|
||||||
|
&mask_transformed_block_width,
|
||||||
|
&mask_transformed_block_height)) {
|
||||||
|
DEBUGF("mask block size less than 1, fallback.\n");
|
||||||
|
RegionTranslate(region, dest->pDrawable->x,
|
||||||
|
dest->pDrawable->y);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fixed_block_width = min(fixed_block_width , mask_transformed_block_width);
|
||||||
|
fixed_block_height = min(fixed_block_height , mask_transformed_block_height);
|
||||||
|
DEBUGF("new mask block size %d x %d \n", fixed_block_width, fixed_block_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*compute the correct block width and height whose transformed source/mask
|
||||||
|
*region can fit into one texture.*/
|
||||||
|
if (force_clip || fixed_block_width < glamor_priv->max_fbo_size
|
||||||
|
|| fixed_block_height < glamor_priv->max_fbo_size)
|
||||||
clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap_priv,
|
clipped_dest_regions = glamor_compute_clipped_regions_ext(dest_pixmap_priv,
|
||||||
region,
|
region,
|
||||||
&n_dest_regions,
|
&n_dest_regions,
|
||||||
|
@ -492,93 +1044,238 @@ glamor_composite_largepixmap_region(CARD8 op,
|
||||||
&n_dest_regions,
|
&n_dest_regions,
|
||||||
0);
|
0);
|
||||||
DEBUGF("dest clipped result %d region: \n", n_dest_regions);
|
DEBUGF("dest clipped result %d region: \n", n_dest_regions);
|
||||||
|
if (source_pixmap_priv == dest_pixmap_priv
|
||||||
|
&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
/* XXX self-copy...*/
|
||||||
|
need_free_source_pixmap_priv = source_pixmap_priv;
|
||||||
|
source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
|
||||||
|
*source_pixmap_priv = *need_free_source_pixmap_priv;
|
||||||
|
need_free_source_pixmap_priv = source_pixmap_priv;
|
||||||
|
}
|
||||||
for(i = 0; i < n_dest_regions; i++)
|
for(i = 0; i < n_dest_regions; i++)
|
||||||
{
|
{
|
||||||
DEBUGF("dest region %d idx %d\n", i, clipped_dest_regions[i].block_idx);
|
DEBUGF("dest region %d idx %d\n", i, clipped_dest_regions[i].block_idx);
|
||||||
DEBUGRegionPrint(clipped_dest_regions[i].region);
|
DEBUGRegionPrint(clipped_dest_regions[i].region);
|
||||||
SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv, clipped_dest_regions[i].block_idx);
|
SET_PIXMAP_FBO_CURRENT(dest_pixmap_priv, clipped_dest_regions[i].block_idx);
|
||||||
if ( source_pixmap_priv && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
if ( source_pixmap_priv && source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
|
if (!source->transform && source_repeat_type != RepeatPad) {
|
||||||
RegionTranslate(clipped_dest_regions[i].region,
|
RegionTranslate(clipped_dest_regions[i].region,
|
||||||
x_source - x_dest,
|
x_source - x_dest,
|
||||||
y_source - y_dest);
|
y_source - y_dest);
|
||||||
clipped_source_regions = glamor_compute_clipped_regions(source_pixmap_priv,
|
clipped_source_regions = glamor_compute_clipped_regions(source_pixmap_priv,
|
||||||
clipped_dest_regions[i].region,
|
clipped_dest_regions[i].region,
|
||||||
&n_source_regions, source_repeat_type);
|
&n_source_regions, source_repeat_type);
|
||||||
|
is_normal_source_fbo = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clipped_source_regions = glamor_compute_transform_clipped_regions(source_pixmap_priv,
|
||||||
|
source->transform,
|
||||||
|
clipped_dest_regions[i].region,
|
||||||
|
&n_source_regions,
|
||||||
|
x_source - x_dest, y_source - y_dest,
|
||||||
|
source_repeat_type);
|
||||||
|
is_normal_source_fbo = 0;
|
||||||
|
if (n_source_regions == 0) {
|
||||||
|
/* Pad the out-of-box region to (0,0,0,0). */
|
||||||
|
null_source = 1;
|
||||||
|
n_source_regions = 1;
|
||||||
|
} else
|
||||||
|
_glamor_process_transformed_clipped_region(source_pixmap_priv,
|
||||||
|
source_repeat_type, clipped_source_regions, &n_source_regions,
|
||||||
|
&need_clean_source_fbo);
|
||||||
|
}
|
||||||
DEBUGF("source clipped result %d region: \n", n_source_regions);
|
DEBUGF("source clipped result %d region: \n", n_source_regions);
|
||||||
for(j = 0; j < n_source_regions; j++)
|
for(j = 0; j < n_source_regions; j++)
|
||||||
{
|
{
|
||||||
SET_PIXMAP_FBO_CURRENT(source_pixmap_priv,
|
if (is_normal_source_fbo)
|
||||||
clipped_source_regions[j].block_idx);
|
SET_PIXMAP_FBO_CURRENT(source_pixmap_priv,
|
||||||
|
clipped_source_regions[j].block_idx);
|
||||||
|
|
||||||
if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
DEBUGF("source region %d idx %d\n", j, clipped_source_regions[j].block_idx);
|
if (is_normal_mask_fbo && is_normal_source_fbo) {
|
||||||
DEBUGRegionPrint(clipped_source_regions[j].region);
|
/* both mask and source are normal fbo box without transform or repeatpad.
|
||||||
RegionTranslate(clipped_source_regions[j].region,
|
* The region is clipped against source and then we clip it against mask here.*/
|
||||||
- x_source + x_mask,
|
DEBUGF("source region %d idx %d\n", j, clipped_source_regions[j].block_idx);
|
||||||
|
DEBUGRegionPrint(clipped_source_regions[j].region);
|
||||||
|
RegionTranslate(clipped_source_regions[j].region,
|
||||||
|
- x_source + x_mask,
|
||||||
- y_source + y_mask);
|
- y_source + y_mask);
|
||||||
clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
|
clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
|
||||||
clipped_source_regions[j].region,
|
clipped_source_regions[j].region,
|
||||||
&n_mask_regions, mask_repeat_type);
|
&n_mask_regions, mask_repeat_type);
|
||||||
|
is_normal_mask_fbo = 1;
|
||||||
|
} else if (is_normal_mask_fbo && !is_normal_source_fbo) {
|
||||||
|
assert(n_source_regions == 1);
|
||||||
|
/* The source fbo is not a normal fbo box, it has transform or repeatpad.
|
||||||
|
* the valid clip region should be the clip dest region rather than the
|
||||||
|
* clip source region.*/
|
||||||
|
RegionTranslate(clipped_dest_regions[i].region,
|
||||||
|
- x_dest + x_mask,
|
||||||
|
- y_dest + y_mask);
|
||||||
|
clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
|
||||||
|
clipped_dest_regions[i].region,
|
||||||
|
&n_mask_regions, mask_repeat_type);
|
||||||
|
is_normal_mask_fbo = 1;
|
||||||
|
} else {
|
||||||
|
/* This mask region has transform or repeatpad, we need clip it agains the previous
|
||||||
|
* valid region rather than the mask region. */
|
||||||
|
if (!is_normal_source_fbo)
|
||||||
|
clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
|
||||||
|
mask->transform,
|
||||||
|
clipped_dest_regions[i].region,
|
||||||
|
&n_mask_regions,
|
||||||
|
x_mask - x_dest,
|
||||||
|
y_mask - y_dest,
|
||||||
|
mask_repeat_type);
|
||||||
|
else
|
||||||
|
clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
|
||||||
|
mask->transform,
|
||||||
|
clipped_source_regions[j].region,
|
||||||
|
&n_mask_regions,
|
||||||
|
x_mask - x_source, y_mask - y_source,
|
||||||
|
mask_repeat_type);
|
||||||
|
is_normal_mask_fbo = 0;
|
||||||
|
if (n_mask_regions == 0) {
|
||||||
|
/* Pad the out-of-box region to (0,0,0,0). */
|
||||||
|
null_mask = 1;
|
||||||
|
n_mask_regions = 1;
|
||||||
|
} else
|
||||||
|
_glamor_process_transformed_clipped_region(mask_pixmap_priv,
|
||||||
|
mask_repeat_type, clipped_mask_regions, &n_mask_regions,
|
||||||
|
&need_clean_mask_fbo);
|
||||||
|
}
|
||||||
DEBUGF("mask clipped result %d region: \n", n_mask_regions);
|
DEBUGF("mask clipped result %d region: \n", n_mask_regions);
|
||||||
|
|
||||||
#define COMPOSITE_REGION(region) do { \
|
#define COMPOSITE_REGION(region) do { \
|
||||||
if (!glamor_composite_clipped_region(op, \
|
if (!glamor_composite_clipped_region(op, \
|
||||||
source, \
|
null_source ? NULL : source, \
|
||||||
mask, dest, region, \
|
null_mask ? NULL : mask, dest, region, \
|
||||||
x_source, y_source, x_mask, y_mask, \
|
x_source, y_source, x_mask, y_mask, \
|
||||||
x_dest, y_dest)) { \
|
x_dest, y_dest)) { \
|
||||||
assert(0); \
|
assert(0); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
for(k = 0; k < n_mask_regions; k++)
|
for(k = 0; k < n_mask_regions; k++)
|
||||||
{
|
{
|
||||||
DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx);
|
DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx);
|
||||||
DEBUGRegionPrint(clipped_mask_regions[k].region);
|
DEBUGRegionPrint(clipped_mask_regions[k].region);
|
||||||
SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
|
if (is_normal_mask_fbo) {
|
||||||
clipped_mask_regions[k].block_idx);
|
SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
|
||||||
DEBUGF("mask fbo off %d %d \n",
|
clipped_mask_regions[k].block_idx);
|
||||||
mask_pixmap_priv->large.box.x1,
|
DEBUGF("mask fbo off %d %d \n",
|
||||||
mask_pixmap_priv->large.box.y1);
|
mask_pixmap_priv->large.box.x1,
|
||||||
DEBUGF("start composite mask hasn't transform.\n");
|
mask_pixmap_priv->large.box.y1);
|
||||||
RegionTranslate(clipped_mask_regions[k].region,
|
DEBUGF("start composite mask hasn't transform.\n");
|
||||||
x_dest - x_mask + dest->pDrawable->x,
|
RegionTranslate(clipped_mask_regions[k].region,
|
||||||
y_dest - y_mask + dest->pDrawable->y);
|
x_dest - x_mask + dest->pDrawable->x,
|
||||||
COMPOSITE_REGION(clipped_mask_regions[k].region);
|
y_dest - y_mask + dest->pDrawable->y);
|
||||||
|
COMPOSITE_REGION(clipped_mask_regions[k].region);
|
||||||
|
} else if (!is_normal_mask_fbo && !is_normal_source_fbo) {
|
||||||
|
DEBUGF("start composite both mask and source have transform.\n");
|
||||||
|
RegionTranslate(clipped_dest_regions[i].region,
|
||||||
|
dest->pDrawable->x,
|
||||||
|
dest->pDrawable->y);
|
||||||
|
COMPOSITE_REGION(clipped_dest_regions[i].region);
|
||||||
|
} else {
|
||||||
|
DEBUGF("start composite only mask has transform.\n");
|
||||||
|
RegionTranslate(clipped_source_regions[j].region,
|
||||||
|
x_dest - x_source + dest->pDrawable->x,
|
||||||
|
y_dest - y_source + dest->pDrawable->y);
|
||||||
|
COMPOSITE_REGION(clipped_source_regions[j].region);
|
||||||
|
}
|
||||||
RegionDestroy(clipped_mask_regions[k].region);
|
RegionDestroy(clipped_mask_regions[k].region);
|
||||||
}
|
}
|
||||||
free(clipped_mask_regions);
|
free(clipped_mask_regions);
|
||||||
|
if (null_mask) null_mask = 0;
|
||||||
|
if (need_clean_mask_fbo) {
|
||||||
|
assert(is_normal_mask_fbo == 0);
|
||||||
|
glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
|
||||||
|
mask_pixmap_priv->base.fbo = NULL;
|
||||||
|
need_clean_mask_fbo = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
RegionTranslate(clipped_source_regions[j].region,
|
if (is_normal_source_fbo) {
|
||||||
-x_source + x_dest + dest->pDrawable->x,
|
RegionTranslate(clipped_source_regions[j].region,
|
||||||
-y_source + y_dest + dest->pDrawable->y);
|
-x_source + x_dest + dest->pDrawable->x,
|
||||||
COMPOSITE_REGION(clipped_source_regions[j].region);
|
-y_source + y_dest + dest->pDrawable->y);
|
||||||
|
COMPOSITE_REGION(clipped_source_regions[j].region);
|
||||||
|
} else {
|
||||||
|
/* Source has transform or repeatPad. dest regions is the right
|
||||||
|
* region to do the composite. */
|
||||||
|
RegionTranslate(clipped_dest_regions[i].region,
|
||||||
|
dest->pDrawable->x,
|
||||||
|
dest->pDrawable->y);
|
||||||
|
COMPOSITE_REGION(clipped_dest_regions[i].region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (clipped_source_regions && clipped_source_regions[j].region)
|
if (clipped_source_regions && clipped_source_regions[j].region)
|
||||||
RegionDestroy(clipped_source_regions[j].region);
|
RegionDestroy(clipped_source_regions[j].region);
|
||||||
}
|
}
|
||||||
free(clipped_source_regions);
|
free(clipped_source_regions);
|
||||||
|
if (null_source) null_source = 0;
|
||||||
|
if (need_clean_source_fbo) {
|
||||||
|
assert(is_normal_source_fbo == 0);
|
||||||
|
glamor_destroy_fbo(source_pixmap_priv->base.fbo);
|
||||||
|
source_pixmap_priv->base.fbo = NULL;
|
||||||
|
need_clean_source_fbo = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
if (mask_pixmap_priv && mask_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
|
||||||
RegionTranslate(clipped_dest_regions[i].region,
|
if (!mask->transform && mask_repeat_type != RepeatPad) {
|
||||||
x_mask - x_dest,
|
RegionTranslate(clipped_dest_regions[i].region,
|
||||||
y_mask - y_dest);
|
x_mask - x_dest,
|
||||||
clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
|
y_mask - y_dest);
|
||||||
clipped_dest_regions[i].region,
|
clipped_mask_regions = glamor_compute_clipped_regions(mask_pixmap_priv,
|
||||||
&n_mask_regions, mask_repeat_type);
|
clipped_dest_regions[i].region,
|
||||||
|
&n_mask_regions, mask_repeat_type);
|
||||||
|
is_normal_mask_fbo = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clipped_mask_regions = glamor_compute_transform_clipped_regions(mask_pixmap_priv,
|
||||||
|
mask->transform,
|
||||||
|
clipped_dest_regions[i].region,
|
||||||
|
&n_mask_regions,
|
||||||
|
x_mask - x_dest, y_mask - y_dest,
|
||||||
|
mask_repeat_type);
|
||||||
|
is_normal_mask_fbo = 0;
|
||||||
|
if (n_mask_regions == 0) {
|
||||||
|
/* Pad the out-of-box region to (0,0,0,0). */
|
||||||
|
null_mask = 1;
|
||||||
|
n_mask_regions = 1;
|
||||||
|
} else
|
||||||
|
_glamor_process_transformed_clipped_region(mask_pixmap_priv,
|
||||||
|
mask_repeat_type, clipped_mask_regions, &n_mask_regions,
|
||||||
|
&need_clean_mask_fbo);
|
||||||
|
}
|
||||||
|
|
||||||
for(k = 0; k < n_mask_regions; k++)
|
for(k = 0; k < n_mask_regions; k++)
|
||||||
{
|
{
|
||||||
DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx);
|
DEBUGF("mask region %d idx %d\n", k, clipped_mask_regions[k].block_idx);
|
||||||
DEBUGRegionPrint(clipped_mask_regions[k].region);
|
DEBUGRegionPrint(clipped_mask_regions[k].region);
|
||||||
SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
|
if (is_normal_mask_fbo) {
|
||||||
clipped_mask_regions[k].block_idx);
|
SET_PIXMAP_FBO_CURRENT(mask_pixmap_priv,
|
||||||
RegionTranslate(clipped_mask_regions[k].region,
|
clipped_mask_regions[k].block_idx);
|
||||||
x_dest - x_mask + dest->pDrawable->x,
|
RegionTranslate(clipped_mask_regions[k].region,
|
||||||
y_dest - y_mask + dest->pDrawable->y);
|
x_dest - x_mask + dest->pDrawable->x,
|
||||||
COMPOSITE_REGION(clipped_mask_regions[k].region);
|
y_dest - y_mask + dest->pDrawable->y);
|
||||||
|
COMPOSITE_REGION(clipped_mask_regions[k].region);
|
||||||
|
} else {
|
||||||
|
RegionTranslate(clipped_dest_regions[i].region,
|
||||||
|
dest->pDrawable->x,
|
||||||
|
dest->pDrawable->y);
|
||||||
|
COMPOSITE_REGION(clipped_dest_regions[i].region);
|
||||||
|
}
|
||||||
RegionDestroy(clipped_mask_regions[k].region);
|
RegionDestroy(clipped_mask_regions[k].region);
|
||||||
}
|
}
|
||||||
free(clipped_mask_regions);
|
free(clipped_mask_regions);
|
||||||
|
if (null_mask) null_mask = 0;
|
||||||
|
if (need_clean_mask_fbo) {
|
||||||
|
glamor_destroy_fbo(mask_pixmap_priv->base.fbo);
|
||||||
|
mask_pixmap_priv->base.fbo = NULL;
|
||||||
|
need_clean_mask_fbo = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RegionTranslate(clipped_dest_regions[i].region,
|
RegionTranslate(clipped_dest_regions[i].region,
|
||||||
|
@ -590,6 +1287,8 @@ glamor_composite_largepixmap_region(CARD8 op,
|
||||||
RegionDestroy(clipped_dest_regions[i].region);
|
RegionDestroy(clipped_dest_regions[i].region);
|
||||||
}
|
}
|
||||||
free(clipped_dest_regions);
|
free(clipped_dest_regions);
|
||||||
|
free(need_free_source_pixmap_priv);
|
||||||
|
free(need_free_mask_pixmap_priv);
|
||||||
ok = TRUE;
|
ok = TRUE;
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -955,7 +955,12 @@ glamor_set_normalize_tcoords_generic(glamor_pixmap_private *priv,
|
||||||
yInverted,
|
yInverted,
|
||||||
texcoords);
|
texcoords);
|
||||||
else if (matrix && repeat_type != RepeatNone)
|
else if (matrix && repeat_type != RepeatNone)
|
||||||
assert(0);
|
glamor_set_repeat_transformed_normalize_tcoords(priv, repeat_type,
|
||||||
|
matrix, xscale, yscale,
|
||||||
|
x1, y1,
|
||||||
|
x2, y2,
|
||||||
|
yInverted,
|
||||||
|
texcoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
@ -1718,9 +1723,9 @@ _glamor_composite(CARD8 op,
|
||||||
extent->x2 - extent->x1, extent->y2 - extent->y1)
|
extent->x2 - extent->x1, extent->y2 - extent->y1)
|
||||||
&& (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
|
&& (dest_pixmap_priv->type != GLAMOR_TEXTURE_LARGE)
|
||||||
&& ((source_pixmap_priv
|
&& ((source_pixmap_priv
|
||||||
&& source_pixmap_priv->type == GLAMOR_MEMORY)
|
&& (source_pixmap_priv->type == GLAMOR_MEMORY || source->repeatType == RepeatPad))
|
||||||
|| (mask_pixmap_priv
|
|| (mask_pixmap_priv
|
||||||
&& mask_pixmap_priv->type == GLAMOR_MEMORY)
|
&& (mask_pixmap_priv->type == GLAMOR_MEMORY || mask->repeatType == RepeatPad))
|
||||||
|| (!source_pixmap_priv
|
|| (!source_pixmap_priv
|
||||||
&& (source->pSourcePict->type != SourcePictTypeSolidFill))
|
&& (source->pSourcePict->type != SourcePictTypeSolidFill))
|
||||||
|| (!mask_pixmap_priv && mask
|
|| (!mask_pixmap_priv && mask
|
||||||
|
@ -1742,7 +1747,6 @@ _glamor_composite(CARD8 op,
|
||||||
x_mask, y_mask,
|
x_mask, y_mask,
|
||||||
x_dest, y_dest,
|
x_dest, y_dest,
|
||||||
width, height);
|
width, height);
|
||||||
|
|
||||||
else
|
else
|
||||||
ok = glamor_composite_clipped_region(op, source,
|
ok = glamor_composite_clipped_region(op, source,
|
||||||
mask, dest, ®ion,
|
mask, dest, ®ion,
|
||||||
|
|
|
@ -39,13 +39,13 @@
|
||||||
#define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_))
|
#define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_))
|
||||||
#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
|
#define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
|
||||||
|
|
||||||
#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)\
|
||||||
do { \
|
do { \
|
||||||
int w,h; \
|
int w,h; \
|
||||||
PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h); \
|
PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h); \
|
||||||
*(_pxscale_) = 1.0 / w; \
|
*(_pxscale_) = 1.0 / w; \
|
||||||
*(_pyscale_) = 1.0 / h; \
|
*(_pyscale_) = 1.0 / h; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -108,24 +108,175 @@
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define fmod(x, w) (x - w * floor((float)x/w))
|
||||||
|
|
||||||
|
#define fmodulus(x, w, c) do {c = fmod(x, w); \
|
||||||
|
c = c >= 0 ? c : c + w;} \
|
||||||
|
while(0)
|
||||||
|
/* @x: is current coord
|
||||||
|
* @x2: is the right/bottom edge
|
||||||
|
* @w: is current width or height
|
||||||
|
* @odd: is output value, 0 means we are in an even region, 1 means we are in a
|
||||||
|
* odd region.
|
||||||
|
* @c: is output value, equal to x mod w. */
|
||||||
|
#define fodd_repeat_mod(x, x2, w, odd, c) \
|
||||||
|
do { \
|
||||||
|
float shift; \
|
||||||
|
fmodulus((x), w, c); \
|
||||||
|
shift = fabs((x) - (c)); \
|
||||||
|
shift = floor(fabs(round(shift)) / w); \
|
||||||
|
odd = (int)shift & 1; \
|
||||||
|
if (odd && (((x2 % w) == 0) && \
|
||||||
|
round(fabs(x)) == x2)) \
|
||||||
|
odd = 0; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/* @txy: output value, is the corrected coords.
|
||||||
|
* @xy: input coords to be fixed up.
|
||||||
|
* @cd: xy mod wh, is a input value.
|
||||||
|
* @wh: current width or height.
|
||||||
|
* @bxy1,bxy2: current box edge's x1/x2 or y1/y2
|
||||||
|
*
|
||||||
|
* case 1:
|
||||||
|
* ----------
|
||||||
|
* | * |
|
||||||
|
* | |
|
||||||
|
* ----------
|
||||||
|
* tx = (c - x1) mod w
|
||||||
|
*
|
||||||
|
* case 2:
|
||||||
|
* ---------
|
||||||
|
* * | |
|
||||||
|
* | |
|
||||||
|
* ---------
|
||||||
|
* tx = - (c - (x1 mod w))
|
||||||
|
*
|
||||||
|
* case 3:
|
||||||
|
*
|
||||||
|
* ----------
|
||||||
|
* | | *
|
||||||
|
* | |
|
||||||
|
* ----------
|
||||||
|
* tx = ((x2 mod x) - c) + (x2 - x1)
|
||||||
|
**/
|
||||||
|
#define __glamor_repeat_reflect_fixup(txy, xy, \
|
||||||
|
cd, wh, bxy1, bxy2) \
|
||||||
|
do { \
|
||||||
|
cd = wh - cd; \
|
||||||
|
if ( xy >= bxy1 && xy < bxy2) { \
|
||||||
|
cd = cd - bxy1; \
|
||||||
|
fmodulus(cd, wh, txy); \
|
||||||
|
} else if (xy < bxy1) { \
|
||||||
|
float bxy1_mod; \
|
||||||
|
fmodulus(bxy1, wh, bxy1_mod); \
|
||||||
|
txy = -(cd - bxy1_mod); \
|
||||||
|
} \
|
||||||
|
else if (xy >= bxy2) { \
|
||||||
|
float bxy2_mod; \
|
||||||
|
fmodulus(bxy2, wh, bxy2_mod); \
|
||||||
|
if (bxy2_mod == 0) \
|
||||||
|
bxy2_mod = wh; \
|
||||||
|
txy = (bxy2_mod - cd) + bxy2 - bxy1; \
|
||||||
|
} else {assert(0); txy = 0;} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define _glamor_repeat_reflect_fixup(txy, xy, cd, odd, \
|
||||||
|
wh, bxy1, bxy2) \
|
||||||
|
do { \
|
||||||
|
if (odd) { \
|
||||||
|
__glamor_repeat_reflect_fixup(txy, xy, \
|
||||||
|
cd, wh, bxy1, bxy2); \
|
||||||
|
} else \
|
||||||
|
txy = xy - bxy1; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define _glamor_get_reflect_transform_coords(priv, repeat_type, \
|
||||||
|
tx1, ty1, \
|
||||||
|
_x1_, _y1_) \
|
||||||
|
do { \
|
||||||
|
int odd_x, odd_y; \
|
||||||
|
float c, d; \
|
||||||
|
fodd_repeat_mod(_x1_,priv->box.x2, \
|
||||||
|
priv->base.pixmap->drawable.width, \
|
||||||
|
odd_x, c); \
|
||||||
|
fodd_repeat_mod(_y1_, priv->box.y2, \
|
||||||
|
priv->base.pixmap->drawable.height, \
|
||||||
|
odd_y, d); \
|
||||||
|
DEBUGF("c %f d %f oddx %d oddy %d \n", \
|
||||||
|
c, d, odd_x, odd_y); \
|
||||||
|
DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2, \
|
||||||
|
priv->box.x1, priv->base.fbo->width); \
|
||||||
|
DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, \
|
||||||
|
priv->box.y1, priv->base.fbo->height); \
|
||||||
|
_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x, \
|
||||||
|
priv->base.pixmap->drawable.width, \
|
||||||
|
priv->box.x1, priv->box.x2); \
|
||||||
|
_glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y, \
|
||||||
|
priv->base.pixmap->drawable.height, \
|
||||||
|
priv->box.y1, priv->box.y2); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#define _glamor_get_repeat_coords(priv, repeat_type, tx1, \
|
#define _glamor_get_repeat_coords(priv, repeat_type, tx1, \
|
||||||
ty1, tx2, ty2, \
|
ty1, tx2, ty2, \
|
||||||
_x1_, _y1_, _x2_, \
|
_x1_, _y1_, _x2_, \
|
||||||
_y2_, c, d, odd_x, odd_y) \
|
_y2_, c, d, odd_x, odd_y) \
|
||||||
do { \
|
do { \
|
||||||
if (repeat_type == RepeatReflect) { \
|
if (repeat_type == RepeatReflect) { \
|
||||||
assert(0); \
|
DEBUGF("x1 y1 %d %d\n", \
|
||||||
|
_x1_, _y1_ ); \
|
||||||
|
DEBUGF("width %d box.x1 %d \n", \
|
||||||
|
(priv)->base.pixmap->drawable.width, \
|
||||||
|
priv->box.x1); \
|
||||||
|
if (odd_x) { \
|
||||||
|
c = (priv)->base.pixmap->drawable.width \
|
||||||
|
- c; \
|
||||||
|
tx1 = c - priv->box.x1; \
|
||||||
|
tx2 = tx1 - ((_x2_) - (_x1_)); \
|
||||||
|
} else { \
|
||||||
|
tx1 = c - priv->box.x1; \
|
||||||
|
tx2 = tx1 + ((_x2_) - (_x1_)); \
|
||||||
|
} \
|
||||||
|
if (odd_y){ \
|
||||||
|
d = (priv)->base.pixmap->drawable.height\
|
||||||
|
- d; \
|
||||||
|
ty1 = d - priv->box.y1; \
|
||||||
|
ty2 = ty1 - ((_y2_) - (_y1_)); \
|
||||||
|
} else { \
|
||||||
|
ty1 = d - priv->box.y1; \
|
||||||
|
ty2 = ty1 + ((_y2_) - (_y1_)); \
|
||||||
|
} \
|
||||||
} else if (repeat_type == RepeatNormal) { \
|
} else if (repeat_type == RepeatNormal) { \
|
||||||
tx1 = (c - priv->box.x1); \
|
tx1 = (c - priv->box.x1); \
|
||||||
ty1 = (d - priv->box.y1); \
|
ty1 = (d - priv->box.y1); \
|
||||||
tx2 = tx1 + ((_x2_) - (_x1_)); \
|
tx2 = tx1 + ((_x2_) - (_x1_)); \
|
||||||
ty2 = ty1 + ((_y2_) - (_y1_)); \
|
ty2 = ty1 + ((_y2_) - (_y1_)); \
|
||||||
} else { \
|
} else { \
|
||||||
assert(0); \
|
tx1 = _x1_ - priv->box.x1; \
|
||||||
|
ty1 = _y1_ - priv->box.y1; \
|
||||||
|
tx2 = tx1 + ((_x2_) - (_x1_)); \
|
||||||
|
ty2 = ty1 + ((_y2_) - (_y1_)); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
/* _x1_ ... _y2_ may has fractional. */
|
||||||
|
#define glamor_get_repeat_transform_coords(priv, repeat_type, tx1, \
|
||||||
|
ty1, _x1_, _y1_) \
|
||||||
|
do { \
|
||||||
|
DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
|
||||||
|
(priv)->base.pixmap->drawable.width, \
|
||||||
|
priv->box.x1, priv->box.x2, priv->box.y1, \
|
||||||
|
priv->box.y2); \
|
||||||
|
DEBUGF("x1 %f y1 %f \n", _x1_, _y1_); \
|
||||||
|
if (repeat_type != RepeatReflect) { \
|
||||||
|
tx1 = _x1_ - priv->box.x1; \
|
||||||
|
ty1 = _y1_ - priv->box.y1; \
|
||||||
|
} else \
|
||||||
|
_glamor_get_reflect_transform_coords(priv, repeat_type, \
|
||||||
|
tx1, ty1, \
|
||||||
|
_x1_, _y1_); \
|
||||||
|
DEBUGF("tx1 %f ty1 %f \n", tx1, ty1); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/* _x1_ ... _y2_ must be integer. */
|
/* _x1_ ... _y2_ must be integer. */
|
||||||
#define glamor_get_repeat_coords(priv, repeat_type, tx1, \
|
#define glamor_get_repeat_coords(priv, repeat_type, tx1, \
|
||||||
|
@ -152,8 +303,6 @@
|
||||||
odd_x, odd_y); \
|
odd_x, odd_y); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define glamor_transform_point(matrix, tx, ty, x, y) \
|
#define glamor_transform_point(matrix, tx, ty, x, y) \
|
||||||
do { \
|
do { \
|
||||||
int i; \
|
int i; \
|
||||||
|
@ -221,6 +370,58 @@
|
||||||
yInverted); \
|
yInverted); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define glamor_set_repeat_transformed_normalize_tcoords( priv, \
|
||||||
|
repeat_type, \
|
||||||
|
matrix, \
|
||||||
|
xscale, \
|
||||||
|
yscale, \
|
||||||
|
_x1_, _y1_, \
|
||||||
|
_x2_, _y2_, \
|
||||||
|
yInverted, \
|
||||||
|
texcoords) \
|
||||||
|
do { \
|
||||||
|
if (priv->type != GLAMOR_TEXTURE_LARGE) { \
|
||||||
|
glamor_set_transformed_normalize_tcoords(priv, matrix, xscale, \
|
||||||
|
yscale, _x1_, _y1_, \
|
||||||
|
_x2_, _y2_, yInverted, \
|
||||||
|
texcoords); \
|
||||||
|
} else { \
|
||||||
|
/* For a large pixmap, if both transform and repeat are set,
|
||||||
|
* the transform must only has x and y scale factor.*/ \
|
||||||
|
float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \
|
||||||
|
float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4; \
|
||||||
|
DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_); \
|
||||||
|
glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_); \
|
||||||
|
glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_); \
|
||||||
|
glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_); \
|
||||||
|
glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \
|
||||||
|
DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \
|
||||||
|
tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \
|
||||||
|
glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
|
||||||
|
ttx1, tty1, \
|
||||||
|
tx1, ty1); \
|
||||||
|
glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
|
||||||
|
ttx2, tty2, \
|
||||||
|
tx2, ty2); \
|
||||||
|
glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
|
||||||
|
ttx3, tty3, \
|
||||||
|
tx3, ty3); \
|
||||||
|
glamor_get_repeat_transform_coords((&priv->large), repeat_type, \
|
||||||
|
ttx4, tty4, \
|
||||||
|
tx4, ty4); \
|
||||||
|
DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \
|
||||||
|
ttx2, tty2, ttx3, tty3, ttx4, tty4); \
|
||||||
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \
|
||||||
|
texcoords, yInverted); \
|
||||||
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \
|
||||||
|
texcoords + 2, yInverted); \
|
||||||
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \
|
||||||
|
texcoords + 4, yInverted); \
|
||||||
|
_glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \
|
||||||
|
texcoords + 6, yInverted); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
|
#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
|
||||||
ty1, tx2, ty2, \
|
ty1, tx2, ty2, \
|
||||||
yInverted, vertices) \
|
yInverted, vertices) \
|
||||||
|
@ -261,6 +462,8 @@
|
||||||
tx2, ty2, yInverted, vertices); \
|
tx2, ty2, yInverted, vertices); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
|
#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
|
||||||
xscale, yscale, \
|
xscale, yscale, \
|
||||||
_x1_, _y1_, _x2_, _y2_, \
|
_x1_, _y1_, _x2_, _y2_, \
|
||||||
|
@ -480,7 +683,7 @@ format_for_pixmap(PixmapPtr pixmap)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map picture's format to the correct gl texture format and type.
|
* Map picture's format to the correct gl texture format and type.
|
||||||
* no_alpha is used to indicate whehter we need to wire alpha to 1.
|
* no_alpha is used to indicate whehter we need to wire alpha to 1.
|
||||||
*
|
*
|
||||||
* Although opengl support A1/GL_BITMAP, we still don't use it
|
* Although opengl support A1/GL_BITMAP, we still don't use it
|
||||||
* here, it seems that mesa has bugs when uploading a A1 bitmap.
|
* here, it seems that mesa has bugs when uploading a A1 bitmap.
|
||||||
|
@ -899,7 +1102,7 @@ inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable)
|
||||||
{
|
{
|
||||||
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
|
||||||
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
|
||||||
return (!pixmap_priv
|
return (!pixmap_priv
|
||||||
|| (pixmap_priv->type == GLAMOR_TEXTURE_DRM
|
|| (pixmap_priv->type == GLAMOR_TEXTURE_DRM
|
||||||
|| pixmap_priv->type == GLAMOR_MEMORY
|
|| pixmap_priv->type == GLAMOR_MEMORY
|
||||||
|| pixmap_priv->type == GLAMOR_DRM_ONLY));
|
|| pixmap_priv->type == GLAMOR_DRM_ONLY));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user