Bug 1050498 - Record compositing operations, r=jsantell,smaug,tromey

This commit is contained in:
Victor Porof 2015-08-25 08:51:58 +03:00
parent 432213854d
commit 334b8c8024
25 changed files with 196 additions and 58 deletions

View File

@ -73,6 +73,11 @@ const TIMELINE_BLUEPRINT = {
colorName: "graphs-green", colorName: "graphs-green",
label: L10N.getStr("marker.label.paint"), label: L10N.getStr("marker.label.paint"),
}, },
"Composite": {
group: 0,
colorName: "graphs-green",
label: L10N.getStr("marker.label.composite"),
},
/* Group 1 - JS */ /* Group 1 - JS */
"DOMEvent": { "DOMEvent": {

View File

@ -17,6 +17,7 @@
marker.label.styles=Recalculate Style marker.label.styles=Recalculate Style
marker.label.reflow=Layout marker.label.reflow=Layout
marker.label.paint=Paint marker.label.paint=Paint
marker.label.composite=Composite Layers
marker.label.javascript=Function Call marker.label.javascript=Function Call
marker.label.parseHTML=Parse HTML marker.label.parseHTML=Parse HTML
marker.label.parseXML=Parse XML marker.label.parseXML=Parse XML

View File

@ -277,10 +277,12 @@ private:
// is stored on docshells directly. // is stored on docshells directly.
friend void mozilla::TimelineConsumers::AddConsumer(nsDocShell* aDocShell); friend void mozilla::TimelineConsumers::AddConsumer(nsDocShell* aDocShell);
friend void mozilla::TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell); friend void mozilla::TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell);
friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
nsDocShell* aDocShell, UniquePtr<TimelineMarker>&& aMarker);
friend void mozilla::TimelineConsumers::AddMarkerForDocShell( friend void mozilla::TimelineConsumers::AddMarkerForDocShell(
nsDocShell* aDocShell, const char* aName, TracingMetadata aMetaData); 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<TimelineMarker>&& aMarker);
public: public:
// Tell the favicon service that aNewURI has the same favicon as aOldURI. // Tell the favicon service that aNewURI has the same favicon as aOldURI.

View File

