Bug 729528 - Add a DisplayPortMetrics to track the requested display resolution along with the area. r=Cwiiis
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 26 Mar 2012 13:15:49 -0400
changeset 90324 3e5eee67741ff61d1a18d922bdd5bc2fa26b7aa4
parent 90323 263150bd32bbd4e3696f246c717023b3ef52d675
child 90325 56aab2bfad06c5cbcbf0a60d11bf67d62a163376
push id22349
push usermak77@bonardo.net
push dateTue, 27 Mar 2012 11:57:36 +0000
treeherdermozilla-central@0ff816e5e992 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersCwiiis
bugs729528
milestone14.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 729528 - Add a DisplayPortMetrics to track the requested display resolution along with the area. r=Cwiiis
mobile/android/base/GeckoEvent.java
mobile/android/base/Makefile.in
mobile/android/base/gfx/DisplayPortMetrics.java
mobile/android/base/gfx/GeckoLayerClient.java
mobile/android/base/gfx/LayerController.java
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -32,18 +32,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 package org.mozilla.gecko;
 
+import org.mozilla.gecko.gfx.DisplayPortMetrics;
 import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.RectUtils;
 import org.mozilla.gecko.gfx.ViewportMetrics;
 import android.os.*;
 import android.app.*;
 import android.view.*;
 import android.content.*;
 import android.graphics.*;
 import android.widget.*;
 import android.hardware.*;
