Bug 1238040 - Add a telemetry probe for potential checkerboarding duration. r=botond,vladan
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 21 Jan 2016 09:13:47 -0500
changeset 317970 7a3b839f4a8e69dedfec8205355a39aba9a6f3dd
parent 317969 e780ca0bc68dca192970a203ea6d6fcabc0cd206
child 317971 27b47b5ed8f3d858848995b368ba947e66e8ace8
push id1079
push userjlund@mozilla.com
push dateFri, 15 Apr 2016 21:02:33 +0000
treeherdermozilla-release@575fbf6786d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond, vladan
bugs1238040
milestone46.0a1
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
Bug 1238040 - Add a telemetry probe for potential checkerboarding duration. r=botond,vladan
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/apz/src/PotentialCheckerboardDurationTracker.cpp
gfx/layers/apz/src/PotentialCheckerboardDurationTracker.h
gfx/layers/moz.build
toolkit/components/telemetry/Histograms.json
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3105,25 +3105,30 @@ AsyncPanZoomController::ReportCheckerboa
   mLastCheckerboardReport = aSampleTime;
 
   bool recordTrace = gfxPrefs::APZRecordCheckerboarding();
   bool forTelemetry = Telemetry::CanRecordExtended();
   if (!mCheckerboardEvent && (recordTrace || forTelemetry)) {
     mCheckerboardEvent = MakeUnique<CheckerboardEvent>(recordTrace);
   }
   uint32_t magnitude = GetCheckerboardMagnitude();
+  if (magnitude) {
+    mPotentialCheckerboardTracker.CheckerboardSeen();
+  }
   if (mCheckerboardEvent && mCheckerboardEvent->RecordFrameInfo(magnitude)) {
     // This checkerboard event is done. Report some metrics to telemetry.
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_SEVERITY,
       mCheckerboardEvent->GetSeverity());
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_PEAK,
       mCheckerboardEvent->GetPeak());
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::CHECKERBOARD_DURATION,
       (uint32_t)mCheckerboardEvent->GetDuration().ToMilliseconds());
 
+    mPotentialCheckerboardTracker.CheckerboardDone();
+
     if (recordTrace) {
       // TODO: save the info somewhere for
       // about:checkerboard. For now we just print it.
       std::stringstream log(mCheckerboardEvent->GetLog());
       print_stderr(log);
     }
     mCheckerboardEvent = nullptr;
   }
@@ -3572,26 +3577,28 @@ void AsyncPanZoomController::DispatchSta
     ReentrantMonitorAutoEnter lock(mMonitor);
     if (mNotificationBlockers > 0) {
       return;
     }
   }
 
   if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
     if (!IsTransformingState(aOldState) && IsTransformingState(aNewState)) {
+      mPotentialCheckerboardTracker.TransformStarted();
       controller->NotifyAPZStateChange(
           GetGuid(), APZStateChange::TransformBegin);
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
       // Let the compositor know about scroll state changes so it can manage
       // windowed plugins.
       if (mCompositorParent) {
         mCompositorParent->ScheduleHideAllPluginWindows();
       }
 #endif
     } else if (IsTransformingState(aOldState) && !IsTransformingState(aNewState)) {
+      mPotentialCheckerboardTracker.TransformStopped();
       controller->NotifyAPZStateChange(
           GetGuid(), APZStateChange::TransformEnd);
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
       if (mCompositorParent) {
         mCompositorParent->ScheduleShowAllPluginWindows();
       }
 #endif
     }
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -21,16 +21,17 @@
 #include "InputData.h"
 #include "Axis.h"
 #include "InputQueue.h"
 #include "APZUtils.h"
 #include "Layers.h"                     // for Layer::ScrollDirection
 #include "LayersTypes.h"
 #include "mozilla/gfx/Matrix.h"
 #include "nsRegion.h"
