Backout 8b3b879bc63f (Bug 777463), 32cc8084d1b7 (Bug 775451), ce9014442e13:4d52cfac7c37 (Bug 779572), b33f2b2dbbc5:963aed158547 (Bug 775463), 36832ad5ea65 (Bug 780210), 10695750e4e9:a2afc5b5e538 (Bug 775448), c9f42eebd694 (Bug 775447) for Linux bustage
authorPhil Ringnalda <philringnalda@gmail.com>
Tue, 07 Aug 2012 20:40:48 -0700
changeset 101760 d8878c0bd67cbb203a41b0574516bdd64bad71fc
parent 101759 8b3b879bc63fd0e2f2ef058817dbee23398f8d77
child 101761 67ea1314c77705b25fa0e813665de42c5945747b
push id13160
push userphilringnalda@gmail.com
push dateWed, 08 Aug 2012 03:41:40 +0000
treeherdermozilla-inbound@d8878c0bd67c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs777463, 775451, 779572, 775463, 780210, 775448, 775447
milestone17.0a1
backs out8b3b879bc63fd0e2f2ef058817dbee23398f8d77
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
Backout 8b3b879bc63f (Bug 777463), 32cc8084d1b7 (Bug 775451), ce9014442e13:4d52cfac7c37 (Bug 779572), b33f2b2dbbc5:963aed158547 (Bug 775463), 36832ad5ea65 (Bug 780210), 10695750e4e9:a2afc5b5e538 (Bug 775448), c9f42eebd694 (Bug 775447) for Linux bustage
dom/browser-element/BrowserElementScrolling.js
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
gfx/layers/ipc/AsyncPanZoomController.cpp
gfx/layers/ipc/AsyncPanZoomController.h
gfx/layers/ipc/GeckoContentController.h
gfx/layers/ipc/GestureEventListener.cpp
gfx/layers/ipc/GestureEventListener.h
ipc/glue/IPCMessageUtils.h
layout/ipc/PRenderFrame.ipdl
layout/ipc/RenderFrameChild.cpp
layout/ipc/RenderFrameChild.h
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
--- a/dom/browser-element/BrowserElementScrolling.js
+++ b/dom/browser-element/BrowserElementScrolling.js
@@ -4,17 +4,16 @@
 
 const ContentPanning = {
   init: function cp_init() {
     ['mousedown', 'mouseup', 'mousemove'].forEach(function(type) {
       addEventListener(type, ContentPanning, true);
     });
 
     addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
-    addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
   },
 
   handleEvent: function cp_handleEvent(evt) {
     switch (evt.type) {
       case 'mousedown':
         this.onTouchStart(evt);
         break;
       case 'mousemove':
@@ -39,26 +38,16 @@ const ContentPanning = {
 
   onTouchStart: function cp_onTouchStart(evt) {
     this.dragging = true;
     this.panning = false;
 
     let oldTarget = this.target;
     [this.target, this.scrollCallback] = this.getPannable(evt.target);
 
-    // If we found a target, that means we have found a scrollable subframe. In
-    // this case, and if we are using async panning and zooming on the parent
-    // frame, inform the pan/zoom controller that it should not attempt to
-    // handle any touch events it gets until the next batch (meaning the next
-    // time we get a touch end).
-    if (this.target != null && ContentPanning._asyncPanZoomForViewportFrame) {
-      var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-      os.notifyObservers(docShell, 'cancel-default-pan-zoom', null);
-    }
-
     // If there is a pan animation running (from a previous pan gesture) and
     // the user touch back the screen, stop this animation immediatly and
     // prevent the possible click action if the touch happens on the same
     // target.
     this.preventNextClick = false;
     if (KineticPanning.active) {
       KineticPanning.stop();
 
@@ -192,158 +181,42 @@ const ContentPanning = {
     this._domUtils.setContentState(root.documentElement, kStateActive);
   },
 
   get _asyncPanZoomForViewportFrame() {
     return docShell.asyncPanZoomEnabled;
   },
 
   _recvViewportChange: function(data) {
-    let metrics = data.json;
-    let displayPort = metrics.displayPort;
-
-    let screenWidth = metrics.screenSize.width;
-    let screenHeight = metrics.screenSize.height;
-
-    let x = metrics.x;
-    let y = metrics.y;
+    let viewport = data.json;
+    let displayPort = viewport.displayPort;
 
-    this._zoom = metrics.zoom;
-    this._viewport = new Rect(x, y,
-                              screenWidth / metrics.zoom,
-                              screenHeight / metrics.zoom);
-    this._cssPageRect = new Rect(metrics.cssPageRect.x,
-                                 metrics.cssPageRect.y,
-                                 metrics.cssPageRect.width,
-                                 metrics.cssPageRect.height);
+    let screenWidth = viewport.screenSize.width;
+    let screenHeight = viewport.screenSize.height;
+
+    let x = viewport.x;
+    let y = viewport.y;
 
     let cwu = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-    if (this._screenWidth != screenWidth || this._screenHeight != screenHeight) {
-      cwu.setCSSViewport(screenWidth, screenHeight);
-      this._screenWidth = screenWidth;
-      this._screenHeight = screenHeight;
-    }
+    cwu.setCSSViewport(screenWidth, screenHeight);
 
     // Set scroll position
     cwu.setScrollPositionClampingScrollPortSize(
-      screenWidth / metrics.zoom, screenHeight / metrics.zoom);
+      screenWidth / viewport.zoom, screenHeight / viewport.zoom);
     content.scrollTo(x, y);
     cwu.setResolution(displayPort.resolution, displayPort.resolution);
 
     let element = null;
     if (content.document && (element = content.document.documentElement)) {
       cwu.setDisplayPortForElement(displayPort.left,
                                    displayPort.top,
                                    displayPort.width,
                                    displayPort.height,
                                    element);
     }
-  },
-
-  _recvDoubleTap: function(data) {
-    let data = data.json;
-
-    // We haven't received a metrics update yet; don't do anything.
-    if (this._viewport == null) {
-      return;
-    }
-
-    let win = content;
-
-    let zoom = this._zoom;
-    let element = ElementTouchHelper.anyElementFromPoint(win, data.x, data.y);
-    if (!element) {
-      this._zoomOut();
-      return;
-    }
-
-    while (element && !this._shouldZoomToElement(element))
-      element = element.parentNode;
-
-    if (!element) {
-      this._zoomOut();
-    } else {
-      const margin = 15;
-      let rect = ElementTouchHelper.getBoundingContentRect(element);
-
-      let cssPageRect = this._cssPageRect;
-      let viewport = this._viewport;
-      let bRect = new Rect(Math.max(cssPageRect.left, rect.x - margin),
-                           rect.y,
-                           rect.w + 2 * margin,
-                           rect.h);
-      // constrict the rect to the screen's right edge
-      bRect.width = Math.min(bRect.width, cssPageRect.right - bRect.x);
-
-      // if the rect is already taking up most of the visible area and is stretching the
-      // width of the page, then we want to zoom out instead.
-      if (this._isRectZoomedIn(bRect, viewport)) {
-        this._zoomOut();
-        return;
-      }
-
-      rect.x = Math.round(bRect.x);
-      rect.y = Math.round(bRect.y);
-      rect.w = Math.round(bRect.width);
-      rect.h = Math.round(Math.min(bRect.width * viewport.height / viewport.height, bRect.height));
-
-      // if the block we're zooming to is really tall, and the user double-tapped
-      // more than a screenful of height from the top of it, then adjust the y-coordinate
-      // so that we center the actual point the user double-tapped upon. this prevents
-      // flying to the top of a page when double-tapping to zoom in (bug 761721).
-      // the 1.2 multiplier is just a little fuzz to compensate for bRect including horizontal
-      // margins but not vertical ones.
-      let cssTapY = viewport.y + data.y;
-      if ((bRect.height > rect.h) && (cssTapY > rect.y + (rect.h * 1.2))) {
-        rect.y = cssTapY - (rect.h / 2);
-      }
-
-      var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-      os.notifyObservers(docShell, 'browser-zoom-to-rect', JSON.stringify(rect));
-    }
-  },
-
-  _shouldZoomToElement: function(aElement) {
-    let win = aElement.ownerDocument.defaultView;
-    if (win.getComputedStyle(aElement, null).display == "inline")
-      return false;
-    if (aElement instanceof Ci.nsIDOMHTMLLIElement)
-      return false;
-    if (aElement instanceof Ci.nsIDOMHTMLQuoteElement)
-      return false;
-    return true;
-  },
-
-  _zoomOut: function() {
-    let rect = new Rect(0, 0, 0, 0);
-    var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-    os.notifyObservers(docShell, 'browser-zoom-to-rect', JSON.stringify(rect));
-  },
-
-  _isRectZoomedIn: function(aRect, aViewport) {
-    // This function checks to see if the area of the rect visible in the
-    // viewport (i.e. the "overlapArea" variable below) is approximately
-    // the max area of the rect we can show. It also checks that the rect
-    // is actually on-screen by testing the left and right edges of the rect.
-    // In effect, this tells us whether or not zooming in to this rect
-    // will significantly change what the user is seeing.
-    const minDifference = -20;
-    const maxDifference = 20;
-
-    let vRect = new Rect(aViewport.x, aViewport.y, aViewport.width, aViewport.height);
-    let overlap = vRect.intersect(aRect);
-    let overlapArea = overlap.width * overlap.height;
-    let availHeight = Math.min(aRect.width * vRect.height / vRect.width, aRect.height);
-    let showing = overlapArea / (aRect.width * availHeight);
-    let dw = (aRect.width - vRect.width);
-    let dx = (aRect.x - vRect.x);
-
-    return (showing > 0.9 &&
-            dx > minDifference && dx < maxDifference &&
-            dw > minDifference && dw < maxDifference);
   }
 };
 
 ContentPanning.init();
 
 // Min/max velocity of kinetic panning. This is in pixels/millisecond.
 const kMinVelocity = 0.4;
 const kMaxVelocity = 6;
@@ -507,57 +380,8 @@ const KineticPanning = {
       }
 
       content.mozRequestAnimationFrame(callback);
     }).bind(this);
 
     content.mozRequestAnimationFrame(callback);
   }
 };
