From 8add8ce2c17701dc0d06888510ff6d71a611f9ce Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Fri, 27 Sep 2013 12:08:45 -0400 Subject: [PATCH] Bug 918825 - Add frame duration marker. r=ehsan --HG-- extra : rebase_source : 25f51e88ee75f47eea51bcc94a7b60f31b9605af --- gfx/layers/client/ClientLayerManager.cpp | 1 + gfx/layers/ipc/CompositorParent.cpp | 1 + gfx/layers/ipc/LayerTransactionParent.cpp | 1 + gfx/layers/ipc/ShadowLayers.cpp | 1 + layout/base/nsRefreshDriver.cpp | 6 ++++ tools/profiler/BreakpadSampler.cpp | 2 +- tools/profiler/GeckoProfiler.h | 9 ++++++ tools/profiler/GeckoProfilerFunc.h | 3 ++ tools/profiler/GeckoProfilerImpl.h | 19 +++++++++++- tools/profiler/ProfileEntry.cpp | 4 +-- tools/profiler/ProfileEntry.h | 2 +- tools/profiler/ProfilerMarkers.cpp | 37 +++++++++++++++++++++-- tools/profiler/ProfilerMarkers.h | 28 +++++++++++++++-- tools/profiler/SaveProfileTask.cpp | 2 +- tools/profiler/TableTicker.cpp | 2 +- tools/profiler/platform-linux.cc | 2 +- tools/profiler/platform.cpp | 6 ++++ 17 files changed, 113 insertions(+), 13 deletions(-) diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index 5bb195ff41d..7d45638cefc 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -165,6 +165,7 @@ ClientLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback, MOZ_LAYERS_LOG((" ----- (beginning paint)")); Log(); #endif + profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_START); NS_ASSERTION(InConstruction(), "Should be in construction phase"); mPhase = PHASE_DRAWING; diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index cba7dfde097..ccc9b7b5074 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -547,6 +547,7 @@ CompositorParent::Composite() 15 + (int)(TimeStamp::Now() - mExpectedComposeTime).ToMilliseconds()); } #endif + profiler_tracing("Paint", "Composite", TRACING_INTERVAL_END); } void diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 3ea3355b62a..67497b36b3e 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -187,6 +187,7 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray& cset, const bool& isFirstPaint, InfallibleTArray* reply) { + profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START); PROFILER_LABEL("LayerTransactionParent", "RecvUpdate"); #ifdef COMPOSITOR_PERFORMANCE_WARNING TimeStamp updateStart = TimeStamp::Now(); diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index a3c75a2d219..c64a27e346d 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -539,6 +539,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies) MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send...")); PlatformSyncBeforeUpdate(); + profiler_tracing("Paint", "Rasterize", TRACING_INTERVAL_END); if (mTxn->mSwapRequired) { MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction...")); RenderTraceScope rendertrace3("Forward Transaction", "000093"); diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 77908932c93..c7a28c8398d 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -1059,6 +1059,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) return; } + profiler_tracing("Paint", "RD", TRACING_INTERVAL_START); + /* * The timer holds a reference to |this| while calling |Notify|. * However, implementations of |WillRefresh| are permitted to destroy @@ -1073,6 +1075,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) if (!mPresContext || !mPresContext->GetPresShell()) { StopTimer(); + profiler_tracing("Paint", "RD", TRACING_INTERVAL_END); return; } } @@ -1090,6 +1093,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) // readded as needed. mFrameRequestCallbackDocs.Clear(); + profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_START); int64_t eventTime = aNowEpoch / PR_USEC_PER_MSEC; for (uint32_t i = 0; i < frameRequestCallbacks.Length(); ++i) { const DocumentFrameCallbacks& docCallbacks = frameRequestCallbacks[i]; @@ -1116,6 +1120,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) } } } + profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_END); // This is the Flush_Style case. if (mPresContext && mPresContext->GetPresShell()) { @@ -1214,6 +1219,7 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) for (uint32_t i = 0; i < mPostRefreshObservers.Length(); ++i) { mPostRefreshObservers[i]->DidRefresh(); } + profiler_tracing("Paint", "RD", TRACING_INTERVAL_END); } /* static */ PLDHashOperator diff --git a/tools/profiler/BreakpadSampler.cpp b/tools/profiler/BreakpadSampler.cpp index 3cef1cde15e..5f583c697c0 100644 --- a/tools/profiler/BreakpadSampler.cpp +++ b/tools/profiler/BreakpadSampler.cpp @@ -13,7 +13,7 @@ // Profiler #include "PlatformMacros.h" -#include "GeckoProfilerImpl.h" +#include "GeckoProfiler.h" #include "platform.h" #include "nsXULAppAPI.h" #include "nsThreadUtils.h" diff --git a/tools/profiler/GeckoProfiler.h b/tools/profiler/GeckoProfiler.h index 3981239c64a..f3971a3eb00 100644 --- a/tools/profiler/GeckoProfiler.h +++ b/tools/profiler/GeckoProfiler.h @@ -56,6 +56,12 @@ namespace mozilla { class TimeStamp; } +enum TracingMetadata { + TRACING_DEFAULT, + TRACING_INTERVAL_START, + TRACING_INTERVAL_END +}; + #ifndef MOZ_ENABLE_PROFILER_SPS #include @@ -82,6 +88,9 @@ class TimeStamp; #define PROFILER_MAIN_THREAD_LABEL(name_space, info) do {} while (0) #define PROFILER_MAIN_THREAD_LABEL_PRINTF(name_space, info, format, ...) do {} while (0) +static inline void profiler_tracing(const char* aCategory, const char* aInfo, + TracingMetadata metaData = TRACING_DEFAULT) {} + // Initilize the profiler TLS, signal handlers on linux. If MOZ_PROFILER_STARTUP // is set the profiler will be started. This call must happen before any other // sampler calls. Particularly sampler_label/sampler_marker. diff --git a/tools/profiler/GeckoProfilerFunc.h b/tools/profiler/GeckoProfilerFunc.h index 11601ef6eb4..2566bbbaaea 100644 --- a/tools/profiler/GeckoProfilerFunc.h +++ b/tools/profiler/GeckoProfilerFunc.h @@ -78,5 +78,8 @@ double mozilla_sampler_time(const mozilla::TimeStamp& aTime); /* Returns true if env var SPS_NEW is set to anything, else false. */ extern bool sps_version2(); +void mozilla_sampler_tracing(const char* aCategory, const char* aInfo, + TracingMetadata aMetaData); + #endif diff --git a/tools/profiler/GeckoProfilerImpl.h b/tools/profiler/GeckoProfilerImpl.h index 823a0708cbe..c3f30a78714 100644 --- a/tools/profiler/GeckoProfilerImpl.h +++ b/tools/profiler/GeckoProfilerImpl.h @@ -201,6 +201,21 @@ bool profiler_in_privacy_mode() return stack->mPrivacyMode; } +static inline void profiler_tracing(const char* aCategory, const char* aInfo, + TracingMetadata aMetaData = TRACING_DEFAULT) +{ + if (!stack_key_initialized) + return; + + // Don't insert a marker if we're not profiling to avoid + // the heap copy (malloc). + if (!profiler_is_active()) { + return; + } + + mozilla_sampler_tracing(aCategory, aInfo, aMetaData); +} + // we want the class and function name but can't easily get that using preprocessor macros // __func__ doesn't have the class name and __PRETTY_FUNCTION__ has the parameters @@ -210,11 +225,13 @@ bool profiler_in_privacy_mode() #define PROFILER_LABEL(name_space, info) mozilla::SamplerStackFrameRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, __LINE__) #define PROFILER_LABEL_PRINTF(name_space, info, ...) mozilla::SamplerStackFramePrintfRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, __LINE__, __VA_ARGS__) + #define PROFILER_MARKER(info) mozilla_sampler_add_marker(info) #define PROFILER_MARKER_PAYLOAD(info, payload) mozilla_sampler_add_marker(info, payload) +#define PROFILER_MAIN_THREAD_MARKER(info) MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread"); mozilla_sampler_add_marker(info) + #define PROFILER_MAIN_THREAD_LABEL(name_space, info) MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread"); mozilla::SamplerStackFrameRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, __LINE__) #define PROFILER_MAIN_THREAD_LABEL_PRINTF(name_space, info, ...) MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread"); mozilla::SamplerStackFramePrintfRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, __LINE__, __VA_ARGS__) -#define PROFILER_MAIN_THREAD_MARKER(info) MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread"); mozilla_sampler_add_marker(info) /* FIXME/bug 789667: memory constraints wouldn't much of a problem for diff --git a/tools/profiler/ProfileEntry.cpp b/tools/profiler/ProfileEntry.cpp index 0f933d1dd01..00666850fb9 100644 --- a/tools/profiler/ProfileEntry.cpp +++ b/tools/profiler/ProfileEntry.cpp @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include "GeckoProfilerImpl.h" #include "platform.h" #include "nsThreadUtils.h" #include "nsXULAppAPI.h" @@ -157,10 +156,11 @@ ThreadProfile::ThreadProfile(const char* aName, int aEntrySize, , mThreadId(aThreadId) , mIsMainThread(aIsMainThread) , mPlatformData(aPlatform) + , mGeneration(0) + , mPendingGenerationFlush(0) , mStackTop(aStackTop) { mEntries = new ProfileEntry[mEntrySize]; - mGeneration = 0; } ThreadProfile::~ThreadProfile() diff --git a/tools/profiler/ProfileEntry.h b/tools/profiler/ProfileEntry.h index c43c0e27a36..daf3dd32c35 100644 --- a/tools/profiler/ProfileEntry.h +++ b/tools/profiler/ProfileEntry.h @@ -8,7 +8,7 @@ #define MOZ_PROFILE_ENTRY_H #include -#include "GeckoProfilerImpl.h" +#include "GeckoProfiler.h" #include "platform.h" #include "ProfilerBacktrace.h" #include "mozilla/Mutex.h" diff --git a/tools/profiler/ProfilerMarkers.cpp b/tools/profiler/ProfilerMarkers.cpp index a865455af68..a48b296d959 100644 --- a/tools/profiler/ProfilerMarkers.cpp +++ b/tools/profiler/ProfilerMarkers.cpp @@ -16,9 +16,9 @@ ProfilerMarkerPayload::ProfilerMarkerPayload(ProfilerBacktrace* aStack) ProfilerMarkerPayload::ProfilerMarkerPayload(const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime, ProfilerBacktrace* aStack) - : mStartTime(aStartTime), - mEndTime(aEndTime), - mStack(aStack) + : mStartTime(aStartTime) + , mEndTime(aEndTime) + , mStack(aStack) {} ProfilerMarkerPayload::~ProfilerMarkerPayload() @@ -58,6 +58,37 @@ ProfilerMarkerPayload::prepareCommonProps( JSObjectBuilder& b, JSObjectBuilder::ObjectHandle aObject); +ProfilerMarkerTracing::ProfilerMarkerTracing(const char* aCategory, TracingMetadata aMetaData) + : mCategory(aCategory) + , mMetaData(aMetaData) +{} + +template +typename Builder::Object +ProfilerMarkerTracing::preparePayloadImp(Builder& b) +{ + typename Builder::RootedObject data(b.context(), b.CreateObject()); + prepareCommonProps("tracing", b, data); + + if (GetCategory()) { + b.DefineProperty(data, "category", GetCategory()); + } + if (GetMetaData() != TRACING_DEFAULT) { + if (GetMetaData() == TRACING_INTERVAL_START) { + b.DefineProperty(data, "interval", "start"); + } else if (GetMetaData() == TRACING_INTERVAL_END) { + b.DefineProperty(data, "interval", "end"); + } + } + + return data; +} + +template JSCustomObjectBuilder::Object +ProfilerMarkerTracing::preparePayloadImp(JSCustomObjectBuilder& b); +template JSObjectBuilder::Object +ProfilerMarkerTracing::preparePayloadImp(JSObjectBuilder& b); + ProfilerMarkerImagePayload::ProfilerMarkerImagePayload(gfxASurface *aImg) : mImg(aImg) {} diff --git a/tools/profiler/ProfilerMarkers.h b/tools/profiler/ProfilerMarkers.h index f7f5ed04a7e..558ebbbdf44 100644 --- a/tools/profiler/ProfilerMarkers.h +++ b/tools/profiler/ProfilerMarkers.h @@ -74,6 +74,30 @@ private: ProfilerBacktrace* mStack; }; +class ProfilerMarkerTracing : public ProfilerMarkerPayload +{ +public: + ProfilerMarkerTracing(const char* aCategory, TracingMetadata aMetaData); + + const char *GetCategory() const { return mCategory; } + TracingMetadata GetMetaData() const { return mMetaData; } + +protected: + virtual JSCustomObjectBuilder::Object + preparePayload(JSCustomObjectBuilder& b) { return preparePayloadImp(b); } + virtual JSObjectBuilder::Object + preparePayload(JSObjectBuilder& b) { return preparePayloadImp(b); } + +private: + template + typename Builder::Object preparePayloadImp(Builder& b); + +private: + const char *mCategory; + TracingMetadata mMetaData; +}; + + class gfxASurface; class ProfilerMarkerImagePayload : public ProfilerMarkerPayload { @@ -89,7 +113,7 @@ protected: private: template typename Builder::Object preparePayloadImp(Builder& b); - + nsRefPtr mImg; }; @@ -109,7 +133,7 @@ protected: private: template typename Builder::Object preparePayloadImp(Builder& b); - + const char* mSource; }; diff --git a/tools/profiler/SaveProfileTask.cpp b/tools/profiler/SaveProfileTask.cpp index 9cbef164c91..e0816a9dfa7 100644 --- a/tools/profiler/SaveProfileTask.cpp +++ b/tools/profiler/SaveProfileTask.cpp @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SaveProfileTask.h" -#include "GeckoProfilerImpl.h" +#include "GeckoProfiler.h" static bool WriteCallback(const jschar *buf, uint32_t len, void *data) diff --git a/tools/profiler/TableTicker.cpp b/tools/profiler/TableTicker.cpp index a585cef65ed..bb14727e71f 100644 --- a/tools/profiler/TableTicker.cpp +++ b/tools/profiler/TableTicker.cpp @@ -7,7 +7,7 @@ #include #include #include -#include "GeckoProfilerImpl.h" +#include "GeckoProfiler.h" #include "SaveProfileTask.h" #include "ProfileEntry.h" #include "SyncProfile.h" diff --git a/tools/profiler/platform-linux.cc b/tools/profiler/platform-linux.cc index a05ac3263ac..ad83b22dc45 100644 --- a/tools/profiler/platform-linux.cc +++ b/tools/profiler/platform-linux.cc @@ -66,7 +66,7 @@ #include #include #include "platform.h" -#include "GeckoProfilerImpl.h" +#include "GeckoProfiler.h" #include "mozilla/Mutex.h" #include "mozilla/Atomics.h" #include "ProfileEntry.h" diff --git a/tools/profiler/platform.cpp b/tools/profiler/platform.cpp index bdd0ca3621d..ca656a5a34a 100644 --- a/tools/profiler/platform.cpp +++ b/tools/profiler/platform.cpp @@ -788,6 +788,12 @@ void mozilla_sampler_free_backtrace(ProfilerBacktrace* aBacktrace) delete aBacktrace; } +void mozilla_sampler_tracing(const char* aCategory, const char* aInfo, + TracingMetadata aMetaData) +{ + mozilla_sampler_add_marker(aInfo, new ProfilerMarkerTracing(aCategory, aMetaData)); +} + // END externally visible functions ////////////////////////////////////////////////////////////////////////