b=579736 use cairo_surface_create_similar in CreateSimilarSurface to create surfaces that support simple overlapping self-copies r=jrmuizel
authorKarl Tomlinson <karlt+@karlt.net>
Fri, 30 Jul 2010 15:16:17 +1200
changeset 48435 d02490c3c2181b3b32cfebac629813fd98d8f0d7
parent 48434 582be9aca672167c31380f8f6fc23b9e1f8d6994
child 48436 55105cdc45c9c744aedeeb5ccb0c23687b865f56
push id14735
push userktomlinson@mozilla.com
push dateFri, 30 Jul 2010 23:11:15 +0000
treeherderautoland@d02490c3c218 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs579736
milestone2.0b3pre
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
b=579736 use cairo_surface_create_similar in CreateSimilarSurface to create surfaces that support simple overlapping self-copies r=jrmuizel
gfx/thebes/gfxXlibSurface.cpp
--- a/gfx/thebes/gfxXlibSurface.cpp
+++ b/gfx/thebes/gfxXlibSurface.cpp
@@ -178,50 +178,41 @@ static PRBool GetForce24bppPref()
     return val;
 }
 
 already_AddRefed<gfxASurface>
 gfxXlibSurface::CreateSimilarSurface(gfxContentType aContent,
                                      const gfxIntSize& aSize)
 {
     if (aContent == CONTENT_COLOR) {
-        // If the destination surface does not have an xrender format, then we
-        // won't be able to copy directly from another Xlib surface with a
-        // different format.  Either an xlib surface with the same visual (for
-        // XCopyArea) or an image surface might be sensible options there, but
-        // we just leave the decision to cairo_surface_create_similar.
-        XRenderPictFormat* format =
-            cairo_xlib_surface_get_xrender_format(CairoSurface());
-        if (format) {
-            // cairo_surface_create_similar will use a matching visual if it
-            // can.  However, systems with 16-bit or indexed default visuals
-            // may benefit from rendering with 24-bit formats.  This same code
-            // can also be used for opaque surfaces when not forcing 24-bit,
-            // so as to skip the black initialization that
-            // cairo_surface_create_simiar does.
-            static PRBool force24bpp = GetForce24bppPref();
-
-            if (force24bpp || (format->type == PictTypeDirect
-                               && format->direct.alphaMask != 0)) {
-                format = XRenderFindStandardFormat(mDisplay,
-                                                   PictStandardRGB24);
-            }
-
+        // cairo_surface_create_similar will use a matching visual if it can.
+        // However, systems with 16-bit or indexed default visuals may benefit
+        // from rendering with 24-bit formats.
+        static PRBool force24bpp = GetForce24bppPref();
+        if (force24bpp
+            && cairo_xlib_surface_get_depth(CairoSurface()) != 24) {
+            XRenderPictFormat* format =
+                XRenderFindStandardFormat(mDisplay, PictStandardRGB24);
             if (format) {
+                // Cairo only performs simple self-copies as desired if it
+                // knows that this is a Pixmap surface.  It only knows that
+                // surfaces are pixmap surfaces if it creates the Pixmap
+                // itself, so we use cairo_surface_create_similar with a
+                // temporary reference surface to indicate the format.
                 Screen* screen = cairo_xlib_surface_get_screen(CairoSurface());
-                nsRefPtr<gfxASurface> result =
-                    gfxXlibSurface::Create(screen, format, aSize, mDrawable);
-            
-                if (result)
-                    return result.forget();
+                nsRefPtr<gfxXlibSurface> depth24reference =
+                    gfxXlibSurface::Create(screen, format,
+                                           gfxIntSize(1, 1), mDrawable);
+                if (depth24reference)
+                    return depth24reference->
+                        gfxASurface::CreateSimilarSurface(aContent, aSize);
             }
         }
     }
 
-    // Fall back to cairo_surface_create_similar().
     return gfxASurface::CreateSimilarSurface(aContent, aSize);
 }
 
 void
 gfxXlibSurface::DoSizeQuery()
 {
     // figure out width/height/depth
     Window root_ignore;