Use a display port in browser.js. Disable zooming and CSS viewport adjustment for now.
authorPatrick Walton <pwalton@mozilla.com>
Tue, 07 Feb 2012 22:45:41 -0800
changeset 90901 dc9d927c6d5dee5dcd4d15e5a08c60f5e33213b3
parent 90900 8e9ea157c3f7f6c81d115f2ccc64ed9f512d0b10
child 90902 970269505811f115110ac5f72ab2039e22d5bca7
push idunknown
push userunknown
push dateunknown
milestone12.0a1
Use a display port in browser.js. Disable zooming and CSS viewport adjustment for now.
mobile/android/chrome/content/browser.js
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -100,16 +100,22 @@ const kElementsReceivingInput = {
     embed: true,
     input: true,
     map: true,
     select: true,
     textarea: true,
     video: true
 };
 
+// How many pixels on each side to buffer.
+const kBufferAmount = 300;
+
+// Whether we're using GL layers.
+const kUsingGLLayers = true;
+
 function dump(a) {
   Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
 }
 
 function getBridge() {
   return Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge);
 }
 
@@ -1387,16 +1393,18 @@ nsBrowserAccess.prototype = {
 
 let gTabIDFactory = 0;
 
 // track the last known screen size so that new tabs
 // get created with the right size rather than being 1x1
 let gScreenWidth = 1;
 let gScreenHeight = 1;
 
+let gBrowserWidth = null;
+
 function Tab(aURL, aParams) {
   this.browser = null;
   this.vbox = null;
   this.id = 0;
   this.showProgress = true;
   this.create(aURL, aParams);
   this._viewport = { x: 0, y: 0, width: gScreenWidth, height: gScreenHeight, offsetX: 0, offsetY: 0,
                      pageWidth: gScreenWidth, pageHeight: gScreenHeight, zoom: 1.0 };
@@ -1416,24 +1424,30 @@ Tab.prototype = {
 
     this.vbox = document.createElement("vbox");
     this.vbox.align = "start";
     BrowserApp.deck.appendChild(this.vbox);
 
     this.browser = document.createElement("browser");
     this.browser.setAttribute("type", "content");
     this.setBrowserSize(980, 480);
+    this.browser.style.width = gScreenWidth + "px";
+    this.browser.style.height = gScreenHeight + "px";
     this.browser.style.MozTransformOrigin = "0 0";
     this.vbox.appendChild(this.browser);
 
     this.browser.stop();
 
-    // Turn off clipping so we can buffer areas outside of the browser element.
     let frameLoader = this.browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
-    frameLoader.clipSubdocument = false;
+    if (kUsingGLLayers) {
+        frameLoader.renderMode = Ci.nsIFrameLoader.RENDER_MODE_ASYNC_SCROLL;
+    } else {
+        // Turn off clipping so we can buffer areas outside of the browser element.
+        frameLoader.clipSubdocument = false;
+    }
 
     this.id = ++gTabIDFactory;
 
     let message = {
       gecko: {
         type: "Tab:Added",
         tabID: this.id,
         uri: aURL,
@@ -1606,18 +1620,18 @@ Tab.prototype = {
   updateTransform: function() {
     let hasZoom = (Math.abs(this._viewport.zoom - 1.0) >= 1e-6);
     let x = this._viewport.offsetX + Math.round(-this.viewportExcess.x * this._viewport.zoom);
     let y = this._viewport.offsetY + Math.round(-this.viewportExcess.y * this._viewport.zoom);
 
     let transform =
       "translate(" + x + "px, " +
                      y + "px)";
-    if (hasZoom)
-      transform += " scale(" + this._viewport.zoom + ")";
+
+    // FIXME: Use nsIDOMWindowUtils::SetResolution(this._viewport.zoom * k) for some k here.
 
     this.browser.style.MozTransform = transform;
   },
 
   get viewport() {
     // Update the viewport to current dimensions
     this._viewport.x = (this.browser.contentWindow.scrollX +
                         this.viewportExcess.x) || 0;
@@ -1724,16 +1738,24 @@ Tab.prototype = {
             this.browser.removeEventListener("pagehide", listener, true);
           }.bind(this), true);
         }
 
         // Show a plugin doorhanger if there are no clickable overlays showing
         if (this._pluginsToPlay.length && !this._pluginOverlayShowing)
           PluginHelper.showDoorHanger(this);
 
+        // FIXME: This should not be in DOMContentLoaded; it should happen earlier.
+        let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                                            .getInterface(Ci.nsIDOMWindowUtils);
+        cwu.setDisplayPortForElement(-kBufferAmount, -kBufferAmount,
+                                     gScreenWidth + kBufferAmount * 2,
+                                     gScreenHeight + kBufferAmount * 2,
+                                     this.browser.contentDocument.documentElement);
+
         break;
       }
 
       case "DOMLinkAdded": {
         let target = aEvent.originalTarget;
         if (!target.href || target.disabled)
           return;
 
@@ -2044,57 +2066,56 @@ Tab.prototype = {
         viewportH = viewportW * (screenH / screenW);
     }
 
     // Make sure the viewport height is not shorter than the window when
     // the page is zoomed out to show its full width.
     let minScale = this.getPageZoomLevel(screenW);
     viewportH = Math.max(viewportH, screenH / minScale);
 
-    let oldBrowserWidth = parseInt(this.browser.style.width);
+    let oldBrowserWidth = gBrowserWidth;
     this.setBrowserSize(viewportW, viewportH);
 
     // Avoid having the scroll position jump around after device rotation.
     let win = this.browser.contentWindow;
     this.userScrollPos.x = win.scrollX;
     this.userScrollPos.y = win.scrollY;
 
     // If the browser width changes, we change the zoom proportionally. This ensures sensible
     // behavior when rotating the device on pages with automatically-resizing viewports.
 
-    if (viewportW == oldBrowserWidth)
+    if (oldBrowserWidth == null || viewportW == oldBrowserWidth)
       return;
 
     let viewport = this.viewport;
     let newZoom = oldBrowserWidth * viewport.zoom / viewportW;
     this.updateViewport(true, newZoom);
   },
 
   getDefaultZoomLevel: function getDefaultZoomLevel() {
     let md = this.metadata;
     if ("defaultZoom" in md && md.defaultZoom)
       return md.defaultZoom;
 
-    let browserWidth = parseInt(this.browser.style.width);
     dump("### getDefaultZoomLevel gScreenWidth=" + gScreenWidth);
-    return gScreenWidth / browserWidth;
+    return gScreenWidth / gBrowserWidth;
   },
 
   getPageZoomLevel: function getPageZoomLevel() {
     // This may get called during a Viewport:Change message while the document
     // has not loaded yet.
     if (!this.browser.contentDocument || !this.browser.contentDocument.body)
       return 1.0;
 
     return this._viewport.width / this.browser.contentDocument.body.clientWidth;
   },
 
   setBrowserSize: function(aWidth, aHeight) {
-    this.browser.style.width = aWidth + "px";
-    this.browser.style.height = aHeight + "px";
+    // TODO: Use nsIDOMWindowUtils::SetCSSViewport() here.
+    gBrowserWidth = aWidth;
   },
 
   getRequestLoadContext: function(aRequest) {
     if (aRequest && aRequest.notificationCallbacks) {
       try {
         return aRequest.notificationCallbacks.getInterface(Ci.nsILoadContext);
       } catch (ex) { }
     }