+#include "PotentialCheckerboardDurationTracker.h"
 
 #include "base/message_loop.h"
 
 namespace mozilla {
 
 namespace ipc {
 
 class SharedMemoryBasic;
@@ -1100,14 +1101,18 @@ private:
    * The functions and members in this section are used for checkerboard
    * recording.
    */
 private:
   // This is created when this APZC instance is first included as part of a
   // composite. If a checkerboard event takes place, this is destroyed at the
   // end of the event, and a new one is created on the next composite.
   UniquePtr<CheckerboardEvent> mCheckerboardEvent;
+  // This is used to track the total amount of time that we could reasonably
+  // be checkerboarding. Combined with other info, this allows us to meaningfully
+  // say how frequently users actually encounter checkerboarding.
+  PotentialCheckerboardDurationTracker mPotentialCheckerboardTracker;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_PanZoomController_h
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/src/PotentialCheckerboardDurationTracker.cpp
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+/* 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 "PotentialCheckerboardDurationTracker.h"
+
+#include "mozilla/Telemetry.h"          // for Telemetry
+
+namespace mozilla {
+namespace layers {
+
+PotentialCheckerboardDurationTracker::PotentialCheckerboardDurationTracker()
+  : mInCheckerboard(false)
+  , mInTransform(false)
+{
+}
+
+void
+PotentialCheckerboardDurationTracker::CheckerboardSeen()
+{
+  // This might get called while mInCheckerboard is already true
+  if (!Tracking()) {
+    mCurrentPeriodStart = TimeStamp::Now();
+  }
+  mInCheckerboard = true;
+}
+
+void
+PotentialCheckerboardDurationTracker::CheckerboardDone()
+{
+  MOZ_ASSERT(Tracking());
+  mInCheckerboard = false;
+  if (!Tracking()) {
+    mozilla::Telemetry::AccumulateTimeDelta(
+        mozilla::Telemetry::CHECKERBOARD_POTENTIAL_DURATION,
+        mCurrentPeriodStart);
+  }
+}
+
+void
+PotentialCheckerboardDurationTracker::TransformStarted()
+{
+  MOZ_ASSERT(!mInTransform);
+  if (!Tracking()) {
+    mCurrentPeriodStart = TimeStamp::Now();
+  }
+  mInTransform = true;
+}
+
+void
+PotentialCheckerboardDurationTracker::TransformStopped()
+{
+  MOZ_ASSERT(mInTransform);
+  mInTransform = false;
+  if (!Tracking()) {
+    mozilla::Telemetry::AccumulateTimeDelta(
+        mozilla::Telemetry::CHECKERBOARD_POTENTIAL_DURATION,
+        mCurrentPeriodStart);
+  }
+}
+
+bool
+PotentialCheckerboardDurationTracker::Tracking() const
+{
+  return mInTransform || mInCheckerboard;
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/src/PotentialCheckerboardDurationTracker.h
@@ -0,0 +1,65 @@
+/* -*- 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_PotentialCheckerboardDurationTracker_h
+#define mozilla_layers_PotentialCheckerboardDurationTracker_h
+
+#include "mozilla/TimeStamp.h"
+
+namespace mozilla {
+namespace layers {
+
+/**
+ * This class allows the owner to track the duration of time considered
+ * "potentially checkerboarding". This is the union of two possibly-intersecting
+ * sets of time periods. The first set is that in which checkerboarding was
+ * actually happening, since by definition it could potentially be happening.
+ * The second set is that in which the APZC is actively transforming content
+ * in the compositor, since it could potentially transform it so as to display
+ * checkerboarding to the user.
+ * The caller of this class calls the appropriate methods to indicate the start
+ * and stop of these two sets, and this class manages accumulating the union
+ * of the various durations.
+ */
+class PotentialCheckerboardDurationTracker {
+public:
+  PotentialCheckerboardDurationTracker();
+
+  /**
+   * This should be called if checkerboarding is encountered. It can be called
+   * multiple times during a checkerboard event.
+   */
+  void CheckerboardSeen();
+  /**
+   * This should be called when checkerboarding is done. It must have been
+   * preceded by one or more calls to CheckerboardSeen().
+   */
+  void CheckerboardDone();
+
+  /**
+   * This should be called when a transform is started. Calls to this must be
+   * interleaved with calls to TransformStopped().
+   */
+  void TransformStarted();
+  /**
+   * This should be called when a transform is stopped. Calls to this must be
+   * interleaved with calls to TransformStarted().
+   */
+  void TransformStopped();
+
+private:
+  bool Tracking() const;
+
+private:
+  bool mInCheckerboard;
+  bool mInTransform;
+
+  TimeStamp mCurrentPeriodStart;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_PotentialCheckerboardDurationTracker_h
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -249,16 +249,17 @@ UNIFIED_SOURCES += [
     'apz/src/AsyncPanZoomController.cpp',
     'apz/src/Axis.cpp',
     'apz/src/CheckerboardEvent.cpp',
     'apz/src/GestureEventListener.cpp',
     'apz/src/HitTestingTreeNode.cpp',
     'apz/src/InputBlockState.cpp',
     'apz/src/InputQueue.cpp',
     'apz/src/OverscrollHandoffState.cpp',
+    'apz/src/PotentialCheckerboardDurationTracker.cpp',
     'apz/src/TouchCounter.cpp',
     'apz/src/WheelScrollAnimation.cpp',
     'apz/testutil/APZTestData.cpp',
     'apz/util/ActiveElementManager.cpp',
     'apz/util/APZCCallbackHelper.cpp',
     'apz/util/APZEventState.cpp',
     'apz/util/APZThreadUtils.cpp',
     'apz/util/ChromeProcessController.cpp',
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -101,16 +101,25 @@
     "alert_emails": ["kgupta@mozilla.com"],
     "bug_numbers": [1238040],
     "expires_in_version": "55",
     "kind": "exponential",
     "high": "3840 * 2160 * 8",
     "n_buckets": 50,
     "description": "Peak number of CSS pixels checkerboarded during a checkerboard event (the high value is the size of a 4k display with max APZ zooming)"
   },
+  "CHECKERBOARD_POTENTIAL_DURATION": {
+    "alert_emails": ["kgupta@mozilla.com"],
+    "bug_numbers": [1238040],
+    "expires_in_version": "55",
+    "kind": "exponential",
+    "high": "1000000",
+    "n_buckets": 50,
+    "description": "Duration of a chunk of time (in ms) that could reasonably have had checkerboarding"
+  },
   "CHECKERBOARD_SEVERITY": {
     "alert_emails": ["kgupta@mozilla.com"],
     "bug_numbers": [1238040],
     "expires_in_version": "55",
     "kind": "exponential",
     "high": "1073741824",
     "n_buckets": 50,
     "description": "Opaque measure of the severity of a checkerboard event"