Back out 530555a2d6d4 (bug 1162064) for debug b2g emulator assertions and failure to thrive
authorPhil Ringnalda <philringnalda@gmail.com>
Sun, 17 May 2015 22:42:05 -0700
changeset 244267 4604104f73a8af6c4fb30d832bf4ad4dc4eac7ae
parent 244266 f399909af71125624418049e90b61e9f84295d85
child 244268 cb3a80b78c0b29b0e640791f69d33bb5df9b28f7
push id59887
push userphilringnalda@gmail.com
push dateMon, 18 May 2015 05:42:24 +0000
treeherdermozilla-inbound@4604104f73a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1162064
milestone41.0a1
backs out530555a2d6d4db1d8606cae069ad8bf27402e8f4
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
Back out 530555a2d6d4 (bug 1162064) for debug b2g emulator assertions and failure to thrive CLOSED TREE
docshell/base/nsDocShell.cpp
dom/base/nsDOMWindowUtils.cpp
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
gfx/layers/Layers.h
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
gfx/layers/client/ClientTiledPaintedLayer.cpp
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/composite/LayerManagerComposite.h
gfx/layers/ipc/CompositorParent.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPrefs.h
image/ImageFactory.cpp
layout/base/AccessibleCaretEventHub.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/SelectionCarets.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresShell.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
layout/tools/reftest/reftest.js
widget/PuppetWidget.cpp
widget/PuppetWidget.h
widget/nsBaseWidget.cpp
widget/nsBaseWidget.h
widget/nsIWidget.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -13853,24 +13853,17 @@ nsDocShell::GetAppManifestURL(nsAString&
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetAsyncPanZoomEnabled(bool* aOut)
 {
-  if (nsIPresShell* presShell = GetPresShell()) {
-    if (layers::LayerManager* lm = presShell->GetLayerManager()) {
-      *aOut = lm->AsyncPanZoomEnabled();
-      return NS_OK;
-    }
-  }
-
-  *aOut = false;
+  *aOut = Preferences::GetBool("layers.async-pan-zoom.enabled", false);
   return NS_OK;
 }
 
 bool
 nsDocShell::HasUnloadedParent()
 {
   nsRefPtr<nsDocShell> parent = GetParentDocshell();
   while (parent) {
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -370,22 +370,19 @@ nsDOMWindowUtils::SetDisplayPortForEleme
                      nsPresContext::CSSPixelsToAppUnits(aYPx),
                      nsPresContext::CSSPixelsToAppUnits(aWidthPx),
                      nsPresContext::CSSPixelsToAppUnits(aHeightPx));
 
   content->SetProperty(nsGkAtoms::DisplayPort,
                        new DisplayPortPropertyData(displayport, aPriority),
                        nsINode::DeleteProperty<DisplayPortPropertyData>);
 
-  if (gfxPrefs::LayoutUseContainersForRootFrames()) {
+  if (nsLayoutUtils::UsesAsyncScrolling() && gfxPrefs::LayoutUseContainersForRootFrames()) {
     nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
-    if (rootScrollFrame &&
-        content == rootScrollFrame->GetContent() &&
-        nsLayoutUtils::UsesAsyncScrolling(rootScrollFrame))
-    {
+    if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
       // We are setting a root displayport for a document.
       // The pres shell needs a special flag set.
       presShell->SetIgnoreViewportScrolling(true);
     }
   }
 
   nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
   if (rootFrame) {
@@ -856,17 +853,17 @@ nsDOMWindowUtils::SendWheelEvent(float a
 
   nsPresContext* presContext = GetPresContext();
   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
 
   wheelEvent.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
 
   widget->DispatchAPZAwareEvent(&wheelEvent);
 
-  if (widget->AsyncPanZoomEnabled()) {
+  if (gfxPrefs::AsyncPanZoomEnabled()) {
     // Computing overflow deltas is not compatible with APZ, so if APZ is
     // enabled, we skip testing it.
     return NS_OK;
   }
 
   bool failedX = false;
   if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
       wheelEvent.overflowDeltaX != 0) {
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -510,18 +510,17 @@ parent:
      * sent to the compositor and are ready to be shown on the next composite.
      * @see PCompositor
      * @see RequestNotifyAfterRemotePaint
      */
     async RemotePaintIsReady();
 
     sync GetRenderFrameInfo(PRenderFrame aRenderFrame)
         returns (TextureFactoryIdentifier textureFactoryIdentifier,
-                 uint64_t layersId,
-                 bool asyncPanZoomEnabled);
+                 uint64_t layersId);
 
     /**
      * Sent by the child to the parent to inform it that an update to the
      * dimensions has been requested, likely through win.moveTo or resizeTo
      */
     async SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY, int32_t aCx, int32_t aCy);
 
     prio(high) sync DispatchWheelEvent(WidgetWheelEvent event);
@@ -541,18 +540,17 @@ child:
      * content processes always render to a virtual <0, 0> top-left
      * point.
      */
     Show(ScreenIntSize size,
          ShowInfo info,
          TextureFactoryIdentifier textureFactoryIdentifier,
          uint64_t layersId,
          nullable PRenderFrame renderFrame,
-         bool parentIsActive,
-         bool asyncPanZoomEnabled);
+         bool parentIsActive);
 
     LoadURL(nsCString uri, BrowserConfiguration config);
 
     CacheFileDescriptor(nsString path, FileDescriptor fd);
 
     UpdateDimensions(IntRect rect, ScreenIntSize size, ScreenOrientation orientation,
                      LayoutDeviceIntPoint chromeDisp) compressall;
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -263,18 +263,17 @@ CSSToScreenScale ConvertScaleForRoot(CSS
 }
 CSSToParentLayerScale ConvertScaleForRoot(CSSToScreenScale aScale) {
   return ViewTargetAs<ParentLayerPixel>(aScale, PixelCastJustification::ScreenIsParentLayerForRoot);
 }
 
 bool
 TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
 {
-  nsIWidget* widget = WebWidget();
-  if (!widget || !widget->AsyncPanZoomEnabled()) {
+  if (!gfxPrefs::AsyncPanZoomEnabled()) {
     return false;
   }
 
   TABC_LOG("HandlePossibleViewportChange aOldScreenSize=%s mInnerSize=%s\n",
     Stringify(aOldScreenSize).c_str(), Stringify(mInnerSize).c_str());
 
   nsCOMPtr<nsIDocument> document(GetDocument());
   if (!document) {
@@ -871,17 +870,16 @@ TabChild::TabChild(nsIContentChild* aMan
   , mSetAllowedTouchBehaviorCallback(new TabChildSetAllowedTouchBehaviorCallback(this))
   , mHasValidInnerSize(false)
   , mDestroyed(false)
   , mUniqueId(aTabId)
   , mDPI(0)
   , mDefaultScale(0)
   , mIPCOpen(true)
   , mParentIsActive(false)
-  , mAsyncPanZoomEnabled(false)
 {
   // preloaded TabChild should not be added to child map
   if (mUniqueId) {
     MOZ_ASSERT(NestedTabChildMap().find(mUniqueId) == NestedTabChildMap().end());
     NestedTabChildMap()[mUniqueId] = this;
   }
 }
 
@@ -918,17 +916,17 @@ TabChild::Observe(nsISupports *aSubject,
         CSSRect rect;
         sscanf(NS_ConvertUTF16toUTF8(aData).get(),
                "{\"x\":%f,\"y\":%f,\"w\":%f,\"h\":%f}",
                &rect.x, &rect.y, &rect.width, &rect.height);
         SendZoomToRect(presShellId, viewId, rect);
       }
     }
   } else if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) {
-    if (AsyncPanZoomEnabled()) {
+    if (gfxPrefs::AsyncPanZoomEnabled()) {
       nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
       nsCOMPtr<nsIDocument> doc(GetDocument());
 
       if (SameCOMIdentity(subject, doc)) {
         nsCOMPtr<nsIPresShell> shell(doc->GetShell());
         if (shell) {
           shell->SetIsFirstPaint(true);
         }
@@ -976,17 +974,17 @@ TabChild::OnProgressChange(nsIWebProgres
 }
 
 NS_IMETHODIMP
 TabChild::OnLocationChange(nsIWebProgress* aWebProgress,
                            nsIRequest* aRequest,
                            nsIURI *aLocation,
                            uint32_t aFlags)
 {
-  if (!AsyncPanZoomEnabled()) {
+  if (!gfxPrefs::AsyncPanZoomEnabled()) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMWindow> window;
   aWebProgress->GetDOMWindow(getter_AddRefs(window));
   if (!window) {
     return NS_OK;
   }
@@ -1534,30 +1532,27 @@ TabChild::ProvideWindowCommon(nsIDOMWind
   if (!*aWindowIsNew) {
     PBrowserChild::Send__delete__(newChild);
     return NS_ERROR_ABORT;
   }
 
   TextureFactoryIdentifier textureFactoryIdentifier;
   uint64_t layersId = 0;
   PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
-  bool asyncPanZoomEnabled = false;
   newChild->SendGetRenderFrameInfo(renderFrame,
                                    &textureFactoryIdentifier,
-                                   &layersId,
-                                   &asyncPanZoomEnabled);
+                                   &layersId);
   if (layersId == 0) { // if renderFrame is invalid.
     PRenderFrameChild::Send__delete__(renderFrame);
     renderFrame = nullptr;
   }
 
   // Unfortunately we don't get a window unless we've shown the frame.  That's
   // pretty bogus; see bug 763602.
-  newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame,
-                       asyncPanZoomEnabled);
+  newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame);
 
   for (size_t i = 0; i < frameScripts.Length(); i++) {
     FrameScriptInfo& info = frameScripts[i];
     if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
       MOZ_CRASH();
     }
   }
 
@@ -1875,22 +1870,21 @@ TabChild::CancelCachedFileDescriptorCall
 
     // Set this flag so that we will close the file descriptor when it arrives.
     info->mCanceled = true;
 }
 
 void
 TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                      const uint64_t& aLayersId,
-                     PRenderFrameChild* aRenderFrame,
-                     bool aAsyncPanZoomEnabled)
+                     PRenderFrameChild* aRenderFrame)
 {
   ShowInfo info(EmptyString(), false, false, 0, 0);
   RecvShow(ScreenIntSize(0, 0), info, aTextureFactoryIdentifier,
-           aLayersId, aRenderFrame, mParentIsActive, aAsyncPanZoomEnabled);
+           aLayersId, aRenderFrame, mParentIsActive);
   mDidFakeShow = true;
 }
 
 void
 TabChild::ApplyShowInfo(const ShowInfo& aInfo)
 {
   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
   if (docShell) {
@@ -1982,18 +1976,17 @@ TabChild::MaybeRequestPreinitCamera()
 #endif
 
 bool
 TabChild::RecvShow(const ScreenIntSize& aSize,
                    const ShowInfo& aInfo,
                    const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                    const uint64_t& aLayersId,
                    PRenderFrameChild* aRenderFrame,
-                   const bool& aParentIsActive,
-                   const bool& aAsyncPanZoomEnabled)
+                   const bool& aParentIsActive)
 {
     MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
 
     if (mDidFakeShow) {
         ApplyShowInfo(aInfo);
         RecvParentActivated(aParentIsActive);
         return true;
     }
@@ -2016,18 +2009,16 @@ TabChild::RecvShow(const ScreenIntSize& 
 
 #ifdef MOZ_WIDGET_GONK
     MaybeRequestPreinitCamera();
 #endif
 
     bool res = InitTabChildGlobal();
     ApplyShowInfo(aInfo);
     RecvParentActivated(aParentIsActive);
-
-    mAsyncPanZoomEnabled = aAsyncPanZoomEnabled;
     return res;
 }
 
 bool
 TabChild::RecvUpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size,
                                const ScreenOrientation& orientation, const LayoutDeviceIntPoint& chromeDisp)
 {
     if (!mRemoteFrame) {
@@ -2203,27 +2194,27 @@ TabChild::RecvRealMouseButtonEvent(const
   return true;
 }
 
 bool
 TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
                               const ScrollableLayerGuid& aGuid,
                               const uint64_t& aInputBlockId)
 {
-  if (AsyncPanZoomEnabled()) {
+  if (gfxPrefs::AsyncPanZoomEnabled()) {
     nsCOMPtr<nsIDocument> document(GetDocument());
     APZCCallbackHelper::SendSetTargetAPZCNotification(WebWidget(), document, aEvent, aGuid,
         aInputBlockId);
   }
 
   WidgetWheelEvent event(aEvent);
   event.widget = mWidget;
   APZCCallbackHelper::DispatchWidgetEvent(event);
 
-  if (AsyncPanZoomEnabled()) {
+  if (gfxPrefs::AsyncPanZoomEnabled()) {
     mAPZEventState->ProcessWheelEvent(event, aGuid, aInputBlockId);
   }
   return true;
 }
 
 bool
 TabChild::RecvMouseScrollTestEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
 {
@@ -2395,30 +2386,30 @@ TabChild::RecvRealTouchEvent(const Widge
   TABC_LOG("Receiving touch event of type %d\n", aEvent.message);
 
   WidgetTouchEvent localEvent(aEvent);
   localEvent.widget = mWidget;
 
   APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
       mWidget->GetDefaultScale(), GetPresShellResolution());
 
-  if (localEvent.message == NS_TOUCH_START && AsyncPanZoomEnabled()) {
+  if (localEvent.message == NS_TOUCH_START && gfxPrefs::AsyncPanZoomEnabled()) {
     if (gfxPrefs::TouchActionEnabled()) {
       APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(WebWidget(),
           localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
     }
     nsCOMPtr<nsIDocument> document = GetDocument();
     APZCCallbackHelper::SendSetTargetAPZCNotification(WebWidget(), document,
         localEvent, aGuid, aInputBlockId);
   }
 
   // Dispatch event to content (potentially a long-running operation)
   nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
 
-  if (!AsyncPanZoomEnabled()) {
+  if (!gfxPrefs::AsyncPanZoomEnabled()) {
     UpdateTapState(localEvent, status);
     return true;
   }
 
   mAPZEventState->ProcessTouchEvent(localEvent, aGuid, aInputBlockId, aApzResponse);
   return true;
 }
 
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -314,18 +314,17 @@ public:
     virtual bool RecvCacheFileDescriptor(const nsString& aPath,
                                          const FileDescriptor& aFileDescriptor)
                                          override;
     virtual bool RecvShow(const ScreenIntSize& aSize,
                           const ShowInfo& aInfo,
                           const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                           const uint64_t& aLayersId,
                           PRenderFrameChild* aRenderFrame,
-                          const bool& aParentIsActive,
-                          const bool& aAsyncPanZoomEnabled) override;
+                          const bool& aParentIsActive) override;
     virtual bool RecvUpdateDimensions(const nsIntRect& rect,
                                       const ScreenIntSize& size,
                                       const ScreenOrientation& orientation,
                                       const LayoutDeviceIntPoint& chromeDisp) override;
     virtual bool RecvUpdateFrame(const layers::FrameMetrics& aFrameMetrics) override;
     virtual bool RecvRequestFlingSnap(const ViewID& aScrollId,
                                       const CSSPoint& aDestination) override;
     virtual bool RecvAcknowledgeScrollUpdate(const ViewID& aScrollId,
@@ -500,17 +499,16 @@ public:
     LayoutDeviceIntPoint GetChromeDisplacement() { return mChromeDisp; };
 
     bool IPCOpen() { return mIPCOpen; }
 
     bool ParentIsActive()
     {
       return mParentIsActive;
     }
-    bool AsyncPanZoomEnabled() { return mAsyncPanZoomEnabled; }
 
 protected:
     virtual ~TabChild();
 
     virtual PRenderFrameChild* AllocPRenderFrameChild() override;
     virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
     virtual bool RecvDestroy() override;
     virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) override;
@@ -557,18 +555,17 @@ private:
                             const uint64_t& aLayersId,
                             PRenderFrameChild* aRenderFrame);
     void DestroyWindow();
     void SetProcessNameToAppName();
 
     // Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
     void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                     const uint64_t& aLayersId,
-                    PRenderFrameChild* aRenderFrame,
-                    bool aAsyncPanZoomEnabled);
+                    PRenderFrameChild* aRenderFrame);
 
     void ApplyShowInfo(const ShowInfo& aInfo);
 
     // These methods are used for tracking synthetic mouse events
     // dispatched for compatibility.  On each touch event, we
     // UpdateTapState().  If we've detected that the current gesture
     // isn't a tap, then we CancelTapTracking().  In the meantime, we
     // may detect a context-menu event, and if so we
@@ -638,17 +635,16 @@ private:
     bool mDestroyed;
     // Position of tab, relative to parent widget (typically the window)
     LayoutDeviceIntPoint mChromeDisp;
     TabId mUniqueId;
     float mDPI;
     double mDefaultScale;
     bool mIPCOpen;
     bool mParentIsActive;
-    bool mAsyncPanZoomEnabled;
 
     DISALLOW_EVIL_CONSTRUCTORS(TabChild);
 };
 
 }
 }
 
 #endif // mozilla_dom_TabChild_h
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -883,18 +883,17 @@ TabParent::Show(const ScreenIntSize& siz
       bool allowFullscreen =
         mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
         mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen);
       bool isPrivate = mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozprivatebrowsing);
       info = ShowInfo(name, allowFullscreen, isPrivate, mDPI, mDefaultScale.scale);
     }
 
     unused << SendShow(size, info, textureFactoryIdentifier,
-                       layersId, renderFrame, aParentIsActive,
-                       AsyncPanZoomEnabled());
+                       layersId, renderFrame, aParentIsActive);
 }
 
 bool
 TabParent::RecvSetDimensions(const uint32_t& aFlags,
                              const int32_t& aX, const int32_t& aY,
                              const int32_t& aCx, const int32_t& aCy)
 {
   MOZ_ASSERT(!(aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER),
@@ -2644,25 +2643,22 @@ TabParent::DeallocPRenderFrameParent(PRe
 {
   delete aFrame;
   return true;
 }
 
 bool
 TabParent::RecvGetRenderFrameInfo(PRenderFrameParent* aRenderFrame,
                                   TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                  uint64_t* aLayersId,
-                                  bool* aAsyncPanZoomEnabled)
+                                  uint64_t* aLayersId)
 {
   RenderFrameParent* renderFrame = static_cast<RenderFrameParent*>(aRenderFrame);
   renderFrame->GetTextureFactoryIdentifier(aTextureFactoryIdentifier);
   *aLayersId = renderFrame->GetLayersId();
 
-  *aAsyncPanZoomEnabled = AsyncPanZoomEnabled();
-
   if (mNeedLayerTreeReadyNotification) {
     RequestNotifyLayerTreeReady();
     mNeedLayerTreeReadyNotification = false;
   }
 
   return true;
 }
 
@@ -2730,17 +2726,17 @@ TabParent::GetWidget() const
   return widget.forget();
 }
 
 void
 TabParent::ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
                                        uint64_t* aOutInputBlockId,
                                        nsEventStatus* aOutApzResponse)
 {
-  if (AsyncPanZoomEnabled()) {
+  if (gfxPrefs::AsyncPanZoomEnabled()) {
     if (aOutTargetGuid) {
       *aOutTargetGuid = InputAPZContext::GetTargetLayerGuid();
 
       // There may be cases where the APZ hit-testing code came to a different
       // conclusion than the main-thread hit-testing code as to where the event
       // is destined. In such cases the layersId of the APZ result may not match
       // the layersId of this renderframe. In such cases the main-thread hit-
       // testing code "wins" so we need to update the guid to reflect this.
@@ -2910,17 +2906,17 @@ TabParent::InjectTouchEvent(const nsAStr
 
   SendRealTouchEvent(event);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabParent::GetUseAsyncPanZoom(bool* useAsyncPanZoom)
 {
-  *useAsyncPanZoom = AsyncPanZoomEnabled();
+  *useAsyncPanZoom = gfxPrefs::AsyncPanZoomEnabled();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TabParent::SetIsDocShellActive(bool isActive)
 {
   unused << SendSetIsDocShellActive(isActive);
   return NS_OK;
@@ -3317,23 +3313,16 @@ void
 TabParent::TakeDragVisualization(RefPtr<mozilla::gfx::SourceSurface>& aSurface,
                                  int32_t& aDragAreaX, int32_t& aDragAreaY)
 {
   aSurface = mDnDVisualization.forget();
   aDragAreaX = mDragAreaX;
   aDragAreaY = mDragAreaY;
 }
 
-bool
-TabParent::AsyncPanZoomEnabled() const
-{
-  nsCOMPtr<nsIWidget> widget = GetWidget();
-  return widget && widget->AsyncPanZoomEnabled();
-}
-
 NS_IMETHODIMP
 FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo)
 {
   nsAuthInformationHolder* holder =
     static_cast<nsAuthInformationHolder*>(aAuthInfo);
 
   if (!net::gNeckoChild->SendOnAuthAvailable(mCallbackId,
                                              holder->User(),
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -443,18 +443,17 @@ protected:
 
     virtual PRenderFrameParent* AllocPRenderFrameParent() override;
     virtual bool DeallocPRenderFrameParent(PRenderFrameParent* aFrame) override;
 
     virtual bool RecvRemotePaintIsReady() override;
 
     virtual bool RecvGetRenderFrameInfo(PRenderFrameParent* aRenderFrame,
                                         TextureFactoryIdentifier* aTextureFactoryIdentifier,
-                                        uint64_t* aLayersId,
-                                        bool* aAsyncPanZoomEnabled) override;
+                                        uint64_t* aLayersId) override;
 
     virtual bool RecvSetDimensions(const uint32_t& aFlags,
                                    const int32_t& aX, const int32_t& aY,
                                    const int32_t& aCx, const int32_t& aCy) override;
 
     bool SendCompositionChangeEvent(mozilla::WidgetCompositionEvent& event);
 
     bool InitBrowserConfiguration(const nsCString& aURI,
@@ -496,18 +495,16 @@ private:
     layout::RenderFrameParent* GetRenderFrame();
     nsRefPtr<nsIContentParent> mManager;
     void TryCacheDPIAndScale();
 
     nsresult UpdatePosition();
 
     CSSPoint AdjustTapToChildWidget(const CSSPoint& aPoint);
 
-    bool AsyncPanZoomEnabled() const;
-
     // Update state prior to routing an APZ-aware event to the child process.
     // |aOutTargetGuid| will contain the identifier
     // of the APZC instance that handled the event. aOutTargetGuid may be null.
     // |aOutInputBlockId| will contain the identifier of the input block
     // that this event was added to, if there was one. aOutInputBlockId may be null.
     // |aOutApzResponse| will contain the response that the APZ gave when processing
     // the input block; this is used for generating appropriate pointercancel events.
     void ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -664,20 +664,16 @@ public:
   }
 
   virtual float RequestProperty(const nsAString& property) { return -1; }
 
   const TimeStamp& GetAnimationReadyTime() const {
     return mAnimationReadyTime;
   }
 
-  virtual bool AsyncPanZoomEnabled() const {
-    return false;
-  }
-
 protected:
   nsRefPtr<Layer> mRoot;
   gfx::UserData mUserData;
   bool mDestroyed;
   bool mSnapEffectiveTransforms;
 
   nsIntRegion mRegionToClear;
 
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -208,17 +208,17 @@ ClientLayerManager::BeginTransactionWith
   // composited (including resampling) asynchronously before we get
   // a chance to repaint, so we have to ensure that it's all valid
   // and not rotated.
   //
   // Desktop does not support async zoom yet, so we ignore this for those
   // platforms.
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
   if (mWidget && mWidget->GetOwningTabChild()) {
-    mCompositorMightResample = AsyncPanZoomEnabled();
+    mCompositorMightResample = gfxPrefs::AsyncPanZoomEnabled();
   }
 #endif
 
   // If we have a non-default target, we need to let our shadow manager draw
   // to it. This will happen at the end of the transaction.
   if (aTarget && XRE_GetProcessType() == GeckoProcessType_Default) {
     mShadowTarget = aTarget;
   } else {
@@ -777,22 +777,16 @@ ClientLayerManager::ProgressiveUpdateCal
   aMetrics.SetScrollOffset(scrollOffset / zoom);
   aMetrics.SetZoom(CSSToParentLayerScale2D(zoom));
   return ret;
 #else
   return false;
 #endif
 }
 
-bool
-ClientLayerManager::AsyncPanZoomEnabled() const
-{
-  return mWidget && mWidget->AsyncPanZoomEnabled();
-}
-
 ClientLayer::~ClientLayer()
 {
   if (HasShadow()) {
     PLayerChild::Send__delete__(GetShadow());
   }
   MOZ_COUNT_DTOR(ClientLayer);
 }
 
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -245,19 +245,16 @@ public:
   }
 
   // Get a copy of the compositor-side APZ test data for our layers ID.
   void GetCompositorSideAPZTestData(APZTestData* aData) const;
 
   void SetTransactionIdAllocator(TransactionIdAllocator* aAllocator) { mTransactionIdAllocator = aAllocator; }
 
   float RequestProperty(const nsAString& aProperty) override;
-
-  bool AsyncPanZoomEnabled() const override;
-
 protected:
   enum TransactionPhase {
     PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
   };
   TransactionPhase mPhase;
 
 private:
   // Listen memory-pressure event for ClientLayerManager
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -252,17 +252,17 @@ ClientTiledPaintedLayer::UseProgressiveD
 
   if (GetIsFixedPosition() || GetParent()->GetIsFixedPosition()) {
     // This layer is fixed-position and so even if it does have a scrolling
     // ancestor it will likely be entirely on-screen all the time, so we
     // should draw it all at once
     return false;
   }
 
-  if (ClientManager()->AsyncPanZoomEnabled()) {
+  if (gfxPrefs::AsyncPanZoomEnabled()) {
     LayerMetricsWrapper scrollAncestor;
     GetAncestorLayers(&scrollAncestor, nullptr, nullptr);
     MOZ_ASSERT(scrollAncestor); // because mPaintData.mCriticalDisplayPort is non-empty
     const FrameMetrics& parentMetrics = scrollAncestor.Metrics();
     if (!IsScrollingOnCompositor(parentMetrics)) {
       return false;
     }
   }
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -1324,22 +1324,16 @@ LayerManagerComposite::NotifyShadowTreeT
 
 void
 LayerComposite::SetLayerManager(LayerManagerComposite* aManager)
 {
   mCompositeManager = aManager;
   mCompositor = aManager->GetCompositor();
 }
 
-bool
-LayerManagerComposite::AsyncPanZoomEnabled() const
-{
-  return mCompositor->GetWidget()->AsyncPanZoomEnabled();
-}
-
 nsIntRegion
 LayerComposite::GetFullyRenderedRegion() {
   if (TiledLayerComposer* tiled = GetTiledLayerComposer()) {
     nsIntRegion shadowVisibleRegion = GetShadowVisibleRegion();
     // Discard the region which hasn't been drawn yet when doing
     // progressive drawing. Note that if the shadow visible region
     // shrunk the tiled valig region may not have discarded this yet.
     shadowVisibleRegion.And(shadowVisibleRegion, tiled->GetValidRegion());
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -244,18 +244,16 @@ public:
   }
 
   void UnusedApzTransformWarning() {
     mUnusedApzTransformWarning = true;
   }
 
   bool LastFrameMissedHWC() { return mLastFrameMissedHWC; }
 
-  bool AsyncPanZoomEnabled() const override;
-
 private:
   /** Region we're clipping our current drawing to. */
   nsIntRegion mClippingRegion;
   gfx::IntRect mRenderBounds;
 
   /** Current root layer. */
   LayerComposite* RootLayer() const;
 
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -657,19 +657,17 @@ CompositorParent::CompositorParent(nsIWi
 
   mRootLayerTreeID = AllocateLayerTreeId();
 
   { // scope lock
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
   }
 
-  // The Compositor uses the APZ pref directly since it needs to know whether
-  // to attempt to create the APZ machinery at all.
-  if (gfxPrefs::AsyncPanZoomEnabledDoNotUseDirectly() &&
+  if (gfxPrefs::AsyncPanZoomEnabled() &&
 #if !defined(MOZ_B2G) && !defined(MOZ_WIDGET_ANDROID)
       // For XUL applications (everything but B2G on mobile and desktop, and
       // Firefox on Android) we only want to use APZ when E10S is enabled. If
       // we ever get input events off the main thread we can consider relaxing
       // this requirement.
       mozilla::BrowserTabsRemoteAutostart() &&
 #endif
       (aWidget->WindowType() == eWindowType_toplevel || aWidget->WindowType() == eWindowType_child)) {
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2439,19 +2439,17 @@ DetectBadApzWheelInputPrefs()
   }
 
   return badPref;
 }
 
 void
 gfxPlatform::GetApzSupportInfo(mozilla::widget::InfoObject& aObj)
 {
-  // This is only a diagnostic so we use the low-level pref to see whether
-  // C++ APZ is enabled at all.
-  if (!gfxPrefs::AsyncPanZoomEnabledDoNotUseDirectly()) {
+  if (!gfxPrefs::AsyncPanZoomEnabled()) {
     return;
   }
 
   if (SupportsApzWheelInput()) {
     nsString badPref = DetectBadApzWheelInputPrefs();
 
     aObj.DefineProperty("ApzWheelInput", 1);
     if (badPref.Length()) {
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -264,17 +264,17 @@ private:
   DECL_GFX_PREF(Once, "image.multithreaded_decoding.limit",    ImageMTDecodingLimit, int32_t, -1);
   DECL_GFX_PREF(Live, "image.single-color-optimization.enabled", ImageSingleColorOptimizationEnabled, bool, true);
 
   DECL_GFX_PREF(Once, "layers.acceleration.disabled",          LayersAccelerationDisabled, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps",          LayersDrawFPS, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.print-histogram",  FPSPrintHistogram, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.write-to-file", WriteFPSToFile, bool, false);
   DECL_GFX_PREF(Once, "layers.acceleration.force-enabled",     LayersAccelerationForceEnabled, bool, false);
-  DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled",         AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
+  DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled",         AsyncPanZoomEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);
   DECL_GFX_PREF(Once, "layers.async-video.enabled",            AsyncVideoEnabled, bool, true);
   DECL_GFX_PREF(Once, "layers.async-video-oop.enabled",        AsyncVideoOOPEnabled, bool, true);
   DECL_GFX_PREF(Live, "layers.bench.enabled",                  LayersBenchEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.bufferrotation.enabled",         BufferRotationEnabled, bool, true);
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
   // If MOZ_GFX_OPTIMIZE_MOBILE is defined, we force component alpha off
   // and ignore the preference.
--- a/image/ImageFactory.cpp
+++ b/image/ImageFactory.cpp
@@ -42,26 +42,21 @@ ShouldDownscaleDuringDecode(const nsCStr
 
 static uint32_t
 ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart)
 {
   nsresult rv;
 
   // We default to the static globals.
   bool isDiscardable = gfxPrefs::ImageMemDiscardable();
+  bool doDecodeOnlyOnDraw = gfxPrefs::ImageDecodeOnlyOnDrawEnabled() &&
+                            gfxPrefs::AsyncPanZoomEnabled();
   bool doDecodeImmediately = gfxPrefs::ImageDecodeImmediatelyEnabled();
   bool doDownscaleDuringDecode = gfxPrefs::ImageDownscaleDuringDecodeEnabled();
 
-  // We use the compositor APZ pref here since we don't have a widget to test.
-  // It's safe since this is an optimization, and the only platform
-  // ImageDecodeOnlyOnDraw is disabled on is B2G (where APZ is enabled in all
-  // widgets anyway).
-  bool doDecodeOnlyOnDraw = gfxPrefs::ImageDecodeOnlyOnDrawEnabled() &&
-                            gfxPrefs::AsyncPanZoomEnabledDoNotUseDirectly();
-
   // We want UI to be as snappy as possible and not to flicker. Disable
   // discarding and decode-only-on-draw for chrome URLS.
   bool isChrome = false;
   rv = uri->SchemeIs("chrome", &isChrome);
   if (NS_SUCCEEDED(rv) && isChrome) {
     isDiscardable = doDecodeOnlyOnDraw = false;
   }
 
--- a/layout/base/AccessibleCaretEventHub.cpp
+++ b/layout/base/AccessibleCaretEventHub.cpp
@@ -3,17 +3,16 @@
 /* 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 "AccessibleCaretEventHub.h"
 
 #include "AccessibleCaretLogger.h"
 #include "AccessibleCaretManager.h"
-#include "Layers.h"
 #include "gfxPrefs.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "nsDocShell.h"
 #include "nsFocusManager.h"
 #include "nsFrameSelection.h"
 #include "nsITimer.h"
@@ -407,19 +406,17 @@ AccessibleCaretEventHub::Init(nsIPresShe
   MOZ_ASSERT(presContext, "PresContext should be given in PresShell::Init()");
 
   nsIDocShell* docShell = presContext->GetDocShell();
   if (!docShell) {
     return;
   }
 
 #if defined(MOZ_WIDGET_GONK)
-  if (layers::LayerManager* lm = mPresShell->GetLayerManager()) {
-    mUseAsyncPanZoom = lm->AsyncPanZoomEnabled();
-  }
+  mUseAsyncPanZoom = gfxPrefs::AsyncPanZoomEnabled();
 #endif
 
   docShell->AddWeakReflowObserver(this);
   docShell->AddWeakScrollObserver(this);
 
   mDocShell = static_cast<nsDocShell*>(docShell);
 
   mLongTapInjectorTimer = do_CreateInstance("@mozilla.org/timer;1");
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -4746,17 +4746,17 @@ FrameLayerBuilder::BuildContainerLayerFo
     (aManager->GetUserData(&gLayerManagerUserData));
 
   nsIntRect pixBounds;
   nscoord appUnitsPerDevPixel;
   bool flattenToSingleLayer = false;
   if ((aContainerFrame->GetStateBits() & NS_FRAME_NO_COMPONENT_ALPHA) &&
       mRetainingManager &&
       mRetainingManager->ShouldAvoidComponentAlphaLayers() &&
-      !nsLayoutUtils::AsyncPanZoomEnabled(aContainerFrame))
+      !gfxPrefs::AsyncPanZoomEnabled())
   {
     flattenToSingleLayer = true;
   }
 
   nscolor backgroundColor = NS_RGBA(0,0,0,0);
   if (aFlags & CONTAINER_ALLOW_PULL_BACKGROUND_COLOR) {
     backgroundColor = aParameters.mBackgroundColor;
   }
@@ -4778,17 +4778,17 @@ FrameLayerBuilder::BuildContainerLayerFo
     appUnitsPerDevPixel = state.GetAppUnitsPerDevPixel();
     state.Finish(&flags, data, pixBounds, aChildren, hasComponentAlphaChildren);
 
     if (hasComponentAlphaChildren &&
         mRetainingManager &&
         mRetainingManager->ShouldAvoidComponentAlphaLayers() &&
         containerLayer->HasMultipleChildren() &&
         !flattenToSingleLayer &&
-        !nsLayoutUtils::AsyncPanZoomEnabled(aContainerFrame))
+        !gfxPrefs::AsyncPanZoomEnabled())
     {
       // Since we don't want any component alpha layers on BasicLayers, we repeat
       // the layer building process with this explicitely forced off.
       // We restore the previous FrameLayerBuilder state since the first set
       // of layer building will have changed it.
       flattenToSingleLayer = true;
       data->mDisplayItems.EnumerateEntries(RestoreDisplayItemData,
                                            &mContainerLayerGeneration);
--- a/layout/base/SelectionCarets.cpp
+++ b/layout/base/SelectionCarets.cpp
@@ -28,17 +28,16 @@
 #include "nsView.h"
 #include "mozilla/dom/DOMRect.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ScrollViewChangeEvent.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/TreeWalker.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/TouchEvents.h"
-#include "Layers.h"
 #include "TouchCaret.h"
 #include "nsFrameSelection.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static PRLogModuleInfo* gSelectionCaretsLog;
 static const char* kSelectionCaretsLogModuleName = "SelectionCarets";
@@ -112,19 +111,17 @@ SelectionCarets::Init()
   MOZ_ASSERT(presContext, "PresContext should be given in PresShell::Init()");
 
   nsIDocShell* docShell = presContext->GetDocShell();
   if (!docShell) {
     return;
   }
 
 #if defined(MOZ_WIDGET_GONK)
-  if (layers::LayerManager* lm = mPresShell->GetLayerManager()) {
-    mUseAsyncPanZoom = lm->AsyncPanZoomEnabled();
-  }
+  mUseAsyncPanZoom = gfxPrefs::AsyncPanZoomEnabled();
 #endif
 
   docShell->AddWeakReflowObserver(this);
   docShell->AddWeakScrollObserver(this);
 
   mDocShell = static_cast<nsDocShell*>(docShell);
 }
 
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -629,18 +629,17 @@ nsDisplayListBuilder::nsDisplayListBuild
       mSyncDecodeImages(false),
       mIsPaintingToWindow(false),
       mIsCompositingCheap(false),
       mContainsPluginItem(false),
       mAncestorHasApzAwareEventHandler(false),
       mHaveScrollableDisplayPort(false),
       mWindowDraggingAllowed(false),
       mIsBuildingForPopup(nsLayoutUtils::IsPopup(aReferenceFrame)),
-      mForceLayerForScrollParent(false),
-      mAsyncPanZoomEnabled(nsLayoutUtils::AsyncPanZoomEnabled(aReferenceFrame))
+      mForceLayerForScrollParent(false)
 {
   MOZ_COUNT_CTOR(nsDisplayListBuilder);
   PL_InitArenaPool(&mPool, "displayListArena", 1024,
                    std::max(NS_ALIGNMENT_OF(void*),NS_ALIGNMENT_OF(double))-1);
   RecomputeCurrentAnimatedGeometryRoot();
 
   nsPresContext* pc = aReferenceFrame->PresContext();
   nsIPresShell *shell = pc->PresShell();
@@ -2280,17 +2279,17 @@ nsDisplayBackgroundImage::IsSingleFixedP
   return true;
 }
 
 bool
 nsDisplayBackgroundImage::ShouldFixToViewport(LayerManager* aManager)
 {
   // APZ doesn't (yet) know how to scroll the visible region for these type of
   // items, so don't layerize them if it's enabled.
-  if (nsLayoutUtils::UsesAsyncScrolling(mFrame) ||
+  if (nsLayoutUtils::UsesAsyncScrolling() ||
       (aManager && aManager->ShouldAvoidComponentAlphaLayers())) {
     return false;
   }
 
   // Put background-attachment:fixed background images in their own
   // compositing layer, unless we have APZ enabled
   return mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
          !mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
@@ -4205,17 +4204,17 @@ nsDisplaySubDocument::ComputeVisibility(
     childVisibleRegion.GetBounds().Intersect(mList.GetBounds(aBuilder));
   bool visible = mList.ComputeVisibilityForSublist(
     aBuilder, &childVisibleRegion, boundedRect,
     usingDisplayPort ? mFrame : nullptr);
 
   // If APZ is enabled then don't allow this computation to influence
   // aVisibleRegion, on the assumption that the layer can be asynchronously
   // scrolled so we'll definitely need all the content under it.
-  if (!nsLayoutUtils::UsesAsyncScrolling(mFrame)) {
+  if (!nsLayoutUtils::UsesAsyncScrolling()) {
     bool snap;
     nsRect bounds = GetBounds(aBuilder, &snap);
     nsRegion removed;
     removed.Sub(bounds, childVisibleRegion);
 
     aBuilder->SubtractFromVisibleRegion(aVisibleRegion, removed);
   }
 
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -345,18 +345,18 @@ public:
   {
     mLayerEventRegions = aItem;
   }
   bool IsBuildingLayerEventRegions()
   {
     if (mMode == PAINTING) {
       // Note: this is the only place that gets to query LayoutEventRegionsEnabled
       // 'directly' - other code should call this function.
-      return gfxPrefs::LayoutEventRegionsEnabledDoNotUseDirectly() ||
-             mAsyncPanZoomEnabled;
+      return (gfxPrefs::LayoutEventRegionsEnabledDoNotUseDirectly() ||
+              gfxPrefs::AsyncPanZoomEnabled());
     }
     return false;
   }
   bool IsInsidePointerEventsNoneDoc()
   {
     return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
   }
 
@@ -971,17 +971,16 @@ private:
   bool                           mAncestorHasApzAwareEventHandler;
   // True when the first async-scrollable scroll frame for which we build a
   // display list has a display port. An async-scrollable scroll frame is one
   // which WantsAsyncScroll().
   bool                           mHaveScrollableDisplayPort;
   bool                           mWindowDraggingAllowed;
   bool                           mIsBuildingForPopup;
   bool                           mForceLayerForScrollParent;
-  bool                           mAsyncPanZoomEnabled;
 };
 
 class nsDisplayItem;
 class nsDisplayList;
 /**
  * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
  * nsDisplayItemLink holds the link. The lists are linked from lowest to
  * highest in z-order.
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -809,44 +809,16 @@ ApplyRectMultiplier(nsRect aRect, float 
   float newWidth = aRect.width * aMultiplier;
   float newHeight = aRect.height * aMultiplier;
   float newX = aRect.x - ((newWidth - aRect.width) / 2.0f);
   float newY = aRect.y - ((newHeight - aRect.height) / 2.0f);
   // Rounding doesn't matter too much here, do a round-in
   return nsRect(ceil(newX), ceil(newY), floor(newWidth), floor(newHeight));
 }
 
-bool
-nsLayoutUtils::UsesAsyncScrolling(nsIFrame* aFrame)
-{
-#ifdef MOZ_WIDGET_ANDROID
-  // We always have async scrolling for android
-  return true;
-#endif
-
-  return AsyncPanZoomEnabled(aFrame);
-}
-
-bool
-nsLayoutUtils::AsyncPanZoomEnabled(nsIFrame* aFrame)
-{
-  // We use this as a shortcut, since if the compositor will never use APZ,
-  // no widget will either.
-  if (!gfxPrefs::AsyncPanZoomEnabledDoNotUseDirectly()) {
-    return false;
-  }
-
-  nsIFrame *frame = nsLayoutUtils::GetDisplayRootFrame(aFrame);
-  nsIWidget* widget = frame->GetNearestWidget();
-  if (!widget) {
-    return false;
-  }
-  return widget->AsyncPanZoomEnabled();
-}
-
 // Return the maximum displayport size, based on the LayerManager's maximum
 // supported texture size. The result is in app units.
 static nscoord
 GetMaxDisplayPortSize(nsIContent* aContent)
 {
   MOZ_ASSERT(!gfxPrefs::LayersTilesEnabled(), "Do not clamp displayports if tiling is enabled");
 
   nsIFrame* frame = aContent->GetPrimaryFrame();
@@ -1108,22 +1080,19 @@ nsLayoutUtils::SetDisplayPortMargins(nsI
     return false;
   }
 
   aContent->SetProperty(nsGkAtoms::DisplayPortMargins,
                         new DisplayPortMarginsPropertyData(
                             aMargins, aPriority),
                         nsINode::DeleteProperty<DisplayPortMarginsPropertyData>);
 
-  if (gfxPrefs::LayoutUseContainersForRootFrames()) {
+  if (nsLayoutUtils::UsesAsyncScrolling() && gfxPrefs::LayoutUseContainersForRootFrames()) {
     nsIFrame* rootScrollFrame = aPresShell->GetRootScrollFrame();
-    if (rootScrollFrame &&
-        aContent == rootScrollFrame->GetContent() &&
-        nsLayoutUtils::UsesAsyncScrolling(rootScrollFrame))
-    {
+    if (rootScrollFrame && aContent == rootScrollFrame->GetContent()) {
       // We are setting a root displayport for a document.
       // If we have APZ, then set a special flag on the pres shell so
       // that we don't get scrollbars drawn.
       aPresShell->SetIgnoreViewportScrolling(true);
     }
   }
 
   if (aRepaintMode == RepaintMode::Repaint) {
@@ -3001,17 +2970,17 @@ nsLayoutUtils::GetOrMaybeCreateDisplayPo
 
   // We perform an optimization where we ensure that at least one
   // async-scrollable frame (i.e. one that WantsAsyncScroll()) has a displayport.
   // If that's not the case yet, and we are async-scrollable, we will get a
   // displayport.
   // Note: we only do this in processes where we do subframe scrolling to
   //       begin with (i.e., not in the parent process on B2G).
   if (aBuilder.IsPaintingToWindow() &&
-      nsLayoutUtils::AsyncPanZoomEnabled(aScrollFrame) &&
+      gfxPrefs::AsyncPanZoomEnabled() &&
       !aBuilder.HaveScrollableDisplayPort() &&
       scrollableFrame->WantAsyncScroll()) {
 
     // If we don't already have a displayport, calculate and set one.
     if (!haveDisplayPort) {
       CalculateAndSetDisplayPortMargins(scrollableFrame, nsLayoutUtils::RepaintMode::DoNotRepaint);
       haveDisplayPort = GetDisplayPort(content, aOutDisplayport);
       NS_ASSERTION(haveDisplayPort, "should have a displayport after having just set it");
@@ -7848,16 +7817,27 @@ nsLayoutUtils::CalculateExpandedScrollab
   if (scrollableRect.height < compSize.height) {
     scrollableRect.y = std::max(0,
                                 scrollableRect.y - (compSize.height - scrollableRect.height));
     scrollableRect.height = compSize.height;
   }
   return scrollableRect;
 }
 
+/* static */ bool
+nsLayoutUtils::UsesAsyncScrolling()
+{
+#ifdef MOZ_WIDGET_ANDROID
+  // We always have async scrolling for android
+  return true;
+#endif
+
+  return gfxPrefs::AsyncPanZoomEnabled();
+}
+
 /* static */ void
 nsLayoutUtils::DoLogTestDataForPaint(LayerManager* aManager,
                                      ViewID aScrollId,
                                      const std::string& aKey,
                                      const std::string& aValue)
 {
   if (aManager->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
     static_cast<ClientLayerManager*>(aManager)->LogTestDataForCurrentPaint(aScrollId, aKey, aValue);
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2509,26 +2509,20 @@ public:
  /**
   * Calculate the expanded scrollable rect for a frame. See FrameMetrics.h for
   * defintion of expanded scrollable rect.
   */
   static nsRect
   CalculateExpandedScrollableRect(nsIFrame* aFrame);
 
   /**
-   * Returns true if the widget owning the given frame uses asynchronous
-   * scrolling.
+   * Returns true if we're using asynchronous scrolling (either through
+   * APZ or the android frontend).
    */
-  static bool UsesAsyncScrolling(nsIFrame* aFrame);
-
-  /**
-   * Returns true if the widget owning the given frame has builtin APZ support
-   * enabled.
-   */
-  static bool AsyncPanZoomEnabled(nsIFrame* aFrame);
+  static bool UsesAsyncScrolling();
 
   /**
    * Log a key/value pair for APZ testing during a paint.
    * @param aManager   The data will be written to the APZTestData associated 
    *                   with this layer manager.
    * @param aScrollId Identifies the scroll frame to which the data pertains.
    * @param aKey The key under which to log the data.
    * @param aValue The value of the data to be logged.
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -11036,20 +11036,20 @@ nsIPresShell::RecomputeFontSizeInflation
   if ((FontSizeInflationEmPerLine() == 0 &&
       FontSizeInflationMinTwips() == 0) || mPresContext->IsChrome()) {
     mFontSizeInflationEnabled = false;
     return;
   }
 
   // Force-enabling font inflation always trumps the heuristics here.
   if (!FontSizeInflationForceEnabled()) {
-    if (TabChild* tab = TabChild::GetFrom(this)) {
+    if (TabChild::GetFrom(this)) {
       // We're in a child process.  Cancel inflation if we're not
       // async-pan zoomed.
-      if (!tab->AsyncPanZoomEnabled()) {
+      if (!gfxPrefs::AsyncPanZoomEnabled()) {
         mFontSizeInflationEnabled = false;
         return;
       }
     } else if (XRE_GetProcessType() == GeckoProcessType_Default) {
       // We're in the master process.  Cancel inflation if it's been
       // explicitly disabled.
       if (FontSizeInflationDisabledInMasterProcess()) {
         mFontSizeInflationEnabled = false;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1819,17 +1819,17 @@ ScrollFrameHelper::ScrollFrameHelper(nsC
   if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
     mScrollbarActivity = new ScrollbarActivity(do_QueryFrame(aOuter));
   }
 
   EnsureImageVisPrefsCached();
 
   if (IsAlwaysActive() &&
       gfxPrefs::LayersTilesEnabled() &&
-      !nsLayoutUtils::UsesAsyncScrolling(mOuter) &&
+      !nsLayoutUtils::UsesAsyncScrolling() &&
       mOuter->GetContent()) {
     // If we have tiling but no APZ, then set a 0-margin display port on
     // active scroll containers so that we paint by whole tile increments
     // when scrolling.
     nsLayoutUtils::SetDisplayPortMargins(mOuter->GetContent(),
                                          mOuter->PresContext()->PresShell(),
                                          ScreenMargin(),
                                          0,
@@ -2023,17 +2023,17 @@ ScrollFrameHelper::ScrollToWithOrigin(ns
         currentVelocity.height = sv.y;
         if (mAsyncScroll) {
           if (mAsyncScroll->mIsSmoothScroll) {
             currentVelocity = mAsyncScroll->VelocityAt(now);
           }
           mAsyncScroll = nullptr;
         }
 
-        if (nsLayoutUtils::AsyncPanZoomEnabled(mOuter)) {
+        if (gfxPrefs::AsyncPanZoomEnabled()) {
           // The animation will be handled in the compositor, pass the
           // information needed to start the animation and skip the main-thread
           // animation for this scroll.
           mLastSmoothScrollOrigin = aOrigin;
           mScrollGeneration = ++sScrollGenerationCounter;
 
           if (!nsLayoutUtils::GetDisplayPort(mOuter->GetContent())) {
             // If this frame doesn't have a displayport then there won't be an
@@ -2904,17 +2904,17 @@ ScrollFrameHelper::BuildDisplayList(nsDi
   // If the element is marked 'scrollgrab', also force building of a layer
   // so that APZ can implement scroll grabbing.
   mShouldBuildScrollableLayer = usingDisplayport || nsContentUtils::HasScrollgrab(mOuter->GetContent());
   bool shouldBuildLayer = false;
   if (mShouldBuildScrollableLayer) {
     shouldBuildLayer = true;
   } else {
     shouldBuildLayer =
-      nsLayoutUtils::AsyncPanZoomEnabled(mOuter) &&
+      gfxPrefs::AsyncPanZoomEnabled() &&
       WantAsyncScroll() &&
       // If we are using containers for root frames, and we are the root
       // scroll frame for the display root, then we don't need a scroll
       // info layer. nsDisplayList::PaintForFrame already calls
       // ComputeFrameMetrics for us.
       (!(gfxPrefs::LayoutUseContainersForRootFrames() && mIsRoot) ||
        (aBuilder->RootReferenceFrame()->PresContext() != mOuter->PresContext()));
   }
@@ -3046,17 +3046,17 @@ ScrollFrameHelper::ComputeFrameMetrics(L
                                        nsTArray<FrameMetrics>* aOutput) const
 {
   nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
   bool isRoot = mIsRoot && mOuter->PresContext()->IsRootContentDocument();
   // If APZ is enabled, do not apply clips to the scroll ports of metrics
   // above the first one on a given layer. They will be applied by the
   // compositor instead, with async transforms for the scrollframes interspersed
   // between them.
-  bool omitClip = nsLayoutUtils::AsyncPanZoomEnabled(mOuter) && aOutput->Length() > 0;
+  bool omitClip = gfxPrefs::AsyncPanZoomEnabled() && aOutput->Length() > 0;
   if (!omitClip && (!gfxPrefs::LayoutUseContainersForRootFrames() || mAddClipRectToLayer)) {
     nsRect clip = nsRect(mScrollPort.TopLeft() + toReferenceFrame,
                          nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
     if (isRoot) {
       double res = mOuter->PresContext()->PresShell()->GetResolution();
       clip.width = NSToCoordRound(clip.width / res);
       clip.height = NSToCoordRound(clip.height / res);
     }
@@ -3350,18 +3350,17 @@ ScrollFrameHelper::ScrollBy(nsIntPoint a
     nsPoint clampAmount = newPos - mDestination;
     float appUnitsPerDevPixel = mOuter->PresContext()->AppUnitsPerDevPixel();
     *aOverflow = nsIntPoint(
         NSAppUnitsToIntPixels(clampAmount.x, appUnitsPerDevPixel),
         NSAppUnitsToIntPixels(clampAmount.y, appUnitsPerDevPixel));
   }
 
   if (aUnit == nsIScrollableFrame::DEVICE_PIXELS &&
-      !nsLayoutUtils::AsyncPanZoomEnabled(mOuter))
-  {
+      !gfxPrefs::AsyncPanZoomEnabled()) {
     // When APZ is disabled, we must track the velocity
     // on the main thread; otherwise, the APZC will manage this.
     mVelocityQueue.Sample(GetScrollPosition());
   }
 }
 
 void
 ScrollFrameHelper::ScrollSnap(nsIScrollableFrame::ScrollMode aMode)
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -294,29 +294,25 @@ private:
 RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader,
                                      TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                      uint64_t* aId,
                                      bool* aSuccess)
   : mLayersId(0)
   , mFrameLoader(aFrameLoader)
   , mFrameLoaderDestroyed(false)
   , mBackgroundColor(gfxRGBA(1, 1, 1))
-  , mAsyncPanZoomEnabled(false)
 {
   *aSuccess = false;
   if (!mFrameLoader) {
     return;
   }
 
   *aId = 0;
 
   nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
-
-  mAsyncPanZoomEnabled = lm && lm->AsyncPanZoomEnabled();
-
   // Perhaps the document containing this frame currently has no presentation?
   if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
     *aTextureFactoryIdentifier =
       static_cast<ClientLayerManager*>(lm.get())->GetTextureFactoryIdentifier();
   } else {
     *aTextureFactoryIdentifier = TextureFactoryIdentifier();
   }
 
@@ -324,17 +320,17 @@ RenderFrameParent::RenderFrameParent(nsF
     // Our remote frame will push layers updates to the compositor,
     // and we'll keep an indirect reference to that tree.
     *aId = mLayersId = CompositorParent::AllocateLayerTreeId();
     if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
       ClientLayerManager *clientManager =
         static_cast<ClientLayerManager*>(lm.get());
       clientManager->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId);
     }
-    if (mAsyncPanZoomEnabled) {
+    if (gfxPrefs::AsyncPanZoomEnabled()) {
       mContentController = new RemoteContentController(this);
       CompositorParent::SetControllerForLayerTree(mLayersId, mContentController);
     }
   } else if (XRE_GetProcessType() == GeckoProcessType_Content) {
     ContentChild::GetSingleton()->SendAllocateLayerTreeId(aId);
     mLayersId = *aId;
     CompositorChild::Get()->SendNotifyChildCreated(mLayersId);
   }
@@ -345,17 +341,17 @@ RenderFrameParent::RenderFrameParent(nsF
 
 APZCTreeManager*
 RenderFrameParent::GetApzcTreeManager()
 {
   // We can't get a ref to the APZCTreeManager until after the child is
   // created and the static getter knows which CompositorParent is
   // instantiated with this layers ID. That's why try to fetch it when
   // we first need it and cache the result.
-  if (!mApzcTreeManager && mAsyncPanZoomEnabled) {
+  if (!mApzcTreeManager && gfxPrefs::AsyncPanZoomEnabled()) {
     mApzcTreeManager = CompositorParent::GetAPZCTreeManager(mLayersId);
   }
   return mApzcTreeManager.get();
 }
 
 RenderFrameParent::~RenderFrameParent()
 {}
 
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -146,18 +146,16 @@ private:
   // 
   // It's possible for mFrameLoader==null and
   // mFrameLoaderDestroyed==false.
   bool mFrameLoaderDestroyed;
   // this is gfxRGBA because that's what ColorLayer wants.
   gfxRGBA mBackgroundColor;
 
   nsRegion mTouchRegion;
-
-  bool mAsyncPanZoomEnabled;
 };
 
 } // namespace layout
 } // namespace mozilla
 
 /**
  * A DisplayRemote exists solely to graft a child process's shadow
  * layer tree (for a given RenderFrameParent) into its parent
--- a/layout/tools/reftest/reftest.js
+++ b/layout/tools/reftest/reftest.js
@@ -739,17 +739,17 @@ function BuildConditionSandbox(aURL) {
     };
 
     // Tests shouldn't care about this except for when they need to
     // crash the content process
     sandbox.browserIsRemote = gBrowserIsRemote;
     sandbox.Mulet = gB2GisMulet;
 
     try {
-        sandbox.asyncPanZoom = gContainingWindow.document.docShell.asyncPanZoomEnabled;
+        sandbox.asyncPanZoom = prefs.getBoolPref("layers.async-pan-zoom.enabled");
     } catch (e) {
         sandbox.asyncPanZoom = false;
     }
 
     if (!gDumpedConditionSandbox) {
         dump("REFTEST INFO | Dumping JSON representation of sandbox \n");
         dump("REFTEST INFO | " + JSON.stringify(CU.waiveXrays(sandbox)) + " \n");
         gDumpedConditionSandbox = true;
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -349,17 +349,17 @@ PuppetWidget::DispatchInputEvent(WidgetI
   }
 
   return nsEventStatus_eIgnore;
 }
 
 nsEventStatus
 PuppetWidget::DispatchAPZAwareEvent(WidgetInputEvent* aEvent)
 {
-  if (!AsyncPanZoomEnabled()) {
+  if (!gfxPrefs::AsyncPanZoomEnabled()) {
     nsEventStatus status = nsEventStatus_eIgnore;
     DispatchEvent(aEvent, status);
     return status;
   }
 
   if (!mTabChild) {
     return nsEventStatus_eIgnore;
   }
@@ -488,22 +488,16 @@ void
 PuppetWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                                      const nsTArray<ScrollableLayerGuid>& aTargets) const
 {
   if (mTabChild) {
     mTabChild->SendSetTargetAPZC(aInputBlockId, aTargets);
   }
 }
 
-bool
-PuppetWidget::AsyncPanZoomEnabled() const
-{
-  return mTabChild && mTabChild->AsyncPanZoomEnabled();
-}
-
 NS_IMETHODIMP_(bool)
 PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
                                       const mozilla::WidgetKeyboardEvent& aEvent,
                                       DoCommandCallback aCallback,
                                       void* aCallbackData)
 {
   // B2G doesn't have native key bindings.
 #ifdef MOZ_WIDGET_GONK
--- a/widget/PuppetWidget.h
+++ b/widget/PuppetWidget.h
@@ -130,17 +130,16 @@ public:
 
   void InitEvent(WidgetGUIEvent& aEvent, nsIntPoint* aPoint = nullptr);
 
   NS_IMETHOD DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus) override;
   nsEventStatus DispatchAPZAwareEvent(WidgetInputEvent* aEvent) override;
   nsEventStatus DispatchInputEvent(WidgetInputEvent* aEvent) override;
   void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                               const nsTArray<ScrollableLayerGuid>& aTargets) const override;
-  bool AsyncPanZoomEnabled() const override;
 
   NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener,
                                  bool aDoCapture) override
   { return NS_ERROR_UNEXPECTED; }
 
   NS_IMETHOD_(bool)
   ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
                           const mozilla::WidgetKeyboardEvent& aEvent,
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1002,22 +1002,16 @@ nsBaseWidget::SetConfirmedTargetAPZC(uin
 {
   // Need to specifically bind this since it's overloaded.
   void (APZCTreeManager::*setTargetApzcFunc)(uint64_t, const nsTArray<ScrollableLayerGuid>&)
           = &APZCTreeManager::SetTargetAPZC;
   APZThreadUtils::RunOnControllerThread(NewRunnableMethod(
     mAPZC.get(), setTargetApzcFunc, aInputBlockId, mozilla::Move(aTargets)));
 }
 
-bool
-nsBaseWidget::AsyncPanZoomEnabled() const
-{
-  return !!mAPZC;
-}
-
 nsEventStatus
 nsBaseWidget::ProcessUntransformedAPZEvent(WidgetInputEvent* aEvent,
                                            const ScrollableLayerGuid& aGuid,
                                            uint64_t aInputBlockId,
                                            nsEventStatus aApzResponse)
 {
   MOZ_ASSERT(NS_IsMainThread());
   InputAPZContext context(aGuid, aInputBlockId, aApzResponse);
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -237,18 +237,16 @@ public:
   nsEventStatus DispatchInputEvent(mozilla::WidgetInputEvent* aEvent) override;
 
   // Dispatch an event that must be first be routed through APZ.
   nsEventStatus DispatchAPZAwareEvent(mozilla::WidgetInputEvent* aEvent) override;
 
   void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                               const nsTArray<ScrollableLayerGuid>& aTargets) const override;
 
-  bool AsyncPanZoomEnabled() const override;
-
   void NotifyWindowDestroyed();
   void NotifySizeMoveDone();
   void NotifyWindowMoved(int32_t aX, int32_t aY);
 
   // Register plugin windows for remote updates from the compositor
   virtual void RegisterPluginWindowForRemoteUpdates() override;
   virtual void UnregisterPluginWindowForRemoteUpdates() override;
 
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -1803,21 +1803,16 @@ class nsIWidget : public nsISupports {
     /**
      * Confirm an APZ-aware event target. This should be used when APZ will
      * not need a layers update to process the event.
      */
     virtual void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                                         const nsTArray<mozilla::layers::ScrollableLayerGuid>& aTargets) const = 0;
 
     /**
-     * Returns true if APZ is in use, false otherwise.
-     */
-    virtual bool AsyncPanZoomEnabled() const = 0;
-
-    /**
      * Enables the dropping of files to a widget (XXX this is temporary)
      *
      */
     NS_IMETHOD EnableDragDrop(bool aEnable) = 0;
    
     /**
      * Enables/Disables system mouse capture.
      * @param aCapture true enables mouse capture, false disables mouse capture