Bug 1307242 - Add infrastructure for measuring time to non-blank paint. r=bkelly, a=lizzard
☠☠ backed out by fb7bda53c7d2 ☠ ☠
authorMarkus Stange <mstange@themasta.com>
Thu, 10 Nov 2016 16:00:45 -0500
changeset 357118 b667cea81ab17ee5ec759eb40a7da8fd9b2c61f8
parent 357117 a482ea2517c4f48abbb597bf1f190ecfd6a29677
child 357119 f4ec73e21b66f0a1c2c151c995f36bc5034ce212
push id6751
push userryanvm@gmail.com
push dateSat, 07 Jan 2017 17:40:00 +0000
treeherdermozilla-beta@d78b42d605ca [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly, lizzard
bugs1307242
milestone51.0
Bug 1307242 - Add infrastructure for measuring time to non-blank paint. r=bkelly, a=lizzard MozReview-Commit-ID: LZBQOvKZYes
dom/base/nsDOMNavigationTiming.cpp
dom/base/nsDOMNavigationTiming.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
--- a/dom/base/nsDOMNavigationTiming.cpp
+++ b/dom/base/nsDOMNavigationTiming.cpp
@@ -1,20 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 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 "nsDOMNavigationTiming.h"
+
+#include "GeckoProfiler.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "prtime.h"
 #include "nsIURI.h"
+#include "nsPrintfCString.h"
 #include "mozilla/dom/PerformanceNavigation.h"
 #include "mozilla/TimeStamp.h"
 
 nsDOMNavigationTiming::nsDOMNavigationTiming()
 {
   Clear();
 }
 
@@ -176,16 +179,40 @@ nsDOMNavigationTiming::NotifyDOMContentL
 {
   if (!mDOMContentLoadedEventEndSet) {
     mLoadedURI = aURI;
     mDOMContentLoadedEventEnd = DurationFromStart();
     mDOMContentLoadedEventEndSet = true;
   }
 }
 
+void
+nsDOMNavigationTiming::NotifyNonBlankPaint()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(!mNavigationStartTimeStamp.IsNull());
+
+  if (!mNonBlankPaintTimeStamp.IsNull()) {
+    return;
+  }
+
+  mNonBlankPaintTimeStamp = TimeStamp::Now();
+  TimeDuration elapsed = mNonBlankPaintTimeStamp - mNavigationStartTimeStamp;
+
+  if (profiler_is_active()) {
+    nsAutoCString spec;
+    if (mLoadedURI) {
+      mLoadedURI->GetSpec(spec);
+    }
+    nsPrintfCString marker("Non-blank paint after %dms for URL %s",
+                           int(elapsed.ToMilliseconds()), spec.get());
+    PROFILER_MARKER(marker.get());
+  }
+}
+
 DOMTimeMilliSec
 nsDOMNavigationTiming::GetUnloadEventStart()
 {
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   nsresult rv = ssm->CheckSameOriginURI(mLoadedURI, mUnloadedURI, false);
   if (NS_SUCCEEDED(rv)) {
     return mUnloadStart;
   }
--- a/dom/base/nsDOMNavigationTiming.h
+++ b/dom/base/nsDOMNavigationTiming.h
@@ -92,16 +92,19 @@ public:
 
   // Document changes state to 'loading' before connecting to timing
   void SetDOMLoadingTimeStamp(nsIURI* aURI, mozilla::TimeStamp aValue);
   void NotifyDOMLoading(nsIURI* aURI);
   void NotifyDOMInteractive(nsIURI* aURI);
   void NotifyDOMComplete(nsIURI* aURI);
   void NotifyDOMContentLoadedStart(nsIURI* aURI);
   void NotifyDOMContentLoadedEnd(nsIURI* aURI);
+
+  void NotifyNonBlankPaint();
+
   DOMTimeMilliSec TimeStampToDOM(mozilla::TimeStamp aStamp) const;
 
   inline DOMHighResTimeStamp TimeStampToDOMHighRes(mozilla::TimeStamp aStamp)
   {
     mozilla::TimeDuration duration = aStamp - mNavigationStartTimeStamp;
     return duration.ToMilliseconds();
   }
 
@@ -112,16 +115,17 @@ private:
   void Clear();
 
   nsCOMPtr<nsIURI> mUnloadedURI;
   nsCOMPtr<nsIURI> mLoadedURI;
 
   Type mNavigationType;
   DOMHighResTimeStamp mNavigationStartHighRes;
   mozilla::TimeStamp mNavigationStartTimeStamp;
+  mozilla::TimeStamp mNonBlankPaintTimeStamp;
   DOMTimeMilliSec DurationFromStart();
 
   DOMTimeMilliSec mBeforeUnloadStart;
   DOMTimeMilliSec mUnloadStart;
   DOMTimeMilliSec mUnloadEnd;
   DOMTimeMilliSec mLoadEventStart;
   DOMTimeMilliSec mLoadEventEnd;
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2742,16 +2742,27 @@ nsPresContext::IsRootContentDocument() c
   if (!view) {
     return true;
   }
 
   nsIFrame* f = view->GetFrame();
   return (f && f->PresContext()->IsChrome());
 }
 
+void
+nsPresContext::NotifyNonBlankPaint()
+{
+  MOZ_ASSERT(!mHadNonBlankPaint);
+  mHadNonBlankPaint = true;
+  RefPtr<nsDOMNavigationTiming> timing = mDocument->GetNavigationTiming();
+  if (timing) {
+    timing->NotifyNonBlankPaint();
+  }
+}
+
 bool nsPresContext::GetPaintFlashing() const
 {
   if (!mPaintFlashingInitialized) {
     bool pref = Preferences::GetBool("nglayout.debug.paint_flashing");
     if (!pref && IsChrome()) {
       pref = Preferences::GetBool("nglayout.debug.paint_flashing_chrome");
     }
     mPaintFlashing = pref;
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1048,16 +1048,22 @@ public:
 
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
   bool IsRootContentDocument() const;
 
+  bool HadNonBlankPaint() const {
+    return mHadNonBlankPaint;
+  }
+
+  void NotifyNonBlankPaint();
+
   bool IsGlyph() const {
     return mIsGlyph;
   }
 
   void SetIsGlyph(bool aValue) {
     mIsGlyph = aValue;
   }
 
@@ -1390,16 +1396,19 @@ protected:
   unsigned mHasWarnedAboutTooLargeDashedOrDottedRadius : 1;
 
   // Have we added quirk.css to the style set?
   unsigned              mQuirkSheetAdded : 1;
 
   // Is there a pref update to process once we have a container?
   unsigned              mNeedsPrefUpdate : 1;
 
+  // Has NotifyNonBlankPaint been called on this PresContext?
+  unsigned              mHadNonBlankPaint : 1;
+
 #ifdef RESTYLE_LOGGING
   // Should we output debug information about restyling for this document?
   bool                  mRestyleLoggingEnabled;
 #endif
 
 #ifdef DEBUG
   bool                  mInitialized;
 #endif