@zenfg/inspector 0.1.0-beta.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/GUIDE.md +182 -0
  2. package/README.md +61 -89
  3. package/THEMING.md +124 -0
  4. package/dist/FrameGraphInspector.d.ts +23 -4
  5. package/dist/FrameGraphInspector.d.ts.map +1 -1
  6. package/dist/FrameGraphInspector.js +137 -29
  7. package/dist/FrameGraphInspector.js.map +1 -1
  8. package/dist/capture.d.ts +5 -0
  9. package/dist/capture.d.ts.map +1 -0
  10. package/dist/capture.js +2 -0
  11. package/dist/capture.js.map +1 -0
  12. package/dist/debugCaptureModel.d.ts +19 -0
  13. package/dist/debugCaptureModel.d.ts.map +1 -1
  14. package/dist/debugCaptureModel.js +36 -2
  15. package/dist/debugCaptureModel.js.map +1 -1
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/panelAliasAnalysis.d.ts +1 -0
  20. package/dist/panelAliasAnalysis.d.ts.map +1 -1
  21. package/dist/panelAliasAnalysis.js +23 -54
  22. package/dist/panelAliasAnalysis.js.map +1 -1
  23. package/dist/panelCytoscapeGraphRenderer.d.ts +15 -2
  24. package/dist/panelCytoscapeGraphRenderer.d.ts.map +1 -1
  25. package/dist/panelCytoscapeGraphRenderer.js +145 -23
  26. package/dist/panelCytoscapeGraphRenderer.js.map +1 -1
  27. package/dist/panelDetailLayout.d.ts +27 -0
  28. package/dist/panelDetailLayout.d.ts.map +1 -0
  29. package/dist/panelDetailLayout.js +174 -0
  30. package/dist/panelDetailLayout.js.map +1 -0
  31. package/dist/panelDetailStyles.d.ts +2 -0
  32. package/dist/panelDetailStyles.d.ts.map +1 -0
  33. package/dist/panelDetailStyles.js +57 -0
  34. package/dist/panelDetailStyles.js.map +1 -0
  35. package/dist/panelDiagnosticsView.d.ts +10 -1
  36. package/dist/panelDiagnosticsView.d.ts.map +1 -1
  37. package/dist/panelDiagnosticsView.js +166 -57
  38. package/dist/panelDiagnosticsView.js.map +1 -1
  39. package/dist/panelDomHelpers.d.ts.map +1 -1
  40. package/dist/panelDomHelpers.js +6 -5
  41. package/dist/panelDomHelpers.js.map +1 -1
  42. package/dist/panelGraphLayout.d.ts +3 -2
  43. package/dist/panelGraphLayout.d.ts.map +1 -1
  44. package/dist/panelGraphLayout.js +6 -5
  45. package/dist/panelGraphLayout.js.map +1 -1
  46. package/dist/panelGraphRenderer.d.ts +10 -0
  47. package/dist/panelGraphRenderer.d.ts.map +1 -1
  48. package/dist/panelGraphRenderer.js.map +1 -1
  49. package/dist/panelGraphScene.d.ts +1 -0
  50. package/dist/panelGraphScene.d.ts.map +1 -1
  51. package/dist/panelGraphScene.js +69 -32
  52. package/dist/panelGraphScene.js.map +1 -1
  53. package/dist/panelGraphSearch.d.ts +16 -0
  54. package/dist/panelGraphSearch.d.ts.map +1 -0
  55. package/dist/panelGraphSearch.js +93 -0
  56. package/dist/panelGraphSearch.js.map +1 -0
  57. package/dist/panelGraphView.d.ts +82 -0
  58. package/dist/panelGraphView.d.ts.map +1 -1
  59. package/dist/panelGraphView.js +15 -4
  60. package/dist/panelGraphView.js.map +1 -1
  61. package/dist/panelGraphVisuals.d.ts +14 -6
  62. package/dist/panelGraphVisuals.d.ts.map +1 -1
  63. package/dist/panelGraphVisuals.js +126 -51
  64. package/dist/panelGraphVisuals.js.map +1 -1
  65. package/dist/panelInspectorView.d.ts +8 -0
  66. package/dist/panelInspectorView.d.ts.map +1 -1
  67. package/dist/panelInspectorView.js +242 -48
  68. package/dist/panelInspectorView.js.map +1 -1
  69. package/dist/panelListStyles.d.ts +3 -0
  70. package/dist/panelListStyles.d.ts.map +1 -0
  71. package/dist/panelListStyles.js +155 -0
  72. package/dist/panelListStyles.js.map +1 -0
  73. package/dist/panelMemoryStyles.d.ts +3 -0
  74. package/dist/panelMemoryStyles.d.ts.map +1 -0
  75. package/dist/panelMemoryStyles.js +42 -0
  76. package/dist/panelMemoryStyles.js.map +1 -0
  77. package/dist/panelMemoryView.d.ts +13 -1
  78. package/dist/panelMemoryView.d.ts.map +1 -1
  79. package/dist/panelMemoryView.js +161 -41
  80. package/dist/panelMemoryView.js.map +1 -1
  81. package/dist/panelPassesView.d.ts +15 -0
  82. package/dist/panelPassesView.d.ts.map +1 -1
  83. package/dist/panelPassesView.js +202 -72
  84. package/dist/panelPassesView.js.map +1 -1
  85. package/dist/panelRawView.d.ts +15 -0
  86. package/dist/panelRawView.d.ts.map +1 -0
  87. package/dist/panelRawView.js +105 -0
  88. package/dist/panelRawView.js.map +1 -0
  89. package/dist/panelResourcesView.d.ts +8 -0
  90. package/dist/panelResourcesView.d.ts.map +1 -1
  91. package/dist/panelResourcesView.js +62 -31
  92. package/dist/panelResourcesView.js.map +1 -1
  93. package/dist/panelSelection.d.ts +9 -1
  94. package/dist/panelSelection.d.ts.map +1 -1
  95. package/dist/panelSelection.js +34 -4
  96. package/dist/panelSelection.js.map +1 -1
  97. package/dist/panelTheme.d.ts +13 -0
  98. package/dist/panelTheme.d.ts.map +1 -0
  99. package/dist/panelTheme.js +104 -0
  100. package/dist/panelTheme.js.map +1 -0
  101. package/dist/panelTypes.d.ts +10 -1
  102. package/dist/panelTypes.d.ts.map +1 -1
  103. package/dist/panelTypes.js.map +1 -1
  104. package/dist/panelVisualTheme.d.ts +147 -50
  105. package/dist/panelVisualTheme.d.ts.map +1 -1
  106. package/dist/panelVisualTheme.js +34 -44
  107. package/dist/panelVisualTheme.js.map +1 -1
  108. package/dist/panelWorkbenchHelpers.d.ts +12 -1
  109. package/dist/panelWorkbenchHelpers.d.ts.map +1 -1
  110. package/dist/panelWorkbenchHelpers.js +62 -1
  111. package/dist/panelWorkbenchHelpers.js.map +1 -1
  112. package/dist/panelWorkbenchStyles.d.ts +2 -0
  113. package/dist/panelWorkbenchStyles.d.ts.map +1 -0
  114. package/dist/panelWorkbenchStyles.js +101 -0
  115. package/dist/panelWorkbenchStyles.js.map +1 -0
  116. package/dist/panelWorkbenchView.d.ts +16 -0
  117. package/dist/panelWorkbenchView.d.ts.map +1 -1
  118. package/dist/panelWorkbenchView.js +228 -50
  119. package/dist/panelWorkbenchView.js.map +1 -1
  120. package/dist/query.js.map +1 -1
  121. package/dist/styles.d.ts.map +1 -1
  122. package/dist/styles.js +147 -195
  123. package/dist/styles.js.map +1 -1
  124. package/dist/theme.d.ts +22 -0
  125. package/dist/theme.d.ts.map +1 -0
  126. package/dist/theme.js +10 -0
  127. package/dist/theme.js.map +1 -0
  128. package/dist/themeDefinitions.d.ts +251 -0
  129. package/dist/themeDefinitions.d.ts.map +1 -0
  130. package/dist/themeDefinitions.js +96 -0
  131. package/dist/themeDefinitions.js.map +1 -0
  132. package/dist/themePalette.d.ts +66 -0
  133. package/dist/themePalette.d.ts.map +1 -0
  134. package/dist/themePalette.js +37 -0
  135. package/dist/themePalette.js.map +1 -0
  136. package/dist/themes.css +165 -0
  137. package/package.json +44 -10
  138. package/src/FrameGraphInspector.ts +130 -31
  139. package/src/capture.ts +4 -0
  140. package/src/debugCaptureModel.ts +53 -2
  141. package/src/index.ts +6 -2
  142. package/src/panelAliasAnalysis.ts +24 -70
  143. package/src/panelCytoscapeGraphRenderer.ts +140 -23
  144. package/src/panelDetailLayout.ts +155 -0
  145. package/src/panelDetailStyles.ts +56 -0
  146. package/src/panelDiagnosticsView.ts +166 -85
  147. package/src/panelDomHelpers.ts +4 -5
  148. package/src/panelGraphLayout.ts +6 -5
  149. package/src/panelGraphRenderer.ts +7 -0
  150. package/src/panelGraphScene.ts +68 -30
  151. package/src/panelGraphSearch.ts +96 -0
  152. package/src/panelGraphView.ts +14 -4
  153. package/src/panelGraphVisuals.ts +122 -52
  154. package/src/panelInspectorView.ts +227 -48
  155. package/src/panelListStyles.ts +154 -0
  156. package/src/panelMemoryStyles.ts +41 -0
  157. package/src/panelMemoryView.ts +178 -53
  158. package/src/panelPassesView.ts +190 -137
  159. package/src/panelRawView.ts +99 -0
  160. package/src/panelResourcesView.ts +69 -56
  161. package/src/panelSelection.ts +37 -5
  162. package/src/panelTheme.ts +85 -0
  163. package/src/panelTypes.ts +7 -1
  164. package/src/panelVisualTheme.ts +38 -49
  165. package/src/panelWorkbenchHelpers.ts +60 -2
  166. package/src/panelWorkbenchStyles.ts +100 -0
  167. package/src/panelWorkbenchView.ts +201 -52
  168. package/src/query.ts +11 -11
  169. package/src/styles.ts +148 -195
  170. package/src/theme.ts +24 -0
  171. package/src/themeDefinitions.ts +103 -0
  172. package/src/themePalette.ts +44 -0
