[cairo] Analysis surface and clipping

Nick Wellnhofer wellnhofer at aevum.de
Sat Jan 20 12:28:05 PST 2007


I got an unexplainable performance hit when using clipping on PDF 
surfaces. The reason turned out to be that clipping was performed on the 
analysis surface with a clip mode of CAIRO_CLIP_MODE_MASK. AFAICS this 
rasterizes the clipping area, which could explain the drop in performance.

I'm not sure if clipping has to be done at all for analysis surfaces. 
The attached patch against the Mozilla trunk version of Cairo disables 
clipping of analysis surfaces in _cairo_meta_surface_replay.

Nick
-------------- next part --------------
--- mozilla-cvs/gfx/cairo/cairo/src/cairo-meta-surface.c	2006-12-23 02:15:53.000000000 +0100
+++ mozilla/gfx/cairo/cairo/src/cairo-meta-surface.c	2007-01-20 20:19:01.140862000 +0100
@@ -651,7 +651,8 @@ _cairo_meta_surface_replay (cairo_surfac
     meta = (cairo_meta_surface_t *) surface;
     status = CAIRO_STATUS_SUCCESS;
 
-    _cairo_clip_init (&clip, target);
+    if (target->type != CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS)
+        _cairo_clip_init (&clip, target);
 
     num_elements = meta->commands.num_elements;
     elements = _cairo_array_index (&meta->commands, 0);
@@ -660,7 +661,8 @@ _cairo_meta_surface_replay (cairo_surfac
 
 	/* For all commands except intersect_clip_path, we have to
 	 * ensure the current clip gets set on the surface. */
-	if (command->type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
+	if (target->type != CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS &&
+	    command->type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
 	    status = _cairo_surface_set_clip (target, &clip);
 	    if (status)
 		break;
@@ -753,14 +755,16 @@ _cairo_meta_surface_replay (cairo_surfac
 	case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
 	    /* XXX Meta surface clipping is broken and requires some
 	     * cairo-gstate.c rewriting.  Work around it for now. */
-	    if (dev_path == NULL)
-		status = _cairo_clip_reset (&clip);
-	    else
-		status = _cairo_clip_clip (&clip, dev_path,
-					   command->intersect_clip_path.fill_rule,
-					   command->intersect_clip_path.tolerance,
-					   command->intersect_clip_path.antialias,
-					   target);
+            if (target->type != CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS) {
+	        if (dev_path == NULL)
+		    status = _cairo_clip_reset (&clip);
+	        else
+		    status = _cairo_clip_clip (&clip, dev_path,
+					       command->intersect_clip_path.fill_rule,
+					       command->intersect_clip_path.tolerance,
+					       command->intersect_clip_path.antialias,
+					       target);
+	    }
 	    break;
 	default:
 	    ASSERT_NOT_REACHED;
@@ -773,7 +777,8 @@ _cairo_meta_surface_replay (cairo_surfac
 	    break;
     }
 
-    _cairo_clip_fini (&clip);
+    if (target->type != CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS)
+        _cairo_clip_fini (&clip);
 
     return status;
 }


More information about the cairo mailing list