Bug 1003707 - Pass surfaces sizes in to CreateSourceSurfaceFromNativeSurface instead of trying to extract it from cairo. r=Bas, a=sledru
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 08 May 2014 11:23:44 +1200
changeset 192262 956578072396
parent 192261 ea7fa7d12c15
child 192263 662c516a1858
push id3551
push userryanvm@gmail.com
push date2014-05-13 14:28 +0000
treeherdermozilla-beta@79e75d908e1d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas, sledru
bugs1003707
milestone30.0
Bug 1003707 - Pass surfaces sizes in to CreateSourceSurfaceFromNativeSurface instead of trying to extract it from cairo. r=Bas, a=sledru
gfx/2d/2D.h
gfx/2d/DrawTargetCairo.cpp
gfx/2d/DrawTargetCairo.h
gfx/2d/Factory.cpp
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
gfx/layers/basic/TextureHostBasic.h
gfx/layers/basic/X11TextureSourceBasic.cpp
gfx/layers/basic/X11TextureSourceBasic.h
gfx/thebes/gfxASurface.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxXlibNativeRenderer.cpp
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -55,16 +55,17 @@ class SourceSurface;
 class DataSourceSurface;
 class DrawTarget;
 class DrawEventRecorder;
 class FilterNode;
 
 struct NativeSurface {
   NativeSurfaceType mType;
   SurfaceFormat mFormat;
+  gfx::IntSize mSize;
   void *mSurface;
 };
 
 struct NativeFont {
   NativeFontType mType;
   void *mFont;
 };
 