@@ -1,77 +1,164 @@
1
1
  import { analyzeSnapshotAliases } from "./panelAliasAnalysis.js";
2
2
  import { createMutedText, labelResource } from "./panelDomHelpers.js";
3
- import { createRelationButton, formatEstimatedBytes, registerSelectable, updateSelectedRows, } from "./panelWorkbenchHelpers.js";
3
+ import { createFilterSelect, createRelationButton, createSearchInput, createViewToolbar, formatEstimatedBytes, formatEstimateCoverage, groupPath, registerSelectable, selectionKey, updateSelectedRows, } from "./panelWorkbenchHelpers.js";
4
4
  export class MemoryView {
5
5
  callbacks;
6
6
  root = document.createElement('section');
7
7
  metrics = document.createElement('div');
8
8
  scroller = document.createElement('div');
9
9
  timeline = document.createElement('div');
10
+ count = document.createElement('span');
11
+ search;
12
+ filterSelect;
10
13
  rows = new Map();
11
14
  snapshot;
12
15
  selected;
16
+ query = '';
17
+ filter = 'all';
18
+ sort = 'allocation';
13
19
  constructor(callbacks, idPrefix) {
14
20
  this.callbacks = callbacks;
15
21
  this.root.className = 'zenfg-inspector-view zenfg-inspector-memory-view';
16
22
  this.root.id = `${idPrefix}-view-memory`;
17
23
  this.root.setAttribute('role', 'tabpanel');
18
24
  this.metrics.className = 'zenfg-inspector-memory-summary';
25
+ const toolbar = createViewToolbar('Memory filters');
26
+ this.search = createSearchInput('Search memory resources or allocations', '', (value) => {
27
+ this.query = value;
28
+ this.renderTimeline();
29
+ });
30
+ this.filterSelect = createFilterSelect('Memory allocation status', this.filter, [
31
+ ['all', 'All'], ['aliased', 'Aliased'], ['single', 'Single'], ['unallocated', 'Unallocated'],
32
+ ], (value) => {
33
+ this.filter = value;
34
+ this.renderTimeline();
35
+ });
36
+ const sort = createFilterSelect('Memory sort', this.sort, [
37
+ ['allocation', 'Allocation order'], ['size', 'Size: largest first'],
38
+ ], (value) => {
39
+ this.sort = value;
40
+ this.renderTimeline();
41
+ });
42
+ const clear = document.createElement('button');
43
+ clear.type = 'button';
44
+ clear.textContent = 'Clear filters';
45
+ clear.addEventListener('click', () => this.clearFilters());
46
+ this.count.className = 'zenfg-inspector-result-count';
47
+ this.count.setAttribute('role', 'status');
48
+ toolbar.append(this.search, this.filterSelect, sort, clear, this.count);
49
+ const note = createMutedText('Whole-snapshot estimates, not total GPU memory or a measured peak. Bars include the first and last execution slots; missing lifetimes have no bar.');
50
+ note.classList.add('zenfg-inspector-memory-note');
19
51
  this.scroller.className = 'zenfg-inspector-memory-scroller';
52
+ this.scroller.setAttribute('aria-label', 'Resource lifetimes by execution slot');
20
53
  this.timeline.className = 'zenfg-inspector-memory-timeline';
21
54
  this.scroller.appendChild(this.timeline);
22
- this.root.append(this.metrics, this.scroller);
55
+ this.root.append(this.metrics, toolbar, note, this.scroller);
23
56
  }
24
57
  setSnapshot(snapshot) {
25
58
  this.snapshot = snapshot;
26
- this.render();
59
+ this.renderMetrics();
60
+ this.renderTimeline();
27
61
  }
28
62
  setSelection(selected) {
29
63
  this.selected = selected;
30
64
  updateSelectedRows(this.rows, selected);
31
65
  }
32
- render() {
66
+ /** Explicit navigation can remove filters; ordinary selection never does. */
67
+ reveal(selection) {
68
+ this.clearFilters();
69
+ this.setSelection(selection);
70
+ const row = this.rows.get(selectionKey(selection))?.[0];
71
+ row?.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });
72
+ row?.querySelector('.zenfg-inspector-relation-button')?.focus({ preventScroll: true });
73
+ }
74
+ clearFilters() {
75
+ this.query = '';
76
+ this.filter = 'all';
77
+ this.search.value = '';
78
+ this.filterSelect.value = 'all';
79
+ this.renderTimeline();
80
+ }
81
+ renderMetrics() {
33
82
  const snapshot = this.snapshot;
34
83
  if (!snapshot)
35
84
  return;
36
85
  const metrics = snapshot.metrics;
37
- this.metrics.replaceChildren(this.createMetric('Logical capacity', formatEstimatedBytes(metrics.logicalCapacityBytes)), this.createMetric('Physical estimate', formatEstimatedBytes(metrics.physicalEstimatedBytes)), this.createMetric('Alias reuse', formatEstimatedBytes(metrics.aliasReuseBytes)), this.createMetric('Allocations', `${snapshot.physicalAllocations.length} · ${metrics.aliasedAllocationCount} aliased`));
86
+ const coverage = metrics.estimatedCoverage;
87
+ const allocationAvailable = snapshot.protocol.memory.allocationReport.status === 'available';
88
+ const pool = snapshot.resourcePool;
89
+ this.metrics.replaceChildren(this.createMetric('Resource estimate', formatEstimateCoverage(metrics.transientEstimatedByteSize, coverage.transient), 'The declared estimated sizes of all transient logical resources.'), this.createMetric('Logical capacity', allocationAvailable ? formatEstimateCoverage(metrics.logicalCapacityBytes, coverage.logical) : 'Not collected', 'Assigned allocation capacity counted once per logical transient resource.'), this.createMetric('Physical estimate', allocationAvailable ? formatEstimateCoverage(metrics.physicalEstimatedBytes, coverage.physical) : 'Not collected', 'Estimated allocation sizes, counting each physical allocation once.'), this.createMetric('Alias reuse', allocationAvailable ? formatEstimatedBytes(metrics.aliasReuseBytes) : 'Not collected', 'Logical allocation capacity minus physical allocation estimate; not a measured saving.'), this.createMetric('Pool retained', pool.status === 'available' ? formatEstimatedBytes(pool.estimatedRetainedBytes) : 'Not collected', 'Estimated bytes retained by the resource pool, including allocations outside this frame.'), this.createMetric('Allocations', allocationAvailable ? `${snapshot.physicalAllocations.length} · ${metrics.aliasedAllocationCount} aliased` : 'Not collected', 'Physical allocation count for the entire snapshot.'));
90
+ }
91
+ renderTimeline() {
92
+ const snapshot = this.snapshot;
93
+ if (!snapshot)
94
+ return;
38
95
  this.rows.clear();
39
96
  this.timeline.replaceChildren();
40
97
  const analysis = analyzeSnapshotAliases(snapshot);
41
- this.timeline.appendChild(this.createAxis(analysis.minUse, analysis.maxUse));
42
- for (const group of analysis.allocations) {
43
- const selection = { kind: 'allocation', id: group.allocation.id };
44
- const header = document.createElement('div');
45
- header.className = 'zenfg-inspector-memory-allocation';
46
- header.dataset.kind = group.allocation.kind;
47
- registerSelectable(this.rows, header, selection, this.callbacks);
48
- const name = createRelationButton(`Allocation #${group.allocation.id}`, selection, this.callbacks.onSelect);
49
- const meta = document.createElement('span');
50
- meta.textContent = `${group.allocation.kind} · class ${group.allocation.compatibilityClassId} · ${formatEstimatedBytes(group.allocation.estimatedByteSize)} · ${group.resources.length > 1 ? `alias ×${group.resources.length}` : 'single'}`;
51
- header.append(name, meta);
52
- this.timeline.appendChild(header);
98
+ const ticks = analysis.hasLifetimes ? this.executionTicks(analysis.minUse, analysis.maxUse) : [];
99
+ this.timeline.appendChild(this.createAxis(analysis.minUse, analysis.maxUse, ticks));
100
+ const query = this.query.trim().toLocaleLowerCase();
101
+ const matches = (resource) => !query || [
102
+ resource.id, resource.label, groupPath(snapshot, resource.debugGroupId),
103
+ ].some((value) => value?.toLocaleLowerCase().includes(query));
104
+ const groups = analysis.allocations.flatMap((group) => {
105
+ if (this.filter === 'unallocated' || (this.filter === 'aliased' && !group.aliases) || (this.filter === 'single' && group.aliases))
106
+ return [];
107
+ const allocationMatch = !query || [group.allocation.id, group.allocation.compatibilityClassId]
108
+ .some((value) => value.toLocaleLowerCase().includes(query));
109
+ const resources = allocationMatch ? group.resources : group.resources.filter(matches);
110
+ return resources.length > 0 || allocationMatch ? [{ ...group, resources }] : [];
111
+ });
112
+ if (this.sort === 'size')
113
+ groups.sort((a, b) => compareSize(a.allocation.estimatedByteSize, b.allocation.estimatedByteSize));
114
+ let shown = 0;
115
+ for (const group of groups) {
116
+ this.timeline.appendChild(this.createAllocationHeader(group));
53
117
  for (const resource of group.resources) {
54
- this.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse));
118
+ this.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse, ticks));
119
+ shown++;
55
120
  }
