Bug 1270019 - Add a SetRestoreResolution API for fennec's SessionRestore to use. r=rbarker
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 17 May 2016 14:50:08 -0400
changeset 367946 1b2d84bdba961202dbc000051532e99248a6461c
parent 367943 d0ab0d508a248687825497a6a50ec9a685a7a5f9
child 367947 b37a67abf35af74a99d1f2cf8b49b22dcac71ac4
child 367973 5bfa8bdba06cde963e98ea3d033016bbe749daef
child 368317 cc6e32ff7333eabf2ec7ebed7825e6be91ba9516
child 368444 a88485a5b750bf1e6a567fea14d3302496a25701
child 368454 613c8dcd144ba77e817f6c37bdf24da8a9a06d76
push id18388
push userbmo:hskupin@gmail.com
push dateTue, 17 May 2016 18:58:40 +0000
reviewersrbarker
bugs1270019
milestone49.0a1
Bug 1270019 - Add a SetRestoreResolution API for fennec's SessionRestore to use. r=rbarker MozReview-Commit-ID: 7WqmgAkFItQ
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/MobileViewportManager.cpp
layout/base/MobileViewportManager.h
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -492,16 +492,29 @@ nsDOMWindowUtils::SetResolutionAndScaleT
   }
 
   presShell->SetResolutionAndScaleTo(aResolution);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::SetRestoreResolution(float aResolution)
+{
+  nsIPresShell* presShell = GetPresShell();
+  if (!presShell) {
+    return NS_ERROR_FAILURE;
+  }
+
+  presShell->SetRestoreResolution(aResolution);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::GetResolution(float* aResolution)
 {
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
     return NS_ERROR_FAILURE;
   }
 
   *aResolution = presShell->GetResolution();
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -218,16 +218,23 @@ interface nsIDOMWindowUtils : nsISupport
    * This can be used to implement a non-reflowing scale-zoom, e.g.
    * for pinch-zoom on mobile platforms.
    *
    * The caller of this method must have chrome privileges.
    */
   void setResolutionAndScaleTo(in float aResolution);
 
   /**
+   * Set a resolution on the presShell which is the "restored" from history.
+   * This resolution should be used when painting for the first time. Calling
+   * this too late may have no effect.
+   */
+  void setRestoreResolution(in float aResolution);
+
+  /**
    * Whether the resolution has been set by the user.
    * This gives a way to check whether the provided resolution is the default
    * value or restored from a previous session.
    *
    * Can only be accessed with chrome privileges.
    */
   readonly attribute boolean isResolutionSet;
 
--- a/layout/base/MobileViewportManager.cpp
+++ b/layout/base/MobileViewportManager.cpp
@@ -80,16 +80,22 @@ MobileViewportManager::Destroy()
     observerService->RemoveObserver(this, BEFORE_FIRST_PAINT.Data());
   }
 
   mDocument = nullptr;
   mPresShell = nullptr;
 }
 
 void
+MobileViewportManager::SetRestoreResolution(float aResolution)
+{
+  mRestoreResolution = Some(aResolution);
+}
+
+void
 MobileViewportManager::RequestReflow()
 {
   MVM_LOG("%p: got a reflow request\n", this);
   RefreshViewportSize(false);
 }
 
 void
 MobileViewportManager::ResolutionUpdated()
@@ -141,38 +147,54 @@ MobileViewportManager::SetInitialViewpor
 {
   MVM_LOG("%p: setting initial viewport\n", this);
   mIsFirstPaint = true;
   mPainted = true;
   RefreshViewportSize(false);
 }
 
 CSSToScreenScale
