Bug 1001438 - Remove setCriticalDisplayPortForElement and have the getter function automatically compute it. r=tn
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 21 May 2014 12:06:02 -0400
changeset 184223 a43da969d38614f09489f381a8fba2a4c43662de
parent 184222 7833f01b65532cf1ea2aa75e44bada2a17bd36e3
child 184224 937f8aa9faed08a3dcb330f8ba54e0b6bf626a73
push id26814
push userryanvm@gmail.com
push dateWed, 21 May 2014 19:50:12 +0000
treeherdermozilla-central@7aee2fa0f655 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1001438
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1001438 - Remove setCriticalDisplayPortForElement and have the getter function automatically compute it. r=tn
content/base/src/nsGkAtomList.h
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/nsLayoutUtils.cpp
mobile/android/chrome/content/browser.js
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -2035,17 +2035,16 @@ GK_ATOM(IMETxnName, "IME")
 GK_ATOM(DeleteTxnName, "Deleting")
 
 // IPC stuff
 GK_ATOM(Remote, "remote")
 GK_ATOM(RemoteId, "_remote_id")
 GK_ATOM(DisplayPort, "_displayport")
 GK_ATOM(DisplayPortMargins, "_displayportmargins")
 GK_ATOM(DisplayPortBase, "_displayportbase")
-GK_ATOM(CriticalDisplayPort, "_critical_displayport")
 
 // Names for system metrics
 GK_ATOM(color_picker_available, "color-picker-available")
 GK_ATOM(scrollbar_start_backward, "scrollbar-start-backward")
 GK_ATOM(scrollbar_start_forward, "scrollbar-start-forward")
 GK_ATOM(scrollbar_end_backward, "scrollbar-end-backward")
 GK_ATOM(scrollbar_end_forward, "scrollbar-end-forward")
 GK_ATOM(scrollbar_thumb_proportional, "scrollbar-thumb-proportional")
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -479,64 +479,16 @@ nsDOMWindowUtils::SetDisplayPortBaseForE
   }
 
   nsLayoutUtils::SetDisplayPortBase(content, nsRect(aX, aY, aWidth, aHeight));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx,
