[tracing] Make TraceableState work in the field
This CL revamps TraceableState to work better in the field - Uses state string for event name; this works around debug annotation being filtered out - Uses StaticString (compile time) to mark these strings privacy-safe - Use Track API which scopes tracks to a thread/process - Generalize tracing categories to ease using new categories - Changes "toplevel" -> "renderer" which is more appropriate and less spammy - Aligns RenderThread state events with other state by emitting it when tracing start Drive-by: - Remove redundant process_type (it's already set at the process level) - Remove unused TraceableObjectState Change-Id: I8f39b23ecae9ed64a44ffbc508354ba894415622 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6375102 Reviewed-by: Scott Haseley <shaseley@chromium.org> Reviewed-by: Dave Tapuska <dtapuska@chromium.org> Commit-Queue: Etienne Pierre-Doray <etiennep@chromium.org> Cr-Commit-Position: refs/heads/main@{#1435649}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
539f793de9
commit
d0aa5fbbfa
chrome/renderer
content
public
renderer
third_party/blink
public
platform
renderer
platform
scheduler
common
back_forward_cache_disabling_feature_tracker.ccback_forward_cache_disabling_feature_tracker.h
throttling
tracing_helper.cctracing_helper.htracing_helper_unittest.ccweb_thread_scheduler.ccmain_thread
frame_origin_type.ccframe_origin_type.hframe_scheduler_impl.ccframe_scheduler_impl.hframe_scheduler_impl_unittest.ccmain_thread_scheduler_impl.ccmain_thread_scheduler_impl.hmain_thread_scheduler_impl_unittest.ccpage_visibility_state.ccpage_visibility_state.htask_type_names.cctask_type_names.huse_case.ccuse_case.h
test
@ -422,11 +422,6 @@ void ChromeContentRendererClient::RenderThreadStarted() {
|
||||
|
||||
const bool is_extension = IsStandaloneContentExtensionProcess();
|
||||
|
||||
thread->SetRendererProcessType(
|
||||
is_extension
|
||||
? blink::scheduler::WebRendererProcessType::kExtensionRenderer
|
||||
: blink::scheduler::WebRendererProcessType::kRenderer);
|
||||
|
||||
if (is_extension) {
|
||||
// The process name was set to "Renderer" in RendererMain(). Update it to
|
||||
// "Extension Renderer" to highlight that it's hosting an extension.
|
||||
|
@ -103,10 +103,6 @@ class CONTENT_EXPORT RenderThread : virtual public ChildThread {
|
||||
// Retrieve the process ID of the browser process.
|
||||
virtual int32_t GetClientId() = 0;
|
||||
|
||||
// Set the renderer process type.
|
||||
virtual void SetRendererProcessType(
|
||||
blink::scheduler::WebRendererProcessType type) = 0;
|
||||
|
||||
// Returns the user-agent string.
|
||||
virtual blink::WebString GetUserAgent() = 0;
|
||||
virtual const blink::UserAgentMetadata& GetUserAgentMetadata() = 0;
|
||||
|
@ -167,9 +167,6 @@ int32_t MockRenderThread::GetClientId() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MockRenderThread::SetRendererProcessType(
|
||||
blink::scheduler::WebRendererProcessType type) {}
|
||||
|
||||
blink::WebString MockRenderThread::GetUserAgent() {
|
||||
return blink::WebString();
|
||||
}
|
||||
|
@ -81,8 +81,6 @@ class MockRenderThread : public RenderThread {
|
||||
int PostTaskToAllWebWorkers(base::RepeatingClosure closure) override;
|
||||
base::WaitableEvent* GetShutdownEvent() override;
|
||||
int32_t GetClientId() override;
|
||||
void SetRendererProcessType(
|
||||
blink::scheduler::WebRendererProcessType type) override;
|
||||
blink::WebString GetUserAgent() override;
|
||||
const blink::UserAgentMetadata& GetUserAgentMetadata() override;
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|
@ -342,8 +342,11 @@ bool IsBackgrounded(std::optional<base::Process::Priority> process_priority) {
|
||||
}
|
||||
|
||||
perfetto::StaticString ProcessPriorityToString(
|
||||
base::Process::Priority priority) {
|
||||
switch (priority) {
|
||||
std::optional<base::Process::Priority> priority) {
|
||||
if (!priority) {
|
||||
return "Unknown";
|
||||
}
|
||||
switch (*priority) {
|
||||
case base::Process::Priority::kBestEffort:
|
||||
return "Best effort";
|
||||
case base::Process::Priority::kUserVisible:
|
||||
@ -355,8 +358,11 @@ perfetto::StaticString ProcessPriorityToString(
|
||||
}
|
||||
|
||||
perfetto::StaticString ProcessVisibilityToString(
|
||||
mojom::RenderProcessVisibleState visible_state) {
|
||||
switch (visible_state) {
|
||||
std::optional<mojom::RenderProcessVisibleState> visible_state) {
|
||||
if (!visible_state) {
|
||||
return "Unknown";
|
||||
}
|
||||
switch (*visible_state) {
|
||||
case mojom::RenderProcessVisibleState::kVisible:
|
||||
return "Visible";
|
||||
case mojom::RenderProcessVisibleState::kHidden:
|
||||
@ -496,8 +502,6 @@ RenderThreadImpl::RenderThreadImpl(
|
||||
main_thread_scheduler_(std::move(scheduler)),
|
||||
client_id_(client_id) {
|
||||
TRACE_EVENT0("startup", "RenderThreadImpl::Create");
|
||||
TRACE_EVENT_BEGIN("renderer", "Unknown", process_priority_track_);
|
||||
TRACE_EVENT_BEGIN("renderer", "Unknown", process_visibility_track_);
|
||||
Init();
|
||||
}
|
||||
|
||||
@ -528,12 +532,17 @@ RenderThreadImpl::RenderThreadImpl(
|
||||
main_thread_scheduler_(std::move(scheduler)),
|
||||
client_id_(GetClientIdFromCommandLine()) {
|
||||
TRACE_EVENT0("startup", "RenderThreadImpl::Create");
|
||||
TRACE_EVENT_BEGIN("renderer", "Unknown", process_priority_track_);
|
||||
TRACE_EVENT_BEGIN("renderer", "Unknown", process_visibility_track_);
|
||||
Init();
|
||||
}
|
||||
|
||||
void RenderThreadImpl::Init() {
|
||||
TRACE_EVENT_BEGIN("renderer", ProcessPriorityToString(std::nullopt),
|
||||
process_priority_track_);
|
||||
TRACE_EVENT_BEGIN("renderer", ProcessVisibilityToString(std::nullopt),
|
||||
process_visibility_track_);
|
||||
base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
|
||||
weak_factory_.GetWeakPtr());
|
||||
|
||||
TRACE_EVENT0("startup", "RenderThreadImpl::Init");
|
||||
|
||||
SCOPED_UMA_HISTOGRAM_TIMER("Renderer.RenderThreadImpl.Init");
|
||||
@ -681,6 +690,9 @@ void RenderThreadImpl::Init() {
|
||||
}
|
||||
|
||||
RenderThreadImpl::~RenderThreadImpl() {
|
||||
base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(
|
||||
this);
|
||||
|
||||
TRACE_EVENT_END("renderer", process_priority_track_);
|
||||
TRACE_EVENT_END("renderer", process_visibility_track_);
|
||||
|
||||
@ -742,6 +754,18 @@ std::string RenderThreadImpl::GetLocale() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
void RenderThreadImpl::OnTraceLogEnabled() {
|
||||
TRACE_EVENT_END("renderer", process_priority_track_);
|
||||
TRACE_EVENT_BEGIN("renderer", ProcessPriorityToString(process_priority_),
|
||||
process_priority_track_);
|
||||
|
||||
TRACE_EVENT_END("renderer", process_visibility_track_);
|
||||
TRACE_EVENT_BEGIN("renderer", ProcessVisibilityToString(visible_state_),
|
||||
process_visibility_track_);
|
||||
}
|
||||
|
||||
void RenderThreadImpl::OnTraceLogDisabled() {}
|
||||
|
||||
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
|
||||
IPC::SyncMessageFilter* RenderThreadImpl::GetSyncMessageFilter() {
|
||||
return sync_message_filter();
|
||||
@ -1272,11 +1296,6 @@ int32_t RenderThreadImpl::GetClientId() {
|
||||
return client_id_;
|
||||
}
|
||||
|
||||
void RenderThreadImpl::SetRendererProcessType(
|
||||
blink::scheduler::WebRendererProcessType type) {
|
||||
main_thread_scheduler_->SetRendererProcessType(type);
|
||||
}
|
||||
|
||||
blink::WebString RenderThreadImpl::GetUserAgent() {
|
||||
DCHECK(!user_agent_.IsNull());
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "base/process/process.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/trace_event/trace_log.h"
|
||||
#include "base/trace_event/typed_macros.h"
|
||||
#include "base/types/pass_key.h"
|
||||
#include "build/build_config.h"
|
||||
@ -126,7 +127,8 @@ class CONTENT_EXPORT RenderThreadImpl
|
||||
: public RenderThread,
|
||||
public ChildThreadImpl,
|
||||
public mojom::Renderer,
|
||||
public viz::mojom::CompositingModeWatcher {
|
||||
public viz::mojom::CompositingModeWatcher,
|
||||
public base::trace_event::TraceLog::AsyncEnabledStateObserver {
|
||||
public:
|
||||
static RenderThreadImpl* current();
|
||||
|
||||
@ -157,6 +159,10 @@ class CONTENT_EXPORT RenderThreadImpl
|
||||
IPC::SyncChannel* GetChannel() override;
|
||||
std::string GetLocale() override;
|
||||
|
||||
// base::trace_event::TraceLog::AsyncEnabledStateObserver implementation:
|
||||
void OnTraceLogEnabled() override;
|
||||
void OnTraceLogDisabled() override;
|
||||
|
||||
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
|
||||
IPC::SyncMessageFilter* GetSyncMessageFilter() override;
|
||||
void AddRoute(int32_t routing_id, IPC::Listener* listener) override;
|
||||
@ -177,8 +183,6 @@ class CONTENT_EXPORT RenderThreadImpl
|
||||
int PostTaskToAllWebWorkers(base::RepeatingClosure closure) override;
|
||||
base::WaitableEvent* GetShutdownEvent() override;
|
||||
int32_t GetClientId() override;
|
||||
void SetRendererProcessType(
|
||||
blink::scheduler::WebRendererProcessType type) override;
|
||||
blink::WebString GetUserAgent() override;
|
||||
const blink::UserAgentMetadata& GetUserAgentMetadata() override;
|
||||
void WriteIntoTrace(
|
||||
|
@ -30,7 +30,6 @@ class WebFakeThreadScheduler : public WebThreadScheduler {
|
||||
void ResumeTimersForAndroidWebView() override;
|
||||
#endif
|
||||
void Shutdown() override;
|
||||
void SetRendererProcessType(WebRendererProcessType type) override;
|
||||
};
|
||||
|
||||
} // namespace scheduler
|
||||
|
@ -48,7 +48,6 @@ class WebMockThreadScheduler : public WebThreadScheduler {
|
||||
MOCK_METHOD0(Shutdown, void());
|
||||
MOCK_METHOD0(VirtualTimePaused, void());
|
||||
MOCK_METHOD0(VirtualTimeResumed, void());
|
||||
MOCK_METHOD1(SetRendererProcessType, void(WebRendererProcessType));
|
||||
};
|
||||
|
||||
} // namespace scheduler
|
||||
|
@ -89,10 +89,6 @@ class BLINK_PLATFORM_EXPORT WebThreadScheduler
|
||||
virtual void ResumeTimersForAndroidWebView();
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
|
||||
// Sets the kind of renderer process. Should be called on the main thread
|
||||
// once.
|
||||
virtual void SetRendererProcessType(WebRendererProcessType type);
|
||||
|
||||
// IPC::Channel::UrgentMessageDelegate implementation:
|
||||
void OnUrgentMessageReceived() override;
|
||||
void OnUrgentMessageProcessed() override;
|
||||
|
6
third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
vendored
6
third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.cc
vendored
@ -14,8 +14,10 @@ BackForwardCacheDisablingFeatureTracker::
|
||||
TraceableVariableController* tracing_controller,
|
||||
ThreadSchedulerBase* scheduler)
|
||||
: opted_out_from_back_forward_cache_{false,
|
||||
"FrameScheduler."
|
||||
"OptedOutFromBackForwardCache",
|
||||
MakeNamedTrack(
|
||||
"FrameScheduler."
|
||||
"OptedOutFromBackForwardCache",
|
||||
this),
|
||||
tracing_controller,
|
||||
YesNoStateToString},
|
||||
scheduler_{scheduler} {}
|
||||
|
2
third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
vendored
2
third_party/blink/renderer/platform/scheduler/common/back_forward_cache_disabling_feature_tracker.h
vendored
@ -105,7 +105,7 @@ class PLATFORM_EXPORT BackForwardCacheDisablingFeatureTracker {
|
||||
// TODO(crbug.com/1366675): Remove back_forward_cache_disabling_features_.
|
||||
std::bitset<static_cast<size_t>(SchedulingPolicy::Feature::kMaxValue) + 1>
|
||||
back_forward_cache_disabling_features_{};
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
opted_out_from_back_forward_cache_;
|
||||
|
||||
// The last set of features passed to FrameOrWorkerScheduler::Delegate::
|
||||
|
@ -20,10 +20,11 @@ CPUTimeBudgetPool::CPUTimeBudgetPool(
|
||||
TraceableVariableController* tracing_controller,
|
||||
base::TimeTicks now)
|
||||
: BudgetPool(name),
|
||||
current_budget_level_(base::TimeDelta(),
|
||||
"RendererScheduler.BackgroundBudgetMs",
|
||||
tracing_controller,
|
||||
TimeDeltaToMilliseconds),
|
||||
current_budget_level_(
|
||||
base::TimeDelta(),
|
||||
MakeCounterTrack("RendererScheduler.BackgroundBudgetMs", this),
|
||||
tracing_controller,
|
||||
[](const base::TimeDelta& delta) { return delta.InMillisecondsF(); }),
|
||||
last_checkpoint_(now),
|
||||
cpu_percentage_(1) {}
|
||||
|
||||
@ -71,8 +72,9 @@ void CPUTimeBudgetPool::SetReportingCallback(
|
||||
bool CPUTimeBudgetPool::CanRunTasksAt(base::TimeTicks moment) const {
|
||||
if (!is_enabled_)
|
||||
return true;
|
||||
if (current_budget_level_->InMicroseconds() >= 0)
|
||||
if (current_budget_level_->InMicroseconds() >= 0) {
|
||||
return true;
|
||||
}
|
||||
base::TimeDelta time_to_recover_budget =
|
||||
-current_budget_level_ / cpu_percentage_;
|
||||
if (moment - last_checkpoint_ >= time_to_recover_budget) {
|
||||
@ -109,13 +111,14 @@ void CPUTimeBudgetPool::RecordTaskRunTime(base::TimeTicks start_time,
|
||||
EnforceBudgetLevelRestrictions();
|
||||
|
||||
if (!reporting_callback_.is_null() && old_budget_level.InSecondsF() > 0 &&
|
||||
current_budget_level_->InSecondsF() < 0) {
|
||||
current_budget_level_->InMicroseconds() < 0) {
|
||||
reporting_callback_.Run(-current_budget_level_ / cpu_percentage_);
|
||||
}
|
||||
}
|
||||
|
||||
if (current_budget_level_->InSecondsF() < 0)
|
||||
if (current_budget_level_->InMicroseconds() < 0) {
|
||||
UpdateStateForAllThrottlers(end_time);
|
||||
}
|
||||
}
|
||||
|
||||
void CPUTimeBudgetPool::OnWakeUp(base::TimeTicks now) {}
|
||||
|
@ -93,7 +93,8 @@ class PLATFORM_EXPORT CPUTimeBudgetPool : public BudgetPool {
|
||||
// that at least one task will be run every max_throttling_delay.
|
||||
std::optional<base::TimeDelta> max_throttling_delay_;
|
||||
|
||||
TraceableCounter<base::TimeDelta, TracingCategory::kInfo>
|
||||
TraceableCounter<base::TimeDelta,
|
||||
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
current_budget_level_;
|
||||
base::TimeTicks last_checkpoint_;
|
||||
double cpu_percentage_;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
namespace blink::scheduler {
|
||||
|
||||
const char* ThrottlingTypeToString(ThrottlingType type) {
|
||||
perfetto::StaticString ThrottlingTypeToString(ThrottlingType type) {
|
||||
switch (type) {
|
||||
case ThrottlingType::kNone:
|
||||
return "none";
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_TYPE_H_
|
||||
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THROTTLING_TYPE_H_
|
||||
|
||||
#include "third_party/perfetto/include/perfetto/tracing/string_helpers.h"
|
||||
|
||||
namespace blink::scheduler {
|
||||
|
||||
// Types of throttling that can be applied to a task queue.
|
||||
@ -20,7 +22,7 @@ enum class ThrottlingType {
|
||||
kBackgroundIntensive,
|
||||
};
|
||||
|
||||
const char* ThrottlingTypeToString(ThrottlingType type);
|
||||
perfetto::StaticString ThrottlingTypeToString(ThrottlingType type);
|
||||
|
||||
} // namespace blink::scheduler
|
||||
|
||||
|
@ -11,11 +11,19 @@ namespace scheduler {
|
||||
|
||||
using perfetto::protos::pbzero::RendererMainThreadTaskExecution;
|
||||
|
||||
double TimeDeltaToMilliseconds(const base::TimeDelta& value) {
|
||||
return value.InMillisecondsF();
|
||||
perfetto::NamedTrack MakeNamedTrack(perfetto::StaticString name,
|
||||
const void* ptr,
|
||||
perfetto::Track parent) {
|
||||
return perfetto::NamedTrack(name, reinterpret_cast<uintptr_t>(ptr), parent);
|
||||
}
|
||||
|
||||
const char* YesNoStateToString(bool is_yes) {
|
||||
perfetto::CounterTrack MakeCounterTrack(perfetto::StaticString name,
|
||||
const void* ptr,
|
||||
perfetto::Track parent) {
|
||||
return perfetto::CounterTrack(name, reinterpret_cast<uintptr_t>(ptr), parent);
|
||||
}
|
||||
|
||||
perfetto::StaticString YesNoStateToString(bool is_yes) {
|
||||
if (is_yes) {
|
||||
return "yes";
|
||||
} else {
|
||||
|
@ -25,31 +25,7 @@
|
||||
namespace blink {
|
||||
namespace scheduler {
|
||||
|
||||
// Available scheduler tracing categories for use with `StateTracer` and
|
||||
// friends.
|
||||
enum class TracingCategory { kTopLevel, kDefault, kInfo, kDebug };
|
||||
|
||||
namespace internal {
|
||||
|
||||
constexpr const char* TracingCategoryToString(TracingCategory category) {
|
||||
switch (category) {
|
||||
case TracingCategory::kTopLevel:
|
||||
return "toplevel";
|
||||
case TracingCategory::kDefault:
|
||||
return "renderer.scheduler";
|
||||
case TracingCategory::kInfo:
|
||||
return TRACE_DISABLED_BY_DEFAULT("renderer.scheduler");
|
||||
case TracingCategory::kDebug:
|
||||
return TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
PLATFORM_EXPORT double TimeDeltaToMilliseconds(const base::TimeDelta& value);
|
||||
|
||||
PLATFORM_EXPORT const char* YesNoStateToString(bool is_yes);
|
||||
PLATFORM_EXPORT perfetto::StaticString YesNoStateToString(bool is_yes);
|
||||
|
||||
PLATFORM_EXPORT
|
||||
perfetto::protos::pbzero::RendererMainThreadTaskExecution::TaskType
|
||||
@ -57,6 +33,15 @@ TaskTypeToProto(TaskType task_type);
|
||||
|
||||
class TraceableVariable;
|
||||
|
||||
PLATFORM_EXPORT perfetto::NamedTrack MakeNamedTrack(
|
||||
perfetto::StaticString name,
|
||||
const void* ptr,
|
||||
perfetto::Track parent = perfetto::ThreadTrack::Current());
|
||||
PLATFORM_EXPORT perfetto::CounterTrack MakeCounterTrack(
|
||||
perfetto::StaticString name,
|
||||
const void* ptr,
|
||||
perfetto::Track parent = perfetto::ThreadTrack::Current());
|
||||
|
||||
// Unfortunately, using |base::trace_event::TraceLog::EnabledStateObserver|
|
||||
// wouldn't be helpful in our case because removing one takes linear time
|
||||
// and tracers may be created and disposed frequently.
|
||||
@ -77,6 +62,17 @@ class PLATFORM_EXPORT TraceableVariableController {
|
||||
HashSet<TraceableVariable*> traceable_variables_;
|
||||
};
|
||||
|
||||
// A wrapper for string literal used in template arguments.
|
||||
template <size_t N>
|
||||
class TracingCategory {
|
||||
public:
|
||||
constexpr TracingCategory(const char (&str)[N]) {
|
||||
std::copy_n(str, N, value);
|
||||
}
|
||||
|
||||
char value[N];
|
||||
};
|
||||
|
||||
class TraceableVariable {
|
||||
public:
|
||||
TraceableVariable(TraceableVariableController* controller)
|
||||
@ -94,98 +90,33 @@ class TraceableVariable {
|
||||
const raw_ptr<TraceableVariableController> controller_; // Not owned.
|
||||
};
|
||||
|
||||
// TRACE_EVENT macros define static variable to cache a pointer to the state
|
||||
// of category. Hence, we need distinct version for each category in order to
|
||||
// prevent unintended leak of state.
|
||||
|
||||
template <TracingCategory category>
|
||||
class StateTracer {
|
||||
DISALLOW_NEW();
|
||||
|
||||
public:
|
||||
explicit StateTracer(const char* name) : name_(name), slice_is_open_(false) {}
|
||||
|
||||
StateTracer(const StateTracer&) = delete;
|
||||
StateTracer& operator=(const StateTracer&) = delete;
|
||||
|
||||
~StateTracer() {
|
||||
if (slice_is_open_) {
|
||||
TRACE_EVENT_NESTABLE_ASYNC_END0(
|
||||
internal::TracingCategoryToString(category), name_,
|
||||
TRACE_ID_LOCAL(this));
|
||||
}
|
||||
}
|
||||
|
||||
// String will be copied before leaving this function.
|
||||
void TraceString(const String& state) {
|
||||
TraceImpl(state.Utf8().c_str(), true);
|
||||
}
|
||||
|
||||
// Trace compile-time defined const string, so no copy needed.
|
||||
// Null may be passed to indicate the absence of state.
|
||||
void TraceCompileTimeString(const char* state) { TraceImpl(state, false); }
|
||||
|
||||
protected:
|
||||
bool is_enabled() const {
|
||||
bool result = false;
|
||||
TRACE_EVENT_CATEGORY_GROUP_ENABLED(
|
||||
internal::TracingCategoryToString(category), &result); // Cached.
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
void TraceImpl(const char* state, bool need_copy) {
|
||||
if (slice_is_open_) {
|
||||
TRACE_EVENT_NESTABLE_ASYNC_END0(
|
||||
internal::TracingCategoryToString(category), name_,
|
||||
TRACE_ID_LOCAL(this));
|
||||
slice_is_open_ = false;
|
||||
}
|
||||
if (!state || !is_enabled())
|
||||
return;
|
||||
|
||||
if (need_copy) {
|
||||
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
|
||||
internal::TracingCategoryToString(category), name_,
|
||||
TRACE_ID_LOCAL(this), "state", TRACE_STR_COPY(state));
|
||||
} else {
|
||||
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
|
||||
internal::TracingCategoryToString(category), name_,
|
||||
TRACE_ID_LOCAL(this), "state", state);
|
||||
}
|
||||
slice_is_open_ = true;
|
||||
}
|
||||
|
||||
const char* const name_; // Not owned.
|
||||
|
||||
// We have to track whether slice is open to avoid confusion since assignment,
|
||||
// "absent" state and OnTraceLogEnabled can happen anytime.
|
||||
bool slice_is_open_;
|
||||
};
|
||||
|
||||
// TODO(kraynov): Rename to something less generic and reflecting
|
||||
// the enum nature of such variables.
|
||||
template <typename T, TracingCategory category>
|
||||
class TraceableState : public TraceableVariable, private StateTracer<category> {
|
||||
class TraceableState : public TraceableVariable {
|
||||
public:
|
||||
// Converter must return compile-time defined const strings because tracing
|
||||
// will not make a copy of them.
|
||||
using ConverterFuncPtr = const char* (*)(T);
|
||||
using ConverterFuncPtr = perfetto::StaticString (*)(T);
|
||||
|
||||
TraceableState(T initial_state,
|
||||
const char* name,
|
||||
perfetto::NamedTrack track,
|
||||
TraceableVariableController* controller,
|
||||
ConverterFuncPtr converter)
|
||||
: TraceableVariable(controller),
|
||||
StateTracer<category>(name),
|
||||
converter_(converter),
|
||||
state_(initial_state) {
|
||||
state_(initial_state),
|
||||
track_(track) {
|
||||
Trace();
|
||||
}
|
||||
|
||||
TraceableState(const TraceableState&) = delete;
|
||||
|
||||
~TraceableState() override = default;
|
||||
~TraceableState() override {
|
||||
if (slice_is_open_) {
|
||||
TRACE_EVENT_END(category.value, track_);
|
||||
}
|
||||
}
|
||||
|
||||
TraceableState& operator=(const T& value) {
|
||||
Assign(value);
|
||||
@ -216,149 +147,29 @@ class TraceableState : public TraceableVariable, private StateTracer<category> {
|
||||
}
|
||||
}
|
||||
|
||||
void (*mock_trace_for_test_)(const char*) = nullptr;
|
||||
|
||||
private:
|
||||
void Trace() {
|
||||
if (mock_trace_for_test_) [[unlikely]] {
|
||||
mock_trace_for_test_(converter_(state_));
|
||||
if (!TRACE_EVENT_CATEGORY_ENABLED(category.value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Null state string means the absence of state.
|
||||
const char* state_str = nullptr;
|
||||
if (StateTracer<category>::is_enabled()) {
|
||||
state_str = converter_(state_);
|
||||
perfetto::StaticString state_str = converter_(state_);
|
||||
if (slice_is_open_) {
|
||||
TRACE_EVENT_END(category.value, track_);
|
||||
}
|
||||
slice_is_open_ = !!state_str;
|
||||
if (state_str) {
|
||||
TRACE_EVENT_BEGIN(category.value, state_str, track_);
|
||||
}
|
||||
|
||||
// We have to be explicit to deal with two-phase name lookup in templates:
|
||||
// http://blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html
|
||||
StateTracer<category>::TraceCompileTimeString(state_str);
|
||||
}
|
||||
|
||||
const ConverterFuncPtr converter_;
|
||||
|
||||
T state_;
|
||||
};
|
||||
|
||||
template <TracingCategory category, typename TypedValue>
|
||||
class ProtoStateTracer {
|
||||
DISALLOW_NEW();
|
||||
|
||||
public:
|
||||
explicit ProtoStateTracer(const char* name)
|
||||
: name_(name), slice_is_open_(false) {}
|
||||
|
||||
ProtoStateTracer(const ProtoStateTracer&) = delete;
|
||||
ProtoStateTracer& operator=(const ProtoStateTracer&) = delete;
|
||||
|
||||
~ProtoStateTracer() {
|
||||
if (slice_is_open_) {
|
||||
TRACE_EVENT_END(internal::TracingCategoryToString(category), track());
|
||||
}
|
||||
}
|
||||
|
||||
void TraceProto(TypedValue* value) {
|
||||
const auto trace_track = track();
|
||||
if (slice_is_open_) {
|
||||
TRACE_EVENT_END(internal::TracingCategoryToString(category), trace_track);
|
||||
slice_is_open_ = false;
|
||||
}
|
||||
if (!is_enabled())
|
||||
return;
|
||||
|
||||
TRACE_EVENT_BEGIN(internal::TracingCategoryToString(category),
|
||||
perfetto::StaticString{name_}, trace_track,
|
||||
[value](perfetto::EventContext ctx) {
|
||||
value->AsProtozeroInto(ctx.event());
|
||||
});
|
||||
|
||||
slice_is_open_ = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool is_enabled() const {
|
||||
bool result = false;
|
||||
TRACE_EVENT_CATEGORY_GROUP_ENABLED(
|
||||
internal::TracingCategoryToString(category), &result); // Cached.
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
perfetto::Track track() const {
|
||||
return perfetto::Track(reinterpret_cast<uint64_t>(this));
|
||||
}
|
||||
|
||||
const char* const name_; // Not owned.
|
||||
perfetto::NamedTrack track_;
|
||||
|
||||
// We have to track whether slice is open to avoid confusion since assignment,
|
||||
// "absent" state and OnTraceLogEnabled can happen anytime.
|
||||
bool slice_is_open_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using InitializeProtoFuncPtr =
|
||||
void (*)(perfetto::protos::pbzero::TrackEvent* event, T e);
|
||||
|
||||
template <typename T, TracingCategory category>
|
||||
class TraceableObjectState
|
||||
: public TraceableVariable,
|
||||
public ProtoStateTracer<category, TraceableObjectState<T, category>> {
|
||||
public:
|
||||
TraceableObjectState(T initial_state,
|
||||
const char* name,
|
||||
TraceableVariableController* controller,
|
||||
InitializeProtoFuncPtr<T> proto_init_func)
|
||||
: TraceableVariable(controller),
|
||||
ProtoStateTracer<category, TraceableObjectState<T, category>>(name),
|
||||
state_(initial_state),
|
||||
proto_init_func_(proto_init_func) {
|
||||
Trace();
|
||||
}
|
||||
|
||||
TraceableObjectState(const TraceableObjectState&) = delete;
|
||||
|
||||
~TraceableObjectState() override = default;
|
||||
|
||||
TraceableObjectState& operator=(const T& value) {
|
||||
Assign(value);
|
||||
return *this;
|
||||
}
|
||||
TraceableObjectState& operator=(const TraceableObjectState& another) {
|
||||
Assign(another.state_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T& get() const { return state_; }
|
||||
|
||||
void OnTraceLogEnabled() final { Trace(); }
|
||||
|
||||
void AsProtozeroInto(perfetto::protos::pbzero::TrackEvent* event) {
|
||||
proto_init_func_(event, state_);
|
||||
}
|
||||
|
||||
protected:
|
||||
void Assign(T new_state) {
|
||||
if (state_ != new_state) {
|
||||
state_ = new_state;
|
||||
Trace();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void Trace() {
|
||||
ProtoStateTracer<category, TraceableObjectState<T, category>>::TraceProto(
|
||||
this);
|
||||
}
|
||||
|
||||
bool is_enabled() const {
|
||||
bool result = false;
|
||||
TRACE_EVENT_CATEGORY_GROUP_ENABLED(
|
||||
internal::TracingCategoryToString(category), &result); // Cached.
|
||||
return result;
|
||||
}
|
||||
|
||||
T state_;
|
||||
InitializeProtoFuncPtr<T> proto_init_func_;
|
||||
bool slice_is_open_ = false;
|
||||
};
|
||||
|
||||
template <typename T, TracingCategory category>
|
||||
@ -367,20 +178,20 @@ class TraceableCounter : public TraceableVariable {
|
||||
using ConverterFuncPtr = double (*)(const T&);
|
||||
|
||||
TraceableCounter(T initial_value,
|
||||
const char* name,
|
||||
perfetto::CounterTrack track,
|
||||
TraceableVariableController* controller,
|
||||
ConverterFuncPtr converter)
|
||||
: TraceableVariable(controller),
|
||||
name_(name),
|
||||
converter_(converter),
|
||||
value_(initial_value) {
|
||||
value_(initial_value),
|
||||
track_(track) {
|
||||
Trace();
|
||||
}
|
||||
|
||||
TraceableCounter(T initial_value,
|
||||
const char* name,
|
||||
perfetto::CounterTrack track,
|
||||
TraceableVariableController* controller)
|
||||
: TraceableCounter(initial_value, name, controller, [](const T& value) {
|
||||
: TraceableCounter(initial_value, track, controller, [](const T& value) {
|
||||
return static_cast<double>(value);
|
||||
}) {}
|
||||
|
||||
@ -415,15 +226,14 @@ class TraceableCounter : public TraceableVariable {
|
||||
void OnTraceLogEnabled() final { Trace(); }
|
||||
|
||||
void Trace() const {
|
||||
TRACE_COUNTER_ID1(internal::TracingCategoryToString(category), name_, this,
|
||||
converter_(value_));
|
||||
TRACE_COUNTER(category.value, track_, converter_(value_));
|
||||
}
|
||||
|
||||
private:
|
||||
const char* const name_; // Not owned.
|
||||
const ConverterFuncPtr converter_;
|
||||
|
||||
T value_;
|
||||
perfetto::CounterTrack track_;
|
||||
};
|
||||
|
||||
// Add operators when it's needed.
|
||||
|
@ -4,7 +4,11 @@
|
||||
|
||||
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
|
||||
|
||||
#include "base/test/task_environment.h"
|
||||
#include "base/test/test_trace_processor.h"
|
||||
#include "base/test/trace_test_utils.h"
|
||||
#include "build/build_config.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace blink {
|
||||
@ -12,71 +16,56 @@ namespace scheduler {
|
||||
|
||||
namespace {
|
||||
|
||||
const char* g_last_state = nullptr;
|
||||
|
||||
void ExpectTraced(const char* state) {
|
||||
EXPECT_TRUE(state);
|
||||
EXPECT_TRUE(g_last_state);
|
||||
EXPECT_STREQ(state, g_last_state);
|
||||
g_last_state = nullptr;
|
||||
}
|
||||
|
||||
void ExpectNotTraced() {
|
||||
EXPECT_FALSE(g_last_state);
|
||||
}
|
||||
|
||||
const char* SignOfInt(int value) {
|
||||
perfetto::StaticString SignOfInt(int value) {
|
||||
if (value > 0)
|
||||
return "positive";
|
||||
if (value < 0)
|
||||
return "negative";
|
||||
return "zero";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class TraceableStateForTest
|
||||
: public TraceableState<int, TracingCategory::kDefault> {
|
||||
public:
|
||||
TraceableStateForTest(TraceableVariableController* controller)
|
||||
: TraceableState(0, "State", controller, SignOfInt) {
|
||||
// We shouldn't expect trace in constructor here because mock isn't set yet.
|
||||
mock_trace_for_test_ = &MockTrace;
|
||||
}
|
||||
|
||||
TraceableStateForTest& operator=(const int& value) {
|
||||
Assign(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static void MockTrace(const char* state) {
|
||||
EXPECT_TRUE(state);
|
||||
EXPECT_FALSE(g_last_state); // No unexpected traces.
|
||||
g_last_state = state;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(kraynov): TraceableCounter tests.
|
||||
|
||||
TEST(TracingHelperTest, TraceableState) {
|
||||
TraceableVariableController controller;
|
||||
TraceableStateForTest state(&controller);
|
||||
TraceableState<int, "renderer.scheduler"> state(
|
||||
0, perfetto::NamedTrack("State"), &controller, SignOfInt);
|
||||
|
||||
base::test::TracingEnvironment tracing_environment;
|
||||
base::test::TaskEnvironment task_environment;
|
||||
|
||||
base::test::TestTraceProcessor test_trace_processor;
|
||||
test_trace_processor.StartTrace("renderer.scheduler");
|
||||
|
||||
controller.OnTraceLogEnabled();
|
||||
ExpectTraced("zero");
|
||||
state = 0;
|
||||
ExpectNotTraced();
|
||||
state = 1;
|
||||
ExpectTraced("positive");
|
||||
state = 0;
|
||||
state = -1;
|
||||
ExpectTraced("negative");
|
||||
|
||||
auto status = test_trace_processor.StopAndParseTrace();
|
||||
ASSERT_TRUE(status.ok()) << status.message();
|
||||
|
||||
auto result = test_trace_processor.RunQuery(R"(
|
||||
SELECT slice.name
|
||||
FROM track left join slice on track.id = slice.track_id
|
||||
WHERE track.name = 'State'
|
||||
ORDER BY ts
|
||||
)");
|
||||
ASSERT_TRUE(result.has_value()) << result.error();
|
||||
EXPECT_THAT(result.value(),
|
||||
::testing::ElementsAre(std::vector<std::string>{"name"},
|
||||
std::vector<std::string>{"positive"},
|
||||
std::vector<std::string>{"negative"}));
|
||||
}
|
||||
|
||||
TEST(TracingHelperTest, TraceableStateOperators) {
|
||||
TraceableVariableController controller;
|
||||
TraceableState<int, TracingCategory::kDebug> x(-1, "X", &controller,
|
||||
SignOfInt);
|
||||
TraceableState<int, TracingCategory::kDebug> y(1, "Y", &controller,
|
||||
SignOfInt);
|
||||
TraceableState<int, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")> x(
|
||||
-1, perfetto::NamedTrack("X"), &controller, SignOfInt);
|
||||
TraceableState<int, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")> y(
|
||||
1, perfetto::NamedTrack("Y"), &controller, SignOfInt);
|
||||
EXPECT_EQ(0, x + y);
|
||||
EXPECT_FALSE(x == y);
|
||||
EXPECT_TRUE(x != y);
|
||||
|
@ -70,10 +70,6 @@ void WebThreadScheduler::ResumeTimersForAndroidWebView() {
|
||||
}
|
||||
#endif // BUILDFLAG(IS_ANDROID)
|
||||
|
||||
void WebThreadScheduler::SetRendererProcessType(WebRendererProcessType type) {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
void WebThreadScheduler::OnUrgentMessageReceived() {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ FrameOriginType GetFrameOriginType(FrameScheduler* scheduler) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* FrameOriginTypeToString(FrameOriginType origin) {
|
||||
perfetto::StaticString FrameOriginTypeToString(FrameOriginType origin) {
|
||||
switch (origin) {
|
||||
case FrameOriginType::kMainFrame:
|
||||
return "main-frame";
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_ORIGIN_TYPE_H_
|
||||
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_ORIGIN_TYPE_H_
|
||||
|
||||
#include "third_party/perfetto/include/perfetto/tracing/string_helpers.h"
|
||||
|
||||
namespace blink {
|
||||
class FrameScheduler;
|
||||
|
||||
@ -21,7 +23,7 @@ enum class FrameOriginType {
|
||||
|
||||
FrameOriginType GetFrameOriginType(FrameScheduler* frame_scheduler);
|
||||
|
||||
const char* FrameOriginTypeToString(FrameOriginType origin);
|
||||
perfetto::StaticString FrameOriginTypeToString(FrameOriginType origin);
|
||||
|
||||
} // namespace scheduler
|
||||
} // namespace blink
|
||||
|
@ -57,7 +57,7 @@ BASE_FEATURE(kRendererMainIsDefaultThreadTypeForWebRTC,
|
||||
"RendererMainIsNormalThreadTypeForWebRTC",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
|
||||
const char* VisibilityStateToString(bool is_visible) {
|
||||
perfetto::StaticString VisibilityStateToString(bool is_visible) {
|
||||
if (is_visible) {
|
||||
return "visible";
|
||||
} else {
|
||||
@ -65,7 +65,7 @@ const char* VisibilityStateToString(bool is_visible) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* IsVisibleAreaLargeStateToString(bool is_large) {
|
||||
perfetto::StaticString IsVisibleAreaLargeStateToString(bool is_large) {
|
||||
if (is_large) {
|
||||
return "large";
|
||||
} else {
|
||||
@ -73,7 +73,7 @@ const char* IsVisibleAreaLargeStateToString(bool is_large) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* UserActivationStateToString(bool had_user_activation) {
|
||||
perfetto::StaticString UserActivationStateToString(bool had_user_activation) {
|
||||
if (had_user_activation) {
|
||||
return "had user activation";
|
||||
} else {
|
||||
@ -81,7 +81,7 @@ const char* UserActivationStateToString(bool had_user_activation) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* PausedStateToString(bool is_paused) {
|
||||
perfetto::StaticString PausedStateToString(bool is_paused) {
|
||||
if (is_paused) {
|
||||
return "paused";
|
||||
} else {
|
||||
@ -89,7 +89,7 @@ const char* PausedStateToString(bool is_paused) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* FrozenStateToString(bool is_frozen) {
|
||||
perfetto::StaticString FrozenStateToString(bool is_frozen) {
|
||||
if (is_frozen) {
|
||||
return "frozen";
|
||||
} else {
|
||||
@ -162,44 +162,47 @@ FrameSchedulerImpl::FrameSchedulerImpl(
|
||||
parent_page_scheduler_ && parent_page_scheduler_->IsPageVisible()
|
||||
? PageVisibilityState::kVisible
|
||||
: PageVisibilityState::kHidden,
|
||||
"FrameScheduler.PageVisibility",
|
||||
MakeNamedTrack("FrameScheduler.PageVisibility", this),
|
||||
&tracing_controller_,
|
||||
PageVisibilityStateToString),
|
||||
frame_visible_(true,
|
||||
"FrameScheduler.FrameVisible",
|
||||
MakeNamedTrack("FrameScheduler.FrameVisible", this),
|
||||
&tracing_controller_,
|
||||
VisibilityStateToString),
|
||||
is_visible_area_large_(true,
|
||||
"FrameScheduler.IsVisibleAreaLarge",
|
||||
&tracing_controller_,
|
||||
IsVisibleAreaLargeStateToString),
|
||||
had_user_activation_(false,
|
||||
"FrameScheduler.HadUserActivation",
|
||||
&tracing_controller_,
|
||||
UserActivationStateToString),
|
||||
is_visible_area_large_(
|
||||
true,
|
||||
MakeNamedTrack("FrameScheduler.IsVisibleAreaLarge", this),
|
||||
&tracing_controller_,
|
||||
IsVisibleAreaLargeStateToString),
|
||||
had_user_activation_(
|
||||
false,
|
||||
MakeNamedTrack("FrameScheduler.HadUserActivation", this),
|
||||
&tracing_controller_,
|
||||
UserActivationStateToString),
|
||||
frame_paused_(false,
|
||||
"FrameScheduler.FramePaused",
|
||||
MakeNamedTrack("FrameScheduler.FramePaused", this),
|
||||
&tracing_controller_,
|
||||
PausedStateToString),
|
||||
frame_origin_type_(frame_type == FrameType::kMainFrame
|
||||
? FrameOriginType::kMainFrame
|
||||
: FrameOriginType::kSameOriginToMainFrame,
|
||||
"FrameScheduler.Origin",
|
||||
MakeNamedTrack("FrameScheduler.Origin", this),
|
||||
&tracing_controller_,
|
||||
FrameOriginTypeToString),
|
||||
subresource_loading_paused_(false,
|
||||
"FrameScheduler.SubResourceLoadingPaused",
|
||||
&tracing_controller_,
|
||||
PausedStateToString),
|
||||
url_tracer_("FrameScheduler.URL"),
|
||||
subresource_loading_paused_(
|
||||
false,
|
||||
MakeNamedTrack("FrameScheduler.SubResourceLoadingPaused", this),
|
||||
&tracing_controller_,
|
||||
PausedStateToString),
|
||||
url_track_("FrameScheduler.URL"),
|
||||
throttling_type_(ThrottlingType::kNone,
|
||||
"FrameScheduler.ThrottlingType",
|
||||
MakeNamedTrack("FrameScheduler.ThrottlingType", this),
|
||||
&tracing_controller_,
|
||||
ThrottlingTypeToString),
|
||||
aggressive_throttling_opt_out_count_(0),
|
||||
opted_out_from_aggressive_throttling_(
|
||||
false,
|
||||
"FrameScheduler.AggressiveThrottlingDisabled",
|
||||
MakeNamedTrack("FrameScheduler.AggressiveThrottlingDisabled", this),
|
||||
&tracing_controller_,
|
||||
YesNoStateToString),
|
||||
subresource_loading_pause_count_(0u),
|
||||
@ -209,24 +212,29 @@ FrameSchedulerImpl::FrameSchedulerImpl(
|
||||
GetLowPriorityAsyncScriptTaskPriority()),
|
||||
page_frozen_for_tracing_(
|
||||
parent_page_scheduler_ ? parent_page_scheduler_->IsFrozen() : true,
|
||||
"FrameScheduler.PageFrozen",
|
||||
MakeNamedTrack("FrameScheduler.PageFrozen", this),
|
||||
&tracing_controller_,
|
||||
FrozenStateToString),
|
||||
waiting_for_contentful_paint_(true,
|
||||
"FrameScheduler.WaitingForContentfulPaint",
|
||||
&tracing_controller_,
|
||||
YesNoStateToString),
|
||||
waiting_for_meaningful_paint_(true,
|
||||
"FrameScheduler.WaitingForMeaningfulPaint",
|
||||
&tracing_controller_,
|
||||
YesNoStateToString),
|
||||
is_load_event_dispatched_(false,
|
||||
"FrameScheduler.IsLoadEventDispatched",
|
||||
&tracing_controller_,
|
||||
YesNoStateToString) {
|
||||
waiting_for_contentful_paint_(
|
||||
true,
|
||||
MakeNamedTrack("FrameScheduler.WaitingForContentfulPaint", this),
|
||||
&tracing_controller_,
|
||||
YesNoStateToString),
|
||||
waiting_for_meaningful_paint_(
|
||||
true,
|
||||
MakeNamedTrack("FrameScheduler.WaitingForMeaningfulPaint", this),
|
||||
&tracing_controller_,
|
||||
YesNoStateToString),
|
||||
is_load_event_dispatched_(
|
||||
false,
|
||||
MakeNamedTrack("FrameScheduler.IsLoadEventDispatched", this),
|
||||
&tracing_controller_,
|
||||
YesNoStateToString) {
|
||||
frame_task_queue_controller_ = base::WrapUnique(
|
||||
new FrameTaskQueueController(main_thread_scheduler_, this, this));
|
||||
back_forward_cache_disabling_feature_tracker_.SetDelegate(delegate_);
|
||||
TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
||||
"FrameScheduler.URL", url_track_, "url", "Unknown");
|
||||
}
|
||||
|
||||
FrameSchedulerImpl::FrameSchedulerImpl()
|
||||
@ -239,6 +247,8 @@ FrameSchedulerImpl::FrameSchedulerImpl()
|
||||
FrameSchedulerImpl::~FrameSchedulerImpl() {
|
||||
weak_factory_.InvalidateWeakPtrs();
|
||||
|
||||
TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), url_track_);
|
||||
|
||||
for (const auto& task_queue_and_voter :
|
||||
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
|
||||
if (task_queue_and_voter.first->CanBeThrottled()) {
|
||||
@ -436,7 +446,9 @@ void FrameSchedulerImpl::SetAgentClusterId(
|
||||
}
|
||||
|
||||
void FrameSchedulerImpl::TraceUrlChange(const String& url) {
|
||||
url_tracer_.TraceString(url);
|
||||
TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), url_track_);
|
||||
TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
|
||||
"FrameScheduler.URL", url_track_, "url", url);
|
||||
}
|
||||
|
||||
void FrameSchedulerImpl::AddTaskTime(base::TimeDelta time) {
|
||||
|
@ -360,19 +360,30 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
|
||||
main_thread_scheduler_; // NOT OWNED
|
||||
raw_ptr<PageSchedulerImpl> parent_page_scheduler_; // NOT OWNED
|
||||
raw_ptr<FrameScheduler::Delegate> delegate_; // NOT OWNED
|
||||
TraceableState<PageVisibilityState, TracingCategory::kInfo> page_visibility_;
|
||||
TraceableState<bool, TracingCategory::kInfo> frame_visible_;
|
||||
TraceableState<bool, TracingCategory::kInfo> is_visible_area_large_;
|
||||
TraceableState<bool, TracingCategory::kInfo> had_user_activation_;
|
||||
TraceableState<bool, TracingCategory::kInfo> frame_paused_;
|
||||
TraceableState<FrameOriginType, TracingCategory::kInfo> frame_origin_type_;
|
||||
TraceableState<bool, TracingCategory::kInfo> subresource_loading_paused_;
|
||||
StateTracer<TracingCategory::kInfo> url_tracer_;
|
||||
TraceableState<ThrottlingType, TracingCategory::kInfo> throttling_type_;
|
||||
TraceableState<PageVisibilityState,
|
||||
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
page_visibility_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
frame_visible_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
is_visible_area_large_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
had_user_activation_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
frame_paused_;
|
||||
TraceableState<FrameOriginType,
|
||||
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
frame_origin_type_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
subresource_loading_paused_;
|
||||
perfetto::NamedTrack url_track_;
|
||||
TraceableState<ThrottlingType,
|
||||
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
throttling_type_;
|
||||
Vector<MainThreadTaskQueue::ThrottleHandle> throttled_task_queue_handles_;
|
||||
// TODO(https://crbug.com/827113): Trace the count of opt-outs.
|
||||
int aggressive_throttling_opt_out_count_;
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
opted_out_from_aggressive_throttling_;
|
||||
size_t subresource_loading_pause_count_;
|
||||
|
||||
@ -386,11 +397,15 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
|
||||
// These are the states of the Page.
|
||||
// They should be accessed via GetPageScheduler()->SetPageState().
|
||||
// they are here because we don't support page-level tracing yet.
|
||||
TraceableState<bool, TracingCategory::kInfo> page_frozen_for_tracing_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
page_frozen_for_tracing_;
|
||||
|
||||
TraceableState<bool, TracingCategory::kInfo> waiting_for_contentful_paint_;
|
||||
TraceableState<bool, TracingCategory::kInfo> waiting_for_meaningful_paint_;
|
||||
TraceableState<bool, TracingCategory::kInfo> is_load_event_dispatched_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
waiting_for_contentful_paint_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
waiting_for_meaningful_paint_;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
is_load_event_dispatched_;
|
||||
base::TimeTicks first_meaningful_paint_timestamp_;
|
||||
|
||||
using TaskRunnerMap =
|
||||
|
6
third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
vendored
6
third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
vendored
@ -986,7 +986,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
testing::Values(TaskType::kJavascriptTimerDelayedLowNesting,
|
||||
TaskType::kJavascriptTimerDelayedHighNesting),
|
||||
[](const testing::TestParamInfo<TaskType>& info) {
|
||||
return TaskTypeNames::TaskTypeToString(info.param);
|
||||
return TaskTypeNames::TaskTypeToString(info.param).value;
|
||||
});
|
||||
|
||||
TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) {
|
||||
@ -1540,7 +1540,7 @@ TEST_F(FrameSchedulerImplTest, ThrottledTaskTypes) {
|
||||
for (TaskType task_type : kAllFrameTaskTypes) {
|
||||
SCOPED_TRACE(testing::Message()
|
||||
<< "TaskType is "
|
||||
<< TaskTypeNames::TaskTypeToString(task_type));
|
||||
<< TaskTypeNames::TaskTypeToString(task_type).value);
|
||||
switch (task_type) {
|
||||
case TaskType::kIdleTask:
|
||||
case TaskType::kInternalContentCapture:
|
||||
@ -2913,7 +2913,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
/* task_type=*/TaskType::kWebSchedulingPostedTask,
|
||||
/* is_intensive_throttling_expected=*/true}),
|
||||
[](const testing::TestParamInfo<IntensiveWakeUpThrottlingTestParam>& info) {
|
||||
return TaskTypeNames::TaskTypeToString(info.param.task_type);
|
||||
return TaskTypeNames::TaskTypeToString(info.param.task_type).value;
|
||||
});
|
||||
|
||||
TEST_F(FrameSchedulerImplTestWithIntensiveWakeUpThrottlingPolicyOverride,
|
||||
|
@ -87,7 +87,7 @@ const double kShortIdlePeriodDurationPercentile = 50;
|
||||
// which main thread compositing can be considered fast.
|
||||
const double kFastCompositingIdleTimeThreshold = .2;
|
||||
|
||||
const char* AudioPlayingStateToString(bool is_audio_playing) {
|
||||
perfetto::StaticString AudioPlayingStateToString(bool is_audio_playing) {
|
||||
if (is_audio_playing) {
|
||||
return "playing";
|
||||
} else {
|
||||
@ -95,17 +95,7 @@ const char* AudioPlayingStateToString(bool is_audio_playing) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* RendererProcessTypeToString(WebRendererProcessType process_type) {
|
||||
switch (process_type) {
|
||||
case WebRendererProcessType::kRenderer:
|
||||
return "normal";
|
||||
case WebRendererProcessType::kExtensionRenderer:
|
||||
return "extension";
|
||||
}
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
const char* OptionalTaskDescriptionToString(
|
||||
perfetto::StaticString OptionalTaskDescriptionToString(
|
||||
std::optional<MainThreadSchedulerImpl::TaskDescriptionForTracing> desc) {
|
||||
if (!desc)
|
||||
return nullptr;
|
||||
@ -113,14 +103,20 @@ const char* OptionalTaskDescriptionToString(
|
||||
return TaskTypeNames::TaskTypeToString(desc->task_type);
|
||||
if (!desc->queue_type)
|
||||
return "detached_tq";
|
||||
return perfetto::protos::pbzero::SequenceManagerTask::QueueName_Name(
|
||||
MainThreadTaskQueue::NameForQueueType(desc->queue_type.value()));
|
||||
return perfetto::StaticString(
|
||||
perfetto::protos::pbzero::SequenceManagerTask::QueueName_Name(
|
||||
MainThreadTaskQueue::NameForQueueType(desc->queue_type.value())));
|
||||
}
|
||||
|
||||
const char* OptionalTaskPriorityToString(std::optional<TaskPriority> priority) {
|
||||
perfetto::StaticString TaskPriorityToStaticString(TaskPriority priority) {
|
||||
return perfetto::StaticString(TaskPriorityToString(priority));
|
||||
}
|
||||
|
||||
perfetto::StaticString OptionalTaskPriorityToString(
|
||||
std::optional<TaskPriority> priority) {
|
||||
if (!priority)
|
||||
return nullptr;
|
||||
return TaskPriorityToString(*priority);
|
||||
return "Unknown";
|
||||
return TaskPriorityToStaticString(*priority);
|
||||
}
|
||||
|
||||
bool IsBlockingEvent(const blink::WebInputEvent& web_input_event) {
|
||||
@ -141,7 +137,7 @@ bool IsBlockingEvent(const blink::WebInputEvent& web_input_event) {
|
||||
blink::WebInputEvent::DispatchType::kBlocking;
|
||||
}
|
||||
|
||||
const char* InputEventStateToString(
|
||||
perfetto::StaticString InputEventStateToString(
|
||||
WidgetScheduler::InputEventState input_event_state) {
|
||||
switch (input_event_state) {
|
||||
case WidgetScheduler::InputEventState::EVENT_CONSUMED_BY_COMPOSITOR:
|
||||
@ -153,7 +149,7 @@ const char* InputEventStateToString(
|
||||
}
|
||||
}
|
||||
|
||||
const char* RenderingPrioritizationStateToString(
|
||||
perfetto::StaticString RenderingPrioritizationStateToString(
|
||||
MainThreadSchedulerImpl::RenderingPrioritizationState state) {
|
||||
using RenderingPrioritizationState =
|
||||
MainThreadSchedulerImpl::RenderingPrioritizationState;
|
||||
@ -336,63 +332,61 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly(
|
||||
kShortIdlePeriodDurationSampleCount,
|
||||
kShortIdlePeriodDurationPercentile),
|
||||
current_use_case(UseCase::kNone,
|
||||
"Scheduler.UseCase",
|
||||
MakeNamedTrack("Scheduler.UseCase", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
UseCaseToString),
|
||||
renderer_pause_count(0,
|
||||
"Scheduler.PauseCount",
|
||||
MakeCounterTrack("Scheduler.PauseCount", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_),
|
||||
blocking_input_expected_soon(
|
||||
false,
|
||||
"Scheduler.BlockingInputExpectedSoon",
|
||||
MakeNamedTrack("Scheduler.BlockingInputExpectedSoon", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
in_idle_period_for_testing(
|
||||
false,
|
||||
"Scheduler.InIdlePeriod",
|
||||
MakeNamedTrack("Scheduler.InIdlePeriod", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
is_audio_playing(false,
|
||||
"RendererAudioState",
|
||||
MakeNamedTrack("Renderer audible", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
AudioPlayingStateToString),
|
||||
compositor_will_send_main_frame_not_expected(
|
||||
false,
|
||||
"Scheduler.CompositorWillSendMainFrameNotExpected",
|
||||
MakeNamedTrack("Scheduler.CompositorWillSendMainFrameNotExpected",
|
||||
this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
has_navigated(false,
|
||||
"Scheduler.HasNavigated",
|
||||
MakeNamedTrack("Scheduler.HasNavigated", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
pause_timers_for_webview(false,
|
||||
"Scheduler.PauseTimersForWebview",
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
pause_timers_for_webview(
|
||||
false,
|
||||
MakeNamedTrack("Scheduler.PauseTimersForWebview", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
background_status_changed_at(now),
|
||||
metrics_helper(main_thread_scheduler_impl, now),
|
||||
process_type(WebRendererProcessType::kRenderer,
|
||||
"RendererProcessType",
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
RendererProcessTypeToString),
|
||||
task_description_for_tracing(
|
||||
std::nullopt,
|
||||
"Scheduler.MainThreadTask",
|
||||
MakeNamedTrack("Scheduler.MainThreadTask", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
OptionalTaskDescriptionToString),
|
||||
task_priority_for_tracing(
|
||||
std::nullopt,
|
||||
"Scheduler.TaskPriority",
|
||||
MakeNamedTrack("Scheduler.TaskPriority", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
OptionalTaskPriorityToString),
|
||||
main_thread_compositing_is_fast(false),
|
||||
compositor_priority(TaskPriority::kNormalPriority,
|
||||
"Scheduler.CompositorPriority",
|
||||
MakeNamedTrack("Scheduler.CompositorPriority", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
TaskPriorityToString),
|
||||
TaskPriorityToStaticString),
|
||||
main_frame_prioritization_state(
|
||||
RenderingPrioritizationState::kNone,
|
||||
"RenderingPrioritizationState",
|
||||
MakeNamedTrack("RenderingPrioritizationState", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
RenderingPrioritizationStateToString),
|
||||
last_frame_time(now),
|
||||
@ -406,52 +400,52 @@ MainThreadSchedulerImpl::AnyThread::AnyThread(
|
||||
MainThreadSchedulerImpl* main_thread_scheduler_impl)
|
||||
: awaiting_touch_start_response(
|
||||
false,
|
||||
"Scheduler.AwaitingTouchstartResponse",
|
||||
MakeNamedTrack("Scheduler.AwaitingTouchstartResponse", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
awaiting_discrete_input_response(
|
||||
false,
|
||||
"Scheduler.AwaitingDiscreteInputResponse",
|
||||
MakeNamedTrack("Scheduler.AwaitingDiscreteInputResponse", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
begin_main_frame_on_critical_path(
|
||||
false,
|
||||
"Scheduler.BeginMainFrameOnCriticalPath",
|
||||
MakeNamedTrack("Scheduler.BeginMainFrameOnCriticalPath", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
last_gesture_was_compositor_driven(
|
||||
false,
|
||||
"Scheduler.LastGestureWasCompositorDriven",
|
||||
MakeNamedTrack("Scheduler.LastGestureWasCompositorDriven", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
default_gesture_prevented(
|
||||
true,
|
||||
"Scheduler.DefaultGesturePrevented",
|
||||
MakeNamedTrack("Scheduler.DefaultGesturePrevented", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
have_seen_a_blocking_gesture(
|
||||
false,
|
||||
"Scheduler.HaveSeenBlockingGesture",
|
||||
MakeNamedTrack("Scheduler.HaveSeenBlockingGesture", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
waiting_for_any_main_frame_contentful_paint(
|
||||
false,
|
||||
"Scheduler.WaitingForMainFrameContentfulPaint",
|
||||
MakeNamedTrack("Scheduler.WaitingForMainFrameContentfulPaint", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
waiting_for_any_main_frame_meaningful_paint(
|
||||
false,
|
||||
"Scheduler.WaitingForMeaningfulPaint",
|
||||
MakeNamedTrack("Scheduler.WaitingForMeaningfulPaint", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
is_any_main_frame_loading(
|
||||
false,
|
||||
"Scheduler.IsAnyMainFrameLoading",
|
||||
MakeNamedTrack("Scheduler.IsAnyMainFrameLoading", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString),
|
||||
have_seen_input_since_navigation(
|
||||
false,
|
||||
"Scheduler.HaveSeenInputSinceNavigation",
|
||||
MakeNamedTrack("Scheduler.HaveSeenInputSinceNavigation", this),
|
||||
&main_thread_scheduler_impl->tracing_controller_,
|
||||
YesNoStateToString) {}
|
||||
|
||||
@ -1943,11 +1937,6 @@ void MainThreadSchedulerImpl::ForEachMainThreadIsolate(
|
||||
}
|
||||
}
|
||||
|
||||
void MainThreadSchedulerImpl::SetRendererProcessType(
|
||||
WebRendererProcessType type) {
|
||||
main_thread_only().process_type = type;
|
||||
}
|
||||
|
||||
Vector<WebInputEventAttribution>
|
||||
MainThreadSchedulerImpl::GetPendingUserInputInfo(
|
||||
bool include_continuous) const {
|
||||
|
@ -186,7 +186,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
|
||||
void PauseTimersForAndroidWebView() override;
|
||||
void ResumeTimersForAndroidWebView() override;
|
||||
#endif
|
||||
void SetRendererProcessType(WebRendererProcessType type) override;
|
||||
void OnUrgentMessageReceived() override;
|
||||
void OnUrgentMessageProcessed() override;
|
||||
|
||||
@ -697,40 +696,40 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
|
||||
~MainThreadOnly();
|
||||
|
||||
IdleTimeEstimator idle_time_estimator;
|
||||
TraceableState<UseCase, TracingCategory::kDefault> current_use_case;
|
||||
TraceableState<UseCase, "renderer.scheduler"> current_use_case;
|
||||
Policy current_policy;
|
||||
base::TimeTicks current_policy_expiration_time;
|
||||
base::TimeTicks estimated_next_frame_begin;
|
||||
base::TimeTicks current_task_start_time;
|
||||
base::TimeTicks discrete_input_response_start_time;
|
||||
base::TimeDelta compositor_frame_interval;
|
||||
TraceableCounter<int, TracingCategory::kInfo>
|
||||
TraceableCounter<int, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
renderer_pause_count; // Renderer is paused if non-zero.
|
||||
|
||||
bool renderer_hidden = false;
|
||||
std::optional<base::ScopedSampleMetadata> renderer_hidden_metadata;
|
||||
std::optional<base::ScopedSampleMetadata> renderer_frozen_metadata;
|
||||
bool renderer_backgrounded = kLaunchingProcessIsBackgrounded;
|
||||
TraceableState<bool, TracingCategory::kDefault>
|
||||
blocking_input_expected_soon;
|
||||
TraceableState<bool, TracingCategory::kDebug> in_idle_period_for_testing;
|
||||
TraceableState<bool, TracingCategory::kTopLevel> is_audio_playing;
|
||||
TraceableState<bool, TracingCategory::kDebug>
|
||||
TraceableState<bool, "renderer.scheduler"> blocking_input_expected_soon;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")>
|
||||
in_idle_period_for_testing;
|
||||
TraceableState<bool, "renderer"> is_audio_playing;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")>
|
||||
compositor_will_send_main_frame_not_expected;
|
||||
TraceableState<bool, TracingCategory::kDebug> has_navigated;
|
||||
TraceableState<bool, TracingCategory::kDebug> pause_timers_for_webview;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")>
|
||||
has_navigated;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")>
|
||||
pause_timers_for_webview;
|
||||
base::TimeTicks background_status_changed_at;
|
||||
HashSet<PageSchedulerImpl*> page_schedulers; // Not owned.
|
||||
base::ObserverList<RAILModeObserver>::Unchecked
|
||||
rail_mode_observers; // Not owned.
|
||||
MainThreadMetricsHelper metrics_helper;
|
||||
TraceableState<WebRendererProcessType, TracingCategory::kTopLevel>
|
||||
process_type;
|
||||
TraceableState<std::optional<TaskDescriptionForTracing>,
|
||||
TracingCategory::kInfo>
|
||||
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
task_description_for_tracing; // Don't use except for tracing.
|
||||
TraceableState<std::optional<TaskPriority>,
|
||||
TracingCategory::kInfo>
|
||||
TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
task_priority_for_tracing; // Only used for tracing.
|
||||
|
||||
// Holds task queues that are currently running.
|
||||
@ -749,9 +748,9 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
|
||||
// kNormalPriority and is updated via UpdateCompositorTaskQueuePriority().
|
||||
// After 100ms with nothing running from this queue, the compositor will
|
||||
// be set to kVeryHighPriority until a frame is run.
|
||||
TraceableState<TaskPriority, TracingCategory::kDefault> compositor_priority;
|
||||
TraceableState<TaskPriority, "renderer.scheduler"> compositor_priority;
|
||||
|
||||
TraceableState<RenderingPrioritizationState, TracingCategory::kDefault>
|
||||
TraceableState<RenderingPrioritizationState, "renderer.scheduler">
|
||||
main_frame_prioritization_state;
|
||||
// Signals needed to compute the `main_frame_prioritization_state`.
|
||||
base::TimeTicks last_frame_time;
|
||||
@ -786,21 +785,25 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl
|
||||
|
||||
PendingUserInput::Monitor pending_input_monitor;
|
||||
UserModel user_model;
|
||||
TraceableState<bool, TracingCategory::kInfo> awaiting_touch_start_response;
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
awaiting_touch_start_response;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
awaiting_discrete_input_response;
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
begin_main_frame_on_critical_path;
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
last_gesture_was_compositor_driven;
|
||||
TraceableState<bool, TracingCategory::kInfo> default_gesture_prevented;
|
||||
TraceableState<bool, TracingCategory::kInfo> have_seen_a_blocking_gesture;
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
default_gesture_prevented;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
have_seen_a_blocking_gesture;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
waiting_for_any_main_frame_contentful_paint;
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
waiting_for_any_main_frame_meaningful_paint;
|
||||
TraceableState<bool, TracingCategory::kInfo> is_any_main_frame_loading;
|
||||
TraceableState<bool, TracingCategory::kInfo>
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
is_any_main_frame_loading;
|
||||
TraceableState<bool, TRACE_DISABLED_BY_DEFAULT("renderer.scheduler")>
|
||||
have_seen_input_since_navigation;
|
||||
};
|
||||
|
||||
|
3
third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
vendored
3
third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
vendored
@ -312,7 +312,8 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl {
|
||||
update_policy_count_++;
|
||||
MainThreadSchedulerImpl::UpdatePolicyLocked(update_type);
|
||||
|
||||
String use_case = UseCaseToString(main_thread_only().current_use_case);
|
||||
String use_case =
|
||||
UseCaseToString(main_thread_only().current_use_case).value;
|
||||
if (main_thread_only().blocking_input_expected_soon) {
|
||||
use_cases_.push_back(use_case + " blocking input expected");
|
||||
} else {
|
||||
|
@ -7,7 +7,8 @@
|
||||
namespace blink {
|
||||
namespace scheduler {
|
||||
|
||||
const char* PageVisibilityStateToString(PageVisibilityState visibility) {
|
||||
perfetto::StaticString PageVisibilityStateToString(
|
||||
PageVisibilityState visibility) {
|
||||
switch (visibility) {
|
||||
case PageVisibilityState::kVisible:
|
||||
return "visible";
|
||||
|
@ -5,18 +5,19 @@
|
||||
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_PAGE_VISIBILITY_STATE_H_
|
||||
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_PAGE_VISIBILITY_STATE_H_
|
||||
|
||||
namespace blink {
|
||||
namespace scheduler {
|
||||
#include "third_party/perfetto/include/perfetto/tracing/string_helpers.h"
|
||||
|
||||
namespace blink::scheduler {
|
||||
|
||||
// TODO(altimin): Move to core/.
|
||||
enum class PageVisibilityState { kVisible, kHidden };
|
||||
|
||||
const char* PageVisibilityStateToString(PageVisibilityState visibility);
|
||||
perfetto::StaticString PageVisibilityStateToString(
|
||||
PageVisibilityState visibility);
|
||||
|
||||
constexpr PageVisibilityState kDefaultPageVisibility =
|
||||
PageVisibilityState::kVisible;
|
||||
|
||||
} // namespace scheduler
|
||||
} // namespace blink
|
||||
} // namespace blink::scheduler
|
||||
|
||||
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_PAGE_VISIBILITY_STATE_H_
|
||||
|
@ -10,7 +10,7 @@ namespace blink {
|
||||
namespace scheduler {
|
||||
|
||||
// static
|
||||
const char* TaskTypeNames::TaskTypeToString(TaskType task_type) {
|
||||
perfetto::StaticString TaskTypeNames::TaskTypeToString(TaskType task_type) {
|
||||
// These names are used in finch trials and should not be changed.
|
||||
switch (task_type) {
|
||||
case TaskType::kDeprecatedNone:
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/string_hash.h"
|
||||
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
|
||||
#include "third_party/perfetto/include/perfetto/tracing/string_helpers.h"
|
||||
|
||||
namespace blink {
|
||||
namespace scheduler {
|
||||
@ -18,7 +19,7 @@ class PLATFORM_EXPORT TaskTypeNames {
|
||||
STATIC_ONLY(TaskTypeNames);
|
||||
|
||||
public:
|
||||
static const char* TaskTypeToString(TaskType task_type);
|
||||
static perfetto::StaticString TaskTypeToString(TaskType task_type);
|
||||
};
|
||||
|
||||
} // namespace scheduler
|
||||
|
@ -7,7 +7,7 @@
|
||||
namespace blink::scheduler {
|
||||
|
||||
// static
|
||||
const char* UseCaseToString(UseCase use_case) {
|
||||
perfetto::StaticString UseCaseToString(UseCase use_case) {
|
||||
switch (use_case) {
|
||||
case UseCase::kNone:
|
||||
return "none";
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USE_CASE_H_
|
||||
|
||||
#include "third_party/blink/renderer/platform/platform_export.h"
|
||||
#include "third_party/perfetto/include/perfetto/tracing/string_helpers.h"
|
||||
|
||||
namespace blink::scheduler {
|
||||
|
||||
@ -52,7 +53,7 @@ enum class UseCase {
|
||||
kMaxValue = kDiscreteInputResponse
|
||||
};
|
||||
|
||||
PLATFORM_EXPORT const char* UseCaseToString(UseCase);
|
||||
PLATFORM_EXPORT perfetto::StaticString UseCaseToString(UseCase);
|
||||
|
||||
} // namespace blink::scheduler
|
||||
|
||||
|
@ -41,8 +41,5 @@ void WebFakeThreadScheduler::ResumeTimersForAndroidWebView() {}
|
||||
|
||||
void WebFakeThreadScheduler::Shutdown() {}
|
||||
|
||||
void WebFakeThreadScheduler::SetRendererProcessType(
|
||||
WebRendererProcessType type) {}
|
||||
|
||||
} // namespace scheduler
|
||||
} // namespace blink
|
||||
|
Reference in New Issue
Block a user