Merge "traced: prefer /run/perfetto for producer and consumer sockets on Linux"
diff --git a/src/trace_processor/importers/proto/graphics_frame_event_parser.cc b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
index e33ed9c..35e27f9 100644
--- a/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_frame_event_parser.cc
@@ -161,6 +161,31 @@
return true;
}
+void GraphicsFrameEventParser::InvalidatePhaseEvent(int64_t timestamp,
+ TrackId track_id,
+ bool reset_name) {
+ const auto opt_slice_id =
+ context_->slice_tracker->EndFrameEvent(timestamp, track_id);
+
+ if (opt_slice_id) {
+ 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);
+ if (reset_name) {
+ // Set the name (frame_number) to be 0 since there is no frame number
+ // associated, example : dequeue event.
+ StringId frame_name_id = context_->storage->InternString("0");
+ graphics_frame_slice_table->mutable_name()->Set(row_idx, frame_name_id);
+ graphics_frame_slice_table->mutable_frame_number()->Set(row_idx, 0);
+ }
+
+ // Set the duration to -1 so that this slice will be ignored by the
+ // UI. Setting any other duration results in wrong data which we want
+ // to avoid at all costs.
+ graphics_frame_slice_table->mutable_dur()->Set(row_idx, -1);
+ }
+}
+
// Here we convert the buffer events into Phases(slices)
// APP: Dequeue to Queue
// Wait for GPU: Queue to Acquire
@@ -200,16 +225,29 @@
tables::GpuTrackTable::Row app_track(track_name_id);
app_track.scope = graphics_event_scope_id_;
track_id = context_->track_tracker->InternGpuTrack(app_track);
+
+ // Error handling
+ auto dequeue_time = dequeue_map_.find(buffer_id);
+ if (dequeue_time != dequeue_map_.end()) {
+ InvalidatePhaseEvent(timestamp, dequeue_time->second, true);
+ dequeue_map_.erase(dequeue_time);
+ }
+ auto queue_time = queue_map_.find(buffer_id);
+ if (queue_time != queue_map_.end()) {
+ InvalidatePhaseEvent(timestamp, queue_time->second);
+ queue_map_.erase(queue_time);
+ }
+
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()) {
+ auto dequeue_time = dequeue_map_.find(buffer_id);
+ if (dequeue_time != dequeue_map_.end()) {
const auto opt_slice_id = context_->slice_tracker->EndFrameEvent(
- timestamp, dequeueTime->second);
+ timestamp, dequeue_time->second);
slice_name.reset();
slice_name.AppendUnsignedInt(frame_number);
if (opt_slice_id) {
@@ -225,7 +263,7 @@
frame_name_id);
graphics_frame_slice_table->mutable_frame_number()->Set(row_idx,
frame_number);
- dequeue_map_.erase(dequeueTime);
+ dequeue_map_.erase(dequeue_time);
}
}
// The AcquireFence might be signaled before receiving a QUEUE event
@@ -247,10 +285,10 @@
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);
+ auto queue_time = queue_map_.find(buffer_id);
+ if (queue_time != queue_map_.end()) {
+ context_->slice_tracker->EndFrameEvent(timestamp, queue_time->second);
+ queue_map_.erase(queue_time);
}
last_acquired_[buffer_id] = timestamp;
start_slice = false;
@@ -259,31 +297,10 @@
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);
- }
+ auto dequeue_time = dequeue_map_.find(buffer_id);
+ if (dequeue_time != dequeue_map_.end()) {
+ InvalidatePhaseEvent(timestamp, dequeue_time->second, true);
+ dequeue_map_.erase(dequeue_time);
}
track_name.reset();
track_name.AppendLiteral("SF_");
@@ -298,15 +315,15 @@
}
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 latch_time = latch_map_.find(buffer_id);
+ if (latch_time != latch_map_.end()) {
+ context_->slice_tracker->EndFrameEvent(timestamp, latch_time->second);
+ latch_map_.erase(latch_time);
}
- auto displayTime = display_map_.find(layer_name_id);
- if (displayTime != display_map_.end()) {
- context_->slice_tracker->EndFrameEvent(timestamp, displayTime->second);
- display_map_.erase(displayTime);
+ auto display_time = display_map_.find(layer_name_id);
+ if (display_time != display_map_.end()) {
+ context_->slice_tracker->EndFrameEvent(timestamp, display_time->second);
+ display_map_.erase(display_time);
}
base::StringView layerName(event.layer_name());
track_name.reset();
diff --git a/src/trace_processor/importers/proto/graphics_frame_event_parser.h b/src/trace_processor/importers/proto/graphics_frame_event_parser.h
index e23fa73..b375c6c 100644
--- a/src/trace_processor/importers/proto/graphics_frame_event_parser.h
+++ b/src/trace_processor/importers/proto/graphics_frame_event_parser.h
@@ -49,6 +49,10 @@
using GraphicsFrameEvent = protos::pbzero::GraphicsFrameEvent;
bool CreateBufferEvent(int64_t timestamp, GraphicsFrameEventDecoder& event);
void CreatePhaseEvent(int64_t timestamp, GraphicsFrameEventDecoder& event);
+ // Invalidate a phase slice that has one of the events missing
+ void InvalidatePhaseEvent(int64_t timestamp,
+ TrackId track_id,
+ bool reset_name = false);
TraceProcessorContext* const context_;
const StringId graphics_event_scope_id_;
diff --git a/test/trace_processor/graphics/graphics_frame_events.out b/test/trace_processor/graphics/graphics_frame_events.out
index 8aca540..59dce99 100644
--- a/test/trace_processor/graphics/graphics_frame_events.out
+++ b/test/trace_processor/graphics/graphics_frame_events.out
@@ -19,3 +19,24 @@
16,"Display_layer2",-1,"12",12,"layer2"
24,"Buffer: 1",0,"PresentFenceSignaled",13,"layer1"
24,"Display_layer1",-1,"13",13,"layer1"
+31,"Buffer: 1",0,"Dequeue",21,"layer1"
+31,"APP_1",3,"21",21,"layer1"
+34,"Buffer: 1",0,"Queue",21,"layer1"
+34,"GPU_1",-1,"21",21,"layer1"
+37,"Buffer: 1",0,"Dequeue",22,"layer1"
+37,"APP_1",4,"22",22,"layer1"
+41,"Buffer: 1",0,"Queue",22,"layer1"
+41,"GPU_1",5,"22",22,"layer1"
+46,"Buffer: 1",0,"AcquireFenceSignaled",22,"layer1"
+53,"Buffer: 2",0,"Dequeue",24,"layer2"
+53,"APP_2",-1,"0",0,"layer2"
+59,"Buffer: 2",0,"AcquireFenceSignaled",24,"layer2"
+61,"Buffer: 2",0,"Latch",24,"layer2"
+61,"SF_2",-1,"24",24,"layer2"
+63,"Buffer: 1",0,"Dequeue",25,"layer1"
+63,"APP_1",-1,"0",0,"layer1"
+73,"Buffer: 1",0,"Dequeue",26,"layer1"
+73,"APP_1",2,"26",26,"layer1"
+75,"Buffer: 1",0,"Queue",26,"layer1"
+75,"GPU_1",4,"26",26,"layer1"
+79,"Buffer: 1",0,"AcquireFenceSignaled",26,"layer1"
diff --git a/test/trace_processor/graphics/graphics_frame_events.py b/test/trace_processor/graphics/graphics_frame_events.py
index 2366ad2..bf28f1f 100755
--- a/test/trace_processor/graphics/graphics_frame_events.py
+++ b/test/trace_processor/graphics/graphics_frame_events.py
@@ -52,4 +52,19 @@
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=15, event_type=-1, duration=0)
+# Missing Acquire
+trace.add_buffer_event_packet(ts=31, buffer_id=1, layer_name="layer1", frame_number=21, event_type=BufferEvent.DEQUEUE, duration=0)
+trace.add_buffer_event_packet(ts=34, buffer_id=1, layer_name="layer1", frame_number=21, event_type=BufferEvent.QUEUE, duration=0)
+trace.add_buffer_event_packet(ts=37, buffer_id=1, layer_name="layer1", frame_number=22, event_type=BufferEvent.DEQUEUE, duration=0)
+trace.add_buffer_event_packet(ts=41, buffer_id=1, layer_name="layer1", frame_number=22, event_type=BufferEvent.QUEUE, duration=0)
+trace.add_buffer_event_packet(ts=46, buffer_id=1, layer_name="layer1", frame_number=22, event_type=BufferEvent.ACQUIRE_FENCE, duration=0)
+# Missing queue with acquire
+trace.add_buffer_event_packet(ts=53, buffer_id=2, layer_name="layer2", frame_number=24, event_type=BufferEvent.DEQUEUE, duration=0)
+trace.add_buffer_event_packet(ts=59, buffer_id=2, layer_name="layer2", frame_number=24, event_type=BufferEvent.ACQUIRE_FENCE, duration=0)
+trace.add_buffer_event_packet(ts=61, buffer_id=2, layer_name="layer2", frame_number=24, event_type=BufferEvent.LATCH, duration=0)
+# Missing queue without acquire
+trace.add_buffer_event_packet(ts=63, buffer_id=1, layer_name="layer1", frame_number=25, event_type=BufferEvent.DEQUEUE, duration=0)
+trace.add_buffer_event_packet(ts=73, buffer_id=1, layer_name="layer1", frame_number=26, event_type=BufferEvent.DEQUEUE, duration=0)
+trace.add_buffer_event_packet(ts=75, buffer_id=1, layer_name="layer1", frame_number=26, event_type=BufferEvent.QUEUE, duration=0)
+trace.add_buffer_event_packet(ts=79, buffer_id=1, layer_name="layer1", frame_number=26, event_type=BufferEvent.ACQUIRE_FENCE, duration=0)
sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/ui/src/common/actions.ts b/ui/src/common/actions.ts
index 6f9a095..7a590ef 100644
--- a/ui/src/common/actions.ts
+++ b/ui/src/common/actions.ts
@@ -479,7 +479,8 @@
this.selectNote(state, {id});
},
- markArea(state: StateDraft, args: {color: string, persistent: boolean}):
+ markCurrentArea(
+ state: StateDraft, args: {color: string, persistent: boolean}):
void {
if (state.currentSelection === null ||
state.currentSelection.kind !== 'AREA') {
@@ -497,17 +498,36 @@
state.currentSelection.noteId = id;
},
- toggleMarkArea(state: StateDraft, args: {persistent: boolean}) {
+ toggleMarkCurrentArea(state: StateDraft, args: {persistent: boolean}) {
const selection = state.currentSelection;
if (selection != null && selection.kind === 'AREA' &&
selection.noteId !== undefined) {
this.removeNote(state, {id: selection.noteId});
} else {
const color = randomColor();
- this.markArea(state, {color, persistent: args.persistent});
+ this.markCurrentArea(state, {color, persistent: args.persistent});
}
},
+ markArea(state: StateDraft, args: {area: Area, persistent: boolean}): void {
+ const areaId = `${state.nextAreaId++}`;
+ state.areas[areaId] = {
+ id: areaId,
+ startSec: args.area.startSec,
+ endSec: args.area.endSec,
+ tracks: args.area.tracks
+ };
+ const id = args.persistent ? `${state.nextNoteId++}` : '0';
+ const color = args.persistent ? randomColor() : '#344596';
+ state.notes[id] = {
+ noteType: 'AREA',
+ id,
+ areaId,
+ color,
+ text: '',
+ };
+ },
+
toggleVideo(state: StateDraft, _: {}): void {
state.videoEnabled = !state.videoEnabled;
if (!state.videoEnabled) {
@@ -601,11 +621,6 @@
ts: args.ts,
type: args.type,
};
- },
-
- showHeapProfileFlamegraph(
- state: StateDraft,
- args: {id: number, upid: number, ts: number, type: string}): void {
state.currentHeapProfileFlamegraph = {
kind: 'HEAP_PROFILE_FLAMEGRAPH',
id: args.id,
diff --git a/ui/src/controller/trace_controller.ts b/ui/src/controller/trace_controller.ts
index cc8a5a1..6c2fc02 100644
--- a/ui/src/controller/trace_controller.ts
+++ b/ui/src/controller/trace_controller.ts
@@ -308,9 +308,26 @@
await this.listThreads();
await this.loadTimelineOverview(traceTime);
globals.dispatch(Actions.sortThreadTracks({}));
+ await this.selectFirstHeapProfile();
+
return engineMode;
}
+ private async selectFirstHeapProfile() {
+ const query = `select * from
+ (select distinct(ts) as ts, 'native' as type,
+ upid from heap_profile_allocation
+ union
+ select distinct(graph_sample_ts) as ts, 'graph' as type, upid from
+ heap_graph_object) order by ts limit 1`;
+ const profile = await assertExists(this.engine).query(query);
+ if (profile.numRecords !== 1) return;
+ const ts = profile.columns[0].longValues![0];
+ const type = profile.columns[1].stringValues![0];
+ const upid = profile.columns[2].longValues![0];
+ globals.dispatch(Actions.selectHeapProfile({id: 0, upid, ts, type}));
+ }
+
private async listTracks() {
this.updateStatus('Loading tracks');
const engine = assertExists<Engine>(this.engine);
diff --git a/ui/src/frontend/keyboard_event_handler.ts b/ui/src/frontend/keyboard_event_handler.ts
index c3bb829..064994d 100644
--- a/ui/src/frontend/keyboard_event_handler.ts
+++ b/ui/src/frontend/keyboard_event_handler.ts
@@ -33,7 +33,7 @@
const selection = globals.state.currentSelection;
if (down && 'm' === key) {
if (selection && selection.kind === 'AREA') {
- globals.dispatch(Actions.toggleMarkArea({persistent: e.shiftKey}));
+ globals.dispatch(Actions.toggleMarkCurrentArea({persistent: e.shiftKey}));
} else if (selection) {
lockSliceSpan(e.shiftKey);
}
@@ -198,8 +198,7 @@
[globals.state.currentSelection.trackId] :
[];
const area: Area = {startSec: range.startTs, endSec: range.endTs, tracks};
- globals.makeSelection(Actions.selectArea({area}));
- globals.dispatch(Actions.toggleMarkArea({persistent}));
+ globals.dispatch(Actions.markArea({area, persistent}));
}
}
diff --git a/ui/src/tracks/heap_profile/frontend.ts b/ui/src/tracks/heap_profile/frontend.ts
index 8852b35..c9c7466 100644
--- a/ui/src/tracks/heap_profile/frontend.ts
+++ b/ui/src/tracks/heap_profile/frontend.ts
@@ -118,8 +118,6 @@
if (index !== -1) {
const ts = data.tsStarts[index];
const type = data.types[index];
- globals.dispatch(Actions.showHeapProfileFlamegraph(
- {id: index, upid: this.config.upid, ts, type}));
globals.makeSelection(Actions.selectHeapProfile(
{id: index, upid: this.config.upid, ts, type}));
return true;