Bug 550475 - Part 2: Use new RefPtr class in D2D backend. r=jrmuizel
authorBas Schouten <bschouten@mozilla.com>
Fri, 09 Apr 2010 23:41:48 +0200
changeset 40634 6cba83fe343bddfad09761f8b343912e5d555b29
parent 40633 578336ac244d59e77ac19727b8aa9b56d3adb1d6
child 40635 eea9f123edfedafa5034662c5a9cbcda787272a2
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs550475
milestone1.9.3a5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 550475 - Part 2: Use new RefPtr class in D2D backend. r=jrmuizel
gfx/cairo/cairo/src/cairo-d2d-private.h
gfx/cairo/cairo/src/cairo-d2d-surface.cpp
gfx/cairo/cairo/src/cairo-dwrite-font.cpp
--- a/gfx/cairo/cairo/src/cairo-d2d-private.h
+++ b/gfx/cairo/cairo/src/cairo-d2d-private.h
@@ -42,56 +42,66 @@
 #include <d2d1.h>
 #include <d3d10.h>
 #include <dxgi.h>
 
 extern "C" {
 #include "cairoint.h"
 }
 
+#include "cairo-win32-refptr.h"
+
 struct _cairo_d2d_surface {
+    _cairo_d2d_surface() : clipRect(NULL), clipping(false), isDrawing(false),
+	textRenderingInit(true)
+    { }
+    ~_cairo_d2d_surface()
+    {
+	delete clipRect;
+    }
+
     cairo_surface_t base;
     /** Render target of the texture we render to */
-    ID2D1RenderTarget *rt;
+    RefPtr<ID2D1RenderTarget> rt;
     /** Surface containing our backstore */
-    ID3D10Resource *surface;
+    RefPtr<ID3D10Resource> surface;
     /** 
      * Surface used to temporarily store our surface if a bitmap isn't available
      * straight from our render target surface.
      */
-    ID3D10Texture2D *bufferTexture;
+    RefPtr<ID3D10Texture2D> bufferTexture;
     /** Backbuffer surface hwndrt renders to (NULL if not a window surface) */
-    IDXGISurface *backBuf;
+    RefPtr<IDXGISurface> backBuf;
     /** Bitmap shared with texture and rendered to by rt */
-    ID2D1Bitmap *surfaceBitmap;
+    RefPtr<ID2D1Bitmap> surfaceBitmap;
     /** Swap chain holding our backbuffer (NULL if not a window surface) */
-    IDXGISwapChain *dxgiChain;
+    RefPtr<IDXGISwapChain> dxgiChain;
     /** Window handle of the window we belong to */
     HWND hwnd;
     /** Format of the surface */
     cairo_format_t format;
     /** Geometry used for clipping when complex clipping is required */
-    ID2D1Geometry *clipMask;
+    RefPtr<ID2D1Geometry> clipMask;
     /** Clip rectangle for axis aligned rectangular clips */
     D2D1_RECT_F *clipRect;
     /** Clip layer used for pushing geometry clip mask */
-    ID2D1Layer *clipLayer;
+    RefPtr<ID2D1Layer> clipLayer;
     /** Mask layer used by surface_mask to push opacity masks */
-    ID2D1Layer *maskLayer;
+    RefPtr<ID2D1Layer> maskLayer;
     /**
      * Layer used for clipping when tiling, and also for clearing out geometries
      * - lazily initialized 
      */
-    ID2D1Layer *helperLayer;
+    RefPtr<ID2D1Layer> helperLayer;
     /** If this layer currently is clipping, used to prevent excessive push/pops */
     bool clipping;
     /** Brush used for bitmaps */
-    ID2D1BitmapBrush *bitmapBrush;
+    RefPtr<ID2D1BitmapBrush> bitmapBrush;
     /** Brush used for solid colors */
-    ID2D1SolidColorBrush *solidColorBrush;
+    RefPtr<ID2D1SolidColorBrush> solidColorBrush;
     /** Indicates if our render target is currently in drawing mode */
     bool isDrawing;
     /** Indicates if text rendering is initialized */
     bool textRenderingInit;
 };
 typedef struct _cairo_d2d_surface cairo_d2d_surface_t;
 
 typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
@@ -205,17 +215,17 @@ public:
 	}
 	return mDeviceInstance;
     }
 private:
     static ID3D10Device1 *mDeviceInstance;
 };
 
 
-ID2D1Brush*
+RefPtr<ID2D1Brush>
 _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf, 
 			            const cairo_pattern_t *pattern,
 				    unsigned int lastrun,
 				    unsigned int *runs_remaining,
 				    bool *pushed_clip,
 				    bool unique = false);
 #endif /* CAIRO_HAS_D2D_SURFACE */
 #endif /* CAIRO_D2D_PRIVATE_H */
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
+++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
@@ -39,16 +39,18 @@
 #include "cairo-d2d-private.h"
 #include "cairo-dwrite-private.h"
 
 extern "C" {
 #include "cairo-win32.h"
 #include "cairo-analysis-surface-private.h"
 }
 
+// Required for using placement new.
+#include <new>
 
 ID2D1Factory *D2DSurfFactory::mFactoryInstance = NULL;
 ID3D10Device1 *D3D10Factory::mDeviceInstance = NULL;
 
 #define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)CAIRO_STATUS_SUCCESS
 
 /**
  * Create a similar surface which will blend effectively to
@@ -384,32 +386,31 @@ static ID3D10Texture2D*
  */
 static void _cairo_d2d_update_surface_bitmap(cairo_d2d_surface_t *d2dsurf)
 {
     if (!d2dsurf->backBuf) {
 	return;
     }
     ID3D10Texture2D *texture = _cairo_d2d_get_buffer_texture(d2dsurf);
     if (!d2dsurf->surfaceBitmap) {
-	IDXGISurface *dxgiSurface;
+	RefPtr<IDXGISurface> dxgiSurface;
 	D2D1_ALPHA_MODE alpha;
 	if (d2dsurf->base.content == CAIRO_CONTENT_COLOR) {
 	    alpha = D2D1_ALPHA_MODE_IGNORE;
 	} else {
 	    alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
 	}
         /** Using DXGI_FORMAT_UNKNOWN will automatically use the texture's format. */
 	D2D1_BITMAP_PROPERTIES bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN,
 										   alpha));
 	texture->QueryInterface(&dxgiSurface);
 	d2dsurf->rt->CreateSharedBitmap(IID_IDXGISurface,
 					dxgiSurface,
 					&bitProps,
 					&d2dsurf->surfaceBitmap);
-	dxgiSurface->Release();
     }
     D3D10Factory::Device()->CopyResource(texture, d2dsurf->surface);
 }
 
 /**
  * Present the backbuffer for a surface create for an HWND. This needs
  * to be called when the owner of the original window surface wants to
  * actually present the executed drawing operations to the screen.
@@ -522,17 +523,17 @@ static D2D1::Matrix3x2F
 
 /**
  * Create a D2D stroke style interface for a cairo stroke style object. Must be
  * released when the calling function is finished with it.
  *
  * \param style Cairo stroke style object
  * \return D2D StrokeStyle interface
  */
