Backed out 6 changesets (bug 1415225) for frequently failing own gfx/layers/apz/test/mochitest/test_group_overrides.html on Windows. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 09 Nov 2017 11:59:04 +0200
changeset 390927 95985f660be18466ff7d4aa1c696e73cdebc3ef8
parent 390926 5bbbbcc79a5a750156eace4b70833848931ce63d
child 390928 5da4fb949bd215e7bca4b63acd76884e0b0208c0
push id32851
push userdluca@mozilla.com
push dateThu, 09 Nov 2017 13:54:04 +0000
treeherdermozilla-central@05ae89bebb64 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1415225
milestone58.0a1
backs out27403a9dec13a8d6c37b764782db51ca81ce9436
9e671058653199248a401a379f787fef0ccced89
8cfef302b7102e2953f61020a26c26313cebc4e4
8ae80d7421d5b01d9e6ef8a7ce1c62a2f0b71149
5f14fc545115a089e128579f7a37189d6cb99d61
4704645d4e81505c680c0238b72ff552c39a6b85
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
Backed out 6 changesets (bug 1415225) for frequently failing own gfx/layers/apz/test/mochitest/test_group_overrides.html on Windows. r=backout Backed out changeset 27403a9dec13 (bug 1415225) Backed out changeset 9e6710586531 (bug 1415225) Backed out changeset 8cfef302b710 (bug 1415225) Backed out changeset 8ae80d7421d5 (bug 1415225) Backed out changeset 5f14fc545115 (bug 1415225) Backed out changeset 4704645d4e81 (bug 1415225)
gfx/layers/LayerMetricsWrapper.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/LayersTypes.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/test/mochitest/helper_override_root.html
gfx/layers/apz/test/mochitest/helper_override_subdoc.html
gfx/layers/apz/test/mochitest/mochitest.ini
gfx/layers/apz/test/mochitest/test_group_overrides.html
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayersMessages.ipdlh
gfx/layers/wr/WebRenderCommandBuilder.cpp
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderScrollData.cpp
gfx/layers/wr/WebRenderScrollData.h
layout/base/nsLayoutUtils.cpp
layout/generic/nsFrame.cpp
layout/generic/nsSubDocumentFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/gfx/layers/LayerMetricsWrapper.h
+++ b/gfx/layers/LayerMetricsWrapper.h
@@ -399,18 +399,18 @@ public:
 
     return 1.0f;
   }
 
   EventRegionsOverride GetEventRegionsOverride() const
   {
     MOZ_ASSERT(IsValid());
 
-    if (mLayer->AsRefLayer()) {
-      return mLayer->AsRefLayer()->GetEventRegionsOverride();
+    if (mLayer->AsContainerLayer()) {
+      return mLayer->AsContainerLayer()->GetEventRegionsOverride();
     }
     return EventRegionsOverride::NoOverride;
   }
 
   const ScrollThumbData& GetScrollThumbData() const
   {
     MOZ_ASSERT(IsValid());
 
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -835,17 +835,18 @@ ContainerLayer::ContainerLayer(LayerMana
     mPreYScale(1.0f),
     mInheritedXScale(1.0f),
     mInheritedYScale(1.0f),
     mPresShellResolution(1.0f),
     mScaleToResolution(false),
     mUseIntermediateSurface(false),
     mSupportsComponentAlphaChildren(false),
     mMayHaveReadbackChild(false),
-    mChildrenChanged(false)
+    mChildrenChanged(false),
+    mEventRegionsOverride(EventRegionsOverride::NoOverride)
 {
 }
 
 ContainerLayer::~ContainerLayer()
 {
 }
 
 bool
@@ -1029,17 +1030,18 @@ ContainerLayer::RepositionChild(Layer* a
   return true;
 }
 
 void
 ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
 {
   aAttrs = ContainerLayerAttributes(mPreXScale, mPreYScale,
                                     mInheritedXScale, mInheritedYScale,
-                                    mPresShellResolution, mScaleToResolution);
+                                    mPresShellResolution, mScaleToResolution,
+                                    mEventRegionsOverride);
 }
 
 bool
 ContainerLayer::Creates3DContextWithExtendingChildren()
 {
   if (Extend3DContext()) {
     return false;
   }
@@ -2055,16 +2057,22 @@ ContainerLayer::PrintInfo(std::stringstr
     aStream << " [usesTmpSurf]";
   }
   if (1.0 != mPreXScale || 1.0 != mPreYScale) {
     aStream << nsPrintfCString(" [preScale=%g, %g]", mPreXScale, mPreYScale).get();
   }
   if (mScaleToResolution) {
     aStream << nsPrintfCString(" [presShellResolution=%g]", mPresShellResolution).get();
   }
+  if (mEventRegionsOverride & EventRegionsOverride::ForceDispatchToContent) {
+    aStream << " [force-dtc]";
+  }
+  if (mEventRegionsOverride & EventRegionsOverride::ForceEmptyHitRegion) {
+    aStream << " [force-ehr]";
+  }
 }
 
 void
 ContainerLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
 {
   Layer::DumpPacket(aPacket, aParent);
   // Get this layer data
   using namespace layerscope;
@@ -2231,22 +2239,16 @@ ImageLayer::DumpPacket(layerscope::Layer
 
 void
 RefLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   ContainerLayer::PrintInfo(aStream, aPrefix);
   if (0 != mId) {
     AppendToString(aStream, mId, " [id=", "]");
   }
-  if (mEventRegionsOverride & EventRegionsOverride::ForceDispatchToContent) {
-    aStream << " [force-dtc]";
-  }
-  if (mEventRegionsOverride & EventRegionsOverride::ForceEmptyHitRegion) {
-    aStream << " [force-ehr]";
-  }
 }
 
 void
 RefLayer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent)
 {
   Layer::DumpPacket(aPacket, aParent);
   // Get this layer data
   using namespace layerscope;
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -2310,16 +2310,30 @@ public:
    * content flag set.
    */
   static bool HasOpaqueAncestorLayer(Layer* aLayer);
 
   void SetChildrenChanged(bool aVal) {
     mChildrenChanged = aVal;
   }
 
+  void SetEventRegionsOverride(EventRegionsOverride aVal) {
+    if (mEventRegionsOverride == aVal) {
+      return;
+    }
+
+    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) EventRegionsOverride", this));
+    mEventRegionsOverride = aVal;
+    Mutated();
+  }
+
+  EventRegionsOverride GetEventRegionsOverride() const {
+    return mEventRegionsOverride;
+  }
+
   // If |aRect| is null, the entire layer should be considered invalid for
   // compositing.
   virtual void SetInvalidCompositeRect(const gfx::IntRect* aRect) {}
 
 protected:
   friend class ReadbackProcessor;
 
   // Note that this is not virtual, and is based on the implementation of
@@ -2399,16 +2413,17 @@ protected:
   // Whether the compositor should scale to mPresShellResolution.
   bool mScaleToResolution;
   bool mUseIntermediateSurface;
   bool mSupportsComponentAlphaChildren;
   bool mMayHaveReadbackChild;
   // This is updated by ComputeDifferences. This will be true if we need to invalidate
   // the intermediate surface.
   bool mChildrenChanged;
+  EventRegionsOverride mEventRegionsOverride;
 };
 
 /**
  * A generic layer that references back to its display item.
  *
  * In order to not throw away information early in the pipeline from layout -> webrender,
  * we'd like a generic layer type that can represent all the nsDisplayItems instead of
  * creating a new layer type for each nsDisplayItem for Webrender. Another option
@@ -2818,35 +2833,16 @@ public:
       return;
     }
 
     mFirstChild = mLastChild = aLayer;
     aLayer->SetParent(this);
   }
 
   /**
-   * CONSTRUCTION PHASE ONLY
-   * Set flags that indicate how event regions in the child layer tree need
-   * to be overridden because of properties of the parent layer tree.
-   */
-  void SetEventRegionsOverride(EventRegionsOverride aVal) {
-    if (mEventRegionsOverride == aVal) {
-      return;
-    }
-
-    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) EventRegionsOverride", this));
-    mEventRegionsOverride = aVal;
-    Mutated();
-  }
-
-  EventRegionsOverride GetEventRegionsOverride() const {
-    return mEventRegionsOverride;
-  }
-
-  /**
    * DRAWING PHASE ONLY
    * |aLayer| is the same as the argument to ConnectReferentLayer().
    */
   void DetachReferentLayer(Layer* aLayer)
   {
     mFirstChild = mLastChild = nullptr;
     aLayer->SetParent(nullptr);
   }