-
-const ElementTouchHelper = {
-  anyElementFromPoint: function(aWindow, aX, aY) {
-    let cwu = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-    let elem = cwu.elementFromPoint(aX, aY, true, true);
-
-    let HTMLIFrameElement = Ci.nsIDOMHTMLIFrameElement;
-    let HTMLFrameElement = Ci.nsIDOMHTMLFrameElement;
-    while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
-      let rect = elem.getBoundingClientRect();
-      aX -= rect.left;
-      aY -= rect.top;
-      cwu = elem.contentDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-      elem = cwu.elementFromPoint(aX, aY, true, true);
-    }
-
-    return elem;
-  },
-
-  getBoundingContentRect: function(aElement) {
-    if (!aElement)
-      return {x: 0, y: 0, w: 0, h: 0};
-
-    let document = aElement.ownerDocument;
-    while (document.defaultView.frameElement)
-      document = document.defaultView.frameElement.ownerDocument;
-
-    let cwu = document.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-    let scrollX = {}, scrollY = {};
-    cwu.getScrollXY(false, scrollX, scrollY);
-
-    let r = aElement.getBoundingClientRect();
-
-    // step out of iframes and frames, offsetting scroll values
-    for (let frame = aElement.ownerDocument.defaultView; frame.frameElement && frame != content; frame = frame.parent) {
-      // adjust client coordinates' origin to be top left of iframe viewport
-      let rect = frame.frameElement.getBoundingClientRect();
-      let left = frame.getComputedStyle(frame.frameElement, "").borderLeftWidth;
-      let top = frame.getComputedStyle(frame.frameElement, "").borderTopWidth;
-      scrollX.value += rect.left + parseInt(left);
-      scrollY.value += rect.top + parseInt(top);
-    }
-
-    return {x: r.left + scrollX.value,
-            y: r.top + scrollY.value,
-            w: r.width,
-            h: r.height };
-  }
-};
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -10,31 +10,26 @@ include protocol PContent;
 include protocol PContentDialog;
 include protocol PDocumentRenderer;
 include protocol PContentPermissionRequest;
 include protocol PRenderFrame;
 include protocol POfflineCacheUpdate;
 include protocol PIndexedDB;
 
 include "gfxMatrix.h";
-include "gfxRect.h";
-include "gfxipc/ShadowLayerUtils.h";
-include "FrameMetrics.h";
 include "IPC/nsGUIEventIPC.h";
 include "mozilla/dom/TabMessageUtils.h";
 include "mozilla/layout/RenderFrameUtils.h";
 include "mozilla/net/NeckoMessageUtils.h";
 
 include DOMTypes;
 
 using IPC::URI;
 using gfxMatrix;
-using gfxRect;
 using gfxSize;
-using mozilla::layers::FrameMetrics;
 using mozilla::layers::LayersBackend;
 using mozilla::layout::ScrollingBehavior;
 using mozilla::WindowsHandle;
 using nscolor;
 using nsCompositionEvent;
 using nsIMEUpdatePreference;
 using nsIntPoint;
 using nsIntRect;
@@ -232,24 +227,16 @@ parent:
      * the window.open.
      *
      * @param opener the PBrowser whose content called window.open.
      */
     sync BrowserFrameOpenWindow(PBrowser opener, nsString aURL,
                                 nsString aName, nsString aFeatures)
       returns (bool windowOpened);
 
-    NotifyDOMTouchListenerAdded();
-
-    /**
-     * Instructs the TabParent to forward a request to zoom to a rect given in
-     * CSS pixels. This rect is relative to the document.
-     */
-    ZoomToRect(gfxRect aRect);
-
     __delete__();
 
 child:
     /**
      * Notify the remote browser that it has been Show()n on this
      * side, with the given |visibleRect|.  This message is expected
      * to trigger creation of the remote browser's "widget".
      *
@@ -258,24 +245,20 @@ child:
      * point.
      */
     Show(nsIntSize size);
 
     LoadURL(nsCString uri);
 
     UpdateDimensions(nsRect rect, nsIntSize size);
 
-    UpdateFrame(FrameMetrics frame);
-
-    /**
-     * Requests handling of a double tap. |point| is in CSS pixels, relative to
-     * the scroll offset. This message is expected to round-trip back to
-     * ZoomToRect() with a rect indicating where we should zoom to.
-     */
-    HandleDoubleTap(nsIntPoint point);
+    UpdateFrame(nsIntRect displayPort,
+                nsIntPoint scrollOffset,
+                gfxSize resolution,
+                nsIntRect screenSize);
 
     /**
      * Sending an activate message moves focus to the child.
      */
     Activate();
 
     Deactivate();
 
@@ -354,9 +337,9 @@ state LIVE:
 state DYING:
     discard send blah;
 // etc.
     recv __delete__;
  */
 };
 
 }
-}
+}
\ No newline at end of file
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -15,17 +15,16 @@
 #include "mozilla/IntentionalCrash.h"
 #include "mozilla/docshell/OfflineCacheUpdateChild.h"
 #include "mozilla/dom/PContentChild.h"
 #include "mozilla/dom/PContentDialogChild.h"
 #include "mozilla/ipc/DocumentRendererChild.h"
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/PLayersChild.h"
 #include "mozilla/layout/RenderFrameChild.h"
-#include "mozilla/unused.h"
 #include "nsComponentManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsEmbedCID.h"
 #include "nsEventListenerManager.h"
 #include "nsIBaseWindow.h"
 #include "nsIComponentManager.h"
 #include "nsIDOMClassInfo.h"
@@ -103,80 +102,30 @@ TabChild::TabChild(PRUint32 aChromeFlags
   , mDidFakeShow(false)
   , mIsBrowserElement(aIsBrowserElement)
   , mAppId(aAppId)
 {
     printf("creating %d!\n", NS_IsMainThread());
 }
 
 nsresult
-TabChild::Observe(nsISupports *aSubject,
-                  const char *aTopic,
-                  const PRUnichar *aData)
-{
-  if (!strcmp(aTopic, "dom-touch-listener-added")) {
-    nsCOMPtr<nsIDOMWindow> subject(do_QueryInterface(aSubject));
-    nsCOMPtr<nsIDOMWindow> win(do_GetInterface(mWebNav));
-    nsCOMPtr<nsIDOMWindow> topSubject;
-    subject->GetTop(getter_AddRefs(topSubject));
-    if (win == topSubject) {
-      SendNotifyDOMTouchListenerAdded();
-    }
-  } else if (!strcmp(aTopic, "cancel-default-pan-zoom")) {
-    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
-    nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
-    if (tabChild == this) {
-      mRemoteFrame->CancelDefaultPanZoom();
-    }
-  } else if (!strcmp(aTopic, "browser-zoom-to-rect")) {
-    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject));
-    nsCOMPtr<nsITabChild> tabChild(GetTabChildFrom(docShell));
-    if (tabChild == this) {
-      gfxRect rect;
-      sscanf(NS_ConvertUTF16toUTF8(aData).get(),
-             "{\"x\":%lf,\"y\":%lf,\"w\":%lf,\"h\":%lf}",
-             &rect.x, &rect.y, &rect.width, &rect.height);
-      SendZoomToRect(rect);
-    }
-  }
-
-  return NS_OK;
-}
-
-nsresult
 TabChild::Init()
 {
   nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
   if (!webBrowser) {
     NS_ERROR("Couldn't create a nsWebBrowser?");
     return NS_ERROR_FAILURE;
   }
 
   webBrowser->SetContainerWindow(this);
   mWebNav = do_QueryInterface(webBrowser);
   NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
 
   nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
   docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
-
-  nsCOMPtr<nsIObserverService> observerService =
-    do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
-
-  if (observerService) {
-    observerService->AddObserver(this,
-                                 "dom-touch-listener-added",
-                                 false);
-    observerService->AddObserver(this,
-                                 "cancel-default-pan-zoom",
-                                 false);
-    observerService->AddObserver(this,
-                                 "browser-zoom-to-rect",
-                                 false);
-  }
-
   return NS_OK;
 }
 
 NS_INTERFACE_MAP_BEGIN(TabChild)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
@@ -690,93 +639,65 @@ TabChild::RecvUpdateDimensions(const nsR
 
     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mWebNav);
     baseWin->SetPositionAndSize(0, 0, size.width, size.height,
                                 true);
 
     return true;
 }
 
