Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: tracing/tracing/ui/extras/side_panel/frame_data_side_panel.html

Issue 1996303002: [Tracing] Introduce Frame Data Side Panel (Closed) Base URL: https://github.com/catapult-project/catapult.git@master
Patch Set: Address review comments; Move BlameContext.attributedEvents computation logic in Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!DOCTYPE html>
2 <!--
3 Copyright 2016 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
6 -->
7
8 <link rel="import" href="/tracing/ui/base/table.html">
9 <link rel="import" href="/tracing/ui/side_panel/side_panel.html">
10 <link rel="import" href="/tracing/value/ui/scalar_span.html">
11 <link rel="import" href="/tracing/value/unit.html">
12
13 <polymer-element name='tr-ui-e-s-frame-data-side-panel'
14 extends='tr-ui-side-panel'>
15 <template>
16 <style>
17 :host {
18 display: flex;
19 width: 600px;
20 flex-direction: column;
21 }
22 table-container {
23 display: flex;
24 overflow: auto;
25 }
26 </style>
27 <table-container>
28 <tr-ui-b-table id="table"></tr-ui-b-table>
29 </table-container>
30 </template>
31 </polymer-element>
32
33 <script>
34 'use strict';
35 tr.exportTo('tr.ui.e.s', function() {
36
37 /**
38 * @constructor
39 */
40 function Row(context) {
41 this.type = context.objectInstance.blameContextType;
42 this.contexts = [context];
43 if (context.crossProcessCounterpart)
44 this.contexts.push(context.crossProcessCounterpart);
45
46 // TODO(xiaochengh): Handle the case where a subframe has a trivial url
47 // (e.g., about:blank), but inherits the origin of its parent. This is not
48 // needed now, but will be required if we want to group rows by origin.
49 this.url = context.url;
50
51 this.renderer = undefined;
52 this.contexts.some(function(context) {
53 if (context.objectInstance.isTracedByRenderer) {
54 this.renderer = context.objectInstance.pid;
55 return true;
56 }
57 }, this);
58
59 // To be computed in batch later for efficiency.
60 this.eventsOfInterest = new tr.model.EventSet(this.contexts);
61 this.time = 0;
62 }
63
64 Polymer('tr-ui-e-s-frame-data-side-panel', {
65 ready: function() {
66 this.model_ = undefined;
67 this.rangeOfInterest_ = new tr.b.Range();
68
69 // TODO(xiaochengh): Design proper grouping of the rows (by renderer
70 // pid, frame tree topology, site, ...) in a follow-up patch.
71 this.$.table.showHeader = true;
72 this.$.table.selectionMode = tr.ui.b.TableFormat.SelectionMode.ROW;
73 this.$.table.tableColumns = this.createFrameDataTableColumns_();
74
75 this.$.table.addEventListener('selection-changed', function(e) {
76 this.selectEventSet_(this.$.table.selectedTableRow.eventsOfInterest);
77 }.bind(this));
78 },
79
80 selectEventSet_: function(eventSet) {
81 var event = new tr.model.RequestSelectionChangeEvent();
82 event.selection = eventSet;
83 this.dispatchEvent(event);
84 },
85
86 createFrameDataTableColumns_: function() {
87 return [
88 {
89 title: 'Renderer',
90 value: row => row.renderer,
91 cmp: (a, b) => a.renderer - b.renderer
92 },
93 {
94 title: 'Type',
95 value: row => row.type
96 },
97 // TODO(xiaochengh): Decide what details to show in the table:
98 // - URL seems necessary, but we may also want origin instead/both.
99 // - Distinguish between browser time and renderer time?
100 // - Distinguish between CPU time and wall clock time?
101 // - Memory? Network? ...
102 {
103 title: 'Time',
104 value: row => tr.v.ui.createScalarSpan(row.time, {
105 unit: tr.v.Unit.byName.timeStampInMs,
petrcermak 2016/05/31 09:57:24 nit: we generally indent 2 spaces inside object li
Xiaocheng 2016/05/31 12:01:10 Done.
106 ownerDocument: this.ownerDocument
107 }
108 ),
109 cmp: (a, b) => a.time - b.time
110 },
111 {
112 title: 'URL',
113 value: row => row.url,
114 cmp: (a, b) => (a.url || '').localeCompare(b.url)
petrcermak 2016/05/31 09:57:24 |''.localeCompared(undefined)| returns -1 while |'
Xiaocheng 2016/05/31 12:01:11 Done.
115 }
116 ];
117 },
118
119 createFrameDataTableRows_: function() {
120 if (!this.model_)
121 return [];
122
123 // Gather contexts into skeletons of rows.
124 var rows = [];
125 var rowMap = {};
126 tr.b.iterItems(this.model_.processes, function(pid, process) {
127 process.objects.iterObjectInstances(function(objectInstance) {
128 if (!objectInstance.blameContextType)
129 return;
130 objectInstance.snapshots.forEach(function(snapshot) {
131 if (rowMap[snapshot.guid])
132 return;
133 var row = new Row(snapshot);
134 row.contexts.forEach(context => rowMap[context.guid] = row);
135 rows.push(row);
136 }, this);
137 }, this);
138 }, this);
139
140 // Find slices attributed to each row.
141 tr.b.iterItems(this.model_.processes, function(pid, process) {
142 tr.b.iterItems(process.threads, function(tid, thread) {
143 // TODO(xiaochengh): Is it possible for AsyncSlices to be attributed?
144 // Currently they are just ignored.
145 thread.sliceGroup.iterSlicesInTimeRange(function(topLevelSlice) {
146 topLevelSlice.contexts.forEach(function(context) {
147 if (!context.snapshot.guid || !rowMap[context.snapshot.guid]) {
148 // TODO(xiaochengh): Throw some warning for broken reference.
149 return;
150 }
151 var row = rowMap[context.snapshot.guid];
152 row.eventsOfInterest.push(topLevelSlice);
153 row.time += topLevelSlice.selfTime || 0;
154 });
155 }, this.currentRangeOfInterest.min, this.currentRangeOfInterest.max);
156 }, this);
157 }, this);
158
159 return rows;
160 },
161 updateContents_: function() {
162 this.$.table.tableRows = this.createFrameDataTableRows_();
163 this.$.table.rebuild();
164 },
165
166 supportsModel: function(m) {
167 if (!m) {
168 return {
169 supported: false,
170 reason: 'No model available.'
171 };
172 }
173
174 var ans = {supported: false};
175 tr.b.iterItems(m.processes, function(pid, process) {
176 process.objects.iterObjectInstances(function(instance) {
177 if (instance.blameContextType)
178 ans.supported = true;
179 });
180 }, this);
181
182 if (!ans.supported)
183 ans.reason = 'No frame data available';
184 return ans;
185 },
186
187 get currentRangeOfInterest() {
188 if (this.rangeOfInterest_.isEmpty)
189 return this.model_.bounds;
190 else
191 return this.rangeOfInterest_;
192 },
193
194 get rangeOfInterest() {
195 return this.rangeOfInterest_;
196 },
197
198 set rangeOfInterest(rangeOfInterest) {
199 this.rangeOfInterest_ = rangeOfInterest;
200 this.updateContents_();
201 },
202
203 get selection() {
204 // Not applicable.
205 },
206
207 set selection(_) {
208 // Not applicable.
209 },
210
211 get textLabel() {
212 return 'Frame Data';
213 },
214
215 get model() {
216 return this.model_;
217 },
218
219 set model(model) {
220 this.model_ = model;
221 this.updateContents_();
222 }
223 });
224 });
225 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698