@@ -2860,28 +2856,25 @@ public:
    * DRAWING PHASE ONLY
    */
   virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) override;
 
   MOZ_LAYER_DECL_NAME("RefLayer", TYPE_REF)
 
 protected:
   RefLayer(LayerManager* aManager, void* aImplData)
-    : ContainerLayer(aManager, aImplData)
-    , mId(0)
-    , mEventRegionsOverride(EventRegionsOverride::NoOverride)
+    : ContainerLayer(aManager, aImplData) , mId(0)
   {}
 
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
 
   virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override;
 
   // 0 is a special value that means "no ID".
   uint64_t mId;
-  EventRegionsOverride mEventRegionsOverride;
 };
 
 void SetAntialiasingFlags(Layer* aLayer, gfx::DrawTarget* aTarget);
 
 #ifdef MOZ_DUMP_PAINTING
 void WriteSnapshotToDumpFile(Layer* aLayer, gfx::DataSourceSurface* aSurf);
 void WriteSnapshotToDumpFile(LayerManager* aManager, gfx::DataSourceSurface* aSurf);
 void WriteSnapshotToDumpFile(Compositor* aCompositor, gfx::DrawTarget* aTarget);
--- a/gfx/layers/LayersTypes.h
+++ b/gfx/layers/LayersTypes.h
@@ -198,17 +198,17 @@ struct EventRegions {
   {
     nsCString result = mHitRegion.ToString();
     result.AppendLiteral(";dispatchToContent=");
     result.Append(mDispatchToContentHitRegion.ToString());
     return result;
   }
 };
 
