Bug 970007 Fix incorrect colorformat when using CairoSurface, r=gal
authorpeter chang <pchang@mozilla.com>
Tue, 15 Apr 2014 11:46:31 +0800
changeset 196979 73f991528355dfacf68d27daf3059b6ea37a11e5
parent 196978 a3e8ddc67239316af4edd4566510ace8c00dbb68
child 196980 1435fc68086f536f7b361c964ee7b5cbee5954a0
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs970007
milestone31.0a1
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 970007 Fix incorrect colorformat when using CairoSurface, r=gal
gfx/2d/2D.h
gfx/2d/DrawTargetCairo.cpp
gfx/2d/DrawTargetCairo.h
gfx/2d/Factory.cpp
gfx/thebes/gfxPlatform.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1027,17 +1027,17 @@ public:
   static bool HasSSE2();
 
   /* Make sure that the given dimensions don't overflow a 32-bit signed int
    * using 4 bytes per pixel; optionally, make sure that either dimension
    * doesn't exceed the given limit.
    */
   static bool CheckSurfaceSize(const IntSize &sz, int32_t limit = 0);
 
-  static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize);
+  static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
 
   static TemporaryRef<SourceSurface>
     CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface,
                                        SurfaceFormat aFormat);
 
   static TemporaryRef<DrawTarget>
     CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
 
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -1152,22 +1152,22 @@ DrawTargetCairo::CreateSimilarDrawTarget
     target->InitAlreadyReferenced(similar, aSize);
     return target;
   }
 
   return nullptr;
 }
 
 bool
-DrawTargetCairo::InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize)
+DrawTargetCairo::InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat)
 {
   mContext = cairo_create(aSurface);
   mSurface = aSurface;
   mSize = aSize;
-  mFormat = CairoContentToGfxFormat(cairo_surface_get_content(aSurface));
+  mFormat = aFormat ? *aFormat : CairoContentToGfxFormat(cairo_surface_get_content(aSurface));
 
   if (mFormat == SurfaceFormat::B8G8R8A8 ||
       mFormat == SurfaceFormat::R8G8B8A8) {
     SetPermitSubpixelAA(false);
   } else {
     SetPermitSubpixelAA(true);
   }
 
@@ -1213,20 +1213,20 @@ DrawTargetCairo::CreateShadowDrawTarget(
   cairo_surface_destroy(similar);
 
   RefPtr<DrawTargetCairo> target = new DrawTargetCairo();
   target->InitAlreadyReferenced(tee, aSize);
   return target;
 }
 
 bool
-DrawTargetCairo::Init(cairo_surface_t* aSurface, const IntSize& aSize)
+DrawTargetCairo::Init(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat)
 {
   cairo_surface_reference(aSurface);
-  return InitAlreadyReferenced(aSurface, aSize);
+  return InitAlreadyReferenced(aSurface, aSize, aFormat);
 }
 
 bool
 DrawTargetCairo::Init(const IntSize& aSize, SurfaceFormat aFormat)
 {
   cairo_surface_t *surf = cairo_image_surface_create(GfxFormatToCairoFormat(aFormat), aSize.width, aSize.height);
   return InitAlreadyReferenced(surf, aSize);
 }
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -151,17 +151,17 @@ public:
     CreateGradientStops(GradientStop *aStops,
                         uint32_t aNumStops,
                         ExtendMode aExtendMode = ExtendMode::CLAMP) const;
 
   virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
 
   virtual void *GetNativeSurface(NativeSurfaceType aType);
 
-  bool Init(cairo_surface_t* aSurface, const IntSize& aSize);
+  bool Init(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
   bool Init(const IntSize& aSize, SurfaceFormat aFormat);
   bool Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
 
   virtual void SetTransform(const Matrix& aTransform);
 
   // Call to set up aContext for drawing (with the current transform, etc).
   // Pass the path you're going to be using if you have one.
   // Implicitly calls WillChange(aPath).
@@ -170,18 +170,17 @@ public:
   static cairo_surface_t *GetDummySurface();
 
   static TemporaryRef<SourceSurface>
       CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface,
                                          SurfaceFormat aFormat);
 
 private: // methods
   // Init cairo surface without doing a cairo_surface_reference() call.
-  bool InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize);
-
+  bool InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
   enum DrawPatternType { DRAW_FILL, DRAW_STROKE };
   void DrawPattern(const Pattern& aPattern,
                    const StrokeOptions& aStrokeOptions,
                    const DrawOptions& aOptions,
                    DrawPatternType aDrawType,
                    bool aPathBoundsClip = false);
 
   void CopySurfaceInternal(cairo_surface_t* aSurface,
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -613,24 +613,24 @@ Factory::CreateCairoGlyphRenderingOption
 
   options->SetHinting(aHinting);
   options->SetAutoHinting(aAutoHinting);
   return options;
 }
 #endif
 
 TemporaryRef<DrawTarget>
-Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize)
+Factory::CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat)
 {
   RefPtr<DrawTarget> retVal;
 
 #ifdef USE_CAIRO
   RefPtr<DrawTargetCairo> newTarget = new DrawTargetCairo();
 
-  if (newTarget->Init(aSurface, aSize)) {
+  if (newTarget->Init(aSurface, aSize, aFormat)) {
     retVal = newTarget;
   }
 
   if (mRecorder && retVal) {
     RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true);
     return recordDT;
   }
 #endif
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -570,17 +570,18 @@ gfxPlatform::OptimizeImage(gfxImageSurfa
     return optSurface.forget();
 }
 
 cairo_user_data_key_t kDrawTarget;
 
 RefPtr<DrawTarget>
 gfxPlatform::CreateDrawTargetForSurface(gfxASurface *aSurface, const IntSize& aSize)
 {
-  RefPtr<DrawTarget> drawTarget = Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(), aSize);
+  SurfaceFormat format = Optimal2DFormatForContent(aSurface->GetContentType());
+  RefPtr<DrawTarget> drawTarget = Factory::CreateDrawTargetForCairoSurface(aSurface->CairoSurface(), aSize, &format);
   aSurface->SetData(&kDrawTarget, drawTarget, nullptr);
   return drawTarget;
 }
 
 // This is a temporary function used by ContentClient to build a DrawTarget
 // around the gfxASurface. This should eventually be replaced by plumbing
 // the DrawTarget through directly
 RefPtr<DrawTarget>