tracing: Distinguish between global and per-thread default track

Make it possible to use perfetto::Track::Global(0u) to signify the
default global track without actually emitting an event on the thread's
default track

Bug: crbug.com/1006541
Change-Id: I916a0ba025e992a2d91cf8b671fa8e472acb0ee5
diff --git a/include/perfetto/tracing/internal/track_event_data_source.h b/include/perfetto/tracing/internal/track_event_data_source.h
index 63d01d1..1bcdeb7 100644
--- a/include/perfetto/tracing/internal/track_event_data_source.h
+++ b/include/perfetto/tracing/internal/track_event_data_source.h
@@ -95,6 +95,9 @@
 
 }  // namespace
 
+// Represents the default track for the calling thread.
+static constexpr Track kDefaultTrack{};
+
 struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {
   using IncrementalStateType = TrackEventIncrementalState;
 
@@ -234,7 +237,7 @@
                                ArgumentFunction arg_function)
       PERFETTO_NO_INLINE {
     TraceForCategoryImpl<CategoryIndex>(
-        instances, dynamic_category, event_name, type, Track(),
+        instances, dynamic_category, event_name, type, kDefaultTrack,
         TrackEventInternal::GetTimeNs(), std::move(arg_function));
   }
 
@@ -257,7 +260,7 @@
                                ArgumentFunction arg_function)
       PERFETTO_NO_INLINE {
     TraceForCategoryImpl<CategoryIndex>(instances, dynamic_category, event_name,
-                                        type, Track(), timestamp,
+                                        type, kDefaultTrack, timestamp,
                                         std::move(arg_function));
   }
 
@@ -362,7 +365,7 @@
                                ArgType&& arg_value) PERFETTO_ALWAYS_INLINE {
     TraceForCategoryWithDebugAnnotations<CategoryIndex, CategoryType, Track,
                                          ArgType>(
-        instances, dynamic_category, event_name, type, Track(), arg_name,
+        instances, dynamic_category, event_name, type, kDefaultTrack, arg_name,
         std::forward<ArgType>(arg_value));
   }
 
@@ -424,7 +427,7 @@
                                ArgType2&& arg_value2) PERFETTO_ALWAYS_INLINE {
     TraceForCategoryWithDebugAnnotations<CategoryIndex, CategoryType, Track,
                                          ArgType, ArgType2>(
-        instances, dynamic_category, event_name, type, Track(), arg_name,
+        instances, dynamic_category, event_name, type, kDefaultTrack, arg_name,
         std::forward<ArgType>(arg_value), arg_name2,
         std::forward<ArgType2>(arg_value2));
   }
@@ -462,7 +465,7 @@
       const CategoryType& dynamic_category,
       const char* event_name,
       perfetto::protos::pbzero::TrackEvent::Type type,
-      TrackType track,
+      const TrackType& track,
       const char* arg_name,
       typename internal::DebugAnnotationArg<ArgType>::type arg_value,
       const char* arg_name2,
@@ -566,7 +569,7 @@
       const CategoryType& dynamic_category,
       const char* event_name,
       perfetto::protos::pbzero::TrackEvent::Type type,
-      const TrackType& track = Track(),
+      const TrackType& track = kDefaultTrack,
       TimestampType timestamp = TrackEventInternal::GetTimeNs(),
       ArgumentFunction arg_function = [](EventContext) {
       }) PERFETTO_ALWAYS_INLINE {
@@ -602,7 +605,7 @@
                     return true;
                   });
             }
-            if (track)
+            if (&track != &kDefaultTrack)
               event_ctx.event()->set_track_uuid(track.uuid);
             arg_function(std::move(event_ctx));
           }  // event_ctx