-void
-TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
-                                        const nsACString& aJSONData)
+bool
+TabChild::RecvUpdateFrame(const nsIntRect& aDisplayPort,
+                          const nsIntPoint& aScrollOffset,
+                          const gfxSize& aResolution,
+                          const nsIntRect& aScreenSize)
 {
+    if (!mCx || !mTabChildGlobal) {
+        return true;
+    }
+    nsCString data;
+    data += nsPrintfCString("{ \"x\" : %d", aScrollOffset.x);
+    data += nsPrintfCString(", \"y\" : %d", aScrollOffset.y);
+    // We don't treat the x and y scales any differently for this
+    // semi-platform-specific code.
+    data += nsPrintfCString(", \"zoom\" : %f", aResolution.width);
+    data += nsPrintfCString(", \"displayPort\" : ");
+        data += nsPrintfCString("{ \"left\" : %d", aDisplayPort.X());
+        data += nsPrintfCString(", \"top\" : %d", aDisplayPort.Y());
+        data += nsPrintfCString(", \"width\" : %d", aDisplayPort.Width());
+        data += nsPrintfCString(", \"height\" : %d", aDisplayPort.Height());
+        data += nsPrintfCString(", \"resolution\" : %f", aResolution.width);
+        data += nsPrintfCString(" }");
+    data += nsPrintfCString(", \"screenSize\" : ");
+        data += nsPrintfCString("{ \"width\" : %d", aScreenSize.width);
+        data += nsPrintfCString(", \"height\" : %d", aScreenSize.height);
+        data += nsPrintfCString(" }");
+    data += nsPrintfCString(" }");
+
     JSAutoRequest ar(mCx);
     jsval json = JSVAL_NULL;
     StructuredCloneData cloneData;
     JSAutoStructuredCloneBuffer buffer;
     if (JS_ParseJSON(mCx,
-                      static_cast<const jschar*>(NS_ConvertUTF8toUTF16(aJSONData).get()),
-                      aJSONData.Length(),
+                      static_cast<const jschar*>(NS_ConvertUTF8toUTF16(data).get()),
+                      data.Length(),
                       &json)) {
         WriteStructuredClone(mCx, json, buffer, cloneData.mClosure);
         cloneData.mData = buffer.data();
         cloneData.mDataLength = buffer.nbytes();
     }
 
     nsFrameScriptCx cx(static_cast<nsIWebBrowserChrome*>(this), this);
     // Let the BrowserElementScrolling helper (if it exists) for this
     // content manipulate the frame state.
     nsRefPtr<nsFrameMessageManager> mm =
       static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
     mm->ReceiveMessage(static_cast<nsIDOMEventTarget*>(mTabChildGlobal),
-                       aMessageName, false, &cloneData, nullptr, nullptr);
-}
-
-bool
-TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
-{
-    if (!mCx || !mTabChildGlobal) {
-        return true;
-    }
-
-    nsCString data;
-    data += nsPrintfCString("{ \"x\" : %d", aFrameMetrics.mViewportScrollOffset.x);
-    data += nsPrintfCString(", \"y\" : %d", aFrameMetrics.mViewportScrollOffset.y);
-    // We don't treat the x and y scales any differently for this
-    // semi-platform-specific code.
-    data += nsPrintfCString(", \"zoom\" : %f", aFrameMetrics.mResolution.width);
-    data += nsPrintfCString(", \"displayPort\" : ");
-        data += nsPrintfCString("{ \"left\" : %d", aFrameMetrics.mDisplayPort.X());
-        data += nsPrintfCString(", \"top\" : %d", aFrameMetrics.mDisplayPort.Y());
-        data += nsPrintfCString(", \"width\" : %d", aFrameMetrics.mDisplayPort.Width());
-        data += nsPrintfCString(", \"height\" : %d", aFrameMetrics.mDisplayPort.Height());
-        data += nsPrintfCString(", \"resolution\" : %f", aFrameMetrics.mResolution.width);
-        data += nsPrintfCString(" }");
-    data += nsPrintfCString(", \"screenSize\" : ");
-        data += nsPrintfCString("{ \"width\" : %d", aFrameMetrics.mViewport.width);
-        data += nsPrintfCString(", \"height\" : %d", aFrameMetrics.mViewport.height);
-        data += nsPrintfCString(" }");
-    data += nsPrintfCString(", \"cssPageRect\" : ");
-        data += nsPrintfCString("{ \"x\" : %f", aFrameMetrics.mCSSContentRect.x);
-        data += nsPrintfCString(", \"y\" : %f", aFrameMetrics.mCSSContentRect.y);
-        data += nsPrintfCString(", \"width\" : %f", aFrameMetrics.mCSSContentRect.width);
-        data += nsPrintfCString(", \"height\" : %f", aFrameMetrics.mCSSContentRect.height);
-        data += nsPrintfCString(" }");
-    data += nsPrintfCString(" }");
-
-    DispatchMessageManagerMessage(NS_LITERAL_STRING("Viewport:Change"), data);
-
-    return true;
-}
-
-bool
-TabChild::RecvHandleDoubleTap(const nsIntPoint& aPoint)
-{
-    if (!mCx || !mTabChildGlobal) {
-        return true;
-    }
-
-    nsCString data;
-    data += nsPrintfCString("{ \"x\" : %d", aPoint.x);
-    data += nsPrintfCString(", \"y\" : %d", aPoint.y);
-    data += nsPrintfCString(" }");
-
-    DispatchMessageManagerMessage(NS_LITERAL_STRING("Gesture:DoubleTap"), data);
-
+                       NS_LITERAL_STRING("Viewport:Change"), false,
+                       &cloneData, nullptr, nullptr);
     return true;
 }
 
 bool
 TabChild::RecvActivate()
 {
   nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
   browser->Activate();
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -42,17 +42,16 @@
 #include "nsIPresShell.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptContext.h"
 #include "nsPIDOMWindow.h"
 #include "nsWeakReference.h"
 #include "nsITabChild.h"
 #include "mozilla/Attributes.h"
-#include "FrameMetrics.h"
 
 struct gfxMatrix;
 
 namespace mozilla {
 namespace layout {
 class RenderFrameChild;
 }
 
@@ -136,18 +135,17 @@ class TabChild : public PBrowserChild,
                  public nsFrameScriptExecutor,
                  public nsIWebBrowserChrome2,
                  public nsIEmbeddingSiteWindow,
                  public nsIWebBrowserChromeFocus,
                  public nsIInterfaceRequestor,
                  public nsIWindowProvider,
                  public nsSupportsWeakReference,
                  public nsIDialogCreator,
-                 public nsITabChild,
-                 public nsIObserver
+                 public nsITabChild
 {
     typedef mozilla::layout::RenderFrameChild RenderFrameChild;
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
 public:
     /**
      * Create a new TabChild object.
      *
@@ -163,23 +161,24 @@ public:
     NS_DECL_NSIWEBBROWSERCHROME
     NS_DECL_NSIWEBBROWSERCHROME2
     NS_DECL_NSIEMBEDDINGSITEWINDOW
     NS_DECL_NSIWEBBROWSERCHROMEFOCUS
     NS_DECL_NSIINTERFACEREQUESTOR
     NS_DECL_NSIWINDOWPROVIDER
     NS_DECL_NSIDIALOGCREATOR
     NS_DECL_NSITABCHILD
-    NS_DECL_NSIOBSERVER
 
     virtual bool RecvLoadURL(const nsCString& uri);
     virtual bool RecvShow(const nsIntSize& size);
     virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size);
-    virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
-    virtual bool RecvHandleDoubleTap(const nsIntPoint& aPoint);
+    virtual bool RecvUpdateFrame(const nsIntRect& aDisplayPort,
+                                      const nsIntPoint& aScrollOffset,
+                                      const gfxSize& aResolution,
+                                      const nsIntRect& aScreenSize);
     virtual bool RecvActivate();
     virtual bool RecvDeactivate();
     virtual bool RecvMouseEvent(const nsString& aType,
                                 const float&    aX,
                                 const float&    aY,
                                 const PRInt32&  aButton,
                                 const PRInt32&  aClickCount,
                                 const PRInt32&  aModifiers,
@@ -283,24 +282,16 @@ private:
 
     bool InitTabChildGlobal();
     bool InitWidget(const nsIntSize& size);
     void DestroyWindow();
 
     // Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
     void DoFakeShow();
 
-    // Wraps up a JSON object as a structured clone and sends it to the browser
-    // chrome script.
-    //
-    // XXX/bug 780335: Do the work the browser chrome script does in C++ instead
-    // so we don't need things like this.
-    void DispatchMessageManagerMessage(const nsAString& aMessageName,
-                                       const nsACString& aJSONData);
-
     nsresult
     BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
                               nsIURI* aURI,
                               const nsAString& aName,
                               const nsACString& aFeatures,
                               bool* aWindowIsNew,
                               nsIDOMWindow** aReturn);
 
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -220,22 +220,20 @@ TabParent::UpdateDimensions(const nsRect
   if (RenderFrameParent* rfp = GetRenderFrame()) {
     rfp->NotifyDimensionsChanged(size.width, size.height);
   }
 }
 
 void
 TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
 {
-  unused << SendUpdateFrame(aFrameMetrics);
-}
-
-void TabParent::HandleDoubleTap(const nsIntPoint& aPoint)
-{
-  unused << SendHandleDoubleTap(aPoint);
+  unused << SendUpdateFrame(aFrameMetrics.mDisplayPort,
+                            aFrameMetrics.mViewportScrollOffset,
+                            aFrameMetrics.mResolution,
+                            aFrameMetrics.mViewport);
 }
 
 void
 TabParent::Activate()
 {
     mActive = true;
     unused << SendActivate();
 }
@@ -1087,28 +1085,10 @@ TabParent::RecvBrowserFrameOpenWindow(PB
                                       bool* aOutWindowOpened)
 {
   *aOutWindowOpened =
     BrowserElementParent::OpenWindowOOP(static_cast<TabParent*>(aOpener),
                                         this, aURL, aName, aFeatures);
   return true;
 }
 
-bool
-TabParent::RecvNotifyDOMTouchListenerAdded()
-{
-  if (RenderFrameParent* rfp = GetRenderFrame()) {
-    rfp->NotifyDOMTouchListenerAdded();
-  }
-  return true;
-}
-
-bool
-TabParent::RecvZoomToRect(const gfxRect& aRect)
-{
-  if (RenderFrameParent* rfp = GetRenderFrame()) {
-    rfp->ZoomToRect(aRect);
-  }
-  return true;
-}
-
 } // namespace tabs
 } // namespace mozilla
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -96,18 +96,16 @@ public:
                                      const nsString& aType,
                                      const nsString& aActionHint,
                                      const PRInt32& aCause,
                                      const PRInt32& aFocusChange);
     virtual bool RecvSetCursor(const PRUint32& aValue);
     virtual bool RecvSetBackgroundColor(const nscolor& aValue);
     virtual bool RecvGetDPI(float* aValue);
     virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue);
-    virtual bool RecvNotifyDOMTouchListenerAdded();
-    virtual bool RecvZoomToRect(const gfxRect& aRect);
     virtual PContentDialogParent* AllocPContentDialog(const PRUint32& aType,
                                                       const nsCString& aName,
                                                       const nsCString& aFeatures,
                                                       const InfallibleTArray<int>& aIntParams,
                                                       const InfallibleTArray<nsString>& aStringParams);
     virtual bool DeallocPContentDialog(PContentDialogParent* aDialog)
     {
       delete aDialog;
@@ -117,17 +115,16 @@ public:
 
     void LoadURL(nsIURI* aURI);
     // XXX/cjones: it's not clear what we gain by hiding these
     // message-sending functions under a layer of indirection and
     // eating the return values
     void Show(const nsIntSize& size);
     void UpdateDimensions(const nsRect& rect, const nsIntSize& size);
     void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
-    void HandleDoubleTap(const nsIntPoint& aPoint);
     void Activate();
     void Deactivate();
 
     /**
      * Is this object active?  That is, was Activate() called more recently than
      * Deactivate()?
      */
     bool Active();
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -1,36 +1,29 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=4 ts=8 et tw=80 : */
 /* 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/. */
 
 #include "CompositorParent.h"
 #include "mozilla/gfx/2D.h"
-#include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Constants.h"
 #include "mozilla/Util.h"
 #include "mozilla/XPCOM.h"
 #include "mozilla/Monitor.h"
-#include "mozilla/StaticPtr.h"
 #include "AsyncPanZoomController.h"
 #include "GestureEventListener.h"
 #include "nsIThreadManager.h"
 #include "nsThreadUtils.h"
 #include "Layers.h"
-#include "AnimationCommon.h"
-
-using namespace mozilla::css;
 
 namespace mozilla {
 namespace layers {
 
-const float AsyncPanZoomController::TOUCH_START_TOLERANCE = 1.0f/16.0f;
-
 static const float EPSILON = 0.0001;
 
 /**
  * Maximum amount of time while panning before sending a viewport change. This
  * will asynchronously repaint the page. It is also forced when panning stops.
  */
 static const PRInt32 PAN_REPAINT_INTERVAL = 250;
 
@@ -46,61 +39,32 @@ static const PRInt32 FLING_REPAINT_INTER
  */
 static const float MIN_SKATE_SPEED = 0.5f;
 
 /**
  * Angle from axis within which we stay axis-locked.
  */
 static const float AXIS_LOCK_ANGLE = M_PI / 6.0;
 
-/**
- * Duration of a zoom to animation.
- */
-static const TimeDuration ZOOM_TO_DURATION = TimeDuration::FromSeconds(0.25);
-
-/**
- * Computed time function used for sampling frames of a zoom to animation.
- */
-StaticAutoPtr<ComputedTimingFunction> gComputedTimingFunction;
-
-/**
- * Maximum zoom amount, always used, even if a page asks for higher.
- */
-static const double MAX_ZOOM = 8.0;
-
-/**
- * Minimum zoom amount, always used, even if a page asks for lower.
- */
-static const double MIN_ZOOM = 0.125;
-
 AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoContentController,
                                                GestureBehavior aGestures)
   :  mGeckoContentController(aGeckoContentController),
      mX(this),
      mY(this),
      mMonitor("AsyncPanZoomController"),
      mLastSampleTime(TimeStamp::Now()),
      mState(NOTHING),
      mDPI(72),
-     mContentPainterStatus(CONTENT_IDLE),
-     mMayHaveTouchListeners(false),
-     mDisableNextTouchBatch(false)
+     mContentPainterStatus(CONTENT_IDLE)
 {
   if (aGestures == USE_GESTURE_DETECTOR) {
     mGestureEventListener = new GestureEventListener(this);
   }
 
   SetDPI(mDPI);
-
-  if (!gComputedTimingFunction) {
-    gComputedTimingFunction = new ComputedTimingFunction();
-    gComputedTimingFunction->Init(
-      nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE));
-    ClearOnShutdown(&gComputedTimingFunction);
-  }
 }
 
 AsyncPanZoomController::~AsyncPanZoomController() {
 
 }
 
 static gfx::Point
 WidgetSpaceToCompensatedViewportSpace(const gfx::Point& aPoint,
@@ -177,17 +141,17 @@ AsyncPanZoomController::HandleInputEvent
   }
 
   return status;
 }
 
 nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent) {
   nsEventStatus rv = nsEventStatus_eIgnore;
 
-  if (mGestureEventListener && !mDisableNextTouchBatch) {
+  if (mGestureEventListener) {
     nsEventStatus rv = mGestureEventListener->HandleInputEvent(aEvent);
     if (rv == nsEventStatus_eConsumeNoDefault)
       return rv;
   }
 
   switch (aEvent.mInputType) {
   case MULTITOUCH_INPUT: {
     const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
@@ -231,69 +195,52 @@ nsEventStatus AsyncPanZoomController::Ha
 
 nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent) {
   SingleTouchData& touch = GetFirstSingleTouch(aEvent);
 
   nsIntPoint point = touch.mScreenPoint;
   PRInt32 xPos = point.x, yPos = point.y;
 
   switch (mState) {
-    case ANIMATING_ZOOM:
-      // We just interrupted a double-tap animation, so force a redraw in case
-      // this touchstart is just a tap that doesn't end up triggering a redraw.
-      RequestContentRepaint();
-      ScheduleComposite();
-      // Fall through.
     case FLING:
-      {
-        MonitorAutoLock monitor(mMonitor);
-        CancelAnimation();
-      }
+      CancelAnimation();
       // Fall through.
     case NOTHING:
       mX.StartTouch(xPos);
       mY.StartTouch(yPos);
-      SetState(TOUCHING);
+      mState = TOUCHING;
       break;
     case TOUCHING:
     case PANNING:
     case PINCHING:
       NS_WARNING("Received impossible touch in OnTouchStart");
       break;
     default:
       NS_WARNING("Unhandled case in OnTouchStart");
       break;
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent) {
-  if (mDisableNextTouchBatch) {
-    return nsEventStatus_eIgnore;
-  }
-
   switch (mState) {
     case FLING:
     case NOTHING:
-    case ANIMATING_ZOOM:
       // May happen if the user double-taps and drags without lifting after the
       // second tap. Ignore the move if this happens.
       return nsEventStatus_eIgnore;
 
     case TOUCHING: {
-      float panThreshold = TOUCH_START_TOLERANCE * mDPI;
+      float panThreshold = 1.0f/2.0f * mDPI;
       UpdateWithTouchAtDevicePoint(aEvent);
-
       if (PanDistance() < panThreshold) {
         return nsEventStatus_eIgnore;
       }
-
       StartPanning(aEvent);
-
       return nsEventStatus_eConsumeNoDefault;
     }
 
     case PANNING:
       TrackTouch(aEvent);
       return nsEventStatus_eConsumeNoDefault;
 
     case PINCHING:
@@ -301,61 +248,55 @@ nsEventStatus AsyncPanZoomController::On
       NS_WARNING("Gesture listener should have handled pinching in OnTouchMove.");
       return nsEventStatus_eIgnore;
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) {
-  if (mDisableNextTouchBatch) {
-    mDisableNextTouchBatch = false;
-    return nsEventStatus_eIgnore;
-  }
-
   switch (mState) {
   case FLING:
     // Should never happen.
     NS_WARNING("Received impossible touch end in OnTouchEnd.");
     // Fall through.
-  case ANIMATING_ZOOM:
   case NOTHING:
     // May happen if the user double-taps and drags without lifting after the
     // second tap. Ignore if this happens.
     return nsEventStatus_eIgnore;
 
   case TOUCHING:
-    SetState(NOTHING);
+    mState = NOTHING;
     return nsEventStatus_eIgnore;
 
   case PANNING:
     {
       MonitorAutoLock monitor(mMonitor);
       ScheduleComposite();
       RequestContentRepaint();
     }
-    SetState(FLING);
+    mState = FLING;
     return nsEventStatus_eConsumeNoDefault;
   case PINCHING:
-    SetState(NOTHING);
+    mState = NOTHING;
     // Scale gesture listener should have handled this.
     NS_WARNING("Gesture listener should have handled pinching in OnTouchEnd.");
     return nsEventStatus_eIgnore;
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnTouchCancel(const MultiTouchInput& aEvent) {
-  SetState(NOTHING);
+  mState = NOTHING;
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEvent) {
-  SetState(PINCHING);
+  mState = PINCHING;
   mLastZoomFocus = aEvent.mFocusPoint;
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
   float prevSpan = aEvent.mPreviousSpan;
   if (fabsf(prevSpan) <= EPSILON || fabsf(aEvent.mCurrentSpan) <= EPSILON) {
@@ -383,24 +324,24 @@ nsEventStatus AsyncPanZoomController::On
     ScrollBy(nsIntPoint(xFocusChange, yFocusChange));
 
     // When we zoom in with focus, we can zoom too much towards the boundaries
     // that we actually go over them. These are the needed displacements along
     // either axis such that we don't overscroll the boundaries when zooming.
     PRInt32 neededDisplacementX = 0, neededDisplacementY = 0;
 
     // Only do the scaling if we won't go over 8x zoom in or out.
-    bool doScale = (scale < MAX_ZOOM && spanRatio > 1.0f) || (scale > MIN_ZOOM && spanRatio < 1.0f);
+    bool doScale = (scale < 8.0f && spanRatio > 1.0f) || (scale > 0.125f && spanRatio < 1.0f);
 
     // If this zoom will take it over 8x zoom in either direction, but it's not
     // already there, then normalize it.
-    if (scale * spanRatio > MAX_ZOOM) {
-      spanRatio = scale / MAX_ZOOM;
-    } else if (scale * spanRatio < MIN_ZOOM) {
-      spanRatio = scale / MIN_ZOOM;
+    if (scale * spanRatio > 8.0f) {
+      spanRatio = scale / 8.0f;
+    } else if (scale * spanRatio < 0.125f) {
+      spanRatio = scale / 0.125f;
     }
 
     if (doScale) {
       switch (mX.ScaleWillOverscroll(spanRatio, focusPoint.x))
       {
         case Axis::OVERSCROLL_NONE:
           break;
         case Axis::OVERSCROLL_MINUS:
@@ -447,17 +388,17 @@ nsEventStatus AsyncPanZoomController::On
 
     mLastZoomFocus = focusPoint;
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 nsEventStatus AsyncPanZoomController::OnScaleEnd(const PinchGestureInput& aEvent) {
-  SetState(PANNING);
+  mState = PANNING;
   mX.StartTouch(aEvent.mFocusPoint.x);
   mY.StartTouch(aEvent.mFocusPoint.y);
   {
     MonitorAutoLock monitor(mMonitor);
     ScheduleComposite();
     RequestContentRepaint();
   }
 
@@ -475,54 +416,48 @@ nsEventStatus AsyncPanZoomController::On
 }
 
 nsEventStatus AsyncPanZoomController::OnSingleTapConfirmed(const TapGestureInput& aEvent) {
   // XXX: Implement this.
   return nsEventStatus_eIgnore;
 }
 
 nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent) {
-  if (mGeckoContentController) {
-    MonitorAutoLock monitor(mMonitor);
-
-    gfx::Point point = WidgetSpaceToCompensatedViewportSpace(
-      gfx::Point(aEvent.mPoint.x, aEvent.mPoint.y),
-      mFrameMetrics.mResolution.width);
-    mGeckoContentController->HandleDoubleTap(nsIntPoint(NS_lround(point.x), NS_lround(point.y)));
-    return nsEventStatus_eConsumeNoDefault;
-  }
+  // XXX: Implement this.
   return nsEventStatus_eIgnore;
 }
 
 nsEventStatus AsyncPanZoomController::OnCancelTap(const TapGestureInput& aEvent) {
   // XXX: Implement this.
   return nsEventStatus_eIgnore;
 }
 
 float AsyncPanZoomController::PanDistance() {
-  MonitorAutoLock monitor(mMonitor);
-  return NS_hypot(mX.PanDistance(), mY.PanDistance());
+  return NS_hypot(mX.PanDistance(), mY.PanDistance()) * mFrameMetrics.mResolution.width;
 }
 
-const gfx::Point AsyncPanZoomController::GetVelocityVector() {
-  return gfx::Point(mX.GetVelocity(), mY.GetVelocity());
+const nsPoint AsyncPanZoomController::GetVelocityVector() {
+  return nsPoint(
+    mX.GetVelocity(),
+    mY.GetVelocity()
+  );
 }
 
 void AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) {
   SingleTouchData& touch = GetFirstSingleTouch(aEvent);
 
   float dx = mX.PanDistance(),
         dy = mY.PanDistance();
 
   double angle = atan2(dy, dx); // range [-pi, pi]
   angle = fabs(angle); // range [0, pi]
 
   mX.StartTouch(touch.mScreenPoint.x);
   mY.StartTouch(touch.mScreenPoint.y);
-  SetState(PANNING);
+  mState = PANNING;
 
   if (angle < AXIS_LOCK_ANGLE || angle > (M_PI - AXIS_LOCK_ANGLE)) {
     mY.LockPanning();
   } else if (fabsf(angle - M_PI / 2) < AXIS_LOCK_ANGLE) {
     mX.LockPanning();
   }
 }
 
@@ -619,73 +554,55 @@ void AsyncPanZoomController::ScrollBy(co
 }
 
 void AsyncPanZoomController::SetPageRect(const gfx::Rect& aCSSPageRect) {
   FrameMetrics metrics = mFrameMetrics;
   gfx::Rect pageSize = aCSSPageRect;
   float scale = mFrameMetrics.mResolution.width;
 
   // The page rect is the css page rect scaled by the current zoom.
-  pageSize.ScaleRoundOut(1 / scale);
+  pageSize.ScaleRoundOut(scale);
 
   // Round the page rect so we don't get any truncation, then get the nsIntRect
   // from this.
   metrics.mContentRect = nsIntRect(pageSize.x, pageSize.y, pageSize.width, pageSize.height);
   metrics.mCSSContentRect = aCSSPageRect;
 
   mFrameMetrics = metrics;
 }
 
 void AsyncPanZoomController::ScaleWithFocus(float aScale, const nsIntPoint& aFocus) {
   FrameMetrics metrics(mFrameMetrics);
 
   // Don't set the scale to the inputted value, but rather multiply it in.
-  float scaleFactor = aScale / metrics.mResolution.width,
-        oldScale = metrics.mResolution.width;
+  float scaleFactor = aScale / metrics.mResolution.width;
 
   metrics.mResolution.width = metrics.mResolution.height = aScale;
 
   // Force a recalculation of the page rect based on the new zoom and the
   // current CSS page rect (which is unchanged since it's not affected by zoom).
   SetPageRect(mFrameMetrics.mCSSContentRect);
 
   nsIntPoint scrollOffset = metrics.mViewportScrollOffset;
 
-  scrollOffset.x += NS_lround(float(aFocus.x) * (scaleFactor - 1.0f) / oldScale);
-  scrollOffset.y += NS_lround(float(aFocus.y) * (scaleFactor - 1.0f) / oldScale);
+  scrollOffset.x += aFocus.x * (scaleFactor - 1.0f);
+  scrollOffset.y += aFocus.y * (scaleFactor - 1.0f);
 
   metrics.mViewportScrollOffset = scrollOffset;
 
   mFrameMetrics = metrics;
 }
 
-bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aViewport,
-                                                         float aVelocity,
-                                                         float* aDisplayPortOffset,
-                                                         float* aDisplayPortLength)
-{
-  const float MIN_SKATE_SIZE_MULTIPLIER = 2.0f;
-  const float MAX_SKATE_SIZE_MULTIPLIER = 4.0f;
-
-  if (fabsf(aVelocity) > MIN_SKATE_SPEED) {
-    *aDisplayPortLength = aViewport * clamped(fabsf(aVelocity),
-      MIN_SKATE_SIZE_MULTIPLIER, MAX_SKATE_SIZE_MULTIPLIER);
-    *aDisplayPortOffset = aVelocity > 0 ? 0 : aViewport - *aDisplayPortLength;
-    return true;
-  }
-  return false;
-}
-
 const nsIntRect AsyncPanZoomController::CalculatePendingDisplayPort() {
   float scale = mFrameMetrics.mResolution.width;
   nsIntRect viewport = mFrameMetrics.mViewport;
   viewport.ScaleRoundIn(1 / scale);
 
   nsIntPoint scrollOffset = mFrameMetrics.mViewportScrollOffset;
-  gfx::Point velocity = GetVelocityVector();
+  nsPoint velocity = GetVelocityVector();
 
   // The displayport is relative to the current scroll offset. Here's a little
   // diagram to make it easier to see:
   //
   //       - - - -
   //       |     |
   //    *************
   //    *  |     |  *
@@ -702,35 +619,38 @@ const nsIntRect AsyncPanZoomController::
   // The full --- area with === inside it is the actual viewport rect, the *** area
   // is the displayport, and the - - - area is an imaginary additional page on all 4
   // borders of the actual page. Notice that the displayport intersects half-way with
   // each of the imaginary extra pages. The @ symbol at the top left of the
   // viewport marks the current scroll offset. From the @ symbol to the far left
   // and far top, it is clear that this distance is 1/4 of the displayport's
   // height/width dimension.
   const float STATIONARY_SIZE_MULTIPLIER = 2.0f;
+  const float SKATE_SIZE_MULTIPLIER = 3.0f;
   gfx::Rect displayPort(0, 0,
                         viewport.width * STATIONARY_SIZE_MULTIPLIER,
                         viewport.height * STATIONARY_SIZE_MULTIPLIER);
 
-  // If there's motion along an axis of movement, and it's above a threshold,
-  // then we want to paint a larger area in the direction of that motion so that
-  // it's less likely to checkerboard.
-  bool enlargedX = EnlargeDisplayPortAlongAxis(
-    viewport.width, velocity.x, &displayPort.x, &displayPort.width);
-  bool enlargedY = EnlargeDisplayPortAlongAxis(
-    viewport.height, velocity.y, &displayPort.y, &displayPort.height);
-
-  if (!enlargedX && !enlargedY) {
+  // Iff there's motion along only one axis of movement, and it's above a
+  // threshold, then we want to paint a larger area in the direction of that
+  // motion so that it's less likely to checkerboard. Also note that the other
+  // axis doesn't need its displayport enlarged beyond the viewport dimension,
+  // since it is impossible for it to checkerboard along that axis until motion
+  // begins on it.
+  if (fabsf(velocity.x) > MIN_SKATE_SPEED && fabsf(velocity.y) < MIN_SKATE_SPEED) {
+    displayPort.height = viewport.height;
+    displayPort.width = viewport.width * SKATE_SIZE_MULTIPLIER;
+    displayPort.x = velocity.x > 0 ? 0 : viewport.width - displayPort.width;
+  } else if (fabsf(velocity.x) < MIN_SKATE_SPEED && fabsf(velocity.y) > MIN_SKATE_SPEED) {
+    displayPort.width = viewport.width;
+    displayPort.height = viewport.height * SKATE_SIZE_MULTIPLIER;
+    displayPort.y = velocity.y > 0 ? 0 : viewport.height - displayPort.height;
+  } else {
     displayPort.x = -displayPort.width / 4;
     displayPort.y = -displayPort.height / 4;
-  } else if (!enlargedX) {
-    displayPort.width = viewport.width;
-  } else if (!enlargedY) {
-    displayPort.height = viewport.height;
   }
 
   gfx::Rect shiftedDisplayPort = displayPort;
   shiftedDisplayPort.MoveBy(scrollOffset.x, scrollOffset.y);
   displayPort = shiftedDisplayPort.Intersect(mFrameMetrics.mCSSContentRect);
   displayPort.MoveBy(-scrollOffset.x, -scrollOffset.y);
 
   // Round the displayport so we don't get any truncation, then get the nsIntRect
@@ -738,20 +658,16 @@ const nsIntRect AsyncPanZoomController::
   displayPort.Round();
   return nsIntRect(displayPort.x, displayPort.y, displayPort.width, displayPort.height);
 }
 
 void AsyncPanZoomController::SetDPI(int aDPI) {
   mDPI = aDPI;
 }
 
-int AsyncPanZoomController::GetDPI() {
-  return mDPI;
-}
-
 void AsyncPanZoomController::ScheduleComposite() {
   if (mCompositorParent) {
     mCompositorParent->ScheduleRenderOnCompositorThread();
   }
 }
 
 void AsyncPanZoomController::RequestContentRepaint() {
   mFrameMetrics.mDisplayPort = CalculatePendingDisplayPort();
@@ -795,53 +711,19 @@ bool AsyncPanZoomController::SampleConte
 
   nsIntPoint metricsScrollOffset(0, 0);
   nsIntPoint scrollOffset;
   float localScaleX, localScaleY;
   const FrameMetrics& frame = aLayer->GetFrameMetrics();
   {
     MonitorAutoLock mon(mMonitor);
 
-    switch (mState)
-    {
-    case FLING:
-      // If a fling is currently happening, apply it now. We can pull the updated
-      // metrics afterwards.
-      requestAnimationFrame |= DoFling(aSampleTime - mLastSampleTime);
-      break;
-    case ANIMATING_ZOOM: {
-      double animPosition = (aSampleTime - mAnimationStartTime) / ZOOM_TO_DURATION;
-      if (animPosition > 1.0) {
-        animPosition = 1.0;
-      }
-      double sampledPosition = gComputedTimingFunction->GetValue(animPosition);
-
-      mFrameMetrics.mResolution.width = mFrameMetrics.mResolution.height =
-        mEndZoomToMetrics.mResolution.width * sampledPosition +
-          mStartZoomToMetrics.mResolution.width * (1 - sampledPosition);
-
-      mFrameMetrics.mViewportScrollOffset = nsIntPoint(
-        mEndZoomToMetrics.mViewportScrollOffset.x * sampledPosition +
-          mStartZoomToMetrics.mViewportScrollOffset.x * (1 - sampledPosition),
-        mEndZoomToMetrics.mViewportScrollOffset.y * sampledPosition +
-          mStartZoomToMetrics.mViewportScrollOffset.y * (1 - sampledPosition)
-      );
-
-      requestAnimationFrame = true;
-
-      if (aSampleTime - mAnimationStartTime >= ZOOM_TO_DURATION) {
-        mState = NOTHING;
-        RequestContentRepaint();
-      }
-
-      break;
-    }
-    default:
-      break;
-    }
+    // If a fling is currently happening, apply it now. We can pull the updated
+    // metrics afterwards.
+    requestAnimationFrame = requestAnimationFrame || DoFling(aSampleTime - mLastSampleTime);
 
     // Current local transform; this is not what's painted but rather what PZC has
     // transformed due to touches like panning or pinching. Eventually, the root
     // layer transform will become this during runtime, but we must wait for Gecko
     // to repaint.
     localScaleX = mFrameMetrics.mResolution.width;
     localScaleY = mFrameMetrics.mResolution.height;
 
@@ -897,21 +779,17 @@ void AsyncPanZoomController::NotifyLayer
     mFrameMetrics.mResolution.width = 1 / mFrameMetrics.mResolution.width;
     mFrameMetrics.mResolution.height = 1 / mFrameMetrics.mResolution.height;
     SetPageRect(mFrameMetrics.mCSSContentRect);
 
     // Bug 776413/fixme: Request a repaint as soon as a page is loaded so that
     // we get a larger displayport. This is very bad because we're wasting a
     // paint and not initializating the displayport correctly.
     RequestContentRepaint();
-
-    // Assuming a first paint means a new page has been loaded, clear the flag
-    // indicating that we may have touch listeners.
-    mMayHaveTouchListeners = false;
-  } else if (!mFrameMetrics.mCSSContentRect.IsEqualEdges(aViewportFrame.mCSSContentRect)) {
+  } else if (!mFrameMetrics.mContentRect.IsEqualEdges(aViewportFrame.mContentRect)) {
     mFrameMetrics.mCSSContentRect = aViewportFrame.mCSSContentRect;
     SetPageRect(mFrameMetrics.mCSSContentRect);
   }
 }
 
 const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() {
   mMonitor.AssertCurrentThreadOwns();
   return mFrameMetrics;
@@ -919,100 +797,10 @@ const FrameMetrics& AsyncPanZoomControll
 
 void AsyncPanZoomController::UpdateViewportSize(int aWidth, int aHeight) {
   MonitorAutoLock mon(mMonitor);
   FrameMetrics metrics = GetFrameMetrics();
   metrics.mViewport = nsIntRect(0, 0, aWidth, aHeight);
   mFrameMetrics = metrics;
 }
 
-void AsyncPanZoomController::NotifyDOMTouchListenerAdded() {
-  mMayHaveTouchListeners = true;
-}
-
-void AsyncPanZoomController::CancelDefaultPanZoom() {
-  mDisableNextTouchBatch = true;
-  if (mGestureEventListener) {
-    mGestureEventListener->CancelGesture();
-  }
-}
-
-void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
-  gfx::Rect zoomToRect(gfx::Rect(aRect.x, aRect.y, aRect.width, aRect.height));
-  gfx::Rect cssPageRect = mFrameMetrics.mCSSContentRect;
-
-  SetState(ANIMATING_ZOOM);
-
-  {
-    MonitorAutoLock mon(mMonitor);
-
-    nsIntRect viewport = mFrameMetrics.mViewport;
-
-    // If the rect is empty, treat it as a request to zoom out to the full page
-    // size.
-    if (zoomToRect.IsEmpty()) {
-      nsIntRect cssViewport = viewport;
-      cssViewport.ScaleRoundIn(1 / mFrameMetrics.mResolution.width);
-      cssViewport.MoveBy(mFrameMetrics.mViewportScrollOffset);
-
-      float y = mFrameMetrics.mViewportScrollOffset.y;
-      float newHeight = cssViewport.height * cssPageRect.width / cssViewport.width;
-      float dh = cssViewport.height - newHeight;
-
-      zoomToRect = gfx::Rect(0.0f,
-                             y + dh/2,
-                             cssPageRect.width,
-                             y + dh/2 + newHeight);
-    } else {
-      float targetRatio = float(viewport.width) / float(viewport.height);
-      float rectRatio = zoomToRect.width / zoomToRect.height;
-
-      if (fabsf(targetRatio - rectRatio) < EPSILON) {
-        // All good, do nothing.
-      } else if (targetRatio < rectRatio) {
-        // Need to increase zoomToRect height.
-        float newHeight = zoomToRect.height / targetRatio;
-        zoomToRect.y -= (newHeight - zoomToRect.height) / 2;
-        zoomToRect.height = newHeight;
-      } else { // (targetRatio > rectRatio) {
-        // Need to increase zoomToRect width.
-        float newWidth = targetRatio * zoomToRect.width;
-        zoomToRect.x -= (newWidth - zoomToRect.width) / 2;
-        zoomToRect.width = newWidth;
-      }
-
-      zoomToRect = zoomToRect.Intersect(cssPageRect);
-    }
-
-    mEndZoomToMetrics.mResolution.width = mEndZoomToMetrics.mResolution.height =
-      NS_MIN(viewport.width / zoomToRect.width, viewport.height / zoomToRect.height);
-
-    mEndZoomToMetrics.mResolution.width = mEndZoomToMetrics.mResolution.height =
-      clamped(mEndZoomToMetrics.mResolution.width, MIN_ZOOM, MAX_ZOOM);
-
-    // Recalculate the zoom to rect using the new dimensions.
-    zoomToRect.width = viewport.width / mEndZoomToMetrics.mResolution.width;
-    zoomToRect.height = viewport.height / mEndZoomToMetrics.mResolution.height;
-
-    // Clamp the zoom to rect to the CSS rect to make sure it fits.
-    zoomToRect = zoomToRect.Intersect(cssPageRect);
-
-    // Do one final recalculation to get the resolution.
-    mEndZoomToMetrics.mResolution.width = mEndZoomToMetrics.mResolution.height =
-      NS_MAX(viewport.width / zoomToRect.width, viewport.height / zoomToRect.height);
-
-    mStartZoomToMetrics = mFrameMetrics;
-    mEndZoomToMetrics.mViewportScrollOffset =
-      nsIntPoint(NS_lround(zoomToRect.x), NS_lround(zoomToRect.y));
-
-    mAnimationStartTime = TimeStamp::Now();
-
-    ScheduleComposite();
-  }
-}
-
-void AsyncPanZoomController::SetState(PanZoomState aState) {
-  MonitorAutoLock monitor(mMonitor);
-  mState = aState;
-}
-
 }
 }
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -52,24 +52,16 @@ public:
     // The platform code is responsible for forwarding gesture events here. We
     // will not attempt to generate gesture events from MultiTouchInputs.
     DEFAULT_GESTURES,
     // An instance of GestureEventListener is used to detect gestures. This is
     // handled completely internally within this class.
     USE_GESTURE_DETECTOR
   };
 
-  /**
-   * Constant describing the tolerance in distance we use, multiplied by the
-   * device DPI, before we start panning the screen. This is to prevent us from
-   * accidentally processing taps as touch moves, and from very short/accidental
-   * touches moving the screen.
-   */
-  static const float TOUCH_START_TOLERANCE;
-
   AsyncPanZoomController(GeckoContentController* aController,
                          GestureBehavior aGestures = DEFAULT_GESTURES);
   ~AsyncPanZoomController();
 
   // --------------------------------------------------------------------------
   // These methods must only be called on the controller/UI thread.
   //
 
@@ -102,43 +94,16 @@ public:
    * using CSS pixels everywhere inside here, but in this case we need to know
    * how large of a displayport to set so we use these dimensions plus some
    * extra.
    *
    * XXX: Use nsIntRect instead.
    */
   void UpdateViewportSize(int aWidth, int aHeight);
 
-  /**
-   * A DOM touch listener has been added. When called, we enable the machinery
-   * that allows touch listeners to preventDefault any touch inputs. This should
-   * not be called unless there are actually touch listeners as it introduces
-   * potentially unbounded lag because it causes a round-trip through content.
-   * Usually, if content is responding in a timely fashion, this only introduces
-   * a nearly constant few hundred ms of lag.
-   */
-  void NotifyDOMTouchListenerAdded();
-
-  /**
-   * We have found a scrollable subframe, so disable our machinery until we hit
-   * a touch end or a new touch start. This prevents us from accidentally
-   * panning both the subframe and the parent frame.
-   *
-   * XXX/bug 775452: We should eventually be supporting async scrollable
-   * subframes.
-   */
-  void CancelDefaultPanZoom();
-
-  /**
-   * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
-   * in. The actual animation is done on the compositor thread after being set
-   * up. |aRect| must be given in CSS pixels, relative to the document.
-   */
-  void ZoomToRect(const gfxRect& aRect);
-
   // --------------------------------------------------------------------------
   // These methods must only be called on the compositor thread.
   //
 
   /**
    * The compositor calls this when it's about to draw pannable/zoomable content
    * and is setting up transforms for compositing the layer tree. This is not
    * idempotent. For example, a fling transform can be applied each time this is
@@ -182,22 +147,16 @@ public:
 
   /**
    * Sets the DPI of the device for use within panning and zooming logic. It is
    * a platform responsibility to set this on initialization of this class and
    * whenever it changes.
    */
   void SetDPI(int aDPI);
 
-  /**
-   * Gets the DPI of the device for use outside the panning and zooming logic.
-   * It defaults to 72 if not set using SetDPI() at any point.
-   */
-  int GetDPI();
-
 protected:
   /**
    * Helper method for touches beginning. Sets everything up for panning and any
    * multitouch gestures.
    */
   nsEventStatus OnTouchStart(const MultiTouchInput& aEvent);
 
   /**
@@ -291,33 +250,31 @@ protected:
    * CompositorParent::ScheduleRenderOnCompositorThread().
    */
   void ScheduleComposite();
 
   /**
    * Cancels any currently running animation. Note that all this does is set the
    * state of the AsyncPanZoomController back to NOTHING, but it is the
    * animation's responsibility to check this before advancing.
-   *
-   * *** The monitor must be held while calling this.
    */
   void CancelAnimation();
 
   /**
    * Gets the displacement of the current touch since it began. That is, it is
    * the distance between the current position and the initial position of the
    * current touch (this only makes sense if a touch is currently happening and
    * OnTouchMove() is being invoked).
    */
   float PanDistance();
 
   /**
    * Gets a vector of the velocities of each axis.
    */
-  const gfx::Point GetVelocityVector();
+  const nsPoint GetVelocityVector();
 
   /**
    * Gets a reference to the first SingleTouchData from a MultiTouchInput.  This
    * gets only the first one and assumes the rest are either missing or not
    * relevant.
    */
   SingleTouchData& GetFirstSingleTouch(const MultiTouchInput& aEvent);
 
@@ -343,27 +300,16 @@ protected:
    * than the actual screen. The viewport refers to the size of the screen,
    * while the displayport is the area actually painted by Gecko. We paint
    * a larger area than the screen so that when you scroll down, you don't
    * checkerboard immediately.
    */
   const nsIntRect CalculatePendingDisplayPort();
 
   /**
-   * Attempts to enlarge the displayport along a single axis. Returns whether or
-   * not the displayport was enlarged. This will fail in circumstances where the
-   * velocity along that axis is not high enough to need any changes. The
-   * displayport metrics are expected to be passed into |aDisplayPortOffset| and
-   * |aDisplayPortLength|. If enlarged, these will be updated with the new
-   * metrics.
-   */
-  bool EnlargeDisplayPortAlongAxis(float aViewport, float aVelocity,
-                                   float* aDisplayPortOffset, float* aDisplayPortLength);
-
-  /**
    * Utility function to send updated FrameMetrics to Gecko so that it can paint
    * the displayport area. Calls into GeckoContentController to do the actual
    * work. Note that only one paint request can be active at a time. If a paint
    * request is made while a paint is currently happening, it gets queued up. If
    * a new paint request arrives before a paint is completed, the old request
    * gets discarded.
    */
   void RequestContentRepaint();
@@ -384,17 +330,16 @@ protected:
 
 private:
   enum PanZoomState {
     NOTHING,        /* no touch-start events received */
     FLING,          /* all touches removed, but we're still scrolling page */
     TOUCHING,       /* one touch-start event received */
     PANNING,        /* panning without axis lock */
     PINCHING,       /* nth touch-start, where n > 1. this mode allows pan and zoom */
-    ANIMATING_ZOOM  /* animated zoom to a new rect */
   };
 
   enum ContentPainterStatus {
     // A paint may be happening, but it is not due to any action taken by this
     // thread. For example, content could be invalidating itself, but
     // AsyncPanZoomController has nothing to do with that.
     CONTENT_IDLE,
     // Set every time we dispatch a request for a repaint. When a
@@ -406,92 +351,53 @@ private:
     // mFrameMetrics.mDisplayPort (the most recent request) if this is toggled.
     // This is distinct from CONTENT_PAINTING in that it signals that a repaint
     // is happening, whereas this signals that we want to repaint as soon as the
     // previous paint finishes. When the request is eventually made, it will use
     // the most up-to-date metrics.
    CONTENT_PAINTING_AND_PAINT_PENDING
   };
 
-  /**
-   * Helper to set the current state. Holds the monitor before actually setting
-   * it. If the monitor is already held by the current thread, it is safe to
-   * instead use: |mState = NEWSTATE;|
-   */
-  void SetState(PanZoomState aState);
-
   nsRefPtr<CompositorParent> mCompositorParent;
   nsRefPtr<GeckoContentController> mGeckoContentController;
   nsRefPtr<GestureEventListener> mGestureEventListener;
 
   // Both |mFrameMetrics| and |mLastContentPaintMetrics| are protected by the
   // monitor. Do not read from or modify either of them without locking.
   FrameMetrics mFrameMetrics;
-
   // These are the metrics at last content paint, the most recent
   // values we were notified of in NotifyLayersUpdate().
   FrameMetrics mLastContentPaintMetrics;
-
   // The last metrics that we requested a paint for. These are used to make sure
   // that we're not requesting a paint of the same thing that's already drawn.
   // If we don't do this check, we don't get a ShadowLayersUpdated back.
   FrameMetrics mLastPaintRequestMetrics;
 
-  // Old metrics from before we started a zoom animation. This is only valid
-  // when we are in the "ANIMATED_ZOOM" state. This is used so that we can
-  // interpolate between the start and end frames. We only use the
-  // |mViewportScrollOffset| and |mResolution| fields on this.
-  FrameMetrics mStartZoomToMetrics;
-  // Target metrics for a zoom to animation. This is only valid when we are in
-  // the "ANIMATED_ZOOM" state. We only use the |mViewportScrollOffset| and
-  // |mResolution| fields on this.
-  FrameMetrics mEndZoomToMetrics;
-
   AxisX mX;
   AxisY mY;
 
-  // Protects |mFrameMetrics|, |mLastContentPaintMetrics| and |mState|. Before
-  // manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the monitor
-  // should be held. When setting |mState|, either the SetState() function can
-  // be used, or the monitor can be held and then |mState| updated.
   Monitor mMonitor;
 
   // The last time the compositor has sampled the content transform for this
   // frame.
   TimeStamp mLastSampleTime;
   // The last time a touch event came through on the UI thread.
   PRInt32 mLastEventTime;
 
-  // Start time of an animation. This is used for a zoom to animation to mark
-  // the beginning.
-  TimeStamp mAnimationStartTime;
-
   // Stores the previous focus point if there is a pinch gesture happening. Used
   // to allow panning by moving multiple fingers (thus moving the focus point).
   nsIntPoint mLastZoomFocus;
-
-  // Stores the state of panning and zooming this frame. This is protected by
-  // |mMonitor|; that is, it should be held whenever this is updated.
   PanZoomState mState;
-
   int mDPI;
 
   // Stores the current paint status of the frame that we're managing. Repaints
   // may be triggered by other things (like content doing things), in which case
   // this status will not be updated. It is only changed when this class
   // requests a repaint.
   ContentPainterStatus mContentPainterStatus;
 
-  // Whether or not we might have touch listeners. This is a conservative
-  // approximation and may not be accurate.
-  bool mMayHaveTouchListeners;
-
-  // Flag used to determine whether or not we should disable handling of the
-  // next batch of touch events. This is used for sync scrolling of subframes.
-  bool mDisableNextTouchBatch;
-
   friend class Axis;
 };
 
 }
 }
 
 #endif // mozilla_layers_PanZoomController_h
--- a/gfx/layers/ipc/GeckoContentController.h
+++ b/gfx/layers/ipc/GeckoContentController.h
@@ -18,24 +18,16 @@ public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GeckoContentController)
 
   /**
    * Requests a paint of the given FrameMetrics |aFrameMetrics| from Gecko.
    * Implementations per-platform are responsible for actually handling this.
    */
   virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) = 0;
 
-  /**
-   * Requests handling of a double tap. |aPoint| is in CSS pixels, relative to
-   * the current scroll offset. This should eventually round-trip back to
-   * AsyncPanZoomController::ZoomToRect with the dimensions that we want to zoom
-   * to.
-   */
-  virtual void HandleDoubleTap(const nsIntPoint& aPoint) = 0;
-
   GeckoContentController() {}
   virtual ~GeckoContentController() {}
 };
 
 }
 }
 
 #endif // mozilla_layers_GeckoContentController_h
--- a/gfx/layers/ipc/GestureEventListener.cpp
+++ b/gfx/layers/ipc/GestureEventListener.cpp
@@ -58,36 +58,30 @@ nsEventStatus GestureEventListener::Hand
       if (!foundAlreadyExistingTouch) {
         mTouches.AppendElement(event.mTouches[i]);
       }
     }
 
     size_t length = mTouches.Length();
     if (length == 1) {
       mTapStartTime = event.mTime;
-      mTouchStartPosition = event.mTouches[0].mScreenPoint;
       if (mState == GESTURE_NONE) {
         mState = GESTURE_WAITING_SINGLE_TAP;
       }
     } else if (length == 2) {
       // Another finger has been added; it can't be a tap anymore.
       HandleTapCancel(event);
     }
 
     break;
   }
   case MultiTouchInput::MULTITOUCH_MOVE: {
-    // If we move too much, bail out of the tap.
-    nsIntPoint touch = (nsIntPoint&)event.mTouches[0].mScreenPoint;
-    if (mTouches.Length() == 1 &&
-        NS_hypot(mTouchStartPosition.x - touch.x, mTouchStartPosition.y - touch.y) >
-          mAsyncPanZoomController->GetDPI() * AsyncPanZoomController::TOUCH_START_TOLERANCE)
-    {
-      HandleTapCancel(event);
-    }
+    // If we move at all, just bail out of the tap. We need to change this so
+    // that there's some tolerance in the future.
+    HandleTapCancel(event);
 
     bool foundAlreadyExistingTouch = false;
     for (size_t i = 0; i < mTouches.Length(); i++) {
       for (size_t j = 0; j < event.mTouches.Length(); j++) {
         if (mTouches[i].mIdentifier == event.mTouches[j].mIdentifier) {
           foundAlreadyExistingTouch = true;
           mTouches[i] = event.mTouches[j];
         }
@@ -261,15 +255,10 @@ void GestureEventListener::TimeoutDouble
     HandleSingleTapConfirmedEvent(mLastTouchInput);
   }
 }
 
 AsyncPanZoomController* GestureEventListener::GetAsyncPanZoomController() {
   return mAsyncPanZoomController;
 }
 
-void GestureEventListener::CancelGesture() {
-  mTouches.Clear();
-  mState = GESTURE_NONE;
-}
-
 }
 }