56
121
  }
57
- const unallocated = snapshot.resources.filter((resource) => (resource.origin === 'transient' && resource.physicalResourceId === undefined));
122
+ const allUnallocated = snapshot.resources.filter((resource) => resource.origin === 'transient'
123
+ && (resource.physicalResourceId === undefined || !snapshot.allocationById.has(resource.physicalResourceId)));
124
+ const unallocated = this.filter === 'all' || this.filter === 'unallocated' ? allUnallocated.filter(matches) : [];
125
+ if (this.sort === 'size')
126
+ unallocated.sort((a, b) => compareSize(a.estimatedByteSize, b.estimatedByteSize));
58
127
  if (unallocated.length > 0) {
59
128
  const header = document.createElement('div');
60
129
  header.className = 'zenfg-inspector-memory-allocation muted';
61
130
  header.dataset.kind = 'unallocated';
62
- header.textContent = 'Unallocated transient resources';
131
+ header.textContent = snapshot.protocol.memory.allocationReport.status === 'available'
132
+ ? 'Unallocated transient resources' : 'Transient resources — allocation report unavailable';
63
133
  this.timeline.appendChild(header);
64
134
  for (const resource of unallocated) {
65
- this.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse));
135
+ this.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse, ticks));
136
+ shown++;
66
137
  }
67
138
  }
68
- if (analysis.allocations.length === 0 && unallocated.length === 0) {
69
- this.timeline.appendChild(createMutedText('No transient resource lifetimes.'));
139
+ const total = analysis.allocations.reduce((sum, group) => sum + group.resources.length, 0) + allUnallocated.length;
140
+ this.count.textContent = `${shown} / ${total} resources`;
141
+ if (groups.length === 0 && unallocated.length === 0) {
142
+ this.timeline.appendChild(createMutedText(total > 0 ? 'No resources match these filters.' : 'No transient resource lifetimes.'));
70
143
  }
71
144
  updateSelectedRows(this.rows, this.selected);
72
145
  }