-                                                   float aWidthPx, float aHeightPx,
-                                                   nsIDOMElement* aElement)
-{
-  if (!nsContentUtils::IsCallerChrome()) {
-    return NS_ERROR_DOM_SECURITY_ERR;
-  }
-
-  nsIPresShell* presShell = GetPresShell();
-  if (!presShell) {
-    return NS_ERROR_FAILURE;
-  }
-
-  if (!aElement) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
-
-  if (!content) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (content->GetCurrentDoc() != presShell->GetDocument()) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsRect displayport;
-  if (!nsLayoutUtils::GetDisplayPort(content, &displayport)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsRect criticalDisplayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
-                             nsPresContext::CSSPixelsToAppUnits(aYPx),
-                             nsPresContext::CSSPixelsToAppUnits(aWidthPx),
-                             nsPresContext::CSSPixelsToAppUnits(aHeightPx));
-  content->SetProperty(nsGkAtoms::CriticalDisplayPort, new nsRect(criticalDisplayport),
-                       nsINode::DeleteProperty<nsRect>);
-
-  nsIFrame* rootFrame = presShell->GetRootFrame();
-  if (rootFrame) {
-    rootFrame->InvalidateFrame();
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
 {
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsIPresShell* presShell = GetPresShell();
   if (!presShell) {
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -43,17 +43,17 @@ interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsICompositionStringSynthesizer;
 interface nsITranslationNodeList;
 
-[scriptable, uuid(a1d75ae1-d3fc-40cb-97d5-8c81846632f4)]
+[scriptable, uuid(8435ca79-517f-40ba-acd9-55201a2a119d)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -187,28 +187,16 @@ interface nsIDOMWindowUtils : nsISupport
 
   void setDisplayPortBaseForElement(in int32_t aX,
                                     in int32_t aY,
                                     in int32_t aWidth,
                                     in int32_t aHeight,
                                     in nsIDOMElement aElement);
 
   /**
-   * When a display port is set, this allows a sub-section of that
-   * display port to be marked as 'critical'. In this scenario, the
-   * area outside of this rectangle may be rendered at a lower
-   * detail (for example, by reducing its resolution), or not rendered
-   * at all under some circumstances.
-   * This call will have no effect if a display port has not been set.
-   */
-  void setCriticalDisplayPortForElement(in float aXPx, in float aYPx,
-                                        in float aWidthPx, in float aHeightPx,
-                                        in nsIDOMElement aElement);
-
-  /**
    * Get/set the resolution at which rescalable web content is drawn.
    * Currently this is only (some) thebes content.
    *
    * Setting a new resolution does *not* trigger reflow.  This API is
    * entirely separate from textZoom and fullZoom; a resolution scale
    * can be applied together with both textZoom and fullZoom.
    *
    * The effect of is API for gfx code to allocate more or fewer
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -666,23 +666,39 @@ nsLayoutUtils::FindScrollableFrameFor(Vi
   if (scrolledFrame && content->OwnerDoc()->GetRootElement() == content) {
     // The content is the root element of a subdocument, so return the root scrollable
     // for the subdocument.
     scrolledFrame = scrolledFrame->PresContext()->PresShell()->GetRootScrollFrame();
   }
   return scrolledFrame ? scrolledFrame->GetScrollTargetFrame() : nullptr;
 }
 
-bool
-nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
+static nsRect
+ApplyRectMultiplier(nsRect aRect, float aMultiplier)
+{
+  if (aMultiplier == 1.0f) {
+    return aRect;
+  }
+  float newWidth = aRect.width * aMultiplier;
+  float newHeight = aRect.height * aMultiplier;
+  float newX = aRect.x - ((newWidth - aRect.width) / 2.0f);
+  float newY = aRect.y - ((newHeight - aRect.height) / 2.0f);
+  // Rounding doesn't matter too much here, do a round-in
+  return nsRect(ceil(newX), ceil(newY), floor(newWidth), floor(newHeight));
+}
+
+static bool
+GetDisplayPortImpl(nsIContent* aContent, nsRect *aResult, float aMultiplier = 1.0f)
 {
   DisplayPortPropertyData* rectData =
     static_cast<DisplayPortPropertyData*>(aContent->GetProperty(nsGkAtoms::DisplayPort));
   DisplayPortMarginsPropertyData* marginsData =
     static_cast<DisplayPortMarginsPropertyData*>(aContent->GetProperty(nsGkAtoms::DisplayPortMargins));
+  nsRect* baseData =
+    static_cast<nsRect*>(aContent->GetProperty(nsGkAtoms::DisplayPortBase));
   if (!rectData && !marginsData) {
     return false;
   }
 
   if (!aResult) {
     // We have displayport data, but no need to compute it because the
     // caller doesn't want it
     return true;
@@ -692,45 +708,55 @@ nsLayoutUtils::GetDisplayPort(nsIContent
     // choose margins if equal priority
     if (rectData->mPriority > marginsData->mPriority) {
       marginsData = nullptr;
     } else {
       rectData = nullptr;
     }
   }
 
+  nsIFrame* frame = aContent->GetPrimaryFrame();
+  if (!frame) {
+    if (rectData) {
+      *aResult = rectData->mRect;
+    } else {
+      // Turns out we can't really compute it. Oops. We still should
+      // return true and set aResult to something sane.
+      NS_WARNING("Attempting to get a displayport from a content with no primary frame!");
+      if (baseData) {
+        *aResult = *baseData;
+      } else {
+        *aResult = nsRect();
+      }
+    }
+    *aResult = ApplyRectMultiplier(*aResult, aMultiplier);
+    return true;
+  }
+
+  bool isRoot = false;
+  if (aContent->OwnerDoc()->GetRootElement() == aContent) {
+    // We want the scroll frame, the root scroll frame differs from all
+    // others in that the primary frame is not the scroll frame.
+    frame = frame->PresContext()->PresShell()->GetRootScrollFrame();
+    isRoot = true;
+  }
+  nsIScrollableFrame* scrollableFrame = frame->GetScrollTargetFrame();
+  nsPoint scrollPos(scrollableFrame ? scrollableFrame->GetScrollPosition() : nsPoint(0,0));
+
+  nsRect result;
   if (rectData) {
     // We have it as a straight-up rect
-    *aResult = rectData->mRect;
+    result = rectData->mRect;
   } else {
     // We need to compute it from the margins + base rect
-    nsRect* baseData =
-      static_cast<nsRect*>(aContent->GetProperty(nsGkAtoms::DisplayPortBase));
     nsRect base;
     if (baseData) {
       base = *baseData;
     }
 
-    nsIFrame* frame = aContent->GetPrimaryFrame();
-    if (!frame) {
-      // Turns out we can't really compute it. Oops. We still should
-      // return true and set aResult to something sane.
-      NS_WARNING("Attempting to get a displayport from a content with no primary frame!");
-      *aResult = base;
-      return true;
-    }
-
-    bool isRoot = false;
-    if (aContent->OwnerDoc()->GetRootElement() == aContent) {
-      // We want the scroll frame, the root scroll frame differs from all
-      // others in that the primary frame is not the scroll frame.
-      frame = frame->PresContext()->PresShell()->GetRootScrollFrame();
-      isRoot = true;
-    }
-
     // first convert the base rect to layer pixels
     nsPresContext* presContext = frame->PresContext();
     int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
     gfxSize res = presContext->PresShell()->GetCumulativeResolution();
     gfxSize parentRes = res;
     if (isRoot) {
       // the base rect for root scroll frames is specified in the parent document
       // coordinate space, so it doesn't include the local resolution.
@@ -741,18 +767,16 @@ nsLayoutUtils::GetDisplayPort(nsIContent
     LayerRect rect;
     rect.x = parentRes.width * NSAppUnitsToFloatPixels(base.x, auPerDevPixel);
     rect.y = parentRes.height * NSAppUnitsToFloatPixels(base.y, auPerDevPixel);
     rect.width = parentRes.width * NSAppUnitsToFloatPixels(base.width, auPerDevPixel);
     rect.height = parentRes.height * NSAppUnitsToFloatPixels(base.height, auPerDevPixel);
 
     rect.Inflate(marginsData->mMargins);
 
-    nsIScrollableFrame* scrollableFrame = frame->GetScrollTargetFrame();
-    nsPoint scrollPos(scrollableFrame ? scrollableFrame->GetScrollPosition() : nsPoint(0,0));
     if (marginsData->mAlignmentX > 0 || marginsData->mAlignmentY > 0) {
       // Avoid division by zero.
       if (marginsData->mAlignmentX == 0) {
         marginsData->mAlignmentX = 1;
       }
       if (marginsData->mAlignmentY == 0) {
         marginsData->mAlignmentY = 1;
       }
@@ -771,31 +795,43 @@ nsLayoutUtils::GetDisplayPort(nsIContent
       float left = marginsData->mAlignmentX * floor(rect.x / marginsData->mAlignmentX);
       float top = marginsData->mAlignmentY * floor(rect.y / marginsData->mAlignmentY);
       float right = marginsData->mAlignmentX * ceil(rect.XMost() / marginsData->mAlignmentX);
       float bottom = marginsData->mAlignmentY * ceil(rect.YMost() / marginsData->mAlignmentY);
       rect = LayerRect(left, top, right - left, bottom - top);
       rect -= scrollPosLayer;
     }
 
-    nsRect result;
     result.x = NSFloatPixelsToAppUnits(rect.x / res.width, auPerDevPixel);
     result.y = NSFloatPixelsToAppUnits(rect.y / res.height, auPerDevPixel);
     result.width = NSFloatPixelsToAppUnits(rect.width / res.width, auPerDevPixel);
     result.height = NSFloatPixelsToAppUnits(rect.height / res.height, auPerDevPixel);
-
-    // Finally, clamp the display port to the expanded scrollable rect.
-    nsRect expandedScrollableRect = CalculateExpandedScrollableRect(frame);
+  }
+
+  result = ApplyRectMultiplier(result, aMultiplier);
+
+  if (marginsData) {
+    // Finally, if the displayport was set via margins, clamp it to the expanded scrollable rect.
+    nsRect expandedScrollableRect = nsLayoutUtils::CalculateExpandedScrollableRect(frame);
     result = expandedScrollableRect.Intersect(result + scrollPos) - scrollPos;
-
-    *aResult = result;
-  }
+  }
+
+  *aResult = result;
   return true;
 }
 
+bool
+nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
+{
+  if (gfxPrefs::UseLowPrecisionBuffer()) {
+    return GetDisplayPortImpl(aContent, aResult, 1.0f / gfxPrefs::LowPrecisionResolution());
+  }
+  return GetDisplayPortImpl(aContent, aResult);
+}
+
 void
 nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
                                      nsIPresShell* aPresShell,
                                      const LayerMargin& aMargins,
                                      uint32_t aAlignmentX,
                                      uint32_t aAlignmentY,
                                      uint32_t aPriority,
                                      RepaintMode aRepaintMode)
@@ -839,25 +875,20 @@ nsLayoutUtils::SetDisplayPortBaseIfNotSe
   if (!aContent->GetProperty(nsGkAtoms::DisplayPortBase)) {
     SetDisplayPortBase(aContent, aBase);
   }
 }
 
 bool
 nsLayoutUtils::GetCriticalDisplayPort(nsIContent* aContent, nsRect* aResult)
 {
-  void* property = aContent->GetProperty(nsGkAtoms::CriticalDisplayPort);
-  if (!property) {
-    return false;
-  }
-
-  if (aResult) {
-    *aResult = *static_cast<nsRect*>(property);
-  }
-  return true;
+  if (gfxPrefs::UseLowPrecisionBuffer()) {
+    return GetDisplayPortImpl(aContent, aResult);
+  }
+  return false;
 }
 
 nsIFrame*
 nsLayoutUtils::LastContinuationWithChild(nsIFrame* aFrame)
 {
   NS_PRECONDITION(aFrame, "NULL frame pointer");
   aFrame = aFrame->LastContinuation();
   while (!aFrame->GetFirstPrincipalChild() &&
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -431,19 +431,16 @@ var BrowserApp = {
     // Broadcast a UIReady message so add-ons know we are finished with startup
     let event = document.createEvent("Events");
     event.initEvent("UIReady", true, false);
     window.dispatchEvent(event);
 
     if (this._startupStatus)
       this.onAppUpdated();
 
-    // Store the low-precision buffer pref
-    this.gUseLowPrecision = Services.prefs.getBoolPref("layers.low-precision-buffer");
-
     // notify java that gecko has loaded
     sendMessageToJava({ type: "Gecko:Ready" });
 
 #ifdef MOZ_SAFE_BROWSING
     // Bug 778855 - Perf regression if we do this here. To be addressed in bug 779008.
     setTimeout(function() { SafeBrowsing.init(); }, 5000);
 #endif
   },
@@ -3288,42 +3285,19 @@ Tab.prototype = {
       height: (aDisplayPort.bottom - aDisplayPort.top) / resolution
     };
 
     if (this._oldDisplayPort == null ||
         !fuzzyEquals(displayPort.x, this._oldDisplayPort.x) ||
         !fuzzyEquals(displayPort.y, this._oldDisplayPort.y) ||
         !fuzzyEquals(displayPort.width, this._oldDisplayPort.width) ||
         !fuzzyEquals(displayPort.height, this._oldDisplayPort.height)) {
-      if (BrowserApp.gUseLowPrecision) {
-        // Set the display-port to be 4x the size of the critical display-port,
-        // on each dimension, giving us a 0.25x lower precision buffer around the
-        // critical display-port. Spare area is *not* redistributed to the other
-        // axis, as display-list building and invalidation cost scales with the
-        // size of the display-port.
-        let pageRect = cwu.getRootBounds();
-        let pageXMost = pageRect.right - geckoScrollX;
-        let pageYMost = pageRect.bottom - geckoScrollY;
-
-        let dpW = Math.min(pageRect.right - pageRect.left, displayPort.width * 4);
-        let dpH = Math.min(pageRect.bottom - pageRect.top, displayPort.height * 4);
-
-        let dpX = Math.min(Math.max(displayPort.x - displayPort.width * 1.5,
-                                    pageRect.left - geckoScrollX), pageXMost - dpW);
-        let dpY = Math.min(Math.max(displayPort.y - displayPort.height * 1.5,
-                                    pageRect.top - geckoScrollY), pageYMost - dpH);
-        cwu.setDisplayPortForElement(dpX, dpY, dpW, dpH, element, 0);
-        cwu.setCriticalDisplayPortForElement(displayPort.x, displayPort.y,
-                                             displayPort.width, displayPort.height,
-                                             element);
-      } else {
-        cwu.setDisplayPortForElement(displayPort.x, displayPort.y,
-                                     displayPort.width, displayPort.height,
-                                     element, 0);
-      }
+      cwu.setDisplayPortForElement(displayPort.x, displayPort.y,
+                                   displayPort.width, displayPort.height,
+                                   element, 0);
     }
 
     this._oldDisplayPort = displayPort;
   },
 
   /*
    * Yes, this is ugly. But it's currently the safest way to account for the rounding errors that occur
    * when we pump the displayport coordinates through gecko and they pop out in the compositor.