--- a/gfx/layers/ipc/GestureEventListener.h
+++ b/gfx/layers/ipc/GestureEventListener.h
@@ -1,9 +1,12 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=4 ts=8 et tw=80 : */ /* 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
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* 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/. */
 
 #ifndef mozilla_layers_GestureEventListener_h
 #define mozilla_layers_GestureEventListener_h
 
 #include "mozilla/RefPtr.h"
 #include "InputData.h"
 #include "Axis.h"
@@ -40,23 +43,16 @@ public:
   /**
    * General input handler for a touch event. If the touch event is not a part
    * of a gesture, then we pass it along to AsyncPanZoomController. Otherwise,
    * it gets consumed here and never forwarded along.
    */
   nsEventStatus HandleInputEvent(const InputData& aEvent);
 
   /**
-   * Cancels any currently active gesture. May not properly handle situations
-   * that require extra work at the gesture's end, like a pinch which only
-   * requests a repaint once it has ended.
-   */
-  void CancelGesture();
-
-  /**
    * Returns the AsyncPanZoomController stored on this class and used for
    * callbacks.
    */
   AsyncPanZoomController* GetAsyncPanZoomController();
 
 protected:
   enum GestureState {
     // There's no gesture going on, and we don't think we're about to enter one.
@@ -162,21 +158,14 @@ protected:
   MultiTouchInput mLastTouchInput;
 
   /**
    * Task used to timeout a double tap. This gets posted to the UI thread such
    * that it runs a short time after a single tap happens. We cache it so that
    * we can cancel it if a double tap actually comes in.
    */
   CancelableTask *mDoubleTapTimeoutTask;
-
-  /**
-   * Position of the last touch starting. This is only valid during an attempt
-   * to determine if a touch is a tap. This means that it is used in both the
-   * "GESTURE_WAITING_SINGLE_TAP" and "GESTURE_WAITING_DOUBLE_TAP" states.
-   */
-  nsIntPoint mTouchStartPosition;
 };
 
 }
 }
 
 #endif
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -18,23 +18,21 @@
 #include "nsMemory.h"
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 #include "gfx3DMatrix.h"
 #include "gfxColor.h"
 #include "gfxMatrix.h"
 #include "gfxPattern.h"
 #include "gfxPoint.h"