-// Bit flags that go on a RefLayer and override the
+// Bit flags that go on a ContainerLayer (or RefLayer) and override the
 // event regions in the entire subtree below. This is needed for propagating
 // various flags across processes since the child-process layout code doesn't
 // know about parent-process listeners or CSS rules.
 enum EventRegionsOverride {
   // The default, no flags set
   NoOverride             = 0,
   // Treat all hit regions in the subtree as dispatch-to-content
   ForceDispatchToContent = (1 << 0),
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -646,20 +646,16 @@ template<class ScrollNode> static EventR
 GetEventRegionsOverride(HitTestingTreeNode* aParent,
                        const ScrollNode& aLayer)
 {
   // Make it so that if the flag is set on the layer tree, it automatically
   // propagates to all the nodes in the corresponding subtree rooted at that
   // layer in the hit-test tree. This saves having to walk up the tree every
   // we want to see if a hit-test node is affected by this flag.
   EventRegionsOverride result = aLayer.GetEventRegionsOverride();
-  if (result != EventRegionsOverride::NoOverride) {
-    // Overrides should only ever get set for ref layers.
-    MOZ_ASSERT(aLayer.GetReferentId());
-  }
   if (aParent) {
     result |= aParent->GetEventRegionsOverride();
   }
   return result;
 }
 
 void
 APZCTreeManager::StartScrollbarDrag(const ScrollableLayerGuid& aGuid,
deleted file mode 100644
--- a/gfx/layers/apz/test/mochitest/helper_override_root.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <meta name="viewport" content="width=device-width; initial-scale=1.0">
-  <title>Simple wheel scroll cancellation</title>
-  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
-  <script type="application/javascript" src="apz_test_utils.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
-  <script type="application/javascript">
-
-// Add a non-passive listener on the document, so that we have a document-level
-// APZ-aware listener, and the entire document is put in the dispatch-to-content
-// region
-document.addEventListener('wheel', function(e) {
-    dump("Wheel listener running...\n");
-
-    // spin for 2 seconds to give APZ time to scroll, if the event region override
-    // is broken and it decides not to wait for the main thread. Note that it's
-    // possible the APZ controller thread is busy for whatever reason so APZ
-    // may not scroll. That might cause this test to only fail intermittently
-    // instead of consistently if the behaviour being tested regresses.
-    var now = Date.now();
-    while (Date.now() - now < 2000);
-
-    // Cancel the scroll. If this works then we know APZ waited for this listener
-    // to run.
-    e.preventDefault();
-
-    setTimeout(function() {
-        flushApzRepaints(checkScroll);
-    }, 0);
-}, false);
-
-function scrollPage() {
-  synthesizeNativeWheel(document.body, 100, 100, 0, -50);
-  dump("Finished native wheel, waiting for listener to run...\n");
-}
-
-function checkScroll() {
-  is(window.scrollY, 0, "check that the window didn't scroll");
-  subtestDone();
-}
-
-if (window.top != window) {
-    dump("Running inside an iframe! stealing functions from window.top...\n");
-    window.subtestDone = window.top.subtestDone;
-    window.SimpleTest = window.top.SimpleTest;
-    window.is = window.top.is;
-    window.ok = window.top.ok;
-}
-
-waitUntilApzStable().then(scrollPage);
-
-  </script>
-</head>
-<body style="height: 5000px; background-image: linear-gradient(green,red);">
-  This page should not be wheel-scrollable.
-</body>
-</html>
deleted file mode 100644
--- a/gfx/layers/apz/test/mochitest/helper_override_subdoc.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <meta name="viewport" content="width=device-width; initial-scale=1.0">
-  <title>Wheel scroll cancellation inside iframe</title>
-  <script type="application/javascript" src="apz_test_utils.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
-</head>
-<body>
-    This just loads helper_override_root in an iframe, so that we test event
-    regions overriding on in-process subdocuments.
-    <iframe src="helper_override_root.html"></iframe>
-</body>
-</html>
--- a/gfx/layers/apz/test/mochitest/mochitest.ini
+++ b/gfx/layers/apz/test/mochitest/mochitest.ini
@@ -16,18 +16,16 @@
     helper_div_pan.html
     helper_drag_click.html
     helper_drag_scroll.html
     helper_iframe_pan.html
     helper_iframe1.html
     helper_iframe2.html
     helper_key_scroll.html
     helper_long_tap.html
-    helper_override_root.html
-    helper_override_subdoc.html
     helper_scroll_inactive_perspective.html
     helper_scroll_inactive_zindex.html
     helper_scroll_on_position_fixed.html
     helper_scroll_over_scrollbar.html
     helper_scroll_tables_perspective.html
     helper_scrollto_tap.html
     helper_subframe_style.css
     helper_tall.html
@@ -69,10 +67,8 @@ skip-if = os == 'win' && os_version == '
 [test_scroll_subframe_scrollbar.html]
   skip-if = (os == 'android') # wheel events not supported on mobile
 [test_touch_listeners_impacting_wheel.html]
   skip-if = (toolkit == 'android') || (toolkit == 'cocoa') # wheel events not supported on mobile, and synthesized wheel smooth-scrolling not supported on OS X
 [test_wheel_scroll.html]
   skip-if = (os == 'android') # wheel events not supported on mobile
 [test_wheel_transactions.html]
   skip-if = (os == 'android') # wheel events not supported on mobile
-[test_group_overrides.html]
-  skip-if = (os == 'android') # wheel events not supported on mobile
deleted file mode 100644
--- a/gfx/layers/apz/test/mochitest/test_group_overrides.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Various tests for event regions overrides</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="apz_test_utils.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript">
-
-var prefs = [
-  // turn off smooth scrolling so that we don't have to wait for
-  // APZ animations to finish before sampling the scroll offset
-  ['general.smoothScroll', false],
-  // Increase the content response timeout because these tests do preventDefault
-  // and we want to make sure APZ actually waits for them.
-  ['apz.content_response_timeout', 10000],
-]
-
-var subtests = [
-  {'file': 'helper_override_root.html', 'prefs': prefs},
-  {'file': 'helper_override_subdoc.html', 'prefs': prefs},
-];
-
-if (isApzEnabled()) {
-  SimpleTest.waitForExplicitFinish();
-  window.onload = function() {
-    runSubtestsSeriallyInFreshWindows(subtests)
-    .then(SimpleTest.finish);
-  };
-}
-
-  </script>
-</head>
-<body>
-</body>
-</html>
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -604,16 +604,20 @@ LayerTransactionParent::SetLayerAttribut
       return false;
     }
     const ContainerLayerAttributes& attrs =
       specific.get_ContainerLayerAttributes();
     containerLayer->SetPreScale(attrs.preXScale(), attrs.preYScale());
     containerLayer->SetInheritedScale(attrs.inheritedXScale(), attrs.inheritedYScale());
     containerLayer->SetScaleToResolution(attrs.scaleToResolution(),
                                          attrs.presShellResolution());
+    if (attrs.eventRegionsOverride() != containerLayer->GetEventRegionsOverride()) {
+      UpdateHitTestingTree(layer, "event regions override changed");
+      containerLayer->SetEventRegionsOverride(attrs.eventRegionsOverride());
+    }
     break;
   }
   case Specific::TColorLayerAttributes: {
     MOZ_LAYERS_LOG(("[ParentSide]   color layer"));
 
     ColorLayer* colorLayer = layer->AsColorLayer();
     if (!colorLayer) {
       return false;
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -282,31 +282,34 @@ struct PaintedLayerAttributes {
 };
 struct ContainerLayerAttributes {
   float preXScale;
   float preYScale;
   float inheritedXScale;
   float inheritedYScale;
   float presShellResolution;
   bool scaleToResolution;
+  EventRegionsOverride eventRegionsOverride;
 };
 
 struct GlyphArray
 {
   LayerColor color;
   Glyph[] glyphs;
 };
 
 // XXX - Bas - Hack warning! This is using a raw pointer to a ScaledFont*
 // and won't work with e10s.
 struct TextLayerAttributes      { IntRect bounds; GlyphArray[] glyphs; uintptr_t scaledFont; };
 struct ColorLayerAttributes     { LayerColor color; IntRect bounds; };
 struct CanvasLayerAttributes    { SamplingFilter samplingFilter; IntRect bounds; };
 struct RefLayerAttributes {
   uint64_t id;
+  // TODO: Once bug 1132895 is fixed we shouldn't need to propagate the override
+  // explicitly here.
   EventRegionsOverride eventRegionsOverride;
 };
 struct ImageLayerAttributes     { SamplingFilter samplingFilter; IntSize scaleToSize; ScaleMode scaleMode; };
 struct BorderLayerAttributes {
   LayerRect rect;
   BorderColors colors;
   BorderCorners corners;
   BorderWidths widths;
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -75,16 +75,22 @@ WebRenderCommandBuilder::BuildWebRenderC
       StackingContextHelper pageRootSc(sc, aBuilder);
       CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder,
                                              pageRootSc, aBuilder, aResourceUpdates);
     }
 
     // Make a "root" layer data that has everything else as descendants
     mLayerScrollData.emplace_back();
     mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
+    if (aDisplayListBuilder->IsBuildingLayerEventRegions()) {
+      nsIPresShell* shell = aDisplayListBuilder->RootReferenceFrame()->PresContext()->PresShell();
+      if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(shell)) {
+        mLayerScrollData.back().SetEventRegionsOverride(EventRegionsOverride::ForceDispatchToContent);
+      }
+    }
     auto callback = [&aScrollData](FrameMetrics::ViewID aScrollId) -> bool {
       return aScrollData.HasMetadataFor(aScrollId);
     };
     if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
           aDisplayListBuilder, mManager, ContainerLayerParameters(), callback)) {
       mLayerScrollData.back().AppendScrollMetadata(aScrollData, rootMetadata.ref());
     }
     // Append the WebRenderLayerScrollData items into WebRenderScrollData
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -220,16 +220,34 @@ WebRenderLayerManager::EndEmptyTransacti
   }
 
   WrBridge()->EndEmptyTransaction(mFocusTarget, mLatestTransactionId, transactionStart);
 
   MakeSnapshotIfRequired(size);
   return true;
 }
 
