Bug 1049138 - Use the cairo surface format to determine gfx format when able. r=jmuizelaar, a=sledru
authorJames Willcox <snorp@snorp.net>
Wed, 17 Dec 2014 15:49:57 -0600
changeset 235574 bfc940387e3fe3a868ab4050f7945222b14992b6
parent 235573 bd8765dacc497c073aa53aa955c2c68d61f0652e
child 235575 4cde4d970ae64aef46996b1cfa8485a899074ecb
push id611
push userraliiev@mozilla.com
push dateMon, 05 Jan 2015 23:23:16 +0000
treeherdermozilla-release@345cd3b9c445 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmuizelaar, sledru
bugs1049138
milestone35.0
Bug 1049138 - Use the cairo surface format to determine gfx format when able. r=jmuizelaar, a=sledru
gfx/2d/DrawTargetCairo.cpp
gfx/2d/HelpersCairo.h
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -588,20 +588,19 @@ TemporaryRef<SourceSurface>
 DrawTargetCairo::Snapshot()
 {
   if (mSnapshot) {
     return mSnapshot;
   }
 
   IntSize size = GetSize();
 
-  cairo_content_t content = cairo_surface_get_content(mSurface);
   mSnapshot = new SourceSurfaceCairo(mSurface,
                                      size,
-                                     CairoContentToGfxFormat(content),
+                                     GfxFormatForCairoSurface(mSurface),
                                      this);
   return mSnapshot;
 }
 
 bool
 DrawTargetCairo::LockBits(uint8_t** aData, IntSize* aSize,
                           int32_t* aStride, SurfaceFormat* aFormat)
 {
@@ -1402,17 +1401,17 @@ DrawTargetCairo::InitAlreadyReferenced(c
                        << aSize << " Cairo Status: " << cairo_surface_status(aSurface);
     cairo_surface_destroy(aSurface);
     return false;
   }
 
   mContext = cairo_create(aSurface);
   mSurface = aSurface;
   mSize = aSize;
-  mFormat = aFormat ? *aFormat : CairoContentToGfxFormat(cairo_surface_get_content(aSurface));
+  mFormat = aFormat ? *aFormat : GfxFormatForCairoSurface(aSurface);
 
   // Cairo image surface have a bug where they will allocate a mask surface (for clipping)
   // the size of the clip extents, and don't take the surface extents into account.
   // Add a manual clip to the surface extents to prevent this.
   cairo_new_path(mContext);
   cairo_rectangle(mContext, 0, 0, mSize.width, mSize.height);
   cairo_clip(mContext);
 
--- a/gfx/2d/HelpersCairo.h
+++ b/gfx/2d/HelpersCairo.h
@@ -209,16 +209,45 @@ CairoContentToGfxFormat(cairo_content_t 
       return SurfaceFormat::B8G8R8X8;
     case CAIRO_CONTENT_ALPHA:
       return SurfaceFormat::A8;
   }
 
   return SurfaceFormat::B8G8R8A8;
 }
 
+static inline SurfaceFormat
+CairoFormatToGfxFormat(cairo_format_t format)
+{
+  switch (format) {
+    case CAIRO_FORMAT_ARGB32:
+      return SurfaceFormat::B8G8R8A8;
+    case CAIRO_FORMAT_RGB24:
+      return SurfaceFormat::B8G8R8X8;
+    case CAIRO_FORMAT_A8:
+      return SurfaceFormat::A8;
+    case CAIRO_FORMAT_RGB16_565:
+      return SurfaceFormat::R5G6B5;
+    default:
+      gfxWarning() << "Unknown cairo format";
+      MOZ_ASSERT(false, "Unknown cairo format");
+      return SurfaceFormat::UNKNOWN;
+  }
+}
+
+static inline SurfaceFormat
+GfxFormatForCairoSurface(cairo_surface_t* surface)
+{
+  if (cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE) {
+    return CairoFormatToGfxFormat(cairo_image_surface_get_format(surface));
+  }
+
+  return CairoContentToGfxFormat(cairo_surface_get_content(surface));
+}
+
 static inline void
 GfxMatrixToCairoMatrix(const Matrix& mat, cairo_matrix_t& retval)
 {
   cairo_matrix_init(&retval, mat._11, mat._12, mat._21, mat._22, mat._31, mat._32);
 }
 
 static inline void
 SetCairoStrokeOptions(cairo_t* aCtx, const StrokeOptions& aStrokeOptions)