-static ID2D1StrokeStyle*
+static RefPtr<ID2D1StrokeStyle>
 _cairo_d2d_create_strokestyle_for_stroke_style(const cairo_stroke_style_t *style)
 {
     D2D1_CAP_STYLE line_cap = D2D1_CAP_STYLE_FLAT;
     switch (style->line_cap) {
 	case CAIRO_LINE_CAP_BUTT:
 	    line_cap = D2D1_CAP_STYLE_FLAT;
 	    break;
 	case CAIRO_LINE_CAP_SQUARE:
@@ -564,17 +565,17 @@ static ID2D1StrokeStyle*
 	}
     }
 
     D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID;
     if (dashes) {
 	dashStyle = D2D1_DASH_STYLE_CUSTOM;
     }
 
-    ID2D1StrokeStyle *strokeStyle;
+    RefPtr<ID2D1StrokeStyle> strokeStyle;
     D2DSurfFactory::Instance()->CreateStrokeStyle(D2D1::StrokeStyleProperties(line_cap, 
 									      line_cap,
 									      line_cap, 
 									      line_join, 
 									      (FLOAT)style->miter_limit,
 									      dashStyle,
 									      (FLOAT)style->dash_offset),
 						  dashes,
@@ -583,35 +584,34 @@ static ID2D1StrokeStyle*
     delete [] dashes;
     return strokeStyle;
 }
 
 cairo_user_data_key_t bitmap_key;
 
 struct cached_bitmap {
     /** The cached bitmap */
-    ID2D1Bitmap *bitmap;
+    RefPtr<ID2D1Bitmap> bitmap;
     /** The cached bitmap was created with a transparent rectangle around it */
     bool isNoneExtended;
     /** The cached bitmap is dirty and needs its data refreshed */
     bool dirty;
     /** Order of snapshot detach/release bitmap called not guaranteed, single threaded refcount for now */
     int refs;
 };
 
 /** 
  * This is called when user data on a surface is replaced or the surface is
  * destroyed.
  */
 static void _d2d_release_bitmap(void *bitmap)
 {
-    cached_bitmap *bitmp = (cached_bitmap*)bitmap;
-    bitmp->bitmap->Release();
-    if (!--bitmp->refs) {
-	delete bitmap;
+    cached_bitmap *existingBitmap = (cached_bitmap*)bitmap;
+    if (!--existingBitmap->refs) {
+	delete existingBitmap;
     }
 }
 
 /**
  * Via a little trick this is just used to determine when a surface has been
  * modified.
  */
 static void _d2d_snapshot_detached(cairo_surface_t *surface)
@@ -636,45 +636,44 @@ static void _d2d_snapshot_detached(cairo
  *
  * \param d2dsurf Surface to create a brush for
  * \param pattern The pattern to create a brush for
  * \param unique We cache the bitmap/color brush for speed. If this
  * needs a brush that is unique (i.e. when more than one is needed),
  * this will make the function return a seperate brush.
  * \return A brush object
  */
-ID2D1Brush*
+RefPtr<ID2D1Brush>
 _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf, 
 				    const cairo_pattern_t *pattern,
 				    unsigned int last_run,
 				    unsigned int *remaining_runs,
 				    bool *pushed_clip,
 				    bool unique)
 {
     *remaining_runs = 1;
     *pushed_clip = false;
 
     if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
 	cairo_solid_pattern_t *sourcePattern =
 	    (cairo_solid_pattern_t*)pattern;
 	D2D1_COLOR_F color = _cairo_d2d_color_from_cairo_color(sourcePattern->color);
 	if (unique) {
-	    ID2D1SolidColorBrush *brush;
+	    RefPtr<ID2D1SolidColorBrush> brush;
 	    d2dsurf->rt->CreateSolidColorBrush(color,
 					       &brush);
 	    *remaining_runs = 0;
 	    return brush;
 	} else {
 	    if (d2dsurf->solidColorBrush->GetColor().a != color.a ||
 		d2dsurf->solidColorBrush->GetColor().r != color.r ||
 		d2dsurf->solidColorBrush->GetColor().g != color.g ||
 		d2dsurf->solidColorBrush->GetColor().b != color.b) {
 		d2dsurf->solidColorBrush->SetColor(color);
 	    }
-	    d2dsurf->solidColorBrush->AddRef();
 	    *remaining_runs = 0;
 	    return d2dsurf->solidColorBrush;
 	}
 
     } else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
 	cairo_matrix_t mat = pattern->matrix;
 	/**
 	 * Cairo views this matrix as the transformation of the destination
@@ -690,26 +689,25 @@ ID2D1Brush*
 
 	D2D1_GRADIENT_STOP *stops = 
 	    new D2D1_GRADIENT_STOP[sourcePattern->base.n_stops];
 	for (unsigned int i = 0; i < sourcePattern->base.n_stops; i++) {
 	    stops[i].position = (FLOAT)sourcePattern->base.stops[i].offset;
 	    stops[i].color = 
 		_cairo_d2d_color_from_cairo_color(sourcePattern->base.stops[i].color);
 	}
-	ID2D1GradientStopCollection *stopCollection;
+	RefPtr<ID2D1GradientStopCollection> stopCollection;
 	d2dsurf->rt->CreateGradientStopCollection(stops, sourcePattern->base.n_stops, &stopCollection);
-	ID2D1LinearGradientBrush *brush;
+	RefPtr<ID2D1LinearGradientBrush> brush;
 	d2dsurf->rt->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(_d2d_point_from_cairo_point(&sourcePattern->p1),
 										   _d2d_point_from_cairo_point(&sourcePattern->p2)),
 					       brushProps,
 					       stopCollection,
 					       &brush);
 	delete [] stops;
-	stopCollection->Release();
 	*remaining_runs = 0;
 	return brush;
 
     } else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) {
 	cairo_matrix_t mat = pattern->matrix;
 	cairo_matrix_invert(&mat);
 
 	D2D1_BRUSH_PROPERTIES brushProps =
@@ -735,28 +733,27 @@ ID2D1Brush*
 
 	D2D1_GRADIENT_STOP *stops = 
 	    new D2D1_GRADIENT_STOP[sourcePattern->base.n_stops];
 	for (unsigned int i = 0; i < sourcePattern->base.n_stops; i++) {
 	    stops[i].position = (FLOAT)sourcePattern->base.stops[i].offset;
 	    stops[i].color = 
 		_cairo_d2d_color_from_cairo_color(sourcePattern->base.stops[i].color);
 	}
-	ID2D1GradientStopCollection *stopCollection;
+	RefPtr<ID2D1GradientStopCollection> stopCollection;
 	d2dsurf->rt->CreateGradientStopCollection(stops, sourcePattern->base.n_stops, &stopCollection);
-	ID2D1RadialGradientBrush *brush;
+	RefPtr<ID2D1RadialGradientBrush> brush;
 
 	d2dsurf->rt->CreateRadialGradientBrush(D2D1::RadialGradientBrushProperties(center,
 										   origin,
 										   _cairo_fixed_to_float(sourcePattern->r2),
 										   _cairo_fixed_to_float(sourcePattern->r2)),
 					       brushProps,
 					       stopCollection,
 					       &brush);
-	stopCollection->Release();
 	delete [] stops;
 	*remaining_runs = 0;
 	return brush;
 
     } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	cairo_matrix_t mat = pattern->matrix;
 	cairo_matrix_invert(&mat);
 
@@ -839,31 +836,30 @@ ID2D1Brush*
 		xoffset = current_horiz_tile * maxSize;
 		yoffset = current_vert_tile * maxSize;
 		*remaining_runs = horiz_tiles * vert_tiles - last_run - 1;
 		width = min(maxSize, srcSurf->width - maxSize * current_horiz_tile);
 		height = min(maxSize, srcSurf->height - maxSize * current_vert_tile);
 		// Move the image to the right spot.
 		cairo_matrix_translate(&mat, xoffset, yoffset);
 		if (true) {
-		    ID2D1RectangleGeometry *clipRect;
+		    RefPtr<ID2D1RectangleGeometry> clipRect;
 		    D2DSurfFactory::Instance()->CreateRectangleGeometry(D2D1::RectF(0, 0, (float)width, (float)height),
 									&clipRect);
 
 		    if (!d2dsurf->helperLayer) {
 			d2dsurf->rt->CreateLayer(&d2dsurf->helperLayer);
 		    }
 		    
 		    d2dsurf->rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
 								 clipRect,
 								 D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
 								 _cairo_d2d_matrix_from_matrix(&mat)),
 					   d2dsurf->helperLayer);
 		    *pushed_clip = true;
-		    clipRect->Release();
 		}
 	    } else {
 		width = srcSurf->width;
 		height = srcSurf->height;
 	    }
 
 	    cached_bitmap *cachebitmap = NULL;
 	    if (!tiled) {
@@ -964,17 +960,17 @@ ID2D1Brush*
 						   extendMode,
 						   D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
 	} else {
 	    bitProps = D2D1::BitmapBrushProperties(extendMode,
 						   extendMode,
 						   D2D1_BITMAP_INTERPOLATION_MODE_LINEAR);
 	}
 	if (unique) {
-	    ID2D1BitmapBrush *bitBrush;
+	    RefPtr<ID2D1BitmapBrush> bitBrush;
 	    D2D1_BRUSH_PROPERTIES brushProps =
 		D2D1::BrushProperties(1.0, _cairo_d2d_matrix_from_matrix(&mat));
 	    d2dsurf->rt->CreateBitmapBrush(sourceBitmap, 
 					   &bitProps,
 					   &brushProps,
 					   &bitBrush);
 	    return bitBrush;
 	} else {
@@ -995,17 +991,16 @@ ID2D1Brush*
 	    } else {
 		D2D1_BRUSH_PROPERTIES brushProps =
 		    D2D1::BrushProperties(1.0, _cairo_d2d_matrix_from_matrix(&mat));
 		d2dsurf->rt->CreateBitmapBrush(sourceBitmap,
 					       &bitProps,
 					       &brushProps,
 					       &d2dsurf->bitmapBrush);
 	    }
-	    d2dsurf->bitmapBrush->AddRef();
 	    return d2dsurf->bitmapBrush;
 	}
     } else {
 	return NULL;
     }
 }
 
 
@@ -1099,24 +1094,24 @@ static cairo_status_t
 /**
  * Create an ID2D1PathGeometry for a cairo_path_fixed_t
  *
  * \param path Path to create a geometry for
  * \param fill_rule Fill rule to use
  * \param type Figure begin type to use
  * \return A D2D geometry
  */
-static ID2D1PathGeometry*
+static RefPtr<ID2D1PathGeometry>
 _cairo_d2d_create_path_geometry_for_path(cairo_path_fixed_t *path, 
 					 cairo_fill_rule_t fill_rule,
 					 D2D1_FIGURE_BEGIN type)
 {
-    ID2D1PathGeometry *d2dpath;
+    RefPtr<ID2D1PathGeometry> d2dpath;
     D2DSurfFactory::Instance()->CreatePathGeometry(&d2dpath);
-    ID2D1GeometrySink *sink;
+    RefPtr<ID2D1GeometrySink> sink;
     d2dpath->Open(&sink);
     D2D1_FILL_MODE fillMode = D2D1_FILL_MODE_WINDING;
     if (fill_rule == CAIRO_FILL_RULE_WINDING) {
 	fillMode = D2D1_FILL_MODE_WINDING;
     } else if (fill_rule == CAIRO_FILL_RULE_EVEN_ODD) {
 	fillMode = D2D1_FILL_MODE_ALTERNATE;
     }
     sink->SetFillMode(fillMode);
@@ -1131,17 +1126,16 @@ static ID2D1PathGeometry*
 				_cairo_d2d_path_line_to,
 				_cairo_d2d_path_curve_to,
 				_cairo_d2d_path_close,
 				&pathConvert);
     if (pathConvert.figureActive) {
 	sink->EndFigure(D2D1_FIGURE_END_OPEN);
     }
     sink->Close();
-    sink->Release();
     return d2dpath;
 }
 
 /**
  * We use this to clear out a certain path on a surface. This will respect
  * the existing clip.
  *
  * \param d2dsurf Surface we clear
@@ -1158,21 +1152,21 @@ static void _cairo_d2d_clear_geometry(ca
 	/**
 	 * We have an axis aligned rectangular clip and no pathGeometry, we can
 	 * just clear the surface.
 	 */
 	d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
 	return;
     }
 
