Bug 756601 - Send the values of mScaleToSize/mScaleMode across IPC. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 10 May 2013 09:02:50 +1200
changeset 138218 47a188160811d46a8d6d80d32e534200b3f4b318
parent 138217 01443bd094b967c6287ac2a9d2fff10d662fa954
child 138219 a260551434fe50e44d061639f75a82726fc49d08
push id3752
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 17:21:10 +0000
treeherdermozilla-aurora@1580544aef0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs756601
milestone23.0a1
Bug 756601 - Send the values of mScaleToSize/mScaleMode across IPC. r=roc
gfx/layers/ImageLayers.h
gfx/layers/client/ClientImageLayer.cpp
gfx/layers/composite/ImageLayerComposite.cpp
gfx/layers/composite/ImageLayerComposite.h
gfx/layers/ipc/LayerTransaction.ipdlh
gfx/layers/ipc/LayerTransactionParent.cpp
ipc/glue/IPCMessageUtils.h
--- a/gfx/layers/ImageLayers.h
+++ b/gfx/layers/ImageLayers.h
@@ -19,17 +19,18 @@ class ImageContainer;
 
 /**
  * A Layer which renders an Image.
  */
 class THEBES_API ImageLayer : public Layer {
 public:
   enum ScaleMode {
     SCALE_NONE,
-    SCALE_STRETCH
+    SCALE_STRETCH,
+    SCALE_SENTINEL
   // Unimplemented - SCALE_PRESERVE_ASPECT_RATIO_CONTAIN
   };
 
   /**
    * CONSTRUCTION PHASE ONLY
    * Set the ImageContainer. aContainer must have the same layer manager
    * as this layer.
    */
@@ -49,18 +50,21 @@ public:
   }
 
   /**
    * CONSTRUCTION PHASE ONLY
    * Set the size to scale the image to and the mode at which to scale.
    */
   void SetScaleToSize(const gfxIntSize &aSize, ScaleMode aMode)
   {
-    mScaleToSize = aSize;
-    mScaleMode = aMode;
+    if (mScaleToSize != aSize || mScaleMode != aMode) {
+      mScaleToSize = aSize;
+      mScaleMode = aMode;
+      Mutated();
+    }
   }
 
 
   ImageContainer* GetContainer() { return mContainer; }
   gfxPattern::GraphicsFilter GetFilter() { return mFilter; }
   const gfxIntSize& GetScaleToSize() { return mScaleToSize; }
   ScaleMode GetScaleMode() { return mScaleMode; }
 
--- a/gfx/layers/client/ClientImageLayer.cpp
+++ b/gfx/layers/client/ClientImageLayer.cpp
@@ -45,17 +45,17 @@ public:
   
   virtual void ClearCachedResources() MOZ_OVERRIDE
   {
     DestroyBackBuffer();
   }
 
   virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
   {
-    aAttrs = ImageLayerAttributes(mFilter);
+    aAttrs = ImageLayerAttributes(mFilter, mScaleToSize, mScaleMode);
   }
 
   virtual Layer* AsLayer() { return this; }
   virtual ShadowableLayer* AsShadowableLayer() { return this; }
 
   virtual void Disconnect()
   {
     DestroyBackBuffer();
--- a/gfx/layers/composite/ImageLayerComposite.cpp
+++ b/gfx/layers/composite/ImageLayerComposite.cpp
@@ -85,16 +85,44 @@ ImageLayerComposite::RenderLayer(const n
   mImageHost->Composite(effectChain,
                         GetEffectiveOpacity(),
                         transform,
                         gfx::Point(aOffset.x, aOffset.y),
                         gfx::ToFilter(mFilter),
                         clipRect);
 }
 
+void 
+ImageLayerComposite::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
+{
+  gfx3DMatrix local = GetLocalTransform();
+
+  // Snap image edges to pixel boundaries
+  gfxRect sourceRect(0, 0, 0, 0);
+  if (mImageHost && mImageHost->GetTextureHost()) {
+    IntSize size = mImageHost->GetTextureHost()->GetSize();
+    sourceRect.SizeTo(size.width, size.height);
+    if (mScaleMode != SCALE_NONE &&
+        sourceRect.width != 0.0 && sourceRect.height != 0.0) {
+      NS_ASSERTION(mScaleMode == SCALE_STRETCH,
+                   "No other scalemodes than stretch and none supported yet.");
+      local.Scale(mScaleToSize.width / sourceRect.width,
+                  mScaleToSize.height / sourceRect.height, 1.0);
+    }
+  }
+  // Snap our local transform first, and snap the inherited transform as well.
+  // This makes our snapping equivalent to what would happen if our content
+  // was drawn into a ThebesLayer (gfxContext would snap using the local
+  // transform, then we'd snap again when compositing the ThebesLayer).
+  mEffectiveTransform =
+      SnapTransform(local, sourceRect, nullptr) *
+      SnapTransformTranslation(aTransformToSurface, nullptr);
+  ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
+}
+
 CompositableHost*
 ImageLayerComposite::GetCompositableHost() {
   return mImageHost.get();
 }
 
 void
 ImageLayerComposite::CleanupResources()
 {
--- a/gfx/layers/composite/ImageLayerComposite.h
+++ b/gfx/layers/composite/ImageLayerComposite.h
@@ -34,16 +34,18 @@ public:
 
   virtual void SetCompositableHost(CompositableHost* aHost) MOZ_OVERRIDE;
 
   virtual Layer* GetLayer() MOZ_OVERRIDE;
 
   virtual void RenderLayer(const nsIntPoint& aOffset,
                            const nsIntRect& aClipRect);
 
+  virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) MOZ_OVERRIDE;
+
   virtual void CleanupResources() MOZ_OVERRIDE;
 
   CompositableHost* GetCompositableHost() MOZ_OVERRIDE;
 
   virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; }
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() const { return "ImageLayerComposite"; }
--- a/gfx/layers/ipc/LayerTransaction.ipdlh
+++ b/gfx/layers/ipc/LayerTransaction.ipdlh
@@ -12,28 +12,30 @@ include protocol PGrallocBuffer;
 include protocol PLayer;
 include protocol PRenderFrame;
 
 include "mozilla/WidgetUtils.h";
 include "mozilla/TimeStamp.h";
 include "mozilla/dom/ScreenOrientation.h";
 include "nsCSSProperty.h";
 include "gfxipc/ShadowLayerUtils.h";
