LCOV - code coverage report
Current view: top level - gfx/layers/composite - AnimationMetricsTracker.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 23 64 35.9 %
Date: 2017-07-14 16:53:18 Functions: 4 7 57.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "mozilla/layers/AnimationMetricsTracker.h"
       7             : 
       8             : #include <algorithm>
       9             : #include <cmath>
      10             : #include <inttypes.h>
      11             : 
      12             : #define AMT_LOG(...)
      13             : // #define AMT_LOG(...) printf_stderr("AMT: " __VA_ARGS__)
      14             : 
      15             : namespace mozilla {
      16             : namespace layers {
      17             : 
      18           1 : AnimationMetricsTracker::AnimationMetricsTracker()
      19           1 :   : mMaxLayerAreaAnimated(0)
      20             : {
      21           1 : }
      22             : 
      23           0 : AnimationMetricsTracker::~AnimationMetricsTracker()
      24             : {
      25           0 : }
      26             : 
      27             : void
      28          29 : AnimationMetricsTracker::UpdateAnimationInProgress(AnimationProcessTypes aActive,
      29             :                                                    uint64_t aLayerArea,
      30             :                                                    TimeDuration aVsyncInterval)
      31             : {
      32          29 :   bool inProgress = (aActive != AnimationProcessTypes::eNone);
      33          29 :   MOZ_ASSERT(inProgress || aLayerArea == 0);
      34          29 :   if (mCurrentAnimationStart && !inProgress) {
      35           0 :     AnimationEnded();
      36           0 :     mCurrentAnimationStart = TimeStamp();
      37           0 :     mMaxLayerAreaAnimated = 0;
      38          29 :   } else if (inProgress) {
      39           0 :     if (!mCurrentAnimationStart) {
      40           0 :       mCurrentAnimationStart = TimeStamp::Now();
      41           0 :       mMaxLayerAreaAnimated = aLayerArea;
      42           0 :       AnimationStarted();
      43             :     } else {
      44           0 :       mMaxLayerAreaAnimated = std::max(mMaxLayerAreaAnimated, aLayerArea);
      45             :     }
      46             :   }
      47             : 
      48          58 :   UpdateAnimationThroughput("chrome",
      49          58 :                             (aActive & AnimationProcessTypes::eChrome) != AnimationProcessTypes::eNone,
      50             :                             mChromeAnimation,
      51             :                             aVsyncInterval,
      52             :                             Telemetry::COMPOSITOR_ANIMATION_THROUGHPUT_CHROME,
      53          29 :                             Telemetry::COMPOSITOR_ANIMATION_MAX_CONTIGUOUS_DROPS_CHROME);
      54          58 :   UpdateAnimationThroughput("content",
      55          58 :                             (aActive & AnimationProcessTypes::eContent) != AnimationProcessTypes::eNone,
      56             :                             mContentAnimation,
      57             :                             aVsyncInterval,
      58             :                             Telemetry::COMPOSITOR_ANIMATION_THROUGHPUT_CONTENT,
      59          29 :                             Telemetry::COMPOSITOR_ANIMATION_MAX_CONTIGUOUS_DROPS_CONTENT);
      60          29 : }
      61             : 
      62             : void
      63          29 : AnimationMetricsTracker::UpdateApzAnimationInProgress(bool aInProgress,
      64             :                                                       TimeDuration aVsyncInterval)
      65             : {
      66          29 :   UpdateAnimationThroughput("apz",
      67             :                             aInProgress,
      68             :                             mApzAnimation,
      69             :                             aVsyncInterval,
      70             :                             Telemetry::COMPOSITOR_ANIMATION_THROUGHPUT_APZ,
      71          29 :                             Telemetry::COMPOSITOR_ANIMATION_MAX_CONTIGUOUS_DROPS_APZ);
      72          29 : }
      73             : 
      74             : void
      75           0 : AnimationMetricsTracker::AnimationStarted()
      76             : {
      77           0 : }
      78             : 
      79             : void
      80           0 : AnimationMetricsTracker::AnimationEnded()
      81             : {
      82           0 :   MOZ_ASSERT(mCurrentAnimationStart);
      83             : 
      84           0 :   Telemetry::AccumulateTimeDelta(Telemetry::COMPOSITOR_ANIMATION_DURATION, mCurrentAnimationStart);
      85           0 :   Telemetry::Accumulate(Telemetry::COMPOSITOR_ANIMATION_MAX_LAYER_AREA, mMaxLayerAreaAnimated);
      86             :   AMT_LOG("Ended animation; duration: %f ms, area: %" PRIu64 "\n",
      87             :     (TimeStamp::Now() - mCurrentAnimationStart).ToMilliseconds(),
      88             :     mMaxLayerAreaAnimated);
      89           0 : }
      90             : 
      91             : void
      92          87 : AnimationMetricsTracker::UpdateAnimationThroughput(const char* aLabel,
      93             :                                                    bool aInProgress,
      94             :                                                    AnimationData& aAnimation,
      95             :                                                    TimeDuration aVsyncInterval,
      96             :                                                    Telemetry::HistogramID aThroughputHistogram,
      97             :                                                    Telemetry::HistogramID aMaxDropsHistogram)
      98             : {
      99          87 :   if (aInProgress && !aAnimation.mStart) {
     100             :     // the animation just started
     101           0 :     aAnimation.mStart = TimeStamp::Now();
     102           0 :     aAnimation.mLastFrameTime = aAnimation.mStart;
     103           0 :     aAnimation.mLongestFrame = TimeDuration();
     104           0 :     aAnimation.mFrameCount = 1;
     105             :     AMT_LOG("Compositor animation of type %s just started\n", aLabel);
     106          87 :   } else if (aInProgress && aAnimation.mStart) {
     107             :     // the animation continues
     108           0 :     aAnimation.mFrameCount++;
     109           0 :     TimeStamp now = TimeStamp::Now();
     110           0 :     aAnimation.mLongestFrame = std::max(aAnimation.mLongestFrame, now - aAnimation.mLastFrameTime);
     111           0 :     aAnimation.mLastFrameTime = now;
     112          87 :   } else if (!aInProgress && aAnimation.mStart) {
     113             :     // the animation just ended
     114             : 
     115           0 :     TimeStamp now = TimeStamp::Now();
     116             :     // Get the length and clear aAnimation.mStart before the early-returns below
     117           0 :     TimeDuration animationLength = now - aAnimation.mStart;
     118           0 :     aAnimation.mStart = TimeStamp();
     119             : 
     120           0 :     if (aVsyncInterval == TimeDuration::Forever()) {
     121             :       AMT_LOG("Invalid vsync interval: forever\n");
     122           0 :       return;
     123             :     }
     124           0 :     double vsyncIntervalMs = aVsyncInterval.ToMilliseconds();
     125           0 :     if (vsyncIntervalMs < 1.0f) {
     126             :       // Guard to avoid division by zero or other crazy results below
     127             :       AMT_LOG("Invalid vsync interval: %fms\n", vsyncIntervalMs);
     128           0 :       return;
     129             :     }
     130             : 
     131             :     // We round the expectedFrameCount because it's a count and should be an
     132             :     // integer. The animationLength might not be an exact vsync multiple because
     133             :     // it's taken during the composition process and the amount of work done
     134             :     // between the vsync signal and the Timestamp::Now() call may vary slightly
     135             :     // from one composite to another.
     136           0 :     uint32_t expectedFrameCount = std::lround(animationLength.ToMilliseconds() / vsyncIntervalMs);
     137             :     AMT_LOG("Type %s ran for %fms (interval: %fms), %u frames (expected: %u)\n",
     138             :         aLabel, animationLength.ToMilliseconds(), vsyncIntervalMs,
     139             :         aAnimation.mFrameCount, expectedFrameCount);
     140           0 :     if (expectedFrameCount <= 0) {
     141             :       // Graceful handling of probably impossible thing, unless the clock
     142             :       // changes while running?
     143             :       // Note that we also skip the frames-dropped probe if this happens,
     144             :       // because we cannot be sure that the frame length measurements are valid.
     145           0 :       return;
     146             :     }
     147             : 
     148             :     // Scale up by 1000 because telemetry takes ints, truncate intentionally
     149             :     // to avoid artificial inflation of the result.
     150           0 :     uint32_t frameHitRatio = (uint32_t)(1000.0f * aAnimation.mFrameCount / expectedFrameCount);
     151           0 :     Telemetry::Accumulate(aThroughputHistogram, frameHitRatio);
     152             :     AMT_LOG("Reported frameHitRatio %u\n", frameHitRatio);
     153             : 
     154             :     // Get the longest frame time (make sure to check the final frame as well)
     155           0 :     TimeDuration longestFrame = std::max(aAnimation.mLongestFrame, now - aAnimation.mLastFrameTime);
     156             :     // As above, we round to get the frame count. Additionally we subtract one
     157             :     // from the frame count to get the number of dropped frames.
     158           0 :     uint32_t framesDropped = std::lround(longestFrame.ToMilliseconds() / vsyncIntervalMs) - 1;
     159             :     AMT_LOG("Longest frame was %fms (%d drops)\n", longestFrame.ToMilliseconds(), framesDropped);
     160           0 :     Telemetry::Accumulate(aMaxDropsHistogram, framesDropped);
     161             :   }
     162             : }
     163             : 
     164             : } // namespace layers
     165             : } // namespace mozilla

Generated by: LCOV version 1.13