@ -6,7 +6,7 @@
#include "mozilla/AutoGlobalTimelineMarker.h" #include "mozilla/AutoGlobalTimelineMarker.h"
#include "mozilla/TimelineConsumers.h" #include "TimelineConsumers.h"
#include "MainThreadUtils.h" #include "MainThreadUtils.h"
namespace mozilla { namespace mozilla {

View File

@ -6,7 +6,7 @@
#include "mozilla/AutoTimelineMarker.h" #include "mozilla/AutoTimelineMarker.h"
#include "mozilla/TimelineConsumers.h" #include "TimelineConsumers.h"
#include "MainThreadUtils.h" #include "MainThreadUtils.h"
#include "nsDocShell.h" #include "nsDocShell.h"

View File

@ -15,13 +15,6 @@ ObservedDocShell::ObservedDocShell(nsDocShell* aDocShell)
: mDocShell(aDocShell) : mDocShell(aDocShell)
{} {}
void
ObservedDocShell::AddMarker(const char* aName, TracingMetadata aMetaData)
{
TimelineMarker* marker = new TimelineMarker(mDocShell, aName, aMetaData);
mTimelineMarkers.AppendElement(marker);
}
void void
ObservedDocShell::AddMarker(UniquePtr<TimelineMarker>&& aMarker) ObservedDocShell::AddMarker(UniquePtr<TimelineMarker>&& aMarker)
{ {

View File

@ -7,7 +7,6 @@
#ifndef ObservedDocShell_h_ #ifndef ObservedDocShell_h_
#define ObservedDocShell_h_ #define ObservedDocShell_h_
#include "GeckoProfiler.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "mozilla/nsRefPtr.h" #include "mozilla/nsRefPtr.h"
@ -33,7 +32,6 @@ public:
explicit ObservedDocShell(nsDocShell* aDocShell); explicit ObservedDocShell(nsDocShell* aDocShell);
nsDocShell* operator*() const { return mDocShell.get(); } nsDocShell* operator*() const { return mDocShell.get(); }
void AddMarker(const char* aName, TracingMetadata aMetaData);
void AddMarker(UniquePtr<TimelineMarker>&& aMarker); void AddMarker(UniquePtr<TimelineMarker>&& aMarker);
void ClearMarkers(); void ClearMarkers();
void PopMarkers(JSContext* aCx, nsTArray<dom::ProfileTimelineMarker>& aStore); void PopMarkers(JSContext* aCx, nsTArray<dom::ProfileTimelineMarker>& aStore);

View File

@ -65,6 +65,27 @@ TimelineConsumers::GetKnownDocShells(Vector<nsRefPtr<nsDocShell>>& aStore)
return true; return true;
} }
void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
TracingMetadata aMetaData)
{
if (aDocShell->IsObserved()) {
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aDocShell, aName, aMetaData)));
}
}
void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
TracingMetadata aMetaData)
{
if (aDocShell->IsObserved()) {
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aDocShell, aName, aTime, aMetaData)));
}
}
void void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell, TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
UniquePtr<TimelineMarker>&& aMarker) UniquePtr<TimelineMarker>&& aMarker)
@ -75,17 +96,33 @@ TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
} }
void void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell, TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName, TracingMetadata aMetaData) const char* aName,
TracingMetadata aMetaData)
{ {
if (aDocShell->IsObserved()) { AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aMetaData);
aDocShell->mObserved->AddMarker(aName, aMetaData); }
}
void
TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
TracingMetadata aMetaData)
{
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aTime, aMetaData);
}
void
TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
UniquePtr<TimelineMarker>&& aMarker)
{
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), Move(aMarker));
} }
void void
TimelineConsumers::AddMarkerForDocShellsList(Vector<nsRefPtr<nsDocShell>>& aDocShells, TimelineConsumers::AddMarkerForDocShellsList(Vector<nsRefPtr<nsDocShell>>& aDocShells,
const char* aName, TracingMetadata aMetaData) const char* aName,
TracingMetadata aMetaData)
{ {
for (Vector<nsRefPtr<nsDocShell>>::Range range = aDocShells.all(); for (Vector<nsRefPtr<nsDocShell>>::Range range = aDocShells.all();
!range.empty(); !range.empty();
@ -95,7 +132,8 @@ TimelineConsumers::AddMarkerForDocShellsList(Vector<nsRefPtr<nsDocShell>>& aDocS
} }
void void
TimelineConsumers::AddMarkerForAllObservedDocShells(const char* aName, TracingMetadata aMetaData) TimelineConsumers::AddMarkerForAllObservedDocShells(const char* aName,
TracingMetadata aMetaData)
{ {
Vector<nsRefPtr<nsDocShell>> docShells; Vector<nsRefPtr<nsDocShell>> docShells;
if (!GetKnownDocShells(docShells)) { if (!GetKnownDocShells(docShells)) {

View File

@ -10,11 +10,14 @@
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/LinkedList.h" #include "mozilla/LinkedList.h"
#include "mozilla/Vector.h" #include "mozilla/Vector.h"
#include "timeline/ObservedDocShell.h" #include "GeckoProfiler.h"
class nsDocShell; class nsDocShell;
class nsIDocShell;
class TimelineMarker;
namespace mozilla { namespace mozilla {
class ObservedDocShell;
class TimelineConsumers class TimelineConsumers
{ {
@ -30,16 +33,49 @@ public:
static bool IsEmpty(); static bool IsEmpty();
static bool GetKnownDocShells(Vector<nsRefPtr<nsDocShell>>& aStore); static bool GetKnownDocShells(Vector<nsRefPtr<nsDocShell>>& aStore);
// Methods for adding markers to appropriate docshells. These will only add // Methods for adding markers relevant for particular docshells, or generic
// markers if the docshell is currently being observed by a timeline. // (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 // 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, static void AddMarkerForDocShell(nsDocShell* aDocShell,
UniquePtr<TimelineMarker>&& aMarker); UniquePtr<TimelineMarker>&& aMarker);
static void AddMarkerForDocShell(nsDocShell* aDocShell, static void AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName, TracingMetadata aMetaData); UniquePtr<TimelineMarker>&& aMarker);
// This method creates custom markers, relevant for a list of docshells.
static void AddMarkerForDocShellsList(Vector<nsRefPtr<nsDocShell>>& aDocShells, static void AddMarkerForDocShellsList(Vector<nsRefPtr<nsDocShell>>& aDocShells,
const char* aName, TracingMetadata aMetaData); const char* aName,
static void AddMarkerForAllObservedDocShells(const char* aName, TracingMetadata aMetaData); 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 } // namespace mozilla

View File

@ -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, TimelineMarker::TimelineMarker(nsDocShell* aDocShell, const char* aName,
TracingMetadata aMetaData, TracingMetadata aMetaData,
const nsAString& aCause, const nsAString& aCause,

View File

@ -26,6 +26,10 @@ public:
TimelineMarker(nsDocShell* aDocShell, const char* aName, TimelineMarker(nsDocShell* aDocShell, const char* aName,
TracingMetadata aMetaData); TracingMetadata aMetaData);
TimelineMarker(nsDocShell* aDocShell, const char* aName,
const mozilla::TimeStamp& aTime,
TracingMetadata aMetaData);
TimelineMarker(nsDocShell* aDocShell, const char* aName, TimelineMarker(nsDocShell* aDocShell, const char* aName,
TracingMetadata aMetaData, TracingMetadata aMetaData,
const nsAString& aCause, const nsAString& aCause,

View File

@ -7,7 +7,9 @@
EXPORTS.mozilla += [ EXPORTS.mozilla += [
'AutoGlobalTimelineMarker.h', 'AutoGlobalTimelineMarker.h',
'AutoTimelineMarker.h', 'AutoTimelineMarker.h',
'ObservedDocShell.h',
'TimelineConsumers.h', 'TimelineConsumers.h',
'TimelineMarker.h',
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [

View File

@ -2862,7 +2862,9 @@ TabChild::GetFrom(uint64_t aLayersId)
} }
void void
TabChild::DidComposite(uint64_t aTransactionId) TabChild::DidComposite(uint64_t aTransactionId,
const TimeStamp& aCompositeStart,
const TimeStamp& aCompositeEnd)
{ {
MOZ_ASSERT(mPuppetWidget); MOZ_ASSERT(mPuppetWidget);
MOZ_ASSERT(mPuppetWidget->GetLayerManager()); MOZ_ASSERT(mPuppetWidget->GetLayerManager());
@ -2871,7 +2873,8 @@ TabChild::DidComposite(uint64_t aTransactionId)
ClientLayerManager *manager = ClientLayerManager *manager =
static_cast<ClientLayerManager*>(mPuppetWidget->GetLayerManager()); static_cast<ClientLayerManager*>(mPuppetWidget->GetLayerManager());
manager->DidComposite(aTransactionId);
manager->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
} }
void void

View File

@ -461,7 +461,10 @@ public:
static TabChild* GetFrom(nsIPresShell* aPresShell); static TabChild* GetFrom(nsIPresShell* aPresShell);
static TabChild* GetFrom(uint64_t aLayersId); static TabChild* GetFrom(uint64_t aLayersId);
void DidComposite(uint64_t aTransactionId); void DidComposite(uint64_t aTransactionId,
const TimeStamp& aCompositeStart,
const TimeStamp& aCompositeEnd);
void ClearCachedResources(); void ClearCachedResources();
static inline TabChild* static inline TabChild*

View File

@ -110,7 +110,8 @@ ClientLayerManager::ClientLayerManager(nsIWidget* aWidget)
ClientLayerManager::~ClientLayerManager() ClientLayerManager::~ClientLayerManager()
{ {
if (mTransactionIdAllocator) { if (mTransactionIdAllocator) {
DidComposite(mLatestTransactionId); TimeStamp now = TimeStamp::Now();
DidComposite(mLatestTransactionId, now, now);
} }
mMemoryPressureObserver->Destroy(); mMemoryPressureObserver->Destroy();
ClearCachedResources(); ClearCachedResources();
@ -384,16 +385,18 @@ ClientLayerManager::Composite()
} }
void void
ClientLayerManager::DidComposite(uint64_t aTransactionId) ClientLayerManager::DidComposite(uint64_t aTransactionId,
const TimeStamp& aCompositeStart,
const TimeStamp& aCompositeEnd)
{ {
MOZ_ASSERT(mWidget); MOZ_ASSERT(mWidget);
nsIWidgetListener *listener = mWidget->GetWidgetListener(); nsIWidgetListener *listener = mWidget->GetWidgetListener();
if (listener) { if (listener) {
listener->DidCompositeWindow(); listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
} }
listener = mWidget->GetAttachedWidgetListener(); listener = mWidget->GetAttachedWidgetListener();
if (listener) { if (listener) {
listener->DidCompositeWindow(); listener->DidCompositeWindow(aCompositeStart, aCompositeEnd);
} }
mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId); mTransactionIdAllocator->NotifyTransactionCompleted(aTransactionId);
} }

View File

@ -203,7 +203,9 @@ public:
virtual bool RequestOverfill(mozilla::dom::OverfillCallback* aCallback) override; virtual bool RequestOverfill(mozilla::dom::OverfillCallback* aCallback) override;
virtual void RunOverfillCallback(const uint32_t aOverfill) 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<gfx::CompositionOp>& aMixBlendModes) override virtual bool SupportsMixBlendModes(EnumSet<gfx::CompositionOp>& aMixBlendModes) override
{ {

View File

@ -345,15 +345,17 @@ CompositorChild::RecvUpdatePluginVisibility(const uintptr_t& aOwnerWidget,
} }
bool 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) { if (mLayerManager) {
MOZ_ASSERT(aId == 0); MOZ_ASSERT(aId == 0);
mLayerManager->DidComposite(aTransactionId); mLayerManager->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
} else if (aId != 0) { } else if (aId != 0) {
dom::TabChild *child = dom::TabChild::GetFrom(aId); dom::TabChild *child = dom::TabChild::GetFrom(aId);
if (child) { if (child) {
child->DidComposite(aTransactionId); child->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
} }
} }
return true; return true;

View File

@ -74,7 +74,9 @@ public:
RecvClearCachedResources(const uint64_t& id) override; RecvClearCachedResources(const uint64_t& id) override;
virtual bool 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 virtual bool
RecvInvalidateAll() override; RecvInvalidateAll() override;

View File

@ -831,7 +831,9 @@ CompositorParent::PauseComposition()
mPaused = true; mPaused = true;
mCompositor->Pause(); mCompositor->Pause();
DidComposite();
TimeStamp now = TimeStamp::Now();
DidComposite(now, now);
} }
// if anyone's waiting to make sure that composition really got paused, tell them // 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 #endif
if (!CanComposite()) { if (!CanComposite()) {
DidComposite(); TimeStamp end = TimeStamp::Now();
DidComposite(start, end);
return; return;
} }
@ -1077,7 +1080,8 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRe
mLayerManager->EndTransaction(time); mLayerManager->EndTransaction(time);
if (!aTarget) { if (!aTarget) {
DidComposite(); TimeStamp end = TimeStamp::Now();
DidComposite(start, end);
} }
// We're not really taking advantage of the stored composite-again-time here. // We're not really taking advantage of the stored composite-again-time here.
@ -1193,7 +1197,8 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
if (aScheduleComposite) { if (aScheduleComposite) {
ScheduleComposition(); ScheduleComposition();
if (mPaused) { if (mPaused) {
DidComposite(); TimeStamp now = TimeStamp::Now();
DidComposite(now, now);
} }
} }
mLayerManager->NotifyShadowTreeTransaction(); mLayerManager->NotifyShadowTreeTransaction();
@ -1226,7 +1231,8 @@ CompositorParent::SetTestSampleTime(LayerTransactionParent* aLayerTree,
if (!requestNextFrame) { if (!requestNextFrame) {
CancelCurrentCompositeTask(); CancelCurrentCompositeTask();
// Pretend we composited in case someone is wating for this event. // 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) { if (!requestNextFrame) {
CancelCurrentCompositeTask(); CancelCurrentCompositeTask();
// Pretend we composited in case someone is waiting for this event. // 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; virtual AsyncCompositionManager* GetCompositionManager(LayerTransactionParent* aParent) override;
void DidComposite(uint64_t aId); void DidComposite(uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd);
private: private:
// Private destructor, to discourage deletion outside of Release(): // Private destructor, to discourage deletion outside of Release():
@ -1738,10 +1747,11 @@ private:
}; };
void void
CompositorParent::DidComposite() CompositorParent::DidComposite(TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
{ {
if (mPendingTransaction) { if (mPendingTransaction) {
unused << SendDidComposite(0, mPendingTransaction); unused << SendDidComposite(0, mPendingTransaction, aCompositeStart, aCompositeEnd);
mPendingTransaction = 0; mPendingTransaction = 0;
} }
if (mLayerManager) { if (mLayerManager) {
@ -1757,7 +1767,8 @@ CompositorParent::DidComposite()
it != sIndirectLayerTrees.end(); it++) { it != sIndirectLayerTrees.end(); it++) {
LayerTreeState* lts = &it->second; LayerTreeState* lts = &it->second;
if (lts->mParent == this && lts->mCrossProcessParent) { if (lts->mParent == this && lts->mCrossProcessParent) {
static_cast<CrossProcessCompositorParent*>(lts->mCrossProcessParent)->DidComposite(it->first); static_cast<CrossProcessCompositorParent*>(lts->mCrossProcessParent)->DidComposite(
it->first, aCompositeStart, aCompositeEnd);
} }
} }
} }
@ -2041,12 +2052,14 @@ UpdatePluginWindowState(uint64_t aId)
#endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) #endif // #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
void void
CrossProcessCompositorParent::DidComposite(uint64_t aId) CrossProcessCompositorParent::DidComposite(uint64_t aId,
TimeStamp& aCompositeStart,
TimeStamp& aCompositeEnd)
{ {
sIndirectLayerTreesLock->AssertCurrentThreadOwns(); sIndirectLayerTreesLock->AssertCurrentThreadOwns();
LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree; LayerTransactionParent *layerTree = sIndirectLayerTrees[aId].mLayerTree;
if (layerTree && layerTree->GetPendingTransactionId()) { if (layerTree && layerTree->GetPendingTransactionId()) {
unused << SendDidComposite(aId, layerTree->GetPendingTransactionId()); unused << SendDidComposite(aId, layerTree->GetPendingTransactionId(), aCompositeStart, aCompositeEnd);
layerTree->SetPendingTransactionId(0); layerTree->SetPendingTransactionId(0);
} }
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)

View File

@ -439,7 +439,7 @@ protected:
*/ */
bool CanComposite(); bool CanComposite();
void DidComposite(); void DidComposite(TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd);
nsRefPtr<LayerManagerComposite> mLayerManager; nsRefPtr<LayerManagerComposite> mLayerManager;
nsRefPtr<Compositor> mCompositor; nsRefPtr<Compositor> mCompositor;

View File

@ -45,7 +45,8 @@ child:
// the root layer tree). // the root layer tree).
// transactionId is the id of the transaction before this composite, or 0 // transactionId is the id of the transaction before this composite, or 0
// if there was no transaction since the last composite. // 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. // The parent sends the child the requested fill ratio numbers.
async Overfill(uint32_t aOverfill); async Overfill(uint32_t aOverfill);

View File

@ -18,6 +18,7 @@
#include "nsXULPopupManager.h" #include "nsXULPopupManager.h"
#include "nsIWidgetListener.h" #include "nsIWidgetListener.h"
#include "nsContentUtils.h" // for nsAutoScriptBlocker #include "nsContentUtils.h" // for nsAutoScriptBlocker
#include "mozilla/TimelineConsumers.h"
using namespace mozilla; using namespace mozilla;
@ -1071,12 +1072,28 @@ nsView::DidPaintWindow()
} }
void void
nsView::DidCompositeWindow() nsView::DidCompositeWindow(const TimeStamp& aCompositeStart,
const TimeStamp& aCompositeEnd)
{ {
nsIPresShell* presShell = mViewManager->GetPresShell(); nsIPresShell* presShell = mViewManager->GetPresShell();
if (presShell) { if (presShell) {
nsAutoScriptBlocker scriptBlocker; 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);
} }
} }

View File

@ -381,7 +381,8 @@ public:
virtual void WillPaintWindow(nsIWidget* aWidget) override; virtual void WillPaintWindow(nsIWidget* aWidget) override;
virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) override; virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) override;
virtual void DidPaintWindow() 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 void RequestRepaint() override;
virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent, virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
bool aUseAttachedEvents) override; bool aUseAttachedEvents) override;

View File

@ -107,7 +107,8 @@ nsIWidgetListener::DidPaintWindow()
} }
void void
nsIWidgetListener::DidCompositeWindow() nsIWidgetListener::DidCompositeWindow(const TimeStamp& aCompositeStart,
const TimeStamp& aCompositeEnd)
{ {
} }

View File

@ -8,6 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include "mozilla/EventForwards.h" #include "mozilla/EventForwards.h"
#include "mozilla/TimeStamp.h"
class nsView; class nsView;
class nsIntRegion; class nsIntRegion;
@ -135,7 +136,8 @@ public:
*/ */
virtual void DidPaintWindow(); 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. * Request that layout schedules a repaint on the next refresh driver tick.