[WIP] Bug 1259781 - Apply the APZ callback transform of relevant scroll frames in GetEventCoordinatesRelativeTo(), rather than applying them all at once in APZCCallbackHelper draft
authorBotond Ballo <botond@mozilla.com>
Mon, 06 Jun 2016 18:47:26 -0400
changeset 375932 fc8a7290125c6dc5281cdca91d5795984be60069
parent 375931 ec5189e224d229d2695fcd3c8dd7527e45259b44
child 523008 ea2bfbd85dfe7153e0ddbaaf4917f341e452657c
push id20424
push userbballo@mozilla.com
push dateMon, 06 Jun 2016 22:48:26 +0000
bugs1259781
milestone49.0a1
[WIP] Bug 1259781 - Apply the APZ callback transform of relevant scroll frames in GetEventCoordinatesRelativeTo(), rather than applying them all at once in APZCCallbackHelper MozReview-Commit-ID: Fd37ALA1nLh
gfx/layers/apz/util/APZCCallbackHelper.cpp
layout/generic/nsFrame.cpp
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -391,52 +391,16 @@ APZCCallbackHelper::ApplyCallbackTransfo
     // resolution to cancel the scale-to-resolution transform that the
     // compositor adds to the layer with the pres shell resolution. The points
     // sent to Gecko by APZ don't have this transform unapplied (unlike other
     // compositor-side transforms) because APZ doesn't know about it.
     if (nsIPresShell* shell = GetRootDocumentPresShell(content)) {
         input = input / shell->GetResolution();
     }
 
-    // This represents any resolution on the Root Content Document (RCD)
-    // that's not on the Root Document (RD). That is, on platforms where
-    // RCD == RD, it's 1, and on platforms where RCD != RD, it's the RCD
-    // resolution. 'input' has this resolution applied, but the scroll
-    // deltas retrieved below do not, so we need to apply them to the
-    // deltas before adding the deltas to 'input'. (Technically, deltas
-    // from scroll frames outside the RCD would already have this
-    // resolution applied, but we don't have such scroll frames in
-    // practice.)
-    float nonRootResolution = 1.0f;
-    if (nsIPresShell* shell = GetRootContentDocumentPresShellForContent(content)) {
-      nonRootResolution = shell->GetCumulativeNonRootScaleResolution();
-    }
-    // Now apply the callback-transform.
-    // XXX: Walk up the frame tree from the frame of this content element
-    // to the root of the frame tree, and apply any apzCallbackTransform
-    // found on the way. This is only approximately correct, as it does
-    // not take into account CSS transforms, nor differences in structure between
-    // the frame tree (which determines the transforms we're applying)
-    // and the layer tree (which determines the transforms we *want* to
-    // apply).
-    nsIFrame* frame = content->GetPrimaryFrame();
-    nsCOMPtr<nsIContent> lastContent;
-    while (frame) {
-        if (content && (content != lastContent)) {
-            void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
-            if (property) {
-                CSSPoint delta = (*static_cast<CSSPoint*>(property));
-                delta = delta * nonRootResolution;
-                input += delta;
-            }
-        }
-        frame = frame->GetParent();
-        lastContent = content;
-        content = frame ? frame->GetContent() : nullptr;
-    }
     return input;
 }
 
 LayoutDeviceIntPoint
 APZCCallbackHelper::ApplyCallbackTransform(const LayoutDeviceIntPoint& aPoint,
                                            const ScrollableLayerGuid& aGuid,
                                            const CSSToLayoutDeviceScale& aScale)
 {
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -5224,18 +5224,29 @@ nsIFrame::GetOffsetToCrossDoc(const nsIF
 
   const nsIFrame* root = nullptr;
   // offset will hold the final offset
   // docOffset holds the currently accumulated offset at the current APD, it
   // will be converted and added to offset when the current APD changes.
   nsPoint offset(0, 0), docOffset(0, 0);
   const nsIFrame* f = this;
   int32_t currAPD = PresContext()->AppUnitsPerDevPixel();
+  nsCOMPtr<nsIContent> lastContent;
   while (f && f != aOther) {
     docOffset += f->GetPosition();
+    if (nsIContent* content = f->GetContent()) {
+      if (content != lastContent) {
+        void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
+        if (property) {
+          CSSPoint delta = (*static_cast<CSSPoint*>(property));
+          docOffset += CSSPoint::ToAppUnits(delta);
+        }
+        lastContent = content;
+      }
+    }
     nsIFrame* parent = f->GetParent();
     if (parent) {
       f = parent;
     } else {
       nsPoint newOffset(0, 0);
       root = f;
       f = nsLayoutUtils::GetCrossDocParentFrame(f, &newOffset);
       int32_t newAPD = f ? f->PresContext()->AppUnitsPerDevPixel() : 0;