Bug 1335895 - part 16: Update AsyncCompositionManager to support toolbar animator r=kats,botond
-Notify on first paint
-Notify on layer update
-Adjust fixed frame margin
-Support snapshot animating
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -34,16 +34,17 @@
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "nsRegion.h" // for nsIntRegion
#include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc
#include "nsTArrayForwardDeclare.h" // for InfallibleTArray
#include "UnitTransforms.h" // for TransformTo
#include "gfxPrefs.h"
#if defined(MOZ_WIDGET_ANDROID)
# include <android/log.h>
+# include "mozilla/layers/UiCompositorControllerParent.h"
# include "mozilla/widget/AndroidCompositorWidget.h"
#endif
#include "GeckoProfiler.h"
#include "FrameUniformityData.h"
#include "TreeTraversal.h" // for ForEachNode, BreadthFirstSearch
#include "VsyncSource.h"
struct nsCSSValueSharedList;
@@ -849,16 +850,17 @@ AsyncCompositionManager::ApplyAsyncConte
{
Maybe<ParentLayerIntRect> clipDeferredFromChildren = stackDeferredClips.top();
stackDeferredClips.pop();
LayerToParentLayerMatrix4x4 oldTransform = layer->GetTransformTyped() *
AsyncTransformMatrix();
AsyncTransformComponentMatrix combinedAsyncTransform;
bool hasAsyncTransform = false;
+ // Only set on the root layer for Android.
ScreenMargin fixedLayerMargins;
// Each layer has multiple clips:
// - Its local clip, which is fixed to the layer contents, i.e. it moves
// with those async transforms which the layer contents move with.
// - Its scrolled clip, which moves with all async transforms.
// - For each ScrollMetadata on the layer, a scroll clip. This includes
// the composition bounds and any other clips induced by layout. This
@@ -938,40 +940,35 @@ AsyncCompositionManager::ApplyAsyncConte
// should not need the root content metrics at all. See bug 1201529 comment
// 6 for details.
if (!(*aOutFoundRoot)) {
*aOutFoundRoot = metrics.IsRootContent() || /* RCD */
(layer->GetParent() == nullptr && /* rootmost metrics */
i + 1 >= layer->GetScrollMetadataCount());
if (*aOutFoundRoot) {
mRootScrollableId = metrics.GetScrollId();
- CSSToLayerScale geckoZoom = metrics.LayersPixelsPerCSSPixel().ToScaleFactor();
+ Compositor* compositor = mLayerManager->GetCompositor();
if (mIsFirstPaint) {
- LayerIntPoint scrollOffsetLayerPixels = RoundedToInt(metrics.GetScrollOffset() * geckoZoom);
- mContentRect = metrics.GetScrollableRect();
- SetFirstPaintViewport(scrollOffsetLayerPixels,
- geckoZoom,
- mContentRect);
- } else {
- ParentLayerPoint scrollOffset = controller->GetCurrentAsyncScrollOffset(
- AsyncPanZoomController::RESPECT_FORCE_DISABLE);
- // Compute the painted displayport in document-relative CSS pixels.
- CSSRect displayPort(metrics.GetCriticalDisplayPort().IsEmpty() ?
- metrics.GetDisplayPort() :
- metrics.GetCriticalDisplayPort());
- displayPort += metrics.GetScrollOffset();
- SyncFrameMetrics(scrollOffset,
- geckoZoom * asyncTransformWithoutOverscroll.mScale,
- metrics.GetScrollableRect(), displayPort, geckoZoom, mLayersUpdated,
- mPaintSyncId, fixedLayerMargins);
- mFixedLayerMargins = fixedLayerMargins;
+ if (CompositorBridgeParent* bridge = compositor->GetCompositorBridgeParent()) {
+ AndroidDynamicToolbarAnimator* animator = bridge->GetAPZCTreeManager()->GetAndroidDynamicToolbarAnimator();
+ MOZ_ASSERT(animator);
+ animator->UpdateRootFrameMetrics(metrics);
+ animator->FirstPaint();
+ }
+ }
+ if (mLayersUpdated) {
+ if (CompositorBridgeParent* bridge = compositor->GetCompositorBridgeParent()) {
+ AndroidDynamicToolbarAnimator* animator = bridge->GetAPZCTreeManager()->GetAndroidDynamicToolbarAnimator();
+ MOZ_ASSERT(animator);
+ animator->NotifyLayersUpdated();
+ }
mLayersUpdated = false;
- mPaintSyncId = 0;
}
mIsFirstPaint = false;
+ fixedLayerMargins = mFixedLayerMargins;
}
}
#else
*aOutFoundRoot = false;
// Non-Android platforms still care about this flag being cleared after
// the first call to TransformShadowTree().
mIsFirstPaint = false;
#endif
@@ -1370,16 +1367,34 @@ AsyncCompositionManager::TransformShadow
animationProcess, layerAreaAnimated, aVsyncRate);
if (!wantNextFrame) {
// Clean up the CompositorAnimationStorage because
// there are no active animations running
storage->Clear();
}
+ // Advance animations to the next expected vsync timestamp, if we can
+ // get it.
+ TimeStamp nextFrame = aCurrentFrame;
+
+ MOZ_ASSERT(aVsyncRate != TimeDuration::Forever());
+ if (aVsyncRate != TimeDuration::Forever()) {
+ nextFrame += aVsyncRate;
+ }
+
+#if defined(MOZ_WIDGET_ANDROID)
+ Compositor* compositor = mLayerManager->GetCompositor();
+ if (CompositorBridgeParent* bridge = compositor->GetCompositorBridgeParent()) {
+ AndroidDynamicToolbarAnimator* animator = bridge->GetAPZCTreeManager()->GetAndroidDynamicToolbarAnimator();
+ MOZ_ASSERT(animator);
+ wantNextFrame |= animator->UpdateAnimation(nextFrame);
+ }
+#endif // defined(MOZ_WIDGET_ANDROID)
+
// Reset the previous time stamp if we don't already have any running
// animations to avoid using the time which is far behind for newly
// started animations.
mPreviousFrameTimeStamp = wantNextFrame ? aCurrentFrame : TimeStamp();
if (!(aSkip & TransformsToSkip::APZ)) {
// FIXME/bug 775437: unify this interface with the ~native-fennec
// derived code
@@ -1397,25 +1412,16 @@ AsyncCompositionManager::TransformShadow
#if defined(MOZ_WIDGET_ANDROID)
MOZ_ASSERT(foundRoot);
if (foundRoot && mFixedLayerMargins != ScreenMargin()) {
MoveScrollbarForLayerMargin(root, mRootScrollableId, mFixedLayerMargins);
}
#endif
}
- // Advance APZ animations to the next expected vsync timestamp, if we can
- // get it.
- TimeStamp nextFrame = aCurrentFrame;
-
- MOZ_ASSERT(aVsyncRate != TimeDuration::Forever());
- if (aVsyncRate != TimeDuration::Forever()) {
- nextFrame += aVsyncRate;
- }
-
bool apzAnimating = SampleAPZAnimations(LayerMetricsWrapper(root), nextFrame);
mAnimationMetricsTracker.UpdateApzAnimationInProgress(apzAnimating, aVsyncRate);
wantNextFrame |= apzAnimating;
}
HostLayer* rootComposite = root->AsHostLayer();
gfx::Matrix4x4 trans = rootComposite->GetShadowBaseTransform();
@@ -1424,47 +1430,18 @@ AsyncCompositionManager::TransformShadow
if (gfxPrefs::CollectScrollTransforms()) {
RecordShadowTransforms(root);
}
return wantNextFrame;
}
-void
-AsyncCompositionManager::SetFirstPaintViewport(const LayerIntPoint& aOffset,
- const CSSToLayerScale& aZoom,
- const CSSRect& aCssPageRect)
-{
-#ifdef MOZ_WIDGET_ANDROID
- widget::AndroidCompositorWidget* widget =
- mLayerManager->GetCompositor()->GetWidget()->AsAndroid();
- if (!widget) {
- return;
- }
- widget->SetFirstPaintViewport(aOffset, aZoom, aCssPageRect);
-#endif
-}
-
+#if defined(MOZ_WIDGET_ANDROID)
void
-AsyncCompositionManager::SyncFrameMetrics(const ParentLayerPoint& aScrollOffset,
- const CSSToParentLayerScale& aZoom,
- const CSSRect& aCssPageRect,
- const CSSRect& aDisplayPort,
- const CSSToLayerScale& aPaintedResolution,
- bool aLayersUpdated,
- int32_t aPaintSyncId,
- ScreenMargin& aFixedLayerMargins)
+AsyncCompositionManager::SetFixedLayerMarginsBottom(ScreenIntCoord aBottom)
{
-#ifdef MOZ_WIDGET_ANDROID
- widget::AndroidCompositorWidget* widget =
- mLayerManager->GetCompositor()->GetWidget()->AsAndroid();
- if (!widget) {
- return;
- }
- widget->SyncFrameMetrics(
- aScrollOffset, aZoom, aCssPageRect, aDisplayPort, aPaintedResolution,
- aLayersUpdated, aPaintSyncId, aFixedLayerMargins);
-#endif
+ mFixedLayerMargins.bottom = aBottom;
}
+#endif // defined(MOZ_WIDGET_ANDROID)
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -73,17 +73,17 @@ public:
explicit AsyncCompositionManager(CompositorBridgeParent* aParent, HostLayerManager* aManager);
/**
* This forces the is-first-paint flag to true. This is intended to
* be called by the widget code when it loses its viewport information
* (or for whatever reason wants to refresh the viewport information).
* The information refresh happens because the compositor will call
- * SetFirstPaintViewport on the next frame of composition.
+ * AndroidDynamicToolbarAnimator::FirstPaint() on the next frame of composition.
*/
void ForceIsFirstPaint() { mIsFirstPaint = true; }
// Sample transforms for layer trees. Return true to request
// another animation frame.
enum class TransformsToSkip : uint8_t { NoneOfThem = 0, APZ = 1 };
bool TransformShadowTree(TimeStamp aCurrentFrame,
TimeDuration aVsyncRate,
@@ -144,28 +144,16 @@ private:
bool ApplyAsyncContentTransformToTree(Layer* aLayer,
bool* aOutFoundRoot);
/**
* Update the shadow transform for aLayer assuming that is a scrollbar,
* so that it stays in sync with the content that is being scrolled by APZ.
*/
void ApplyAsyncTransformToScrollbar(Layer* aLayer);
- void SetFirstPaintViewport(const LayerIntPoint& aOffset,
- const CSSToLayerScale& aZoom,
- const CSSRect& aCssPageRect);
- void SyncFrameMetrics(const ParentLayerPoint& aScrollOffset,
- const CSSToParentLayerScale& aZoom,
- const CSSRect& aCssPageRect,
- const CSSRect& aDisplayPort,
- const CSSToLayerScale& aPaintedResolution,
- bool aLayersUpdated,
- int32_t aPaintSyncId,
- ScreenMargin& aFixedLayerMargins);
-
/**
* Adds a translation to the transform of any fixed position (whose parent
* layer is not fixed) or sticky position layer descendant of
* |aTransformedSubtreeRoot|. The translation is chosen so that the layer's
* anchor point relative to |aTransformedSubtreeRoot|'s parent layer is the same
* as it was when |aTransformedSubtreeRoot|'s GetLocalTransform() was
* |aPreviousTransformForRoot|. |aCurrentTransformForRoot| is
* |aTransformedSubtreeRoot|'s current GetLocalTransform() modulo any
@@ -239,16 +227,19 @@ private:
LayerTransformRecorder mLayerTransformRecorder;
TimeStamp mPreviousFrameTimeStamp;
AnimationMetricsTracker mAnimationMetricsTracker;
CompositorBridgeParent* mCompositorBridge;
#ifdef MOZ_WIDGET_ANDROID
+public:
+ void SetFixedLayerMarginsBottom(ScreenIntCoord aBottom);
+private:
// The following two fields are only needed on Fennec with C++ APZ, because
// then we need to reposition the gecko scrollbar to deal with the
// dynamic toolbar shifting content around.
FrameMetrics::ViewID mRootScrollableId;
ScreenMargin mFixedLayerMargins;
#endif
};