[cairo-commit] 4 commits - perf/Makefile.am src/cairo-surface.c src/cairo-xlib-xcb-surface.c

Uli Schlachter psychon at kemper.freedesktop.org
Thu Aug 4 12:39:46 PDT 2011


 perf/Makefile.am             |    2 +
 src/cairo-surface.c          |   48 +++++++++++++++++++++++++++++--------------
 src/cairo-xlib-xcb-surface.c |   41 ++++++++++++++++++++++++++++++++++--
 3 files changed, 73 insertions(+), 18 deletions(-)

New commits:
commit 95d6235bbecc7a646590edac07d6a68f150b1b8b
Author: Uli Schlachter <psychon at znc.in>
Date:   Thu Aug 4 21:18:13 2011 +0200

    Clarify the API docs for the newest functions
    
    Recently cairo_surface_create_similar_image(), cairo_surface_map_to_image() and
    cairo_surface_unmap_image() were introduced. However, the documentation was
    slightly misleading and recommended a wrong usage.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index fafc875..9a8fcb9 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -484,6 +484,9 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
  * Initially the surface contents are all 0 (transparent if contents
  * have transparency, black otherwise.)
  *
+ * Use cairo_surface_create_similar_image() if you need an image surface
+ * which can be painted quickly to the target surface.
+ *
  * Return value: a pointer to the newly allocated surface. The caller
  * owns the surface and should call cairo_surface_destroy() when done
  * with it.
