[cairo-commit] 3 commits - src/cairoint.h src/cairo-scaled-font.c src/cairo-scaled-font-test.h src/cairo-xlib-surface.c src/Makefile.am test/.gitignore test/glyph-cache-pressure.c test/glyph-cache-pressure-pdf-argb32-ref.png test/glyph-cache-pressure-ps-argb32-ref.png test/glyph-cache-pressure-ref.png test/glyph-cache-pressure-svg-argb32-ref.png test/glyph-cache-pressure-svg-rgb24-ref.png test/Makefile.am

Carl Worth cworth at kemper.freedesktop.org
Thu Jun 22 22:38:06 PDT 2006


 src/Makefile.am                              |    1 
 src/cairo-scaled-font-test.h                 |   49 +++++++++++++
 src/cairo-scaled-font.c                      |   29 +++++++-
 src/cairo-xlib-surface.c                     |   15 +++-
 src/cairoint.h                               |    6 +
 test/.gitignore                              |    1 
 test/Makefile.am                             |    2 
 test/glyph-cache-pressure-pdf-argb32-ref.png |binary
 test/glyph-cache-pressure-ps-argb32-ref.png  |binary
 test/glyph-cache-pressure-ref.png            |binary
 test/glyph-cache-pressure-svg-argb32-ref.png |binary
 test/glyph-cache-pressure-svg-rgb24-ref.png  |binary
 test/glyph-cache-pressure.c                  |   96 +++++++++++++++++++++++++++
 13 files changed, 197 insertions(+), 2 deletions(-)

New commits:
diff-tree 7e457cb4c1e69670f27e3e8e134a9e32a8f75788 (from 6a58658b73924fa6897bd1e290d754ce1df44b0d)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Jun 22 22:32:57 2006 -0700

    Bug 6955: Fix by adding freeze/thaw around scaled_font glyph cache in _cairo_xlib_surface_show_glyphs

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 66e9fbc..30da355 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -364,6 +364,18 @@ _cairo_scaled_font_init (cairo_scaled_fo
 }
 
 void
+_cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font)
+{
+    _cairo_cache_freeze (scaled_font->glyphs);
+}
+
+void
+_cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font)
+{
+    _cairo_cache_thaw (scaled_font->glyphs);
+}
+
+void
 _cairo_scaled_font_set_metrics (cairo_scaled_font_t	    *scaled_font,
 				cairo_font_extents_t	    *fs_metrics)
 {
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index f10d2f4..8eb5580 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2579,7 +2579,7 @@ _cairo_xlib_surface_show_glyphs (void   
 				 int		      num_glyphs,
 				 cairo_scaled_font_t *scaled_font)
 {
-    cairo_int_status_t status;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_xlib_surface_t *dst = (cairo_xlib_surface_t*) abstract_dst;
 
     composite_operation_t operation;
@@ -2635,6 +2635,17 @@ _cairo_xlib_surface_show_glyphs (void   
 	(font_private != NULL && font_private->dpy != dst->dpy))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
+    /* After passing all those tests, we're now committed to rendering
+     * these glyphs or to fail trying. We first upload any glyphs to
+     * the X server that it doesn't have already, then we draw
+     * them. We tie into the scaled_font's glyph cache and remove
+     * glyphs from the X server when they are ejected from the
+     * scaled_font cache. Because of this we first freeze the
+     * scaled_font's cache so that we don't cause any of our glyphs to
+     * be ejected and removed from the X server before we have a
+     * chance to render them. */
+    _cairo_scaled_font_freeze_cache (scaled_font);
+
     /* PictOpClear doesn't seem to work with CompositeText; it seems to ignore
      * the mask (the glyphs).  This code below was executed as a side effect
      * of going through the _clip_and_composite fallback code for old_show_glyphs,
@@ -2726,6 +2737,8 @@ _cairo_xlib_surface_show_glyphs (void   
     }
 
   FAIL:
+    _cairo_scaled_font_thaw_cache (scaled_font);
+
     if (src)
         _cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
     if (src_pattern == &solid_pattern.base)
diff --git a/src/cairoint.h b/src/cairoint.h
index 103873f..54995d2 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1379,6 +1379,12 @@ _cairo_color_get_rgba_premultiplied (cai
 /* cairo-font.c */
 
 cairo_private void
+_cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font);
+
+cairo_private void
+_cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font);
+
+cairo_private void
 _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font,
 			      cairo_status_t status);
 
