Bug 558934: Cache extended and none-extended surfaces separately. r=jrmuizel a=dholbert
authorBas Schouten <bschouten@mozilla.com>
Sat, 24 Apr 2010 01:16:50 +0200
changeset 41226 983c5a5c13852ccb0bbccd2f4081b319d2300db3
parent 41225 e825fb134e7a4985478780de6356b0b24a698dc5
child 41227 4e008ffe35aa21c501031816e46c11c25bc2ca88
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, dholbert
bugs558934
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 558934: Cache extended and none-extended surfaces separately. r=jrmuizel a=dholbert
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
@@ -580,23 +580,23 @@ static RefPtr<ID2D1StrokeStyle>
 									      (FLOAT)style->dash_offset),
 						  dashes,
 						  style->num_dashes,
 						  &strokeStyle);
     delete [] dashes;
     return strokeStyle;
 }
 
-cairo_user_data_key_t bitmap_key;
+cairo_user_data_key_t bitmap_key_nonextend;
+cairo_user_data_key_t bitmap_key_extend;
+cairo_user_data_key_t bitmap_key_snapshot;
 
 struct cached_bitmap {
     /** The cached 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
@@ -611,17 +611,17 @@ static void _d2d_release_bitmap(void *bi
 }
 
 /**
  * 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)
 {
-    cached_bitmap *existingBitmap = (cached_bitmap*)cairo_surface_get_user_data(surface, &bitmap_key);
+    cached_bitmap *existingBitmap = (cached_bitmap*)cairo_surface_get_user_data(surface, &bitmap_key_snapshot);
     if (existingBitmap) {
 	existingBitmap->dirty = true;
     }
     if (!--existingBitmap->refs) {
 	delete existingBitmap;
     }
     cairo_surface_destroy(surface);
 }
@@ -755,20 +755,22 @@ RefPtr<ID2D1Brush>
 
     } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	cairo_matrix_t mat = pattern->matrix;
 	cairo_matrix_invert(&mat);
 
 	cairo_surface_pattern_t *surfacePattern =
 	    (cairo_surface_pattern_t*)pattern;
 	D2D1_EXTEND_MODE extendMode;
-	bool nonExtended = false;
+
+	cairo_user_data_key_t *key = &bitmap_key_extend;
+
 	if (pattern->extend == CAIRO_EXTEND_NONE) {
 	    extendMode = D2D1_EXTEND_MODE_CLAMP;
-	    nonExtended = true;
+	    key = &bitmap_key_nonextend;
 	    /** 
 	     * For image surfaces we create a slightly larger bitmap with
 	     * a transparent border around it for this case. Need to translate
 	     * for that.
 	     */
 	    if (surfacePattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
 		cairo_matrix_translate(&mat, -1.0, -1.0);
 	    }
@@ -857,51 +859,51 @@ RefPtr<ID2D1Brush>
 		    *pushed_clip = true;
 		}
 	    } else {
 		width = srcSurf->width;
 		height = srcSurf->height;
 	    }
 
 	    cached_bitmap *cachebitmap = NULL;
+
 	    if (!tiled) {
 		cachebitmap = 
 		    (cached_bitmap*)cairo_surface_get_user_data(
 		    surfacePattern->surface,
-		    &bitmap_key);
+		    key);
 	    }
 
-	    if (cachebitmap && cachebitmap->isNoneExtended == nonExtended) {
+	    if (cachebitmap) {
 		sourceBitmap = cachebitmap->bitmap;
 		if (cachebitmap->dirty) {
 		    D2D1_RECT_U rect;
 		    /** No need to take tiling into account - tiled surfaces are never cached. */
-		    if (nonExtended) {
+		    if (pattern->extend == CAIRO_EXTEND_NONE) {
 			rect = D2D1::RectU(1, 1, srcSurf->width + 1, srcSurf->height + 1);
 		    } else {
 			rect = D2D1::RectU(0, 0, srcSurf->width, srcSurf->height);
 		    }
 		    sourceBitmap->CopyFromMemory(&rect,
 						 srcSurf->data,
 						 srcSurf->stride);
 		    cairo_surface_t *nullSurf =
 			_cairo_null_surface_create(CAIRO_CONTENT_COLOR_ALPHA);
 		    cachebitmap->refs++;
 		    cachebitmap->dirty = false;
 		    cairo_surface_set_user_data(nullSurf,
-						&bitmap_key,
+						&bitmap_key_snapshot,
 						cachebitmap,
 						NULL);
 		    _cairo_surface_attach_snapshot(surfacePattern->surface,
 						   nullSurf,
 						   _d2d_snapshot_detached);
 		}
 	    } else {
 		cached_bitmap *cachebitmap = new cached_bitmap;
-		cachebitmap->isNoneExtended = nonExtended;
 		if (pattern->extend != CAIRO_EXTEND_NONE) {
 		    d2dsurf->rt->CreateBitmap(D2D1::SizeU(width, height),
 							  srcSurf->data + yoffset * srcSurf->stride + xoffset,
 							  srcSurf->stride,
 							  D2D1::BitmapProperties(D2D1::PixelFormat(format,
 												   alpha)),
 					      &sourceBitmap);
 		} else {
@@ -932,23 +934,23 @@ RefPtr<ID2D1Brush>
 					      &sourceBitmap);
 		    delete [] tmp;
 		}
 
 		cachebitmap->dirty = false;
 		cachebitmap->bitmap = sourceBitmap;
 		cachebitmap->refs = 2;
 		cairo_surface_set_user_data(surfacePattern->surface,
-					    &bitmap_key,
+					    key,
 					    cachebitmap,
 					    _d2d_release_bitmap);
 		cairo_surface_t *nullSurf =
 		    _cairo_null_surface_create(CAIRO_CONTENT_COLOR_ALPHA);
 		cairo_surface_set_user_data(nullSurf,
-					    &bitmap_key,
+					    &bitmap_key_snapshot,
 					    cachebitmap,
 					    NULL);
 		_cairo_surface_attach_snapshot(surfacePattern->surface,
 					       nullSurf,
 					       _d2d_snapshot_detached);
 	    }
 	} else {
 	    return NULL;