@@ -528,11 +531,14 @@ cairo_surface_create_similar (cairo_surface_t  *other,
  * @height: height of the new surface (in device-space units)
  *
  * Create a new image surface that is as compatible as possible for uploading
- * to and the use in conjunction with an existing surface.
+ * to and the use in conjunction with an existing surface. However, this surface
+ * can still be used like any normal image surface.
  *
  * Initially the surface contents are all 0 (transparent if contents
  * have transparency, black otherwise.)
  *
+ * Use cairo_surface_create_similar() if you don't need an image surface.
+ *
  * Return value: a pointer to the newly allocated image surface. The caller
  * owns the surface and should call cairo_surface_destroy() when done
  * with it.
@@ -575,11 +581,11 @@ cairo_surface_create_similar_image (cairo_surface_t  *other,
  *
  * Note, the use of the original surface as a target or source whilst it is
  * mapped is undefined. The result of mapping the surface multiple times is
- * undefined.
+ * undefined. Calling cairo_surface_destroy() or cairo_surface_finish() on the
+ * resulting image surface results in undefined behavior.
  *
  * Return value: a pointer to the newly allocated image surface. The caller
- * owns the surface and should call cairo_surface_destroy() when done
- * with it.
+ * must use cairo_surface_unmap_image() to destroy this image surface.
  *
  * This function always returns a valid pointer, but it will return a
  * pointer to a "nil" surface if @other is already in an error state
@@ -637,21 +643,16 @@ cairo_surface_map_to_image (cairo_surface_t  *surface,
 
 /**
  * cairo_surface_unmap_image:
- * @surface: an existing surface used to extract the image from
+ * @surface: the surface passed to cairo_surface_map_to_image().
  * @image: the currently mapped image
  *
  * Unmaps the image surface as returned from #cairo_surface_map_to_image().
- * Returns an image surface that is the most efficient mechanism for
- * modifying the backing store of the target surface. The region retrieved
- * may be limited to the @extents or %NULL for the whole surface
  *
- * Return value: a pointer to the newly allocated image surface. The caller
- * owns the surface and should call cairo_surface_destroy() when done
- * with it.
+ * The content of the image will be uploaded to the target surface.
+ * Afterwards, the image is destroyed.
  *
- * This function always returns a valid pointer, but it will return a
- * pointer to a "nil" surface if @other is already in an error state
- * or any other error occurs.
+ * Using an image surface which wasn't returned by cairo_surface_map_to_image()
+ * results in undefined behavior.
  **/
 void
 cairo_surface_unmap_image (cairo_surface_t *surface,
commit 971d42302cf52fa5007fc1faa94542fcad9bacfb
Author: Uli Schlachter <psychon at znc.in>
Date:   Thu Aug 4 21:06:53 2011 +0200

    perf: Also build the code in perf/micro
    
    This fixes weird and occasional build failures when updating the source, e.g.:
    
    cairo-perf-micro.o:(.rodata+0xb0): undefined reference to `hash_table'
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/perf/Makefile.am b/perf/Makefile.am
index 17678a3..d41891f 100644
--- a/perf/Makefile.am
+++ b/perf/Makefile.am
@@ -12,6 +12,8 @@ AM_CPPFLAGS =					\
 
 AM_LDFLAGS = $(CAIRO_LDFLAGS)
 
+SUBDIRS = micro
+
 noinst_PROGRAMS = cairo-perf-trace cairo-perf-micro
 
 EXTRA_PROGRAMS += cairo-perf-micro \
commit 78f7db1a7f668dbcc80366511ecaf9ff30b77a98
Author: Uli Schlachter <psychon at znc.in>
Date:   Wed Aug 3 22:29:42 2011 +0200

    xlib-xcb: Implement the new backend functions
    
    This implements create_similar_image, map_to_image and unmap.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-xlib-xcb-surface.c b/src/cairo-xlib-xcb-surface.c
index b975113..aa74223 100644
--- a/src/cairo-xlib-xcb-surface.c
+++ b/src/cairo-xlib-xcb-surface.c
@@ -103,6 +103,41 @@ _cairo_xlib_xcb_surface_finish (void *abstract_surface)
     return status;
 }
 
+static cairo_surface_t *
+_cairo_xlib_xcb_surface_create_similar_image (void			*abstract_other,
+					      cairo_format_t		 format,
+					      int			 width,
+					      int			 height)
+{
+    cairo_xlib_xcb_surface_t *surface = abstract_other;
+    return cairo_surface_create_similar_image (&surface->xcb->base, format, width, height);
+}
+
+static cairo_surface_t *
+_cairo_xlib_xcb_surface_map_to_image (void *abstract_surface,
+				      const cairo_rectangle_int_t *extents)
+{
+    cairo_xlib_xcb_surface_t *surface = abstract_surface;
+    cairo_rectangle_t rect;
+
+    rect.x = extents->x;
+    rect.y = extents->y;
+    rect.width = extents->width;
+    rect.height = extents->height;
+
+    return cairo_surface_map_to_image (&surface->xcb->base, &rect);
+}
+
+static cairo_int_status_t
+_cairo_xlib_xcb_surface_unmap (void *abstract_surface,
+			       cairo_image_surface_t *image)
+{
+    cairo_xlib_xcb_surface_t *surface = abstract_surface;
+
+    cairo_surface_unmap_image (&surface->xcb->base, &image->base);
+    return cairo_surface_status (&surface->xcb->base);
+}
+
 static cairo_status_t
 _cairo_xlib_xcb_surface_acquire_source_image (void *abstract_surface,
 					      cairo_image_surface_t **image_out,
@@ -239,9 +274,9 @@ static const cairo_surface_backend_t _cairo_xlib_xcb_surface_backend = {
     _cairo_default_context_create, /* XXX */
 
     _cairo_xlib_xcb_surface_create_similar,
-    NULL, /* similar image */
-    NULL, /* map to image */
-    NULL, /* unmap image */
+    _cairo_xlib_xcb_surface_create_similar_image,
+    _cairo_xlib_xcb_surface_map_to_image,
+    _cairo_xlib_xcb_surface_unmap,
 
     _cairo_xlib_xcb_surface_acquire_source_image,
     _cairo_xlib_xcb_surface_release_source_image,
commit 51faa5a1c2d3d13b2d4b63c92ad1f12f63277d10
Author: Uli Schlachter <psychon at znc.in>
Date:   Wed Aug 3 21:38:27 2011 +0200

    surface_unmap_image: Fix fallback
    
    The fallback code assumed that the caller mapped the complete surface to an
    image. If only parts of a surface were mapped, the code didn't correctly
    translate and clip its operations.
    
    Fixes map-bit-to-image for xlib-xcb and improves the result for recording.
    
    Thanks to Chris Wilson for some simplifications.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 592eeef..fafc875 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -685,17 +685,34 @@ cairo_surface_unmap_image (cairo_surface_t *surface,
     if (surface->backend->unmap_image)
 	status = surface->backend->unmap_image (surface, (cairo_image_surface_t *) image);
     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+	cairo_image_surface_t *img = (cairo_image_surface_t *) image;
 	cairo_surface_pattern_t pattern;
+	cairo_clip_t *clip;
+	cairo_rectangle_int_t extents;
 
 	_cairo_pattern_init_for_surface (&pattern, image);
 	pattern.base.filter = CAIRO_FILTER_NEAREST;
 
+	/* We have to apply the translate from map_to_image's extents.x and .y */
+	cairo_matrix_init_translate (&pattern.base.matrix,
+				     image->device_transform.x0,
+				     image->device_transform.y0);
+
+	/* And we also have to clip the operation to the image's extents */
+	extents.x = image->device_transform_inverse.x0;
+	extents.y = image->device_transform_inverse.y0;
+	extents.width = img->width;
+	extents.height = img->height;
+
+	clip = _cairo_clip_intersect_rectangle (NULL, &extents);
+
 	status = _cairo_surface_paint (surface,
 				       CAIRO_OPERATOR_SOURCE,
 				       &pattern.base,
-				       NULL);
+				       clip);
 
 	_cairo_pattern_fini (&pattern.base);
+	_cairo_clip_destroy (clip);
     }
 
 error:


More information about the cairo-commit mailing list