-    IDXGISurface *dxgiSurface;
-    ID2D1Bitmap *bitmp;
+    RefPtr<IDXGISurface> dxgiSurface;
+    RefPtr<ID2D1Bitmap> bitmp;
 
     /** Create a temporary buffer for our surface content */
-    ID3D10Texture2D *bufTexture = _cairo_d2d_get_buffer_texture(d2dsurf);
+    RefPtr<ID3D10Texture2D> bufTexture = _cairo_d2d_get_buffer_texture(d2dsurf);
 
     /** Copy our contents into the temporary buffer */
     D3D10Factory::Device()->CopyResource(bufTexture, d2dsurf->surface);
 
     /** Make the temporary buffer available as a D2D Bitmap */
     bufTexture->QueryInterface(&dxgiSurface);
     D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
 									    D2D1_ALPHA_MODE_PREMULTIPLIED));
@@ -1182,43 +1176,40 @@ static void _cairo_d2d_clear_geometry(ca
 						 &bitmp);
 
     /** Clear our original surface */
     d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
 
     DXGI_SURFACE_DESC desc;
     dxgiSurface->GetDesc(&desc);
 
-    ID2D1RectangleGeometry *rectGeom;
-    ID2D1PathGeometry *inverse;
-    ID2D1Geometry *clearGeometry;
-    ID2D1GeometrySink *sink;
+    RefPtr<ID2D1RectangleGeometry> rectGeom;
+    RefPtr<ID2D1PathGeometry> inverse;
+    RefPtr<ID2D1Geometry> clearGeometry;
+    RefPtr<ID2D1GeometrySink> sink;
 
     if (!d2dsurf->clipMask) {
 	/** No clip mask, our clear geometry is equal to our path geometry. */
 	clearGeometry = pathGeometry;
-	clearGeometry->AddRef();
     } else if (!pathGeometry) {
 	/** No path geometry, our clear geometry is equal to our clip mask. */
 	clearGeometry = d2dsurf->clipMask;
-	clearGeometry->AddRef();
     } else {
 	/**
 	 * A clipping mask and a pathGeometry, the intersect of the two
 	 * geometries is the area of the surface that we want to clear.
 	 */
-	ID2D1PathGeometry *clipPathUnion;
+	RefPtr<ID2D1PathGeometry> clipPathUnion;
 	D2DSurfFactory::Instance()->CreatePathGeometry(&clipPathUnion);
 	clipPathUnion->Open(&sink);
 	pathGeometry->CombineWithGeometry(d2dsurf->clipMask,
 					  D2D1_COMBINE_MODE_INTERSECT,
 					  D2D1::IdentityMatrix(),
 					  sink);
 	sink->Close();
-	sink->Release();
 	clearGeometry = clipPathUnion;
     }
 
     if (d2dsurf->clipMask) {
 	/** If we have a clip mask, we'll need to pop the surface clip */
 	_cairo_d2d_surface_pop_clip(d2dsurf);
     }
 
