Merge "Add gpu_track_tracker to prevent repeated GPU tracks"
diff --git a/src/trace_processor/graphics_event_parser.cc b/src/trace_processor/graphics_event_parser.cc
index 3ce7fdf..6044d2f 100644
--- a/src/trace_processor/graphics_event_parser.cc
+++ b/src/trace_processor/graphics_event_parser.cc
@@ -35,6 +35,8 @@
 
 GraphicsEventParser::GraphicsEventParser(TraceProcessorContext* context)
     : context_(context),
+      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")),
@@ -152,9 +154,11 @@
       protos::pbzero::GpuRenderStageEvent_Specifications_Description::Decoder
           hw_queue(it->data(), it->size());
       if (hw_queue.has_name()) {
-        // TODO: create vtrack for each HW queue when it's ready.
+        StringId track_name = context_->storage->InternString(hw_queue.name());
+        tables::GpuTrackTable::Row track(track_name.id);
+        track.scope = gpu_render_stage_scope_id_;
         gpu_hw_queue_ids_.emplace_back(
-            context_->storage->InternString(hw_queue.name()));
+            context_->track_tracker->InternGpuTrack(track));
       }
     }
     for (auto it = spec.stage(); it; ++it) {
@@ -189,8 +193,9 @@
       stage_name = context_->storage->InternString(buffer);
     }
     const auto slice_id = context_->slice_tracker->Scoped(
-        ts, event.hw_queue_id(), RefType::kRefGpuId, 0, /* cat */
-        stage_name, static_cast<int64_t>(event.duration()), args_callback);
+        ts, gpu_hw_queue_ids_[static_cast<size_t>(event.hw_queue_id())],
+        RefType::kRefTrack, 0 /* cat */, stage_name,
+        static_cast<int64_t>(event.duration()), args_callback);
 
     context_->storage->mutable_gpu_slice_table()->Insert(
         tables::GpuSliceTable::Row(
diff --git a/src/trace_processor/graphics_event_parser.h b/src/trace_processor/graphics_event_parser.h
index 7b28962..22479ae 100644
--- a/src/trace_processor/graphics_event_parser.h
+++ b/src/trace_processor/graphics_event_parser.h
@@ -44,7 +44,8 @@
   std::unordered_map<uint32_t, const TraceStorage::CounterDefinitions::Id>
       gpu_counter_ids_;
   // For GpuRenderStageEvent
-  std::vector<StringId> gpu_hw_queue_ids_;
+  const StringId gpu_render_stage_scope_id_;
+  std::vector<TrackId> gpu_hw_queue_ids_;
   std::vector<StringId> gpu_render_stage_ids_;
   // For GraphicsFrameEvent
   const StringId graphics_event_scope_id_;
diff --git a/src/trace_processor/track_tracker.cc b/src/trace_processor/track_tracker.cc
index cc0792e..38e6f0e 100644
--- a/src/trace_processor/track_tracker.cc
+++ b/src/trace_processor/track_tracker.cc
@@ -36,7 +36,7 @@
 }
 
 TrackId TrackTracker::InternGpuTrack(const tables::GpuTrackTable::Row& row) {
-  GpuTrackTuple tuple{row.name.id, row.scope};
+  GpuTrackTuple tuple{row.name.id, row.scope, row.context_id.value_or(0)};
 
   auto it = gpu_tracks_.find(tuple);
   if (it != gpu_tracks_.end())
diff --git a/src/trace_processor/track_tracker.h b/src/trace_processor/track_tracker.h
index 285b87c..6dd3872 100644
--- a/src/trace_processor/track_tracker.h
+++ b/src/trace_processor/track_tracker.h
@@ -51,9 +51,11 @@
   struct GpuTrackTuple {
     StringId track_name;
     StringId scope;
+    int64_t context_id;
 
     friend bool operator<(const GpuTrackTuple& l, const GpuTrackTuple& r) {
-      return std::tie(l.track_name, l.scope) < std::tie(r.track_name, r.scope);
+      return std::tie(l.track_name, l.scope, l.context_id)
+          < std::tie(r.track_name, r.scope, r.context_id);
     }
   };
   struct ChromeTrackTuple {
diff --git a/test/trace_processor/gpu_render_stages.out b/test/trace_processor/gpu_render_stages.out
index ab28793..4eaa783 100644
--- a/test/trace_processor/gpu_render_stages.out
+++ b/test/trace_processor/gpu_render_stages.out
@@ -1,19 +1,19 @@
-"ts","dur","ref","ref_type","name","depth","arg_set_id","flat_key","string_value","context_id","render_target","submission_id","hw_queue_id"
-10,5,1,"gpu","stage 1",0,1,"keyOnlyTest","[NULL]",42,0,0,1
-10,5,1,"gpu","stage 1",0,1,"stencilBPP","1",42,0,0,1
-10,5,1,"gpu","stage 1",0,1,"height","1.000000",42,0,0,1
-20,5,0,"gpu","stage 2",0,2,"keyOnlyTest","[NULL]",42,0,0,0
-20,5,0,"gpu","stage 2",0,2,"height","4.000000",42,0,0,0
-30,5,1,"gpu","stage 0",0,3,"keyOnlyTest","[NULL]",42,0,0,1
-30,5,1,"gpu","stage 0",0,3,"stencilBPP","1",42,0,0,1
-30,5,1,"gpu","stage 0",0,3,"height","9.000000",42,0,0,1
-40,5,0,"gpu","stage 1",0,0,"[NULL]","[NULL]",42,0,0,0
-50,5,1,"gpu","stage 2",0,4,"keyOnlyTest","[NULL]",42,0,0,1
-50,5,1,"gpu","stage 2",0,4,"stencilBPP","1",42,0,0,1
-50,5,1,"gpu","stage 2",0,4,"height","25.000000",42,0,0,1
-60,5,0,"gpu","stage 0",0,5,"keyOnlyTest","[NULL]",42,0,0,0
-60,5,0,"gpu","stage 0",0,5,"height","36.000000",42,0,0,0
-70,5,1,"gpu","stage 1",0,6,"keyOnlyTest","[NULL]",42,0,0,1
-70,5,1,"gpu","stage 1",0,6,"stencilBPP","1",42,0,0,1
-70,5,1,"gpu","stage 1",0,6,"height","49.000000",42,0,0,1
-80,5,0,"gpu","stage 2",0,0,"[NULL]","[NULL]",42,0,0,0
+"track_name","ts","dur","slice_name","depth","arg_set_id","flat_key","string_value","context_id","render_target","submission_id","hw_queue_id"
+"queue 1",10,5,"stage 1",0,1,"keyOnlyTest","[NULL]",42,0,0,1
+"queue 1",10,5,"stage 1",0,1,"stencilBPP","1",42,0,0,1
+"queue 1",10,5,"stage 1",0,1,"height","1.000000",42,0,0,1
+"queue 0",20,5,"stage 2",0,2,"keyOnlyTest","[NULL]",42,0,0,0
+"queue 0",20,5,"stage 2",0,2,"height","4.000000",42,0,0,0
+"queue 1",30,5,"stage 0",0,3,"keyOnlyTest","[NULL]",42,0,0,1
+"queue 1",30,5,"stage 0",0,3,"stencilBPP","1",42,0,0,1
+"queue 1",30,5,"stage 0",0,3,"height","9.000000",42,0,0,1
+"queue 0",40,5,"stage 1",0,0,"[NULL]","[NULL]",42,0,0,0
+"queue 1",50,5,"stage 2",0,4,"keyOnlyTest","[NULL]",42,0,0,1
+"queue 1",50,5,"stage 2",0,4,"stencilBPP","1",42,0,0,1
+"queue 1",50,5,"stage 2",0,4,"height","25.000000",42,0,0,1
+"queue 0",60,5,"stage 0",0,5,"keyOnlyTest","[NULL]",42,0,0,0
+"queue 0",60,5,"stage 0",0,5,"height","36.000000",42,0,0,0
+"queue 1",70,5,"stage 1",0,6,"keyOnlyTest","[NULL]",42,0,0,1
+"queue 1",70,5,"stage 1",0,6,"stencilBPP","1",42,0,0,1
+"queue 1",70,5,"stage 1",0,6,"height","49.000000",42,0,0,1
+"queue 0",80,5,"stage 2",0,0,"[NULL]","[NULL]",42,0,0,0
diff --git a/test/trace_processor/gpu_render_stages.sql b/test/trace_processor/gpu_render_stages.sql
index e08025b..151ba68 100644
--- a/test/trace_processor/gpu_render_stages.sql
+++ b/test/trace_processor/gpu_render_stages.sql
@@ -1,5 +1,9 @@
-SELECT "ts","dur","ref","ref_type","name","depth", internal_slice.arg_set_id, "flat_key",
-       "string_value", "context_id", "render_target", "submission_id", "hw_queue_id" FROM internal_slice
+SELECT track.name AS track_name, ts,dur, slice.name AS slice_name,
+    depth, slice.arg_set_id, flat_key, string_value, gpu_slice.context_id,
+    render_target, submission_id, hw_queue_id
+FROM gpu_track
+LEFT JOIN track USING (id)
+LEFT JOIN slice ON gpu_track.id=slice.ref
 INNER JOIN gpu_slice USING(slice_id)
-LEFT JOIN args ON internal_slice.arg_set_id = args.arg_set_id
-ORDER BY "ts";
+LEFT JOIN args ON slice.arg_set_id = args.arg_set_id
+ORDER BY ts;
diff --git a/test/trace_processor/graphics_frame_events.out b/test/trace_processor/graphics_frame_events.out
index 96db1e5..fdef2eb 100644
--- a/test/trace_processor/graphics_frame_events.out
+++ b/test/trace_processor/graphics_frame_events.out
@@ -1,7 +1,10 @@
-"ts","dur","name","key","frame_id","layer_name"
-1,6,"Dequeue","layer_name",1,"layerName1"
-2,7,"Queue","layer_name",2,"layerName2"
-3,8,"Post","layer_name",3,"layerName3"
-4,9,"AcquireFenceSignaled","layer_name",4,"layerName4"
-5,10,"Latch","layer_name",5,"layerName5"
-7,12,"unknown_event","layer_name",7,"layerName7"
+"scope","track_name","ts","dur","slice_name","frame_id","key","layer_name"
+"graphics_frame_event","layer1[buffer:1]",1,6,"Dequeue",11,"layer_name","layer1"
+"graphics_frame_event","layer1[buffer:1]",6,11,"Dequeue",12,"layer_name","layer1"
+"graphics_frame_event","layer2[buffer:2]",2,7,"Queue",11,"layer_name","layer2"
+"graphics_frame_event","layer2[buffer:2]",7,12,"Queue",12,"layer_name","layer2"
+"graphics_frame_event","layer3[buffer:3]",3,8,"Post",11,"layer_name","layer3"
+"graphics_frame_event","layer3[buffer:3]",8,13,"Post",12,"layer_name","layer3"
+"graphics_frame_event","layer4[buffer:4]",4,9,"AcquireFenceSignaled",11,"layer_name","layer4"
+"graphics_frame_event","layer5[buffer:5]",5,10,"Latch",11,"layer_name","layer5"
+"graphics_frame_event","layer7[buffer:7]",7,12,"unknown_event",13,"layer_name","layer7"
diff --git a/test/trace_processor/graphics_frame_events.py b/test/trace_processor/graphics_frame_events.py
index 1c3ee94..3b9a171 100755
--- a/test/trace_processor/graphics_frame_events.py
+++ b/test/trace_processor/graphics_frame_events.py
@@ -18,14 +18,18 @@
 import synth_common
 
 trace = synth_common.create_trace()
-trace.add_buffer_event_packet(ts=1, buffer_id=1, layer_name="layerName1", frame_number=1, event_type=1, duration=6)
-trace.add_buffer_event_packet(ts=2, buffer_id=2, layer_name="layerName2", frame_number=2, event_type=2, duration=7)
-trace.add_buffer_event_packet(ts=3, buffer_id=3, layer_name="layerName3", frame_number=3, event_type=3, duration=8)
-trace.add_buffer_event_packet(ts=4, buffer_id=4, layer_name="layerName4", frame_number=4, event_type=4, duration=9)
-trace.add_buffer_event_packet(ts=5, buffer_id=5, layer_name="layerName5", frame_number=5, event_type=5, duration=10)
+trace.add_buffer_event_packet(ts=1, buffer_id=1, layer_name="layer1", frame_number=11, event_type=1, duration=6)
+trace.add_buffer_event_packet(ts=2, buffer_id=2, layer_name="layer2", frame_number=11, event_type=2, duration=7)
+trace.add_buffer_event_packet(ts=3, buffer_id=3, layer_name="layer3", frame_number=11, event_type=3, duration=8)
+trace.add_buffer_event_packet(ts=4, buffer_id=4, layer_name="layer4", frame_number=11, event_type=4, duration=9)
+trace.add_buffer_event_packet(ts=5, buffer_id=5, layer_name="layer5", frame_number=11, event_type=5, duration=10)
+# Repeat some layers
+trace.add_buffer_event_packet(ts=6, buffer_id=1, layer_name="layer1", frame_number=12, event_type=1, duration=11)
+trace.add_buffer_event_packet(ts=7, buffer_id=2, layer_name="layer2", frame_number=12, event_type=2, duration=12)
+trace.add_buffer_event_packet(ts=8, buffer_id=3, layer_name="layer3", frame_number=12, event_type=3, duration=13)
 # Missing id.
-trace.add_buffer_event_packet(ts=6, buffer_id=-1, layer_name="layerName6", frame_number=6, event_type=6, duration=11)
+trace.add_buffer_event_packet(ts=6, buffer_id=-1, layer_name="layer6", frame_number=13, event_type=6, duration=11)
 # Missing type.
-trace.add_buffer_event_packet(ts=7, buffer_id=7, layer_name="layerName7", frame_number=7, event_type=-1, duration=12)
+trace.add_buffer_event_packet(ts=7, buffer_id=7, layer_name="layer7", frame_number=13, event_type=-1, duration=12)
 
 print(trace.trace.SerializeToString())
diff --git a/test/trace_processor/graphics_frame_events.sql b/test/trace_processor/graphics_frame_events.sql
index 1730d10..87d8e36 100644
--- a/test/trace_processor/graphics_frame_events.sql
+++ b/test/trace_processor/graphics_frame_events.sql
@@ -1,5 +1,7 @@
-select ts, dur, name, key, frame_id, string_value as layer_name
-from internal_slice
-inner join gpu_slice using(slice_id)
-left join args
-on internal_slice.arg_set_id=args.arg_set_id and args.key='layer_name'
+select scope, track.name as track_name, ts, dur, slice.name as slice_name,
+    frame_id, key, string_value as layer_name
+from gpu_track
+left join track using (id)
+left join slice on gpu_track.id=slice.ref
+left join gpu_slice using(slice_id)
+left join args on slice.arg_set_id=args.arg_set_id and args.key='layer_name'