Add layer tracing's MODE_GENERATED_BUGREPORT_ONLY
The generated layers trace can be quite large (100-400 MB), which is way above
the perfetto's field upload budget.
On the field (AOT) we want the layers trace to be generated only when a bugreport
is taken and not when a perfetto's field upload happens. We achieve it as follows:
- In the AOT configuration, enable the 'android.surfaceflinger_layers' data source
with MODE_GENERATED_BUGREPORT_ONLY.
- When LayerTracing receives perfetto's OnFlush event and MODE_GENERATED_BUGREPORT_ONLY is enabled,
generate the layers trace only if the OnFlush event is due to a bugreport being taken:
args.flush_flags.reason() == perfetto::FlushFlags::Reason::kTraceClone &&
args.flush_flags.clone_target() == perfetto::FlushFlags::CloneTarget::kBugreport
In a test environment instead, we can use MODE_GENERATED to test the layers trace generation
without having to take a bugreport.
Bug: b/293429094
Test: 1. Manually start the perfetto's android.surfaceflinger_layers data source
with MODE_GENERATED_BUGREPORT_ONLY setting a high bugreport_score (e.g. 50000)
2. Take a bugreport (adb bugreport)
3. Verify that FS/data/misc/perfetto-traces/bugreport/systrace.pftrace (in the bugreport)
contains the generated layers trace. E.g. inspect bugreport with go/winscope.
Change-Id: I5b3ce59cc762fd5a22170e677e48be987380c94e
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index 403e105..41bcdf0 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -67,9 +67,27 @@
break;
}
case Mode::MODE_GENERATED: {
+ // This tracing mode processes the buffer of transactions (owned by TransactionTracing),
+ // generates layers snapshots and writes them to perfetto. This happens every time an
+ // OnFlush event is received.
ALOGD("Started generated tracing (waiting for OnFlush event to generated layers)");
break;
}
+ case Mode::MODE_GENERATED_BUGREPORT_ONLY: {
+ // Same as MODE_GENERATED, but only when the received OnFlush event is due to a
+ // bugreport being taken. This mode exists because the generated layers trace is very
+ // large (hundreds of MB), hence we want to include it only in bugreports and not in
+ // field uploads.
+ //
+ // Note that perfetto communicates only whether the OnFlush event is due to a bugreport
+ // or not, hence we need an additional "bugreport only" tracing mode.
+ // If perfetto had communicated when the OnFlush is due to a field upload, then we could
+ // have had a single "generated" tracing mode that would have been a noop in case of
+ // field uploads.
+ ALOGD("Started 'generated bugreport only' tracing"
+ " (waiting for bugreport's OnFlush event to generate layers)");
+ break;
+ }
case Mode::MODE_DUMP: {
auto snapshot = mTakeLayersSnapshotProto(flags);
addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_DUMP);
@@ -82,10 +100,18 @@
}
}
-void LayerTracing::onFlush(Mode mode, uint32_t flags) {
+void LayerTracing::onFlush(Mode mode, uint32_t flags, bool isBugreport) {
// In "generated" mode process the buffer of transactions (owned by TransactionTracing),
- // generate a sequence of layers snapshots and write them to perfetto.
- if (mode != Mode::MODE_GENERATED) {
+ // generate layers snapshots and write them to perfetto.
+ if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
+ ALOGD("Skipping layers trace generation (not a 'generated' tracing session)");
+ return;
+ }
+
+ // In "generated bugreport only" mode skip the layers snapshot generation
+ // if the perfetto's OnFlush event is not due to a bugreport being taken.
+ if (mode == Mode::MODE_GENERATED_BUGREPORT_ONLY && !isBugreport) {
+ ALOGD("Skipping layers trace generation (not a bugreport OnFlush event)");
return;
}
@@ -147,14 +173,23 @@
}
void LayerTracing::writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot,
- Mode mode) {
+ Mode srcMode) {
const auto snapshotBytes = snapshot.SerializeAsString();
LayerDataSource::Trace([&](LayerDataSource::TraceContext context) {
- if (mode != context.GetCustomTlsState()->mMode) {
+ auto dstMode = context.GetCustomTlsState()->mMode;
+ if (srcMode == Mode::MODE_GENERATED) {
+ // Layers snapshots produced by LayerTraceGenerator have srcMode == MODE_GENERATED
+ // and should be written to tracing sessions with MODE_GENERATED
+ // or MODE_GENERATED_BUGREPORT_ONLY.
+ if (dstMode != Mode::MODE_GENERATED && dstMode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
+ return;
+ }
+ } else if (srcMode != dstMode) {
return;
}
- if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(mode, snapshot.vsync_id())) {
+
+ if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(srcMode, snapshot.vsync_id())) {
return;
}
{
@@ -176,7 +211,7 @@
// In some situations (e.g. two bugreports taken shortly one after the other) the generated
// sequence of layers snapshots might overlap. Here we check the snapshot's vsyncid to make
// sure that in generated tracing mode a given snapshot is written only once to perfetto.
- if (mode != Mode::MODE_GENERATED) {
+ if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
return true;
}