@@ -1226,30 +1217,23 @@ static void _cairo_d2d_clear_geometry(ca
      * Calculate the inverse of the geometry to clear. This is the clip mask
      * when drawing our original content back to the surface.
      */
     D2DSurfFactory::Instance()->CreatePathGeometry(&inverse);
     inverse->Open(&sink);
     D2DSurfFactory::Instance()->CreateRectangleGeometry(D2D1::RectF(0, 0, (FLOAT)desc.Width, (FLOAT)desc.Height), &rectGeom);
     rectGeom->CombineWithGeometry(clearGeometry, D2D1_COMBINE_MODE_EXCLUDE, D2D1::IdentityMatrix(), sink);
     sink->Close();
-    sink->Release();
-    rectGeom->Release();
-    clearGeometry->Release();
 
     /** Clip by the inverse and draw our content back to the surface */
     d2dsurf->rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), inverse),
 			   d2dsurf->helperLayer);
     d2dsurf->rt->DrawBitmap(bitmp);
     d2dsurf->rt->PopLayer();
 
-    bitmp->Release();
-    dxgiSurface->Release();
-    inverse->Release();
-
     if (d2dsurf->clipMask) {
 	/** If we have a clip mask, we'll need to push back the surface clip */
 	_cairo_d2d_surface_push_clip(d2dsurf);
     }
 }
 
 static cairo_operator_t _cairo_d2d_simplify_operator(cairo_operator_t op,
 						     const cairo_pattern_t *source)
@@ -1278,19 +1262,19 @@ static cairo_surface_t*
 _cairo_d2d_create_similar(void			*surface,
 			  cairo_content_t	 content,
 			  int			 width,
 			  int			 height)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
     
-    memset(newSurf, 0, sizeof(cairo_d2d_surface_t));
+    new (newSurf) cairo_d2d_surface_t();
+    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
 
-    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, content);
 
     D2D1_SIZE_U sizePixels;
     D2D1_SIZE_F size;
     HRESULT hr;
 
     sizePixels.width = width;
     sizePixels.height = height;
     FLOAT dpiX;
@@ -1317,147 +1301,101 @@ static cairo_surface_t*
 								       dpiY);
 
     if (sizePixels.width < 1) {
 	sizePixels.width = 1;
     }
     if (sizePixels.height < 1) {
 	sizePixels.height = 1;
     }
-    IDXGISurface *oldDxgiSurface;
+    RefPtr<IDXGISurface> oldDxgiSurface;
     d2dsurf->surface->QueryInterface(&oldDxgiSurface);
     DXGI_SURFACE_DESC origDesc;
 
     oldDxgiSurface->GetDesc(&origDesc);
-    oldDxgiSurface->Release();
 
     CD3D10_TEXTURE2D_DESC desc(origDesc.Format,
 			       sizePixels.width,
 			       sizePixels.height);
 
     if (content == CAIRO_CONTENT_ALPHA) {
 	desc.Format = DXGI_FORMAT_A8_UNORM;
     }
 
     desc.MipLevels = 1;
     desc.Usage = D3D10_USAGE_DEFAULT;
     desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
-    ID3D10Texture2D *texture;
+    RefPtr<ID3D10Texture2D> texture;
+    RefPtr<IDXGISurface> dxgiSurface;
 
     hr = D3D10Factory::Device()->CreateTexture2D(&desc, NULL, &texture);
     if (FAILED(hr)) {
-	goto FAIL_D3DTEXTURE;
+	goto FAIL_CREATESIMILAR;
     }
 
     newSurf->surface = texture;
 
     // Create the DXGI surface.
-    IDXGISurface *dxgiSurface;
     hr = newSurf->surface->QueryInterface(IID_IDXGISurface, (void**)&dxgiSurface);
     if (FAILED(hr)) {
-	goto FAIL_DXGISURFACE;
+	goto FAIL_CREATESIMILAR;
     }
     hr = D2DSurfFactory::Instance()->CreateDxgiSurfaceRenderTarget(dxgiSurface,
 								   props,
 								   &newSurf->rt);
 
     if (FAILED(hr)) {
-	goto FAIL_DXGIRT;
+	goto FAIL_CREATESIMILAR;
     }
 
     hr = newSurf->rt->CreateSharedBitmap(IID_IDXGISurface,
 					 dxgiSurface,
 					 &bitProps,
 					 &newSurf->surfaceBitmap);
     if (FAILED(hr)) {
-	goto FAIL_SHAREDBITMAP;
+	goto FAIL_CREATESIMILAR;
     }
 
-    dxgiSurface->Release();
-
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
     return reinterpret_cast<cairo_surface_t*>(newSurf);
 
-FAIL_SHAREDBITMAP:
-    newSurf->rt->Release();
-FAIL_DXGIRT:
-    dxgiSurface->Release();
-FAIL_DXGISURFACE:
-    newSurf->surface->Release();
-FAIL_D3DTEXTURE:
+FAIL_CREATESIMILAR:
+    /** Ensure we call our surfaces desctructor */
+    newSurf->~cairo_d2d_surface_t();
     free(newSurf);
     return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
 }
 
 static cairo_status_t
 _cairo_d2d_finish(void	    *surface)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
-    if (d2dsurf->rt) {
-	d2dsurf->rt->Release();
-    }
-    if (d2dsurf->surfaceBitmap) {
-	d2dsurf->surfaceBitmap->Release();
-    }
-    if (d2dsurf->backBuf) {
-	d2dsurf->backBuf->Release();
-    }
-    if (d2dsurf->dxgiChain) {
-	d2dsurf->dxgiChain->Release();
-    }
-    if (d2dsurf->clipMask) {
-	d2dsurf->clipMask->Release();
-    }
-    if (d2dsurf->clipRect) {
-	delete d2dsurf->clipRect;
-    }
-    if (d2dsurf->clipLayer) {
-	d2dsurf->clipLayer->Release();
-    }
-    if (d2dsurf->maskLayer) {
-	d2dsurf->maskLayer->Release();
-    }
-    if (d2dsurf->solidColorBrush) {
-	d2dsurf->solidColorBrush->Release();
-    }
-    if (d2dsurf->bitmapBrush) {
-	d2dsurf->bitmapBrush->Release();
-    }
-    if (d2dsurf->surface) {
-	d2dsurf->surface->Release();
-    }
-    if (d2dsurf->helperLayer) {
-	d2dsurf->helperLayer->Release();
-    }
-    if (d2dsurf->bufferTexture) {
-	d2dsurf->bufferTexture->Release();
-    }
+    d2dsurf->~cairo_d2d_surface_t();
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
 _cairo_d2d_acquire_source_image(void                    *abstract_surface,
 				cairo_image_surface_t  **image_out,
 				void                   **image_extra)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(abstract_surface);
     _cairo_d2d_flush(d2dsurf);
 
     HRESULT hr;
     D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
 
-    ID3D10Texture2D *softTexture;
+    RefPtr<ID3D10Texture2D> softTexture;
 
-    IDXGISurface *dxgiSurface;
+    RefPtr<IDXGISurface> dxgiSurface;
     d2dsurf->surface->QueryInterface(&dxgiSurface);
     DXGI_SURFACE_DESC desc;
 
     dxgiSurface->GetDesc(&desc);
