Bug 909881 - Save the zoom constraints in RenderFrameParent so that TabChild can send them before the APZC is created and they don't get lost. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 13 Sep 2013 10:18:33 -0400
changeset 147032 64751fbe352f32f13f4fd1dbddacd24939cb0729
parent 147031 b28702f474ebc0e9c66df43f00fdd2563432d348
child 147033 3bbea4db9ac64cb9da22422980c0a8fc27a0edcf
push id999
push userkgupta@mozilla.com
push dateFri, 13 Sep 2013 14:19:03 +0000
treeherderb2g-inbound@3bbea4db9ac6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs909881
milestone26.0a1
Bug 909881 - Save the zoom constraints in RenderFrameParent so that TabChild can send them before the APZC is created and they don't get lost. r=botond
gfx/layers/composite/APZCTreeManager.cpp
gfx/layers/ipc/GeckoContentController.h
layout/ipc/RenderFrameParent.cpp
--- a/gfx/layers/composite/APZCTreeManager.cpp
+++ b/gfx/layers/composite/APZCTreeManager.cpp
@@ -110,17 +110,19 @@ APZCTreeManager::UpdatePanZoomController
     if (container->GetFrameMetrics().IsScrollable()) {
       const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
       if (state && state->mController.get()) {
         // If we get here, aLayer is a scrollable container layer and somebody
         // has registered a GeckoContentController for it, so we need to ensure
         // it has an APZC instance to manage its scrolling.
 
         controller = container->GetAsyncPanZoomController();
-        if (!controller) {
+
+        bool newController = (controller == nullptr);
+        if (newController) {
           controller = new AsyncPanZoomController(aLayersId, state->mController,
                                                   AsyncPanZoomController::USE_GESTURE_DETECTOR);
           controller->SetCompositorParent(aCompositor);
         } else {
           // If there was already an APZC for the layer clear the tree pointers
           // so that it doesn't continue pointing to APZCs that should no longer
           // be in the tree. These pointers will get reset properly as we continue
           // building the tree. Also remove it from the set of APZCs that are going
@@ -146,16 +148,27 @@ APZCTreeManager::UpdatePanZoomController
         } else if (aParent) {
           aParent->SetLastChild(controller);
         } else {
           mRootApzc = controller;
         }
 
         // Let this controller be the parent of other controllers when we recurse downwards
         aParent = controller;
+
+        if (newController && controller->IsRootForLayersId()) {
+          // If we just created a new controller that is the root for its layers ID, then
+          // we need to update its zoom constraints which might have arrived before this
+          // was created
+          bool allowZoom;
+          CSSToScreenScale minZoom, maxZoom;
+          if (state->mController->GetZoomConstraints(&allowZoom, &minZoom, &maxZoom)) {
+            controller->UpdateZoomConstraints(allowZoom, minZoom, maxZoom);
+          }
+        }
       }
     }
 
     container->SetAsyncPanZoomController(controller);
   }
 
   // Accumulate the CSS transform between layers that have an APZC, but exclude any
   // any layers that do have an APZC, and reset the accumulation at those layers.
--- a/gfx/layers/ipc/GeckoContentController.h
+++ b/gfx/layers/ipc/GeckoContentController.h
@@ -59,16 +59,26 @@ public:
                                        const CSSSize &aScrollableSize) = 0;
 
   /**
    * Schedules a runnable to run on the controller/UI thread at some time
    * in the future.
    */
   virtual void PostDelayedTask(Task* aTask, int aDelayMs) = 0;
 
+  /**
+   * Retrieves the last known zoom constraints. This function should return
+   * false if there are no last known zoom constraints.
+   */
+  virtual bool GetZoomConstraints(bool* aOutAllowZoom,
+                                  CSSToScreenScale* aOutMinZoom,
+                                  CSSToScreenScale* aOutMaxZoom)
+  {
+    return false;
+  }
 
   /**
    * Request any special actions be performed when panning starts
    */
   virtual void HandlePanBegin() {}
 
   /**
    * Request any special actions be performed when panning ends
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -482,16 +482,18 @@ GetFrom(nsFrameLoader* aFrameLoader)
   return nsContentUtils::LayerManagerForDocument(doc);
 }
 
 class RemoteContentController : public GeckoContentController {
 public:
   RemoteContentController(RenderFrameParent* aRenderFrame)
     : mUILoop(MessageLoop::current())
     , mRenderFrame(aRenderFrame)
+    , mHaveZoomConstraints(false)
+    , mAllowZoom(true)
   { }
 
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) MOZ_OVERRIDE
   {
     // We always need to post requests into the "UI thread" otherwise the
     // requests may get processed out of order.
     mUILoop->PostTask(
       FROM_HERE,
@@ -571,27 +573,54 @@ public:
     }
   }
 
   virtual void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE
   {
     MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
   }
 
+  void SaveZoomConstraints(bool aAllowZoom,
+                           const CSSToScreenScale& aMinZoom,
+                           const CSSToScreenScale& aMaxZoom)
+  {
+    mHaveZoomConstraints = true;
+    mAllowZoom = aAllowZoom;
+    mMinZoom = aMinZoom;
+    mMaxZoom = aMaxZoom;
+  }
+
+  virtual bool GetZoomConstraints(bool* aOutAllowZoom,
+                                  CSSToScreenScale* aOutMinZoom,
+                                  CSSToScreenScale* aOutMaxZoom)
+  {
+    if (mHaveZoomConstraints) {
+      *aOutAllowZoom = mAllowZoom;
+      *aOutMinZoom = mMinZoom;
+      *aOutMaxZoom = mMaxZoom;
+    }
+    return mHaveZoomConstraints;
+  }
+
 private:
   void DoRequestContentRepaint(const FrameMetrics& aFrameMetrics)
   {
     if (mRenderFrame) {
       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
       browser->UpdateFrame(aFrameMetrics);
     }
   }
 
   MessageLoop* mUILoop;
   RenderFrameParent* mRenderFrame;
+
+  bool mHaveZoomConstraints;
+  bool mAllowZoom;
+  CSSToScreenScale mMinZoom;
+  CSSToScreenScale mMaxZoom;
 };
 
 RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
                                      ScrollingBehavior aScrollingBehavior,
                                      TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                      uint64_t* aId)
   : mLayersId(0)
   , mFrameLoader(aFrameLoader)
@@ -1007,16 +1036,19 @@ RenderFrameParent::ContentReceivedTouch(
   }
 }
 
 void
 RenderFrameParent::UpdateZoomConstraints(bool aAllowZoom,
                                          const CSSToScreenScale& aMinZoom,
                                          const CSSToScreenScale& aMaxZoom)
 {
+  if (mContentController) {
+    mContentController->SaveZoomConstraints(aAllowZoom, aMinZoom, aMaxZoom);
+  }
   if (GetApzcTreeManager()) {
     GetApzcTreeManager()->UpdateZoomConstraints(ScrollableLayerGuid(mLayersId),
                                                 aAllowZoom, aMinZoom, aMaxZoom);
   }
 }
 
 void
 RenderFrameParent::UpdateScrollOffset(uint32_t aPresShellId, ViewID aViewId, const CSSIntPoint& aScrollOffset)