@@ -413,25 +413,25 @@ public class GeckoEvent {
 
     public static GeckoEvent createBroadcastEvent(String subject, String data) {
         GeckoEvent event = new GeckoEvent(BROADCAST);
         event.mCharacters = subject;
         event.mCharactersExtra = data;
         return event;
     }
 
-    public static GeckoEvent createViewportEvent(ViewportMetrics viewport, RectF displayPort) {
+    public static GeckoEvent createViewportEvent(ViewportMetrics viewport, DisplayPortMetrics displayPort) {
         GeckoEvent event = new GeckoEvent(VIEWPORT);
         event.mCharacters = "Viewport:Change";
         PointF origin = viewport.getOrigin();
         StringBuffer sb = new StringBuffer(256);
         sb.append("{ \"x\" : ").append(origin.x)
           .append(", \"y\" : ").append(origin.y)
           .append(", \"zoom\" : ").append(viewport.getZoomFactor())
-          .append(", \"displayPort\" :").append(RectUtils.toJSON(displayPort))
+          .append(", \"displayPort\" :").append(displayPort.toJSON())
           .append('}');
         event.mCharactersExtra = sb.toString();
         return event;
     }
 
     public static GeckoEvent createLoadEvent(String uri) {
         GeckoEvent event = new GeckoEvent(LOAD_URI);
         event.mCharacters = uri;
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -115,16 +115,17 @@ FENNEC_JAVA_FILES = \
   TabsTray.java \
   TabsAccessor.java \
   gfx/BitmapUtils.java \
   gfx/BufferedCairoImage.java \
   gfx/CairoGLInfo.java \
   gfx/CairoImage.java \
   gfx/CairoUtils.java \
   gfx/CheckerboardImage.java \
+  gfx/DisplayPortMetrics.java \
   gfx/FlexibleGLSurfaceView.java \
   gfx/FloatSize.java \
   gfx/GeckoLayerClient.java \
   gfx/GLController.java \
   gfx/GLThread.java \
   gfx/ImmutableViewportMetrics.java \
   gfx/InputConnectionHandler.java \
   gfx/IntSize.java \
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/gfx/DisplayPortMetrics.java
@@ -0,0 +1,51 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.gfx;
+
+import android.graphics.RectF;
+
+/*
+ * This class keeps track of the area we request Gecko to paint, as well
+ * as the resolution of the paint. The area may be different from the visible
+ * area of the page, and the resolution may be different from the resolution
+ * used in the compositor to render the page. This is so that we can ask Gecko
+ * to paint a much larger area without using extra memory, and then render some
+ * subsection of that with compositor scaling.
+ */
+public final class DisplayPortMetrics {
+    private final RectF mPosition;
+    private final float mResolution;
+
+    public DisplayPortMetrics() {
+        this(0, 0, 0, 0, 1);
+    }
+
+    public DisplayPortMetrics(float left, float top, float right, float bottom, float resolution) {
+        mPosition = new RectF(left, top, right, bottom);
+        mResolution = resolution;
+    }
+
+    public boolean contains(RectF rect) {
+        return mPosition.contains(rect);
+    }
+
+    public String toJSON() {
+        StringBuffer sb = new StringBuffer(256);
+        sb.append("{ \"left\": ").append(mPosition.left)
+          .append(", \"top\": ").append(mPosition.top)
+          .append(", \"right\": ").append(mPosition.right)
+          .append(", \"bottom\": ").append(mPosition.bottom)
+          .append(", \"resolution\": ").append(mResolution)
+          .append('}');
+        return sb.toString();
+    }
+
+    public String toString() {
+        return "DisplayPortMetrics(" + mPosition.left + ","
+                + mPosition.top + "," + mPosition.right + ","
+                + mPosition.bottom + "," + mResolution + ")";
+    }
+}
--- a/mobile/android/base/gfx/GeckoLayerClient.java
+++ b/mobile/android/base/gfx/GeckoLayerClient.java
@@ -63,18 +63,18 @@ public class GeckoLayerClient implements
     private static final int DEFAULT_DISPLAY_PORT_MARGIN = 300;
 
     private LayerController mLayerController;
     private LayerRenderer mLayerRenderer;
     private boolean mLayerRendererInitialized;
 
     private IntSize mScreenSize;
     private IntSize mWindowSize;
-    private RectF mDisplayPort;
-    private RectF mReturnDisplayPort;
+    private DisplayPortMetrics mDisplayPort;
+    private DisplayPortMetrics mReturnDisplayPort;
 
     private VirtualLayer mRootLayer;
 
     /* The Gecko viewport as per the UI thread. Must be touched only on the UI thread. */
     private ViewportMetrics mGeckoViewport;
 
     /*
      * The viewport metrics being used to draw the current frame. This is only
@@ -90,17 +90,17 @@ public class GeckoLayerClient implements
     /* Used as a temporary ViewTransform by syncViewportInfo */
     private ViewTransform mCurrentViewTransform;
 
     public GeckoLayerClient(Context context) {
         // we can fill these in with dummy values because they are always written
         // to before being read
         mScreenSize = new IntSize(0, 0);
         mWindowSize = new IntSize(0, 0);
-        mDisplayPort = new RectF();
+        mDisplayPort = new DisplayPortMetrics();
         mCurrentViewTransform = new ViewTransform(0, 0, 1);
     }
 
     /** Attaches the root layer to the layer controller so that Gecko appears. */
     void setLayerController(LayerController layerController) {
         LayerView view = layerController.getView();
 
         mLayerController = layerController;
@@ -115,17 +115,17 @@ public class GeckoLayerClient implements
 
         view.setListener(this);
         view.setLayerRenderer(mLayerRenderer);
         layerController.setRoot(mRootLayer);
 
         sendResizeEventIfNecessary(true);
     }
 
-    RectF getDisplayPort() {
+    DisplayPortMetrics getDisplayPort() {
         return mDisplayPort;
     }
 
     /* Informs Gecko that the screen size has changed. */
     private void sendResizeEventIfNecessary(boolean force) {
         DisplayMetrics metrics = new DisplayMetrics();
         GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
         View view = mLayerController.getView();
@@ -166,17 +166,17 @@ public class GeckoLayerClient implements
         // us of the new viewport.
         sendResizeEventIfNecessary(true);
         // the following call also sends gecko a message, which will be processed after the resize
         // message above has updated the viewport. this message ensures that if we have just put
         // focus in a text field, we scroll the content so that the text field is in view.
         GeckoAppShell.viewSizeChanged();
     }
 
-    private static RectF calculateDisplayPort(ImmutableViewportMetrics metrics) {
+    private static DisplayPortMetrics calculateDisplayPort(ImmutableViewportMetrics metrics) {
         float desiredXMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
         float desiredYMargins = 2 * DEFAULT_DISPLAY_PORT_MARGIN;
 
         // we need to avoid having a display port that is larger than the page, or we will end up
         // painting things outside the page bounds (bug 729169). we simultaneously need to make
         // the display port as large as possible so that we redraw less.
 
         // figure out how much of the desired buffer amount we can actually use on the horizontal axis
@@ -221,20 +221,21 @@ public class GeckoLayerClient implements
             topMargin += delta / 2;
             bottomMargin += delta / 2;
         }
 
         // note that unless the viewport size changes, or the page dimensions change (either because of
         // content changes or zooming), the size of the display port should remain constant. this
         // is intentional to avoid re-creating textures and all sorts of other reallocations in the
         // draw and composition code.
-        return new RectF(metrics.viewportRectLeft - leftMargin,
-                         metrics.viewportRectTop - topMargin,
-                         metrics.viewportRectRight + rightMargin,
-                         metrics.viewportRectBottom + bottomMargin);
+        return new DisplayPortMetrics(metrics.viewportRectLeft - leftMargin,
+                metrics.viewportRectTop - topMargin,
+                metrics.viewportRectRight + rightMargin,
+                metrics.viewportRectBottom + bottomMargin,
+                metrics.zoomFactor);
     }
 
     private void adjustViewport() {
         ViewportMetrics viewportMetrics =
             new ViewportMetrics(mLayerController.getViewportMetrics());
 
         viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
 
@@ -315,17 +316,17 @@ public class GeckoLayerClient implements
         // display port we calculated. Different messages will generate different
         // display ports and put them in mReturnDisplayPort, so we just return that.
         // Note that mReturnDisplayPort is always touched on the Gecko thread, so
         // no synchronization is needed for it.
         if (mReturnDisplayPort == null) {
             return "";
         }
         try {
-            return RectUtils.toJSON(mReturnDisplayPort);
+            return mReturnDisplayPort.toJSON();
         } finally {
             mReturnDisplayPort = null;
         }
     }
 
     void geometryChanged() {
         /* Let Gecko know if the screensize has changed */
         sendResizeEventIfNecessary(false);
--- a/mobile/android/base/gfx/LayerController.java
+++ b/mobile/android/base/gfx/LayerController.java
@@ -340,17 +340,17 @@ public class LayerController implements 
         // close to checkerboarding.
         FloatSize pageSize = getPageSize();
         RectF adjustedViewport = RectUtils.expand(getViewport(), DANGER_ZONE_X, DANGER_ZONE_Y);
         if (adjustedViewport.top < 0) adjustedViewport.top = 0;
         if (adjustedViewport.left < 0) adjustedViewport.left = 0;
         if (adjustedViewport.right > pageSize.width) adjustedViewport.right = pageSize.width;
         if (adjustedViewport.bottom > pageSize.height) adjustedViewport.bottom = pageSize.height;
 
-        RectF displayPort = (mLayerClient == null ? new RectF() : mLayerClient.getDisplayPort());
+        DisplayPortMetrics displayPort = (mLayerClient == null ? new DisplayPortMetrics() : mLayerClient.getDisplayPort());
         return !displayPort.contains(adjustedViewport);
     }
 
     /**
      * Converts a point from layer view coordinates to layer coordinates. In other words, given a
      * point measured in pixels from the top left corner of the layer view, returns the point in
      * pixels measured from the last scroll position we sent to Gecko, in CSS pixels. Assuming the
      * events being sent to Gecko are processed in FIFO order, this calculation should always be
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1600,30 +1600,30 @@ Tab.prototype = {
       this.browser.docShellIsActive = false;
     }
   },
 
   getActive: function getActive() {
       return this.browser.docShellIsActive;
   },
 
-  setDisplayPort: function(aViewportX, aViewportY, aDisplayPortRect) {
+  setDisplayPort: function(aViewportX, aViewportY, aDisplayPort) {
     let zoom = this._zoom;
     if (zoom <= 0)
       return;
 
     let element = this.browser.contentDocument.documentElement;
     if (!element)
       return;
 
     let cwu = window.top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-    cwu.setDisplayPortForElement((aDisplayPortRect.left - aViewportX) / zoom,
-                                 (aDisplayPortRect.top - aViewportY) / zoom,
-                                 (aDisplayPortRect.right - aDisplayPortRect.left) / zoom,
-                                 (aDisplayPortRect.bottom - aDisplayPortRect.top) / zoom,
+    cwu.setDisplayPortForElement((aDisplayPort.left - aViewportX) / zoom,
+                                 (aDisplayPort.top - aViewportY) / zoom,
+                                 (aDisplayPort.right - aDisplayPort.left) / zoom,
+                                 (aDisplayPort.bottom - aDisplayPort.top) / zoom,
                                  element);
   },
 
   setViewport: function(aViewport) {
     // Transform coordinates based on zoom
     let x = aViewport.x / aViewport.zoom;
     let y = aViewport.y / aViewport.zoom;