Bug 587316 - Part 3: Allow custom operators when doing masking. r=jrmuizel
authorBas Schouten <bschouten@mozilla.com>
Mon, 16 Aug 2010 09:15:02 +0200
changeset 50650 1d7c15818f663035ce835a7c336d6d0496a7fe54
parent 50649 ea6bbdbf14906e86599d3648594ad5aefc322321
child 50651 055a407bb683d9e5d567d9972446dd1d5d61cd83
push id15108
push userbschouten@mozilla.com
push dateMon, 16 Aug 2010 07:15:44 +0000
treeherdermozilla-central@bffe7baa4e00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs587316
milestone2.0b4pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 587316 - Part 3: Allow custom operators when doing masking. r=jrmuizel
gfx/cairo/cairo/src/cairo-d2d-surface.cpp
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
+++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
@@ -2948,22 +2948,33 @@ static cairo_int_status_t
 		const cairo_pattern_t	*mask,
 		cairo_clip_t		*clip)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     cairo_rectangle_int_t extents;
 
     cairo_int_status_t status;
 
-    _begin_draw_state(d2dsurf);
-    status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
-
-    if (unlikely (status))
-	return status;
-
+    RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt;
+#ifndef ALWAYS_MANUAL_COMPOSITE
+    if (op != CAIRO_OPERATOR_OVER) {
+#endif
+	target_rt = _cairo_d2d_get_temp_rt(d2dsurf, clip);
+	if (!target_rt) {
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+	}
+#ifndef ALWAYS_MANUAL_COMPOSITE
+    } else {
+	_begin_draw_state(d2dsurf);
+	status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
+
+	if (unlikely(status))
+	    return status;
+    }
+#endif
 
     status = (cairo_int_status_t)_cairo_surface_mask_extents (&d2dsurf->base,
 		    op, source,
 		    mask,
 		    clip, &extents);
     if (unlikely (status))
 	    return status;
 
@@ -2984,42 +2995,50 @@ static cairo_int_status_t
     rect.bottom = (FLOAT)(extents.y + extents.height);
 
 
     if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
 	cairo_solid_pattern_t *solidPattern =
 	    (cairo_solid_pattern_t*)mask;
 	if (solidPattern->content = CAIRO_CONTENT_ALPHA) {
 	    brush->SetOpacity((FLOAT)solidPattern->color.alpha);
-	    d2dsurf->rt->FillRectangle(rect,
-				       brush);
+	    target_rt->FillRectangle(rect,
+				     brush);
 	    brush->SetOpacity(1.0);
+
+	    if (target_rt.get() != d2dsurf->rt.get()) {
+		return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
+	    }
 	    return CAIRO_INT_STATUS_SUCCESS;
 	}
     }
 
     RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, mask, true);
     if (!opacityBrush) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
     if (!d2dsurf->maskLayer) {
 	d2dsurf->rt->CreateLayer(&d2dsurf->maskLayer);
     }
-    d2dsurf->rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
-						 0,
-						 D2D1_ANTIALIAS_MODE_ALIASED,
-						 D2D1::IdentityMatrix(),
-						 1.0,
-						 opacityBrush),
-			   d2dsurf->maskLayer);
-
-    d2dsurf->rt->FillRectangle(rect,
-			       brush);
-    d2dsurf->rt->PopLayer();
+    target_rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
+					       0,
+					       D2D1_ANTIALIAS_MODE_ALIASED,
+					       D2D1::IdentityMatrix(),
+					       1.0,
+					       opacityBrush),
+			 d2dsurf->maskLayer);
+
+    target_rt->FillRectangle(rect,
+			     brush);
+    target_rt->PopLayer();
+
+    if (target_rt.get() != d2dsurf->rt.get()) {
+	return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
+    }
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_d2d_stroke(void			*surface,
 		  cairo_operator_t	 op,
 		  const cairo_pattern_t	*source,
 		  cairo_path_fixed_t	*path,