From 334b8c80241e6453779fb1cb66546ad36d96c4f0 Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Tue, 25 Aug 2015 08:51:58 +0300 Subject: [PATCH] Bug 1050498 - Record compositing operations, r=jsantell,smaug,tromey --- .../devtools/performance/modules/markers.js | 5 ++ .../browser/devtools/markers.properties | 1 + docshell/base/nsDocShell.h | 6 ++- .../timeline/AutoGlobalTimelineMarker.cpp | 2 +- docshell/base/timeline/AutoTimelineMarker.cpp | 2 +- docshell/base/timeline/ObservedDocShell.cpp | 7 --- docshell/base/timeline/ObservedDocShell.h | 2 - docshell/base/timeline/TimelineConsumers.cpp | 52 ++++++++++++++++--- docshell/base/timeline/TimelineConsumers.h | 50 +++++++++++++++--- docshell/base/timeline/TimelineMarker.cpp | 9 ++++ docshell/base/timeline/TimelineMarker.h | 4 ++ docshell/base/timeline/moz.build | 2 + dom/ipc/TabChild.cpp | 7 ++- dom/ipc/TabChild.h | 5 +- gfx/layers/client/ClientLayerManager.cpp | 11 ++-- gfx/layers/client/ClientLayerManager.h | 4 +- gfx/layers/ipc/CompositorChild.cpp | 8 +-- gfx/layers/ipc/CompositorChild.h | 4 +- gfx/layers/ipc/CompositorParent.cpp | 37 ++++++++----- gfx/layers/ipc/CompositorParent.h | 2 +- gfx/layers/ipc/PCompositor.ipdl | 3 +- view/nsView.cpp | 21 +++++++- view/nsView.h | 3 +- widget/nsIWidgetListener.cpp | 3 +- widget/nsIWidgetListener.h | 4 +- 25 files changed, 196 insertions(+), 58 deletions(-) diff --git a/browser/devtools/performance/modules/markers.js b/browser/devtools/performance/modules/markers.js index 374f70d9567..e48a0c25419 100644 --- a/browser/devtools/performance/modules/markers.js +++ b/browser/devtools/performance/modules/markers.js @@ -73,6 +73,11 @@ const TIMELINE_BLUEPRINT = { colorName: "graphs-green", label: L10N.getStr("marker.label.paint"), }, + "Composite": { + group: 0, + colorName: "graphs-green", + label: L10N.getStr("marker.label.composite"), + }, /* Group 1 - JS */ "DOMEvent": { diff --git a/browser/locales/en-US/chrome/browser/devtools/markers.properties b/browser/locales/en-US/chrome/browser/devtools/markers.properties index ed0bbc5a06a..d84ceb509cc 100644 --- a/browser/locales/en-US/chrome/browser/devtools/markers.properties +++ b/browser/locales/en-US/chrome/browser/devtools/markers.properties @@ -17,6 +17,7 @@ marker.label.styles=Recalculate Style marker.label.reflow=Layout marker.label.paint=Paint +marker.label.composite=Composite Layers marker.label.javascript=Function Call marker.label.parseHTML=Parse HTML marker.label.parseXML=Parse XML diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 992b4582c59..d5f048b061e 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -277,10 +277,12 @@ private: // is stored on docshells directly. friend void mozilla::TimelineConsumers::AddConsumer(nsDocShell* aDocShell); friend void mozilla::TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell); - friend void mozilla::TimelineConsumers::AddMarkerForDocShell( - nsDocShell* aDocShell, UniquePtr&& aMarker); friend void mozilla::TimelineConsumers::AddMarkerForDocShell( nsDocShell* aDocShell, const char* aName, TracingMetadata aMetaData); + friend void mozilla::TimelineConsumers::AddMarkerForDocShell( + nsDocShell* aDocShell, const char* aName, const TimeStamp& aTime, TracingMetadata aMetaData); + friend void mozilla::TimelineConsumers::AddMarkerForDocShell( + nsDocShell* aDocShell, UniquePtr&& aMarker); public: // Tell the favicon service that aNewURI has the same favicon as aOldURI. diff --git a/docshell/base/timeline/AutoGlobalTimelineMarker.cpp b/docshell/base/timeline/AutoGlobalTimelineMarker.cpp index 6f38b09a27a..a098443cce6 100644 --- a/docshell/base/timeline/AutoGlobalTimelineMarker.cpp +++ b/docshell/base/timeline/AutoGlobalTimelineMarker.cpp @@ -6,7 +6,7 @@ #include "mozilla/AutoGlobalTimelineMarker.h" -#include "mozilla/TimelineConsumers.h" +#include "TimelineConsumers.h" #include "MainThreadUtils.h" namespace mozilla { diff --git a/docshell/base/timeline/AutoTimelineMarker.cpp b/docshell/base/timeline/AutoTimelineMarker.cpp index 8ac05e1e7a1..2ef8b144dbf 100644 --- a/docshell/base/timeline/AutoTimelineMarker.cpp +++ b/docshell/base/timeline/AutoTimelineMarker.cpp @@ -6,7 +6,7 @@ #include "mozilla/AutoTimelineMarker.h" -#include "mozilla/TimelineConsumers.h" +#include "TimelineConsumers.h" #include "MainThreadUtils.h" #include "nsDocShell.h" diff --git a/docshell/base/timeline/ObservedDocShell.cpp b/docshell/base/timeline/ObservedDocShell.cpp index 613ca93d623..03abe410447 100644 --- a/docshell/base/timeline/ObservedDocShell.cpp +++ b/docshell/base/timeline/ObservedDocShell.cpp @@ -15,13 +15,6 @@ ObservedDocShell::ObservedDocShell(nsDocShell* aDocShell) : mDocShell(aDocShell) {} -void -ObservedDocShell::AddMarker(const char* aName, TracingMetadata aMetaData) -{ - TimelineMarker* marker = new TimelineMarker(mDocShell, aName, aMetaData); - mTimelineMarkers.AppendElement(marker); -} - void ObservedDocShell::AddMarker(UniquePtr&& aMarker) { diff --git a/docshell/base/timeline/ObservedDocShell.h b/docshell/base/timeline/ObservedDocShell.h index e0932b277ed..e3fd11e6571 100644 --- a/docshell/base/timeline/ObservedDocShell.h +++ b/docshell/base/timeline/ObservedDocShell.h @@ -7,7 +7,6 @@ #ifndef ObservedDocShell_h_ #define ObservedDocShell_h_ -#include "GeckoProfiler.h" #include "nsTArray.h" #include "mozilla/nsRefPtr.h" @@ -33,7 +32,6 @@ public: explicit ObservedDocShell(nsDocShell* aDocShell); nsDocShell* operator*() const { return mDocShell.get(); } - void AddMarker(const char* aName, TracingMetadata aMetaData); void AddMarker(UniquePtr&& aMarker); void ClearMarkers(); void PopMarkers(JSContext* aCx, nsTArray& aStore); diff --git a/docshell/base/timeline/TimelineConsumers.cpp b/docshell/base/timeline/TimelineConsumers.cpp index 13f0a05abda..e099f3043c0 100644 --- a/docshell/base/timeline/TimelineConsumers.cpp +++ b/docshell/base/timeline/TimelineConsumers.cpp @@ -65,6 +65,27 @@ TimelineConsumers::GetKnownDocShells(Vector>& aStore) return true; } +void +TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell, + const char* aName, + TracingMetadata aMetaData) +{ + if (aDocShell->IsObserved()) { + aDocShell->mObserved->AddMarker(Move(MakeUnique(aDocShell, aName, aMetaData))); + } +} + +void +TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell, + const char* aName, + const TimeStamp& aTime, + TracingMetadata aMetaData) +{ + if (aDocShell->IsObserved()) { + aDocShell->mObserved->AddMarker(Move(MakeUnique(aDocShell, aName, aTime, aMetaData))); + } +} + void TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell, UniquePtr&& aMarker) @@ -75,17 +96,33 @@ TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell, } void -TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell, - const char* aName, TracingMetadata aMetaData) +TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell, + const char* aName, + TracingMetadata aMetaData) { - if (aDocShell->IsObserved()) { - aDocShell->mObserved->AddMarker(aName, aMetaData); - } + AddMarkerForDocShell(static_cast(aDocShell), aName, aMetaData); +} + +void +TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell, + const char* aName, + const TimeStamp& aTime, + TracingMetadata aMetaData) +{ + AddMarkerForDocShell(static_cast(aDocShell), aName, aTime, aMetaData); +} + +void +TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell, + UniquePtr&& aMarker) +{ + AddMarkerForDocShell(static_cast(aDocShell), Move(aMarker)); } void TimelineConsumers::AddMarkerForDocShellsList(Vector>& aDocShells, - const char* aName, TracingMetadata aMetaData) + const char* aName, + TracingMetadata aMetaData) { for (Vector>::Range range = aDocShells.all(); !range.empty(); @@ -95,7 +132,8 @@ TimelineConsumers::AddMarkerForDocShellsList(Vector>& aDocS } void -TimelineConsumers::AddMarkerForAllObservedDocShells(const char* aName, TracingMetadata aMetaData) +TimelineConsumers::AddMarkerForAllObservedDocShells(const char* aName, + TracingMetadata aMetaData) { Vector> docShells; if (!GetKnownDocShells(docShells)) { diff --git a/docshell/base/timeline/TimelineConsumers.h b/docshell/base/timeline/TimelineConsumers.h index 3540a4287cf..263df46b13a 100644 --- a/docshell/base/timeline/TimelineConsumers.h +++ b/docshell/base/timeline/TimelineConsumers.h @@ -10,11 +10,14 @@ #include "mozilla/UniquePtr.h" #include "mozilla/LinkedList.h" #include "mozilla/Vector.h" -#include "timeline/ObservedDocShell.h" +#include "GeckoProfiler.h" class nsDocShell; +class nsIDocShell; +class TimelineMarker; namespace mozilla { +class ObservedDocShell; class TimelineConsumers { @@ -30,16 +33,49 @@ public: static bool IsEmpty(); static bool GetKnownDocShells(Vector>& aStore); - // Methods for adding markers to appropriate docshells. These will only add - // markers if the docshell is currently being observed by a timeline. + // Methods for adding markers relevant for particular docshells, or generic + // (meaning that they either can't be tied to a particular docshell, or one + // wasn't accessible in the part of the codebase where they're instantiated). + + // These will only add markers if at least one docshell is currently being + // observed by a timeline. Markers tied to a particular docshell won't be + // created unless that docshell is specifically being currently observed. // See nsIDocShell::recordProfileTimelineMarkers + + // These methods create a custom marker from a name and some metadata, + // relevant for a specific docshell. + static void AddMarkerForDocShell(nsDocShell* aDocShell, + const char* aName, + TracingMetadata aMetaData); + static void AddMarkerForDocShell(nsIDocShell* aDocShell, + const char* aName, + TracingMetadata aMetaData); + + static void AddMarkerForDocShell(nsDocShell* aDocShell, + const char* aName, + const TimeStamp& aTime, + TracingMetadata aMetaData); + static void AddMarkerForDocShell(nsIDocShell* aDocShell, + const char* aName, + const TimeStamp& aTime, + TracingMetadata aMetaData); + + // These methods register and receive ownership of an already created marker, + // relevant for a specific docshell. static void AddMarkerForDocShell(nsDocShell* aDocShell, UniquePtr&& aMarker); - static void AddMarkerForDocShell(nsDocShell* aDocShell, - const char* aName, TracingMetadata aMetaData); + static void AddMarkerForDocShell(nsIDocShell* aDocShell, + UniquePtr&& aMarker); + + // This method creates custom markers, relevant for a list of docshells. static void AddMarkerForDocShellsList(Vector>& aDocShells, - const char* aName, TracingMetadata aMetaData); - static void AddMarkerForAllObservedDocShells(const char* aName, TracingMetadata aMetaData); + const char* aName, + TracingMetadata aMetaData); + + // This method creates custom markers, none of which have to be tied to a + // particular docshell. + static void AddMarkerForAllObservedDocShells(const char* aName, + TracingMetadata aMetaData); }; } // namespace mozilla diff --git a/docshell/base/timeline/TimelineMarker.cpp b/docshell/base/timeline/TimelineMarker.cpp index 90f70f4b04e..51a78fbcfe7 100644 --- a/docshell/base/timeline/TimelineMarker.cpp +++ b/docshell/base/timeline/TimelineMarker.cpp @@ -20,6 +20,15 @@ TimelineMarker::TimelineMarker(nsDocShell* aDocShell, const char* aName, } } +TimelineMarker::TimelineMarker(nsDocShell* aDocShell, const char* aName, + const mozilla::TimeStamp& aTime, + TracingMetadata aMetaData) + : TimelineMarker(aDocShell, aName, aMetaData) +{ + bool isInconsistent = false; + mTime = (aTime - mozilla::TimeStamp::ProcessCreation(isInconsistent)).ToMilliseconds(); +} + TimelineMarker::TimelineMarker(nsDocShell* aDocShell, const char* aName, TracingMetadata aMetaData, const nsAString& aCause, diff --git a/docshell/base/timeline/TimelineMarker.h b/docshell/base/timeline/TimelineMarker.h index 25e6e2e8e53..49f99b39e4f 100644 --- a/docshell/base/timeline/TimelineMarker.h +++ b/docshell/base/timeline/TimelineMarker.h @@ -26,6 +26,10 @@ public: TimelineMarker(nsDocShell* aDocShell, const char* aName, TracingMetadata aMetaData); + TimelineMarker(nsDocShell* aDocShell, const char* aName, + const mozilla::TimeStamp& aTime, + TracingMetadata aMetaData); + TimelineMarker(nsDocShell* aDocShell, const char* aName, TracingMetadata aMetaData, const nsAString& aCause, diff --git a/docshell/base/timeline/moz.build b/docshell/base/timeline/moz.build index 92b12fded4a..0078dbcdf91 100644 --- a/docshell/base/timeline/moz.build +++ b/docshell/base/timeline/moz.build @@ -7,7 +7,9 @@ EXPORTS.mozilla += [ 'AutoGlobalTimelineMarker.h', 'AutoTimelineMarker.h', + 'ObservedDocShell.h', 'TimelineConsumers.h', + 'TimelineMarker.h', ] UNIFIED_SOURCES += [ diff --git a/dom/ipc/TabChild.cpp b/dom/ipc/TabChild.cpp index 2ea68ecd1c3..98e617b656d 100644 --- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2862,7 +2862,9 @@ TabChild::GetFrom(uint64_t aLayersId) } void -TabChild::DidComposite(uint64_t aTransactionId) +TabChild::DidComposite(uint64_t aTransactionId, + const TimeStamp& aCompositeStart, + const TimeStamp& aCompositeEnd) { MOZ_ASSERT(mPuppetWidget); MOZ_ASSERT(mPuppetWidget->GetLayerManager()); @@ -2871,7 +2873,8 @@ TabChild::DidComposite(uint64_t aTransactionId) ClientLayerManager *manager = static_cast(mPuppetWidget->GetLayerManager()); - manager->DidComposite(aTransactionId); + + manager->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd); } void diff --git a/dom/ipc/TabChild.h b/dom/ipc/TabChild.h index 00d85ee4a39..09c977f4b11 100644 --- a/dom/ipc/TabChild.h +++ b/dom/ipc/TabChild.h @@ -461,7 +461,10 @@ public: static TabChild* GetFrom(nsIPresShell* aPresShell); static TabChild* GetFrom(uint64_t aLayersId); - void DidComposite(uint64_t aTransactionId); + void DidComposite(uint64_t aTransactionId, + const TimeStamp& aCompositeStart, + const TimeStamp& aCompositeEnd); + void ClearCachedResources(); static inline TabChild* diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index 4f0b0f42e7d..53a0716eee6 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -110,7 +110,8 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget) ClientLayerManager::~ClientLayerManager() { if (mTransactionIdAllocator) { - DidComposite(mLatestTransactionId); + TimeStamp now = TimeStamp::Now(); + DidComposite(mLatestTransactionId, now, now); } mMemoryPressureObserver->Destroy(); ClearCachedResources(); @@ -384,16 +385,18 @@ ClientLayerManager::Composite() } void -ClientLayerManager::DidComposite(uint64_t aTransactionId) +ClientLayerManager::DidComposite(uint64_t aTransactionId, + const TimeStamp& aCompositeStart, + const TimeStamp& aCompositeEnd) { MOZ_ASSERT(mWidget); nsIWidgetListener *listener = mWidget->GetWidgetListener(); if (listener) { - listener->DidCompositeWindow(); + listener->DidCompositeWindow(aCompositeStart, aCompositeEnd); } listener = mWidget->GetAttachedWidgetListener(); if (listener) { - listener->DidCompositeWindow(); + listener->DidCompositeWindow(aCompositeStart, aCompositeEnd); } mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId); } diff --git a/gfx/layers/client/ClientLayerManager.h b/gfx/layers/client/ClientLayerManager.h index 32e8ba2b2dc..9defd20bdfa 100644 --- a/gfx/layers/client/ClientLayerManager.h +++ b/gfx/layers/client/ClientLayerManager.h @@ -203,7 +203,9 @@ public: virtual bool RequestOverfill(mozilla::dom::OverfillCallback* aCallback) override; virtual void RunOverfillCallback(const uint32_t aOverfill) override; - void DidComposite(uint64_t aTransactionId); + void DidComposite(uint64_t aTransactionId, + const mozilla::TimeStamp& aCompositeStart, + const mozilla::TimeStamp& aCompositeEnd); virtual bool SupportsMixBlendModes(EnumSet& aMixBlendModes) override { diff --git a/gfx/layers/ipc/CompositorChild.cpp b/gfx/layers/ipc/CompositorChild.cpp index b287e1e7ee1..1618b39b3f8 100644 --- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -345,15 +345,17 @@ CompositorChild::RecvUpdatePluginVisibility(const uintptr_t& aOwnerWidget, } bool -CompositorChild::RecvDidComposite(const uint64_t& aId, const uint64_t& aTransactionId) +CompositorChild::RecvDidComposite(const uint64_t& aId, const uint64_t& aTransactionId, + const TimeStamp& aCompositeStart, + const TimeStamp& aCompositeEnd) { if (mLayerManager) { MOZ_ASSERT(aId == 0); - mLayerManager->DidComposite(aTransactionId); + mLayerManager->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd); } else if (aId != 0) { dom::TabChild *child = dom::TabChild::GetFrom(aId); if (child) { - child->DidComposite(aTransactionId); + child->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd); } } return true; diff --git a/gfx/layers/ipc/CompositorChild.h b/gfx/layers/ipc/CompositorChild.h index 1710957dc79..447efad8576 100644 --- a/gfx/layers/ipc/CompositorChild.h +++ b/gfx/layers/ipc/CompositorChild.h @@ -74,7 +74,9 @@ public: RecvClearCachedResources(const uint64_t& id) override; virtual bool - RecvDidComposite(const uint64_t& aId, const uint64_t& aTransactionId) override; + RecvDidComposite(const uint64_t& aId, const uint64_t& aTransactionId, + const TimeStamp& aCompositeStart, + const TimeStamp& aCompositeEnd) override; virtual bool RecvInvalidateAll() override; diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index eb7b7bc9900..edc8f436df5 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -831,7 +831,9 @@ CompositorParent::PauseComposition() mPaused = true; mCompositor->Pause(); - DidComposite(); + + TimeStamp now = TimeStamp::Now(); + DidComposite(now, now); } // if anyone's waiting to make sure that composition really got paused, tell them @@ -1034,7 +1036,8 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe #endif if (!CanComposite()) { - DidComposite(); + TimeStamp end = TimeStamp::Now(); + DidComposite(start, end); return; } @@ -1077,7 +1080,8 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe mLayerManager->EndTransaction(time); if (!aTarget) { - DidComposite(); + TimeStamp end = TimeStamp::Now(); + DidComposite(start, end); } // We're not really taking advantage of the stored composite-again-time here. @@ -1193,7 +1197,8 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree, if (aScheduleComposite) { ScheduleComposition(); if (mPaused) { - DidComposite(); + TimeStamp now = TimeStamp::Now(); + DidComposite(now, now); } } mLayerManager->NotifyShadowTreeTransaction(); @@ -1226,7 +1231,8 @@ CompositorParent::SetTestSampleTime(LayerTransactionParent* aLayerTree, if (!requestNextFrame) { CancelCurrentCompositeTask(); // Pretend we composited in case someone is wating for this event. - DidComposite(); + TimeStamp now = TimeStamp::Now(); + DidComposite(now, now); } } @@ -1258,7 +1264,8 @@ CompositorParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree) if (!requestNextFrame) { CancelCurrentCompositeTask(); // Pretend we composited in case someone is waiting for this event. - DidComposite(); + TimeStamp now = TimeStamp::Now(); + DidComposite(now, now); } } } @@ -1717,7 +1724,9 @@ public: virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) override; - void DidComposite(uint64_t aId); + void DidComposite(uint64_t aId, + TimeStamp& aCompositeStart, + TimeStamp& aCompositeEnd); private: // Private destructor, to discourage deletion outside of Release(): @@ -1738,10 +1747,11 @@ private: }; void -CompositorParent::DidComposite() +CompositorParent::DidComposite(TimeStamp& aCompositeStart, + TimeStamp& aCompositeEnd) { if (mPendingTransaction) { - unused << SendDidComposite(0, mPendingTransaction); + unused << SendDidComposite(0, mPendingTransaction, aCompositeStart, aCompositeEnd); mPendingTransaction = 0; } if (mLayerManager) { @@ -1757,7 +1767,8 @@ CompositorParent::DidComposite() it != sIndirectLayerTrees.end(); it++) { LayerTreeState* lts = &it->second; if (lts->mParent == this && lts->mCrossProcessParent) { - static_cast(lts->mCrossProcessParent)->DidComposite(it->first); + static_cast(lts->mCrossProcessParent)->DidComposite( + it->first, aCompositeStart, aCompositeEnd); } } } @@ -2041,12 +2052,14 @@ UpdatePluginWindowState(uint64_t aId) #endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) void -CrossProcessCompositorParent::DidComposite(uint64_t aId) +CrossProcessCompositorParent::DidComposite(uint64_t aId, + TimeStamp& aCompositeStart, + TimeStamp& aCompositeEnd) { sIndirectLayerTreesLock->AssertCurrentThreadOwns(); LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree; if (layerTree && layerTree->GetPendingTransactionId()) { - unused << SendDidComposite(aId, layerTree->GetPendingTransactionId()); + unused << SendDidComposite(aId, layerTree->GetPendingTransactionId(), aCompositeStart, aCompositeEnd); layerTree->SetPendingTransactionId(0); } #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 95a05d264f7..4ac9e3d085b 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -439,7 +439,7 @@ protected: */ bool CanComposite(); - void DidComposite(); + void DidComposite(TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd); nsRefPtr mLayerManager; nsRefPtr mCompositor; diff --git a/gfx/layers/ipc/PCompositor.ipdl b/gfx/layers/ipc/PCompositor.ipdl index eb01970da15..e53d66dc708 100644 --- a/gfx/layers/ipc/PCompositor.ipdl +++ b/gfx/layers/ipc/PCompositor.ipdl @@ -45,7 +45,8 @@ child: // the root layer tree). // transactionId is the id of the transaction before this composite, or 0 // if there was no transaction since the last composite. - async DidComposite(uint64_t id, uint64_t transactionId); + async DidComposite(uint64_t id, uint64_t transactionId, + TimeStamp compositeStart, TimeStamp compositeEnd); // The parent sends the child the requested fill ratio numbers. async Overfill(uint32_t aOverfill); diff --git a/view/nsView.cpp b/view/nsView.cpp index eefe5b849bf..a355c6f15d7 100644 --- a/view/nsView.cpp +++ b/view/nsView.cpp @@ -18,6 +18,7 @@ #include "nsXULPopupManager.h" #include "nsIWidgetListener.h" #include "nsContentUtils.h" // for nsAutoScriptBlocker +#include "mozilla/TimelineConsumers.h" using namespace mozilla; @@ -1071,12 +1072,28 @@ nsView::DidPaintWindow() } void -nsView::DidCompositeWindow() +nsView::DidCompositeWindow(const TimeStamp& aCompositeStart, + const TimeStamp& aCompositeEnd) { nsIPresShell* presShell = mViewManager->GetPresShell(); if (presShell) { nsAutoScriptBlocker scriptBlocker; - presShell->GetPresContext()->GetDisplayRootPresContext()->GetRootPresContext()->NotifyDidPaintForSubtree(nsIPresShell::PAINT_COMPOSITE); + + nsPresContext* context = presShell->GetPresContext(); + context->GetDisplayRootPresContext()->GetRootPresContext()->NotifyDidPaintForSubtree(nsIPresShell::PAINT_COMPOSITE); + + // If the two timestamps are identical, this was likely a fake composite + // event which wouldn't be terribly useful to display. + if (aCompositeStart == aCompositeEnd) { + return; + } + + nsIDocShell* docShell = context->GetDocShell(); + + TimelineConsumers::AddMarkerForDocShell(docShell, + "Composite", aCompositeStart, TRACING_INTERVAL_START); + TimelineConsumers::AddMarkerForDocShell(docShell, + "Composite", aCompositeEnd, TRACING_INTERVAL_END); } } diff --git a/view/nsView.h b/view/nsView.h index e4980a7a7fe..9b5dad5fdb4 100644 --- a/view/nsView.h +++ b/view/nsView.h @@ -381,7 +381,8 @@ public: virtual void WillPaintWindow(nsIWidget* aWidget) override; virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) override; virtual void DidPaintWindow() override; - virtual void DidCompositeWindow() override; + virtual void DidCompositeWindow(const mozilla::TimeStamp& aCompositeStart, + const mozilla::TimeStamp& aCompositeEnd) override; virtual void RequestRepaint() override; virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent, bool aUseAttachedEvents) override; diff --git a/widget/nsIWidgetListener.cpp b/widget/nsIWidgetListener.cpp index 51e88d84cd8..050ad8de131 100644 --- a/widget/nsIWidgetListener.cpp +++ b/widget/nsIWidgetListener.cpp @@ -107,7 +107,8 @@ nsIWidgetListener::DidPaintWindow() } void -nsIWidgetListener::DidCompositeWindow() +nsIWidgetListener::DidCompositeWindow(const TimeStamp& aCompositeStart, + const TimeStamp& aCompositeEnd) { } diff --git a/widget/nsIWidgetListener.h b/widget/nsIWidgetListener.h index 11ef193fe21..153e0dd482f 100644 --- a/widget/nsIWidgetListener.h +++ b/widget/nsIWidgetListener.h @@ -8,6 +8,7 @@ #include #include "mozilla/EventForwards.h" +#include "mozilla/TimeStamp.h" class nsView; class nsIntRegion; @@ -135,7 +136,8 @@ public: */ virtual void DidPaintWindow(); - virtual void DidCompositeWindow(); + virtual void DidCompositeWindow(const mozilla::TimeStamp& aCompositeStart, + const mozilla::TimeStamp& aCompositeEnd); /** * Request that layout schedules a repaint on the next refresh driver tick.