diff --git a/include/perfetto/tracing/track_event_legacy.h b/include/perfetto/tracing/track_event_legacy.h
index 7f4a31b..d138223 100644
--- a/include/perfetto/tracing/track_event_legacy.h
+++ b/include/perfetto/tracing/track_event_legacy.h
@@ -331,7 +331,7 @@
                                uint32_t flags,
                                Args&&... args) PERFETTO_NO_INLINE {
     AddDebugAnnotations(&ctx, std::forward<Args>(args)...);
-    SetTrackIfNeeded(&ctx, flags);
+    SetTrackIfNeeded(&ctx, phase, flags);
     if (NeedLegacyFlags(phase, flags)) {
       auto legacy_event = ctx.event()->set_legacy_event();
       SetLegacyFlags(legacy_event, phase, flags);
@@ -372,7 +372,7 @@
       ctx.event()->set_track_uuid(0);
     } else {
       // No pid/tid/track overrides => obey the flags instead.
-      SetTrackIfNeeded(&ctx, flags);
+      SetTrackIfNeeded(&ctx, phase, flags);
     }
     if (NeedLegacyFlags(phase, flags) || pid_override || tid_override) {
       auto legacy_event = ctx.event()->set_legacy_event();
@@ -409,7 +409,10 @@
   }
 
  private:
-  static void SetTrackIfNeeded(EventContext* ctx, uint32_t flags) {
+  static void SetTrackIfNeeded(EventContext* ctx, char phase, uint32_t flags) {
+    // Scopes are only relevant for instant events.
+    if (phase != TRACE_EVENT_PHASE_INSTANT)
+      return;
     // Note: This avoids the need to set LegacyEvent::instant_event_scope.
     auto scope = flags & TRACE_EVENT_FLAG_SCOPE_MASK;
     switch (scope) {
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index e9f45a9..acb86a0 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -540,6 +540,13 @@
       }
       const auto& track_event = packet.track_event();
       std::string slice;
+
+      if (track_event.has_track_uuid()) {
+        std::stringstream track;
+        track << "[track=" << track_event.track_uuid() << "]";
+        slice += track.str();
+      }
+
       switch (track_event.type()) {
         case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
           slice += "B";
@@ -1876,6 +1883,21 @@
   EXPECT_THAT(slices, ElementsAre("I:test.TestEvent", "I:test.AnotherEvent"));
 }
 
+TEST_P(PerfettoApiTest, TrackEventDefaultGlobalTrack) {
+  // Create a new trace session.
+  auto* tracing_session = NewTraceWithCategories({"test"});
+  tracing_session->get()->StartBlocking();
+
+  TRACE_EVENT_INSTANT("test", "ThreadEvent");
+  TRACE_EVENT_INSTANT("test", "GlobalEvent", perfetto::Track::Global(0u));
+  perfetto::TrackEvent::Flush();
+
+  tracing_session->get()->StopBlocking();
+  auto slices = ReadSlicesFromTrace(tracing_session->get());
+  EXPECT_THAT(slices,
+              ElementsAre("I:test.ThreadEvent", "[track=0]I:test.GlobalEvent"));
+}
+
 TEST_P(PerfettoApiTest, TrackEventDebugAnnotations) {
   // Create a new trace session.
   auto* tracing_session = NewTraceWithCategories({"test"});
@@ -2824,13 +2846,14 @@
   EXPECT_THAT(
       slices,
       ElementsAre(
-          "I:cat.LegacyEvent", "B:cat.LegacyEvent(arg=(int)123)",
+          "[track=0]I:cat.LegacyEvent", "B:cat.LegacyEvent(arg=(int)123)",
           "E.LegacyEvent(arg=(string)string,arg2=(double)0.123)",
           "B:cat.ScopedLegacyEvent", "E",
           "B(bind_id=3671771902)(flow_direction=1):disabled-by-default-cat."
           "LegacyFlowEvent",
-          "I:cat.LegacyInstantEvent",
-          "Legacy_S(unscoped_id=1)(pid_override=123)(tid_override=456):cat."
+          "[track=0]I:cat.LegacyInstantEvent",
+          "[track=0]Legacy_S(unscoped_id=1)(pid_override=123)(tid_override=456)"
+          ":cat."
           "LegacyWithIdTidAndTimestamp",
           "Legacy_C:cat.LegacyCounter(value=(int)1234)",
           "Legacy_C(unscoped_id=1234):cat.LegacyCounterWithId(value=(int)9000)",
@@ -3439,7 +3462,7 @@
   tracing_session->get()->StopBlocking();
   auto slices = ReadSlicesFromTrace(tracing_session->get());
   EXPECT_THAT(slices, ElementsAre("I:cat.Instant(value=(int)1)",
-                                  "I:cat.InstantLegacy(value=(int)1)",
+                                  "[track=0]I:cat.InstantLegacy(value=(int)1)",
                                   "B:cat.Scoped(value=(int)1)", "E",
                                   "B:cat.ScopedLegacy(value=(int)1)", "E"));
 }