73
- createMetric(label, value) {
146
+ createAllocationHeader(group) {
147
+ const selection = { kind: 'allocation', id: group.allocation.id };
148
+ const header = document.createElement('div');
149
+ header.className = 'zenfg-inspector-memory-allocation';
150
+ header.dataset.kind = group.allocation.kind;
151
+ registerSelectable(this.rows, header, selection, this.callbacks);
152
+ const name = createRelationButton(`Allocation ${group.allocation.id.replace(/^allocation:/, '')}`, selection, this.callbacks.onSelect);
153
+ name.title = group.allocation.id;
154
+ const meta = document.createElement('span');
155
+ meta.textContent = `${group.allocation.kind} · class ${group.allocation.compatibilityClassId} · ${formatEstimatedBytes(group.allocation.estimatedByteSize)} · ${group.aliases ? `aliased ×${group.allocation.resourceIds.length}` : 'single'}`;
156
+ header.append(name, meta);
157
+ return header;
158
+ }
159
+ createMetric(label, value, explanation) {
74
160
  const item = document.createElement('div');
161
+ item.title = explanation;
75
162
  const term = document.createElement('span');
76
163
  term.textContent = label;
77
164
  const amount = document.createElement('strong');
@@ -79,47 +166,73 @@ export class MemoryView {
79
166
  item.append(term, amount);
80
167
  return item;
81
168
  }
82
- createAxis(minUse, maxUse) {
169
+ executionTicks(minUse, maxUse) {
170
+ const count = Math.min(6, maxUse - minUse + 1);
171
+ return Array.from({ length: count }, (_, index) => count === 1 ? minUse : minUse + Math.round(index * (maxUse - minUse) / (count - 1)));
172
+ }
173
+ createAxis(minUse, maxUse, ticks) {
83
174
  const axis = document.createElement('div');
84
175
  axis.className = 'zenfg-inspector-memory-axis';
85
176
  const label = document.createElement('span');
86
- label.textContent = 'Execution order';
177
+ label.textContent = 'Resource';
178
+ const lifetime = document.createElement('span');
179
+ lifetime.textContent = 'First–last slot';
87
180
  const track = document.createElement('div');
88
181
  track.className = 'zenfg-inspector-memory-axis-track';
89
- const range = Math.max(1, maxUse - minUse);
90
- const step = Math.max(1, Math.ceil(range / 5));
91
- for (let value = minUse; value <= maxUse; value += step) {
182
+ track.setAttribute('aria-label', 'Execution slots');
183
+ if (ticks.length === 0)
184
+ track.textContent = 'No execution lifetimes';
185
+ const slots = maxUse - minUse + 1;
186
+ for (const value of ticks) {
92
187
  const tick = document.createElement('span');
93
- tick.style.left = `${((value - minUse) / range) * 100}%`;
188
+ tick.style.left = `${((value - minUse + 0.5) / slots) * 100}%`;
94
189
  tick.textContent = String(value);
95
190
  track.appendChild(tick);
96
191
  }
97
- if (maxUse > minUse && (maxUse - minUse) % step !== 0) {
98
- const tick = document.createElement('span');
99
- tick.style.left = '100%';
100
- tick.textContent = String(maxUse);
101
- track.appendChild(tick);
102
- }
103
- axis.append(label, track);
192
+ const size = document.createElement('span');
193
+ size.textContent = 'Estimate';
194
+ axis.append(label, lifetime, track, size);
104
195
  return axis;
105
196
  }
106
- createResourceRow(resource, minUse, maxUse) {
197
+ createResourceRow(resource, minUse, maxUse, ticks) {
107
198
  const selection = { kind: 'resource', id: resource.id };
108
199
  const row = document.createElement('div');
109
200
  row.className = 'zenfg-inspector-memory-resource';
110
201
  row.dataset.kind = resource.kind;
111
202
  registerSelectable(this.rows, row, selection, this.callbacks);
112
- const name = createRelationButton(labelResource(resource), selection, this.callbacks.onSelect);
203
+ const name = document.createElement('div');
204
+ name.className = 'zenfg-inspector-memory-name';
205
+ const button = createRelationButton(labelResource(resource), selection, this.callbacks.onSelect);
206
+ button.title = resource.id;
207
+ name.appendChild(button);
208
+ if (this.callbacks.onReveal) {
209
+ const reveal = document.createElement('button');
210
+ reveal.type = 'button';
211
+ reveal.className = 'zenfg-inspector-memory-reveal';
212
+ reveal.textContent = 'Locate';
213
+ reveal.title = 'Locate in Resources';
214
+ reveal.setAttribute('aria-label', `Locate ${labelResource(resource)} in Resources`);
215
+ reveal.addEventListener('click', () => this.callbacks.onReveal?.(selection, 'resources'));
216
+ name.appendChild(reveal);
217
+ }
113
218
  const range = document.createElement('span');
114
- range.textContent = resource.lifetime ? `${resource.lifetime.firstUse}–${resource.lifetime.lastUse}` : 'no lifetime';
219
+ range.textContent = resource.lifetime ? `${resource.lifetime.firstUse}–${resource.lifetime.lastUse}` : 'No lifetime';
115
220
  const track = document.createElement('div');
116
221
  track.className = 'zenfg-inspector-memory-track';
222
+ const slots = maxUse - minUse + 1;
223
+ for (const value of ticks) {
224
+ const grid = document.createElement('span');
225
+ grid.className = 'zenfg-inspector-memory-gridline';
226
+ grid.style.left = `${((value - minUse + 0.5) / slots) * 100}%`;
227
+ grid.setAttribute('aria-hidden', 'true');
228
+ track.appendChild(grid);
229
+ }
117
230
  const bar = document.createElement('span');
118
231
  bar.className = `zenfg-inspector-memory-bar ${resource.kind}`;
119
232
  if (resource.lifetime) {
120
- const slots = Math.max(1, maxUse - minUse + 1);
121
233
  bar.style.left = `${((resource.lifetime.firstUse - minUse) / slots) * 100}%`;
122
234
  bar.style.width = `${((resource.lifetime.lastUse - resource.lifetime.firstUse + 1) / slots) * 100}%`;
235
+ bar.title = `Execution slots ${resource.lifetime.firstUse}–${resource.lifetime.lastUse} (inclusive)`;
123
236
  }
124
237
  else {
125
238
  bar.classList.add('empty');
@@ -131,4 +244,11 @@ export class MemoryView {
131
244
  return row;
132
245
  }
133
246
  }
247
+ function compareSize(a, b) {
248
+ if (a === undefined)
249
+ return b === undefined ? 0 : 1;
250
+ if (b === undefined)
251
+ return -1;
252
+ return b - a;
253
+ }
134
254
  //# sourceMappingURL=panelMemoryView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"panelMemoryView.js","sourceRoot":"","sources":["../src/panelMemoryView.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameGraphDebugResource, FrameGraphDebugViewModel } from './debugCaptureModel.ts';\nimport { analyzeSnapshotAliases } from './panelAliasAnalysis.ts';\nimport { createMutedText, labelResource } from './panelDomHelpers.ts';\nimport type { Selection } from './panelTypes.ts';\nimport {\n\tcreateRelationButton,\n\tformatEstimatedBytes,\n\tregisterSelectable,\n\ttype WorkbenchCallbacks,\n\tupdateSelectedRows,\n} from './panelWorkbenchHelpers.ts';\n\nexport class MemoryView {\n\treadonly root = document.createElement('section');\n\tprivate readonly metrics = document.createElement('div');\n\tprivate readonly scroller = document.createElement('div');\n\tprivate readonly timeline = document.createElement('div');\n\tprivate readonly rows = new Map<string, HTMLElement[]>();\n\tprivate snapshot: FrameGraphDebugViewModel | undefined;\n\tprivate selected: Selection | undefined;\n\n\tconstructor(private readonly callbacks: WorkbenchCallbacks, idPrefix: string) {\n\t\tthis.root.className = 'zenfg-inspector-view zenfg-inspector-memory-view';\n\t\tthis.root.id = `${idPrefix}-view-memory`;\n\t\tthis.root.setAttribute('role', 'tabpanel');\n\t\tthis.metrics.className = 'zenfg-inspector-memory-summary';\n\t\tthis.scroller.className = 'zenfg-inspector-memory-scroller';\n\t\tthis.timeline.className = 'zenfg-inspector-memory-timeline';\n\t\tthis.scroller.appendChild(this.timeline);\n\t\tthis.root.append(this.metrics, this.scroller);\n\t}\n\n\tsetSnapshot(snapshot: FrameGraphDebugViewModel): void {\n\t\tthis.snapshot = snapshot;\n\t\tthis.render();\n\t}\n\n\tsetSelection(selected: Selection | undefined): void {\n\t\tthis.selected = selected;\n\t\tupdateSelectedRows(this.rows, selected);\n\t}\n\n\tprivate render(): void {\n\t\tconst snapshot = this.snapshot;\n\t\tif (!snapshot) return;\n\t\tconst metrics = snapshot.metrics;\n\t\tthis.metrics.replaceChildren(\n\t\t\tthis.createMetric('Logical capacity', formatEstimatedBytes(metrics.logicalCapacityBytes)),\n\t\t\tthis.createMetric('Physical estimate', formatEstimatedBytes(metrics.physicalEstimatedBytes)),\n\t\t\tthis.createMetric('Alias reuse', formatEstimatedBytes(metrics.aliasReuseBytes)),\n\t\t\tthis.createMetric('Allocations', `${snapshot.physicalAllocations.length} · ${metrics.aliasedAllocationCount} aliased`),\n\t\t);\n\t\tthis.rows.clear();\n\t\tthis.timeline.replaceChildren();\n\t\tconst analysis = analyzeSnapshotAliases(snapshot);\n\t\tthis.timeline.appendChild(this.createAxis(analysis.minUse, analysis.maxUse));\n\n\t\tfor (const group of analysis.allocations) {\n\t\t\tconst selection: Selection = { kind: 'allocation', id: group.allocation.id };\n\t\t\tconst header = document.createElement('div');\n\t\t\theader.className = 'zenfg-inspector-memory-allocation';\n\t\t\theader.dataset.kind = group.allocation.kind;\n\t\t\tregisterSelectable(this.rows, header, selection, this.callbacks);\n\t\t\tconst name = createRelationButton(`Allocation #${group.allocation.id}`, selection, this.callbacks.onSelect);\n\t\t\tconst meta = document.createElement('span');\n\t\t\tmeta.textContent = `${group.allocation.kind} · class ${group.allocation.compatibilityClassId} · ${formatEstimatedBytes(group.allocation.estimatedByteSize)} · ${group.resources.length > 1 ? `alias ×${group.resources.length}` : 'single'}`;\n\t\t\theader.append(name, meta);\n\t\t\tthis.timeline.appendChild(header);\n\t\t\tfor (const resource of group.resources) {\n\t\t\t\tthis.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse));\n\t\t\t}\n\t\t}\n\n\t\tconst unallocated = snapshot.resources.filter((resource) => (\n\t\t\tresource.origin === 'transient' && resource.physicalResourceId === undefined\n\t\t));\n\t\tif (unallocated.length > 0) {\n\t\t\tconst header = document.createElement('div');\n\t\t\theader.className = 'zenfg-inspector-memory-allocation muted';\n\t\t\theader.dataset.kind = 'unallocated';\n\t\t\theader.textContent = 'Unallocated transient resources';\n\t\t\tthis.timeline.appendChild(header);\n\t\t\tfor (const resource of unallocated) {\n\t\t\t\tthis.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse));\n\t\t\t}\n\t\t}\n\t\tif (analysis.allocations.length === 0 && unallocated.length === 0) {\n\t\t\tthis.timeline.appendChild(createMutedText('No transient resource lifetimes.'));\n\t\t}\n\t\tupdateSelectedRows(this.rows, this.selected);\n\t}\n\n\tprivate createMetric(label: string, value: string): HTMLElement {\n\t\tconst item = document.createElement('div');\n\t\tconst term = document.createElement('span');\n\t\tterm.textContent = label;\n\t\tconst amount = document.createElement('strong');\n\t\tamount.textContent = value;\n\t\titem.append(term, amount);\n\t\treturn item;\n\t}\n\n\tprivate createAxis(minUse: number, maxUse: number): HTMLElement {\n\t\tconst axis = document.createElement('div');\n\t\taxis.className = 'zenfg-inspector-memory-axis';\n\t\tconst label = document.createElement('span');\n\t\tlabel.textContent = 'Execution order';\n\t\tconst track = document.createElement('div');\n\t\ttrack.className = 'zenfg-inspector-memory-axis-track';\n\t\tconst range = Math.max(1, maxUse - minUse);\n\t\tconst step = Math.max(1, Math.ceil(range / 5));\n\t\tfor (let value = minUse; value <= maxUse; value += step) {\n\t\t\tconst tick = document.createElement('span');\n\t\t\ttick.style.left = `${((value - minUse) / range) * 100}%`;\n\t\t\ttick.textContent = String(value);\n\t\t\ttrack.appendChild(tick);\n\t\t}\n\t\tif (maxUse > minUse && (maxUse - minUse) % step !== 0) {\n\t\t\tconst tick = document.createElement('span');\n\t\t\ttick.style.left = '100%';\n\t\t\ttick.textContent = String(maxUse);\n\t\t\ttrack.appendChild(tick);\n\t\t}\n\t\taxis.append(label, track);\n\t\treturn axis;\n\t}\n\n\tprivate createResourceRow(resource: FrameGraphDebugResource, minUse: number, maxUse: number): HTMLElement {\n\t\tconst selection: Selection = { kind: 'resource', id: resource.id };\n\t\tconst row = document.createElement('div');\n\t\trow.className = 'zenfg-inspector-memory-resource';\n\t\trow.dataset.kind = resource.kind;\r\n\t\tregisterSelectable(this.rows, row, selection, this.callbacks);\n\t\tconst name = createRelationButton(labelResource(resource), selection, this.callbacks.onSelect);\n\t\tconst range = document.createElement('span');\n\t\trange.textContent = resource.lifetime ? `${resource.lifetime.firstUse}–${resource.lifetime.lastUse}` : 'no lifetime';\n\t\tconst track = document.createElement('div');\n\t\ttrack.className = 'zenfg-inspector-memory-track';\n\t\tconst bar = document.createElement('span');\n\t\tbar.className = `zenfg-inspector-memory-bar ${resource.kind}`;\n\t\tif (resource.lifetime) {\n\t\t\tconst slots = Math.max(1, maxUse - minUse + 1);\n\t\t\tbar.style.left = `${((resource.lifetime.firstUse - minUse) / slots) * 100}%`;\n\t\t\tbar.style.width = `${((resource.lifetime.lastUse - resource.lifetime.firstUse + 1) / slots) * 100}%`;\n\t\t} else {\n\t\t\tbar.classList.add('empty');\n\t\t}\n\t\ttrack.appendChild(bar);\n\t\tconst size = document.createElement('span');\n\t\tsize.textContent = formatEstimatedBytes(resource.estimatedByteSize);\n\t\trow.append(name, range, track, size);\n\t\treturn row;\n\t}\n}\n"]}
1
+ {"version":3,"file":"panelMemoryView.js","sourceRoot":"","sources":["../src/panelMemoryView.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FrameGraphDebugResource, FrameGraphDebugViewModel } from './debugCaptureModel.ts';\nimport { analyzeSnapshotAliases, type AliasAnalysisAllocation } from './panelAliasAnalysis.ts';\nimport { createMutedText, labelResource } from './panelDomHelpers.ts';\nimport type { Selection } from './panelTypes.ts';\nimport {\n\tcreateFilterSelect, createRelationButton, createSearchInput, createViewToolbar,\n\tformatEstimatedBytes, formatEstimateCoverage, groupPath, registerSelectable,\n\tselectionKey, type WorkbenchCallbacks, updateSelectedRows,\n} from './panelWorkbenchHelpers.ts';\n\ntype MemoryFilter = 'all' | 'aliased' | 'single' | 'unallocated';\ntype MemorySort = 'allocation' | 'size';\n\nexport class MemoryView {\n\treadonly root = document.createElement('section');\n\tprivate readonly metrics = document.createElement('div');\n\tprivate readonly scroller = document.createElement('div');\n\tprivate readonly timeline = document.createElement('div');\n\tprivate readonly count = document.createElement('span');\n\tprivate readonly search: HTMLInputElement;\n\tprivate readonly filterSelect: HTMLSelectElement;\n\tprivate readonly rows = new Map<string, HTMLElement[]>();\n\tprivate snapshot: FrameGraphDebugViewModel | undefined;\n\tprivate selected: Selection | undefined;\n\tprivate query = '';\n\tprivate filter: MemoryFilter = 'all';\n\tprivate sort: MemorySort = 'allocation';\n\n\tconstructor(private readonly callbacks: WorkbenchCallbacks, idPrefix: string) {\n\t\tthis.root.className = 'zenfg-inspector-view zenfg-inspector-memory-view';\n\t\tthis.root.id = `${idPrefix}-view-memory`;\n\t\tthis.root.setAttribute('role', 'tabpanel');\n\t\tthis.metrics.className = 'zenfg-inspector-memory-summary';\n\t\tconst toolbar = createViewToolbar('Memory filters');\n\t\tthis.search = createSearchInput('Search memory resources or allocations', '', (value) => {\n\t\t\tthis.query = value;\n\t\t\tthis.renderTimeline();\n\t\t});\n\t\tthis.filterSelect = createFilterSelect('Memory allocation status', this.filter, [\n\t\t\t['all', 'All'], ['aliased', 'Aliased'], ['single', 'Single'], ['unallocated', 'Unallocated'],\n\t\t], (value) => {\n\t\t\tthis.filter = value as MemoryFilter;\n\t\t\tthis.renderTimeline();\n\t\t});\n\t\tconst sort = createFilterSelect('Memory sort', this.sort, [\n\t\t\t['allocation', 'Allocation order'], ['size', 'Size: largest first'],\n\t\t], (value) => {\n\t\t\tthis.sort = value as MemorySort;\n\t\t\tthis.renderTimeline();\n\t\t});\n\t\tconst clear = document.createElement('button');\n\t\tclear.type = 'button';\n\t\tclear.textContent = 'Clear filters';\n\t\tclear.addEventListener('click', () => this.clearFilters());\n\t\tthis.count.className = 'zenfg-inspector-result-count';\n\t\tthis.count.setAttribute('role', 'status');\n\t\ttoolbar.append(this.search, this.filterSelect, sort, clear, this.count);\n\t\tconst note = createMutedText('Whole-snapshot estimates, not total GPU memory or a measured peak. Bars include the first and last execution slots; missing lifetimes have no bar.');\n\t\tnote.classList.add('zenfg-inspector-memory-note');\n\t\tthis.scroller.className = 'zenfg-inspector-memory-scroller';\n\t\tthis.scroller.setAttribute('aria-label', 'Resource lifetimes by execution slot');\n\t\tthis.timeline.className = 'zenfg-inspector-memory-timeline';\n\t\tthis.scroller.appendChild(this.timeline);\n\t\tthis.root.append(this.metrics, toolbar, note, this.scroller);\n\t}\n\n\tsetSnapshot(snapshot: FrameGraphDebugViewModel): void {\n\t\tthis.snapshot = snapshot;\n\t\tthis.renderMetrics();\n\t\tthis.renderTimeline();\n\t}\n\n\tsetSelection(selected: Selection | undefined): void {\n\t\tthis.selected = selected;\n\t\tupdateSelectedRows(this.rows, selected);\n\t}\n\n\t/** Explicit navigation can remove filters; ordinary selection never does. */\n\treveal(selection: Selection): void {\n\t\tthis.clearFilters();\n\t\tthis.setSelection(selection);\n\t\tconst row = this.rows.get(selectionKey(selection))?.[0];\n\t\trow?.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });\n\t\trow?.querySelector<HTMLButtonElement>('.zenfg-inspector-relation-button')?.focus({ preventScroll: true });\n\t}\n\n\tprivate clearFilters(): void {\n\t\tthis.query = '';\n\t\tthis.filter = 'all';\n\t\tthis.search.value = '';\n\t\tthis.filterSelect.value = 'all';\n\t\tthis.renderTimeline();\n\t}\n\n\tprivate renderMetrics(): void {\n\t\tconst snapshot = this.snapshot;\n\t\tif (!snapshot) return;\n\t\tconst metrics = snapshot.metrics;\n\t\tconst coverage = metrics.estimatedCoverage;\n\t\tconst allocationAvailable = snapshot.protocol.memory.allocationReport.status === 'available';\n\t\tconst pool = snapshot.resourcePool;\n\t\tthis.metrics.replaceChildren(\n\t\t\tthis.createMetric('Resource estimate', formatEstimateCoverage(metrics.transientEstimatedByteSize, coverage.transient),\n\t\t\t\t'The declared estimated sizes of all transient logical resources.'),\n\t\t\tthis.createMetric('Logical capacity', allocationAvailable ? formatEstimateCoverage(metrics.logicalCapacityBytes, coverage.logical) : 'Not collected',\n\t\t\t\t'Assigned allocation capacity counted once per logical transient resource.'),\n\t\t\tthis.createMetric('Physical estimate', allocationAvailable ? formatEstimateCoverage(metrics.physicalEstimatedBytes, coverage.physical) : 'Not collected',\n\t\t\t\t'Estimated allocation sizes, counting each physical allocation once.'),\n\t\t\tthis.createMetric('Alias reuse', allocationAvailable ? formatEstimatedBytes(metrics.aliasReuseBytes) : 'Not collected',\n\t\t\t\t'Logical allocation capacity minus physical allocation estimate; not a measured saving.'),\n\t\t\tthis.createMetric('Pool retained', pool.status === 'available' ? formatEstimatedBytes(pool.estimatedRetainedBytes) : 'Not collected',\n\t\t\t\t'Estimated bytes retained by the resource pool, including allocations outside this frame.'),\n\t\t\tthis.createMetric('Allocations', allocationAvailable ? `${snapshot.physicalAllocations.length} · ${metrics.aliasedAllocationCount} aliased` : 'Not collected',\n\t\t\t\t'Physical allocation count for the entire snapshot.'),\n\t\t);\n\t}\n\n\tprivate renderTimeline(): void {\n\t\tconst snapshot = this.snapshot;\n\t\tif (!snapshot) return;\n\t\tthis.rows.clear();\n\t\tthis.timeline.replaceChildren();\n\t\tconst analysis = analyzeSnapshotAliases(snapshot);\n\t\tconst ticks = analysis.hasLifetimes ? this.executionTicks(analysis.minUse, analysis.maxUse) : [];\n\t\tthis.timeline.appendChild(this.createAxis(analysis.minUse, analysis.maxUse, ticks));\n\t\tconst query = this.query.trim().toLocaleLowerCase();\n\t\tconst matches = (resource: FrameGraphDebugResource): boolean => !query || [\n\t\t\tresource.id, resource.label, groupPath(snapshot, resource.debugGroupId),\n\t\t].some((value) => value?.toLocaleLowerCase().includes(query));\n\t\tconst groups = analysis.allocations.flatMap((group) => {\n\t\t\tif (this.filter === 'unallocated' || (this.filter === 'aliased' && !group.aliases) || (this.filter === 'single' && group.aliases)) return [];\n\t\t\tconst allocationMatch = !query || [group.allocation.id, group.allocation.compatibilityClassId]\n\t\t\t\t.some((value) => value.toLocaleLowerCase().includes(query));\n\t\t\tconst resources = allocationMatch ? group.resources : group.resources.filter(matches);\n\t\t\treturn resources.length > 0 || allocationMatch ? [{ ...group, resources }] : [];\n\t\t});\n\t\tif (this.sort === 'size') groups.sort((a, b) => compareSize(a.allocation.estimatedByteSize, b.allocation.estimatedByteSize));\n\t\tlet shown = 0;\n\t\tfor (const group of groups) {\n\t\t\tthis.timeline.appendChild(this.createAllocationHeader(group));\n\t\t\tfor (const resource of group.resources) {\n\t\t\t\tthis.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse, ticks));\n\t\t\t\tshown++;\n\t\t\t}\n\t\t}\n\n\t\tconst allUnallocated = snapshot.resources.filter((resource) => resource.origin === 'transient'\n\t\t\t&& (resource.physicalResourceId === undefined || !snapshot.allocationById.has(resource.physicalResourceId)));\n\t\tconst unallocated = this.filter === 'all' || this.filter === 'unallocated' ? allUnallocated.filter(matches) : [];\n\t\tif (this.sort === 'size') unallocated.sort((a, b) => compareSize(a.estimatedByteSize, b.estimatedByteSize));\n\t\tif (unallocated.length > 0) {\n\t\t\tconst header = document.createElement('div');\n\t\t\theader.className = 'zenfg-inspector-memory-allocation muted';\n\t\t\theader.dataset.kind = 'unallocated';\n\t\t\theader.textContent = snapshot.protocol.memory.allocationReport.status === 'available'\n\t\t\t\t? 'Unallocated transient resources' : 'Transient resources — allocation report unavailable';\n\t\t\tthis.timeline.appendChild(header);\n\t\t\tfor (const resource of unallocated) {\n\t\t\t\tthis.timeline.appendChild(this.createResourceRow(resource, analysis.minUse, analysis.maxUse, ticks));\n\t\t\t\tshown++;\n\t\t\t}\n\t\t}\n\t\tconst total = analysis.allocations.reduce((sum, group) => sum + group.resources.length, 0) + allUnallocated.length;\n\t\tthis.count.textContent = `${shown} / ${total} resources`;\n\t\tif (groups.length === 0 && unallocated.length === 0) {\n\t\t\tthis.timeline.appendChild(createMutedText(total > 0 ? 'No resources match these filters.' : 'No transient resource lifetimes.'));\n\t\t}\n\t\tupdateSelectedRows(this.rows, this.selected);\n\t}\n\n\tprivate createAllocationHeader(group: AliasAnalysisAllocation): HTMLElement {\n\t\tconst selection: Selection = { kind: 'allocation', id: group.allocation.id };\n\t\tconst header = document.createElement('div');\n\t\theader.className = 'zenfg-inspector-memory-allocation';\n\t\theader.dataset.kind = group.allocation.kind;\n\t\tregisterSelectable(this.rows, header, selection, this.callbacks);\n\t\tconst name = createRelationButton(`Allocation ${group.allocation.id.replace(/^allocation:/, '')}`, selection, this.callbacks.onSelect);\n\t\tname.title = group.allocation.id;\n\t\tconst meta = document.createElement('span');\n\t\tmeta.textContent = `${group.allocation.kind} · class ${group.allocation.compatibilityClassId} · ${formatEstimatedBytes(group.allocation.estimatedByteSize)} · ${group.aliases ? `aliased ×${group.allocation.resourceIds.length}` : 'single'}`;\n\t\theader.append(name, meta);\n\t\treturn header;\n\t}\n\n\tprivate createMetric(label: string, value: string, explanation: string): HTMLElement {\n\t\tconst item = document.createElement('div');\n\t\titem.title = explanation;\n\t\tconst term = document.createElement('span');\n\t\tterm.textContent = label;\n\t\tconst amount = document.createElement('strong');\n\t\tamount.textContent = value;\n\t\titem.append(term, amount);\n\t\treturn item;\n\t}\n\n\tprivate executionTicks(minUse: number, maxUse: number): number[] {\n\t\tconst count = Math.min(6, maxUse - minUse + 1);\n\t\treturn Array.from({ length: count }, (_, index) => count === 1 ? minUse : minUse + Math.round(index * (maxUse - minUse) / (count - 1)));\n\t}\n\n\tprivate createAxis(minUse: number, maxUse: number, ticks: readonly number[]): HTMLElement {\n\t\tconst axis = document.createElement('div');\n\t\taxis.className = 'zenfg-inspector-memory-axis';\n\t\tconst label = document.createElement('span');\n\t\tlabel.textContent = 'Resource';\n\t\tconst lifetime = document.createElement('span');\n\t\tlifetime.textContent = 'First–last slot';\n\t\tconst track = document.createElement('div');\n\t\ttrack.className = 'zenfg-inspector-memory-axis-track';\n\t\ttrack.setAttribute('aria-label', 'Execution slots');\n\t\tif (ticks.length === 0) track.textContent = 'No execution lifetimes';\n\t\tconst slots = maxUse - minUse + 1;\n\t\tfor (const value of ticks) {\n\t\t\tconst tick = document.createElement('span');\n\t\t\ttick.style.left = `${((value - minUse + 0.5) / slots) * 100}%`;\n\t\t\ttick.textContent = String(value);\n\t\t\ttrack.appendChild(tick);\n\t\t}\n\t\tconst size = document.createElement('span');\n\t\tsize.textContent = 'Estimate';\n\t\taxis.append(label, lifetime, track, size);\n\t\treturn axis;\n\t}\n\n\tprivate createResourceRow(resource: FrameGraphDebugResource, minUse: number, maxUse: number, ticks: readonly number[]): HTMLElement {\n\t\tconst selection: Selection = { kind: 'resource', id: resource.id };\n\t\tconst row = document.createElement('div');\n\t\trow.className = 'zenfg-inspector-memory-resource';\n\t\trow.dataset.kind = resource.kind;\n\t\tregisterSelectable(this.rows, row, selection, this.callbacks);\n\t\tconst name = document.createElement('div');\n\t\tname.className = 'zenfg-inspector-memory-name';\n\t\tconst button = createRelationButton(labelResource(resource), selection, this.callbacks.onSelect);\n\t\tbutton.title = resource.id;\n\t\tname.appendChild(button);\n\t\tif (this.callbacks.onReveal) {\n\t\t\tconst reveal = document.createElement('button');\n\t\t\treveal.type = 'button';\n\t\t\treveal.className = 'zenfg-inspector-memory-reveal';\n\t\t\treveal.textContent = 'Locate';\n\t\t\treveal.title = 'Locate in Resources';\n\t\t\treveal.setAttribute('aria-label', `Locate ${labelResource(resource)} in Resources`);\n\t\t\treveal.addEventListener('click', () => this.callbacks.onReveal?.(selection, 'resources'));\n\t\t\tname.appendChild(reveal);\n\t\t}\n\t\tconst range = document.createElement('span');\n\t\trange.textContent = resource.lifetime ? `${resource.lifetime.firstUse}–${resource.lifetime.lastUse}` : 'No lifetime';\n\t\tconst track = document.createElement('div');\n\t\ttrack.className = 'zenfg-inspector-memory-track';\n\t\tconst slots = maxUse - minUse + 1;\n\t\tfor (const value of ticks) {\n\t\t\tconst grid = document.createElement('span');\n\t\t\tgrid.className = 'zenfg-inspector-memory-gridline';\n\t\t\tgrid.style.left = `${((value - minUse + 0.5) / slots) * 100}%`;\n\t\t\tgrid.setAttribute('aria-hidden', 'true');\n\t\t\ttrack.appendChild(grid);\n\t\t}\n\t\tconst bar = document.createElement('span');\n\t\tbar.className = `zenfg-inspector-memory-bar ${resource.kind}`;\n\t\tif (resource.lifetime) {\n\t\t\tbar.style.left = `${((resource.lifetime.firstUse - minUse) / slots) * 100}%`;\n\t\t\tbar.style.width = `${((resource.lifetime.lastUse - resource.lifetime.firstUse + 1) / slots) * 100}%`;\n\t\t\tbar.title = `Execution slots ${resource.lifetime.firstUse}–${resource.lifetime.lastUse} (inclusive)`;\n\t\t} else {\n\t\t\tbar.classList.add('empty');\n\t\t}\n\t\ttrack.appendChild(bar);\n\t\tconst size = document.createElement('span');\n\t\tsize.textContent = formatEstimatedBytes(resource.estimatedByteSize);\n\t\trow.append(name, range, track, size);\n\t\treturn row;\n\t}\n}\n\nfunction compareSize(a: number | undefined, b: number | undefined): number {\n\tif (a === undefined) return b === undefined ? 0 : 1;\n\tif (b === undefined) return -1;\n\treturn b - a;\n}\n"]}
@@ -5,6 +5,7 @@ export declare class PassesView {
5
5
  private readonly callbacks;
6
6
  readonly root: HTMLElement;
7
7
  private readonly toolbar;
8
+ private readonly groupToolbar;
8
9
  private readonly tabList;
9
10
  private readonly listButton;
10
11
  private readonly groupsButton;
@@ -13,18 +14,32 @@ export declare class PassesView {
13
14
  private readonly listTable;
14
15
  private readonly groupsTable;
15
16
  private readonly rows;
17
+ private readonly collapsedGroups;
18
+ private readonly count;
19
+ private readonly groupCount;
20
+ private readonly timing;
21
+ private readonly searchInput;
22
+ private readonly groupSearchInput;
23
+ private readonly kindSelect;
24
+ private readonly statusSelect;
16
25
  private snapshot;
17
26
  private selected;
18
27
  private subview;
19
28
  private search;
29
+ private groupSearch;
20
30
  private kind;
31
+ private status;
21
32
  private sort;
22
33
  constructor(callbacks: WorkbenchCallbacks, idPrefix: string);
23
34
  setSnapshot(snapshot: FrameGraphDebugViewModel): void;
24
35
  setSelection(selected: Selection | undefined): void;
36
+ showCulled(): void;
37
+ reveal(selection: Selection): void;
38
+ private clearFilters;
25
39
  private createSubviewButton;
26
40
  private updateSubview;
27
41
  private renderRows;
42
+ private renderGroups;
28
43
  private matchesNode;
29
44
  private compareNodes;
30
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"panelPassesView.d.ts","sourceRoot":"","sources":["../src/panelPassesView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAE5F,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAUN,KAAK,kBAAkB,EAEvB,MAAM,4BAA4B,CAAC;AAIpC,qBAAa,UAAU;IAmCV,OAAO,CAAC,QAAQ,CAAC,SAAS;IAlCtC,QAAQ,CAAC,IAAI,cAAqC;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiD;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiD;IAC5E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyD;IACtF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CASvB;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAQzB;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoC;IACzD,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAqB;gBAEJ,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM;IAsD5E,WAAW,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI;IAQrD,YAAY,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI;IAKnD,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,UAAU;IA+DlB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,YAAY;CAQpB"}
1
+ {"version":3,"file":"panelPassesView.d.ts","sourceRoot":"","sources":["../src/panelPassesView.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6C,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElH,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAGuC,KAAK,kBAAkB,EACpE,MAAM,4BAA4B,CAAC;AAUpC,qBAAa,UAAU;IAoCV,OAAO,CAAC,QAAQ,CAAC,SAAS;IAnCtC,QAAQ,CAAC,IAAI,cAAqC;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiD;IACzE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAClE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiD;IAC5E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyD;IACtF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAGvB;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAIzB;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoC;IACzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAqB;gBAEJ,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM;IAoD5E,WAAW,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI;IAQrD,YAAY,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI;IAInD,UAAU,IAAI,IAAI;IAKlB,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAelC,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,UAAU;IAuClB,OAAO,CAAC,YAAY;IA0DpB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,YAAY;CAWpB"}