Backout bug 818575
authorNicholas Cameron <ncameron@mozilla.com>
Wed, 09 Jan 2013 18:06:35 +0100
changeset 118438 b28889afccbee0dd3709230913d85acc0138f723
parent 118437 5be4511b8225fbe33e31b584027dd896bb49bbf1
child 118439 f9ef215299560fe911e42d13f5280af2f236fad2
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs818575
milestone21.0a1
Backout bug 818575
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -225,46 +225,16 @@ LayerManager::GetPrimaryScrollableLayer(
       queue.AppendElement(child);
       child = child->GetNextSibling();
     }
   }
 
   return mRoot;
 }
 
-void
-LayerManager::GetScrollableLayers(nsTArray<Layer*>& aArray)
-{
-  if (!mRoot) {
-    return;
-  }
-
-  nsTArray<Layer*> queue;
-  queue.AppendElement(mRoot);
-  while (!queue.IsEmpty()) {
-    ContainerLayer* containerLayer = queue.LastElement()->AsContainerLayer();
-    queue.RemoveElementAt(queue.Length() - 1);
-    if (!containerLayer) {
-      continue;
-    }
-
-    const FrameMetrics& frameMetrics = containerLayer->GetFrameMetrics();
-    if (frameMetrics.IsScrollable()) {
-      aArray.AppendElement(containerLayer);
-      continue;
-    }
-
-    Layer* child = containerLayer->GetFirstChild();
-    while (child) {
-      queue.AppendElement(child);
-      child = child->GetNextSibling();
-    }
-  }
-}
-
 already_AddRefed<gfxASurface>
 LayerManager::CreateOptimalSurface(const gfxIntSize &aSize,
                                    gfxASurface::gfxImageFormat aFormat)
 {
   return gfxPlatform::GetPlatform()->
     CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFormat));
 }
 
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -283,22 +283,16 @@ public:
   /**
    * Does a breadth-first search from the root layer to find the first
    * scrollable layer.
    * Can be called any time.
    */
   Layer* GetPrimaryScrollableLayer();
 
   /**
-   * Returns a list of all descendant layers for which 
-   * GetFrameMetrics().IsScrollable() is true.
-   */
-  void GetScrollableLayers(nsTArray<Layer*>& aArray);
-
-  /**
    * CONSTRUCTION PHASE ONLY
    * Called when a managee has mutated.
    * Subclasses overriding this method must first call their
    * superclass's impl
    */
 #ifdef DEBUG
   // In debug builds, we check some properties of |aLayer|.
   virtual void Mutated(Layer* aLayer);
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -894,168 +894,152 @@ CompositorParent::ApplyAsyncContentTrans
       treeTransform.mScale);
 
     appliedTransform = true;
   }
 
   return appliedTransform;
 }
 