-#include "gfxRect.h"
 #include "nsRect.h"
 #include "nsRegion.h"
 #include "gfxASurface.h"
 #include "jsapi.h"
 #include "LayersTypes.h"
-#include "FrameMetrics.h"
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4800 )
 #endif
 
 #if !defined(OS_POSIX)
 // This condition must be kept in sync with the one in
 // ipc_message_utils.h, but this dummy definition of
@@ -515,38 +513,16 @@ struct ParamTraits<gfxSize>
         ReadParam(aMsg, aIter, &aResult->height))
       return true;
 
     return false;
   }
 };
 
 template<>
-struct ParamTraits<gfxRect>
-{
-  typedef gfxRect paramType;
-
-  static void Write(Message* aMsg, const paramType& aParam)
-  {
-    WriteParam(aMsg, aParam.x);
-    WriteParam(aMsg, aParam.y);
-    WriteParam(aMsg, aParam.width);
-    WriteParam(aMsg, aParam.height);
-  }
-
-  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
-  {
-    return ReadParam(aMsg, aIter, &aResult->x) &&
-           ReadParam(aMsg, aIter, &aResult->y) &&
-           ReadParam(aMsg, aIter, &aResult->width) &&
-           ReadParam(aMsg, aIter, &aResult->height);
-  }
-};
-
-template<>
 struct ParamTraits<gfx3DMatrix>
 {
   typedef gfx3DMatrix paramType;
 
   static void Write(Message* msg, const paramType& param)
   {
 #define Wr(_f)  WriteParam(msg, param. _f)
     Wr(_11); Wr(_12); Wr(_13); Wr(_14);
--- a/layout/ipc/PRenderFrame.ipdl
+++ b/layout/ipc/PRenderFrame.ipdl
@@ -36,18 +36,16 @@ parent:
      *
      * |id| is set to 0 in the "direct" case, and to a whole number
      * in the "indirect" case.
      */
     async PLayers();
 
     async NotifyCompositorTransaction();
 
-    async CancelDefaultPanZoom();
-
     async __delete__();
 
 state EMPTY_OR_DIRECT_COMPOSITOR:
     recv PLayers goto HAVE_CONTENT;
     recv NotifyCompositorTransaction goto EMPTY_OR_DIRECT_COMPOSITOR;
     recv __delete__;
 
 state HAVE_CONTENT:
--- a/layout/ipc/RenderFrameChild.cpp
+++ b/layout/ipc/RenderFrameChild.cpp
@@ -27,22 +27,16 @@ RenderFrameChild::Destroy()
     layers->Destroy();
     // |layers| was just deleted, take care
   }
 
   Send__delete__(this);
   // WARNING: |this| is dead, hands off
 }
 
