LCOV - code coverage report
Current view: top level - gfx/layers/apz/src - CheckerboardEvent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 25 96 26.0 %
Date: 2017-07-14 16:53:18 Functions: 6 15 40.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=8 et tw=80 : */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "CheckerboardEvent.h"
       8             : 
       9             : #include <algorithm> // for std::sort
      10             : 
      11             : namespace mozilla {
      12             : namespace layers {
      13             : 
      14             : // Relatively arbitrary limit to prevent a perma-checkerboard event from
      15             : // eating up gobs of memory. Ideally we shouldn't have perma-checkerboarding
      16             : // but better to guard against it.
      17             : #define LOG_LENGTH_LIMIT (50 * 1024)
      18             : 
      19             : const char* CheckerboardEvent::sDescriptions[] = {
      20             :   "page",
      21             :   "painted critical displayport",
      22             :   "painted displayport",
      23             :   "requested displayport",
      24             :   "viewport",
      25             : };
      26             : 
      27             : const char* CheckerboardEvent::sColors[] = {
      28             :   "brown",
      29             :   "darkgreen",
      30             :   "lightgreen",
      31             :   "yellow",
      32             :   "red",
      33             : };
      34             : 
      35           2 : CheckerboardEvent::CheckerboardEvent(bool aRecordTrace)
      36             :   : mRecordTrace(aRecordTrace)
      37             :   , mOriginTime(TimeStamp::Now())
      38             :   , mCheckerboardingActive(false)
      39             :   , mLastSampleTime(mOriginTime)
      40             :   , mFrameCount(0)
      41             :   , mTotalPixelMs(0)
      42             :   , mPeakPixels(0)
      43           2 :   , mRendertraceLock("Rendertrace")
      44             : {
      45           2 : }
      46             : 
      47             : uint32_t
      48           0 : CheckerboardEvent::GetSeverity()
      49             : {
      50             :   // Scale the total into a 32-bit value
      51           0 :   return (uint32_t)sqrt((double)mTotalPixelMs);
      52             : }
      53             : 
      54             : uint32_t
      55           0 : CheckerboardEvent::GetPeak()
      56             : {
      57           0 :   return mPeakPixels;
      58             : }
      59             : 
      60             : TimeDuration
      61           0 : CheckerboardEvent::GetDuration()
      62             : {
      63           0 :   return mEndTime - mStartTime;
      64             : }
      65             : 
      66             : std::string
      67           0 : CheckerboardEvent::GetLog()
      68             : {
      69           0 :   MonitorAutoLock lock(mRendertraceLock);
      70           0 :   return mRendertraceInfo.str();
      71             : }
      72             : 
      73             : bool
      74           7 : CheckerboardEvent::IsRecordingTrace()
      75             : {
      76           7 :   return mRecordTrace;
      77             : }
      78             : 
      79             : void
      80          52 : CheckerboardEvent::UpdateRendertraceProperty(RendertraceProperty aProperty,
      81             :                                              const CSSRect& aRect,
      82             :                                              const std::string& aExtraInfo)
      83             : {
      84          52 :   if (!mRecordTrace) {
      85           0 :     return;
      86             :   }
      87         104 :   MonitorAutoLock lock(mRendertraceLock);
      88          52 :   if (!mCheckerboardingActive) {
      89          52 :     mBufferedProperties[aProperty].Update(aProperty, aRect, aExtraInfo, lock);
      90             :   } else {
      91           0 :     LogInfo(aProperty, TimeStamp::Now(), aRect, aExtraInfo, lock);
      92             :   }
      93             : }
      94             : 
      95             : void
      96           0 : CheckerboardEvent::LogInfo(RendertraceProperty aProperty,
      97             :                            const TimeStamp& aTimestamp,
      98             :                            const CSSRect& aRect,
      99             :                            const std::string& aExtraInfo,
     100             :                            const MonitorAutoLock& aProofOfLock)
     101             : {
     102           0 :   MOZ_ASSERT(mRecordTrace);
     103           0 :   if (mRendertraceInfo.tellp() >= LOG_LENGTH_LIMIT) {
     104             :     // The log is already long enough, don't put more things into it. We'll
     105             :     // append a truncation message when this event ends.
     106           0 :     return;
     107             :   }
     108             :   // The log is consumed by the page at http://people.mozilla.org/~kgupta/rendertrace.html
     109             :   // and will move to about:checkerboard in bug 1238042. The format is not
     110             :   // formally specced, but an informal description can be found at
     111             :   // https://github.com/staktrace/rendertrace/blob/master/index.html#L30
     112           0 :   mRendertraceInfo << "RENDERTRACE "
     113           0 :       << (aTimestamp - mOriginTime).ToMilliseconds() << " rect "
     114           0 :       << sColors[aProperty] << " "
     115           0 :       << aRect.x << " "
     116           0 :       << aRect.y << " "
     117           0 :       << aRect.width << " "
     118           0 :       << aRect.height << " "
     119             :       << "// " << sDescriptions[aProperty]
     120           0 :       << aExtraInfo << std::endl;
     121             : }
     122             : 
     123             : bool
     124          35 : CheckerboardEvent::RecordFrameInfo(uint32_t aCssPixelsCheckerboarded)
     125             : {
     126          35 :   TimeStamp sampleTime = TimeStamp::Now();
     127          35 :   bool eventEnding = false;
     128          35 :   if (aCssPixelsCheckerboarded > 0) {
     129           0 :     if (!mCheckerboardingActive) {
     130           0 :       StartEvent();
     131             :     }
     132           0 :     MOZ_ASSERT(mCheckerboardingActive);
     133           0 :     MOZ_ASSERT(sampleTime >= mLastSampleTime);
     134           0 :     mTotalPixelMs += (uint64_t)((sampleTime - mLastSampleTime).ToMilliseconds() * aCssPixelsCheckerboarded);
     135           0 :     if (aCssPixelsCheckerboarded > mPeakPixels) {
     136           0 :       mPeakPixels = aCssPixelsCheckerboarded;
     137             :     }
     138           0 :     mFrameCount++;
     139             :   } else {
     140          35 :     if (mCheckerboardingActive) {
     141           0 :       StopEvent();
     142           0 :       eventEnding = true;
     143             :     }
     144          35 :     MOZ_ASSERT(!mCheckerboardingActive);
     145             :   }
     146          35 :   mLastSampleTime = sampleTime;
     147          35 :   return eventEnding;
     148             : }
     149             : 
     150             : void
     151           0 : CheckerboardEvent::StartEvent()
     152             : {
     153           0 :   MOZ_ASSERT(!mCheckerboardingActive);
     154           0 :   mCheckerboardingActive = true;
     155           0 :   mStartTime = TimeStamp::Now();
     156             : 
     157           0 :   if (!mRecordTrace) {
     158           0 :     return;
     159             :   }
     160           0 :   MonitorAutoLock lock(mRendertraceLock);
     161           0 :   std::vector<PropertyValue> history;
     162           0 :   for (size_t i = 0; i < sRendertracePropertyCount; i++) {
     163           0 :     mBufferedProperties[i].Flush(history, lock);
     164             :   }
     165           0 :   std::sort(history.begin(), history.end());
     166           0 :   for (const PropertyValue& p : history) {
     167           0 :     LogInfo(p.mProperty, p.mTimeStamp, p.mRect, p.mExtraInfo, lock);
     168             :   }
     169           0 :   mRendertraceInfo << " -- checkerboarding starts below --" << std::endl;
     170             : }
     171             : 
     172             : void
     173           0 : CheckerboardEvent::StopEvent()
     174             : {
     175           0 :   mCheckerboardingActive = false;
     176           0 :   mEndTime = TimeStamp::Now();
     177             : 
     178           0 :   if (!mRecordTrace) {
     179           0 :     return;
     180             :   }
     181           0 :   MonitorAutoLock lock(mRendertraceLock);
     182           0 :   if (mRendertraceInfo.tellp() >= LOG_LENGTH_LIMIT) {
     183           0 :     mRendertraceInfo << "[logging aborted due to length limitations]\n";
     184             :   }
     185           0 :   mRendertraceInfo << "Checkerboarded for " << mFrameCount << " frames ("
     186           0 :     << (mEndTime - mStartTime).ToMilliseconds() << " ms), "
     187           0 :     << mPeakPixels << " peak, " << GetSeverity() << " severity." << std::endl;
     188             : }
     189             : 
     190             : bool
     191           0 : CheckerboardEvent::PropertyValue::operator<(const PropertyValue& aOther) const
     192             : {
     193           0 :   if (mTimeStamp < aOther.mTimeStamp) {
     194           0 :     return true;
     195           0 :   } else if (mTimeStamp > aOther.mTimeStamp) {
     196           0 :     return false;
     197             :   }
     198           0 :   return mProperty < aOther.mProperty;
     199             : }
     200             : 
     201          10 : CheckerboardEvent::PropertyBuffer::PropertyBuffer()
     202          10 :   : mIndex(0)
     203             : {
     204          10 : }
     205             : 
     206             : void
     207          52 : CheckerboardEvent::PropertyBuffer::Update(RendertraceProperty aProperty,
     208             :                                           const CSSRect& aRect,
     209             :                                           const std::string& aExtraInfo,
     210             :                                           const MonitorAutoLock& aProofOfLock)
     211             : {
     212          52 :   mValues[mIndex] = { aProperty, TimeStamp::Now(), aRect, aExtraInfo };
     213          52 :   mIndex = (mIndex + 1) % BUFFER_SIZE;
     214          52 : }
     215             : 
     216             : void
     217           0 : CheckerboardEvent::PropertyBuffer::Flush(std::vector<PropertyValue>& aOut,
     218             :                                          const MonitorAutoLock& aProofOfLock)
     219             : {
     220           0 :   for (uint32_t i = 0; i < BUFFER_SIZE; i++) {
     221           0 :     uint32_t ix = (mIndex + i) % BUFFER_SIZE;
     222           0 :     if (!mValues[ix].mTimeStamp.IsNull()) {
     223           0 :       aOut.push_back(mValues[ix]);
     224           0 :       mValues[ix].mTimeStamp = TimeStamp();
     225             :     }
     226             :   }
     227           0 : }
     228             : 
     229             : } // namespace layers
     230             : } // namespace mozilla

Generated by: LCOV version 1.13