-void
-CompositorParent::TransformScrollableLayer(Layer* aLayer,
-                                           const gfx3DMatrix& aRootTransform,
-                                           bool aPrimaryLayer)
-{
-  ShadowLayer* shadow = aLayer->AsShadowLayer();
-  ContainerLayer* container = aLayer->AsContainerLayer();
-
-  const FrameMetrics& metrics = container->GetFrameMetrics();
-  // We must apply the resolution scale before a pan/zoom transform, so we call
-  // GetTransform here.
-  const gfx3DMatrix& currentTransform = aLayer->GetTransform();
-
-  gfx3DMatrix treeTransform;
-
-  // Translate fixed position layers so that they stay in the correct position
-  // when mScrollOffset and metricsScrollOffset differ.
-  gfxPoint offset;
-  gfxSize scaleDiff;
-
-  float rootScaleX = aRootTransform.GetXScale(),
-        rootScaleY = aRootTransform.GetYScale();
-  // The ratio of layers pixels to device pixels.  The Java
-  // compositor wants to see values in units of device pixels, so we
-  // map our FrameMetrics values to that space.  This is not exposed
-  // as a FrameMetrics helper because it's a deprecated conversion.
-  float devPixelRatioX = 1 / rootScaleX, devPixelRatioY = 1 / rootScaleY;
-
-  gfxPoint scrollOffsetLayersPixels(metrics.GetScrollOffsetInLayerPixels());
-  nsIntPoint scrollOffsetDevPixels(
-    NS_lround(scrollOffsetLayersPixels.x * devPixelRatioX),
-    NS_lround(scrollOffsetLayersPixels.y * devPixelRatioY));
-
-  if (mIsFirstPaint) {
-    mContentRect = metrics.mContentRect;
-    SetFirstPaintViewport(scrollOffsetDevPixels,
-                          1/rootScaleX,
-                          mContentRect,
-                          metrics.mScrollableRect);
-    mIsFirstPaint = false;
-  } else if (!metrics.mContentRect.IsEqualEdges(mContentRect)) {
-    mContentRect = metrics.mContentRect;
-    SetPageRect(metrics.mScrollableRect);
-  }
-
-  // We synchronise the viewport information with Java after sending the above
-  // notifications, so that Java can take these into account in its response.
-  // Calculate the absolute display port to send to Java
-  gfx::Rect displayPortLayersPixels(metrics.mCriticalDisplayPort.IsEmpty() ?
-                                    metrics.mDisplayPort : metrics.mCriticalDisplayPort);
-  nsIntRect displayPortDevPixels(
-    NS_lround(displayPortLayersPixels.x * devPixelRatioX),
-    NS_lround(displayPortLayersPixels.y * devPixelRatioY),
-    NS_lround(displayPortLayersPixels.width * devPixelRatioX),
-    NS_lround(displayPortLayersPixels.height * devPixelRatioY));
-
-  displayPortDevPixels.x += scrollOffsetDevPixels.x;
-  displayPortDevPixels.y += scrollOffsetDevPixels.y;
-
-  if (aPrimaryLayer) {
-    SyncViewportInfo(displayPortDevPixels, 1/rootScaleX, mLayersUpdated,
-                     mScrollOffset, mXScale, mYScale);
-    mLayersUpdated = false;
-  }
-
-  // Handle transformations for asynchronous panning and zooming. We determine the
-  // zoom used by Gecko from the transformation set on the root layer, and we
-  // determine the scroll offset used by Gecko from the frame metrics of the
-  // primary scrollable layer. We compare this to the desired zoom and scroll
-  // offset in the view transform we obtained from Java in order to compute the
-  // transformation we need to apply.
-  float tempScaleDiffX = rootScaleX * mXScale;
-  float tempScaleDiffY = rootScaleY * mYScale;
-
-  nsIntPoint metricsScrollOffset(0, 0);
-  if (metrics.IsScrollable()) {
-    metricsScrollOffset = scrollOffsetDevPixels;
-  }
-
-  nsIntPoint scrollCompensation(
-    (mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale,
-    (mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale);
-  treeTransform = gfx3DMatrix(ViewTransform(-scrollCompensation,
-                                            gfxSize(mXScale, mYScale)));
-
-  // If the contents can fit entirely within the widget area on a particular
-  // dimenson, we need to translate and scale so that the fixed layers remain
-  // within the page boundaries.
-  if (mContentRect.width * tempScaleDiffX < mWidgetSize.width) {
-    offset.x = -metricsScrollOffset.x;
-    scaleDiff.width = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width);
-  } else {
-    offset.x = clamped(mScrollOffset.x / tempScaleDiffX, (float)mContentRect.x,
-                       mContentRect.XMost() - mWidgetSize.width / tempScaleDiffX) -
-               metricsScrollOffset.x;
-    scaleDiff.width = tempScaleDiffX;
-  }
-
-  if (mContentRect.height * tempScaleDiffY < mWidgetSize.height) {
-    offset.y = -metricsScrollOffset.y;
-    scaleDiff.height = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height);
-  } else {
-    offset.y = clamped(mScrollOffset.y / tempScaleDiffY, (float)mContentRect.y,
-                       mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY) -
-               metricsScrollOffset.y;
-    scaleDiff.height = tempScaleDiffY;
-  }
-
-  // The transform already takes the resolution scale into account.  Since we
-  // will apply the resolution scale again when computing the effective
-  // transform, we must apply the inverse resolution scale here.
-  gfx3DMatrix computedTransform = treeTransform * currentTransform;
-  computedTransform.Scale(1.0f/container->GetPreXScale(),
-                          1.0f/container->GetPreYScale(),
-                          1);
-  computedTransform.ScalePost(1.0f/container->GetPostXScale(),
-                              1.0f/container->GetPostYScale(),
-                              1);
-  shadow->SetShadowTransform(computedTransform);
-  TransformFixedLayers(aLayer, offset, scaleDiff);
-}
-
 bool
 CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
 {
   bool wantNextFrame = false;
+  Layer* layer = mLayerManager->GetPrimaryScrollableLayer();
+  ShadowLayer* shadow = layer->AsShadowLayer();
+  ContainerLayer* container = layer->AsContainerLayer();
   Layer* root = mLayerManager->GetRoot();
 
   // NB: we must sample animations *before* sampling pan/zoom
   // transforms.
   wantNextFrame |= SampleAnimations(root, aCurrentFrame);
 
+  const FrameMetrics& metrics = container->GetFrameMetrics();
+  // We must apply the resolution scale before a pan/zoom transform, so we call
+  // GetTransform here.
   const gfx3DMatrix& rootTransform = root->GetTransform();
+  const gfx3DMatrix& currentTransform = layer->GetTransform();
 
   // FIXME/bug 775437: unify this interface with the ~native-fennec
   // derived code
   //
   // Attempt to apply an async content transform to any layer that has
   // an async pan zoom controller (which means that it is rendered
   // async using Gecko). If this fails, fall back to transforming the
   // primary scrollable layer.  "Failing" here means that we don't
   // find a frame that is async scrollable.  Note that the fallback
   // code also includes Fennec which is rendered async.  Fennec uses
   // its own platform-specific async rendering that is done partially
   // in Gecko and partially in Java.
   if (!ApplyAsyncContentTransformToTree(aCurrentFrame, root, &wantNextFrame)) {
-    nsAutoTArray<Layer*,1> scrollableLayers;
-    mLayerManager->GetScrollableLayers(scrollableLayers);
+    gfx3DMatrix treeTransform;
+
+    // Translate fixed position layers so that they stay in the correct position
+    // when mScrollOffset and metricsScrollOffset differ.
+    gfxPoint offset;
+    gfxSize scaleDiff;
+
+    float rootScaleX = rootTransform.GetXScale(),
+          rootScaleY = rootTransform.GetYScale();
+    // The ratio of layers pixels to device pixels.  The Java
+    // compositor wants to see values in units of device pixels, so we
+    // map our FrameMetrics values to that space.  This is not exposed
+    // as a FrameMetrics helper because it's a deprecated conversion.
+    float devPixelRatioX = 1 / rootScaleX, devPixelRatioY = 1 / rootScaleY;
+
+    gfxPoint scrollOffsetLayersPixels(metrics.GetScrollOffsetInLayerPixels());
+    nsIntPoint scrollOffsetDevPixels(
+      NS_lround(scrollOffsetLayersPixels.x * devPixelRatioX),
+      NS_lround(scrollOffsetLayersPixels.y * devPixelRatioY));
+
+    if (mIsFirstPaint) {
+      mContentRect = metrics.mContentRect;
+      SetFirstPaintViewport(scrollOffsetDevPixels,
+                            1/rootScaleX,
+                            mContentRect,
+                            metrics.mScrollableRect);
+      mIsFirstPaint = false;
+    } else if (!metrics.mContentRect.IsEqualEdges(mContentRect)) {
+      mContentRect = metrics.mContentRect;
+      SetPageRect(metrics.mScrollableRect);
+    }
+
+    // We synchronise the viewport information with Java after sending the above
+    // notifications, so that Java can take these into account in its response.
+    // Calculate the absolute display port to send to Java
+    gfx::Rect displayPortLayersPixels(metrics.mCriticalDisplayPort.IsEmpty() ?
+                                      metrics.mDisplayPort : metrics.mCriticalDisplayPort);
+    nsIntRect displayPortDevPixels(
+      NS_lround(displayPortLayersPixels.x * devPixelRatioX),
+      NS_lround(displayPortLayersPixels.y * devPixelRatioY),
+      NS_lround(displayPortLayersPixels.width * devPixelRatioX),
+      NS_lround(displayPortLayersPixels.height * devPixelRatioY));
+
+    displayPortDevPixels.x += scrollOffsetDevPixels.x;
+    displayPortDevPixels.y += scrollOffsetDevPixels.y;
+
+    SyncViewportInfo(displayPortDevPixels, 1/rootScaleX, mLayersUpdated,
+                     mScrollOffset, mXScale, mYScale);
+    mLayersUpdated = false;
 
-    for (uint32_t i = 0; i < scrollableLayers.Length(); i++) {
-      TransformScrollableLayer(scrollableLayers[i], rootTransform, i == 0);
+    // Handle transformations for asynchronous panning and zooming. We determine the
+    // zoom used by Gecko from the transformation set on the root layer, and we
+    // determine the scroll offset used by Gecko from the frame metrics of the
+    // primary scrollable layer. We compare this to the desired zoom and scroll
+    // offset in the view transform we obtained from Java in order to compute the
+    // transformation we need to apply.
+    float tempScaleDiffX = rootScaleX * mXScale;
+    float tempScaleDiffY = rootScaleY * mYScale;
+
+    nsIntPoint metricsScrollOffset(0, 0);
+    if (metrics.IsScrollable()) {
+      metricsScrollOffset = scrollOffsetDevPixels;
     }
+
+    nsIntPoint scrollCompensation(
+      (mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale,
+      (mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale);
+    treeTransform = gfx3DMatrix(ViewTransform(-scrollCompensation,
+                                              gfxSize(mXScale, mYScale)));
+
+    // If the contents can fit entirely within the widget area on a particular
+    // dimenson, we need to translate and scale so that the fixed layers remain
+    // within the page boundaries.
+    if (mContentRect.width * tempScaleDiffX < mWidgetSize.width) {
+      offset.x = -metricsScrollOffset.x;
+      scaleDiff.height = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width);
+    } else {
+      offset.x = clamped(mScrollOffset.x / tempScaleDiffX, (float)mContentRect.x,
+                         mContentRect.XMost() - mWidgetSize.width / tempScaleDiffX) -
+                 metricsScrollOffset.x;
+      scaleDiff.height = tempScaleDiffX;
+    }
+
+    if (mContentRect.height * tempScaleDiffY < mWidgetSize.height) {
+      offset.y = -metricsScrollOffset.y;
+      scaleDiff.width = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height);
+    } else {
+      offset.y = clamped(mScrollOffset.y / tempScaleDiffY, (float)mContentRect.y,
+                         mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY) -
+                 metricsScrollOffset.y;
+      scaleDiff.width = tempScaleDiffY;
+    }
+
+    // The transform already takes the resolution scale into account.  Since we
+    // will apply the resolution scale again when computing the effective
+    // transform, we must apply the inverse resolution scale here.
+    gfx3DMatrix computedTransform = treeTransform * currentTransform;
+    computedTransform.Scale(1.0f/container->GetPreXScale(),
+                            1.0f/container->GetPreYScale(),
+                            1);
+    computedTransform.ScalePost(1.0f/container->GetPostXScale(),
+                                1.0f/container->GetPostYScale(),
+                                1);
+    shadow->SetShadowTransform(computedTransform);
+    TransformFixedLayers(layer, offset, scaleDiff);
   }
 
   return wantNextFrame;
 }
 
 void
 CompositorParent::SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom,
                                         const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -184,18 +184,16 @@ private:
   void PauseComposition();
   void ResumeComposition();
   void ResumeCompositionAndResize(int width, int height);
   void ForceComposition();
 
   // Sample transforms for layer trees.  Return true to request
   // another animation frame.
   bool TransformShadowTree(TimeStamp aCurrentFrame);
-  void TransformScrollableLayer(Layer* aLayer, const gfx3DMatrix& aRootTransform,
-                                bool aPrimaryLayer);
   // Return true if an AsyncPanZoomController content transform was
   // applied for |aLayer|.  *aWantNextFrame is set to true if the
   // controller wants another animation frame.
   bool ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, Layer* aLayer,
                                         bool* aWantNextFrame);
 
   inline PlatformThreadId CompositorThreadID();