+/*static*/ int32_t
+PopulateScrollData(WebRenderScrollData& aTarget, Layer* aLayer)
+{
+  MOZ_ASSERT(aLayer);
+
+  // We want to allocate a WebRenderLayerScrollData object for this layer,
+  // but don't keep a pointer to it since it might get memmove'd during the
+  // recursion below. Instead keep the index and get the pointer later.
+  size_t index = aTarget.AddNewLayerData();
+
+  int32_t descendants = 0;
+  for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
+    descendants += PopulateScrollData(aTarget, child);
+  }
+  aTarget.GetLayerDataMutable(index)->Initialize(aTarget, aLayer, descendants);
+  return descendants + 1;
+}
+
 void
 WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
                                       void* aCallbackData,
                                       EndTransactionFlags aFlags)
 {
   // This should never get called, all callers should use
   // EndTransactionWithoutLayer instead.
   MOZ_ASSERT(false);
--- a/gfx/layers/wr/WebRenderScrollData.cpp
+++ b/gfx/layers/wr/WebRenderScrollData.cpp
@@ -28,16 +28,47 @@ WebRenderLayerScrollData::WebRenderLayer
 {
 }
 
 WebRenderLayerScrollData::~WebRenderLayerScrollData()
 {
 }
 
 void
+WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
+                                     Layer* aLayer,
+                                     int32_t aDescendantCount)
+{
+  MOZ_ASSERT(aDescendantCount >= 0); // Ensure value is valid
+  MOZ_ASSERT(mDescendantCount == -1); // Don't allow re-setting an already set value
+  mDescendantCount = aDescendantCount;
+
+  MOZ_ASSERT(aLayer);
+  for (uint32_t i = 0; i < aLayer->GetScrollMetadataCount(); i++) {
+    mScrollIds.AppendElement(aOwner.AddMetadata(aLayer->GetScrollMetadata(i)));
+  }
+
+  mTransform = aLayer->GetTransform();
+  mTransformIsPerspective = aLayer->GetTransformIsPerspective();
+  mEventRegions = aLayer->GetEventRegions();
+  mVisibleRegion = aLayer->GetVisibleRegion();
+  mReferentId = aLayer->AsRefLayer()
+      ? Some(aLayer->AsRefLayer()->GetReferentId())
+      : Nothing();
+  mEventRegionsOverride = aLayer->AsContainerLayer()
+      ? aLayer->AsContainerLayer()->GetEventRegionsOverride()
+      : EventRegionsOverride::NoOverride;
+  mScrollThumbData = aLayer->GetScrollThumbData();
+  mScrollbarAnimationId = aLayer->GetCompositorAnimationsId();
+  mScrollbarTargetContainerId = aLayer->GetScrollbarTargetContainerId();
+  mIsScrollbarContainer = aLayer->IsScrollbarContainer();
+  mFixedPosScrollContainerId = aLayer->GetFixedPositionScrollContainerId();
+}
+
+void
 WebRenderLayerScrollData::InitializeRoot(int32_t aDescendantCount)
 {
   mDescendantCount = aDescendantCount;
 }
 
 void
 WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
                                      nsDisplayItem* aItem,