+MobileViewportManager::ClampZoom(const CSSToScreenScale& aZoom,
+                                 const nsViewportInfo& aViewportInfo)
+{
+  CSSToScreenScale zoom = aZoom;
+  if (zoom < aViewportInfo.GetMinZoom()) {
+    zoom = aViewportInfo.GetMinZoom();
+    MVM_LOG("%p: Clamped to %f\n", this, zoom.scale);
+  }
+  if (zoom > aViewportInfo.GetMaxZoom()) {
+    zoom = aViewportInfo.GetMaxZoom();
+    MVM_LOG("%p: Clamped to %f\n", this, zoom.scale);
+  }
+  return zoom;
+}
+
+CSSToScreenScale
 MobileViewportManager::UpdateResolution(const nsViewportInfo& aViewportInfo,
                                         const ScreenIntSize& aDisplaySize,
                                         const CSSSize& aViewport,
                                         const Maybe<float>& aDisplayWidthChangeRatio)
 {
   CSSToLayoutDeviceScale cssToDev =
       mPresShell->GetPresContext()->CSSToDevPixelScale();
   LayoutDeviceToLayerScale res(mPresShell->GetResolution());
 
   if (mIsFirstPaint) {
-    CSSToScreenScale defaultZoom = aViewportInfo.GetDefaultZoom();
-    MVM_LOG("%p: default zoom from viewport is %f\n", this, defaultZoom.scale);
-    if (!aViewportInfo.IsDefaultZoomValid()) {
-      defaultZoom = MaxScaleRatio(ScreenSize(aDisplaySize), aViewport);
-      MVM_LOG("%p: Intrinsic computed zoom is %f\n", this, defaultZoom.scale);
-      if (defaultZoom < aViewportInfo.GetMinZoom()) {
-        defaultZoom = aViewportInfo.GetMinZoom();
-        MVM_LOG("%p: Clamped to %f\n", this, defaultZoom.scale);
-      }
-      if (defaultZoom > aViewportInfo.GetMaxZoom()) {
-        defaultZoom = aViewportInfo.GetMaxZoom();
-        MVM_LOG("%p: Clamped to %f\n", this, defaultZoom.scale);
+    CSSToScreenScale defaultZoom;
+    if (mRestoreResolution) {
+      defaultZoom = CSSToScreenScale(mRestoreResolution.value() * cssToDev.scale);
+      MVM_LOG("%p: restored zoom is %f\n", this, defaultZoom.scale);
+      defaultZoom = ClampZoom(defaultZoom, aViewportInfo);
+    } else {
+      defaultZoom = aViewportInfo.GetDefaultZoom();
+      MVM_LOG("%p: default zoom from viewport is %f\n", this, defaultZoom.scale);
+      if (!aViewportInfo.IsDefaultZoomValid()) {
+        defaultZoom = MaxScaleRatio(ScreenSize(aDisplaySize), aViewport);
+        MVM_LOG("%p: Intrinsic computed zoom is %f\n", this, defaultZoom.scale);
+        defaultZoom = ClampZoom(defaultZoom, aViewportInfo);
       }
     }
     MOZ_ASSERT(aViewportInfo.GetMinZoom() <= defaultZoom &&
       defaultZoom <= aViewportInfo.GetMaxZoom());
 
     CSSToParentLayerScale zoom = ViewTargetAs<ParentLayerPixel>(defaultZoom,
       PixelCastJustification::ScreenIsParentLayerForRoot);
 
--- a/layout/base/MobileViewportManager.h
+++ b/layout/base/MobileViewportManager.h
@@ -22,16 +22,21 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMEVENTLISTENER
   NS_DECL_NSIOBSERVER
 
   MobileViewportManager(nsIPresShell* aPresShell,
                         nsIDocument* aDocument);
   void Destroy();
 
+  /* Provide a resolution to use during the first paint instead of the default
+   * resolution computed from the viewport info metadata. This is in the same
+   * "units" as the argument to nsDOMWindowUtils::SetResolutionAndScaleTo. */
+  void SetRestoreResolution(float aResolution);
+
   /* Notify the MobileViewportManager that a reflow was requested in the
    * presShell.*/
   void RequestReflow();
 
   /* Notify the MobileViewportManager that the resolution on the presShell was
    * updated, and the SPCSPS needs to be updated. */
   void ResolutionUpdated();
 
@@ -44,16 +49,20 @@ private:
 
   /* Main helper method to update the CSS viewport and any other properties that
    * need updating. */
   void RefreshViewportSize(bool aForceAdjustResolution);
 
   /* Secondary main helper method to update just the SPCSPS. */
   void RefreshSPCSPS();
 
+  /* Helper to clamp the given zoom by the min/max in the viewport info. */
+  mozilla::CSSToScreenScale ClampZoom(const mozilla::CSSToScreenScale& aZoom,
+                                      const nsViewportInfo& aViewportInfo);
+
   /* Updates the presShell resolution and returns the new zoom. */
   mozilla::CSSToScreenScale UpdateResolution(const nsViewportInfo& aViewportInfo,
                                              const mozilla::ScreenIntSize& aDisplaySize,
                                              const mozilla::CSSSize& aViewport,
                                              const mozilla::Maybe<float>& aDisplayWidthChangeRatio);
   /* Updates the scroll-position-clamping scrollport size */
   void UpdateSPCSPS(const mozilla::ScreenIntSize& aDisplaySize,
                     const mozilla::CSSToScreenScale& aZoom);
@@ -62,12 +71,13 @@ private:
 
   nsCOMPtr<nsIDocument> mDocument;
   nsIPresShell* MOZ_NON_OWNING_REF mPresShell; // raw ref since the presShell owns this
   nsCOMPtr<nsIDOMEventTarget> mEventTarget;
   bool mIsFirstPaint;
   bool mPainted;
   mozilla::LayoutDeviceIntSize mDisplaySize;
   mozilla::CSSSize mMobileViewportSize;
+  mozilla::Maybe<float> mRestoreResolution;
 };
 
 #endif
 
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1431,16 +1431,22 @@ public:
   /**
    * Return whether we are scaling to the set resolution.
    * This is initially false; it's set to true by a call to
    * SetResolutionAndScaleTo(), and set to false by a call to SetResolution().
    */
   virtual bool ScaleToResolution() const = 0;
 
   /**
+   * Used by session restore code to restore a resolution before the first
+   * paint.
+   */
+  virtual void SetRestoreResolution(float aResolution) = 0;
+
+  /**
    * Returns whether we are in a DrawWindow() call that used the
    * DRAWWINDOW_DO_NOT_FLUSH flag.
    */
   bool InDrawWindowNotFlushing() const
   { return mRenderFlags & STATE_DRAWWINDOW_NOT_FLUSHING; }
 
   /**
    * Set the isFirstPaint flag.
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5560,16 +5560,23 @@ float PresShell::GetCumulativeNonRootSca
       currentShell = parentCtx->PresShell();
     } else {
       currentShell = nullptr;
     }
   }
   return resolution;
 }
 
+void PresShell::SetRestoreResolution(float aResolution)
+{
+  if (mMobileViewportManager) {
+    mMobileViewportManager->SetRestoreResolution(aResolution);
+  }
+}
+
 void PresShell::SetRenderingState(const RenderingState& aState)
 {
   if (mRenderFlags != aState.mRenderFlags) {
     // Rendering state changed in a way that forces us to flush any
     // retained layers we might already have.
     LayerManager* manager = GetLayerManager();
     if (manager) {
       FrameLayerBuilder::InvalidateAllLayers(manager);
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -227,16 +227,17 @@ public:
     return SetResolutionImpl(aResolution, /* aScaleToResolution = */ false);
   }
   virtual nsresult SetResolutionAndScaleTo(float aResolution) override {
     return SetResolutionImpl(aResolution, /* aScaleToResolution = */ true);
   }
   virtual bool ScaleToResolution() const override;
   virtual float GetCumulativeResolution() override;
   virtual float GetCumulativeNonRootScaleResolution() override;
+  virtual void SetRestoreResolution(float aResolution) override;
 
   //nsIViewObserver interface
 
   virtual void Paint(nsView* aViewToPaint, const nsRegion& aDirtyRegion,
                      uint32_t aFlags) override;
   virtual nsresult HandleEvent(nsIFrame* aFrame,
                                mozilla::WidgetGUIEvent* aEvent,
                                bool aDontRetargetEvents,