[cairo-commit] cairo/src cairo-xlib-surface.c,1.88,1.89
Vladimir Vukicevic
commit at pdx.freedesktop.org
Fri Jul 15 13:45:22 PDT 2005
- Previous message: [cairo-commit] cairo ChangeLog,1.736,1.737 ROADMAP,1.19,1.20
- Next message: [cairo-commit] cairo/test .cvsignore, 1.35, 1.36 Makefile.am, 1.62,
1.63 composite-integer-translate-over-repeat.c, NONE,
1.1 composite-integer-translate-over.c, NONE,
1.1 composite-integer-translate-source.c, NONE,
1.1 composite-integer-translate-over-ref.png, NONE,
1.1 composite-integer-translate-over-repeat-ref.png, NONE,
1.1 composite-integer-translate-source-ref.png, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Committed by: vladimir
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv30887/src
Modified Files:
cairo-xlib-surface.c
Log Message:
2005-07-15 Vladimir Vukicevic <vladimir at pobox.com>
* src/cairo-xlib-surface.c: (_cairo_xlib_surface_composite,
_recategorize_composite_repeat): Use XCopyArea when
possible, for optimization and bug workaround.
* test/composite-integer-translate-{source,over,over-repeat}.c:
Exercise XCopyArea, XRenderComposite, and XSetTile/XFillRectangle
paths for _cairo_xlib_surface_composite
Index: cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -d -r1.88 -r1.89
--- cairo-xlib-surface.c 14 Jul 2005 23:56:08 -0000 1.88
+++ cairo-xlib-surface.c 15 Jul 2005 20:45:19 -0000 1.89
@@ -829,17 +829,39 @@
}
}
+/* Returns true if the given operator and source-alpha combination
+ * requires alpha compositing to complete.
+ */
+static cairo_bool_t
+_operator_needs_alpha_composite (cairo_operator_t operator,
+ cairo_bool_t surface_has_alpha)
+{
+ if (operator == CAIRO_OPERATOR_SOURCE ||
+ (!surface_has_alpha &&
+ (operator == CAIRO_OPERATOR_OVER ||
+ operator == CAIRO_OPERATOR_ATOP ||
+ operator == CAIRO_OPERATOR_IN)))
+ return FALSE;
+
+ return TRUE;
+}
+
/* There is a bug in most older X servers with compositing using a repeating
* source pattern when the source is in off-screen video memory. When that
* bug could be triggered, we need a fallback: in the common case where we have no
* transformation and the source and destination have the same format/visual,
* we can do the operation using the core protocol, otherwise, we need
* a software fallback.
+ *
+ * We can also often optimize a compositing operation by calling XCopyArea
+ * for some common cases where there is no alpha compositing to be done.
+ * We figure that out here as well.
*/
typedef enum {
- DO_RENDER, /* use render */
- DO_XLIB, /* core protocol fallback */
- DO_UNSUPPORTED /* software fallback */
+ DO_RENDER, /* use render */
+ DO_XCOPYAREA, /* core protocol XCopyArea optimization/fallback */
+ DO_XTILE, /* core protocol XSetTile optimization/fallback */
+ DO_UNSUPPORTED /* software fallback */
} composite_operation_t;
/* Initial check for the bug; we need to recheck after we turn
@@ -850,10 +872,10 @@
* hit the bug and won't be able to use a core protocol fallback.
*/
static composite_operation_t
-_categorize_composite_repeat (cairo_xlib_surface_t *dst,
- cairo_operator_t operator,
- cairo_pattern_t *src_pattern,
- cairo_bool_t have_mask)
+_categorize_composite_operation (cairo_xlib_surface_t *dst,
+ cairo_operator_t operator,
+ cairo_pattern_t *src_pattern,
+ cairo_bool_t have_mask)
{
if (!dst->buggy_repeat)
@@ -892,27 +914,43 @@
* If we end up returning DO_UNSUPPORTED here, we're throwing away work we
* did to turn gradients into a pattern, but most of the time we can handle
* that case with core protocol fallback.
+ *
+ * Also check here if we can just use XCopyArea, instead of going through
+ * Render.
*/
static composite_operation_t
-_recategorize_composite_repeat (cairo_xlib_surface_t *dst,
- cairo_operator_t operator,
- cairo_xlib_surface_t *src,
- cairo_surface_attributes_t *src_attr,
- cairo_bool_t have_mask)
+_recategorize_composite_operation (cairo_xlib_surface_t *dst,
+ cairo_operator_t operator,
+ cairo_xlib_surface_t *src,
+ cairo_surface_attributes_t *src_attr,
+ cairo_bool_t have_mask)
{
+ cairo_bool_t is_integer_translation =
+ _cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL);
+ cairo_bool_t needs_alpha_composite =
+ _operator_needs_alpha_composite (operator, _surface_has_alpha (src));
+
+ if (!have_mask &&
+ is_integer_translation &&
+ src_attr->extend == CAIRO_EXTEND_NONE &&
+ !needs_alpha_composite &&
+ _surfaces_compatible(src, dst))
+ {
+ return DO_XCOPYAREA;
+ }
+
if (!dst->buggy_repeat)
return DO_RENDER;
- if (_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) &&
+ if (is_integer_translation &&
src_attr->extend == CAIRO_EXTEND_REPEAT &&
(src->width != 1 || src->height != 1))
{
if (!have_mask &&
- (operator == CAIRO_OPERATOR_SOURCE ||
- (operator == CAIRO_OPERATOR_OVER && !_surface_has_alpha (src))))
+ !needs_alpha_composite &&
+ _surfaces_compatible (dst, src))
{
- if (_surfaces_compatible (dst, src))
- return DO_XLIB;
+ return DO_XTILE;
}
return DO_UNSUPPORTED;
@@ -981,12 +1019,13 @@
cairo_xlib_surface_t *mask;
cairo_int_status_t status;
composite_operation_t operation;
+ int itx, ity;
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))
return CAIRO_INT_STATUS_UNSUPPORTED;
- operation = _categorize_composite_repeat (dst, operator, src_pattern,
- mask_pattern != NULL);
+ operation = _categorize_composite_operation (dst, operator, src_pattern,
+ mask_pattern != NULL);
if (operation == DO_UNSUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1001,8 +1040,8 @@
if (status)
return status;
- operation = _recategorize_composite_repeat (dst, operator, src, &src_attr,
- mask_pattern != NULL);
+ operation = _recategorize_composite_operation (dst, operator, src, &src_attr,
+ mask_pattern != NULL);
if (operation == DO_UNSUPPORTED) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto FAIL;
@@ -1012,8 +1051,9 @@
if (status)
goto FAIL;
- if (operation == DO_RENDER)
+ switch (operation)
{
+ case DO_RENDER:
_cairo_xlib_surface_ensure_dst_picture (dst);
if (mask) {
status = _cairo_xlib_surface_set_attributes (mask, &mask_attr);
@@ -1041,17 +1081,28 @@
dst_x, dst_y,
width, height);
}
- }
- else /* DO_XLIB */
- {
+ break;
+
+ case DO_XCOPYAREA:
+ _cairo_xlib_surface_ensure_gc (dst);
+ XCopyArea (dst->dpy,
+ src->drawable,
+ dst->drawable,
+ dst->gc,
+ src_x + src_attr.x_offset,
+ src_y + src_attr.y_offset,
+ width, height,
+ dst_x, dst_y);
+ break;
+
+ case DO_XTILE:
/* This case is only used for bug fallbacks, though it is theoretically
* applicable to the case where we don't have the RENDER extension as
* well.
*
* We've checked that we have a repeating unscaled source in
- * _recategorize_composite_repeat.
+ * _recategorize_composite_operation.
*/
- int itx, ity;
_cairo_xlib_surface_ensure_gc (dst);
_cairo_matrix_is_integer_translation (&src_attr.matrix, &itx, &ity);
@@ -1063,6 +1114,10 @@
XFillRectangle (dst->dpy, dst->drawable, dst->gc,
dst_x, dst_y, width, height);
+ break;
+
+ default:
+ ASSERT_NOT_REACHED;
}
FAIL:
@@ -1127,7 +1182,7 @@
if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
return CAIRO_INT_STATUS_UNSUPPORTED;
- operation = _categorize_composite_repeat (dst, operator, pattern, TRUE);
+ operation = _categorize_composite_operation (dst, operator, pattern, TRUE);
if (operation == DO_UNSUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1138,7 +1193,7 @@
if (status)
return status;
- operation = _recategorize_composite_repeat (dst, operator, src, &attributes, TRUE);
+ operation = _recategorize_composite_operation (dst, operator, src, &attributes, TRUE);
if (operation == DO_UNSUPPORTED) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto FAIL;
@@ -1959,7 +2014,7 @@
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->format)
return CAIRO_INT_STATUS_UNSUPPORTED;
- operation = _categorize_composite_repeat (self, operator, pattern, TRUE);
+ operation = _categorize_composite_operation (self, operator, pattern, TRUE);
if (operation == DO_UNSUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1970,7 +2025,7 @@
if (status)
return status;
- operation = _recategorize_composite_repeat (self, operator, src, &attributes, TRUE);
+ operation = _recategorize_composite_operation (self, operator, src, &attributes, TRUE);
if (operation == DO_UNSUPPORTED) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto FAIL;
- Previous message: [cairo-commit] cairo ChangeLog,1.736,1.737 ROADMAP,1.19,1.20
- Next message: [cairo-commit] cairo/test .cvsignore, 1.35, 1.36 Makefile.am, 1.62,
1.63 composite-integer-translate-over-repeat.c, NONE,
1.1 composite-integer-translate-over.c, NONE,
1.1 composite-integer-translate-source.c, NONE,
1.1 composite-integer-translate-over-ref.png, NONE,
1.1 composite-integer-translate-over-repeat-ref.png, NONE,
1.1 composite-integer-translate-source-ref.png, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the cairo-commit
mailing list