--- a/gfx/layers/wr/WebRenderScrollData.h
+++ b/gfx/layers/wr/WebRenderScrollData.h
@@ -37,16 +37,22 @@ class WebRenderScrollData;
 // Each WebRenderLayerScrollData is conceptually associated with an "owning"
 // WebRenderScrollData.
 class WebRenderLayerScrollData
 {
 public:
   WebRenderLayerScrollData(); // needed for IPC purposes
   ~WebRenderLayerScrollData();
 
+  // Actually initialize the object. This is not done during the constructor
+  // for optimization purposes (the call site is hard to write efficiently
+  // if we do this in the constructor).
+  void Initialize(WebRenderScrollData& aOwner,
+                  Layer* aLayer,
+                  int32_t aDescendantCount);
   void InitializeRoot(int32_t aDescendantCount);
   void Initialize(WebRenderScrollData& aOwner,
                   nsDisplayItem* aItem,
                   int32_t aDescendantCount,
                   const ActiveScrolledRoot* aStopAtAsr);
 
   int32_t GetDescendantCount() const;
   size_t GetScrollMetadataCount() const;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3776,19 +3776,16 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
           id = nsLayoutUtils::FindOrCreateIDFor(element);
         }
       }
 
       nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(&builder, id);
 
       builder.SetVisibleRect(visibleRect);
       builder.SetIsBuilding(true);