@@ -1022,20 +1023,16 @@ public:
   /* 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<SourceSurface>
-    CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface,
-                                       SurfaceFormat aFormat);
-
   static TemporaryRef<DrawTarget>
     CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
 
   static TemporaryRef<DrawTarget>
     CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
      
   static TemporaryRef<DrawTarget>
     CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -77,80 +77,16 @@ private:
 
   cairo_t* mCtx;
 };
 
 
 } // end anonymous namespace
 
 static bool
-GetCairoSurfaceSize(cairo_surface_t* surface, IntSize& size)
-{
-  switch (cairo_surface_get_type(surface))
-  {
-    case CAIRO_SURFACE_TYPE_IMAGE:
-    {
-      size.width = cairo_image_surface_get_width(surface);
-      size.height = cairo_image_surface_get_height(surface);
-      return true;
-    }
-
-#ifdef CAIRO_HAS_XLIB_SURFACE
-    case CAIRO_SURFACE_TYPE_XLIB:
-    {
-      size.width = cairo_xlib_surface_get_width(surface);
-      size.height = cairo_xlib_surface_get_height(surface);
-      return true;
-    }
-#endif
-
-#ifdef CAIRO_HAS_QUARTZ_SURFACE
-    case CAIRO_SURFACE_TYPE_QUARTZ:
-    {
-      CGContextRef cgc = cairo_quartz_surface_get_cg_context(surface);
-
-      // It's valid to call these CGBitmapContext functions on non-bitmap
-      // contexts; they'll just return 0 in that case.
-      size.width = CGBitmapContextGetWidth(cgc);
-      size.height = CGBitmapContextGetHeight(cgc);
-      return true;
-    }
-#endif
-#ifdef CAIRO_HAS_WIN32_SURFACE
-#ifdef MOZ2D_HAS_MOZ_CAIRO
-    case CAIRO_SURFACE_TYPE_WIN32:
-    case CAIRO_SURFACE_TYPE_WIN32_PRINTING:
-    {
-      size.width = cairo_win32_surface_get_width(surface);
-      size.height = cairo_win32_surface_get_height(surface);
-      return true;
-    }
-#else
-    case CAIRO_SURFACE_TYPE_WIN32:
-    {
-      cairo_surface_t *img = cairo_win32_surface_get_image(surface);
-
-      if (!img) {
-        // XXX - fix me
-        MOZ_ASSERT(false);
-        return true;
-      }
-      size.width = cairo_image_surface_get_width(img);
-      size.height = cairo_image_surface_get_height(img);
-      return true;
-    }
-#endif
-#endif
-
-    default:
-      return false;
-  }
-}
-
-static bool
 SupportsSelfCopy(cairo_surface_t* surface)
 {
   switch (cairo_surface_get_type(surface))
   {
 #ifdef CAIRO_HAS_QUARTZ_SURFACE
     case CAIRO_SURFACE_TYPE_QUARTZ:
       return true;
 #endif
@@ -1105,36 +1041,24 @@ DrawTargetCairo::OptimizeSourceSurface(S
 {
   return aSurface;
 }
 
 TemporaryRef<SourceSurface>
 DrawTargetCairo::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
 {
   if (aSurface.mType == NativeSurfaceType::CAIRO_SURFACE) {
-    IntSize size;
-    cairo_surface_t* surf = static_cast<cairo_surface_t*>(aSurface.mSurface);
-    if (GetCairoSurfaceSize(surf, size)) {
-      RefPtr<SourceSurfaceCairo> source =
-        new SourceSurfaceCairo(surf, size, aSurface.mFormat);
-      return source;
+    if (aSurface.mSize.width <= 0 ||
+        aSurface.mSize.height <= 0) {
+      gfxWarning() << "Can't create a SourceSurface without a valid size";
+      return nullptr;
     }
-  }
-
-  return nullptr;
-}
-
-TemporaryRef<SourceSurface>
-DrawTargetCairo::CreateSourceSurfaceForCairoSurface(cairo_surface_t *aSurface,
-                                                    SurfaceFormat aFormat)
-{
-  IntSize size;
-  if (GetCairoSurfaceSize(aSurface, size)) {
+    cairo_surface_t* surf = static_cast<cairo_surface_t*>(aSurface.mSurface);
     RefPtr<SourceSurfaceCairo> source =
-      new SourceSurfaceCairo(aSurface, size, aFormat);
+      new SourceSurfaceCairo(surf, aSurface.mSize, aSurface.mFormat);
     return source;
   }
 
   return nullptr;
 }
 
 TemporaryRef<DrawTarget>
 DrawTargetCairo::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -164,20 +164,16 @@ public:
 
   // 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).
   void PrepareForDrawing(cairo_t* aContext, const Path* aPath = nullptr);
 
   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);
 
   enum DrawPatternType { DRAW_FILL, DRAW_STROKE };
   void DrawPattern(const Pattern& aPattern,
                    const StrokeOptions& aStrokeOptions,
                    const DrawOptions& aOptions,
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -632,28 +632,16 @@ Factory::CreateDrawTargetForCairoSurface
   if (mRecorder && retVal) {
     RefPtr<DrawTarget> recordDT = new DrawTargetRecording(mRecorder, retVal, true);
     return recordDT;
   }
 #endif
   return retVal;
 }
 
-TemporaryRef<SourceSurface>
-Factory::CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface,
-                                            SurfaceFormat aFormat)
-{
-  RefPtr<SourceSurface> retVal;
-
-#ifdef USE_CAIRO
-  retVal = DrawTargetCairo::CreateSourceSurfaceForCairoSurface(aSurface, aFormat);
-#endif
-  return retVal;
-}
-
 #ifdef XP_MACOSX
 TemporaryRef<DrawTarget>
 Factory::CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize)
 {
   RefPtr<DrawTarget> retVal;
 
   RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
 
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -27,17 +27,17 @@ namespace layers {
 
 class DataTextureSourceBasic : public DataTextureSource
                              , public TextureSourceBasic
 {
 public:
 
   virtual TextureSourceBasic* AsSourceBasic() MOZ_OVERRIDE { return this; }
 
-  virtual gfx::SourceSurface* GetSurface() MOZ_OVERRIDE { return mSurface; }
+  virtual gfx::SourceSurface* GetSurface(DrawTarget* aTarget) MOZ_OVERRIDE { return mSurface; }
 
   SurfaceFormat GetFormat() const MOZ_OVERRIDE
   {
     return mSurface->GetFormat();
   }
 
   virtual IntSize GetSize() const MOZ_OVERRIDE
   {
@@ -76,17 +76,17 @@ public:
   {}
 
   SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
 
   virtual IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
   virtual TextureSourceBasic* AsSourceBasic() MOZ_OVERRIDE { return this; }
 
-  SourceSurface *GetSurface() MOZ_OVERRIDE { return mSurface; }
+  virtual SourceSurface *GetSurface(DrawTarget* aTarget) MOZ_OVERRIDE { return mSurface; }
 
   virtual void SetCompositor(Compositor* aCompositor)
   {
     mCompositor = static_cast<BasicCompositor*>(aCompositor);
   }
 
   virtual const char *Name() { return "DeprecatedTextureHostBasic"; }
 
@@ -463,17 +463,17 @@ BasicCompositor::DrawQuad(const gfx::Rec
 
   newTransform.Translate(-offset.x, -offset.y);
   buffer->SetTransform(newTransform);
 
   RefPtr<SourceSurface> sourceMask;
   Matrix maskTransform;
   if (aEffectChain.mSecondaryEffects[EFFECT_MASK]) {
     EffectMask *effectMask = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EFFECT_MASK].get());
-    sourceMask = effectMask->mMaskTexture->AsSourceBasic()->GetSurface();
+    sourceMask = effectMask->mMaskTexture->AsSourceBasic()->GetSurface(dest);
     MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!");
     MOZ_ASSERT(!effectMask->mIs3D);
     maskTransform = effectMask->mMaskTransform.As2D();
   }
 
   switch (aEffectChain.mPrimaryEffect->mType) {
     case EFFECT_SOLID_COLOR: {
       EffectSolidColor* effectSolidColor =
@@ -485,17 +485,17 @@ BasicCompositor::DrawQuad(const gfx::Rec
       break;
     }
     case EFFECT_RGB: {
       TexturedEffect* texturedEffect =
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic();
 
       DrawSurfaceWithTextureCoords(dest, aRect,
-                                   source->GetSurface(),
+                                   source->GetSurface(dest),
                                    texturedEffect->mTextureCoords,
                                    texturedEffect->mFilter,
                                    aOpacity, sourceMask, maskTransform);
       break;
     }
     case EFFECT_YCBCR: {
       NS_RUNTIMEABORT("Can't (easily) support component alpha with BasicCompositor!");
       break;
--- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
+++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.cpp
@@ -41,17 +41,17 @@ MacIOSurfaceTextureHostBasic::MacIOSurfa
   : TextureHost(aFlags)
 {
   mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
                                          aDescriptor.scaleFactor(),
                                          aDescriptor.hasAlpha());
 }
 
 gfx::SourceSurface*
-MacIOSurfaceTextureSourceBasic::GetSurface()
+MacIOSurfaceTextureSourceBasic::GetSurface(gfx::DrawTarget* aTarget)
 {
   if (!mSourceSurface) {
     mSourceSurface = mSurface->GetAsSurface();
   }
   return mSourceSurface;
 }
 
 void
--- a/gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
+++ b/gfx/layers/basic/MacIOSurfaceTextureHostBasic.h
@@ -29,17 +29,17 @@ public:
   MacIOSurfaceTextureSourceBasic(BasicCompositor* aCompositor,
                                  MacIOSurface* aSurface);
   virtual ~MacIOSurfaceTextureSourceBasic();
 
   virtual TextureSourceBasic* AsSourceBasic() MOZ_OVERRIDE { return this; }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
-  virtual gfx::SourceSurface* GetSurface() MOZ_OVERRIDE;
+  virtual gfx::SourceSurface* GetSurface(gfx::DrawTarget* aTarget) MOZ_OVERRIDE;
 
   virtual void DeallocateDeviceData() MOZ_OVERRIDE { }
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
 protected:
   BasicCompositor* mCompositor;
   RefPtr<MacIOSurface> mSurface;
--- a/gfx/layers/basic/TextureHostBasic.h
+++ b/gfx/layers/basic/TextureHostBasic.h
@@ -17,15 +17,15 @@ namespace layers {
 
 /**
  * A texture source interface that can be used by the software Compositor.
  */
 class TextureSourceBasic
 {
 public:
   virtual ~TextureSourceBasic() {}
-  virtual gfx::SourceSurface* GetSurface() = 0;
+  virtual gfx::SourceSurface* GetSurface(gfx::DrawTarget* aTarget) = 0;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_TEXTUREHOSTBASIC_H_
--- a/gfx/layers/basic/X11TextureSourceBasic.cpp
+++ b/gfx/layers/basic/X11TextureSourceBasic.cpp
@@ -27,21 +27,25 @@ X11TextureSourceBasic::GetSize() const
 SurfaceFormat
 X11TextureSourceBasic::GetFormat() const
 {
   gfxContentType type = mSurface->GetContentType();
   return X11TextureSourceBasic::ContentTypeToSurfaceFormat(type);
 }
 
 SourceSurface*
-X11TextureSourceBasic::GetSurface()
+X11TextureSourceBasic::GetSurface(DrawTarget* aTarget)
 {
   if (!mSourceSurface) {
-    mSourceSurface =
-      Factory::CreateSourceSurfaceForCairoSurface(mSurface->CairoSurface(), GetFormat());
+    NativeSurface surf;
+    surf.mFormat = GetFormat();
+    surf.mType = NativeSurfaceType::CAIRO_SURFACE;
+    surf.mSurface = mSurface->CairoSurface();
+    surf.mSize = GetSize();
+    mSourceSurface = aTarget->CreateSourceSurfaceFromNativeSurface(surf);
   }
   return mSourceSurface;
 }
 
 void
 X11TextureSourceBasic::SetCompositor(Compositor* aCompositor)
 {
   MOZ_ASSERT(aCompositor->GetBackendType() == LayersBackend::LAYERS_BASIC);
@@ -57,9 +61,9 @@ X11TextureSourceBasic::ContentTypeToSurf
       return SurfaceFormat::B8G8R8X8;
     case gfxContentType::ALPHA:
       return SurfaceFormat::A8;
     case gfxContentType::COLOR_ALPHA:
       return SurfaceFormat::B8G8R8A8;
     default:
       return SurfaceFormat::UNKNOWN;
   }
-}
\ No newline at end of file
+}
--- a/gfx/layers/basic/X11TextureSourceBasic.h
+++ b/gfx/layers/basic/X11TextureSourceBasic.h
@@ -21,17 +21,17 @@ class X11TextureSourceBasic
 {
 public:
   X11TextureSourceBasic(BasicCompositor* aCompositor, gfxXlibSurface* aSurface);
 
   virtual X11TextureSourceBasic* AsSourceBasic() MOZ_OVERRIDE { return this; }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
-  virtual gfx::SourceSurface* GetSurface() MOZ_OVERRIDE;
+  virtual gfx::SourceSurface* GetSurface(gfx::DrawTarget* aTarget) MOZ_OVERRIDE;
 
   virtual void DeallocateDeviceData() MOZ_OVERRIDE { }
 
   virtual void SetCompositor(Compositor* aCompositor);
 
   static gfx::SurfaceFormat ContentTypeToSurfaceFormat(gfxContentType aType);
 
 protected:
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -7,16 +7,17 @@
 #include "nsMemory.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Base64.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 #include "nsISupportsImpl.h"
 #include "mozilla/gfx/2D.h"
+#include "gfx2DGlue.h"
 
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "gfxRect.h"
 
 #include "cairo.h"
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -732,30 +732,32 @@ gfxPlatform::GetSourceSurfaceForSurface(
 
 #ifdef XP_WIN
   if (aSurface->GetType() == gfxSurfaceType::D2D &&
       format != SurfaceFormat::A8) {
     NativeSurface surf;
     surf.mFormat = format;
     surf.mType = NativeSurfaceType::D3D10_TEXTURE;
     surf.mSurface = static_cast<gfxD2DSurface*>(aSurface)->GetTexture();
+    surf.mSize = ToIntSize(aSurface->GetSize());
     mozilla::gfx::DrawTarget *dt = static_cast<mozilla::gfx::DrawTarget*>(aSurface->GetData(&kDrawTarget));
     if (dt) {
       dt->Flush();
     }
     srcBuffer = aTarget->CreateSourceSurfaceFromNativeSurface(surf);
   } else
 #endif
   if (aSurface->CairoSurface() && aTarget->GetType() == BackendType::CAIRO) {
     // If this is an xlib cairo surface we don't want to fetch it into memory
     // because this is a major slow down.
     NativeSurface surf;
     surf.mFormat = format;
     surf.mType = NativeSurfaceType::CAIRO_SURFACE;
     surf.mSurface = aSurface->CairoSurface();
+    surf.mSize = ToIntSize(aSurface->GetSize());
     srcBuffer = aTarget->CreateSourceSurfaceFromNativeSurface(surf);
 
     if (srcBuffer) {
       // It's cheap enough to make a new one so we won't keep it around and
       // keeping it creates a cycle.
       return srcBuffer;
     }
   }
--- a/gfx/thebes/gfxXlibNativeRenderer.cpp
+++ b/gfx/thebes/gfxXlibNativeRenderer.cpp
@@ -570,28 +570,29 @@ gfxXlibNativeRenderer::Draw(gfxContext* 
         cairo_paint(tmpCtx);
         cairo_destroy(tmpCtx);
     }
 
     if (!DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft())) {
         cairo_surface_destroy(tempXlibSurface);
         return;
     }
-  
+
     SurfaceFormat moz2DFormat =
         cairo_surface_get_content(tempXlibSurface) == CAIRO_CONTENT_COLOR ?
             SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8;
     if (method != eAlphaExtraction) {
         if (drawTarget) {
-            // It doesn't matter if moz2DFormat doesn't exactly match the format
-            // of tempXlibSurface, since this DrawTarget just wraps the cairo
-            // drawing.
+            NativeSurface native;
+            native.mFormat = moz2DFormat;
+            native.mType = NativeSurfaceType::CAIRO_SURFACE;
+            native.mSurface = tempXlibSurface;
+            native.mSize = ToIntSize(size);
             RefPtr<SourceSurface> sourceSurface =
-                Factory::CreateSourceSurfaceForCairoSurface(tempXlibSurface,
-                                                            moz2DFormat);
+                drawTarget->CreateSourceSurfaceFromNativeSurface(native);
             if (sourceSurface) {
                 drawTarget->DrawSurface(sourceSurface,
                     Rect(offset.x, offset.y, size.width, size.height),
                     Rect(0, 0, size.width, size.height));
             }
         } else {
             nsRefPtr<gfxASurface> tmpSurf = gfxASurface::Wrap(tempXlibSurface);
             ctx->SetSource(tmpSurf, offset);
@@ -617,19 +618,23 @@ gfxXlibNativeRenderer::Draw(gfxContext* 
         whiteImage->CairoStatus() == CAIRO_STATUS_SUCCESS) {
         if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage)) {
             cairo_surface_destroy(tempXlibSurface);
             return;
         }
 
         gfxASurface* paintSurface = blackImage;
         if (drawTarget) {
+            NativeSurface native;
+            native.mFormat = moz2DFormat;
+            native.mType = NativeSurfaceType::CAIRO_SURFACE;
+            native.mSurface = tempXlibSurface;
+            native.mSize = ToIntSize(size);
             RefPtr<SourceSurface> sourceSurface =
-                Factory::CreateSourceSurfaceForCairoSurface(paintSurface->CairoSurface(),
-                                                            moz2DFormat);
+                drawTarget->CreateSourceSurfaceFromNativeSurface(native);
             if (sourceSurface) {
                 drawTarget->DrawSurface(sourceSurface,
                     Rect(offset.x, offset.y, size.width, size.height),
                     Rect(0, 0, size.width, size.height));
             }
         } else {
             ctx->SetSource(paintSurface, offset);
             ctx->Paint();