glamor_glyphs: Don't merge extents for different lists.
If we merge all lists's extent together, than we may have some fail overlap checking. Here is a simple: A E B F C D The first list has vertical "ABCD". And the second list has two char "EF". When detecting E, it can successfully find it doesn't overlap with previous glyphs. But after that, the original code will merge the previous extent with E's extent, then the extent will cover "F", so when detecting F, it will be treated as overlapped. We can simply solve this issue by not merge extent from different list. We can union different list's extent to a global region. And then do the intersect checkint between that region and current glyph extent, then we can avoid that fail checking. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
32a7438bf7
commit
88c317fb1e
|
@ -616,7 +616,6 @@ glyph_new_fixed_list(struct glamor_glyph_list *fixed_list,
|
|||
int *head_y,
|
||||
int *fixed_cnt,
|
||||
int type,
|
||||
GlyphListPtr prev_list,
|
||||
BoxPtr prev_extents
|
||||
)
|
||||
{
|
||||
|
@ -708,26 +707,39 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
|
|||
int x1, x2, y1, y2;
|
||||
int n;
|
||||
int x, y;
|
||||
BoxRec extents, prev_extents;
|
||||
Bool first = TRUE;
|
||||
BoxPtr extents;
|
||||
BoxRec prev_extents;
|
||||
Bool first = TRUE, first_list = TRUE;
|
||||
Bool need_free_list_region = FALSE;
|
||||
Bool need_free_fixed_list = FALSE;
|
||||
struct glamor_glyph *priv;
|
||||
Bool in_non_intersected_list = -1;
|
||||
GlyphListPtr head_list, prev_list, saved_list;
|
||||
GlyphListPtr head_list, saved_list;
|
||||
int head_x, head_y, head_pos;
|
||||
int fixed_cnt = 0;
|
||||
GlyphPtr *head_glyphs;
|
||||
GlyphListPtr cur_list = list;
|
||||
RegionRec list_region;
|
||||
RegionRec current_region;
|
||||
BoxRec current_box;
|
||||
|
||||
if (nlist > 1) {
|
||||
pixman_region_init(&list_region);
|
||||
need_free_list_region = TRUE;
|
||||
}
|
||||
|
||||
pixman_region_init(¤t_region);
|
||||
|
||||
extents = pixman_region_extents(¤t_region);
|
||||
|
||||
saved_list = list;
|
||||
x = 0;
|
||||
y = 0;
|
||||
extents.x1 = 0;
|
||||
extents.y1 = 0;
|
||||
extents.x2 = 0;
|
||||
extents.y2 = 0;
|
||||
prev_extents = extents;
|
||||
prev_list = list;
|
||||
extents->x1 = 0;
|
||||
extents->y1 = 0;
|
||||
extents->x2 = 0;
|
||||
extents->y2 = 0;
|
||||
|
||||
head_list = list;
|
||||
DEBUGF("has %d lists.\n", nlist);
|
||||
while (nlist--) {
|
||||
|
@ -742,6 +754,18 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
|
|||
left_to_right = TRUE;
|
||||
cur_list = list++;
|
||||
|
||||
if (unlikely(!first_list)) {
|
||||
pixman_region_init_with_extents(¤t_region, extents);
|
||||
pixman_region_union(&list_region, &list_region, ¤t_region);
|
||||
first = TRUE;
|
||||
} else {
|
||||
head_list = cur_list;
|
||||
head_pos = cur_list->len - n;
|
||||
head_x = x;
|
||||
head_y = y;
|
||||
head_glyphs = glyphs;
|
||||
}
|
||||
|
||||
DEBUGF("current list %p has %d glyphs\n", cur_list, n);
|
||||
while (n--) {
|
||||
GlyphPtr glyph = *glyphs++;
|
||||
|
@ -777,17 +801,14 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
|
|||
y2 = MAXSHORT;
|
||||
|
||||
if (first) {
|
||||
extents.x1 = x1;
|
||||
extents.y1 = y1;
|
||||
extents.x2 = x2;
|
||||
extents.y2 = y2;
|
||||
extents->x1 = x1;
|
||||
extents->y1 = y1;
|
||||
extents->x2 = x2;
|
||||
extents->y2 = y2;
|
||||
|
||||
prev_extents = *extents;
|
||||
|
||||
first = FALSE;
|
||||
head_list = cur_list;
|
||||
head_pos = cur_list->len - n - 1;
|
||||
head_x = x;
|
||||
head_y = y;
|
||||
head_glyphs = glyphs - 1;
|
||||
if (check_fake_overlap && priv
|
||||
&& priv->has_edge_map && glyph->info.yOff == 0) {
|
||||
left_box.x1 = x1;
|
||||
|
@ -802,10 +823,20 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
|
|||
has_right_edge_box = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (unlikely(!first_list)) {
|
||||
current_box.x1 = x1;
|
||||
current_box.y1 = y1;
|
||||
current_box.x2 = x2;
|
||||
current_box.y2 = y2;
|
||||
if (pixman_region_contains_rectangle(&list_region, ¤t_box) != PIXMAN_REGION_OUT) {
|
||||
need_free_fixed_list = TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (x1 < extents.x2 && x2 > extents.x1
|
||||
&& y1 < extents.y2
|
||||
&& y2 > extents.y1) {
|
||||
if (x1 < extents->x2 && x2 > extents->x1
|
||||
&& y1 < extents->y2
|
||||
&& y2 > extents->y1) {
|
||||
|
||||
if (check_fake_overlap && (has_left_edge_box || has_right_edge_box)
|
||||
&& priv->has_edge_map && glyph->info.yOff == 0) {
|
||||
|
@ -814,7 +845,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
|
|||
|
||||
left_dx = has_left_edge_box ? 1 : 0;
|
||||
right_dx = has_right_edge_box ? 1 : 0;
|
||||
if (x1 + 1 < extents.x2 - right_dx && x2 - 1 > extents.x1 + left_dx)
|
||||
if (x1 + 1 < extents->x2 - right_dx && x2 - 1 > extents->x1 + left_dx)
|
||||
goto real_intersected;
|
||||
|
||||
if (left_to_right && has_right_edge_box) {
|
||||
|
@ -851,7 +882,7 @@ glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr * glyphs,
|
|||
goto real_intersected;
|
||||
}
|
||||
} else {
|
||||
if (x1 < extents.x2 && x1 + 2 > extents.x1)
|
||||
if (x1 < extents->x2 && x1 + 2 > extents->x1)
|
||||
goto real_intersected;
|
||||
}
|
||||
goto non_intersected;
|
||||
|
@ -874,7 +905,6 @@ real_intersected:
|
|||
&head_x,
|
||||
&head_y, &fixed_cnt,
|
||||
NON_INTERSECTED,
|
||||
prev_list,
|
||||
&prev_extents
|
||||
)){
|
||||
need_free_fixed_list = TRUE;
|
||||
|
@ -904,7 +934,6 @@ non_intersected:
|
|||
&head_x,
|
||||
&head_y, &fixed_cnt,
|
||||
INTERSECTED,
|
||||
prev_list,
|
||||
&prev_extents
|
||||
)) {
|
||||
need_free_fixed_list = TRUE;
|
||||
|
@ -913,12 +942,12 @@ non_intersected:
|
|||
}
|
||||
in_non_intersected_list = 1;
|
||||
}
|
||||
prev_extents = extents;
|
||||
prev_extents = *extents;
|
||||
}
|
||||
|
||||
if (check_fake_overlap && priv
|
||||
&& priv->has_edge_map && glyph->info.yOff == 0) {
|
||||
if (!has_left_edge_box || x1 < extents.x1) {
|
||||
if (!has_left_edge_box || x1 < extents->x1) {
|
||||
left_box.x1 = x1;
|
||||
left_box.x2 = x1 + 1;
|
||||
left_box.y1 = y1;
|
||||
|
@ -926,7 +955,7 @@ non_intersected:
|
|||
left_priv = priv;
|
||||
}
|
||||
|
||||
if (!has_right_edge_box || x2 > extents.x2) {
|
||||
if (!has_right_edge_box || x2 > extents->x2) {
|
||||
right_box.x1 = x2 - 2;
|
||||
right_box.x2 = x2 - 1;
|
||||
right_box.y1 = y1;
|
||||
|
@ -935,20 +964,20 @@ non_intersected:
|
|||
}
|
||||
}
|
||||
|
||||
if (x1 < extents.x1)
|
||||
extents.x1 = x1;
|
||||
if (x2 > extents.x2)
|
||||
extents.x2 = x2;
|
||||
if (x1 < extents->x1)
|
||||
extents->x1 = x1;
|
||||
if (x2 > extents->x2)
|
||||
extents->x2 = x2;
|
||||
|
||||
if (y1 < extents.y1)
|
||||
extents.y1 = y1;
|
||||
if (y2 > extents.y2)
|
||||
extents.y2 = y2;
|
||||
if (y1 < extents->y1)
|
||||
extents->y1 = y1;
|
||||
if (y2 > extents->y2)
|
||||
extents->y2 = y2;
|
||||
|
||||
x += glyph->info.xOff;
|
||||
y += glyph->info.yOff;
|
||||
prev_list = cur_list;
|
||||
}
|
||||
first_list = FALSE;
|
||||
}
|
||||
|
||||
if (in_non_intersected_list == 0 && fixed_cnt == 0) {
|
||||
|
@ -973,7 +1002,6 @@ non_intersected:
|
|||
&head_x,
|
||||
&head_y, &fixed_cnt,
|
||||
(!in_non_intersected_list) | 0x80,
|
||||
prev_list,
|
||||
&prev_extents
|
||||
)) {
|
||||
need_free_fixed_list = TRUE;
|
||||
|
@ -982,6 +1010,10 @@ non_intersected:
|
|||
}
|
||||
|
||||
done:
|
||||
if (need_free_list_region)
|
||||
pixman_region_fini(&list_region);
|
||||
pixman_region_fini(¤t_region);
|
||||
|
||||
if (need_free_fixed_list && fixed_cnt >= 0) {
|
||||
while(fixed_cnt--) {
|
||||
free(fixed_list[fixed_cnt].list);
|
||||
|
|
Loading…
Reference in New Issue
Block a user