Bug 1339220 - Add telemetry probes to measure duration and max-area of animations in the compositor. r=botond,bsmedberg
MozReview-Commit-ID: KyvsNSTcxG8
new file mode 100644
--- /dev/null
+++ b/gfx/layers/composite/AnimationMetricsTracker.cpp
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "mozilla/layers/AnimationMetricsTracker.h"
+
+#include <algorithm>
+#include <inttypes.h>
+#include "mozilla/Telemetry.h"
+
+#define AMT_LOG(...)
+// #define AMT_LOG(...) printf_stderr("AMT: " __VA_ARGS__)
+
+namespace mozilla {
+namespace layers {
+
+AnimationMetricsTracker::AnimationMetricsTracker()
+{
+}
+
+AnimationMetricsTracker::~AnimationMetricsTracker()
+{
+}
+
+void
+AnimationMetricsTracker::UpdateAnimationInProgress(bool aInProgress,
+ uint64_t aLayerArea)
+{
+ MOZ_ASSERT(aInProgress || aLayerArea == 0);
+ if (mCurrentAnimationStart && !aInProgress) {
+ AnimationEnded();
+ mCurrentAnimationStart = TimeStamp();
+ mMaxLayerAreaAnimated = 0;
+ } else if (aInProgress) {
+ if (!mCurrentAnimationStart) {
+ mCurrentAnimationStart = TimeStamp::Now();
+ mMaxLayerAreaAnimated = aLayerArea;
+ AnimationStarted();
+ } else {
+ mMaxLayerAreaAnimated = std::max(mMaxLayerAreaAnimated, aLayerArea);
+ }
+ }
+}
+
+void
+AnimationMetricsTracker::AnimationStarted()
+{
+}
+
+void
+AnimationMetricsTracker::AnimationEnded()
+{
+ MOZ_ASSERT(mCurrentAnimationStart);
+ Telemetry::AccumulateTimeDelta(Telemetry::COMPOSITOR_ANIMATION_DURATION, mCurrentAnimationStart);
+ Telemetry::Accumulate(Telemetry::COMPOSITOR_ANIMATION_MAX_LAYER_AREA, mMaxLayerAreaAnimated);
+ AMT_LOG("Ended animation; duration: %f ms, area: %" PRIu64 "\n",
+ (TimeStamp::Now() - mCurrentAnimationStart).ToMilliseconds(),
+ mMaxLayerAreaAnimated);
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/composite/AnimationMetricsTracker.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef mozilla_layers_AnimationMetricsTracker_h
+#define mozilla_layers_AnimationMetricsTracker_h
+
+#include "mozilla/TimeStamp.h"
+
+namespace mozilla {
+namespace layers {
+
+/**
+ * Tracks the start and end of compositor animations.
+ */
+class AnimationMetricsTracker {
+public:
+ AnimationMetricsTracker();
+ ~AnimationMetricsTracker();
+
+ /**
+ * This function should be called per composite, to inform the metrics
+ * tracker if any animation is in progress, and if so, what area is
+ * being animated. The aLayerArea is in Layer pixels squared.
+ */
+ void UpdateAnimationInProgress(bool aInProgress, uint64_t aLayerArea);
+
+private:
+ void AnimationStarted();
+ void AnimationEnded();
+
+ TimeStamp mCurrentAnimationStart;
+ uint64_t mMaxLayerAreaAnimated;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_AnimationMetricsTracker_h
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -629,38 +629,41 @@ ApplyAnimatedValue(Layer* aLayer,
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unhandled animated property");
}
}
static bool
-SampleAnimations(Layer* aLayer, TimeStamp aPoint)
+SampleAnimations(Layer* aLayer, TimeStamp aPoint, uint64_t* aLayerAreaAnimated)
{
bool activeAnimations = false;
ForEachNode<ForwardIterator>(
aLayer,
- [&activeAnimations, &aPoint] (Layer* layer)
+ [&activeAnimations, &aPoint, &aLayerAreaAnimated] (Layer* layer)
{
bool hasInEffectAnimations = false;
StyleAnimationValue animationValue = layer->GetBaseAnimationStyle();
activeAnimations |=
AnimationHelper::SampleAnimationForEachNode(aPoint,
layer->GetAnimations(),
layer->GetAnimationData(),
animationValue,
hasInEffectAnimations);
if (hasInEffectAnimations) {
Animation& animation = layer->GetAnimations().LastElement();
ApplyAnimatedValue(layer,
animation.property(),
animation.data(),
animationValue);
+ if (aLayerAreaAnimated) {
+ *aLayerAreaAnimated += (layer->GetVisibleRegion().Area());
+ }
}
});
return activeAnimations;
}
static bool
SampleAPZAnimations(const LayerMetricsWrapper& aLayer, TimeStamp aSampleTime)
{
@@ -1306,19 +1309,23 @@ AsyncCompositionManager::TransformShadow
// First, compute and set the shadow transforms from OMT animations.
// NB: we must sample animations *before* sampling pan/zoom
// transforms.
// Use a previous vsync time to make main thread animations and compositor
// more in sync with each other.
// On the initial frame we use aVsyncTimestamp here so the timestamp on the
// second frame are the same as the initial frame, but it does not matter.
+ uint64_t layerAreaAnimated = 0;
bool wantNextFrame = SampleAnimations(root,
!mPreviousFrameTimeStamp.IsNull() ?
- mPreviousFrameTimeStamp : aCurrentFrame);
+ mPreviousFrameTimeStamp : aCurrentFrame,
+ &layerAreaAnimated);
+ mAnimationMetricsTracker.UpdateAnimationInProgress(
+ wantNextFrame, layerAreaAnimated);
// 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
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -9,16 +9,17 @@
#include "Units.h" // for ScreenPoint, etc
#include "mozilla/layers/LayerManagerComposite.h" // for LayerManagerComposite
#include "mozilla/Attributes.h" // for final, etc
#include "mozilla/RefPtr.h" // for RefCounted
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
+#include "mozilla/layers/AnimationMetricsTracker.h" // for AnimationMetricsTracker
#include "mozilla/layers/FrameUniformityData.h" // For FrameUniformityData
#include "mozilla/layers/LayersMessages.h" // for TargetConfig
#include "mozilla/RefPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc
namespace mozilla {
namespace layers {
@@ -233,16 +234,17 @@ private:
int32_t mPaintSyncId;
bool mReadyForCompose;
gfx::Matrix mWorldTransform;
LayerTransformRecorder mLayerTransformRecorder;
TimeStamp mPreviousFrameTimeStamp;
+ AnimationMetricsTracker mAnimationMetricsTracker;
#ifdef MOZ_WIDGET_ANDROID
// 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
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -137,16 +137,17 @@ EXPORTS.mozilla.layers += [
'client/GPUVideoTextureClient.h',
'client/ImageClient.h',
'client/SingleTiledContentClient.h',
'client/TextureClient.h',
'client/TextureClientPool.h',
'client/TextureClientRecycleAllocator.h',
'client/TextureClientSharedSurface.h',
'client/TiledContentClient.h',
+ 'composite/AnimationMetricsTracker.h',
'composite/AsyncCompositionManager.h',
'composite/CanvasLayerComposite.h',
'composite/ColorLayerComposite.h',
'composite/ContainerLayerComposite.h',
'composite/ContentHost.h',
'composite/FrameUniformityData.h',
'composite/GPUVideoTextureHost.h',
'composite/ImageComposite.h',
@@ -317,16 +318,17 @@ UNIFIED_SOURCES += [
'client/GPUVideoTextureClient.cpp',
'client/ImageClient.cpp',
'client/SingleTiledContentClient.cpp',
'client/TextureClient.cpp',
'client/TextureClientPool.cpp',
'client/TextureClientRecycleAllocator.cpp',
'client/TextureClientSharedSurface.cpp',
'client/TiledContentClient.cpp',
+ 'composite/AnimationMetricsTracker.cpp',
'composite/AsyncCompositionManager.cpp',
'composite/CanvasLayerComposite.cpp',
'composite/ColorLayerComposite.cpp',
'composite/CompositableHost.cpp',
'composite/ContainerLayerComposite.cpp',
'composite/ContentHost.cpp',
'composite/FPSCounter.cpp',
'composite/FrameUniformityData.cpp',
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -252,16 +252,34 @@
},
"COMPOSITE_FRAME_ROUNDTRIP_TIME" : {
"expires_in_version": "never",
"description": "Time from vsync to finishing a composite in milliseconds.",
"kind": "exponential",
"high": 1000,
"n_buckets": 50
},
+ "COMPOSITOR_ANIMATION_DURATION" : {
+ "expires_in_version": "58",
+ "description": "Duration of animations running on the compositor in milliseconds",
+ "kind": "exponential",
+ "high": 20000,
+ "n_buckets": 50,
+ "alert_emails": ["kgupta@mozilla.com"],
+ "bug_numbers": [1339220]
+ },
+ "COMPOSITOR_ANIMATION_MAX_LAYER_AREA" : {
+ "expires_in_version": "58",
+ "description": "High-watermark of layer area affected during a compositor animation. Units are layer pixels squared.",
+ "kind": "exponential",
+ "high": 8294400,
+ "n_buckets": 50,
+ "alert_emails": ["kgupta@mozilla.com"],
+ "bug_numbers": [1339220]
+ },
"CONTENT_PROCESS_LAUNCH_TIME_MS" : {
"alert_emails": ["bsmedberg@mozilla.com", "mconley@mozilla.com"],
"expires_in_version": "57",
"bug_numbers": [1304790],
"kind": "exponential",
"high": 64000,
"n_buckets": 100,
"releaseChannelCollection": "opt-out",