Bug 1307242 - Add infrastructure for measuring time to non-blank paint. r?bkelly
MozReview-Commit-ID: LZBQOvKZYes
--- 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
@@ -2747,16 +2747,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
@@ -1051,16 +1051,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;
}
@@ -1396,16 +1402,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