diff --git a/BUILD.gn b/BUILD.gn index 571049f3e4..5828a81e00 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -174,16 +174,18 @@ config("common_inherited_config") { defines += [ "RTC_ENABLE_WIN_WGC" ] } - # Some tests need to declare their own trace event handlers. If this define is - # not set, the first time TRACE_EVENT_* is called it will store the return - # value for the current handler in an static variable, so that subsequent - # changes to the handler for that TRACE_EVENT_* will be ignored. - # So when tests are included, we set this define, making it possible to use - # different event handlers in different tests. - if (rtc_include_tests) { - defines += [ "WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1" ] - } else { - defines += [ "WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=0" ] + if (!rtc_use_perfetto) { + # Some tests need to declare their own trace event handlers. If this define is + # not set, the first time TRACE_EVENT_* is called it will store the return + # value for the current handler in an static variable, so that subsequent + # changes to the handler for that TRACE_EVENT_* will be ignored. + # So when tests are included, we set this define, making it possible to use + # different event handlers in different tests. + if (rtc_include_tests) { + defines += [ "WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1" ] + } else { + defines += [ "WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=0" ] + } } if (build_with_chromium) { defines += [ "WEBRTC_CHROMIUM_BUILD" ] @@ -269,6 +271,30 @@ config("rtc_prod_config") { } } +group("tracing") { + if (rtc_use_perfetto) { + if (build_with_chromium) { + public_deps = # no-presubmit-check TODO(webrtc:8603) + [ "//third_party/perfetto:libperfetto" ] + } else { + public_deps = # no-presubmit-check TODO(webrtc:8603) + [ ":webrtc_libperfetto" ] + } + } +} + +if (rtc_use_perfetto) { + rtc_library("webrtc_libperfetto") { + public_configs = [ "//third_party/perfetto/gn:public_config" ] + deps = [ + "//third_party/perfetto/src/tracing:client_api_without_backends", + "//third_party/perfetto/src/tracing:platform_impl", + ] + public_deps += # no-presubmit-check TODO(webrtc:8603) + [ "//third_party/perfetto/include/perfetto/tracing" ] + } +} + config("common_config") { cflags = [] cflags_c = [] @@ -478,6 +504,10 @@ config("common_config") { "/U_UNICODE", ] } + + if (rtc_use_perfetto) { + defines += [ "RTC_USE_PERFETTO" ] + } } config("common_objc") { diff --git a/DEPS b/DEPS index 69c52e8dca..89ffcb425a 100644 --- a/DEPS +++ b/DEPS @@ -2668,6 +2668,10 @@ include_rules = [ # Abseil flags are allowed in tests and tools. "+absl/flags", + + # Perfetto + '+third_party/perfetto/include/perfetto/tracing', + '+third_party/perfetto/include/perfetto/test', ] specific_include_rules = { diff --git a/build_overrides/build.gni b/build_overrides/build.gni index cfa795870a..219de19556 100644 --- a/build_overrides/build.gni +++ b/build_overrides/build.gni @@ -34,6 +34,9 @@ ubsan_vptr_ignorelist_path = # so we just ignore that assert. See https://crbug.com/648948 for more info. ignore_elf32_limitations = true +perfetto_build_with_embedder = true +enable_perfetto_trace_processor = true + # Use bundled hermetic Xcode installation maintainted by Chromium, # except for local iOS builds where it's unsupported. # Allow for mac cross compile on linux machines. diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc index 1ff060c061..8c28532d40 100644 --- a/pc/rtc_stats_integrationtest.cc +++ b/pc/rtc_stats_integrationtest.cc @@ -50,64 +50,11 @@ namespace { const int64_t kGetStatsTimeoutMs = 10000; -const unsigned char* GetCategoryEnabledHandler(const char* name) { - if (strcmp("webrtc_stats", name) != 0) { - return reinterpret_cast(""); - } - return reinterpret_cast(name); -} - -class RTCStatsReportTraceListener { - public: - static void SetUp() { - if (!traced_report_) - traced_report_ = new RTCStatsReportTraceListener(); - traced_report_->last_trace_ = ""; - SetupEventTracer(&GetCategoryEnabledHandler, - &RTCStatsReportTraceListener::AddTraceEventHandler); - } - - static const std::string& last_trace() { - RTC_DCHECK(traced_report_); - return traced_report_->last_trace_; - } - - private: - static void AddTraceEventHandler( - char phase, - const unsigned char* category_enabled, - const char* name, - unsigned long long id, // NOLINT(runtime/int) - int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values, // NOLINT(runtime/int) - unsigned char flags) { - RTC_DCHECK(traced_report_); - EXPECT_STREQ("webrtc_stats", - reinterpret_cast(category_enabled)); - EXPECT_STREQ("webrtc_stats", name); - EXPECT_EQ(1, num_args); - EXPECT_STREQ("report", arg_names[0]); - EXPECT_EQ(TRACE_VALUE_TYPE_COPY_STRING, arg_types[0]); - - traced_report_->last_trace_ = reinterpret_cast(arg_values[0]); - } - - static RTCStatsReportTraceListener* traced_report_; - std::string last_trace_; -}; - -RTCStatsReportTraceListener* RTCStatsReportTraceListener::traced_report_ = - nullptr; - class RTCStatsIntegrationTest : public ::testing::Test { public: RTCStatsIntegrationTest() : network_thread_(new rtc::Thread(&virtual_socket_server_)), worker_thread_(rtc::Thread::Create()) { - RTCStatsReportTraceListener::SetUp(); - RTC_CHECK(network_thread_->Start()); RTC_CHECK(worker_thread_->Start()); @@ -1054,10 +1001,6 @@ TEST_F(RTCStatsIntegrationTest, GetStatsFromCaller) { rtc::scoped_refptr report = GetStatsFromCaller(); RTCStatsReportVerifier(report.get()).VerifyReport({}); - -#if RTC_TRACE_EVENTS_ENABLED - EXPECT_EQ(report->ToJson(), RTCStatsReportTraceListener::last_trace()); -#endif } TEST_F(RTCStatsIntegrationTest, GetStatsFromCallee) { @@ -1076,10 +1019,6 @@ TEST_F(RTCStatsIntegrationTest, GetStatsFromCallee) { }; EXPECT_TRUE_WAIT(GetStatsReportAndReturnTrueIfRttIsDefined(), kMaxWaitMs); RTCStatsReportVerifier(report.get()).VerifyReport({}); - -#if RTC_TRACE_EVENTS_ENABLED - EXPECT_EQ(report->ToJson(), RTCStatsReportTraceListener::last_trace()); -#endif } // These tests exercise the integration of the stats selection algorithm inside @@ -1157,10 +1096,6 @@ TEST_F(RTCStatsIntegrationTest, // Any pending stats requests should have completed in the act of destroying // the peer connection. ASSERT_TRUE(stats_obtainer->report()); -#if RTC_TRACE_EVENTS_ENABLED - EXPECT_EQ(stats_obtainer->report()->ToJson(), - RTCStatsReportTraceListener::last_trace()); -#endif } TEST_F(RTCStatsIntegrationTest, GetsStatsWhileClosingPeerConnection) { @@ -1172,10 +1107,6 @@ TEST_F(RTCStatsIntegrationTest, GetsStatsWhileClosingPeerConnection) { caller_->pc()->Close(); ASSERT_TRUE(stats_obtainer->report()); -#if RTC_TRACE_EVENTS_ENABLED - EXPECT_EQ(stats_obtainer->report()->ToJson(), - RTCStatsReportTraceListener::last_trace()); -#endif } // GetStatsReferencedIds() is optimized to recognize what is or isn't a diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index b3cb17c274..e5ead5b0f5 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -215,6 +215,13 @@ rtc_library("event_tracer") { "system:rtc_export", ] absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] + if (rtc_use_perfetto) { + sources += [ + "trace_categories.cc", + "trace_categories.h", + ] + deps += [ "..:tracing" ] + } } rtc_library("histogram_percentile_counter") { diff --git a/rtc_base/DEPS b/rtc_base/DEPS index 3a77b5502a..4ba8c92e33 100644 --- a/rtc_base/DEPS +++ b/rtc_base/DEPS @@ -12,4 +12,10 @@ specific_include_rules = { "gunit\.h": [ "+testing/base/public/gunit.h" ], + "trace_categories\.h": [ + "+perfetto", + ], + "event_tracer\.cc": [ + "+perfetto", + ] } diff --git a/rtc_base/event_tracer.cc b/rtc_base/event_tracer.cc index 6ad83300ab..677b95bb70 100644 --- a/rtc_base/event_tracer.cc +++ b/rtc_base/event_tracer.cc @@ -7,11 +7,19 @@ * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ + #include "rtc_base/event_tracer.h" +#include + +#include "rtc_base/trace_event.h" + +#if defined(RTC_USE_PERFETTO) +#include "perfetto/tracing/tracing.h" +#include "rtc_base/trace_categories.h" +#else #include #include -#include #include #include @@ -28,21 +36,27 @@ #include "rtc_base/synchronization/mutex.h" #include "rtc_base/thread_annotations.h" #include "rtc_base/time_utils.h" -#include "rtc_base/trace_event.h" - -// This is a guesstimate that should be enough in most cases. -static const size_t kEventLoggerArgsStrBufferInitialSize = 256; -static const size_t kTraceArgBufferLength = 32; +#endif namespace webrtc { namespace { +#if !defined(RTC_USE_PERFETTO) GetCategoryEnabledPtr g_get_category_enabled_ptr = nullptr; AddTraceEventPtr g_add_trace_event_ptr = nullptr; +#endif } // namespace +#if defined(RTC_USE_PERFETTO) +void RegisterPerfettoTrackEvents() { + if (perfetto::Tracing::IsInitialized()) { + webrtc::TrackEvent::Register(); + } +} +#else + void SetupEventTracer(GetCategoryEnabledPtr get_category_enabled_ptr, AddTraceEventPtr add_trace_event_ptr) { g_get_category_enabled_ptr = get_category_enabled_ptr; @@ -73,9 +87,28 @@ void EventTracer::AddTraceEvent(char phase, arg_names, arg_types, arg_values, flags); } } +#endif } // namespace webrtc +#if defined(RTC_USE_PERFETTO) +// TODO(bugs.webrtc.org/15917): Implement for perfetto. +namespace rtc::tracing { +void SetupInternalTracer(bool enable_all_categories) {} +bool StartInternalCapture(absl::string_view filename) { + return false; +} +void StartInternalCaptureToFile(FILE* file) {} +void StopInternalCapture() {} +void ShutdownInternalTracer() {} + +} // namespace rtc::tracing +#else + +// This is a guesstimate that should be enough in most cases. +static const size_t kEventLoggerArgsStrBufferInitialSize = 256; +static const size_t kTraceArgBufferLength = 32; + namespace rtc { namespace tracing { namespace { @@ -412,3 +445,5 @@ void ShutdownInternalTracer() { } // namespace tracing } // namespace rtc + +#endif // defined(RTC_USE_PERFETTO) diff --git a/rtc_base/event_tracer.h b/rtc_base/event_tracer.h index dc2eaed669..7f8d3e6ca6 100644 --- a/rtc_base/event_tracer.h +++ b/rtc_base/event_tracer.h @@ -8,6 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ +#ifndef RTC_BASE_EVENT_TRACER_H_ +#define RTC_BASE_EVENT_TRACER_H_ + // This file defines the interface for event tracing in WebRTC. // // Event log handlers are set through SetupEventTracer(). User of this API will @@ -23,9 +26,6 @@ // // Parameters for the above two functions are described in trace_event.h. -#ifndef RTC_BASE_EVENT_TRACER_H_ -#define RTC_BASE_EVENT_TRACER_H_ - #include #include "absl/strings/string_view.h" @@ -33,6 +33,9 @@ namespace webrtc { +#if defined(RTC_USE_PERFETTO) +void RegisterPerfettoTrackEvents(); +#else typedef const unsigned char* (*GetCategoryEnabledPtr)(const char* name); typedef void (*AddTraceEventPtr)(char phase, const unsigned char* category_enabled, @@ -67,19 +70,19 @@ class EventTracer { const unsigned long long* arg_values, unsigned char flags); }; +#endif } // namespace webrtc -namespace rtc { -namespace tracing { +namespace rtc::tracing { // Set up internal event tracer. +// TODO(webrtc:15917): Implement for perfetto. RTC_EXPORT void SetupInternalTracer(bool enable_all_categories = true); RTC_EXPORT bool StartInternalCapture(absl::string_view filename); RTC_EXPORT void StartInternalCaptureToFile(FILE* file); RTC_EXPORT void StopInternalCapture(); // Make sure we run this, this will tear down the internal tracing. RTC_EXPORT void ShutdownInternalTracer(); -} // namespace tracing -} // namespace rtc +} // namespace rtc::tracing #endif // RTC_BASE_EVENT_TRACER_H_ diff --git a/rtc_base/event_tracer_unittest.cc b/rtc_base/event_tracer_unittest.cc index d0783c3f2d..eae19a2588 100644 --- a/rtc_base/event_tracer_unittest.cc +++ b/rtc_base/event_tracer_unittest.cc @@ -50,16 +50,16 @@ class TestStatistics { namespace webrtc { TEST(EventTracerTest, EventTracerDisabled) { - { TRACE_EVENT0("test", "EventTracerDisabled"); } + { TRACE_EVENT0("webrtc-test", "EventTracerDisabled"); } EXPECT_FALSE(TestStatistics::Get()->Count()); TestStatistics::Get()->Reset(); } -#if RTC_TRACE_EVENTS_ENABLED +#if RTC_TRACE_EVENTS_ENABLED && !defined(RTC_USE_PERFETTO) TEST(EventTracerTest, ScopedTraceEvent) { SetupEventTracer( [](const char* /*name*/) { - return reinterpret_cast("test"); + return reinterpret_cast("webrtc-test"); }, [](char /*phase*/, const unsigned char* /*category_enabled*/, const char* /*name*/, unsigned long long /*id*/, int /*num_args*/, diff --git a/rtc_base/trace_categories.cc b/rtc_base/trace_categories.cc new file mode 100644 index 0000000000..2fe63e282d --- /dev/null +++ b/rtc_base/trace_categories.cc @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_base/trace_categories.h" + +PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS(webrtc, RTC_EXPORT); diff --git a/rtc_base/trace_categories.h b/rtc_base/trace_categories.h new file mode 100644 index 0000000000..c22ce911d3 --- /dev/null +++ b/rtc_base/trace_categories.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_BASE_TRACE_CATEGORIES_H_ +#define RTC_BASE_TRACE_CATEGORIES_H_ + +#define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 1 + +#include "perfetto/tracing/track_event.h" // IWYU pragma: export +#include "perfetto/tracing/track_event_category_registry.h" +#include "perfetto/tracing/track_event_legacy.h" // IWYU pragma: export +#include "rtc_base/system/rtc_export.h" + +PERFETTO_DEFINE_TEST_CATEGORY_PREFIXES("webrtc-test"); + +PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS( + webrtc, + RTC_EXPORT, + perfetto::Category("webrtc"), + perfetto::Category("webrtc_stats"), + perfetto::Category(TRACE_DISABLED_BY_DEFAULT("webrtc")), + perfetto::Category(TRACE_DISABLED_BY_DEFAULT("webrtc_stats"))); + +PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(webrtc); + +#endif // RTC_BASE_TRACE_CATEGORIES_H_ diff --git a/rtc_base/trace_event.h b/rtc_base/trace_event.h index 8499983aa0..ab628022ef 100644 --- a/rtc_base/trace_event.h +++ b/rtc_base/trace_event.h @@ -1,25 +1,40 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file under third_party_mods/chromium or at: -// http://src.chromium.org/svn/trunk/src/LICENSE +/* + * Copyright (c) 2024 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ #ifndef RTC_BASE_TRACE_EVENT_H_ #define RTC_BASE_TRACE_EVENT_H_ -#include - -#include "rtc_base/event_tracer.h" - -#if defined(TRACE_EVENT0) -#error "Another copy of trace_event.h has already been included." -#endif - #if defined(RTC_DISABLE_TRACE_EVENTS) #define RTC_TRACE_EVENTS_ENABLED 0 #else #define RTC_TRACE_EVENTS_ENABLED 1 #endif +#if defined(RTC_USE_PERFETTO) + +#include "rtc_base/trace_categories.h" // IWYU pragma: export + +// TODO(webrtc:15917): Replace these events. +#define TRACE_EVENT_ASYNC_STEP0(category_group, name, id, step) \ + TRACE_EVENT_ASYNC_STEP_INTO0(category_group, name, id, step) +#define TRACE_EVENT_ASYNC_STEP1(category_group, name, id, step, arg1_name, \ + arg1_val) \ + TRACE_EVENT_ASYNC_STEP_INTO1(category_group, name, id, step, arg1_name, \ + arg1_val) + +#else + +#include + +#include "rtc_base/event_tracer.h" + // Type values for identifying types in the TraceValue union. #define TRACE_VALUE_TYPE_BOOL (static_cast(1)) #define TRACE_VALUE_TYPE_UINT (static_cast(2)) @@ -29,6 +44,10 @@ #define TRACE_VALUE_TYPE_STRING (static_cast(6)) #define TRACE_VALUE_TYPE_COPY_STRING (static_cast(7)) +#if defined(TRACE_EVENT0) +#error "Another copy of trace_event.h has already been included." +#endif + #if RTC_TRACE_EVENTS_ENABLED // Extracted from Chromium's src/base/debug/trace_event.h. @@ -705,6 +724,7 @@ class TraceEndOnScopeClose { } // namespace trace_event_internal } // namespace webrtc + #else //////////////////////////////////////////////////////////////////////////////// @@ -779,5 +799,6 @@ class TraceEndOnScopeClose { #define TRACE_EVENT_API_ADD_TRACE_EVENT RTC_NOOP() #endif // RTC_TRACE_EVENTS_ENABLED +#endif // RTC_USE_PERFETTO #endif // RTC_BASE_TRACE_EVENT_H_ diff --git a/test/BUILD.gn b/test/BUILD.gn index d1554d750d..783e94acdd 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -627,6 +627,9 @@ if (rtc_include_tests) { if (is_win) { deps += [ "../rtc_base:win32_socket_init" ] } + if (rtc_use_perfetto) { + deps += [ "//third_party/perfetto/src/tracing:client_api" ] + } } rtc_library("test_main") { diff --git a/test/DEPS b/test/DEPS index a9e9a7b5f1..f9f47e16a7 100644 --- a/test/DEPS +++ b/test/DEPS @@ -49,6 +49,10 @@ specific_include_rules = { ".*stun_validator_fuzzer\.cc": [ "+p2p/base/stun.h", ], + ".*test_main_lib\.cc": [ + "+perfetto/tracing", + "+protos/perfetto/config", + ], ".*test_main\.cc": [ "+absl/debugging/failure_signal_handler.h", "+absl/debugging/symbolize.h", diff --git a/test/test_main_lib.cc b/test/test_main_lib.cc index 4c80315ac5..76b5a16851 100644 --- a/test/test_main_lib.cc +++ b/test/test_main_lib.cc @@ -10,7 +10,10 @@ #include "test/test_main_lib.h" +#include +#include #include +#include #include #include #include @@ -18,6 +21,7 @@ #include "absl/flags/flag.h" #include "absl/memory/memory.h" #include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/test/metrics/chrome_perf_dashboard_metrics_exporter.h" #include "api/test/metrics/global_metrics_logger_and_exporter.h" @@ -39,6 +43,13 @@ #include "test/testsupport/perf_test.h" #include "test/testsupport/resources_dir_flag.h" +#if defined(RTC_USE_PERFETTO) +#include "perfetto/tracing/backend_type.h" +#include "perfetto/tracing/tracing.h" +#include "protos/perfetto/config/trace_config.gen.h" +#include "rtc_base/event_tracer.h" +#endif + #if defined(WEBRTC_WIN) #include "rtc_base/win32_socket_init.h" #endif @@ -92,8 +103,7 @@ ABSL_FLAG(bool, verbose, false, "verbose logs to stderr"); ABSL_FLAG(std::string, trace_event, "", - "Path to collect trace events (json file) for chrome://tracing. " - "If not set, events aren't captured."); + "Path to collect trace events. If not set, events aren't captured."); ABSL_FLAG(std::string, test_launcher_shard_index, @@ -167,8 +177,7 @@ class TestMainImpl : public TestMain { std::string trace_event_path = absl::GetFlag(FLAGS_trace_event); const bool capture_events = !trace_event_path.empty(); if (capture_events) { - rtc::tracing::SetupInternalTracer(); - rtc::tracing::StartInternalCapture(trace_event_path); + StartTracingCapture(trace_event_path); } absl::optional> metrics_to_plot = @@ -236,7 +245,7 @@ class TestMainImpl : public TestMain { #endif if (capture_events) { - rtc::tracing::StopInternalCapture(); + StopTracingCapture(); } #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ @@ -256,6 +265,59 @@ class TestMainImpl : public TestMain { #if defined(WEBRTC_WIN) std::unique_ptr winsock_init_; #endif +#if defined(RTC_USE_PERFETTO) + std::unique_ptr tracing_session_; + FILE* tracing_output_file_ = nullptr; +#endif + + void StartTracingCapture(absl::string_view trace_output_file) { +#if defined(RTC_USE_PERFETTO) + tracing_output_file_ = std::fopen(trace_output_file.data(), "w"); + if (!tracing_output_file_) { + RTC_LOG(LS_ERROR) << "Failed to open trace file \"" << trace_output_file + << "\". Tracing will be disabled."; + } + perfetto::TracingInitArgs args; + args.backends |= perfetto::kInProcessBackend; + perfetto::Tracing::Initialize(args); + webrtc::RegisterPerfettoTrackEvents(); + + perfetto::TraceConfig cfg; + cfg.add_buffers()->set_size_kb(1024); // Record up to 1 MiB. + tracing_session_ = perfetto::Tracing::NewTrace(); + tracing_session_->Setup(cfg); + RTC_LOG(LS_INFO) + << "Starting tracing with Perfetto and outputting to file \"" + << trace_output_file << "\""; + tracing_session_->StartBlocking(); +#else + rtc::tracing::SetupInternalTracer(); + rtc::tracing::StartInternalCapture(trace_output_file); +#endif + } + + void StopTracingCapture() { +#if defined(RTC_USE_PERFETTO) + if (tracing_output_file_) { + RTC_CHECK(tracing_session_); + tracing_session_->StopBlocking(); + std::vector tracing_data = tracing_session_->ReadTraceBlocking(); + size_t count = std::fwrite(tracing_data.data(), sizeof tracing_data[0], + tracing_data.size(), tracing_output_file_); + if (count != tracing_data.size()) { + RTC_LOG(LS_ERROR) << "Expected to write " << tracing_data.size() + << " bytes but only " << count << " bytes written"; + } + std::fclose(tracing_output_file_); + tracing_output_file_ = nullptr; + } else { + RTC_LOG(LS_INFO) << "no file"; + } + +#else + rtc::tracing::StopInternalCapture(); +#endif + } }; } // namespace diff --git a/tools_webrtc/mb/mb_config.pyl b/tools_webrtc/mb/mb_config.pyl index 8862950e0e..a64b9e0537 100644 --- a/tools_webrtc/mb/mb_config.pyl +++ b/tools_webrtc/mb/mb_config.pyl @@ -147,6 +147,7 @@ 'dummy_audio_file_devices_no_protobuf_android_arm', 'rtti_no_sctp': 'rtti_no_sctp_android_arm', 'disable_trace_events': 'disable_trace_events_android_arm', + 'perfetto': 'perfetto_android_arm', }, 'android_arm_rel': 'android_release_bot_arm', 'android_compile_arm64_dbg': 'android_debug_static_bot_arm64', @@ -185,6 +186,7 @@ 'dummy_audio_file_devices_no_protobuf_x64', 'rtti_no_sctp': 'rtti_no_sctp_x64', 'disable_trace_events': 'disable_trace_events_x64', + 'perfetto': 'perfetto_x64', }, 'linux_msan': 'msan_clang_release_bot_x64', 'linux_rel': 'release_bot_x64', @@ -221,6 +223,7 @@ 'dummy_audio_file_devices_no_protobuf_x86', 'rtti_no_sctp': 'rtti_no_sctp_no_unicode_win_x86', 'disable_trace_events': 'disable_trace_events_x86', + 'perfetto': 'perfetto_x86', }, } }, @@ -353,6 +356,9 @@ 'msan_clang_release_bot_x64': ['msan', 'clang', 'openh264', 'pure_release_bot', 'x64', 'h265'], 'no_h264_debug_bot_x86': ['debug_bot', 'x86'], + 'perfetto_android_arm': [ 'android', 'arm', 'perfetto', 'release_bot'], + 'perfetto_x64': [ 'x64', 'perfetto', 'release_bot'], + 'perfetto_x86': [ 'x86', 'perfetto', 'release_bot'], 'pure_release_bot_x64': ['openh264', 'pure_release_bot', 'x64', 'h265'], 'pure_release_bot_x86': ['openh264', 'pure_release_bot', 'x86', 'h265'], 'release_bot_arm': ['openh264', 'release_bot', 'arm', 'h265'], @@ -513,6 +519,9 @@ 'gn_args': 'coverage_instrumentation_input_file="//.code-coverage/files_to_instrument.txt"' }, + 'perfetto': { + 'gn_args': 'rtc_use_perfetto=true', + }, # The 'pure_release_bot' configuration is for release bots that are doing a # 100% release build without DCHECKs while 'release_bot' is a partial # release configs since `dcheck_always_on` is set to true. diff --git a/webrtc.gni b/webrtc.gni index 969cdbd2be..de35c2171d 100644 --- a/webrtc.gni +++ b/webrtc.gni @@ -268,6 +268,9 @@ declare_args() { # WebRTC does not declare its public dependencies. See webrtc:8603. Instead # WebRTC is using a global common dependencies. rtc_common_public_deps = [] # no-presubmit-check TODO(webrtc:8603) + + # When true, include the Perfetto library. + rtc_use_perfetto = false } if (!build_with_mozilla) { @@ -385,6 +388,9 @@ if (is_mac || is_ios) { rtc_common_configs += [ "//build/config/compiler:enable_arc" ] } } +if (rtc_use_perfetto) { + rtc_common_configs += [ "//third_party/perfetto/gn:public_config" ] +} # Global public configuration that should be applied to all WebRTC targets. You # normally shouldn't need to include this in your target as it's automatically