-      builder.SetAncestorHasApzAwareEventHandler(
-          builder.IsBuildingLayerEventRegions() &&
-          nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell));
 
       const bool paintedPreviously =
         aFrame->HasProperty(nsIFrame::ModifiedFrameList());
 
       // Attempt to do a partial build and merge into the existing list.
       // This calls BuildDisplayListForStacking context on a subset of the
       // viewport.
       bool merged = false;
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2523,20 +2523,16 @@ public:
   ~AutoSaveRestoreContainsBlendMode() {
     mBuilder.SetContainsBlendMode(mSavedContainsBlendMode);
   }
 };
 
 static void
 CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
 {
-  if (aBuilder->GetAncestorHasApzAwareEventHandler()) {
-    return;
-  }
-
   nsIContent* content = aFrame->GetContent();
   if (!content) {
     return;
   }
 
   if (content->IsNodeApzAware()) {
     aBuilder->SetAncestorHasApzAwareEventHandler(true);
   }
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -442,16 +442,22 @@ nsSubDocumentFrame::BuildDisplayList(nsD
       constructZoomItem ||
       haveDisplayPort ||
       presContext->IsRootContentDocument() ||
       (sf && sf->IsScrollingActive(aBuilder)))
   {
     needsOwnLayer = true;
   }
 
+  if (!needsOwnLayer && aBuilder->IsBuildingLayerEventRegions() &&
+      nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell))
+  {
+    needsOwnLayer = true;
+  }
+
   if (aBuilder->IsRetainingDisplayList()) {
     // The value of needsOwnLayer can change between builds without
     // an invalidation recorded for this frame (like if the root
     // scrollframe becomes active). If this happens,
     // then we need to notify the builder so that merging can
     // happen correctly.
     if (!mPreviouslyNeededLayer ||
         mPreviouslyNeededLayer.value() != needsOwnLayer) {
@@ -494,21 +500,17 @@ nsSubDocumentFrame::BuildDisplayList(nsD
     if (subdocRootFrame) {
       nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
       nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(
           aBuilder,
           ignoreViewportScrolling && rootScrollFrame && rootScrollFrame->GetContent()
               ? nsLayoutUtils::FindOrCreateIDFor(rootScrollFrame->GetContent())
               : aBuilder->GetCurrentScrollParentId());
 
-      bool hasDocumentLevelListenersForApzAwareEvents =
-          aBuilder->IsBuildingLayerEventRegions() &&
-          nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell);
-
-      aBuilder->SetAncestorHasApzAwareEventHandler(hasDocumentLevelListenersForApzAwareEvents);
+      aBuilder->SetAncestorHasApzAwareEventHandler(false);
       subdocRootFrame->
         BuildDisplayListForStackingContext(aBuilder, &childItems);
     }
 
     if (!aBuilder->IsForEventDelivery()) {
       // If we are going to use a displayzoom below then any items we put under
       // it need to have underlying frames from the subdocument. So we need to
       // calculate the bounds based on which frame will be the underlying frame
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -369,18 +369,18 @@ nsDisplayRemote::nsDisplayRemote(nsDispl
 }
 
 already_AddRefed<Layer>
 nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
                             LayerManager* aManager,
                             const ContainerLayerParameters& aContainerParameters)
 {
   RefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, this, aContainerParameters);
-  if (layer && layer->AsRefLayer()) {
-    layer->AsRefLayer()->SetEventRegionsOverride(mEventRegionsOverride);
+  if (layer && layer->AsContainerLayer()) {
+    layer->AsContainerLayer()->SetEventRegionsOverride(mEventRegionsOverride);
   }
   return layer.forget();
 }
 
 bool
 nsDisplayRemote::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                          mozilla::wr::IpcResourceUpdateQueue& aResources,
                                          const StackingContextHelper& aSc,
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2476,16 +2476,22 @@ already_AddRefed<LayerManager> nsDisplay
       layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
       return nullptr;
     }
     // Root is being scaled up by the X/Y resolution. Scale it back down.
     root->SetPostScale(1.0f/containerParameters.mXScale,
                        1.0f/containerParameters.mYScale);
     root->SetScaleToResolution(presShell->ScaleToResolution(),
         containerParameters.mXScale);
+    if (aBuilder->IsBuildingLayerEventRegions() &&
+        nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(presShell)) {
+      root->SetEventRegionsOverride(EventRegionsOverride::ForceDispatchToContent);
+    } else {
+      root->SetEventRegionsOverride(EventRegionsOverride::NoOverride);
+    }
 
     auto callback = [root](FrameMetrics::ViewID aScrollId) -> bool {
       return nsLayoutUtils::ContainsMetricsWithId(root, aScrollId);
     };
     if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
           aBuilder, root->Manager(), containerParameters, callback)) {
       root->SetScrollMetadata(rootMetadata.value());
     }