+include "ImageLayers.h";
 
 using gfxPoint3D;
 using nscoord;
 using nsRect;
 using nsPoint;
 using mozilla::TimeDuration;
 using mozilla::TimeStamp;
 using mozilla::ScreenRotation;
 using nsCSSProperty;
 using mozilla::dom::ScreenOrientation;
 using mozilla::layers::TextureInfo;
 using mozilla::gfx::Margin;
+using mozilla::layers::ImageLayer::ScaleMode;
 
 namespace mozilla {
 namespace layers {
 
 struct TargetConfig {
   nsIntRect naturalBounds;
   ScreenRotation rotation;
   nsIntRect clientBounds;
@@ -197,17 +199,17 @@ struct ContainerLayerAttributes {
   float preXScale;
   float preYScale;
   float inheritedXScale;
   float inheritedYScale;
 };
 struct ColorLayerAttributes     { LayerColor color; };
 struct CanvasLayerAttributes    { GraphicsFilterType filter; nsIntRect bounds; };
 struct RefLayerAttributes       { int64_t id; };
-struct ImageLayerAttributes     { GraphicsFilterType filter; };
+struct ImageLayerAttributes     { GraphicsFilterType filter; gfxIntSize scaleToSize; ScaleMode scaleMode; };
 
 union SpecificLayerAttributes {
   null_t;
   ThebesLayerAttributes;
   ContainerLayerAttributes;
   ColorLayerAttributes;
   CanvasLayerAttributes;
   RefLayerAttributes;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -317,16 +317,17 @@ LayerTransactionParent::RecvUpdate(const
         break;
 
       case Specific::TImageLayerAttributes: {
         MOZ_LAYERS_LOG(("[ParentSide]   image layer"));
 
         ImageLayer* imageLayer = static_cast<ImageLayer*>(layer);
         const ImageLayerAttributes& attrs = specific.get_ImageLayerAttributes();
         imageLayer->SetFilter(attrs.filter());
+        imageLayer->SetScaleToSize(attrs.scaleToSize(), attrs.scaleMode());
         break;
       }
       default:
         NS_RUNTIMEABORT("not reached");
       }
       break;
     }
     case Edit::TOpSetColoredBorders: {
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -31,16 +31,17 @@
 #include "nsRect.h"
 #include "nsRegion.h"
 #include "gfxASurface.h"
 #include "jsapi.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "FrameMetrics.h"
 #include "nsCSSProperty.h"
+#include "ImageLayers.h"
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4800 )
 #endif
 
 #if !defined(OS_POSIX)
 // This condition must be kept in sync with the one in
 // ipc_message_utils.h, but this dummy definition of
@@ -52,16 +53,17 @@ namespace base { struct FileDescriptor {
 
 namespace mozilla {
 
 typedef gfxASurface::gfxContentType gfxContentType;
 typedef gfxASurface::gfxImageFormat PixelFormat;
 typedef gfxASurface::gfxSurfaceType gfxSurfaceType;
 typedef gfxPattern::GraphicsFilter GraphicsFilterType;
 typedef layers::LayersBackend LayersBackend;
+typedef layers::ImageLayer::ScaleMode ScaleMode;
 
 // This is a cross-platform approximation to HANDLE, which we expect
 // to be typedef'd to void* or thereabouts.
 typedef uintptr_t WindowsHandle;
 
 // XXX there are out of place and might be generally useful.  Could
 // move to nscore.h or something.
 struct void_t {
@@ -609,16 +611,23 @@ struct ParamTraits<mozilla::GraphicsFilt
 template <>
 struct ParamTraits<mozilla::layers::LayersBackend>
   : public EnumSerializer<mozilla::layers::LayersBackend,
                           mozilla::layers::LAYERS_NONE,
                           mozilla::layers::LAYERS_LAST>
 {};
 
 template <>
+struct ParamTraits<mozilla::ScaleMode>
+  : public EnumSerializer<mozilla::ScaleMode,
+                          mozilla::layers::ImageLayer::SCALE_NONE,
+                          mozilla::layers::ImageLayer::SCALE_SENTINEL>
+{};
+
+template <>
 struct ParamTraits<mozilla::PixelFormat>
   : public EnumSerializer<mozilla::PixelFormat,
                           gfxASurface::ImageFormatARGB32,
                           gfxASurface::ImageFormatUnknown>
 {};
 
 template <>
 struct ParamTraits<nsCSSProperty>