diff --git a/test/glyph-cache-pressure.c b/test/glyph-cache-pressure.c
index b9ea4e1..7f4ea2c 100644
--- a/test/glyph-cache-pressure.c
+++ b/test/glyph-cache-pressure.c
@@ -40,6 +40,13 @@
  *   We replicate this bug by using the cairo_scaled_font_set_max_glyphs_per_font
  *   function to artifically induce cache pressure. (This function was added
  *   for this very purpose.)
+ *
+ * 2006-06-22  Carl Worth  <cworth at cworth.org>
+ *
+ *   Bug was simple enough to solve by just adding a freeze/thaw pair
+ *   around the scaled_font's glyph cache in
+ *   _cairo_xlib_surface_show_glyphs, (I went ahead and added
+ *   _cairo_sacled_font_freeze/thaw_cache functions for this).
  */
 
 cairo_test_t test = {
diff-tree 6a58658b73924fa6897bd1e290d754ce1df44b0d (from 333ac8f4d9ccc356cb91e7118ed56bfc07e78c2f)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Jun 22 22:05:20 2006 -0700

    Add test/glyph-cache-pressure to demonstrate xlib failure (bug 6955)

diff --git a/test/.gitignore b/test/.gitignore
index 115762b..fa5dbb6 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -46,6 +46,7 @@ ft-text-antialias-none
 font-face-get-type
 get-and-set
 get-group-target
+glyph-cache-pressure
 gradient-alpha
 imagediff
 leaky-dash
diff --git a/test/Makefile.am b/test/Makefile.am
index a9d3c12..dcaa67e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -29,6 +29,7 @@ fill-and-stroke-alpha-add	\
 fill-rule			\
 filter-nearest-offset		\
 font-face-get-type		\
+glyph-cache-pressure		\
 get-and-set			\
 get-group-target		\
 gradient-alpha			\
@@ -189,6 +190,7 @@ fill-rule-rgb24-ref.png					\
 fill-rule-ps-argb32-ref.png				\
 filter-nearest-offset-ref.png				\
 get-group-target-ref.png				\
+glyph-cache-pressure-ref.png				\
 gradient-alpha-ref.png					\
 gradient-alpha-rgb24-ref.png				\
 leaky-dash-ref.png					\
diff --git a/test/glyph-cache-pressure-pdf-argb32-ref.png b/test/glyph-cache-pressure-pdf-argb32-ref.png
new file mode 100644
index 0000000..8b9031c
Binary files /dev/null and b/test/glyph-cache-pressure-pdf-argb32-ref.png differ
diff --git a/test/glyph-cache-pressure-ps-argb32-ref.png b/test/glyph-cache-pressure-ps-argb32-ref.png
new file mode 100644
index 0000000..cc02ff6
Binary files /dev/null and b/test/glyph-cache-pressure-ps-argb32-ref.png differ
diff --git a/test/glyph-cache-pressure-ref.png b/test/glyph-cache-pressure-ref.png
new file mode 100644
index 0000000..0947a67
Binary files /dev/null and b/test/glyph-cache-pressure-ref.png differ
diff --git a/test/glyph-cache-pressure-svg-argb32-ref.png b/test/glyph-cache-pressure-svg-argb32-ref.png
new file mode 100644
index 0000000..0a49bc4
Binary files /dev/null and b/test/glyph-cache-pressure-svg-argb32-ref.png differ
diff --git a/test/glyph-cache-pressure-svg-rgb24-ref.png b/test/glyph-cache-pressure-svg-rgb24-ref.png
new file mode 100644
index 0000000..6f40d60
Binary files /dev/null and b/test/glyph-cache-pressure-svg-rgb24-ref.png differ
diff --git a/test/glyph-cache-pressure.c b/test/glyph-cache-pressure.c
new file mode 100644
index 0000000..b9ea4e1
--- /dev/null
+++ b/test/glyph-cache-pressure.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Carl D. Worth <cworth at cworth.org>
+ */
+
+#include "cairo-test.h"
+#include "cairo-scaled-font-test.h"
+
+#define TEXT_SIZE 12
+
+/* Bug history
+ *
+ * 2006-06-22  Carl Worth  <cworth at cworth.org>
+ *
+ *   This is a test case to demonstrate the following bug in the xlib backend:
+ *
+ *	Some characters aren't displayed when using xlib (cache usage missing freeze/thaw)
+ *	https://bugs.freedesktop.org/show_bug.cgi?id=6955
+ *
+ *   We replicate this bug by using the cairo_scaled_font_set_max_glyphs_per_font
+ *   function to artifically induce cache pressure. (This function was added
+ *   for this very purpose.)
+ */
+
+cairo_test_t test = {
+    "glyph-cache-pressure",
+    "Ensure that all backends behave well under artificial glyph cache pressure",
+    223, TEXT_SIZE + 4
+};
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_font_options_t *font_options;
+
+    /* We draw in the default black, so paint white first. */
+    cairo_save (cr);
+    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
+    cairo_paint (cr);
+    cairo_restore (cr);
+
+    cairo_scaled_font_test_set_max_glyphs_cached_per_font (1);
+
+    cairo_select_font_face (cr, "Bitstream Vera Sans",
+			    CAIRO_FONT_SLANT_NORMAL,
+			    CAIRO_FONT_WEIGHT_NORMAL);
+    cairo_set_font_size (cr, TEXT_SIZE);
+
+    font_options = cairo_font_options_create ();
+
+    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
+    cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
+
+    cairo_set_font_options (cr, font_options);
+    cairo_font_options_destroy (font_options);
+
+    cairo_set_source_rgb (cr, 0, 0, 0); /* black */
+
+    cairo_move_to (cr, 1, TEXT_SIZE);
+    cairo_show_text (cr, "the five boxing wizards jump quickly");
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+int
+main (void)
+{
+    return cairo_test (&test, draw);
+}
diff-tree 333ac8f4d9ccc356cb91e7118ed56bfc07e78c2f (from d5197c1e0defc1018320efcb461977557a7d5d6e)
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Jun 22 22:03:06 2006 -0700

    Add 'private' cairo_scaled_font_test_set_max_glyphs_cached_per_font for testing

diff --git a/src/Makefile.am b/src/Makefile.am
index 2f1c8e0..57d1e80 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -189,6 +189,7 @@ libcairo_la_SOURCES =				\
 	cairo-rectangle.c			\
 	cairo-region.c				\
 	cairo-scaled-font.c			\
+	cairo-scaled-font-test.h		\
 	cairo-slope.c				\
 	cairo-spline.c				\
 	cairo-stroke-style.c			\
diff --git a/src/cairo-scaled-font-test.h b/src/cairo-scaled-font-test.h
new file mode 100644
index 0000000..20723af
--- /dev/null
+++ b/src/cairo-scaled-font-test.h
@@ -0,0 +1,49 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2006 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is University of Southern
+ * California.
+ *
+ * Contributor(s):
+ *	Carl D. Worth <cworth at cworth.org>
+ */
+
+#ifndef CAIRO_SCALED_FONT_TEST_H
+#define CAIRO_SCALED_FONT_TEST_H
+
+#include <cairo.h>
+
+CAIRO_BEGIN_DECLS
+
+void
+cairo_scaled_font_test_set_max_glyphs_cached_per_font (int max);
+
+CAIRO_END_DECLS
+
+#endif /* CAIRO_SCALED_FONT_TEST_H */
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index c614d81..66e9fbc 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -37,6 +37,7 @@
  */
 
 #include "cairoint.h"
+#include "cairo-scaled-font-test.h"
 
 static cairo_bool_t
 _cairo_scaled_glyph_keys_equal (const void *abstract_key_a, const void *abstract_key_b)
@@ -313,6 +314,20 @@ _cairo_scaled_font_keys_equal (const voi
 	    cairo_font_options_equal (&key_a->options, &key_b->options));
 }
 
+/* XXX: This 256 number is arbitary---we've never done any measurement
+ * of this. In fact, having a per-font glyph caches each managed
+ * separately is probably not waht we want anyway. Would probably be
+ * much better to have a single cache for glyphs with random
+ * replacement across all glyphs of all fonts. */
+static int max_glyphs_cached_per_font = 256;
+
+/* For internal testing purposes only. Not part of the supported API. */
+void
+cairo_scaled_font_test_set_max_glyphs_cached_per_font (int max)
+{
+    max_glyphs_cached_per_font = max;
+}
+
 /*
  * Basic cairo_scaled_font_t object management
  */
@@ -338,7 +353,7 @@ _cairo_scaled_font_init (cairo_scaled_fo
 
     scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal,
 					       _cairo_scaled_glyph_destroy,
-					       256);
+					       max_glyphs_cached_per_font);
 
     scaled_font->surface_backend = NULL;
     scaled_font->surface_private = NULL;


More information about the cairo-commit mailing list