Merge changes Ic1c3e077,I69b8ec0d into main
* changes:
ui: Use plugin deps to add tracks to process groups
ui: Don't render tracks while the trace is loading
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index 9509c1d..0e5668f 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -323,28 +323,30 @@
m(PanelContainer, {
trace: attrs.trace,
className: 'pinned-panel-container',
- panels: attrs.trace.workspace.pinnedTracks.map((trackNode) => {
- if (trackNode.uri) {
- const tr = attrs.trace.tracks.getTrackRenderer(trackNode.uri);
- return new TrackPanel({
- trace: attrs.trace,
- reorderable: true,
- node: trackNode,
- trackRenderer: tr,
- revealOnCreate: true,
- indentationLevel: 0,
- topOffsetPx: 0,
- });
- } else {
- return new TrackPanel({
- trace: attrs.trace,
- node: trackNode,
- revealOnCreate: true,
- indentationLevel: 0,
- topOffsetPx: 0,
- });
- }
- }),
+ panels: AppImpl.instance.isLoadingTrace
+ ? []
+ : attrs.trace.workspace.pinnedTracks.map((trackNode) => {
+ if (trackNode.uri) {
+ const tr = attrs.trace.tracks.getTrackRenderer(trackNode.uri);
+ return new TrackPanel({
+ trace: attrs.trace,
+ reorderable: true,
+ node: trackNode,
+ trackRenderer: tr,
+ revealOnCreate: true,
+ indentationLevel: 0,
+ topOffsetPx: 0,
+ });
+ } else {
+ return new TrackPanel({
+ trace: attrs.trace,
+ node: trackNode,
+ revealOnCreate: true,
+ indentationLevel: 0,
+ topOffsetPx: 0,
+ });
+ }
+ }),
renderUnderlay: (ctx, size) => renderUnderlay(attrs.trace, ctx, size),
renderOverlay: (ctx, size, panels) =>
renderOverlay(attrs.trace, ctx, size, panels),
@@ -353,7 +355,7 @@
m(PanelContainer, {
trace: attrs.trace,
className: 'scrolling-panel-container',
- panels: scrollingPanels,
+ panels: AppImpl.instance.isLoadingTrace ? [] : scrollingPanels,
onPanelStackResize: (width) => {
const timelineWidth = width - TRACK_SHELL_WIDTH;
this.timelineWidthPx = timelineWidth;
diff --git a/ui/src/plugins/dev.perfetto.AndroidDmabuf/index.ts b/ui/src/plugins/dev.perfetto.AndroidDmabuf/index.ts
index a946cc2..b9d0919 100644
--- a/ui/src/plugins/dev.perfetto.AndroidDmabuf/index.ts
+++ b/ui/src/plugins/dev.perfetto.AndroidDmabuf/index.ts
@@ -17,13 +17,10 @@
SqlDataSource,
} from '../../public/lib/tracks/query_counter_track';
import {PerfettoPlugin} from '../../public/plugin';
-import {
- getOrCreateGroupForProcess,
- getOrCreateGroupForThread,
-} from '../../public/standard_groups';
import {Trace} from '../../public/trace';
import {TrackNode} from '../../public/workspace';
import {NUM_NULL} from '../../trace_processor/query_result';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
async function registerAllocsTrack(
ctx: Trace,
@@ -44,6 +41,8 @@
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.AndroidDmabuf';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
const e = ctx.engine;
await e.query(`INCLUDE PERFETTO MODULE android.memory.dmabuf`);
@@ -66,9 +65,10 @@
WHERE upid = ${it.upid}`,
};
await registerAllocsTrack(ctx, uri, config);
- getOrCreateGroupForProcess(ctx.workspace, it.upid).addChildInOrder(
- new TrackNode({uri, title: 'dmabuf allocs'}),
- );
+ ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForProcess(it.upid)
+ ?.addChildInOrder(new TrackNode({uri, title: 'dmabuf allocs'}));
} else if (it.utid != null) {
const uri = `/android_process_dmabuf_utid_${it.utid}`;
const config: SqlDataSource = {
@@ -76,9 +76,10 @@
WHERE utid = ${it.utid}`,
};
await registerAllocsTrack(ctx, uri, config);
- getOrCreateGroupForThread(ctx.workspace, it.utid).addChildInOrder(
- new TrackNode({uri, title: 'dmabuf allocs'}),
- );
+ ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForThread(it.utid)
+ ?.addChildInOrder(new TrackNode({uri, title: 'dmabuf allocs'}));
}
}
}
diff --git a/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts b/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts
index ecd8dab..e5940cd 100644
--- a/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts
+++ b/ui/src/plugins/dev.perfetto.AsyncSlices/index.ts
@@ -20,19 +20,18 @@
import {getThreadUriPrefix, getTrackName} from '../../public/utils';
import {NUM, NUM_NULL, STR, STR_NULL} from '../../trace_processor/query_result';
import {AsyncSliceTrack} from './async_slice_track';
-import {
- getOrCreateGroupForProcess,
- getOrCreateGroupForThread,
-} from '../../public/standard_groups';
import {exists} from '../../base/utils';
import {assertExists, assertTrue} from '../../base/logging';
import {SliceSelectionAggregator} from './slice_selection_aggregator';
import {sqlTableRegistry} from '../../frontend/widgets/sql/table/sql_table_registry';
import {getSliceTable} from './table';
import {extensions} from '../../public/lib/extensions';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.AsyncSlices';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
const trackIdsToUris = new Map<number, string>();
@@ -298,8 +297,10 @@
if (parent !== false && parent !== undefined) {
parent.trackNode.addChildInOrder(t.trackNode);
} else {
- const processGroup = getOrCreateGroupForProcess(ctx.workspace, t.upid);
- processGroup.addChildInOrder(t.trackNode);
+ const processGroup = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForProcess(t.upid);
+ processGroup?.addChildInOrder(t.trackNode);
}
});
}
@@ -399,8 +400,10 @@
if (parent !== false && parent !== undefined) {
parent.trackNode.addChildInOrder(t.trackNode);
} else {
- const group = getOrCreateGroupForThread(ctx.workspace, t.utid);
- group.addChildInOrder(t.trackNode);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForThread(t.utid);
+ group?.addChildInOrder(t.trackNode);
}
});
}
diff --git a/ui/src/plugins/dev.perfetto.Counter/index.ts b/ui/src/plugins/dev.perfetto.Counter/index.ts
index ef063ca..47a8f61 100644
--- a/ui/src/plugins/dev.perfetto.Counter/index.ts
+++ b/ui/src/plugins/dev.perfetto.Counter/index.ts
@@ -27,11 +27,8 @@
import {TraceProcessorCounterTrack} from './trace_processor_counter_track';
import {exists} from '../../base/utils';
import {TrackNode} from '../../public/workspace';
-import {
- getOrCreateGroupForProcess,
- getOrCreateGroupForThread,
-} from '../../public/standard_groups';
import {CounterSelectionAggregator} from './counter_selection_aggregator';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
const NETWORK_TRACK_REGEX = new RegExp('^.* (Received|Transmitted)( KB)?$');
const ENTITY_RESIDENCY_REGEX = new RegExp('^Entity residency:');
@@ -108,6 +105,8 @@
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.Counter';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
await this.addCounterTracks(ctx);
await this.addGpuFrequencyTracks(ctx);
@@ -313,9 +312,11 @@
name,
),
});
- const group = getOrCreateGroupForThread(ctx.workspace, utid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForThread(utid);
const track = new TrackNode({uri, title: name, sortOrder: 30});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
}
@@ -371,9 +372,11 @@
name,
),
});
- const group = getOrCreateGroupForProcess(ctx.workspace, upid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForProcess(upid);
const track = new TrackNode({uri, title: name, sortOrder: 20});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
}
diff --git a/ui/src/plugins/dev.perfetto.CpuProfile/index.ts b/ui/src/plugins/dev.perfetto.CpuProfile/index.ts
index e33e341..05718df 100644
--- a/ui/src/plugins/dev.perfetto.CpuProfile/index.ts
+++ b/ui/src/plugins/dev.perfetto.CpuProfile/index.ts
@@ -19,11 +19,13 @@
import {CpuProfileTrack} from './cpu_profile_track';
import {getThreadUriPrefix} from '../../public/utils';
import {exists} from '../../base/utils';
-import {getOrCreateGroupForThread} from '../../public/standard_groups';
import {TrackNode} from '../../public/workspace';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.CpuProfile';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
const result = await ctx.engine.query(`
with thread_cpu_sample as (
@@ -62,9 +64,11 @@
},
track: new CpuProfileTrack(ctx, uri, utid),
});
- const group = getOrCreateGroupForThread(ctx.workspace, utid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForThread(utid);
const track = new TrackNode({uri, title, sortOrder: -40});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
}
}
diff --git a/ui/src/plugins/dev.perfetto.Frames/index.ts b/ui/src/plugins/dev.perfetto.Frames/index.ts
index 8d3abec..d9df86c 100644
--- a/ui/src/plugins/dev.perfetto.Frames/index.ts
+++ b/ui/src/plugins/dev.perfetto.Frames/index.ts
@@ -18,16 +18,18 @@
} from '../../public/track_kinds';
import {Trace} from '../../public/trace';
import {PerfettoPlugin} from '../../public/plugin';
-import {getOrCreateGroupForProcess} from '../../public/standard_groups';
import {getTrackName} from '../../public/utils';
import {TrackNode} from '../../public/workspace';
import {NUM, NUM_NULL, STR, STR_NULL} from '../../trace_processor/query_result';
import {ActualFramesTrack} from './actual_frames_track';
import {ExpectedFramesTrack} from './expected_frames_track';
import {FrameSelectionAggregator} from './frame_selection_aggregator';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.Frames';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
this.addExpectedFrames(ctx);
this.addActualFrames(ctx);
@@ -88,9 +90,11 @@
kind: EXPECTED_FRAMES_SLICE_TRACK_KIND,
},
});
- const group = getOrCreateGroupForProcess(ctx.workspace, upid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForProcess(upid);
const track = new TrackNode({uri, title, sortOrder: -50});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
}
@@ -151,9 +155,11 @@
kind: ACTUAL_FRAMES_SLICE_TRACK_KIND,
},
});
- const group = getOrCreateGroupForProcess(ctx.workspace, upid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForProcess(upid);
const track = new TrackNode({uri, title, sortOrder: -50});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
}
}
diff --git a/ui/src/plugins/dev.perfetto.HeapProfile/index.ts b/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
index 2e0591f..fcd79a3 100644
--- a/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
+++ b/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
@@ -17,9 +17,9 @@
import {PerfettoPlugin} from '../../public/plugin';
import {LONG, NUM, STR} from '../../trace_processor/query_result';
import {HeapProfileTrack} from './heap_profile_track';
-import {getOrCreateGroupForProcess} from '../../public/standard_groups';
import {TrackNode} from '../../public/workspace';
import {createPerfettoTable} from '../../trace_processor/sql_utils';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
function getUriForTrack(upid: number): string {
return `/process_${upid}/heap_profile`;
@@ -27,6 +27,8 @@
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.HeapProfile';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
const it = await ctx.engine.query(`
select value from stats
@@ -94,9 +96,11 @@
},
track: new HeapProfileTrack(ctx, uri, tableName, upid, incomplete),
});
- const group = getOrCreateGroupForProcess(ctx.workspace, upid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForProcess(upid);
const track = new TrackNode({uri, title, sortOrder: -30});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
ctx.addEventListener('traceready', async () => {
diff --git a/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts b/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts
index 04e8b13..1488376 100644
--- a/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts
+++ b/ui/src/plugins/dev.perfetto.PerfSamplesProfile/index.ts
@@ -23,11 +23,8 @@
ThreadPerfSamplesProfileTrack,
} from './perf_samples_profile_track';
import {getThreadUriPrefix} from '../../public/utils';
-import {
- getOrCreateGroupForProcess,
- getOrCreateGroupForThread,
-} from '../../public/standard_groups';
import {TrackNode} from '../../public/workspace';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
export interface Data extends TrackData {
tsStarts: BigInt64Array;
@@ -39,6 +36,8 @@
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.PerfSamplesProfile';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
const pResult = await ctx.engine.query(`
select distinct upid
@@ -59,9 +58,11 @@
},
track: new ProcessPerfSamplesProfileTrack(ctx, uri, upid),
});
- const group = getOrCreateGroupForProcess(ctx.workspace, upid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForProcess(upid);
const track = new TrackNode({uri, title, sortOrder: -40});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
const tResult = await ctx.engine.query(`
select distinct
@@ -99,9 +100,11 @@
},
track: new ThreadPerfSamplesProfileTrack(ctx, uri, utid),
});
- const group = getOrCreateGroupForThread(ctx.workspace, utid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForThread(utid);
const track = new TrackNode({uri, title, sortOrder: -50});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
ctx.addEventListener('traceready', async () => {
diff --git a/ui/src/plugins/dev.perfetto.ProcessThreadGroups/index.ts b/ui/src/plugins/dev.perfetto.ProcessThreadGroups/index.ts
index 60aa11c..eb720c9 100644
--- a/ui/src/plugins/dev.perfetto.ProcessThreadGroups/index.ts
+++ b/ui/src/plugins/dev.perfetto.ProcessThreadGroups/index.ts
@@ -14,10 +14,6 @@
import {Trace} from '../../public/trace';
import {PerfettoPlugin} from '../../public/plugin';
-import {
- getOrCreateGroupForProcess,
- getOrCreateGroupForThread,
-} from '../../public/standard_groups';
import {TrackNode} from '../../public/workspace';
import {NUM, STR, STR_NULL} from '../../trace_processor/query_result';
@@ -41,24 +37,35 @@
// including the kernel groups, sorting, and adding summary tracks.
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.ProcessThreadGroups';
- async onTraceLoad(ctx: Trace): Promise<void> {
- const processGroups = new Map<number, TrackNode>();
- const threadGroups = new Map<number, TrackNode>();
+ private readonly processGroups = new Map<number, TrackNode>();
+ private readonly threadGroups = new Map<number, TrackNode>();
+
+ constructor(private readonly ctx: Trace) {}
+
+ getGroupForProcess(upid: number): TrackNode | undefined {
+ return this.processGroups.get(upid);
+ }
+
+ getGroupForThread(utid: number): TrackNode | undefined {
+ return this.threadGroups.get(utid);
+ }
+
+ async onTraceLoad(ctx: Trace): Promise<void> {
// Pre-group all kernel "threads" (actually processes) if this is a linux
// system trace. Below, addProcessTrackGroups will skip them due to an
// existing group uuid, and addThreadStateTracks will fill in the
// per-thread tracks. Quirk: since all threads will appear to be
// TrackKindPriority.MAIN_THREAD, any process-level tracks will end up
// pushed to the bottom of the group in the UI.
- await this.addKernelThreadGrouping(ctx, threadGroups);
+ await this.addKernelThreadGrouping();
// Create the per-process track groups. Note that this won't necessarily
// create a track per process. If a process has been completely idle and has
// no sched events, no track group will be emitted.
// Will populate this.addTrackGroupActions
- await this.addProcessGroups(ctx, processGroups, threadGroups);
- await this.addThreadGroups(ctx, processGroups, threadGroups);
+ await this.addProcessGroups();
+ await this.addThreadGroups();
ctx.addEventListener('traceready', () => {
// If, by the time the trace has finished loading, some of the process or
@@ -68,15 +75,12 @@
g.remove();
}
};
- processGroups.forEach(removeIfEmpty);
- threadGroups.forEach(removeIfEmpty);
+ this.processGroups.forEach(removeIfEmpty);
+ this.threadGroups.forEach(removeIfEmpty);
});
}
- private async addKernelThreadGrouping(
- ctx: Trace,
- threadGroups: Map<number, TrackNode>,
- ): Promise<void> {
+ private async addKernelThreadGrouping(): Promise<void> {
// Identify kernel threads if this is a linux system trace, and sufficient
// process information is available. Kernel threads are identified by being
// children of kthreadd (always pid 2).
@@ -86,7 +90,7 @@
// which has pid 0 but appears as a distinct process (with its own comm) on
// each cpu. It'd make sense to exclude its thread state track, but still
// put process-scoped tracks in this group.
- const result = await ctx.engine.query(`
+ const result = await this.ctx.engine.query(`
select
t.utid, p.upid, (case p.pid when 2 then 1 else 0 end) isKthreadd
from
@@ -123,28 +127,27 @@
sortOrder: 50,
isSummary: true,
});
- ctx.workspace.addChildInOrder(kernelThreadsGroup);
+ this.ctx.workspace.addChildInOrder(kernelThreadsGroup);
// Set the group for all kernel threads (including kthreadd itself).
for (; it.valid(); it.next()) {
const {utid} = it;
- const threadGroup = getOrCreateGroupForThread(ctx.workspace, utid);
- threadGroup.headless = true;
+ const threadGroup = new TrackNode({
+ uri: `thread${utid}`,
+ title: `Thread ${utid}`,
+ isSummary: true,
+ headless: true,
+ });
kernelThreadsGroup.addChildInOrder(threadGroup);
-
- threadGroups.set(utid, threadGroup);
+ this.threadGroups.set(utid, threadGroup);
}
}
// Adds top level groups for processes and thread that don't belong to a
// process.
- private async addProcessGroups(
- ctx: Trace,
- processGroups: Map<number, TrackNode>,
- threadGroups: Map<number, TrackNode>,
- ): Promise<void> {
- const result = await ctx.engine.query(`
+ private async addProcessGroups(): Promise<void> {
+ const result = await this.ctx.engine.query(`
with processGroups as (
select
upid,
@@ -231,7 +234,7 @@
if (kind === 'process') {
// Ignore kernel process groups
- if (processGroups.has(uid)) {
+ if (this.processGroups.has(uid)) {
continue;
}
@@ -247,41 +250,41 @@
}
const displayName = getProcessDisplayName(name ?? undefined, id);
- const group = getOrCreateGroupForProcess(ctx.workspace, uid);
- group.title = displayName;
- group.uri = `/process_${uid}`; // Summary track URI
- group.sortOrder = 50;
+ const group = new TrackNode({
+ uri: `/process_${uid}`,
+ title: displayName,
+ isSummary: true,
+ sortOrder: 50,
+ });
// Re-insert the child node to sort it
- ctx.workspace.addChildInOrder(group);
- processGroups.set(uid, group);
+ this.ctx.workspace.addChildInOrder(group);
+ this.processGroups.set(uid, group);
} else {
// Ignore kernel process groups
- if (threadGroups.has(uid)) {
+ if (this.threadGroups.has(uid)) {
continue;
}
const displayName = getThreadDisplayName(name ?? undefined, id);
- const group = getOrCreateGroupForThread(ctx.workspace, uid);
- group.title = displayName;
- group.uri = `/thread_${uid}`; // Summary track URI
- group.sortOrder = 50;
+ const group = new TrackNode({
+ uri: `/thread_${uid}`,
+ title: displayName,
+ isSummary: true,
+ sortOrder: 50,
+ });
// Re-insert the child node to sort it
- ctx.workspace.addChildInOrder(group);
- threadGroups.set(uid, group);
+ this.ctx.workspace.addChildInOrder(group);
+ this.threadGroups.set(uid, group);
}
}
}
// Create all the nested & headless thread groups that live inside existing
// process groups.
- private async addThreadGroups(
- ctx: Trace,
- processGroups: Map<number, TrackNode>,
- threadGroups: Map<number, TrackNode>,
- ): Promise<void> {
- const result = await ctx.engine.query(`
+ private async addThreadGroups(): Promise<void> {
+ const result = await this.ctx.engine.query(`
with threadGroups as (
select
utid,
@@ -329,15 +332,18 @@
const {utid, tid, upid, threadName} = it;
// Ignore kernel thread groups
- if (threadGroups.has(utid)) {
+ if (this.threadGroups.has(utid)) {
continue;
}
- const group = getOrCreateGroupForThread(ctx.workspace, utid);
- group.title = getThreadDisplayName(threadName ?? undefined, tid);
- threadGroups.set(utid, group);
- group.headless = true;
- processGroups.get(upid)?.addChildInOrder(group);
+ const group = new TrackNode({
+ uri: `/thread_${utid}`,
+ title: getThreadDisplayName(threadName ?? undefined, tid),
+ isSummary: true,
+ headless: true,
+ });
+ this.threadGroups.set(utid, group);
+ this.processGroups.get(upid)?.addChildInOrder(group);
}
}
}
diff --git a/ui/src/plugins/dev.perfetto.ThreadState/index.ts b/ui/src/plugins/dev.perfetto.ThreadState/index.ts
index 155b35f..d7c2363 100644
--- a/ui/src/plugins/dev.perfetto.ThreadState/index.ts
+++ b/ui/src/plugins/dev.perfetto.ThreadState/index.ts
@@ -22,9 +22,9 @@
import {getThreadStateTable} from './table';
import {sqlTableRegistry} from '../../frontend/widgets/sql/table/sql_table_registry';
import {TrackNode} from '../../public/workspace';
-import {getOrCreateGroupForThread} from '../../public/standard_groups';
import {ThreadStateSelectionAggregator} from './thread_state_selection_aggregator';
import {extensions} from '../../public/lib/extensions';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
function uriForThreadStateTrack(upid: number | null, utid: number): string {
return `${getThreadUriPrefix(upid, utid)}_state`;
@@ -32,6 +32,8 @@
export default class implements PerfettoPlugin {
static readonly id = 'dev.perfetto.ThreadState';
+ static readonly dependencies = [ProcessThreadGroupsPlugin];
+
async onTraceLoad(ctx: Trace): Promise<void> {
const {engine} = ctx;
@@ -87,9 +89,11 @@
track: new ThreadStateTrack(ctx, uri, utid),
});
- const group = getOrCreateGroupForThread(ctx.workspace, utid);
+ const group = ctx.plugins
+ .getPlugin(ProcessThreadGroupsPlugin)
+ .getGroupForThread(utid);
const track = new TrackNode({uri, title, sortOrder: 10});
- group.addChildInOrder(track);
+ group?.addChildInOrder(track);
}
sqlTableRegistry['thread_state'] = getThreadStateTable();
diff --git a/ui/src/public/standard_groups.ts b/ui/src/public/standard_groups.ts
index 61b844a..2bc7570 100644
--- a/ui/src/public/standard_groups.ts
+++ b/ui/src/public/standard_groups.ts
@@ -15,40 +15,6 @@
import {TrackNode, TrackNodeArgs, Workspace} from './workspace';
/**
- * Gets or creates a group for a given process given the normal grouping
- * conventions.
- *
- * @param workspace - The workspace to search for the group on.
- * @param upid - The upid of teh process to find.
- */
-export function getOrCreateGroupForProcess(
- workspace: Workspace,
- upid: number,
-): TrackNode {
- return getOrCreateGroup(workspace, `process${upid}`, {
- title: `Process ${upid}`,
- isSummary: true,
- });
-}
-
-/**
- * Gets or creates a group for a given thread given the normal grouping
- * conventions.
- *
- * @param workspace - The workspace to search for the group on.
- * @param utid - The utid of the thread to find.
- */
-export function getOrCreateGroupForThread(
- workspace: Workspace,
- utid: number,
-): TrackNode {
- return getOrCreateGroup(workspace, `thread${utid}`, {
- title: `Thread ${utid}`,
- isSummary: true,
- });
-}
-
-/**
* Gets or creates a group for user interaction
*
* @param workspace - The workspace on which to create the group.