-    dxgiSurface->Release();
 
     CD3D10_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
 
     /**
      * We can't actually map our backing store texture, so we create one in CPU memory, and then
      * tell D3D to copy the data from our surface there, readback is expensive, we -never-
      * -ever- want this to happen.
      */
@@ -1470,26 +1408,25 @@ static cairo_status_t
 	return CAIRO_STATUS_NO_MEMORY;
     }
 
     D3D10Factory::Device()->CopyResource(softTexture, d2dsurf->surface);
 
     D3D10_MAPPED_TEXTURE2D data;
     hr = softTexture->Map(0, D3D10_MAP_READ_WRITE, 0, &data);
     if (FAILED(hr)) {
-	softTexture->Release();
 	return (cairo_status_t)CAIRO_INT_STATUS_UNSUPPORTED;
     }
     *image_out = 
 	(cairo_image_surface_t*)_cairo_image_surface_create_for_data_with_content((unsigned char*)data.pData,
 										  CAIRO_CONTENT_COLOR_ALPHA,
 										  size.width,
 										  size.height,
 										  data.RowPitch);
-    *image_extra = softTexture;
+    *image_extra = softTexture.forget();
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_d2d_release_source_image(void                   *abstract_surface,
 				cairo_image_surface_t  *image,
 				void                   *image_extra)
@@ -1515,25 +1452,24 @@ static cairo_status_t
 			      void                   **image_extra)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(abstract_surface);
     _cairo_d2d_flush(d2dsurf);
 
     HRESULT hr;
     D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
 
-    ID3D10Texture2D *softTexture;
+    RefPtr<ID3D10Texture2D> softTexture;
 
 
-    IDXGISurface *dxgiSurface;
+    RefPtr<IDXGISurface> dxgiSurface;
     d2dsurf->surface->QueryInterface(&dxgiSurface);
     DXGI_SURFACE_DESC desc;
 
     dxgiSurface->GetDesc(&desc);
-    dxgiSurface->Release();
 
     CD3D10_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
 
     image_rect->width = desc.Width;
     image_rect->height = desc.Height;
     image_rect->x = image_rect->y = 0;
 
     softDesc.MipLevels = 1;
@@ -1544,26 +1480,25 @@ static cairo_status_t
     if (FAILED(hr)) {
 	return CAIRO_STATUS_NO_MEMORY;
     }
     D3D10Factory::Device()->CopyResource(softTexture, d2dsurf->surface);
 
     D3D10_MAPPED_TEXTURE2D data;
     hr = softTexture->Map(0, D3D10_MAP_READ_WRITE, 0, &data);
     if (FAILED(hr)) {
-	softTexture->Release();
 	return (cairo_status_t)CAIRO_INT_STATUS_UNSUPPORTED;
     }
     *image_out = 
 	(cairo_image_surface_t*)_cairo_image_surface_create_for_data_with_content((unsigned char*)data.pData,
 										  CAIRO_CONTENT_COLOR_ALPHA,
 										  size.width,
 										  size.height,
 										  data.RowPitch);
-    *image_extra = softTexture;
+    *image_extra = softTexture.forget();
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static void
 _cairo_d2d_release_dest_image(void                    *abstract_surface,
 			      cairo_rectangle_int_t   *interest_rect,
 			      cairo_image_surface_t   *image,
@@ -1596,17 +1531,16 @@ cairo_int_status_t
 			       double			tolerance,
 			       cairo_antialias_t	antialias)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(dst);
 
     _cairo_d2d_surface_pop_clip(d2dsurf);
     if (!path) {
 	if (d2dsurf->clipMask) {
-	    d2dsurf->clipMask->Release();
 	    d2dsurf->clipMask = NULL;
 	}
 	if (d2dsurf->clipRect) {
 	    delete d2dsurf->clipRect;
 	    d2dsurf->clipRect = NULL;
 	}
 	return CAIRO_INT_STATUS_SUCCESS;
     }
@@ -1637,89 +1571,77 @@ cairo_int_status_t
 		d2dsurf->clipRect->left = d2dsurf->clipRect->right;
 	    }
 	    return CAIRO_INT_STATUS_SUCCESS;
 	} else {
 	    /** 
 	     * We have a mask, see if this rect is completely contained by it, so we
 	     * can optimize by just using this rect rather than a geometry mask.
 	     */
-	    ID2D1RectangleGeometry *newMask;
+	    RefPtr<ID2D1RectangleGeometry> newMask;
 	    D2DSurfFactory::Instance()->CreateRectangleGeometry(D2D1::RectF(_cairo_fixed_to_float(box.p1.x),
 									    _cairo_fixed_to_float(box.p1.y),
 									    _cairo_fixed_to_float(box.p2.x),
 									    _cairo_fixed_to_float(box.p2.y)), 
 								&newMask);
 	    D2D1_GEOMETRY_RELATION relation;
 	    d2dsurf->clipMask->CompareWithGeometry(newMask, D2D1::Matrix3x2F::Identity(), &relation);
 	    if (relation == D2D1_GEOMETRY_RELATION_CONTAINS) {
-	        d2dsurf->clipMask->Release();
 		d2dsurf->clipMask = NULL;
-	        newMask->Release();
 	        d2dsurf->clipRect = new D2D1_RECT_F(D2D1::RectF(_cairo_fixed_to_float(box.p1.x),
 								_cairo_fixed_to_float(box.p1.y),
 								_cairo_fixed_to_float(box.p2.x),
 								_cairo_fixed_to_float(box.p2.y)));
 		return CAIRO_INT_STATUS_SUCCESS;		    
 		
 	    }
-	    newMask->Release();
 	}
     }
     
     if (!d2dsurf->clipRect && !d2dsurf->clipMask) {
 	/** Nothing yet, just use this clip path */
 	d2dsurf->clipMask = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
     } else if (d2dsurf->clipMask) {
 	/** We already have a clip mask, combine the two into a new clip mask */
-	ID2D1Geometry *newMask = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
-	ID2D1PathGeometry *finalMask;
+	RefPtr<ID2D1Geometry> newMask = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
+	RefPtr<ID2D1PathGeometry> finalMask;
 	D2DSurfFactory::Instance()->CreatePathGeometry(&finalMask);
-	ID2D1GeometrySink *sink;
+	RefPtr<ID2D1GeometrySink> sink;
 	finalMask->Open(&sink);
 	newMask->CombineWithGeometry(d2dsurf->clipMask,
 				     D2D1_COMBINE_MODE_INTERSECT,
 				     D2D1::Matrix3x2F::Identity(),
 				     sink);
 	sink->Close();
-	sink->Release();
-	d2dsurf->clipMask->Release();
-	newMask->Release();
 	d2dsurf->clipMask = finalMask;
     } else if (d2dsurf->clipRect) {
 	/** 
 	 * We have a clip rect, if we contain it, we can keep using that, if
 	 * it contains the new path, use the new path, otherwise, go into a
 	 * potentially expensive combine.
 	 */
-	ID2D1RectangleGeometry *currentMask;
+	RefPtr<ID2D1RectangleGeometry> currentMask;
 	D2DSurfFactory::Instance()->CreateRectangleGeometry(d2dsurf->clipRect, &currentMask);
-	ID2D1Geometry *newMask = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
+	RefPtr<ID2D1Geometry> newMask = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
         D2D1_GEOMETRY_RELATION relation;
 	newMask->CompareWithGeometry(currentMask, D2D1::Matrix3x2F::Identity(), &relation);
 	if (relation == D2D1_GEOMETRY_RELATION_CONTAINS) {
-	    currentMask->Release();
-	    newMask->Release();
 	    return CAIRO_INT_STATUS_SUCCESS;
 	} else if (relation == D2D1_GEOMETRY_RELATION_IS_CONTAINED) {
-	    currentMask->Release();
 	    d2dsurf->clipMask = newMask;
 	} else {
-	    ID2D1PathGeometry *finalMask;
+	    RefPtr<ID2D1PathGeometry> finalMask;
 	    D2DSurfFactory::Instance()->CreatePathGeometry(&finalMask);
-	    ID2D1GeometrySink *sink;
+	    RefPtr<ID2D1GeometrySink> sink;
 	    finalMask->Open(&sink);
 	    newMask->CombineWithGeometry(currentMask,
 					 D2D1_COMBINE_MODE_INTERSECT,
 					 D2D1::Matrix3x2F::Identity(),
 					 sink);
 	    sink->Close();
-	    sink->Release();
-	    currentMask->Release();
-	    newMask->Release();
 	    d2dsurf->clipMask = finalMask;
 	}
     }
 
     if (d2dsurf->clipRect) {
 	delete d2dsurf->clipRect;
 	d2dsurf->clipRect = NULL;
     }
