From 8ad8aa63605610eaec78cdbfea321148c02be331 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Fri, 15 Jul 2005 13:45:19 +0000 Subject: [PATCH] Use XCopyArea when possible, for optimization and bug workaround. Exercise XCopyArea, XRenderComposite, and XSetTile/XFillRectangle paths for _cairo_xlib_surface_composite --- ChangeLog | 10 ++ ROADMAP | 2 +- src/cairo-xlib-surface.c | 117 +++++++++++++----- test/.cvsignore | 3 + test/Makefile.am | 11 +- test/composite-integer-translate-over-ref.png | Bin 0 -> 15397 bytes ...site-integer-translate-over-repeat-ref.png | Bin 0 -> 401 bytes .../composite-integer-translate-over-repeat.c | 61 +++++++++ test/composite-integer-translate-over.c | 42 +++++++ ...composite-integer-translate-source-ref.png | Bin 0 -> 16385 bytes test/composite-integer-translate-source.c | 42 +++++++ 11 files changed, 255 insertions(+), 33 deletions(-) create mode 100644 test/composite-integer-translate-over-ref.png create mode 100644 test/composite-integer-translate-over-repeat-ref.png create mode 100644 test/composite-integer-translate-over-repeat.c create mode 100644 test/composite-integer-translate-over.c create mode 100644 test/composite-integer-translate-source-ref.png create mode 100644 test/composite-integer-translate-source.c diff --git a/ChangeLog b/ChangeLog index 508293e80..7a3cbfe76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-07-15 Vladimir Vukicevic + + * 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 + 2005-07-15 Carl Worth * test/Makefile.am: Add new check-valgrind target for running the diff --git a/ROADMAP b/ROADMAP index 9b79e9521..88fad3087 100644 --- a/ROADMAP +++ b/ROADMAP @@ -10,7 +10,7 @@ cairo 0.5.2 0.1.4 which is already fixed in libpixman 0.1.5) Add a workaround for Render's overlapping source/dest bug - Use XCopyArea when possible (integer translation) +✓ Use XCopyArea when possible (integer translation) Otherwise make a copy of the source Fix the cache lock deadlocking problems. diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 95df4d298..caec2b9dd 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -829,17 +829,39 @@ _surface_has_alpha (cairo_xlib_surface_t *surface) } } +/* 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 @@ typedef enum { * 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 @@ _categorize_composite_repeat (cairo_xlib_surface_t *dst, * 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_composite (cairo_operator_t operator, 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 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, 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 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, 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 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, 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 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, XFillRectangle (dst->dpy, dst->drawable, dst->gc, dst_x, dst_y, width, height); + break; + + default: + ASSERT_NOT_REACHED; } FAIL: @@ -1127,7 +1182,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, 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 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, 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 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font, 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 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font, 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; diff --git a/test/.cvsignore b/test/.cvsignore index 5ce9bbd3a..00ed2feca 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -4,6 +4,9 @@ Makefile Makefile.in clip-nesting clip-twice +composite-integer-translate-source +composite-integer-translate-over +composite-integer-translate-over-repeat coverage create-from-png fill-and-stroke diff --git a/test/Makefile.am b/test/Makefile.am index 118b298f0..ee8d1b98d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,6 +2,9 @@ TESTS = \ clip-nesting \ clip-twice \ +composite-integer-translate-source \ +composite-integer-translate-over \ +composite-integer-translate-over-repeat \ create-from-png \ fill-and-stroke \ fill-rule \ @@ -52,6 +55,9 @@ endif EXTRA_DIST = \ clip-nesting-ref.png \ clip-twice-ref.png \ +composite-integer-translate-source-ref.png \ +composite-integer-translate-over-ref.png \ +composite-integer-translate-over-repeat-ref.png \ create-from-png-ref.png \ fill-and-stroke-ref.png \ fill-rule-ref.png \ @@ -133,6 +139,9 @@ LDADDS = libcairotest.la $(top_builddir)/src/libcairo.la # from autogen.sh. My, but this is painful... clip_nesting_LDADD = $(LDADDS) clip_twice_LDADD = $(LDADDS) +composite_integer_translate_source_LDADD = $(LDADDS) +composite_integer_translate_over_LDADD = $(LDADDS) +composite_integer_translate_over_repeat_LDADD = $(LDADDS) create_from_png_LDADD = $(LDADDS) fill_and_stroke_LDADD = $(LDADDS) fill_rule_LDADD = $(LDADDS) @@ -181,4 +190,4 @@ CLEANFILES = \ pdf-clip.pdf check-valgrind: - TESTS_ENVIRONMENT="libtool --mode=execute valgrind --tool=memcheck --leak-check=yes --show-reachable=yes" $(MAKE) check \ No newline at end of file + TESTS_ENVIRONMENT="libtool --mode=execute valgrind --tool=memcheck --leak-check=yes --show-reachable=yes" $(MAKE) check diff --git a/test/composite-integer-translate-over-ref.png b/test/composite-integer-translate-over-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..1fbaaaa3b155181e196fd1031005893bbf5bf6a9 GIT binary patch literal 15397 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 z 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 P00000NkvXXu0mjfJiJel literal 0 HcmV?d00001 diff --git a/test/composite-integer-translate-over-repeat-ref.png b/test/composite-integer-translate-over-repeat-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..c04db2631ca052d05d42f242c5635fb0029b5824 GIT binary patch literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^DIm{r?Oh4k2FE;6WPU|=-%ba4!+nDh3gA=eQD9tOwXC;sn$vzk9hW62KPv{wpD-CT?J zUbE`%IlsTYA-?Gdhmf*IkAfkbasA8Tm&JAb_BOZoSevQ1O^|R*V(An_Fw*`6-9Nnj zSL9~(m6hLfP_#nKIMY1)*B95Ud$TLCX+P#`Yj(a3!`7xFJ60Zlb`!%kp#A1wZ`eqq zITB>k<7INQ)16Tr2X^kAE6Ja+Ijm=PRn9zKWWPXt_mfFk)9HotW}aEV5M}Um^>bP0 Hl+XkK +#include "cairo-test.h" +#include + +#define SIZE 100 +#define SIZE2 20 +#define OFFSET 10 + +cairo_test_t test = { + "composite-integer-translate-over-repeat", + "Test simple compositing: integer-translation 32->32 OVER, with repeat", + SIZE, SIZE +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *image; + cairo_pattern_t *pat; + cairo_t *cr2; + + image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, SIZE2, SIZE2); + + cr2 = cairo_create (image); + cairo_set_source_rgba (cr2, 1, 0, 0, 1); + cairo_rectangle (cr2, 0, 0, SIZE2/2, SIZE2/2); + cairo_fill (cr2); + cairo_set_source_rgba (cr2, 0, 1, 0, 1); + cairo_rectangle (cr2, SIZE2/2, 0, SIZE2/2, SIZE2/2); + cairo_fill (cr2); + cairo_set_source_rgba (cr2, 0, 0, 1, 1); + cairo_rectangle (cr2, 0, SIZE2/2, SIZE2/2, SIZE2/2); + cairo_fill (cr2); + cairo_set_source_rgba (cr2, 1, 1, 0, 1); + cairo_rectangle (cr2, SIZE2/2, SIZE2/2, SIZE2/2, SIZE2/2); + cairo_fill (cr2); + cairo_destroy (cr2); + + pat = cairo_pattern_create_for_surface (image); + cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT); + + cairo_set_source_rgba (cr, 0, 0, 0, 1); + cairo_rectangle (cr, 0, 0, SIZE, SIZE); + cairo_fill (cr); + + cairo_translate (cr, OFFSET, OFFSET); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source (cr, pat); + cairo_rectangle (cr, 0, 0, SIZE - OFFSET, SIZE - OFFSET); + cairo_fill (cr); + + cairo_surface_destroy (image); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/composite-integer-translate-over.c b/test/composite-integer-translate-over.c new file mode 100644 index 000000000..867448889 --- /dev/null +++ b/test/composite-integer-translate-over.c @@ -0,0 +1,42 @@ +#include +#include "cairo-test.h" +#include + +#define SIZE 100 +#define OFFSET 5.5 +#define SCALE 1.5 +const char png_filename[] = "romedalen.png"; + +cairo_test_t test = { + "composite-integer-translate-over", + "Test simple compositing: integer-translation 32->32 OVER", + SIZE, SIZE +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *image; + + image = cairo_image_surface_create_from_png (png_filename); + + cairo_set_source_rgba (cr, 0, 0, 0, 1); + cairo_rectangle (cr, 0, 0, SIZE, SIZE); + cairo_fill (cr); + + cairo_translate (cr, OFFSET, OFFSET); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_source_surface (cr, image, 0, 0); + cairo_rectangle (cr, 0, 0, (SIZE-OFFSET), (SIZE-OFFSET)); + cairo_fill (cr); + + cairo_surface_destroy (image); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/composite-integer-translate-source-ref.png b/test/composite-integer-translate-source-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..da9a3986afbba99942d3c4a549fd0eb4b4a5415f GIT binary patch literal 16385 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 P00000NkvXXu0mjf6eSG4 literal 0 HcmV?d00001 diff --git a/test/composite-integer-translate-source.c b/test/composite-integer-translate-source.c new file mode 100644 index 000000000..a467f089a --- /dev/null +++ b/test/composite-integer-translate-source.c @@ -0,0 +1,42 @@ +#include +#include "cairo-test.h" +#include + +#define SIZE 100 +#define OFFSET 10 + +const char png_filename[] = "romedalen.png"; + +cairo_test_t test = { + "composite-integer-translate-source", + "Test simple compositing: integer-translation 32->32 SOURCE", + SIZE, SIZE +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *image; + + image = cairo_image_surface_create_from_png (png_filename); + + cairo_set_source_rgba (cr, 0, 0, 0, 1); + cairo_rectangle (cr, 0, 0, SIZE, SIZE); + cairo_fill (cr); + + cairo_translate (cr, OFFSET, OFFSET); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_surface (cr, image, 0, 0); + cairo_rectangle (cr, 0, 0, SIZE - OFFSET, SIZE - OFFSET); + cairo_fill (cr); + + cairo_surface_destroy (image); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +}