Skip to content

Commit bfcd9d9

Browse files
baylesjactions-user
authored andcommitted
[Tracing] Add Perfetto support to Open Screen
This patch adds Perfetto support to Open Screen, and the standalone cast sender and receiver binaries. This should help make diagnosing issues with Cast and other components easier. With this patch, you can now run Open Screen binaries, such as the Cast standalone sender and receiver, with Perfetto enabled by passing the `-P` or `--perfetto` flag. A pftrace file is automatically generated upon application exit that can be loaded in the Perfetto UI. Bug: 479649464 Change-Id: I45e44017a88cf5b8ef95fe894a417b01d34c4d85 Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/7530400 Reviewed-by: Muyao Xu <muyaoxu@google.com> Commit-Queue: Jordan Bayles <jophba@chromium.org>
1 parent 67cac11 commit bfcd9d9

20 files changed

Lines changed: 568 additions & 23 deletions

File tree

.github/workflows/main.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Exact OpenScreen Mirror with .github Protection
2+
3+
on:
4+
workflow_dispatch: # Manuel olarak tetiklenebilir
5+
schedule:
6+
- cron: '0 0 */3 * *' # Her 3 günde bir otomatik olarak çalışır
7+
8+
jobs:
9+
mirror:
10+
runs-on: ubuntu-latest # İş akışı Ubuntu üzerinde çalışır
11+
steps:
12+
# Adım 1: Mevcut depoyu tam tarihçe ile al
13+
- name: Checkout Full History
14+
uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0 # Tüm commit geçmişini al
17+
18+
# Adım 2: OpenScreen verilerini mevcut depoya entegre et
19+
- name: Integrate OpenScreen
20+
run: |
21+
# 'actions' branch'ine geç
22+
git checkout actions
23+
24+
# OpenScreen'i uzak depo olarak ekle
25+
git remote add openscreen https://chromium.googlesource.com/openscreen
26+
27+
# OpenScreen'den tüm branch'leri ve tag'leri al
28+
git fetch openscreen --tags
29+
30+
# OpenScreen'deki tüm branch'leri yerel olarak oluştur (main hariç)
31+
git branch -r | grep 'openscreen/' | grep -v 'HEAD' | while read remote; do
32+
branch_name=${remote#openscreen/}
33+
git branch -f "$branch_name" "$remote"
34+
done
35+
36+
# Adım 3: Main branch'i koru ve .github dosyalarını güncelle
37+
- name: Protect Main Branch
38+
run: |
39+
# Main branch'e geç
40+
git checkout main
41+
42+
# Git kullanıcı bilgilerini ayarla (commit için)
43+
git config user.name "GitHub Actions"
44+
git config user.email "actions@github.com"
45+
46+
# 'actions' branch'inden .github klasörünü al ve main branch'ine merge et
47+
git checkout actions -- .github
48+
git add .github
49+
git commit --amend --no-edit # Commit'i güncelle (fast-forward olmadan)
50+
51+
# Adım 4: Tüm branch'leri ve tag'leri force push et
52+
- name: Force Push Mirrored Branches
53+
env:
54+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub token'ı kullan
55+
run: |
56+
# Tüm branch'leri ve tag'leri force push et
57+
git push origin --all --force
58+
git push origin --tags --force

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,7 @@
7272
path = third_party/googleurl/src
7373
url = https://quiche.googlesource.com/googleurl
7474
gclient-condition = not build_with_chromium
75+
[submodule "third_party/perfetto/src"]
76+
path = third_party/perfetto/src
77+
url = https://chromium.googlesource.com/external/github.com/google/perfetto
78+
gclient-condition = not build_with_chromium

DEPS

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,13 @@ deps = {
413413
'url': Var('quiche_git') + '/googleurl.git' +
414414
'@' + '94ff147fe0b96b4cca5d6d316b9af6210c0b8051', #2025-11-11
415415
'condition': 'not build_with_chromium',
416-
}
416+
},
417+
418+
'third_party/perfetto/src': {
419+
'url': Var('chromium_git') + '/external/github.com/google/perfetto.git' +
420+
'@' + '1d9994a93c6ada2fb261dc72984fa07683a6c86e',
421+
'condition': 'not build_with_chromium',
422+
},
417423
}
418424

419425
hooks = [

build_overrides/build.gni

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ if (host_os == "mac" || is_apple) {
3939
assert(current_os != "ios" || use_system_xcode)
4040
assert(host_os == "mac" || !use_system_xcode)
4141
}
42+
43+
import("//build_overrides/perfetto.gni")

build_overrides/perfetto.gni

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright 2026 The Chromium Authors
2+
# Use of this source code is governed by a BSD-style license that can be
3+
# found in the LICENSE file.
4+
5+
# This file is imported by Perfetto's BUILD.gn files.
6+
7+
# The location of the Perfetto checkout.
8+
perfetto_root = "//third_party/perfetto/src"
9+
perfetto_root_path = "//third_party/perfetto/src/"
10+
11+
# Prevent Perfetto from trying to use its own standalone build setup.
12+
perfetto_build_with_embedder = true
13+
14+
# We don't want to build the trace processor, just the tracing SDK.
15+
enable_perfetto_trace_processor = false
16+
17+
# We don't need the IPC layer.
18+
enable_perfetto_ipc = false
19+
20+
# We want the client library.
21+
enable_perfetto_platform_services = false
22+
23+
# Other flags to minimize build size/deps.
24+
enable_perfetto_heapprofd = false
25+
enable_perfetto_traced_probes = false
26+
enable_perfetto_tools = false
27+
enable_perfetto_unittests = false
28+
enable_perfetto_benchmarks = false
29+
enable_perfetto_fuzzers = false
30+
enable_perfetto_integration_tests = false
31+
32+
# Map dependencies.
33+
perfetto_protobuf_target = "//third_party/protobuf:protobuf_lite"
34+
perfetto_protobuf_config = "//third_party/protobuf:protobuf_config"

cast/standalone_receiver/main.cc

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include "util/trace_logging.h"
3030
#include "util/uuid.h"
3131

32+
#if defined(USE_PERFETTO)
33+
#include "platform/impl/perfetto_trace_logging_platform.h"
34+
#endif
35+
3236
namespace openscreen::cast {
3337
namespace {
3438

@@ -69,12 +73,13 @@ usage: {} <options> <interface>
6973
-q, --disable-dscp: Disable DSCP packet prioritization, used for QoS over
7074
the UDP socket connection.
7175
72-
-t, --tracing: Enable performance tracing logging.
76+
-t, --tracing: Enable text based performance trace logging.
7377
7478
-v, --verbose: Enable verbose logging.
7579
7680
-x, --disable-discovery: Disable discovery.
7781
82+
-P, --perfetto: Enable Perfetto based performance trace logging.
7883
)";
7984

8085
std::cerr << StringFormat(kTemplate, argv0);
@@ -126,7 +131,7 @@ struct Arguments {
126131
bool should_generate_credentials = false;
127132
std::string model_name = "cast_standalone_receiver";
128133
std::string private_key_path;
129-
std::unique_ptr<TextTraceLoggingPlatform> trace_logger;
134+
std::unique_ptr<TraceLoggingPlatform> trace_logger;
130135
bool is_verbose = false;
131136
};
132137

@@ -146,11 +151,14 @@ std::optional<Arguments> ParseArgs(int argc, char* argv[]) {
146151
{"private-key", required_argument, nullptr, 'p'},
147152
{"tracing", no_argument, nullptr, 't'},
148153
{"verbose", no_argument, nullptr, 'v'},
154+
#if defined(USE_PERFETTO)
155+
{"perfetto", no_argument, nullptr, 'P'},
156+
#endif
149157
{nullptr, 0, nullptr, 0}};
150158

151159
Arguments args;
152160
int ch = -1;
153-
while ((ch = getopt_long(argc, argv, "d:f:ghm:p:qtvx", kArgumentOptions,
161+
while ((ch = getopt_long(argc, argv, "d:f:ghm:p:qtvxP", kArgumentOptions,
154162
nullptr)) != -1) {
155163
switch (ch) {
156164
case 'd':
@@ -182,6 +190,11 @@ std::optional<Arguments> ParseArgs(int argc, char* argv[]) {
182190
case 'x':
183191
args.enable_discovery = false;
184192
break;
193+
#if defined(USE_PERFETTO)
194+
case 'P':
195+
args.trace_logger = std::make_unique<PerfettoTraceLoggingPlatform>();
196+
break;
197+
#endif
185198
}
186199
}
187200

cast/standalone_sender/main.cc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
#include "util/string_util.h"
3434
#include "util/stringprintf.h"
3535

36+
#if defined(USE_PERFETTO)
37+
#include "platform/impl/perfetto_trace_logging_platform.h"
38+
#endif
39+
3640
namespace openscreen::cast {
3741
namespace {
3842

@@ -82,10 +86,12 @@ usage: {} <options> addr[:port] media_file
8286
8387
-r, --remoting: Enable remoting content instead of mirroring.
8488
85-
-t, --tracing: Enable performance tracing logging.
89+
-t, --tracing: Enable text based performance trace logging.
8690
8791
-v, --verbose: Enable verbose logging.
8892
93+
-P, --perfetto: Enable perfetto based performance trace logging.
94+
8995
)";
9096

9197
std::cerr << StringFormat(kTemplate, argv0, argv0, kDefaultCastPort,
@@ -139,7 +145,7 @@ struct Arguments {
139145
bool use_remoting = false;
140146
bool is_verbose = false;
141147
VideoCodec codec = VideoCodec::kVp8;
142-
std::unique_ptr<TextTraceLoggingPlatform> trace_logger;
148+
std::unique_ptr<TraceLoggingPlatform> trace_logger;
143149
bool enable_dscp = true;
144150
};
145151

@@ -158,12 +164,15 @@ std::optional<Arguments> ParseArgs(int argc, char* argv[]) {
158164
{"disable-dscp", no_argument, nullptr, 'q'},
159165
{"remoting", no_argument, nullptr, 'r'},
160166
{"tracing", no_argument, nullptr, 't'},
167+
#if defined(USE_PERFETTO)
168+
{"perfetto", no_argument, nullptr, 'P'},
169+
#endif
161170
{"verbose", no_argument, nullptr, 'v'},
162171
{nullptr, 0, nullptr, 0}};
163172

164173
Arguments args;
165174
int ch = -1;
166-
while ((ch = getopt_long(argc, argv, "ac:d:hm:nqrtv", kArgumentOptions,
175+
while ((ch = getopt_long(argc, argv, "ac:d:hm:nqrtvP", kArgumentOptions,
167176
nullptr)) != -1) {
168177
switch (ch) {
169178
case 'a':
@@ -206,6 +215,11 @@ std::optional<Arguments> ParseArgs(int argc, char* argv[]) {
206215
return std::nullopt;
207216
}
208217
break;
218+
#if defined(USE_PERFETTO)
219+
case 'P':
220+
args.trace_logger = std::make_unique<PerfettoTraceLoggingPlatform>();
221+
break;
222+
#endif
209223
}
210224
}
211225

docs/trace_logging.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ The code for Trace Logging is divided up as follows:
334334
*trace_logging.h*, and connecting it to the platform API.
335335
* *platform/api/trace_logging_platform.h*: the platform implementation that is
336336
used as the trace logging destination while tracing is active.
337+
* *platform/impl/text_trace_logging_platform.h*: a basic implementation that
338+
logs trace events to the console.
339+
* *platform/impl/perfetto_trace_logging_platform.h*: an implementation that
340+
logs trace events to a Perfetto trace file.
337341

338342
This information is intended to be only explanatory for embedders - only the one
339343
file mentioned above in Imports must be imported.
@@ -353,5 +357,36 @@ For an embedder to create a custom TraceLogging implementation:
353357
These activate/deactivate tracing by providing the TraceLoggingPlatform
354358
instance and later clearing references to it.
355359

356-
**The default implementation of this layer can be seen in
357-
platform/impl/trace_logging_platform.cc.**
360+
**Example implementations of this layer can be seen in
361+
platform/impl/text_trace_logging_platform.cc (console logging) and
362+
platform/impl/perfetto_trace_logging_platform.cc (Perfetto tracing).**
363+
364+
## Perfetto Tracing Support
365+
366+
Open Screen supports [Perfetto](https://perfetto.dev/) for trace logging in
367+
standalone builds. This allows for generating trace files that can be viewed in
368+
the Perfetto UI.
369+
370+
### Enabling Perfetto
371+
372+
To enable Perfetto support, ensure the `use_perfetto` GN argument is set to
373+
`true`. This is the default for standalone builds (i.e., when
374+
`build_with_chromium` is `false`).
375+
376+
```bash
377+
gn gen out/Default --args="use_perfetto=true"
378+
```
379+
380+
### Using Perfetto in Standalone Apps
381+
382+
When Perfetto support is compiled in, you can enable it in the standalone sender
383+
and receiver applications using the `--perfetto` or `-P` flag.
384+
385+
```bash
386+
./out/Default/cast_sender -P ...
387+
./out/Default/cast_receiver -P ...
388+
```
389+
390+
When enabled, a trace file (e.g., `openscreen_<pid>.pftrace`) will be generated
391+
upon termination of the application. This file can be opened at
392+
[ui.perfetto.dev](https://ui.perfetto.dev/).

platform/BUILD.gn

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ openscreen_source_set("api") {
8181
]
8282
}
8383

84+
declare_args() {
85+
use_perfetto = !build_with_chromium
86+
}
87+
88+
config("standalone_config") {
89+
if (use_perfetto) {
90+
defines = [ "USE_PERFETTO" ]
91+
}
92+
}
93+
8494
# The following target is only activated in standalone builds (see :platform).
8595
# Disable standalone implementation for IOS. It is not supported.
8696
if (!is_ios) {
@@ -119,7 +129,10 @@ if (!is_ios) {
119129
"impl/tls_write_buffer.h",
120130
]
121131

122-
public_configs = [ "../util:trace_logging_config" ]
132+
public_configs = [
133+
"../util:trace_logging_config",
134+
":standalone_config",
135+
]
123136

124137
if (is_linux || is_chromeos || is_android) {
125138
sources += [ "impl/network_interface_linux.cc" ]
@@ -167,6 +180,13 @@ if (!is_ios) {
167180
"../third_party/boringssl",
168181
"../util",
169182
]
183+
184+
if (use_perfetto) {
185+
public += [ "impl/perfetto_trace_logging_platform.h" ]
186+
sources += [ "impl/perfetto_trace_logging_platform.cc" ]
187+
deps += [ "../third_party/perfetto" ]
188+
}
189+
170190
friend = [ ":unittests" ]
171191
}
172192
}
@@ -279,5 +299,9 @@ openscreen_source_set("unittests") {
279299
"impl/udp_socket_reader_posix_unittest.cc",
280300
]
281301
}
302+
303+
if (use_perfetto) {
304+
sources += [ "impl/perfetto_trace_logging_platform_unittest.cc" ]
305+
}
282306
}
283307
}

platform/base/trace_logging_types.cc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,25 @@ bool operator!=(const TraceIdHierarchy& lhs, const TraceIdHierarchy& rhs) {
3434
const char* ToString(TraceCategory category) {
3535
switch (category) {
3636
case TraceCategory::kAny:
37-
return "Any";
37+
return "any";
3838
case TraceCategory::kMdns:
39-
return "Mdns";
39+
return "mdns";
4040
case TraceCategory::kQuic:
41-
return "Quic";
41+
return "quic";
4242
case TraceCategory::kSsl:
43-
return "SSL";
43+
return "ssl";
4444
case TraceCategory::kPresentation:
45-
return "Presentation";
45+
return "presentation";
4646
case TraceCategory::kStandaloneReceiver:
47-
return "StandaloneReceiver";
47+
return "standalone_receiver";
4848
case TraceCategory::kDiscovery:
49-
return "Discovery";
49+
return "discovery";
5050
case TraceCategory::kStandaloneSender:
51-
return "StandaloneSender";
51+
return "standalone_sender";
5252
case TraceCategory::kReceiver:
53-
return "Receiver";
53+
return "receiver";
5454
case TraceCategory::kSender:
55-
return "Sender";
55+
return "sender";
5656
}
5757

5858
// OSP_NOTREACHED is not available in platform/base.

0 commit comments

Comments
 (0)