Revert^2 Integrate layer tracing with perfetto
Define the perfetto custom data source LayerDataSource.
LayerDataSource is registered with perfetto. The data source
is used to listen to perfetto events (setup, start, stop, flush)
and to write trace packets to perfetto.
The user can configure/start/stop tracing via /system/bin/perfetto.
Tracing can operate in the following modes.
ACTIVE mode:
A layers snapshot is taken and written to perfetto for each vsyncid commit.
GENERATED mode:
Listens to the perfetto 'flush' event (e.g. when a bugreport is taken).
When a 'flush' event is received, the ring buffer of transactions (hold by TransactionTracing)
is processed by LayerTraceGenerator, a sequence of layers snapshots is generated
and written to perfetto.
DUMP mode:
When the 'start' event is received a single layers snapshot is taken
and written to perfetto.
Bug: b/284424784
Test: atest libsurfaceflinger_unittest && atest transactiontrace_testsuite
Change-Id: Ic1b10a040ec4533f0b56a4c8087c5a2898e3e34d
diff --git a/services/surfaceflinger/Tracing/tools/Android.bp b/services/surfaceflinger/Tracing/tools/Android.bp
index b6435a8..2ff09c3 100644
--- a/services/surfaceflinger/Tracing/tools/Android.bp
+++ b/services/surfaceflinger/Tracing/tools/Android.bp
@@ -31,7 +31,6 @@
srcs: [
":libsurfaceflinger_sources",
":libsurfaceflinger_mock_sources",
- ":layertracegenerator_sources",
"main.cpp",
],
static_libs: [
@@ -41,15 +40,3 @@
"libsurfaceflinger_mocks_headers",
],
}
-
-filegroup {
- name: "layertracegenerator_sources",
- srcs: [
- "LayerTraceGenerator.cpp",
- ],
-}
-
-cc_library_headers {
- name: "layertracegenerator_headers",
- export_include_dirs: ["."],
-}
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index 9471e95..62c362e 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -41,7 +41,9 @@
using namespace ftl::flag_operators;
bool LayerTraceGenerator::generate(const perfetto::protos::TransactionTraceFile& traceFile,
- const char*, bool onlyLastEntry) {
+ std::uint32_t traceFlags,
+ std::optional<std::reference_wrapper<std::ostream>> outStream,
+ bool onlyLastEntry) {
if (traceFile.entry_size() == 0) {
ALOGD("Trace file is empty");
return false;
@@ -49,6 +51,11 @@
TransactionProtoParser parser(std::make_unique<TransactionProtoParser::FlingerDataMapper>());
+ LayerTracing layerTracing;
+ if (outStream) {
+ layerTracing.setOutputStream(outStream->get());
+ }
+
// frontend
frontend::LayerLifecycleManager lifecycleManager;
frontend::LayerHierarchyBuilder hierarchyBuilder{{}};
@@ -60,18 +67,10 @@
property_get("ro.surface_flinger.supports_background_blur", value, "0");
bool supportsBlur = atoi(value);
- LayerTracing layerTracing;
- layerTracing.setTraceFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS);
- // 10MB buffer size (large enough to hold a single entry)
- layerTracing.setBufferSize(10 * 1024 * 1024);
- layerTracing.enable();
- layerTracing.writeToFile(outputLayersTracePath);
- std::ofstream out(outputLayersTracePath, std::ios::binary | std::ios::app);
-
ALOGD("Generating %d transactions...", traceFile.entry_size());
for (int i = 0; i < traceFile.entry_size(); i++) {
// parse proto
- proto::TransactionTraceEntry entry = traceFile.entry(i);
+ perfetto::protos::TransactionTraceEntry entry = traceFile.entry(i);
ALOGV(" Entry %04d/%04d for time=%" PRId64 " vsyncid=%" PRId64
" layers +%d -%d handles -%d transactions=%d",
i, traceFile.entry_size(), entry.elapsed_realtime_nanos(), entry.vsync_id(),
@@ -154,19 +153,26 @@
lifecycleManager.commitChanges();
- LayersProto layersProto = LayerProtoFromSnapshotGenerator(snapshotBuilder, displayInfos, {},
- layerTracing.getFlags())
- .generate(hierarchyBuilder.getHierarchy());
+ auto layersProto =
+ LayerProtoFromSnapshotGenerator(snapshotBuilder, displayInfos, {}, traceFlags)
+ .generate(hierarchyBuilder.getHierarchy());
auto displayProtos = LayerProtoHelper::writeDisplayInfoToProto(displayInfos);
if (!onlyLastEntry || (i == traceFile.entry_size() - 1)) {
- layerTracing.notify(visibleRegionsDirty, entry.elapsed_realtime_nanos(),
- entry.vsync_id(), &layersProto, {}, &displayProtos);
- layerTracing.appendToStream(out);
+ perfetto::protos::LayersSnapshotProto snapshotProto{};
+ snapshotProto.set_vsync_id(entry.vsync_id());
+ snapshotProto.set_elapsed_realtime_nanos(entry.elapsed_realtime_nanos());
+ snapshotProto.set_where(visibleRegionsDirty ? "visibleRegionsDirty" : "bufferLatched");
+ *snapshotProto.mutable_layers() = std::move(layersProto);
+ if ((traceFlags & LayerTracing::TRACE_COMPOSITION) == 0) {
+ snapshotProto.set_excludes_composition_state(true);
+ }
+ *snapshotProto.mutable_displays() = std::move(displayProtos);
+
+ layerTracing.addProtoSnapshotToOstream(std::move(snapshotProto),
+ LayerTracing::Mode::MODE_GENERATED);
}
}
- layerTracing.disable("", /*writeToFile=*/false);
- out.close();
- ALOGD("End of generating trace file. File written to %s", outputLayersTracePath);
+ ALOGD("End of generating trace file");
return true;
}
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h
index a1e5fc8..2bb6f51 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.h
@@ -18,10 +18,19 @@
#include <Tracing/TransactionTracing.h>
+#include <functional>
+#include <optional>
+#include <ostream>
+#include <string>
+
namespace android {
+
+class LayerTracing;
+
class LayerTraceGenerator {
public:
- bool generate(const perfetto::protos::TransactionTraceFile&, const char* outputLayersTracePath,
- bool onlyLastEntry);
+ bool generate(const perfetto::protos::TransactionTraceFile&, std::uint32_t traceFlags,
+ std::optional<std::reference_wrapper<std::ostream>> outStream = std::nullopt,
+ bool onlyLastEntry = false);
};
} // namespace android
diff --git a/services/surfaceflinger/Tracing/tools/main.cpp b/services/surfaceflinger/Tracing/tools/main.cpp
index 0ff8f98..a8ac36a 100644
--- a/services/surfaceflinger/Tracing/tools/main.cpp
+++ b/services/surfaceflinger/Tracing/tools/main.cpp
@@ -21,6 +21,7 @@
#include <iostream>
#include <string>
+#include <Tracing/LayerTracing.h>
#include "LayerTraceGenerator.h"
using namespace android;
@@ -47,19 +48,22 @@
return -1;
}
- const char* outputLayersTracePath =
- (argc >= 3) ? argv[2] : "/data/misc/wmtrace/layers_trace.winscope";
+ const auto* outputLayersTracePath =
+ (argc == 3) ? argv[2] : "/data/misc/wmtrace/layers_trace.winscope";
+ auto outStream = std::ofstream{outputLayersTracePath, std::ios::binary | std::ios::app};
const bool generateLastEntryOnly =
argc >= 4 && std::string_view(argv[3]) == "--last-entry-only";
+ auto traceFlags = LayerTracing::Flag::TRACE_INPUT | LayerTracing::Flag::TRACE_BUFFERS;
+
ALOGD("Generating %s...", outputLayersTracePath);
std::cout << "Generating " << outputLayersTracePath << "\n";
- if (!LayerTraceGenerator().generate(transactionTraceFile, outputLayersTracePath,
+ if (!LayerTraceGenerator().generate(transactionTraceFile, traceFlags, outStream,
generateLastEntryOnly)) {
std::cout << "Error: Failed to generate layers trace " << outputLayersTracePath;
return -1;
}
return 0;
-}
\ No newline at end of file
+}