@@ -1758,21 +1680,21 @@ static cairo_int_status_t
 
     d2dsurf->rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
 
     unsigned int runs_remaining = 1;
     unsigned int last_run = 0;
     bool pushed_clip = false;
 
     while (runs_remaining) {
-	ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
-								source,
-								last_run++,
-								&runs_remaining,
-								&pushed_clip);
+	RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
+								       source,
+								       last_run++,
+								       &runs_remaining,
+								       &pushed_clip);
 
 	if (!brush) {
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
 	if (op == CAIRO_OPERATOR_OVER && extents) {
 	    d2dsurf->rt->FillRectangle(D2D1::RectF((FLOAT)extents->x,
 						   (FLOAT)extents->y,
 						   (FLOAT)extents->x + extents->width,
@@ -1789,20 +1711,18 @@ static cairo_int_status_t
 	    D2D1_SIZE_F size = d2dsurf->rt->GetSize();
             d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
             d2dsurf->rt->FillRectangle(D2D1::RectF((FLOAT)0,
 						   (FLOAT)0,
 						   (FLOAT)size.width,
 						   (FLOAT)size.height),
 				       brush);
         } else {
-	    brush->Release();
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
-	brush->Release();
 
 	if (pushed_clip) {
 	    d2dsurf->rt->PopLayer();
 	}
     }
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
@@ -1814,22 +1734,21 @@ static cairo_int_status_t
 		cairo_rectangle_int_t	*extents)
 {
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     _begin_draw_state(d2dsurf);
 
     unsigned int runs_remaining = 0;
     bool pushed_clip;
 
-    ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, source, 0, &runs_remaining, &pushed_clip);
+    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, source, 0, &runs_remaining, &pushed_clip);
     if (!brush) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     if (runs_remaining) {
-	brush->Release();
 	// TODO: Implement me!!
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     D2D1_RECT_F rect = D2D1::RectF(0,
 				   0,
 				   (FLOAT)d2dsurf->rt->GetPixelSize().width,
 				   (FLOAT)d2dsurf->rt->GetPixelSize().height);
     if (extents) {
@@ -1842,46 +1761,40 @@ static cairo_int_status_t
     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);
 	    brush->SetOpacity(1.0);
-	    brush->Release();
 	    return CAIRO_INT_STATUS_SUCCESS;
 	}
     }
-    ID2D1Brush *opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, mask, 0, &runs_remaining, &pushed_clip, true);
+    RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, mask, 0, &runs_remaining, &pushed_clip, true);
     if (!opacityBrush) {
-	brush->Release();
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     if (runs_remaining) {
-	brush->Release();
-	opacityBrush->Release();
 	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();
-    brush->Release();
-    opacityBrush->Release();
     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,
@@ -1907,112 +1820,101 @@ static cairo_int_status_t
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
     if (antialias == CAIRO_ANTIALIAS_NONE) {
 	d2dsurf->rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
     } else {
 	d2dsurf->rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
     }
-    ID2D1StrokeStyle *strokeStyle = _cairo_d2d_create_strokestyle_for_stroke_style(style);
+    RefPtr<ID2D1StrokeStyle> strokeStyle = _cairo_d2d_create_strokestyle_for_stroke_style(style);
 
     if (!strokeStyle) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     D2D1::Matrix3x2F mat = _cairo_d2d_matrix_from_matrix(ctm);
 
     _cairo_path_fixed_transform(path, ctm_inverse);
 
     if (op == CAIRO_OPERATOR_CLEAR) {
-	ID2D1Geometry *d2dpath = _cairo_d2d_create_path_geometry_for_path(path,
-									  CAIRO_FILL_RULE_WINDING,
-									  D2D1_FIGURE_BEGIN_FILLED);
+	RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path,
+										 CAIRO_FILL_RULE_WINDING,
+										 D2D1_FIGURE_BEGIN_FILLED);
 
         ID2D1PathGeometry *strokeGeometry;
 	D2DSurfFactory::Instance()->CreatePathGeometry(&strokeGeometry);
 
-	ID2D1GeometrySink *sink;
+	RefPtr<ID2D1GeometrySink> sink;
 	strokeGeometry->Open(&sink);
 	d2dpath->Widen((FLOAT)style->line_width, strokeStyle, mat, (FLOAT)tolerance, sink);
 	sink->Close();
-	sink->Release();
 
 	_cairo_d2d_clear_geometry(d2dsurf, strokeGeometry);
 
-	strokeGeometry->Release();
-	d2dpath->Release();
-
-        return CAIRO_INT_STATUS_SUCCESS;
+	return CAIRO_INT_STATUS_SUCCESS;
     }
 
     d2dsurf->rt->SetTransform(mat);
 
     unsigned int runs_remaining = 1;
     unsigned int last_run = 0;
     bool pushed_clip = false;
     cairo_box_t box;
 
     if (_cairo_path_fixed_is_box(path, &box)) {
 	float x1 = _cairo_fixed_to_float(box.p1.x);    
 	float y1 = _cairo_fixed_to_float(box.p1.y);    
 	float x2 = _cairo_fixed_to_float(box.p2.x);    
 	float y2 = _cairo_fixed_to_float(box.p2.y);
 	while (runs_remaining) {
-	    ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
-								    source,
-								    last_run++,
-								    &runs_remaining,
-								    &pushed_clip);
+	    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
+			    						   source,
+									   last_run++,
+									   &runs_remaining,
+									   &pushed_clip);
 
 	    if (!brush) {
-		strokeStyle->Release();
 		return CAIRO_INT_STATUS_UNSUPPORTED;
 	    }
 	    d2dsurf->rt->DrawRectangle(D2D1::RectF(x1,
 						   y1,
 						   x2,
 						   y2),
 				       brush,
 				       (FLOAT)style->line_width,
 				       strokeStyle);
 
-	    brush->Release();
 	    if (pushed_clip) {
 		d2dsurf->rt->PopLayer();
 	    }
 	}
     } else {
-	ID2D1Geometry *d2dpath = _cairo_d2d_create_path_geometry_for_path(path, 
-									  CAIRO_FILL_RULE_WINDING, 
-									  D2D1_FIGURE_BEGIN_HOLLOW);
+	RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, 
+			    							 CAIRO_FILL_RULE_WINDING, 
+										 D2D1_FIGURE_BEGIN_HOLLOW);
 	while (runs_remaining) {
-	    ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
-								    source,
-								    last_run++,
-								    &runs_remaining,
-								    &pushed_clip);
+	    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
+									   source,
+									   last_run++,
+									   &runs_remaining,
+									   &pushed_clip);
 
 	    if (!brush) {
-		strokeStyle->Release();
-		d2dpath->Release();
 		return CAIRO_INT_STATUS_UNSUPPORTED;
 	    }
 	    d2dsurf->rt->DrawGeometry(d2dpath, brush, (FLOAT)style->line_width, strokeStyle);
 