-void
-RenderFrameChild::CancelDefaultPanZoom()
-{
-  SendCancelDefaultPanZoom();
-}
-
 PLayersChild*
 RenderFrameChild::AllocPLayers()
 {
   return new ShadowLayersChild();
 }
 
 bool
 RenderFrameChild::DeallocPLayers(PLayersChild* aLayers)
--- a/layout/ipc/RenderFrameChild.h
+++ b/layout/ipc/RenderFrameChild.h
@@ -14,18 +14,16 @@ namespace mozilla {
 namespace layout {
 
 class RenderFrameChild : public PRenderFrameChild
 {
 public:
   RenderFrameChild() {}
   virtual ~RenderFrameChild() {}
 
-  void CancelDefaultPanZoom();
-
   void Destroy();
 
 protected:
   virtual PLayersChild* AllocPLayers() MOZ_OVERRIDE;
   virtual bool DeallocPLayers(PLayersChild* aLayers) MOZ_OVERRIDE;
 };
 
 } // namespace layout
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -487,33 +487,16 @@ public:
       return;
     }
     if (mRenderFrame) {
       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
       browser->UpdateFrame(aFrameMetrics);
     }
   }
 
-  virtual void HandleDoubleTap(const nsIntPoint& aPoint) MOZ_OVERRIDE
-  {
-    if (MessageLoop::current() != mUILoop) {
-      // We have to send this message from the "UI thread" (main
-      // thread).
-      mUILoop->PostTask(
-        FROM_HERE,
-        NewRunnableMethod(this, &RemoteContentController::HandleDoubleTap,
-                          aPoint));
-      return;
-    }
-    if (mRenderFrame) {
-      TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
-      browser->HandleDoubleTap(aPoint);
-    }
-  }
-
   void ClearRenderFrame() { mRenderFrame = nullptr; }
 
 private:
   MessageLoop* mUILoop;
   RenderFrameParent* mRenderFrame;
 };
 
 RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
