diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 466616031c3..0e2742ff2a2 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -13862,7 +13862,12 @@ nsDocShell::GetAppManifestURL(nsAString& aAppManifestURL) NS_IMETHODIMP nsDocShell::GetAsyncPanZoomEnabled(bool* aOut) { - *aOut = Preferences::GetBool("layers.async-pan-zoom.enabled", false); + if (nsIPresShell* presShell = GetPresShell()) { + *aOut = presShell->AsyncPanZoomEnabled(); + return NS_OK; + } + + *aOut = false; return NS_OK; } diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 8676ee63c42..c4ee28fd207 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -378,9 +378,12 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx, new DisplayPortPropertyData(displayport, aPriority), nsINode::DeleteProperty); - if (nsLayoutUtils::UsesAsyncScrolling() && gfxPrefs::LayoutUseContainersForRootFrames()) { + if (gfxPrefs::LayoutUseContainersForRootFrames()) { nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame(); - if (rootScrollFrame && content == rootScrollFrame->GetContent()) { + if (rootScrollFrame && + content == rootScrollFrame->GetContent() && + nsLayoutUtils::UsesAsyncScrolling(rootScrollFrame)) + { // We are setting a root displayport for a document. // The pres shell needs a special flag set. presShell->SetIgnoreViewportScrolling(true); @@ -861,7 +864,7 @@ nsDOMWindowUtils::SendWheelEvent(float aX, widget->DispatchAPZAwareEvent(&wheelEvent); - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (widget->AsyncPanZoomEnabled()) { // Computing overflow deltas is not compatible with APZ, so if APZ is // enabled, we skip testing it. return NS_OK; diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 5a8bd28b110..b17208f8c15 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -293,7 +293,8 @@ TabChildBase::GetPageSize(nsCOMPtr aDocument, const CSSSize& aViewp bool TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize) { - if (!gfxPrefs::AsyncPanZoomEnabled()) { + nsIWidget* widget = WebWidget(); + if (!widget || !widget->AsyncPanZoomEnabled()) { return false; } @@ -899,6 +900,13 @@ TabChild::TabChild(nsIContentChild* aManager, , mIPCOpen(true) , mParentIsActive(false) { + // In the general case having the TabParent tell us if APZ is enabled or not + // doesn't really work because the TabParent itself may not have a reference + // to the owning widget during initialization. Instead we assume that this + // TabChild corresponds to a widget type that would have APZ enabled, and just + // check the other conditions necessary for enabling APZ. + mAsyncPanZoomEnabled = gfxPlatform::AsyncPanZoomEnabled(); + // preloaded TabChild should not be added to child map if (mUniqueId) { MOZ_ASSERT(NestedTabChildMap().find(mUniqueId) == NestedTabChildMap().end()); @@ -944,7 +952,7 @@ TabChild::Observe(nsISupports *aSubject, } } } else if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) { - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (AsyncPanZoomEnabled()) { nsCOMPtr subject(do_QueryInterface(aSubject)); nsCOMPtr doc(GetDocument()); @@ -1002,7 +1010,7 @@ TabChild::OnLocationChange(nsIWebProgress* aWebProgress, nsIURI *aLocation, uint32_t aFlags) { - if (!gfxPrefs::AsyncPanZoomEnabled()) { + if (!AsyncPanZoomEnabled()) { return NS_OK; } @@ -2037,6 +2045,7 @@ TabChild::RecvShow(const ScreenIntSize& aSize, bool res = InitTabChildGlobal(); ApplyShowInfo(aInfo); RecvParentActivated(aParentIsActive); + return res; } @@ -2222,7 +2231,7 @@ TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent, const ScrollableLayerGuid& aGuid, const uint64_t& aInputBlockId) { - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (AsyncPanZoomEnabled()) { nsCOMPtr document(GetDocument()); APZCCallbackHelper::SendSetTargetAPZCNotification(WebWidget(), document, aEvent, aGuid, aInputBlockId); @@ -2232,7 +2241,7 @@ TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent, event.widget = mWidget; APZCCallbackHelper::DispatchWidgetEvent(event); - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (AsyncPanZoomEnabled()) { mAPZEventState->ProcessWheelEvent(event, aGuid, aInputBlockId); } return true; @@ -2414,7 +2423,7 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent, APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid, mWidget->GetDefaultScale(), GetPresShellResolution()); - if (localEvent.message == NS_TOUCH_START && gfxPrefs::AsyncPanZoomEnabled()) { + if (localEvent.message == NS_TOUCH_START && AsyncPanZoomEnabled()) { if (gfxPrefs::TouchActionEnabled()) { APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(WebWidget(), localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback); @@ -2427,7 +2436,7 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent, // Dispatch event to content (potentially a long-running operation) nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent); - if (!gfxPrefs::AsyncPanZoomEnabled()) { + if (!AsyncPanZoomEnabled()) { UpdateTapState(localEvent, status); return true; } diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 42adc4fb4c0..38bc979302a 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -508,6 +508,7 @@ public: { return mParentIsActive; } + bool AsyncPanZoomEnabled() { return mAsyncPanZoomEnabled; } protected: virtual ~TabChild(); @@ -644,6 +645,7 @@ private: double mDefaultScale; bool mIPCOpen; bool mParentIsActive; + bool mAsyncPanZoomEnabled; DISALLOW_EVIL_CONSTRUCTORS(TabChild); }; diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 5f42af51977..38f640f5c35 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -2813,7 +2813,7 @@ TabParent::ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid, uint64_t* aOutInputBlockId, nsEventStatus* aOutApzResponse) { - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (AsyncPanZoomEnabled()) { if (aOutTargetGuid) { *aOutTargetGuid = InputAPZContext::GetTargetLayerGuid(); @@ -2993,7 +2993,7 @@ TabParent::InjectTouchEvent(const nsAString& aType, NS_IMETHODIMP TabParent::GetUseAsyncPanZoom(bool* useAsyncPanZoom) { - *useAsyncPanZoom = gfxPrefs::AsyncPanZoomEnabled(); + *useAsyncPanZoom = AsyncPanZoomEnabled(); return NS_OK; } @@ -3400,6 +3400,13 @@ TabParent::TakeDragVisualization(RefPtr& aSurface, aDragAreaY = mDragAreaY; } +bool +TabParent::AsyncPanZoomEnabled() const +{ + nsCOMPtr widget = GetWidget(); + return widget && widget->AsyncPanZoomEnabled(); +} + NS_IMETHODIMP FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 657d333dd75..87f5ca9959e 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -514,6 +514,8 @@ private: 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. diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 057b36ef369..8a2b901bd47 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -668,6 +668,10 @@ public: return mAnimationReadyTime; } + virtual bool AsyncPanZoomEnabled() const { + return false; + } + protected: nsRefPtr mRoot; gfx::UserData mUserData; diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index dc8ba1a98f4..2a45dce1385 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -213,7 +213,7 @@ ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget) // platforms. #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) if (mWidget && mWidget->GetOwningTabChild()) { - mCompositorMightResample = gfxPrefs::AsyncPanZoomEnabled(); + mCompositorMightResample = AsyncPanZoomEnabled(); } #endif @@ -782,6 +782,12 @@ ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, #endif } +bool +ClientLayerManager::AsyncPanZoomEnabled() const +{ + return mWidget && mWidget->AsyncPanZoomEnabled(); +} + ClientLayer::~ClientLayer() { if (HasShadow()) { diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index 65f2c3ed730..43ffa28578e 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -250,6 +250,9 @@ public: 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 diff --git a/gfx/layers/client/ClientTiledPaintedLayer.cpp b/gfx/layers/client/ClientTiledPaintedLayer.cpp index 7d2169905a0..ea70921f1cb 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.cpp +++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp @@ -257,7 +257,7 @@ ClientTiledPaintedLayer::UseProgressiveDraw() { return false; } - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (ClientManager()->AsyncPanZoomEnabled()) { LayerMetricsWrapper scrollAncestor; GetAncestorLayers(&scrollAncestor, nullptr, nullptr); MOZ_ASSERT(scrollAncestor); // because mPaintData.mCriticalDisplayPort is non-empty diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index cc5dabe4994..b4811fb385a 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -1329,6 +1329,12 @@ LayerComposite::SetLayerManager(LayerManagerComposite* aManager) mCompositor = aManager->GetCompositor(); } +bool +LayerManagerComposite::AsyncPanZoomEnabled() const +{ + return mCompositor->GetWidget()->AsyncPanZoomEnabled(); +} + nsIntRegion LayerComposite::GetFullyRenderedRegion() { if (TiledLayerComposer* tiled = GetTiledLayerComposer()) { diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index b6a0de1618e..5cfbe7c4244 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -249,6 +249,8 @@ public: bool LastFrameMissedHWC() { return mLastFrameMissedHWC; } + bool AsyncPanZoomEnabled() const override; + private: /** Region we're clipping our current drawing to. */ nsIntRegion mClippingRegion; diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 787bd0f9cbe..ad1ea129f1a 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -50,7 +50,6 @@ #include "nsDebug.h" // for NS_ASSERTION, etc #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc #include "nsIWidget.h" // for nsIWidget -#include "nsIXULRuntime.h" // for mozilla::BrowserTabsRemoteAutostart #include "nsTArray.h" // for nsTArray #include "nsThreadUtils.h" // for NS_IsMainThread #include "nsXULAppAPI.h" // for XRE_GetIOMessageLoop @@ -663,14 +662,9 @@ CompositorParent::CompositorParent(nsIWidget* aWidget, sIndirectLayerTrees[mRootLayerTreeID].mParent = this; } - 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 + // The Compositor uses the APZ pref directly since it needs to know whether + // to attempt to create the APZ machinery at all. + if (gfxPlatform::AsyncPanZoomEnabled() && (aWidget->WindowType() == eWindowType_toplevel || aWidget->WindowType() == eWindowType_child)) { mApzcTreeManager = new APZCTreeManager(); } diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 0e694883e8a..25d5c6a5ab8 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -2454,7 +2454,7 @@ DetectBadApzWheelInputPrefs() void gfxPlatform::GetApzSupportInfo(mozilla::widget::InfoObject& aObj) { - if (!gfxPrefs::AsyncPanZoomEnabled()) { + if (!gfxPlatform::AsyncPanZoomEnabled()) { return; } @@ -2472,3 +2472,17 @@ gfxPlatform::GetApzSupportInfo(mozilla::widget::InfoObject& aObj) } } +/*static*/ bool +gfxPlatform::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. + if (!BrowserTabsRemoteAutostart()) { + return false; + } +#endif + return gfxPrefs::AsyncPanZoomEnabledDoNotUseDirectly(); +} diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 977b7eead63..abb59296a1f 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -289,6 +289,8 @@ public: /// as different platforms may override the behaviour. virtual bool UseProgressivePaint() { return gfxPrefs::ProgressivePaintDoNotUseDirectly(); } + static bool AsyncPanZoomEnabled(); + void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) { aObj.DefineProperty("AzureCanvasBackend", GetBackendName(mPreferredCanvasBackend)); aObj.DefineProperty("AzureSkiaAccelerated", UseAcceleratedSkiaCanvas()); diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index fbb6a33acfe..64f01da05cf 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -276,7 +276,7 @@ private: 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", AsyncPanZoomEnabled, bool, false); + DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true); 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); diff --git a/image/ImageFactory.cpp b/image/ImageFactory.cpp index ddd1a3df25e..b61d538af81 100644 --- a/image/ImageFactory.cpp +++ b/image/ImageFactory.cpp @@ -47,11 +47,16 @@ ComputeImageFlags(ImageURL* uri, const nsCString& aMimeType, bool isMultiPart) // 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; diff --git a/layout/base/AccessibleCaretEventHub.cpp b/layout/base/AccessibleCaretEventHub.cpp index a269f1a0da9..48264f9946b 100644 --- a/layout/base/AccessibleCaretEventHub.cpp +++ b/layout/base/AccessibleCaretEventHub.cpp @@ -8,6 +8,7 @@ #include "AccessibleCaretLogger.h" #include "AccessibleCaretManager.h" +#include "Layers.h" #include "gfxPrefs.h" #include "mozilla/MouseEvents.h" #include "mozilla/TextEvents.h" @@ -411,7 +412,7 @@ AccessibleCaretEventHub::Init(nsIPresShell* aPresShell) } #if defined(MOZ_WIDGET_GONK) - mUseAsyncPanZoom = gfxPrefs::AsyncPanZoomEnabled(); + mUseAsyncPanZoom = mPresShell->AsyncPanZoomEnabled(); #endif docShell->AddWeakReflowObserver(this); diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 57cfe1dab49..120fc3b7ab3 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -4885,7 +4885,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, if ((aContainerFrame->GetStateBits() & NS_FRAME_NO_COMPONENT_ALPHA) && mRetainingManager && mRetainingManager->ShouldAvoidComponentAlphaLayers() && - !gfxPrefs::AsyncPanZoomEnabled()) + !nsLayoutUtils::AsyncPanZoomEnabled(aContainerFrame)) { flattenToSingleLayer = true; } @@ -4917,7 +4917,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, mRetainingManager->ShouldAvoidComponentAlphaLayers() && containerLayer->HasMultipleChildren() && !flattenToSingleLayer && - !gfxPrefs::AsyncPanZoomEnabled()) + !nsLayoutUtils::AsyncPanZoomEnabled(aContainerFrame)) { // Since we don't want any component alpha layers on BasicLayers, we repeat // the layer building process with this explicitely forced off. diff --git a/layout/base/SelectionCarets.cpp b/layout/base/SelectionCarets.cpp index b099f1431ba..def5269122a 100644 --- a/layout/base/SelectionCarets.cpp +++ b/layout/base/SelectionCarets.cpp @@ -33,6 +33,7 @@ #include "mozilla/dom/TreeWalker.h" #include "mozilla/Preferences.h" #include "mozilla/TouchEvents.h" +#include "Layers.h" #include "TouchCaret.h" #include "nsFrameSelection.h" @@ -116,7 +117,7 @@ SelectionCarets::Init() } #if defined(MOZ_WIDGET_GONK) - mUseAsyncPanZoom = gfxPrefs::AsyncPanZoomEnabled(); + mUseAsyncPanZoom = mPresShell->AsyncPanZoomEnabled(); #endif docShell->AddWeakReflowObserver(this); diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 638eb93f9d8..a5071a964f5 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -635,7 +635,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, mHaveScrollableDisplayPort(false), mWindowDraggingAllowed(false), mIsBuildingForPopup(nsLayoutUtils::IsPopup(aReferenceFrame)), - mForceLayerForScrollParent(false) + mForceLayerForScrollParent(false), + mAsyncPanZoomEnabled(nsLayoutUtils::AsyncPanZoomEnabled(aReferenceFrame)) { MOZ_COUNT_CTOR(nsDisplayListBuilder); PL_InitArenaPool(&mPool, "displayListArena", 1024, @@ -1553,7 +1554,7 @@ already_AddRefed nsDisplayList::PaintRoot(nsDisplayListBuilder* aB // Add metrics if there are none in the layer tree with the id (create an id // if there isn't one already) of the root scroll frame/root content. bool ensureMetricsForRootId = - gfxPrefs::AsyncPanZoomEnabled() && + nsLayoutUtils::AsyncPanZoomEnabled(frame) && !gfxPrefs::LayoutUseContainersForRootFrames() && aBuilder->IsPaintingToWindow() && !presContext->GetParentPresContext(); @@ -2333,7 +2334,7 @@ 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() || + if (nsLayoutUtils::UsesAsyncScrolling(mFrame) || (aManager && aManager->ShouldAvoidComponentAlphaLayers())) { return false; } @@ -4275,7 +4276,7 @@ nsDisplaySubDocument::ComputeVisibility(nsDisplayListBuilder* aBuilder, // 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()) { + if (!nsLayoutUtils::UsesAsyncScrolling(mFrame)) { bool snap; nsRect bounds = GetBounds(aBuilder, &snap); nsRegion removed; diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 5a6147963fd..884e6fc33db 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -350,8 +350,8 @@ public: if (mMode == PAINTING) { // Note: this is the only place that gets to query LayoutEventRegionsEnabled // 'directly' - other code should call this function. - return (gfxPrefs::LayoutEventRegionsEnabledDoNotUseDirectly() || - gfxPrefs::AsyncPanZoomEnabled()); + return gfxPrefs::LayoutEventRegionsEnabledDoNotUseDirectly() || + mAsyncPanZoomEnabled; } return false; } @@ -996,6 +996,7 @@ private: bool mWindowDraggingAllowed; bool mIsBuildingForPopup; bool mForceLayerForScrollParent; + bool mAsyncPanZoomEnabled; }; class nsDisplayItem; diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index e558636a1a8..bc69cd4d847 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1368,6 +1368,12 @@ public: */ virtual LayerManager* GetLayerManager() = 0; + /** + * Return true iff there is a widget rendering this presShell and that + * widget is APZ-enabled. + */ + virtual bool AsyncPanZoomEnabled() = 0; + /** * Track whether we're ignoring viewport scrolling for the purposes * of painting. If we are ignoring, then layers aren't clipped to diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index e9a885122ce..fc550dc932e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -815,6 +815,34 @@ ApplyRectMultiplier(nsRect aRect, float aMultiplier) 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 @@ -1093,9 +1121,12 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent, aMargins, aPriority), nsINode::DeleteProperty); - if (nsLayoutUtils::UsesAsyncScrolling() && gfxPrefs::LayoutUseContainersForRootFrames()) { + if (gfxPrefs::LayoutUseContainersForRootFrames()) { nsIFrame* rootScrollFrame = aPresShell->GetRootScrollFrame(); - if (rootScrollFrame && aContent == rootScrollFrame->GetContent()) { + if (rootScrollFrame && + aContent == rootScrollFrame->GetContent() && + nsLayoutUtils::UsesAsyncScrolling(rootScrollFrame)) + { // 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. @@ -2987,7 +3018,7 @@ nsLayoutUtils::GetOrMaybeCreateDisplayPort(nsDisplayListBuilder& aBuilder, // 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() && - gfxPrefs::AsyncPanZoomEnabled() && + nsLayoutUtils::AsyncPanZoomEnabled(aScrollFrame) && !aBuilder.HaveScrollableDisplayPort() && scrollableFrame->WantAsyncScroll()) { @@ -7838,17 +7869,6 @@ nsLayoutUtils::CalculateExpandedScrollableRect(nsIFrame* aFrame) 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, diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index e6592b06f17..d6e2b655b0d 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2529,10 +2529,16 @@ public: CalculateExpandedScrollableRect(nsIFrame* aFrame); /** - * Returns true if we're using asynchronous scrolling (either through - * APZ or the android frontend). + * Returns true if the widget owning the given frame uses asynchronous + * scrolling. */ - static bool UsesAsyncScrolling(); + static bool UsesAsyncScrolling(nsIFrame* aFrame); + + /** + * Returns true if the widget owning the given frame has builtin APZ support + * enabled. + */ + static bool AsyncPanZoomEnabled(nsIFrame* aFrame); /** * Log a key/value pair for APZ testing during a paint. diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index fdd6ea10d7b..940fd020628 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -5558,6 +5558,18 @@ LayerManager* PresShell::GetLayerManager() return nullptr; } +bool PresShell::AsyncPanZoomEnabled() +{ + NS_ASSERTION(mViewManager, "Should have view manager"); + nsView* rootView = mViewManager->GetRootView(); + if (rootView) { + if (nsIWidget* widget = rootView->GetWidget()) { + return widget->AsyncPanZoomEnabled(); + } + } + return false; +} + void PresShell::SetIgnoreViewportScrolling(bool aIgnore) { if (IgnoringViewportScrolling() == aIgnore) { @@ -11053,10 +11065,10 @@ nsIPresShell::RecomputeFontSizeInflationEnabled() // Force-enabling font inflation always trumps the heuristics here. if (!FontSizeInflationForceEnabled()) { - if (TabChild::GetFrom(this)) { + if (TabChild* tab = TabChild::GetFrom(this)) { // We're in a child process. Cancel inflation if we're not // async-pan zoomed. - if (!gfxPrefs::AsyncPanZoomEnabled()) { + if (!tab->AsyncPanZoomEnabled()) { mFontSizeInflationEnabled = false; return; } diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index cfd5558b616..ca2f467f23d 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -198,6 +198,8 @@ public: virtual LayerManager* GetLayerManager() override; + virtual bool AsyncPanZoomEnabled() override; + virtual void SetIgnoreViewportScrolling(bool aIgnore) override; virtual nsresult SetResolution(float aResolution) override { diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index fa012d9354e..b06b6da430c 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1826,7 +1826,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter, if (IsAlwaysActive() && gfxPrefs::LayersTilesEnabled() && - !nsLayoutUtils::UsesAsyncScrolling() && + !nsLayoutUtils::UsesAsyncScrolling(mOuter) && 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 @@ -2030,7 +2030,7 @@ ScrollFrameHelper::ScrollToWithOrigin(nsPoint aScrollPosition, mAsyncScroll = nullptr; } - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (nsLayoutUtils::AsyncPanZoomEnabled(mOuter)) { // 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. @@ -2914,7 +2914,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, shouldBuildLayer = true; } else { shouldBuildLayer = - gfxPrefs::AsyncPanZoomEnabled() && + nsLayoutUtils::AsyncPanZoomEnabled(mOuter) && 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 @@ -3085,7 +3085,7 @@ ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer, parentLayerClip = Some(clip); } - bool thisScrollFrameUsesAsyncScrolling = nsLayoutUtils::UsesAsyncScrolling(); + bool thisScrollFrameUsesAsyncScrolling = nsLayoutUtils::UsesAsyncScrolling(mOuter); #if defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_ANDROID_APZ) // Android without apzc (aka the java pan zoom code) only uses async scrolling // for the root scroll frame of the root content document. @@ -3403,7 +3403,8 @@ ScrollFrameHelper::ScrollBy(nsIntPoint aDelta, } if (aUnit == nsIScrollableFrame::DEVICE_PIXELS && - !gfxPrefs::AsyncPanZoomEnabled()) { + !nsLayoutUtils::AsyncPanZoomEnabled(mOuter)) + { // When APZ is disabled, we must track the velocity // on the main thread; otherwise, the APZC will manage this. mVelocityQueue.Sample(GetScrollPosition()); diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 52097f26fbf..acc6ecd8926 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -299,6 +299,7 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, , mFrameLoader(aFrameLoader) , mFrameLoaderDestroyed(false) , mBackgroundColor(gfxRGBA(1, 1, 1)) + , mAsyncPanZoomEnabled(false) { *aSuccess = false; if (!mFrameLoader) { @@ -308,6 +309,9 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, *aId = 0; nsRefPtr 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 = @@ -325,7 +329,7 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, static_cast(lm.get()); clientManager->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId); } - if (gfxPrefs::AsyncPanZoomEnabled()) { + if (mAsyncPanZoomEnabled) { mContentController = new RemoteContentController(this); CompositorParent::SetControllerForLayerTree(mLayersId, mContentController); } @@ -346,7 +350,7 @@ RenderFrameParent::GetApzcTreeManager() // 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 && gfxPrefs::AsyncPanZoomEnabled()) { + if (!mApzcTreeManager && mAsyncPanZoomEnabled) { mApzcTreeManager = CompositorParent::GetAPZCTreeManager(mLayersId); } return mApzcTreeManager.get(); diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h index 9114dddf508..64abba21db1 100644 --- a/layout/ipc/RenderFrameParent.h +++ b/layout/ipc/RenderFrameParent.h @@ -151,6 +151,8 @@ private: gfxRGBA mBackgroundColor; nsRegion mTouchRegion; + + bool mAsyncPanZoomEnabled; }; } // namespace layout diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js index 5721021fcfd..263feb65b1f 100644 --- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -745,7 +745,7 @@ function BuildConditionSandbox(aURL) { sandbox.Mulet = gB2GisMulet; try { - sandbox.asyncPanZoom = prefs.getBoolPref("layers.async-pan-zoom.enabled"); + sandbox.asyncPanZoom = gContainingWindow.document.docShell.asyncPanZoomEnabled; } catch (e) { sandbox.asyncPanZoom = false; } diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 3d1e6f9964f..0f73ad0ed08 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -344,7 +344,7 @@ PuppetWidget::DispatchInputEvent(WidgetInputEvent* aEvent) nsEventStatus PuppetWidget::DispatchAPZAwareEvent(WidgetInputEvent* aEvent) { - if (!gfxPrefs::AsyncPanZoomEnabled()) { + if (!AsyncPanZoomEnabled()) { nsEventStatus status = nsEventStatus_eIgnore; DispatchEvent(aEvent, status); return status; @@ -483,6 +483,12 @@ PuppetWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId, } } +bool +PuppetWidget::AsyncPanZoomEnabled() const +{ + return mTabChild && mTabChild->AsyncPanZoomEnabled(); +} + NS_IMETHODIMP_(bool) PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType, const mozilla::WidgetKeyboardEvent& aEvent, diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index a52d36946ff..60f6b5c2819 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -135,6 +135,7 @@ public: nsEventStatus DispatchInputEvent(WidgetInputEvent* aEvent) override; void SetConfirmedTargetAPZC(uint64_t aInputBlockId, const nsTArray& aTargets) const override; + bool AsyncPanZoomEnabled() const override; NS_IMETHOD CaptureRollupEvents(nsIRollupListener* aListener, bool aDoCapture) override diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index e8b72b06517..91e55d637d8 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -1010,6 +1010,12 @@ nsBaseWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId, mAPZC.get(), setTargetApzcFunc, aInputBlockId, mozilla::Move(aTargets))); } +bool +nsBaseWidget::AsyncPanZoomEnabled() const +{ + return !!mAPZC; +} + nsEventStatus nsBaseWidget::ProcessUntransformedAPZEvent(WidgetInputEvent* aEvent, const ScrollableLayerGuid& aGuid, diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index 8687f27a26b..697bea1dfbf 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -243,6 +243,8 @@ public: void SetConfirmedTargetAPZC(uint64_t aInputBlockId, const nsTArray& aTargets) const override; + bool AsyncPanZoomEnabled() const override; + void NotifyWindowDestroyed(); void NotifySizeMoveDone(); void NotifyWindowMoved(int32_t aX, int32_t aY); diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 889077983fe..92e348e6040 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -1820,6 +1820,11 @@ class nsIWidget : public nsISupports { virtual void SetConfirmedTargetAPZC(uint64_t aInputBlockId, const nsTArray& 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) *