Bug 1666617 - Add RefreshObserver profiler markers, r=smaug

This creates a marker that starts when an observer is added and ends when it is removed.
If there are multiple observers at the same time, their markers overlap.

The current profiler markers API only lets us insert the marker once we know
both the start and the end timestamp. This means that, if a profile is captured
in the middle of a refresh observer's observation period, there will not be a
marker for that observer in the profile. This can be improved once we have a way
to emit separate start and end markers and a way to associate the correct markers
with each other (bug 1661114).

Differential Revision: https://phabricator.services.mozilla.com/D91059
This commit is contained in:
Florian Quèze 2020-09-25 11:51:06 +00:00
Родитель f366fca45a
Коммит 84f14af9e6
2 изменённых файлов: 40 добавлений и 3 удалений

Просмотреть файл

@ -1255,15 +1255,41 @@ TimeStamp nsRefreshDriver::MostRecentRefresh() const {
void nsRefreshDriver::AddRefreshObserver(nsARefreshObserver* aObserver,
FlushType aFlushType) {
MOZ_RELEASE_ASSERT(mPresContext);
ObserverArray& array = ArrayFor(aFlushType);
array.AppendElement(aObserver);
Maybe<uint64_t> innerWindowID;
#ifdef MOZ_GECKO_PROFILER
innerWindowID =
profiler_get_inner_window_id_from_docshell(mPresContext->GetDocShell());
#endif
array.AppendElement(ObserverData{aObserver, TimeStamp::Now(), innerWindowID,
profiler_capture_backtrace()});
EnsureTimerStarted();
}
bool nsRefreshDriver::RemoveRefreshObserver(nsARefreshObserver* aObserver,
FlushType aFlushType) {
ObserverArray& array = ArrayFor(aFlushType);
return array.RemoveElement(aObserver);
auto index = array.IndexOf(aObserver);
if (index == ObserverArray::array_type::NoIndex) {
return false;
}
#ifdef MOZ_GECKO_PROFILER
if (profiler_can_accept_markers()) {
auto& data = array.ElementAt(index);
PROFILER_MARKER_TEXT(
"RefreshObserver",
GRAPHICS.WithOptions(
MarkerStack::TakeBacktrace(std::move(data.mCause)),
MarkerTiming::IntervalUntilNowFrom(data.mRegisterTime),
MarkerInnerWindowId(data.mInnerWindowId)),
nsCString(kFlushTypeNames[aFlushType]));
}
#endif
array.RemoveElementAt(index);
return true;
}
void nsRefreshDriver::AddTimerAdjustmentObserver(

Просмотреть файл

@ -418,7 +418,6 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
};
private:
typedef nsTObserverArray<nsARefreshObserver*> ObserverArray;
typedef nsTArray<RefPtr<VVPResizeEvent>> VisualViewportResizeEventArray;
typedef nsTArray<RefPtr<mozilla::Runnable>> ScrollEventArray;
typedef nsTArray<RefPtr<VVPScrollEvent>> VisualViewportScrollEventArray;
@ -431,6 +430,18 @@ class nsRefreshDriver final : public mozilla::layers::TransactionIdAllocator,
};
typedef nsClassHashtable<nsUint32HashKey, ImageStartData> ImageStartTable;
struct ObserverData {
nsARefreshObserver* mObserver;
mozilla::TimeStamp mRegisterTime;
mozilla::Maybe<uint64_t> mInnerWindowId;
mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> mCause;
bool operator==(nsARefreshObserver* aObserver) const {
return mObserver == aObserver;
}
operator RefPtr<nsARefreshObserver>() { return mObserver; }
};
typedef nsTObserverArray<ObserverData> ObserverArray;
void RunFullscreenSteps();
void DispatchAnimationEvents();
MOZ_CAN_RUN_SCRIPT