@@ -6850,31 +6856,45 @@ nsDisplaySubDocument::nsDisplaySubDocume
                                            nsSubDocumentFrame* aSubDocFrame,
                                            nsDisplayList* aList, uint32_t aFlags)
     : nsDisplayOwnLayer(aBuilder, aFrame, aList, aBuilder->CurrentActiveScrolledRoot(), aFlags)
     , mScrollParentId(aBuilder->GetCurrentScrollParentId())
     , mShouldFlatten(false)
     , mSubDocFrame(aSubDocFrame)
 {
   MOZ_COUNT_CTOR(nsDisplaySubDocument);
+  mForceDispatchToContentRegion =
+    aBuilder->IsBuildingLayerEventRegions() &&
+    nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresContext()->PresShell());
 
   // The SubDocument display item is conceptually outside the viewport frame,
   // so in cases where the viewport frame is an AGR, the SubDocument's AGR
   // should be not the viewport frame itself, but its parent AGR.
   if (*mAnimatedGeometryRoot == mFrame && mAnimatedGeometryRoot->mParentAGR) {
     mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
   }
 }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
 nsDisplaySubDocument::~nsDisplaySubDocument() {
   MOZ_COUNT_DTOR(nsDisplaySubDocument);
 }
 #endif
 
+already_AddRefed<Layer>
+nsDisplaySubDocument::BuildLayer(nsDisplayListBuilder* aBuilder,
+                                 LayerManager* aManager,
+                                 const ContainerLayerParameters& aContainerParameters) {
+  RefPtr<Layer> layer = nsDisplayOwnLayer::BuildLayer(aBuilder, aManager, aContainerParameters);
+  layer->AsContainerLayer()->SetEventRegionsOverride(mForceDispatchToContentRegion
+    ? EventRegionsOverride::ForceDispatchToContent
+    : EventRegionsOverride::NoOverride);
+  return layer.forget();
+}
+
 UniquePtr<ScrollMetadata>
 nsDisplaySubDocument::ComputeScrollMetadata(LayerManager* aLayerManager,
                                             const ContainerLayerParameters& aContainerParameters)
 {
   if (!(mFlags & GENERATE_SCROLLABLE_LAYER)) {
     return UniquePtr<ScrollMetadata>(nullptr);
   }
 
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -696,17 +696,17 @@ public:
   }
   bool IsBuildingLayerEventRegions();
   static bool LayerEventRegionsEnabled();
   bool IsInsidePointerEventsNoneDoc()
   {
     return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
   }
 
-  bool GetAncestorHasApzAwareEventHandler() const { return mAncestorHasApzAwareEventHandler; }
+  bool GetAncestorHasApzAwareEventHandler() { return mAncestorHasApzAwareEventHandler; }
   void SetAncestorHasApzAwareEventHandler(bool aValue)
   {
     mAncestorHasApzAwareEventHandler = aValue;
   }
 
   bool HaveScrollableDisplayPort() const { return mHaveScrollableDisplayPort; }
   void SetHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = true; }
   void ClearHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = false; }
@@ -5106,16 +5106,20 @@ class nsDisplaySubDocument : public nsDi
 public:
   nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
                        nsIFrame* aFrame, nsSubDocumentFrame* aSubDocFrame,
                        nsDisplayList* aList, uint32_t aFlags);
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplaySubDocument();
 #endif
 
+  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
+                                             LayerManager* aManager,
+                                             const ContainerLayerParameters& aContainerParameters) override;
+
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
                            bool* aSnap) const override;
 
   virtual nsSubDocumentFrame* SubDocumentFrame() { return mSubDocFrame; }
 
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                  nsRegion* aVisibleRegion) override;