Frame lifecycle MVP updates
We have decided to show the lifecycle of a frame as a view of ownership,
which makes it easy to understand for the users who are not
SurfaceFlinger-savvy. To do this, we try to create the ownership
slices(Phases) from the existing buffer events. This calls for a bit
more bookkeeping than usual.
Along with the updates, this CL also includes the following:
1) Move frame events parsing out of the graphics_event_parser
2) Rename the existing graphics_event_parser as gpu_event_parser as it
has only gpu events after the move
3) Code cleanup of the existing frame events parsing
Test: diff_test_trace_processor --trace-filter='graphics_frame*'
Bug: 155242423
Change-Id: I89201b1416f8ff37c03658dbd1ad9509e12a8453
diff --git a/Android.bp b/Android.bp
index ccae72b..6221868 100644
--- a/Android.bp
+++ b/Android.bp
@@ -6645,8 +6645,9 @@
"src/trace_processor/importers/proto/android_probes_module.cc",
"src/trace_processor/importers/proto/android_probes_parser.cc",
"src/trace_processor/importers/proto/android_probes_tracker.cc",
+ "src/trace_processor/importers/proto/gpu_event_parser.cc",
"src/trace_processor/importers/proto/graphics_event_module.cc",
- "src/trace_processor/importers/proto/graphics_event_parser.cc",
+ "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
"src/trace_processor/importers/proto/heap_graph_module.cc",
"src/trace_processor/importers/proto/heap_graph_tracker.cc",
"src/trace_processor/importers/proto/system_probes_module.cc",
diff --git a/BUILD b/BUILD
index 578133a..4cc4a94 100644
--- a/BUILD
+++ b/BUILD
@@ -985,10 +985,12 @@
"src/trace_processor/importers/proto/android_probes_parser.h",
"src/trace_processor/importers/proto/android_probes_tracker.cc",
"src/trace_processor/importers/proto/android_probes_tracker.h",
+ "src/trace_processor/importers/proto/gpu_event_parser.cc",
+ "src/trace_processor/importers/proto/gpu_event_parser.h",
"src/trace_processor/importers/proto/graphics_event_module.cc",
"src/trace_processor/importers/proto/graphics_event_module.h",
- "src/trace_processor/importers/proto/graphics_event_parser.cc",
- "src/trace_processor/importers/proto/graphics_event_parser.h",
+ "src/trace_processor/importers/proto/graphics_frame_event_parser.cc",
+ "src/trace_processor/importers/proto/graphics_frame_event_parser.h",
"src/trace_processor/importers/proto/heap_graph_module.cc",
"src/trace_processor/importers/proto/heap_graph_module.h",
"src/trace_processor/importers/proto/heap_graph_tracker.cc",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 1f26298..2b26b7e 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -208,8 +208,10 @@
"importers/proto/android_probes_tracker.h",
"importers/proto/graphics_event_module.cc",
"importers/proto/graphics_event_module.h",
- "importers/proto/graphics_event_parser.cc",
- "importers/proto/graphics_event_parser.h",
+ "importers/proto/gpu_event_parser.cc",
+ "importers/proto/gpu_event_parser.h",
+ "importers/proto/graphics_frame_event_parser.cc",
+ "importers/proto/graphics_frame_event_parser.h",
"importers/proto/heap_graph_module.cc",
"importers/proto/heap_graph_module.h",
"importers/proto/heap_graph_tracker.cc",
diff --git a/src/trace_processor/importers/common/slice_tracker.cc b/src/trace_processor/importers/common/slice_tracker.cc
index 40dfa43..8c82982 100644
--- a/src/trace_processor/importers/common/slice_tracker.cc
+++ b/src/trace_processor/importers/common/slice_tracker.cc
@@ -96,16 +96,18 @@
});
}
-void SliceTracker::ScopedFrameEvent(
+SliceId SliceTracker::ScopedFrameEvent(
const tables::GraphicsFrameSliceTable::Row& row,
SetArgsCallback args_callback) {
PERFETTO_DCHECK(row.dur >= 0);
- StartSlice(row.ts, TrackId(row.track_id), args_callback, [this, &row]() {
- return context_->storage->mutable_graphics_frame_slice_table()
- ->Insert(row)
- .id;
+ SliceId id;
+ StartSlice(row.ts, TrackId(row.track_id), args_callback, [this, &row, &id]() {
+ id =
+ context_->storage->mutable_graphics_frame_slice_table()->Insert(row).id;
+ return id;
});
+ return id;
}
base::Optional<uint32_t> SliceTracker::End(int64_t timestamp,
diff --git a/src/trace_processor/importers/common/slice_tracker.h b/src/trace_processor/importers/common/slice_tracker.h
index 56be608..804806c 100644
--- a/src/trace_processor/importers/common/slice_tracker.h
+++ b/src/trace_processor/importers/common/slice_tracker.h
@@ -61,8 +61,8 @@
void ScopedGpu(const tables::GpuSliceTable::Row& row,
SetArgsCallback args_callback = SetArgsCallback());
- void ScopedFrameEvent(const tables::GraphicsFrameSliceTable::Row& row,
- SetArgsCallback args_callback = SetArgsCallback());
+ SliceId ScopedFrameEvent(const tables::GraphicsFrameSliceTable::Row& row,
+ SetArgsCallback args_callback = SetArgsCallback());
// virtual for testing
virtual base::Optional<uint32_t> End(
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.cc b/src/trace_processor/importers/proto/gpu_event_parser.cc
similarity index 68%
rename from src/trace_processor/importers/proto/graphics_event_parser.cc
rename to src/trace_processor/importers/proto/gpu_event_parser.cc
index 6981a63..4ba14d8 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/gpu_event_parser.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/importers/proto/graphics_event_parser.h"
+#include "src/trace_processor/importers/proto/gpu_event_parser.h"
#include <inttypes.h>
@@ -92,44 +92,12 @@
} // anonymous namespace
-GraphicsEventParser::GraphicsEventParser(TraceProcessorContext* context)
+GpuEventParser::GpuEventParser(TraceProcessorContext* context)
: context_(context),
vulkan_memory_tracker_(context),
description_id_(context->storage->InternString("description")),
gpu_render_stage_scope_id_(
context->storage->InternString("gpu_render_stage")),
- graphics_event_scope_id_(
- context->storage->InternString("graphics_frame_event")),
- unknown_event_name_id_(context->storage->InternString("unknown_event")),
- no_layer_name_name_id_(context->storage->InternString("no_layer_name")),
- layer_name_key_id_(context->storage->InternString("layer_name")),
- event_type_name_ids_{
- {context->storage->InternString(
- "unspecified_event") /* UNSPECIFIED */,
- context->storage->InternString("Dequeue") /* DEQUEUE */,
- context->storage->InternString("Queue") /* QUEUE */,
- context->storage->InternString("Post") /* POST */,
- context->storage->InternString(
- "AcquireFenceSignaled") /* ACQUIRE_FENCE */,
- context->storage->InternString("Latch") /* LATCH */,
- context->storage->InternString(
- "HWCCompositionQueued") /* HWC_COMPOSITION_QUEUED */,
- context->storage->InternString(
- "FallbackComposition") /* FALLBACK_COMPOSITION */,
- context->storage->InternString(
- "PresentFenceSignaled") /* PRESENT_FENCE */,
- context->storage->InternString(
- "ReleaseFenceSignaled") /* RELEASE_FENCE */,
- context->storage->InternString("Modify") /* MODIFY */,
- context->storage->InternString("Detach") /* DETACH */,
- context->storage->InternString("Attach") /* ATTACH */,
- context->storage->InternString("Cancel") /* CANCEL */}},
- present_frame_name_(present_frame_buffer_,
- base::ArraySize(present_frame_buffer_)),
- present_frame_layer_name_(present_frame_layer_buffer_,
- base::ArraySize(present_frame_layer_buffer_)),
- present_frame_numbers_(present_frame_numbers_buffer_,
- base::ArraySize(present_frame_numbers_buffer_)),
gpu_log_track_name_id_(context_->storage->InternString("GPU Log")),
gpu_log_scope_id_(context_->storage->InternString("gpu_log")),
tag_id_(context_->storage->InternString("tag")),
@@ -146,7 +114,7 @@
vk_event_scope_id_(context->storage->InternString("vulkan_events")),
vk_queue_submit_id_(context->storage->InternString("vkQueueSubmit")) {}
-void GraphicsEventParser::ParseGpuCounterEvent(int64_t ts, ConstBytes blob) {
+void GpuEventParser::ParseGpuCounterEvent(int64_t ts, ConstBytes blob) {
protos::pbzero::GpuCounterEvent::Decoder event(blob.data, blob.size);
protos::pbzero::GpuCounterDescriptor::Decoder descriptor(
@@ -246,7 +214,7 @@
}
}
-const StringId GraphicsEventParser::GetFullStageName(
+const StringId GpuEventParser::GetFullStageName(
const protos::pbzero::GpuRenderStageEvent_Decoder& event) const {
size_t stage_id = static_cast<size_t>(event.stage_id());
StringId stage_name;
@@ -265,7 +233,7 @@
* Create a GPU render stage track based
* GpuRenderStageEvent.Specifications.Description.
*/
-void GraphicsEventParser::InsertGpuTrack(
+void GpuEventParser::InsertGpuTrack(
const protos::pbzero::
GpuRenderStageEvent_Specifications_Description_Decoder& hw_queue) {
StringId track_name = context_->storage->InternString(hw_queue.name());
@@ -306,7 +274,7 @@
}
++gpu_hw_queue_counter_;
}
-base::Optional<std::string> GraphicsEventParser::FindDebugName(
+base::Optional<std::string> GpuEventParser::FindDebugName(
int32_t vk_object_type,
uint64_t vk_handle) const {
auto map = debug_marker_names_.find(vk_object_type);
@@ -322,8 +290,7 @@
}
}
-void GraphicsEventParser::ParseGpuRenderStageEvent(int64_t ts,
- ConstBytes blob) {
+void GpuEventParser::ParseGpuRenderStageEvent(int64_t ts, ConstBytes blob) {
protos::pbzero::GpuRenderStageEvent::Decoder event(blob.data, blob.size);
if (event.has_specifications()) {
@@ -395,21 +362,24 @@
gpu_hw_queue_ids_[hw_queue_id] = track_id;
}
- auto render_target_name = FindDebugName(VK_OBJECT_TYPE_FRAMEBUFFER, event.render_target_handle());
+ auto render_target_name =
+ FindDebugName(VK_OBJECT_TYPE_FRAMEBUFFER, event.render_target_handle());
auto render_target_name_id = render_target_name.has_value()
- ? context_->storage->InternString(
- render_target_name.value().c_str())
- : kNullStringId;
- auto render_pass_name = FindDebugName(VK_OBJECT_TYPE_RENDER_PASS, event.render_pass_handle());
- auto render_pass_name_id = render_pass_name.has_value()
- ? context_->storage->InternString(
- render_pass_name.value().c_str())
- : kNullStringId;
- auto command_buffer_name = FindDebugName(VK_OBJECT_TYPE_COMMAND_BUFFER, event.command_buffer_handle());
+ ? context_->storage->InternString(
+ render_target_name.value().c_str())
+ : kNullStringId;
+ auto render_pass_name =
+ FindDebugName(VK_OBJECT_TYPE_RENDER_PASS, event.render_pass_handle());
+ auto render_pass_name_id =
+ render_pass_name.has_value()
+ ? context_->storage->InternString(render_pass_name.value().c_str())
+ : kNullStringId;
+ auto command_buffer_name = FindDebugName(VK_OBJECT_TYPE_COMMAND_BUFFER,
+ event.command_buffer_handle());
auto command_buffer_name_id = command_buffer_name.has_value()
- ? context_->storage->InternString(
- command_buffer_name.value().c_str())
- : kNullStringId;
+ ? context_->storage->InternString(
+ command_buffer_name.value().c_str())
+ : kNullStringId;
tables::GpuSliceTable::Row row;
row.ts = ts;
@@ -430,203 +400,7 @@
}
}
-void GraphicsEventParser::ParseGraphicsFrameEvent(int64_t timestamp,
- ConstBytes blob) {
- using GraphicsFrameEvent = protos::pbzero::GraphicsFrameEvent;
- protos::pbzero::GraphicsFrameEvent_Decoder frame_event(blob.data, blob.size);
- if (!frame_event.has_buffer_event()) {
- return;
- }
-
- ConstBytes bufferBlob = frame_event.buffer_event();
- protos::pbzero::GraphicsFrameEvent_BufferEvent_Decoder event(bufferBlob.data,
- bufferBlob.size);
-
- if (!event.has_buffer_id()) {
- context_->storage->IncrementStats(
- stats::graphics_frame_event_parser_errors);
- PERFETTO_ELOG("GraphicsFrameEvent with missing buffer id field.");
- return;
- }
-
- StringId event_name_id = unknown_event_name_id_;
- if (event.has_type()) {
- const auto type = static_cast<size_t>(event.type());
- if (type < event_type_name_ids_.size()) {
- event_name_id = event_type_name_ids_[type];
- graphics_frame_stats_map_[event.buffer_id()][type] = timestamp;
- } else {
- context_->storage->IncrementStats(
- stats::graphics_frame_event_parser_errors);
- PERFETTO_ELOG("GraphicsFrameEvent with unknown type %zu.", type);
- }
- } else {
- context_->storage->IncrementStats(
- stats::graphics_frame_event_parser_errors);
- PERFETTO_ELOG("GraphicsFrameEvent with missing type field.");
- }
-
- const uint32_t buffer_id = event.buffer_id();
- StringId layer_name_id;
-
- char buffer[4096];
- const size_t layerNameMaxLength = 4000;
- base::StringWriter track_name(buffer, sizeof(buffer));
- if (event.has_layer_name()) {
- const base::StringView layer_name(event.layer_name());
- layer_name_id = context_->storage->InternString(layer_name);
- track_name.AppendString(layer_name.substr(0, layerNameMaxLength));
- } else {
- layer_name_id = no_layer_name_name_id_;
- track_name.AppendLiteral("unknown_layer");
- }
- track_name.AppendLiteral("[buffer:");
- track_name.AppendUnsignedInt(buffer_id);
- track_name.AppendChar(']');
-
- const StringId track_name_id =
- context_->storage->InternString(track_name.GetStringView());
- const int64_t duration =
- event.has_duration_ns() ? static_cast<int64_t>(event.duration_ns()) : 0;
- const uint32_t frame_number =
- event.has_frame_number() ? event.frame_number() : 0;
-
- tables::GpuTrackTable::Row track(track_name_id);
- track.scope = graphics_event_scope_id_;
- TrackId track_id = context_->track_tracker->InternGpuTrack(track);
-
- {
- char frame_number_buffer[256];
- base::StringWriter frame_numbers(frame_number_buffer,
- base::ArraySize(frame_number_buffer));
- frame_numbers.AppendUnsignedInt(frame_number);
-
- tables::GraphicsFrameSliceTable::Row row;
- row.ts = timestamp;
- row.track_id = track_id;
- row.name = event_name_id;
- row.dur = duration;
- row.frame_numbers =
- context_->storage->InternString(frame_numbers.GetStringView());
- row.layer_names = layer_name_id;
- context_->slice_tracker->ScopedFrameEvent(row);
- }
-
- /* Displayed Frame track */
- if (event.type() == GraphicsFrameEvent::PRESENT_FENCE) {
- // Insert the frame stats for the buffer that was presented
- auto acquire_ts =
- graphics_frame_stats_map_[event.buffer_id()]
- [GraphicsFrameEvent::ACQUIRE_FENCE];
- auto queue_ts =
- graphics_frame_stats_map_[event.buffer_id()][GraphicsFrameEvent::QUEUE];
- auto latch_ts =
- graphics_frame_stats_map_[event.buffer_id()][GraphicsFrameEvent::LATCH];
- tables::GraphicsFrameStatsTable::Row stats_row;
- // AcquireFence can signal before Queue sometimes, so have 0 as a bound.
- stats_row.queue_to_acquire_time =
- std::max(acquire_ts - queue_ts, static_cast<int64_t>(0));
- stats_row.acquire_to_latch_time = latch_ts - acquire_ts;
- stats_row.latch_to_present_time = timestamp - latch_ts;
- auto stats_row_id =
- context_->storage->mutable_graphics_frame_stats_table()->Insert(
- stats_row);
-
- if (previous_timestamp_ == 0) {
- const StringId present_track_name_id =
- context_->storage->InternString("Displayed Frame");
- tables::GpuTrackTable::Row present_track(present_track_name_id);
- present_track.scope = graphics_event_scope_id_;
- present_track_id_ =
- context_->track_tracker->InternGpuTrack(present_track);
- }
-
- // The displayed frame is a slice from one present fence to another present
- // fence. If multiple buffers have present fence at the same time, they all
- // are shown on screen at the same time. So that particular displayed frame
- // slice should include info from all those buffers in it.
- // Since the events are parsed one by one, the following bookkeeping is
- // needed to create the slice properly.
- if (previous_timestamp_ == timestamp && previous_timestamp_ != 0) {
- // Same timestamp as previous present fence. This buffer should also
- // contribute to this slice.
- present_frame_name_.AppendLiteral(", ");
- present_frame_name_.AppendUnsignedInt(buffer_id);
-
- // Append Layer names
- present_frame_layer_name_.AppendLiteral(", ");
- present_frame_layer_name_.AppendString(event.layer_name());
-
- // Append Frame numbers
- present_frame_numbers_.AppendLiteral(", ");
- present_frame_numbers_.AppendUnsignedInt(frame_number);
-
- // Add the current stats row to the list of stats that go with this frame
- graphics_frame_stats_idx_.push_back(stats_row_id.row);
- } else {
-
- if (previous_timestamp_ != 0) {
- StringId present_frame_layer_name_id = context_->storage->InternString(
- present_frame_layer_name_.GetStringView());
- // End the current slice that's being tracked.
- const auto opt_slice_id = context_->slice_tracker->EndFrameEvent(
- timestamp, present_track_id_);
-
- if (opt_slice_id) {
- // The slice could have had additional buffers in it, so we need to
- // update the table.
- auto* graphics_frame_slice_table =
- context_->storage->mutable_graphics_frame_slice_table();
-
- uint32_t row_idx =
- *graphics_frame_slice_table->id().IndexOf(*opt_slice_id);
- StringId frame_name_id = context_->storage->InternString(
- present_frame_name_.GetStringView());
- graphics_frame_slice_table->mutable_name()->Set(row_idx,
- frame_name_id);
-
- StringId present_frame_numbers_id = context_->storage->InternString(
- present_frame_numbers_.GetStringView());
- graphics_frame_slice_table->mutable_frame_numbers()->Set(
- row_idx, present_frame_numbers_id);
- graphics_frame_slice_table->mutable_layer_names()->Set(
- row_idx, present_frame_layer_name_id);
-
- // Set the slice_id for the frame_stats rows under this displayed
- // frame
- auto* slice_table = context_->storage->mutable_slice_table();
- uint32_t slice_idx = *slice_table->id().IndexOf(*opt_slice_id);
- for (uint32_t i = 0; i < graphics_frame_stats_idx_.size(); i++) {
- context_->storage->mutable_graphics_frame_stats_table()
- ->mutable_slice_id()
- ->Set(graphics_frame_stats_idx_[i], slice_idx);
- }
- }
- present_frame_layer_name_.reset();
- present_frame_name_.reset();
- present_frame_numbers_.reset();
- graphics_frame_stats_idx_.clear();
- }
-
- // Start a new slice
- present_frame_name_.AppendUnsignedInt(buffer_id);
- previous_timestamp_ = timestamp;
- present_frame_layer_name_.AppendString(event.layer_name());
- present_frame_numbers_.AppendUnsignedInt(frame_number);
- present_event_name_id_ =
- context_->storage->InternString(present_frame_name_.GetStringView());
- graphics_frame_stats_idx_.push_back(stats_row_id.row);
-
- tables::GraphicsFrameSliceTable::Row row;
- row.ts = timestamp;
- row.track_id = present_track_id_;
- row.name = present_event_name_id_;
- context_->slice_tracker->BeginFrameEvent(row);
- }
- }
-}
-
-void GraphicsEventParser::UpdateVulkanMemoryAllocationCounters(
+void GpuEventParser::UpdateVulkanMemoryAllocationCounters(
UniquePid upid,
const VulkanMemoryEvent::Decoder& event) {
StringId track_str_id = kNullStringId;
@@ -722,7 +496,7 @@
}
}
-void GraphicsEventParser::ParseVulkanMemoryEvent(
+void GpuEventParser::ParseVulkanMemoryEvent(
PacketSequenceStateGeneration* sequence_state,
ConstBytes blob) {
using protos::pbzero::InternedData;
@@ -803,7 +577,7 @@
}
}
-void GraphicsEventParser::ParseGpuLog(int64_t ts, ConstBytes blob) {
+void GpuEventParser::ParseGpuLog(int64_t ts, ConstBytes blob) {
protos::pbzero::GpuLog::Decoder event(blob.data, blob.size);
tables::GpuTrackTable::Row track(gpu_log_track_name_id_);
@@ -837,7 +611,7 @@
context_->slice_tracker->ScopedGpu(row, args_callback);
}
-void GraphicsEventParser::ParseVulkanApiEvent(int64_t ts, ConstBytes blob) {
+void GpuEventParser::ParseVulkanApiEvent(int64_t ts, ConstBytes blob) {
protos::pbzero::VulkanApiEvent::Decoder vk_event(blob.data, blob.size);
if (vk_event.has_vk_debug_utils_object_name()) {
protos::pbzero::VulkanApiEvent_VkDebugUtilsObjectName::Decoder event(
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.h b/src/trace_processor/importers/proto/gpu_event_parser.h
similarity index 76%
rename from src/trace_processor/importers/proto/graphics_event_parser.h
rename to src/trace_processor/importers/proto/gpu_event_parser.h
index 93224d4..175f62c 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.h
+++ b/src/trace_processor/importers/proto/gpu_event_parser.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_PARSER_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_PARSER_H_
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GPU_EVENT_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GPU_EVENT_PARSER_H_
#include <vector>
@@ -52,16 +52,15 @@
};
// Class for parsing graphics related events.
-class GraphicsEventParser {
+class GpuEventParser {
public:
using ConstBytes = protozero::ConstBytes;
using VulkanMemoryEventSource = VulkanMemoryEvent::Source;
using VulkanMemoryEventOperation = VulkanMemoryEvent::Operation;
- explicit GraphicsEventParser(TraceProcessorContext*);
+ explicit GpuEventParser(TraceProcessorContext*);
void ParseGpuCounterEvent(int64_t ts, ConstBytes);
void ParseGpuRenderStageEvent(int64_t ts, ConstBytes);
- void ParseGraphicsFrameEvent(int64_t timestamp, ConstBytes);
void ParseGpuLog(int64_t ts, ConstBytes);
void ParseVulkanMemoryEvent(PacketSequenceStateGeneration*, ConstBytes);
@@ -90,27 +89,6 @@
size_t gpu_hw_queue_counter_ = 0;
// Map of stage ID -> pair(stage name, stage description)
std::vector<std::pair<StringId, StringId>> gpu_render_stage_ids_;
- // For GraphicsFrameEvent
- const StringId graphics_event_scope_id_;
- const StringId unknown_event_name_id_;
- const StringId no_layer_name_name_id_;
- const StringId layer_name_key_id_;
- std::array<StringId, 14> event_type_name_ids_;
- int64_t previous_timestamp_ = 0;
- char present_frame_buffer_[4096];
- char present_frame_layer_buffer_[4096];
- char present_frame_numbers_buffer_[4096];
- StringId present_event_name_id_;
- base::StringWriter present_frame_name_;
- base::StringWriter present_frame_layer_name_;
- base::StringWriter present_frame_numbers_;
- TrackId present_track_id_;
- // Row indices of frame stats table. Used to populate the slice_id after
- // inserting the rows.
- std::vector<uint32_t> graphics_frame_stats_idx_;
- // Map of buffer ID -> (Map of GraphicsFrameEvent -> ts of that event)
- std::unordered_map<uint32_t, std::unordered_map<uint64_t, int64_t>>
- graphics_frame_stats_map_;
// For VulkanMemoryEvent
std::unordered_map<VulkanMemoryEvent::AllocationScope,
int64_t /*counter_value*/,
@@ -140,4 +118,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_PARSER_H_
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GPU_EVENT_PARSER_H_
diff --git a/src/trace_processor/importers/proto/graphics_event_module.cc b/src/trace_processor/importers/proto/graphics_event_module.cc
index f003464..432b3bd 100644
--- a/src/trace_processor/importers/proto/graphics_event_module.cc
+++ b/src/trace_processor/importers/proto/graphics_event_module.cc
@@ -22,7 +22,7 @@
using perfetto::protos::pbzero::TracePacket;
GraphicsEventModule::GraphicsEventModule(TraceProcessorContext* context)
- : parser_(context) {
+ : parser_(context), frame_parser_(context) {
RegisterForField(TracePacket::kGpuCounterEventFieldNumber, context);
RegisterForField(TracePacket::kGpuRenderStageEventFieldNumber, context);
RegisterForField(TracePacket::kGpuLogFieldNumber, context);
@@ -48,8 +48,8 @@
parser_.ParseGpuLog(ttp.timestamp, decoder.gpu_log());
return;
case TracePacket::kGraphicsFrameEventFieldNumber:
- parser_.ParseGraphicsFrameEvent(ttp.timestamp,
- decoder.graphics_frame_event());
+ frame_parser_.ParseGraphicsFrameEvent(ttp.timestamp,
+ decoder.graphics_frame_event());
return;
case TracePacket::kVulkanMemoryEventFieldNumber:
PERFETTO_DCHECK(ttp.type == TimestampedTracePiece::Type::kTracePacket);
diff --git a/src/trace_processor/importers/proto/graphics_event_module.h b/src/trace_processor/importers/proto/graphics_event_module.h
index f7a36dd..f84b2c5 100644
--- a/src/trace_processor/importers/proto/graphics_event_module.h
+++ b/src/trace_processor/importers/proto/graphics_event_module.h
@@ -18,7 +18,8 @@
#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_EVENT_MODULE_H_
#include "perfetto/base/build_config.h"
-#include "src/trace_processor/importers/proto/graphics_event_parser.h"
+#include "src/trace_processor/importers/proto/gpu_event_parser.h"
+#include "src/trace_processor/importers/proto/graphics_frame_event_parser.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
#include "src/trace_processor/timestamped_trace_piece.h"
@@ -38,7 +39,8 @@
uint32_t field_id) override;
private:
- GraphicsEventParser parser_;
+ GpuEventParser parser_;
+ GraphicsFrameEventParser frame_parser_;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/graphics_frame_event_parser.cc b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
new file mode 100644
index 0000000..e33ed9c
--- /dev/null
+++ b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/proto/graphics_frame_event_parser.h"
+
+#include <inttypes.h>
+
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/protozero/field.h"
+#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/process_tracker.h"
+#include "src/trace_processor/importers/common/slice_tracker.h"
+#include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+
+#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+constexpr char kQueueLostMessage[] =
+ "Missing queue event. The slice is now a bit extended than it might "
+ "actually have been";
+GraphicsFrameEventParser::GraphicsFrameEventParser(
+ TraceProcessorContext* context)
+ : context_(context),
+ graphics_event_scope_id_(
+ context->storage->InternString("graphics_frame_event")),
+ unknown_event_name_id_(context->storage->InternString("unknown_event")),
+ no_layer_name_name_id_(context->storage->InternString("no_layer_name")),
+ layer_name_key_id_(context->storage->InternString("layer_name")),
+ event_type_name_ids_{
+ {context->storage->InternString(
+ "unspecified_event") /* UNSPECIFIED */,
+ context->storage->InternString("Dequeue") /* DEQUEUE */,
+ context->storage->InternString("Queue") /* QUEUE */,
+ context->storage->InternString("Post") /* POST */,
+ context->storage->InternString(
+ "AcquireFenceSignaled") /* ACQUIRE_FENCE */,
+ context->storage->InternString("Latch") /* LATCH */,
+ context->storage->InternString(
+ "HWCCompositionQueued") /* HWC_COMPOSITION_QUEUED */,
+ context->storage->InternString(
+ "FallbackComposition") /* FALLBACK_COMPOSITION */,
+ context->storage->InternString(
+ "PresentFenceSignaled") /* PRESENT_FENCE */,
+ context->storage->InternString(
+ "ReleaseFenceSignaled") /* RELEASE_FENCE */,
+ context->storage->InternString("Modify") /* MODIFY */,
+ context->storage->InternString("Detach") /* DETACH */,
+ context->storage->InternString("Attach") /* ATTACH */,
+ context->storage->InternString("Cancel") /* CANCEL */}},
+ queue_lost_message_id_(
+ context->storage->InternString(kQueueLostMessage)) {}
+
+bool GraphicsFrameEventParser::CreateBufferEvent(
+ int64_t timestamp,
+ GraphicsFrameEventDecoder& event) {
+ if (!event.has_buffer_id()) {
+ context_->storage->IncrementStats(
+ stats::graphics_frame_event_parser_errors);
+ PERFETTO_ELOG("GraphicsFrameEvent with missing buffer id field.");
+ return false;
+ }
+
+ StringId event_name_id = unknown_event_name_id_;
+ if (event.has_type()) {
+ const auto type = static_cast<size_t>(event.type());
+ if (type < event_type_name_ids_.size()) {
+ event_name_id = event_type_name_ids_[type];
+ graphics_frame_stats_map_[event.buffer_id()][type] = timestamp;
+ } else {
+ context_->storage->IncrementStats(
+ stats::graphics_frame_event_parser_errors);
+ PERFETTO_ELOG("GraphicsFrameEvent with unknown type %zu.", type);
+ }
+ } else {
+ context_->storage->IncrementStats(
+ stats::graphics_frame_event_parser_errors);
+ PERFETTO_ELOG("GraphicsFrameEvent with missing type field.");
+ }
+
+ const uint32_t buffer_id = event.buffer_id();
+ StringId layer_name_id;
+
+ if (event.has_layer_name()) {
+ auto layer_name_str = event.layer_name();
+ const base::StringView layer_name(layer_name_str);
+ layer_name_id = context_->storage->InternString(layer_name);
+ } else {
+ layer_name_id = no_layer_name_name_id_;
+ }
+ char buffer[4096];
+ base::StringWriter track_name(buffer, sizeof(buffer));
+ track_name.AppendLiteral("Buffer: ");
+ track_name.AppendUnsignedInt(buffer_id);
+
+ const StringId track_name_id =
+ context_->storage->InternString(track_name.GetStringView());
+ const int64_t duration =
+ event.has_duration_ns() ? static_cast<int64_t>(event.duration_ns()) : 0;
+ uint32_t frame_number = event.has_frame_number() ? event.frame_number() : 0;
+
+ tables::GpuTrackTable::Row track(track_name_id);
+ track.scope = graphics_event_scope_id_;
+ TrackId track_id = context_->track_tracker->InternGpuTrack(track);
+
+ {
+ tables::GraphicsFrameSliceTable::Row row;
+ row.ts = timestamp;
+ row.track_id = track_id;
+ row.name = event_name_id;
+ row.dur = duration;
+ row.frame_number = frame_number;
+ row.layer_name = layer_name_id;
+ if (event.type() == GraphicsFrameEvent::PRESENT_FENCE) {
+ auto acquire_ts =
+ graphics_frame_stats_map_[event.buffer_id()]
+ [GraphicsFrameEvent::ACQUIRE_FENCE];
+ auto queue_ts = graphics_frame_stats_map_[event.buffer_id()]
+ [GraphicsFrameEvent::QUEUE];
+ auto latch_ts = graphics_frame_stats_map_[event.buffer_id()]
+ [GraphicsFrameEvent::LATCH];
+
+ row.queue_to_acquire_time =
+ std::max(acquire_ts - queue_ts, static_cast<int64_t>(0));
+ row.acquire_to_latch_time = latch_ts - acquire_ts;
+ row.latch_to_present_time = timestamp - latch_ts;
+ }
+ auto slice_id = context_->slice_tracker->ScopedFrameEvent(row);
+ if (event.type() == GraphicsFrameEvent::DEQUEUE) {
+ dequeue_slice_ids_[buffer_id] = slice_id;
+ } else if (event.type() == GraphicsFrameEvent::QUEUE) {
+ auto it = dequeue_slice_ids_.find(buffer_id);
+ if (it != dequeue_slice_ids_.end()) {
+ auto dequeue_slice_id = it->second;
+ auto* graphics_frame_slice_table =
+ context_->storage->mutable_graphics_frame_slice_table();
+ uint32_t row_idx =
+ *graphics_frame_slice_table->id().IndexOf(dequeue_slice_id);
+ graphics_frame_slice_table->mutable_frame_number()->Set(row_idx,
+ frame_number);
+ }
+ }
+ }
+ return true;
+}
+
+// Here we convert the buffer events into Phases(slices)
+// APP: Dequeue to Queue
+// Wait for GPU: Queue to Acquire
+// SurfaceFlinger (SF): Latch to Present
+// Display: Present to next Present (of the same layer)
+void GraphicsFrameEventParser::CreatePhaseEvent(
+ int64_t timestamp,
+ GraphicsFrameEventDecoder& event) {
+ const uint32_t buffer_id = event.buffer_id();
+ uint32_t frame_number = event.has_frame_number() ? event.frame_number() : 0;
+ StringId layer_name_id;
+ if (event.has_layer_name()) {
+ auto layer_name_str = event.layer_name();
+ const base::StringView layer_name(layer_name_str);
+ layer_name_id = context_->storage->InternString(layer_name);
+ } else {
+ layer_name_id = no_layer_name_name_id_;
+ }
+ char track_buffer[4096];
+ char slice_buffer[4096];
+ // We'll be using the name StringWriter and name_id for writing track names
+ // and slice names.
+ base::StringWriter track_name(track_buffer, sizeof(track_buffer));
+ base::StringWriter slice_name(slice_buffer, sizeof(slice_buffer));
+ StringId track_name_id;
+ TrackId track_id;
+ bool start_slice = true;
+
+ // Close the previous phase before starting the new phase
+ switch (event.type()) {
+ case GraphicsFrameEvent::DEQUEUE: {
+ track_name.reset();
+ track_name.AppendLiteral("APP_");
+ track_name.AppendUnsignedInt(buffer_id);
+ track_name_id =
+ context_->storage->InternString(track_name.GetStringView());
+ tables::GpuTrackTable::Row app_track(track_name_id);
+ app_track.scope = graphics_event_scope_id_;
+ track_id = context_->track_tracker->InternGpuTrack(app_track);
+ dequeue_map_[buffer_id] = track_id;
+ last_dequeued_[buffer_id] = timestamp;
+ break;
+ }
+
+ case GraphicsFrameEvent::QUEUE: {
+ auto dequeueTime = dequeue_map_.find(buffer_id);
+ if (dequeueTime != dequeue_map_.end()) {
+ const auto opt_slice_id = context_->slice_tracker->EndFrameEvent(
+ timestamp, dequeueTime->second);
+ slice_name.reset();
+ slice_name.AppendUnsignedInt(frame_number);
+ if (opt_slice_id) {
+ auto* graphics_frame_slice_table =
+ context_->storage->mutable_graphics_frame_slice_table();
+ // Set the name of the slice to be the frame number since dequeue did
+ // not have a frame number at that time.
+ uint32_t row_idx =
+ *graphics_frame_slice_table->id().IndexOf(*opt_slice_id);
+ StringId frame_name_id =
+ context_->storage->InternString(slice_name.GetStringView());
+ graphics_frame_slice_table->mutable_name()->Set(row_idx,
+ frame_name_id);
+ graphics_frame_slice_table->mutable_frame_number()->Set(row_idx,
+ frame_number);
+ dequeue_map_.erase(dequeueTime);
+ }
+ }
+ // The AcquireFence might be signaled before receiving a QUEUE event
+ // sometimes. In that case, we shouldn't start a slice.
+ if (last_acquired_[buffer_id] > last_dequeued_[buffer_id] &&
+ last_acquired_[buffer_id] < timestamp) {
+ start_slice = false;
+ break;
+ }
+ track_name.reset();
+ track_name.AppendLiteral("GPU_");
+ track_name.AppendUnsignedInt(buffer_id);
+ track_name_id =
+ context_->storage->InternString(track_name.GetStringView());
+ tables::GpuTrackTable::Row gpu_track(track_name_id);
+ gpu_track.scope = graphics_event_scope_id_;
+ track_id = context_->track_tracker->InternGpuTrack(gpu_track);
+ queue_map_[buffer_id] = track_id;
+ break;
+ }
+ case GraphicsFrameEvent::ACQUIRE_FENCE: {
+ auto queueTime = queue_map_.find(buffer_id);
+ if (queueTime != queue_map_.end()) {
+ context_->slice_tracker->EndFrameEvent(timestamp, queueTime->second);
+ queue_map_.erase(queueTime);
+ }
+ last_acquired_[buffer_id] = timestamp;
+ start_slice = false;
+ break;
+ }
+ case GraphicsFrameEvent::LATCH: {
+ // b/157578286 - Sometimes Queue event goes missing. To prevent having a
+ // wrong slice info, we try to close any existing APP slice.
+ auto dequeueTime = dequeue_map_.find(buffer_id);
+ if (dequeueTime != dequeue_map_.end()) {
+ auto args_callback = [this](ArgsTracker::BoundInserter* inserter) {
+ inserter->AddArg(context_->storage->InternString("Details"),
+ Variadic::String(queue_lost_message_id_));
+ };
+ const auto opt_slice_id = context_->slice_tracker->EndFrameEvent(
+ timestamp, dequeueTime->second, args_callback);
+ slice_name.reset();
+ slice_name.AppendUnsignedInt(frame_number);
+ if (opt_slice_id) {
+ auto* graphics_frame_slice_table =
+ context_->storage->mutable_graphics_frame_slice_table();
+ // Set the name of the slice to be the frame number since dequeue did
+ // not have a frame number at that time.
+ uint32_t row_idx =
+ *graphics_frame_slice_table->id().IndexOf(*opt_slice_id);
+ StringId frame_name_id =
+ context_->storage->InternString(slice_name.GetStringView());
+ graphics_frame_slice_table->mutable_name()->Set(row_idx,
+ frame_name_id);
+ graphics_frame_slice_table->mutable_frame_number()->Set(row_idx,
+ frame_number);
+ dequeue_map_.erase(dequeueTime);
+ }
+ }
+ track_name.reset();
+ track_name.AppendLiteral("SF_");
+ track_name.AppendUnsignedInt(buffer_id);
+ track_name_id =
+ context_->storage->InternString(track_name.GetStringView());
+ tables::GpuTrackTable::Row sf_track(track_name_id);
+ sf_track.scope = graphics_event_scope_id_;
+ track_id = context_->track_tracker->InternGpuTrack(sf_track);
+ latch_map_[buffer_id] = track_id;
+ break;
+ }
+
+ case GraphicsFrameEvent::PRESENT_FENCE: {
+ auto latchTime = latch_map_.find(buffer_id);
+ if (latchTime != latch_map_.end()) {
+ context_->slice_tracker->EndFrameEvent(timestamp, latchTime->second);
+ latch_map_.erase(latchTime);
+ }
+ auto displayTime = display_map_.find(layer_name_id);
+ if (displayTime != display_map_.end()) {
+ context_->slice_tracker->EndFrameEvent(timestamp, displayTime->second);
+ display_map_.erase(displayTime);
+ }
+ base::StringView layerName(event.layer_name());
+ track_name.reset();
+ track_name.AppendLiteral("Display_");
+ track_name.AppendString(layerName.substr(0, 10));
+ track_name_id =
+ context_->storage->InternString(track_name.GetStringView());
+ tables::GpuTrackTable::Row display_track(track_name_id);
+ display_track.scope = graphics_event_scope_id_;
+ track_id = context_->track_tracker->InternGpuTrack(display_track);
+ display_map_[layer_name_id] = track_id;
+ break;
+ }
+
+ default:
+ start_slice = false;
+ }
+
+ // Start the new phase if needed.
+ if (start_slice) {
+ tables::GraphicsFrameSliceTable::Row slice;
+ slice.ts = timestamp;
+ slice.track_id = track_id;
+ slice.layer_name = layer_name_id;
+ slice_name.reset();
+ // If the frame_number is known, set it as the name of the slice.
+ // If not known (DEQUEUE), set the name as the timestamp.
+ // Timestamp is chosen here because the stack_id is hashed based on the name
+ // of the slice. To not have any conflicting stack_id with any of the
+ // existing slices, we use timestamp as the temporary name.
+ if (frame_number != 0) {
+ slice_name.AppendUnsignedInt(frame_number);
+ } else {
+ slice_name.AppendInt(timestamp);
+ }
+ slice.name = context_->storage->InternString(slice_name.GetStringView());
+ slice.frame_number = frame_number;
+ context_->slice_tracker->BeginFrameEvent(slice);
+ }
+}
+
+void GraphicsFrameEventParser::ParseGraphicsFrameEvent(int64_t timestamp,
+ ConstBytes blob) {
+ protos::pbzero::GraphicsFrameEvent_Decoder frame_event(blob.data, blob.size);
+ if (!frame_event.has_buffer_event()) {
+ return;
+ }
+
+ ConstBytes bufferBlob = frame_event.buffer_event();
+ protos::pbzero::GraphicsFrameEvent_BufferEvent_Decoder event(bufferBlob.data,
+ bufferBlob.size);
+ if (CreateBufferEvent(timestamp, event)) {
+ // Create a phase event only if the buffer event finishes successfully
+ CreatePhaseEvent(timestamp, event);
+ }
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/graphics_frame_event_parser.h b/src/trace_processor/importers/proto/graphics_frame_event_parser.h
new file mode 100644
index 0000000..e23fa73
--- /dev/null
+++ b/src/trace_processor/importers/proto/graphics_frame_event_parser.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_FRAME_EVENT_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_FRAME_EVENT_PARSER_H_
+
+#include <vector>
+
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_writer.h"
+#include "perfetto/protozero/field.h"
+#include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/proto/proto_incremental_state.h"
+#include "src/trace_processor/importers/proto/vulkan_memory_tracker.h"
+#include "src/trace_processor/storage/trace_storage.h"
+
+#include "protos/perfetto/trace/android/graphics_frame_event.pbzero.h"
+
+namespace perfetto {
+
+namespace trace_processor {
+
+class TraceProcessorContext;
+
+// Class for parsing graphics frame related events.
+class GraphicsFrameEventParser {
+ public:
+ using ConstBytes = protozero::ConstBytes;
+ explicit GraphicsFrameEventParser(TraceProcessorContext*);
+
+ void ParseGraphicsFrameEvent(int64_t timestamp, ConstBytes);
+
+ private:
+ using GraphicsFrameEventDecoder =
+ protos::pbzero::GraphicsFrameEvent_BufferEvent_Decoder;
+ using GraphicsFrameEvent = protos::pbzero::GraphicsFrameEvent;
+ bool CreateBufferEvent(int64_t timestamp, GraphicsFrameEventDecoder& event);
+ void CreatePhaseEvent(int64_t timestamp, GraphicsFrameEventDecoder& event);
+
+ TraceProcessorContext* const context_;
+ const StringId graphics_event_scope_id_;
+ const StringId unknown_event_name_id_;
+ const StringId no_layer_name_name_id_;
+ const StringId layer_name_key_id_;
+ std::array<StringId, 14> event_type_name_ids_;
+ const StringId queue_lost_message_id_;
+ // Map of buffer ID -> slice id of the dequeue event
+ std::unordered_map<uint32_t, SliceId> dequeue_slice_ids_;
+
+ // Row indices of frame stats table. Used to populate the slice_id after
+ // inserting the rows.
+ std::vector<uint32_t> graphics_frame_stats_idx_;
+ // Map of buffer ID -> (Map of GraphicsFrameEvent -> ts of that event)
+ std::unordered_map<uint32_t, std::unordered_map<uint64_t, int64_t>>
+ graphics_frame_stats_map_;
+
+ // Maps of buffer id -> track id
+ std::unordered_map<uint32_t, TrackId> dequeue_map_;
+ std::unordered_map<uint32_t, TrackId> queue_map_;
+ std::unordered_map<uint32_t, TrackId> latch_map_;
+ // Map of layer name -> track id
+ std::unordered_map<StringId, TrackId> display_map_;
+
+ // Maps of buffer id -> timestamp
+ std::unordered_map<uint32_t, int64_t> last_dequeued_;
+ std::unordered_map<uint32_t, int64_t> last_acquired_;
+};
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_GRAPHICS_FRAME_EVENT_PARSER_H_
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index 6846bd5..290de0d 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -593,14 +593,6 @@
return &graphics_frame_slice_table_;
}
- const tables::GraphicsFrameStatsTable& graphics_frame_stats_table() const {
- return graphics_frame_stats_table_;
- }
-
- tables::GraphicsFrameStatsTable* mutable_graphics_frame_stats_table() {
- return &graphics_frame_stats_table_;
- }
-
const StringPool& string_pool() const { return string_pool_; }
StringPool* mutable_string_pool() { return &string_pool_; }
@@ -815,8 +807,6 @@
tables::GraphicsFrameSliceTable graphics_frame_slice_table_{&string_pool_,
&slice_table_};
- tables::GraphicsFrameStatsTable graphics_frame_stats_table_{&string_pool_,
- nullptr};
// The below array allow us to map between enums and their string
// representations.
diff --git a/src/trace_processor/tables/slice_tables.h b/src/trace_processor/tables/slice_tables.h
index 49eaaf1..c347dcb 100644
--- a/src/trace_processor/tables/slice_tables.h
+++ b/src/trace_processor/tables/slice_tables.h
@@ -91,23 +91,13 @@
#define PERFETTO_TP_GRAPHICS_FRAME_SLICES_DEF(NAME, PARENT, C) \
NAME(GraphicsFrameSliceTable, "frame_slice") \
PARENT(PERFETTO_TP_SLICE_TABLE_DEF, C) \
- C(StringPool::Id, frame_numbers) \
- C(StringPool::Id, layer_names)
-
-PERFETTO_TP_TABLE(PERFETTO_TP_GRAPHICS_FRAME_SLICES_DEF);
-
-// frame_slice -> frame_stats : 1 -> Many,
-// with frame_slice.id = frame_stats.slice_id
-// @tablegroup Events
-#define PERFETTO_TP_GRAPHICS_FRAME_STATS_DEF(NAME, PARENT, C) \
- NAME(GraphicsFrameStatsTable, "frame_stats") \
- PERFETTO_TP_ROOT_TABLE(PARENT, C) \
- C(uint32_t, slice_id) \
- C(int64_t, queue_to_acquire_time) \
- C(int64_t, acquire_to_latch_time) \
+ C(uint32_t, frame_number) \
+ C(StringPool::Id, layer_name) \
+ C(int64_t, queue_to_acquire_time) \
+ C(int64_t, acquire_to_latch_time) \
C(int64_t, latch_to_present_time)
-PERFETTO_TP_TABLE(PERFETTO_TP_GRAPHICS_FRAME_STATS_DEF);
+PERFETTO_TP_TABLE(PERFETTO_TP_GRAPHICS_FRAME_SLICES_DEF);
#define PERFETTO_TP_DESCRIBE_SLICE_TABLE(NAME, PARENT, C) \
NAME(DescribeSliceTable, "describe_slice") \
diff --git a/src/trace_processor/tables/table_destructors.cc b/src/trace_processor/tables/table_destructors.cc
index 1f15028..859be5d 100644
--- a/src/trace_processor/tables/table_destructors.cc
+++ b/src/trace_processor/tables/table_destructors.cc
@@ -66,7 +66,6 @@
SchedSliceTable::~SchedSliceTable() = default;
GpuSliceTable::~GpuSliceTable() = default;
GraphicsFrameSliceTable::~GraphicsFrameSliceTable() = default;
-GraphicsFrameStatsTable::~GraphicsFrameStatsTable() = default;
DescribeSliceTable::~DescribeSliceTable() = default;
// track_tables.h
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index ea0764c..db4f201 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -617,7 +617,6 @@
RegisterDbTable(storage->vulkan_memory_allocations_table());
RegisterDbTable(storage->graphics_frame_slice_table());
- RegisterDbTable(storage->graphics_frame_stats_table());
RegisterDbTable(storage->metadata_table());
RegisterDbTable(storage->cpu_table());
diff --git a/test/trace_processor/graphics_frame_events.out b/test/trace_processor/graphics_frame_events.out
index 7c1d441..8aca540 100644
--- a/test/trace_processor/graphics_frame_events.out
+++ b/test/trace_processor/graphics_frame_events.out
@@ -1,20 +1,21 @@
-"ts","track_name","dur","slice_name","frame_numbers","layer_names"
-1,"layer1[buffer:1]",6,"Dequeue","11","layer1"
-2,"layer1[buffer:1]",7,"Queue","11","layer1"
-3,"layer1[buffer:1]",8,"Post","11","layer1"
-4,"layer1[buffer:1]",9,"AcquireFenceSignaled","11","layer1"
-5,"layer1[buffer:1]",10,"Latch","11","layer1"
-6,"layer1[buffer:1]",0,"PresentFenceSignaled","11","layer1"
-6,"layer2[buffer:2]",5,"Dequeue","12","layer2"
-6,"Displayed Frame",10,"1, 5","11, 10","layer1, layer5"
-6,"layer5[buffer:5]",0,"PresentFenceSignaled","10","layer5"
-6,"layer1[buffer:2]",11,"Dequeue","12","layer1"
-7,"layer2[buffer:2]",0,"Queue","12","layer2"
-7,"layer2[buffer:2]",12,"Queue","12","layer2"
-7,"layer7[buffer:7]",12,"unknown_event","13","layer7"
-8,"layer2[buffer:2]",2,"Detach","14","layer2"
-8,"layer3[buffer:2]",13,"Post","12","layer3"
-9,"layer3[buffer:3]",5,"Attach","15","layer3"
-10,"layer3[buffer:3]",10,"Cancel","16","layer3"
-16,"Displayed Frame",-1,"6","[NULL]","[NULL]"
-16,"layer5[buffer:6]",0,"PresentFenceSignaled","17","layer5"
+"ts","track_name","dur","slice_name","frame_number","layer_name"
+1,"Buffer: 1",0,"Dequeue",11,"layer1"
+1,"APP_1",3,"11",11,"layer1"
+4,"Buffer: 1",0,"Queue",11,"layer1"
+4,"GPU_1",2,"11",11,"layer1"
+6,"Buffer: 1",0,"AcquireFenceSignaled",11,"layer1"
+6,"Buffer: 2",0,"Dequeue",12,"layer2"
+6,"APP_2",3,"12",12,"layer2"
+7,"Buffer: 7",0,"unknown_event",15,"layer7"
+8,"Buffer: 1",0,"Latch",11,"layer1"
+8,"Buffer: 2",0,"AcquireFenceSignaled",12,"layer2"
+8,"SF_1",6,"11",11,"layer1"
+9,"Buffer: 2",0,"Queue",12,"layer2"
+11,"Buffer: 2",0,"Latch",12,"layer2"
+11,"SF_2",5,"12",12,"layer2"
+14,"Buffer: 1",0,"PresentFenceSignaled",11,"layer1"
+14,"Display_layer1",10,"11",11,"layer1"
+16,"Buffer: 2",0,"PresentFenceSignaled",12,"layer2"
+16,"Display_layer2",-1,"12",12,"layer2"
+24,"Buffer: 1",0,"PresentFenceSignaled",13,"layer1"
+24,"Display_layer1",-1,"13",13,"layer1"
diff --git a/test/trace_processor/graphics_frame_events.py b/test/trace_processor/graphics_frame_events.py
index 64c0606..beaf23a 100755
--- a/test/trace_processor/graphics_frame_events.py
+++ b/test/trace_processor/graphics_frame_events.py
@@ -34,26 +34,22 @@
CANCEL = 13
trace = synth_common.create_trace()
-trace.add_buffer_event_packet(ts=1, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.DEQUEUE, duration=6)
-trace.add_buffer_event_packet(ts=2, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.QUEUE, duration=7)
-trace.add_buffer_event_packet(ts=3, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.POST, duration=8)
-trace.add_buffer_event_packet(ts=4, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.ACQUIRE_FENCE, duration=9)
-trace.add_buffer_event_packet(ts=5, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.LATCH, duration=10)
-trace.add_buffer_event_packet(ts=6, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.DEQUEUE, duration=5)
-trace.add_buffer_event_packet(ts=6, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.PRESENT_FENCE, duration=0)
-trace.add_buffer_event_packet(ts=7, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.QUEUE, duration=0)
-trace.add_buffer_event_packet(ts=6, buffer_id=5, layer_name="layer5", frame_number=10, event_type=BufferEvent.PRESENT_FENCE, duration=0)
-trace.add_buffer_event_packet(ts=16, buffer_id=6, layer_name="layer5", frame_number=17, event_type=BufferEvent.PRESENT_FENCE, duration=0)
-# Repeat some layers
-trace.add_buffer_event_packet(ts=6, buffer_id=2, layer_name="layer1", frame_number=12, event_type=BufferEvent.DEQUEUE, duration=11)
-trace.add_buffer_event_packet(ts=7, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.QUEUE, duration=12)
-trace.add_buffer_event_packet(ts=8, buffer_id=2, layer_name="layer3", frame_number=12, event_type=BufferEvent.POST, duration=13)
+# Layer 1
+trace.add_buffer_event_packet(ts=1, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.DEQUEUE, duration=0)
+trace.add_buffer_event_packet(ts=4, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.QUEUE, duration=0)
+trace.add_buffer_event_packet(ts=6, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.ACQUIRE_FENCE, duration=0)
+trace.add_buffer_event_packet(ts=8, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.LATCH, duration=0)
+trace.add_buffer_event_packet(ts=14, buffer_id=1, layer_name="layer1", frame_number=11, event_type=BufferEvent.PRESENT_FENCE, duration=0)
+# Layer 2
+trace.add_buffer_event_packet(ts=6, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.DEQUEUE, duration=0)
+trace.add_buffer_event_packet(ts=8, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.ACQUIRE_FENCE, duration=0)
+trace.add_buffer_event_packet(ts=9, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.QUEUE, duration=0)
+trace.add_buffer_event_packet(ts=11, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.LATCH, duration=0)
+trace.add_buffer_event_packet(ts=16, buffer_id=2, layer_name="layer2", frame_number=12, event_type=BufferEvent.PRESENT_FENCE, duration=0)
+# Next Present of layer 1
+trace.add_buffer_event_packet(ts=24, buffer_id=1, layer_name="layer1", frame_number=13, event_type=BufferEvent.PRESENT_FENCE, duration=0)
# Missing id.
-trace.add_buffer_event_packet(ts=6, buffer_id=-1, layer_name="layer6", frame_number=13, event_type=BufferEvent.HWC_COMPOSITION_QUEUED, duration=11)
+trace.add_buffer_event_packet(ts=6, buffer_id=-1, layer_name="layer6", frame_number=14, event_type=BufferEvent.HWC_COMPOSITION_QUEUED, duration=0)
# Missing type.
-trace.add_buffer_event_packet(ts=7, buffer_id=7, layer_name="layer7", frame_number=13, event_type=-1, duration=12)
-# Add some more events
-trace.add_buffer_event_packet(ts=8, buffer_id=2, layer_name="layer2", frame_number=14, event_type=BufferEvent.DETACH, duration=2)
-trace.add_buffer_event_packet(ts=9, buffer_id=3, layer_name="layer3", frame_number=15, event_type=BufferEvent.ATTACH, duration=5)
-trace.add_buffer_event_packet(ts=10, buffer_id=3, layer_name="layer3", frame_number=16, event_type=BufferEvent.CANCEL, duration=10)
+trace.add_buffer_event_packet(ts=7, buffer_id=7, layer_name="layer7", frame_number=15, event_type=-1, duration=0)
print(trace.trace.SerializeToString())
diff --git a/test/trace_processor/graphics_frame_events.sql b/test/trace_processor/graphics_frame_events.sql
index dea74e8..3e42f53 100644
--- a/test/trace_processor/graphics_frame_events.sql
+++ b/test/trace_processor/graphics_frame_events.sql
@@ -14,7 +14,7 @@
-- limitations under the License.
--
select ts, gpu_track.name as track_name, dur, frame_slice.name as slice_name,
- frame_numbers, layer_names
+ frame_number, layer_name
from gpu_track
left join frame_slice on gpu_track.id=frame_slice.track_id
where scope='graphics_frame_event'