Merge "Add Renderthread frame times for CUJ jank tracking"
diff --git a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256 b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
index 0d2eafa..80ea2f4 100644
--- a/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
+++ b/test/data/ui-screenshots/ui-android_trace_30s_expand_camera.png.sha256
@@ -1 +1 @@
-7be9a9c82f04d1322c9e4e7b4ce75dc688152ca72af2391a0292749673ce8c1f
\ No newline at end of file
+436e358bbe14b492a48f369a4296fff45de2879308196ce9838ea1df7adcd7c8
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
index 729dfb4..0f1fd38 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_expand_browser_proc.png.sha256
@@ -1 +1 @@
-6699299b62ee4632f851f555703c94b541de0fb9a2792262bd428c49ec3a321c
\ No newline at end of file
+70b1ccb9b490aa038837b8b010d4c4a03418b5b5c78e0ef26a10343763a80565
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256 b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
index 9ed6aa2..43fc3a3 100644
--- a/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
+++ b/test/data/ui-screenshots/ui-chrome_rendering_desktop_select_slice_with_flows.png.sha256
@@ -1 +1 @@
-404f4b826297b80b5d4c67c3326bf7b044b297114247d912114efae308f99370
\ No newline at end of file
+0ec0548f87e4bac68a968606ed5dbaac3b0be7048df84161adb8f6113ac10a36
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256 b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
index 035f335..1c1134b 100644
--- a/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_navigate_navigate_back_and_forward.png.sha256
@@ -1 +1 @@
-e8ffe0046ea98d27b4216c8d1ff64c665392c90ab3d90e2db99069ae54d12707
\ No newline at end of file
+582c5550a14de74aabcd2b0342f8295b040febc4cf6bcb4e9fb6cb155e9c8d4d
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256 b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
index d7c7cb9..ce4aadf 100644
--- a/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_open_invalid_trace_from_blank_page.png.sha256
@@ -1 +1 @@
-14e436dda252119dbe75bbe7233e8b62ade69e27bbad311181927c097adb86d0
\ No newline at end of file
+72e9695470c9067005bca54fcdee310feaeed23d58d6bf4c2e575748a992027e
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256 b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
index b5f3a52..3c99db9 100644
--- a/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
+++ b/test/data/ui-screenshots/ui-routing_start_from_no_trace_open_invalid_trace.png.sha256
@@ -1 +1 @@
-77ead2d35348d988d3938b88fc66f0731f494fb77f2165d3fbddca7f37df97f6
\ No newline at end of file
+9425ea9f775ab88ebd9d0f47946c0835191a7d4579da40d04f20c9db9d288e95
\ No newline at end of file
diff --git a/ui/src/assets/common.scss b/ui/src/assets/common.scss
index 46f9db4..964c283 100644
--- a/ui/src/assets/common.scss
+++ b/ui/src/assets/common.scss
@@ -452,6 +452,13 @@
.panel {
position: relative; // Otherwise canvas covers panel dom.
+
+ &.sticky {
+ position: sticky;
+ z-index: 3;
+ top: 0;
+ background-color: hsl(215, 22%, 19%);
+ }
}
.pan-and-zoom-content {
diff --git a/ui/src/frontend/panel_container.ts b/ui/src/frontend/panel_container.ts
index 662cd54..132d7cf 100644
--- a/ui/src/frontend/panel_container.ts
+++ b/ui/src/frontend/panel_container.ts
@@ -30,6 +30,7 @@
RunningStatistics,
runningStatStr
} from './perf';
+import {TrackGroupAttrs} from './viewer_page';
/**
* If the panel container scrolls, the backing canvas height is
@@ -216,21 +217,45 @@
perfDisplay.removeContainer(this);
}
+ isTrackGroupAttrs(attrs: unknown): attrs is TrackGroupAttrs {
+ return (attrs as {collapsed?: boolean}).collapsed !== undefined;
+ }
+
+ renderPanel(node: AnyAttrsVnode, key: string, extraClass = ''): m.Vnode {
+ assertFalse(this.panelByKey.has(key));
+ this.panelByKey.set(key, node);
+
+ return m(
+ `.panel${extraClass}`,
+ {key, 'data-key': key},
+ perfDebug() ?
+ [node, m('.debug-panel-border', {key: 'debug-panel-border'})] :
+ node);
+ }
+
+ // Render a tree of panels into one vnode. Argument `path` is used to build
+ // `key` attribute for intermediate tree vnodes: otherwise Mithril internals
+ // will complain about keyed and non-keyed vnodes mixed together.
+ renderTree(node: AnyAttrsVnode, path: string): m.Vnode {
+ if (this.isTrackGroupAttrs(node.attrs)) {
+ return m(
+ 'div',
+ {key: path},
+ this.renderPanel(
+ node.attrs.header,
+ `${path}-header`,
+ node.attrs.collapsed ? '' : '.sticky'),
+ ...node.attrs.childTracks.map(
+ (child, index) => this.renderTree(child, `${path}-${index}`)));
+ }
+ return this.renderPanel(node, assertExists(node.key) as string);
+ }
+
view({attrs}: m.CVnode<Attrs>) {
this.attrs = attrs;
this.panelByKey.clear();
- const children = [];
- for (const panel of attrs.panels) {
- const key = assertExists(panel.key) as string;
- assertFalse(this.panelByKey.has(key));
- this.panelByKey.set(key, panel);
- children.push(
- m('.panel',
- {key: panel.key, 'data-key': panel.key},
- perfDebug() ?
- [panel, m('.debug-panel-border', {key: 'debug-panel-border'})] :
- panel));
- }
+ const children = attrs.panels.map(
+ (panel, index) => this.renderTree(panel, `track-tree-${index}`));
return [
m(
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index 0cce472..f2370a9 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -59,6 +59,20 @@
return null;
}
+export interface TrackGroupAttrs {
+ header: AnyAttrsVnode;
+ collapsed: boolean;
+ childTracks: AnyAttrsVnode[];
+}
+
+export class TrackGroup implements m.ClassComponent<TrackGroupAttrs> {
+ view() {
+ // TrackGroup component acts as a holder for a bunch of tracks rendered
+ // together: the actual rendering happens in PanelContainer. In order to
+ // avoid confusion, this method remains empty.
+ }
+}
+
/**
* Top-most level component for the viewer page. Holds tracks, brush timeline,
* panels, and everything else that's part of the main trace viewer page.
@@ -212,22 +226,30 @@
id => m(TrackPanel, {key: id, id, selectable: true}));
for (const group of Object.values(globals.state.trackGroups)) {
- scrollingPanels.push(m(TrackGroupPanel, {
+ const headerPanel = m(TrackGroupPanel, {
trackGroupId: group.id,
key: `trackgroup-${group.id}`,
- selectable: true,
- }));
- if (group.collapsed) continue;
+ selectable: true
+ });
+
+ const childTracks: AnyAttrsVnode[] = [];
// The first track is the summary track, and is displayed as part of the
// group panel, we don't want to display it twice so we start from 1.
- for (let i = 1; i < group.tracks.length; ++i) {
- const id = group.tracks[i];
- scrollingPanels.push(m(TrackPanel, {
- key: `track-${group.id}-${id}`,
- id,
- selectable: true,
- }));
+ if (!group.collapsed) {
+ for (let i = 1; i < group.tracks.length; ++i) {
+ const id = group.tracks[i];
+ childTracks.push(m(TrackPanel, {
+ key: `track-${group.id}-${id}`,
+ id,
+ selectable: true,
+ }));
+ }
}
+ scrollingPanels.push(m(TrackGroup, {
+ header: headerPanel,
+ collapsed: group.collapsed,
+ childTracks,
+ } as TrackGroupAttrs));
}
return m(