@@ -732,25 +715,16 @@ RenderFrameParent::ActorDestroy(ActorDes
 
 bool
 RenderFrameParent::RecvNotifyCompositorTransaction()
 {
   TriggerRepaint();
   return true;
 }
 
-bool
-RenderFrameParent::RecvCancelDefaultPanZoom()
-{
-  if (mPanZoomController) {
-    mPanZoomController->CancelDefaultPanZoom();
-  }
-  return true;
-}
-
 PLayersParent*
 RenderFrameParent::AllocPLayers()
 {
   if (!mFrameLoader || mFrameLoaderDestroyed) {
     return nullptr;
   }
   nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
   return new ShadowLayersParent(lm->AsShadowManager(), this, 0);
@@ -873,32 +847,16 @@ RenderFrameParent::BuildDisplayList(nsDi
   nsPoint offset = aFrame->GetOffsetToCrossDoc(aBuilder->ReferenceFrame());
   nsRect bounds = aFrame->EnsureInnerView()->GetBounds() + offset;
 
   return aLists.Content()->AppendNewToTop(
     new (aBuilder) nsDisplayClip(aBuilder, aFrame, &shadowTree,
                                  bounds));
 }
 
-void
-RenderFrameParent::NotifyDOMTouchListenerAdded()
-{
-  if (mPanZoomController) {
-    mPanZoomController->NotifyDOMTouchListenerAdded();
-  }
-}
-
-void
-RenderFrameParent::ZoomToRect(const gfxRect& aRect)
-{
-  if (mPanZoomController) {
-    mPanZoomController->ZoomToRect(aRect);
-  }
-}
-
 }  // namespace layout
 }  // namespace mozilla
 
 already_AddRefed<Layer>
 nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
                             LayerManager* aManager,
                             const ContainerParameters& aContainerParameters)
 {
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -88,27 +88,21 @@ public:
 
   void SetBackgroundColor(nscolor aColor) { mBackgroundColor = gfxRGBA(aColor); };
 
   void NotifyInputEvent(const nsInputEvent& aEvent,
                         nsInputEvent* aOutEvent);
 
   void NotifyDimensionsChanged(int width, int height);
 
-  void NotifyDOMTouchListenerAdded();
-
-  void ZoomToRect(const gfxRect& aRect);
-
 protected:
   void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
   virtual bool RecvNotifyCompositorTransaction() MOZ_OVERRIDE;
 
-  virtual bool RecvCancelDefaultPanZoom() MOZ_OVERRIDE;
-
   virtual PLayersParent* AllocPLayers() MOZ_OVERRIDE;
   virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE;
 
 private:
   void BuildViewMap();
   void TriggerRepaint();
   void DispatchEventForPanZoomController(const InputEvent& aEvent);