diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index 01086fbb89b0..407ff546c19a 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -1030,7 +1030,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) } bool -AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame) +AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame, + TransformsToSkip aSkip) { PROFILER_LABEL("AsyncCompositionManager", "TransformShadowTree", js::ProfileEntry::Category::GRAPHICS); @@ -1045,29 +1046,31 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame) // transforms. bool wantNextFrame = SampleAnimations(root, aCurrentFrame); - // FIXME/bug 775437: unify this interface with the ~native-fennec - // derived code - // - // Attempt to apply an async content transform to any layer that has - // an async pan zoom controller (which means that it is rendered - // async using Gecko). If this fails, fall back to transforming the - // primary scrollable layer. "Failing" here means that we don't - // find a frame that is async scrollable. Note that the fallback - // code also includes Fennec which is rendered async. Fennec uses - // its own platform-specific async rendering that is done partially - // in Gecko and partially in Java. - wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), aCurrentFrame); - if (!ApplyAsyncContentTransformToTree(root)) { - nsAutoTArray scrollableLayers; + if (!(aSkip & TransformsToSkip::APZ)) { + // FIXME/bug 775437: unify this interface with the ~native-fennec + // derived code + // + // Attempt to apply an async content transform to any layer that has + // an async pan zoom controller (which means that it is rendered + // async using Gecko). If this fails, fall back to transforming the + // primary scrollable layer. "Failing" here means that we don't + // find a frame that is async scrollable. Note that the fallback + // code also includes Fennec which is rendered async. Fennec uses + // its own platform-specific async rendering that is done partially + // in Gecko and partially in Java. + wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), aCurrentFrame); + if (!ApplyAsyncContentTransformToTree(root)) { + nsAutoTArray scrollableLayers; #ifdef MOZ_WIDGET_ANDROID - mLayerManager->GetRootScrollableLayers(scrollableLayers); + mLayerManager->GetRootScrollableLayers(scrollableLayers); #else - mLayerManager->GetScrollableLayers(scrollableLayers); + mLayerManager->GetScrollableLayers(scrollableLayers); #endif - for (uint32_t i = 0; i < scrollableLayers.Length(); i++) { - if (scrollableLayers[i]) { - TransformScrollableLayer(scrollableLayers[i]); + for (uint32_t i = 0; i < scrollableLayers.Length(); i++) { + if (scrollableLayers[i]) { + TransformScrollableLayer(scrollableLayers[i]); + } } } } diff --git a/gfx/layers/composite/AsyncCompositionManager.h b/gfx/layers/composite/AsyncCompositionManager.h index 54d02250a92b..50810af7f3ec 100644 --- a/gfx/layers/composite/AsyncCompositionManager.h +++ b/gfx/layers/composite/AsyncCompositionManager.h @@ -95,7 +95,9 @@ public: // Sample transforms for layer trees. Return true to request // another animation frame. - bool TransformShadowTree(TimeStamp aCurrentFrame); + enum class TransformsToSkip : uint8_t { NoneOfThem = 0, APZ = 1 }; + bool TransformShadowTree(TimeStamp aCurrentFrame, + TransformsToSkip aSkip = TransformsToSkip::NoneOfThem); // Calculates the correct rotation and applies the transform to // our layer manager @@ -208,6 +210,8 @@ private: gfx::Matrix mWorldTransform; }; +MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AsyncCompositionManager::TransformsToSkip) + class MOZ_STACK_CLASS AutoResolveRefLayers { public: explicit AutoResolveRefLayers(AsyncCompositionManager* aManager) : mManager(aManager) diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 83bb6420831d..6e7809b7ed98 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -1152,12 +1152,6 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, if (mPaused) { DidComposite(); } - // When testing we synchronously update the shadow tree with the animated - // values to avoid race conditions when calling GetAnimationTransform etc. - // (since the above SetShadowProperties will remove animation effects). - if (mIsTesting) { - ApplyAsyncProperties(aLayerTree); - } } mLayerManager->NotifyShadowTreeTransaction(); } @@ -1210,16 +1204,15 @@ CompositorParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree) // true or when called from test-only methods like // LayerTransactionParent::RecvGetAnimationTransform. - // Synchronously update the layer tree, but only if a composite was already - // scehduled. - if (aLayerTree->GetRoot() && - (mCurrentCompositeTask || - (mCompositorVsyncObserver && - mCompositorVsyncObserver->NeedsComposite()))) { + // Synchronously update the layer tree + if (aLayerTree->GetRoot()) { AutoResolveRefLayers resolve(mCompositionManager); + SetShadowProperties(mLayerManager->GetRoot()); + TimeStamp time = mIsTesting ? mTestTime : mLastCompose; bool requestNextFrame = - mCompositionManager->TransformShadowTree(time); + mCompositionManager->TransformShadowTree(time, + AsyncCompositionManager::TransformsToSkip::APZ); if (!requestNextFrame) { CancelCurrentCompositeTask(); // Pretend we composited in case someone is waiting for this event. diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 1a16718a0219..f392b44e89dc 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -664,6 +664,8 @@ LayerTransactionParent::RecvGetOpacity(PLayerParent* aParent, return false; } + mShadowLayersManager->ApplyAsyncProperties(this); + *aOpacity = layer->GetLocalOpacity(); return true; }