-	    brush->Release();
 	    if (pushed_clip) {
 		d2dsurf->rt->PopLayer();
 	    }
 	}
-	d2dpath->Release();
     }
 
     _cairo_path_fixed_transform(path, ctm);
     d2dsurf->rt->SetTransform(D2D1::Matrix3x2F::Identity());
-    strokeStyle->Release();
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_d2d_fill(void			*surface,
 		cairo_operator_t	 op,
 		const cairo_pattern_t	*source,
 		cairo_path_fixed_t	*path,
@@ -2057,69 +1959,64 @@ static cairo_int_status_t
 							 _cairo_fixed_to_float(box.p1.y),
 							 _cairo_fixed_to_float(box.p2.x),
 							 _cairo_fixed_to_float(box.p2.y)),
 					     D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
 	    d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
 	    d2dsurf->rt->PopAxisAlignedClip();
 	    return CAIRO_INT_STATUS_SUCCESS;
 	}
-	ID2D1Geometry *d2dpath = _cairo_d2d_create_path_geometry_for_path(path,
-									  fill_rule,
-									  D2D1_FIGURE_BEGIN_FILLED);
+	RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path,
+										 fill_rule,
+										 D2D1_FIGURE_BEGIN_FILLED);
 	_cairo_d2d_clear_geometry(d2dsurf, d2dpath);
 	
-	d2dpath->Release();
 	return CAIRO_INT_STATUS_SUCCESS;
     }
 
     if (_cairo_path_fixed_is_box(path, &box)) {
 	float x1 = _cairo_fixed_to_float(box.p1.x);
 	float y1 = _cairo_fixed_to_float(box.p1.y);    
 	float x2 = _cairo_fixed_to_float(box.p2.x);    
 	float y2 = _cairo_fixed_to_float(box.p2.y);
 	while (runs_remaining) {
-	    ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
-								    source,
-								    last_run++,
-								    &runs_remaining,
-								    &pushed_clip);
+	    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
+									   source,
+									   last_run++,
+									   &runs_remaining,
+									   &pushed_clip);
 	    if (!brush) {
 		return CAIRO_INT_STATUS_UNSUPPORTED;
 	    }
 
 	    d2dsurf->rt->FillRectangle(D2D1::RectF(x1,
 						   y1,
 						   x2,
 						   y2),
 				       brush);
 	    if (pushed_clip) {
 		d2dsurf->rt->PopLayer();
 	    }
-	    brush->Release();
 	}
     } else {
-	ID2D1Geometry *d2dpath = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
+	RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
 	while (runs_remaining) {
-	    ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
-								    source,
-								    last_run++,
-								    &runs_remaining,
-								    &pushed_clip);
+	    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
+									   source,
+									   last_run++,
+									   &runs_remaining,
+									   &pushed_clip);
 	    if (!brush) {
-		d2dpath->Release();
 		return CAIRO_INT_STATUS_UNSUPPORTED;
 	    }
 	    d2dsurf->rt->FillGeometry(d2dpath, brush);
-	    brush->Release();
 	    if (pushed_clip) {
 		d2dsurf->rt->PopLayer();
 	    }
 	}
-	d2dpath->Release();
     }
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
 static cairo_int_status_t
 _cairo_d2d_show_glyphs (void			*surface,
 			cairo_operator_t	 op,
 			const cairo_pattern_t	*source,
@@ -2129,21 +2026,20 @@ static cairo_int_status_t
 			int			*remaining_glyphs,
 			cairo_rectangle_int_t	*extents)
 {
     if (((cairo_surface_t*)surface)->type != CAIRO_SURFACE_TYPE_D2D) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
     cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
     if (!d2dsurf->textRenderingInit) {
-	IDWriteRenderingParams *params;
+	RefPtr<IDWriteRenderingParams> params;
 	DWriteFactory::Instance()->CreateRenderingParams(&params);
 	d2dsurf->rt->SetTextRenderingParams(params);
 	d2dsurf->textRenderingInit = true;
-	params->Release();
     }
     _begin_draw_state(d2dsurf);
     cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
     if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
         status = (cairo_int_status_t)
 	    cairo_dwrite_show_glyphs_on_d2d_surface(surface, op, source, glyphs, num_glyphs, scaled_font, extents);
     }
 
@@ -2176,18 +2072,18 @@ cairo_d2d_surface_create_for_hwnd(HWND w
 	/**
 	 * FIXME: In the near future we can use cairo_device_t to pass in a
 	 * device.
 	 */
 	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_DEVICE));
     }
 
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
+    new (newSurf) cairo_d2d_surface_t();
 
-    memset(newSurf, 0, sizeof(cairo_d2d_surface_t));
     _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
 
     RECT rc;
     HRESULT hr;
 
     newSurf->isDrawing = false;
     ::GetClientRect(wnd, &rc);
 
@@ -2205,25 +2101,26 @@ cairo_d2d_surface_create_for_hwnd(HWND w
 
     if (!sizePixels.width) {
 	sizePixels.width = 1;
     }
     if (!sizePixels.height) {
 	sizePixels.height = 1;
     }
     ID3D10Device1 *device = D3D10Factory::Device();
-    IDXGIDevice *dxgiDevice;
-    IDXGIAdapter *dxgiAdapter;
-    IDXGIFactory *dxgiFactory;
-    
+    RefPtr<IDXGIDevice> dxgiDevice;
+    RefPtr<IDXGIAdapter> dxgiAdapter;
+    RefPtr<IDXGIFactory> dxgiFactory;
+    RefPtr<IDXGISurface> dxgiSurface;
+    D2D1_RENDER_TARGET_PROPERTIES props;    
+    D2D1_BITMAP_PROPERTIES bitProps;
+
     device->QueryInterface(&dxgiDevice);
     dxgiDevice->GetAdapter(&dxgiAdapter);
     dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
-    dxgiAdapter->Release();
-    dxgiDevice->Release();
 
     DXGI_SWAP_CHAIN_DESC swapDesc;
     ::ZeroMemory(&swapDesc, sizeof(swapDesc));
 
     swapDesc.BufferDesc.Width = sizePixels.width;
     swapDesc.BufferDesc.Height = sizePixels.height;
     swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
     swapDesc.BufferDesc.RefreshRate.Numerator = 60;
@@ -2237,82 +2134,75 @@ cairo_d2d_surface_create_for_hwnd(HWND w
 
     /**
      * Create a swap chain, this swap chain will contain the backbuffer for
      * the window we draw to. The front buffer is the full screen front
      * buffer.
      */
     hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, &newSurf->dxgiChain);
 
-    dxgiFactory->Release();
     if (FAILED(hr)) {
-	free(newSurf);
-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+	goto FAIL_HWND;
     }
     /** Get the backbuffer surface from the swap chain */
     hr = newSurf->dxgiChain->GetBuffer(0,
 	                               IID_PPV_ARGS(&newSurf->backBuf));
 
     if (FAILED(hr)) {
-	newSurf->dxgiChain->Release();
-	free(newSurf);
-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+	goto FAIL_HWND;
     }
 
     newSurf->backBuf->QueryInterface(&newSurf->surface);
 
     size.width = sizePixels.width * dpiX;
     size.height = sizePixels.height * dpiY;
 
     /** Create the DXGI surface. */
-    IDXGISurface *dxgiSurface;
     hr = newSurf->surface->QueryInterface(IID_IDXGISurface, (void**)&dxgiSurface);
 
-    D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+    props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
 								       D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
 								       dpiX,
 								       dpiY,
 								       D2D1_RENDER_TARGET_USAGE_NONE);
     hr = D2DSurfFactory::Instance()->CreateDxgiSurfaceRenderTarget(dxgiSurface,
 								   props,
 								   &newSurf->rt);
     if (FAILED(hr)) {
-	dxgiSurface->Release();
-	newSurf->surface->Release();
-	newSurf->dxgiChain->Release();
-	newSurf->backBuf->Release();
-	free(newSurf);
-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+	goto FAIL_HWND;
     }
 
