1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
diff --git a/gfx/cairo/cairo/src/cairo-xlib-surface.c b/gfx/cairo/cairo/src/cairo-xlib-surface.c
--- a/gfx/cairo/cairo/src/cairo-xlib-surface.c
+++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c
@@ -1722,30 +1722,31 @@ _surface_has_alpha (cairo_xlib_surface_t
else
return FALSE;
} else {
/* In the no-render case, we never have alpha */
return FALSE;
}
}
-/* Returns true if the given operator and source-alpha combination
- * requires alpha compositing to complete.
+/* Returns true if the given operator and alpha combination requires alpha
+ * compositing to complete on source and destination surfaces with the same
+ * format. i.e. if a simple bitwise copy is not appropriate.
*/
static cairo_bool_t
_operator_needs_alpha_composite (cairo_operator_t op,
- cairo_bool_t destination_has_alpha,
- cairo_bool_t source_has_alpha)
+ cairo_bool_t surfaces_have_alpha)
{
- if (op == CAIRO_OPERATOR_SOURCE ||
- (! source_has_alpha &&
- (op == CAIRO_OPERATOR_OVER ||
- op == CAIRO_OPERATOR_ATOP ||
- op == CAIRO_OPERATOR_IN)))
- return destination_has_alpha;
+ if (op == CAIRO_OPERATOR_SOURCE)
+ return FALSE;
+
+ if (op == CAIRO_OPERATOR_OVER ||
+ op == CAIRO_OPERATOR_IN ||
+ op == CAIRO_OPERATOR_ATOP)
+ return surfaces_have_alpha;
return TRUE;
}
/* There is a bug in most older X servers with compositing using a
* untransformed repeating source pattern when the source is in off-screen
* video memory, and another with repeated transformed images using a
* general transform matrix. When these bugs could be triggered, we need a
@@ -1843,24 +1844,24 @@ _categorize_composite_operation (cairo_x
*/
static composite_operation_t
_recategorize_composite_operation (cairo_xlib_surface_t *dst,
cairo_operator_t op,
cairo_xlib_surface_t *src,
cairo_surface_attributes_t *src_attr,
cairo_bool_t have_mask)
{
- /* Can we use the core protocol? */
+ /* Can we use the core protocol? (If _surfaces_compatible, then src and
+ * dst have the same format and _surface_has_alpha is the same for each.)
+ */
if (! have_mask &&
src->owns_pixmap &&
- src->depth == dst->depth &&
+ _surfaces_compatible (src, dst) &&
_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) &&
- ! _operator_needs_alpha_composite (op,
- _surface_has_alpha (dst),
- _surface_has_alpha (src)))
+ ! _operator_needs_alpha_composite (op, _surface_has_alpha (dst)))
{
if (src_attr->extend == CAIRO_EXTEND_NONE)
return DO_XCOPYAREA;
if (dst->buggy_repeat && src_attr->extend == CAIRO_EXTEND_REPEAT)
return DO_XTILE;
}
@@ -2211,34 +2212,28 @@ _cairo_xlib_surface_composite (cairo_ope
cairo_surface_attributes_t src_attr, mask_attr;
cairo_xlib_surface_t *dst = abstract_dst;
cairo_xlib_surface_t *src;
cairo_xlib_surface_t *mask;
cairo_int_status_t status;
composite_operation_t operation;
int itx, ity;
cairo_bool_t is_integer_translation;
- cairo_bool_t needs_alpha_composite;
GC gc;
if (mask_pattern != NULL && ! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
return UNSUPPORTED ("no support for masks");
operation = _categorize_composite_operation (dst, op, src_pattern,
mask_pattern != NULL);
if (operation == DO_UNSUPPORTED)
return UNSUPPORTED ("unsupported operation");
X_DEBUG ((dst->dpy, "composite (dst=%x)", (unsigned int) dst->drawable));
- needs_alpha_composite =
- _operator_needs_alpha_composite (op,
- _surface_has_alpha (dst),
- ! _cairo_pattern_is_opaque (src_pattern));
-
_cairo_xlib_display_notify (dst->display);
status =
_cairo_xlib_surface_acquire_pattern_surfaces (dst,
src_pattern, mask_pattern,
src_x, src_y,
mask_x, mask_y,
width, height,
|