-    D2D1_BITMAP_PROPERTIES bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
+    bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
 									       D2D1_ALPHA_MODE_PREMULTIPLIED));
     
-    dxgiSurface->Release();
-
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
     return reinterpret_cast<cairo_surface_t*>(newSurf);
+
+FAIL_HWND:
+    newSurf->~cairo_d2d_surface_t();
+    free(newSurf);
+    return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
 }
 
 cairo_surface_t *
 cairo_d2d_surface_create(cairo_format_t format,
                          int width,
                          int height)
 {
     if (!D3D10Factory::Device() || !D2DSurfFactory::Instance()) {
 	/**
 	 * FIXME: In the near future we can use cairo_device_t to pass in a
 	 * device.
 	 */
 	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_DEVICE));
     }
     cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
+    new (newSurf) cairo_d2d_surface_t();
 
-    memset(newSurf, 0, sizeof(cairo_d2d_surface_t));
     DXGI_FORMAT dxgiformat = DXGI_FORMAT_B8G8R8A8_UNORM;
     D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
     if (format == CAIRO_FORMAT_ARGB32) {
 	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR_ALPHA);
     } else if (format == CAIRO_FORMAT_RGB24) {
 	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, CAIRO_CONTENT_COLOR);
 	alpha = D2D1_ALPHA_MODE_IGNORE;
     } else {
@@ -2331,90 +2221,83 @@ cairo_d2d_surface_create(cairo_format_t 
 	dxgiformat,
 	sizePixels.width,
 	sizePixels.height
 	);
     desc.MipLevels = 1;
     desc.Usage = D3D10_USAGE_DEFAULT;
     desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
     
-    ID3D10Texture2D *texture;
+    RefPtr<ID3D10Texture2D> texture;
+    RefPtr<IDXGISurface> dxgiSurface;
+    D2D1_BITMAP_PROPERTIES bitProps;
+    D2D1_RENDER_TARGET_PROPERTIES props;
 
     hr = D3D10Factory::Device()->CreateTexture2D(&desc, NULL, &texture);
 
     if (FAILED(hr)) {
-	free(newSurf);
-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+	goto FAIL_CREATE;
     }
 
     newSurf->surface = texture;
 
     /** Create the DXGI surface. */
-    IDXGISurface *dxgiSurface;
     hr = newSurf->surface->QueryInterface(IID_IDXGISurface, (void**)&dxgiSurface);
     if (FAILED(hr)) {
-	newSurf->surface->Release();
-	free(newSurf);
-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+	goto FAIL_CREATE;
     }
 
-    D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+    props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
 								       D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, alpha));
     hr = D2DSurfFactory::Instance()->CreateDxgiSurfaceRenderTarget(dxgiSurface,
 								   props,
 								   &newSurf->rt);
 
     if (FAILED(hr)) {
-	dxgiSurface->Release();
-	newSurf->surface->Release();
-	free(newSurf);
-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+	goto FAIL_CREATE;
     }
 
-    D2D1_BITMAP_PROPERTIES bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
+    bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
 									       alpha));
     hr = newSurf->rt->CreateSharedBitmap(IID_IDXGISurface,
 					 dxgiSurface,
 					 &bitProps,
 					 &newSurf->surfaceBitmap);
 
     if (FAILED(hr)) {
-	dxgiSurface->Release();
-	newSurf->rt->Release();
-	newSurf->surface->Release();
-	free(newSurf);
-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
     }
 
-    dxgiSurface->Release();
-
     newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
 
     return reinterpret_cast<cairo_surface_t*>(newSurf);
+
+FAIL_CREATE:
+    newSurf->~cairo_d2d_surface_t();
+    free(newSurf);
+    return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
 }
 
 void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip)
 {
     if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
         return;
     }
     cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
 
     /** For now, we invalidate our storing texture with this operation. */
     D2D1_POINT_2U point;
     D3D10_BOX rect;
     rect.front = 0;
     rect.back = 1;
 
-    IDXGISurface *dxgiSurface;
+    RefPtr<IDXGISurface> dxgiSurface;
     d2dsurf->surface->QueryInterface(&dxgiSurface);
     DXGI_SURFACE_DESC desc;
 
     dxgiSurface->GetDesc(&desc);
-    dxgiSurface->Release();
 
     /**
      * It's important we constrain the size of the clip region to the area of
      * the surface. If we don't we might get a box that goes outside the
      * surface, and CopySubresourceRegion will become very angry with us.
      * It will cause a device failure and subsequent drawing will break.
      */
     clip->x = MAX(clip->x, 0);
--- a/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
+++ b/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
@@ -1317,21 +1317,21 @@ cairo_dwrite_show_glyphs_on_d2d_surface(
     if (transform) {
 	dst->rt->SetTransform(mat);
     }
     unsigned int last_run = 0;
     unsigned int runs_remaining = 1;
     bool pushed_clip = false;
 
     while (runs_remaining) {
-	ID2D1Brush *brush = _cairo_d2d_create_brush_for_pattern(dst,
-								source,
-								last_run++,
-								&runs_remaining,
-								&pushed_clip);
+	RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst,
+								       source,
+								       last_run++,
+								       &runs_remaining,
+								       &pushed_clip);
 	if (!brush) {
 	    delete [] indices;
 	    delete [] offsets;
 	    delete [] advances;
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
 	if (transform) {
 	    D2D1::Matrix3x2F mat_inverse = _cairo_d2d_matrix_from_matrix(&dwritesf->mat_inverse);
@@ -1340,17 +1340,16 @@ cairo_dwrite_show_glyphs_on_d2d_surface(
 	    // The brush matrix needs to be multiplied with the inverted matrix
 	    // as well, to move the brush into the space of the glyphs. Before
 	    // the render target transformation.
 	    brush->GetTransform(&mat_brush);
 	    mat_brush = mat_brush * mat_inverse;
 	    brush->SetTransform(&mat_brush);
 	}
         dst->rt->DrawGlyphRun(D2D1::Point2F(0, 0), &run, brush);
-	brush->Release();
 	if (pushed_clip) {
 	    dst->rt->PopLayer();
 	}
     }
     if (transform) {
 	dst->rt->SetTransform(D2D1::Matrix3x2F::Identity());
     }