Commit 5054efae authored by nduca@chromium.org's avatar nduca@chromium.org

Tons of timeline tweaks

- Dont resize or invalidate until attached to the document.
- Unregister handlers on global objects when detached.
- Dont handle input events when TimelineView is focusable.
- Reduce console spam.
- Move dragBox offscreen, fixing bug where scroll resets when dragging.
- Size heading dynamically using measuring stick
- Disable text eliding [was causing huge GC pauses]

Review URL: http://codereview.chromium.org/8359025

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@109814 0039d316-1c4b-4281-b951-d872f2087c98
parent 5924c874
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<include src="tracing/tracing_controller.js"> <include src="tracing/tracing_controller.js">
<include src="tracing/timeline_model.js"> <include src="tracing/timeline_model.js">
<include src="tracing/sorted_array_utils.js"> <include src="tracing/sorted_array_utils.js">
<include src="tracing/measuring_stick.js">
<include src="tracing/timeline.js"> <include src="tracing/timeline.js">
<include src="tracing/timeline_track.js"> <include src="tracing/timeline_track.js">
<include src="tracing/fast_rect_renderer.js"> <include src="tracing/fast_rect_renderer.js">
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
cr.define('tracing', function() {
/**
* Uses an embedded iframe to measure provided elements without forcing layout
* on the main document.
* @constructor
* @extends {Object}
*/
function MeasuringStick() {
var iframe = document.createElement('iframe');
iframe.style.cssText = 'width:100%;height:0;border:0;visibility:hidden';
document.body.appendChild(iframe);
this._doc = iframe.contentDocument;
this._window = iframe.contentWindow;
this._doc.body.style.cssText = 'padding:0;margin:0;overflow:hidden';
var stylesheets = document.querySelectorAll('link[rel=stylesheet]');
for (var i = 0; i < stylesheets.length; i++) {
var stylesheet = stylesheets[i];
var link = this._doc.createElement('link');
link.rel = 'stylesheet';
link.href = stylesheet.href;
this._doc.head.appendChild(link);
}
}
MeasuringStick.prototype = {
__proto__: Object.prototype,
/**
* Measures the provided element without forcing layout on the main
* document.
*/
measure: function(element) {
this._doc.body.appendChild(element);
var style = this._window.getComputedStyle(element);
var width = parseInt(style.width, 10);
var height = parseInt(style.height, 10);
this._doc.body.removeChild(element);
return { width: width, height: height };
}
};
return {
MeasuringStick: MeasuringStick
};
});
...@@ -5,17 +5,16 @@ found in the LICENSE file. ...@@ -5,17 +5,16 @@ found in the LICENSE file.
*/ */
.timeline-drag-box { .timeline-drag-box {
position: fixed;
background-color: rgba(0, 0, 255, 0.25); background-color: rgba(0, 0, 255, 0.25);
border: 1px solid rgb(0, 0, 96); border: 1px solid #000060
font-size: 75%; font-size: 75%;
position: fixed;
} }
.timeline-thread-track { .timeline-thread-track {
display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
padding-top: 1px; display: -webkit-box;
padding-bottom: 1px; padding: 1px 0;
} }
.timeline-thread-track:not(:first-child) { .timeline-thread-track:not(:first-child) {
...@@ -23,21 +22,22 @@ found in the LICENSE file. ...@@ -23,21 +22,22 @@ found in the LICENSE file.
} }
.timeline-slice-track { .timeline-slice-track {
display: -webkit-box;
-webkit-box-orient: horizontal; -webkit-box-orient: horizontal;
-webkit-box-align: stretch; -webkit-box-align: stretch;
background-color: white; background-color: white;
padding-right: 5px; display: -webkit-box;
height: 18px;
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 18px; padding-right: 5px;
} }
.timeline-slice-track-title { .timeline-slice-track-title {
text-align: right; overflow: hidden;
overflow: visible;
width: 300px;
padding-right: 5px; padding-right: 5px;
text-align: right;
text-overflow: ellipsis;
white-space: nowrap;
} }
.timeline-slice-track-canvas-container { .timeline-slice-track-canvas-container {
...@@ -47,6 +47,6 @@ found in the LICENSE file. ...@@ -47,6 +47,6 @@ found in the LICENSE file.
.timeline-slice-track-canvas { .timeline-slice-track-canvas {
-webkit-box-flex: 1; -webkit-box-flex: 1;
width: 100%;
height: 100%; height: 100%;
width: 100%;
} }
...@@ -282,8 +282,8 @@ cr.define('tracing', function() { ...@@ -282,8 +282,8 @@ cr.define('tracing', function() {
slice.durationInUserTime = event.uts - slice.slice.startInUserTime; slice.durationInUserTime = event.uts - slice.slice.startInUserTime;
// Store the slice in a non-nested subrow. // Store the slice in a non-nested subrow.
var thread = self.getOrCreateProcess(event.pid). var thread =
getOrCreateThread(event.tid); self.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);
thread.addNonNestedSlice(slice.slice); thread.addNonNestedSlice(slice.slice);
delete state.openNonNestedSlices[name]; delete state.openNonNestedSlices[name];
} else { } else {
...@@ -298,7 +298,7 @@ cr.define('tracing', function() { ...@@ -298,7 +298,7 @@ cr.define('tracing', function() {
// Store the slice on the correct subrow. // Store the slice on the correct subrow.
var thread = self.getOrCreateProcess(event.pid) var thread = self.getOrCreateProcess(event.pid)
.getOrCreateThread(event.tid); .getOrCreateThread(event.tid);
var subRowIndex = state.openSlices.length; var subRowIndex = state.openSlices.length;
thread.getSubrow(subRowIndex).push(slice); thread.getSubrow(subRowIndex).push(slice);
...@@ -338,7 +338,7 @@ cr.define('tracing', function() { ...@@ -338,7 +338,7 @@ cr.define('tracing', function() {
} }
} else { } else {
this.importErrors.push('Unrecognized event phase: ' + event.ph + this.importErrors.push('Unrecognized event phase: ' + event.ph +
'(' + event.name + ')'); '(' + event.name + ')');
} }
} }
this.pruneEmptyThreads(); this.pruneEmptyThreads();
......
...@@ -275,9 +275,9 @@ function testUserTime() { ...@@ -275,9 +275,9 @@ function testUserTime() {
]; ];
var m = new tracing.TimelineModel(events); var m = new tracing.TimelineModel(events);
var subRow = m.processes[1].threads[1].subRows[0]; var subRow = m.processes[1].threads[1].subRows[0];
assertEquals(subRow[0].startInUserTime, 70); assertEquals(subRow[0].startInUserTime, 0.07);
assertEquals(subRow[0].durationInUserTime, 7); assertEquals(subRow[0].durationInUserTime, 0.007);
assertEquals(subRow[1].startInUserTime, 80); assertEquals(subRow[1].startInUserTime, 0.08);
assertEquals(subRow[1].durationInUserTime, 0); assertEquals(subRow[1].durationInUserTime, 0);
} }
......
...@@ -93,6 +93,22 @@ cr.define('tracing', function() { ...@@ -93,6 +93,22 @@ cr.define('tracing', function() {
this.updateChildTracks_(); this.updateChildTracks_();
}, },
/**
* @return {string} A human-readable name for the track.
*/
get heading() {
if (!this.thread_)
return '';
var tname = this.thread_.name || this.thread_.tid;
return this.thread_.parent.pid + ': ' +
tname + ':';
},
set headingWidth(width) {
for (var i = 0; i < this.tracks_.length; i++)
this.tracks_[i].headingWidth = width;
},
set viewport(v) { set viewport(v) {
this.viewport_ = v; this.viewport_ = v;
for (var i = 0; i < this.tracks_.length; i++) for (var i = 0; i < this.tracks_.length; i++)
...@@ -132,9 +148,7 @@ cr.define('tracing', function() { ...@@ -132,9 +148,7 @@ cr.define('tracing', function() {
addTrack(this, this.thread_.subRows[srI]); addTrack(this, this.thread_.subRows[srI]);
} }
if (this.tracks_.length > 0) { if (this.tracks_.length > 0) {
var tname = this.thread_.name || this.thread_.tid; this.tracks_[0].heading = this.heading;
this.tracks_[0].heading = this.thread_.parent.pid + ': ' +
tname + ':';
this.tracks_[0].tooltip = 'pid: ' + this.thread_.parent.pid + this.tracks_[0].tooltip = 'pid: ' + this.thread_.parent.pid +
', tid: ' + this.thread_.tid + ', tid: ' + this.thread_.tid +
(this.thread_.name ? ', name: ' + this.thread_.name : ''); (this.thread_.name ? ', name: ' + this.thread_.name : '');
...@@ -212,6 +226,14 @@ cr.define('tracing', function() { ...@@ -212,6 +226,14 @@ cr.define('tracing', function() {
this.ctx_ = this.canvas_.getContext('2d'); this.ctx_ = this.canvas_.getContext('2d');
}, },
set headingWidth(width) {
this.headingDiv_.style.width = width;
},
get heading() {
return this.headingDiv_.textContent;
},
set heading(text) { set heading(text) {
this.headingDiv_.textContent = text; this.headingDiv_.textContent = text;
}, },
...@@ -335,21 +357,13 @@ cr.define('tracing', function() { ...@@ -335,21 +357,13 @@ cr.define('tracing', function() {
if (slice.didNotFinish) { if (slice.didNotFinish) {
title += ' (Did Not Finish)'; title += ' (Did Not Finish)';
} }
function labelWidth() { var labelWidth = quickMeasureText(ctx, title) + 2;
return quickMeasureText(ctx, title) + 2; var labelWidthWorld = pixWidth * labelWidth;
}
function labelWidthWorld() { if (labelWidthWorld < slice.duration) {
return pixWidth * labelWidth(); var cX = vp.xWorldToView(slice.start + 0.5 * slice.duration);
} ctx.fillText(title, cX, 2.5, labelWidthWorld);
var elided = false;
while (labelWidthWorld() > slice.duration) {
title = title.substring(0, title.length * 0.75);
elided = true;
} }
if (elided && title.length > 3)
title = title.substring(0, title.length - 3) + '...';
var cX = vp.xWorldToView(slice.start + 0.5 * slice.duration);
ctx.fillText(title, cX, 2.5, labelWidthWorld());
} }
} }
}, },
...@@ -443,7 +457,7 @@ cr.define('tracing', function() { ...@@ -443,7 +457,7 @@ cr.define('tracing', function() {
return index != undefined ? this.slices_[index] : undefined; return index != undefined ? this.slices_[index] : undefined;
}, },
/** /**
* Return the previous slice, if any, before the given slice. * Return the previous slice, if any, before the given slice.
* @param {slice} A slice. * @param {slice} A slice.
* @return {slice} The previous slice, or undefined. * @return {slice} The previous slice, or undefined.
...@@ -455,7 +469,7 @@ cr.define('tracing', function() { ...@@ -455,7 +469,7 @@ cr.define('tracing', function() {
else if ((index != undefined) && (index > 0)) else if ((index != undefined) && (index > 0))
index--; index--;
return index != undefined ? this.slices_[index] : undefined; return index != undefined ? this.slices_[index] : undefined;
}, }
}; };
......
...@@ -64,7 +64,6 @@ cr.define('tracing', function() { ...@@ -64,7 +64,6 @@ cr.define('tracing', function() {
}, },
set traceEvents(traceEvents) { set traceEvents(traceEvents) {
console.log('TimelineView.refresh');
this.timelineModel_ = new tracing.TimelineModel(traceEvents); this.timelineModel_ = new tracing.TimelineModel(traceEvents);
// remove old timeline // remove old timeline
...@@ -72,10 +71,11 @@ cr.define('tracing', function() { ...@@ -72,10 +71,11 @@ cr.define('tracing', function() {
// create new timeline if needed // create new timeline if needed
if (traceEvents.length) { if (traceEvents.length) {
if (this.timeline_)
this.timeline_.detach();
this.timeline_ = new tracing.Timeline(); this.timeline_ = new tracing.Timeline();
this.timeline_.model = this.timelineModel_; this.timeline_.model = this.timelineModel_;
this.timelineContainer_.appendChild(this.timeline_); this.timelineContainer_.appendChild(this.timeline_);
this.timeline_.onResize();
this.timeline_.addEventListener('selectionChange', this.timeline_.addEventListener('selectionChange',
this.onSelectionChangedBoundToThis_); this.onSelectionChangedBoundToThis_);
this.onSelectionChanged_(); this.onSelectionChanged_();
...@@ -85,7 +85,6 @@ cr.define('tracing', function() { ...@@ -85,7 +85,6 @@ cr.define('tracing', function() {
}, },
onSelectionChanged_: function(e) { onSelectionChanged_: function(e) {
console.log('selection changed');
var timeline = this.timeline_; var timeline = this.timeline_;
var selection = timeline.selection; var selection = timeline.selection;
if (!selection.length) { if (!selection.length) {
...@@ -105,8 +104,9 @@ cr.define('tracing', function() { ...@@ -105,8 +104,9 @@ cr.define('tracing', function() {
tsRound(slice.start) + ' ms\n'; tsRound(slice.start) + ' ms\n';
text += leftAlign('Duration', c0Width) + ': ' + text += leftAlign('Duration', c0Width) + ': ' +
tsRound(slice.duration) + ' ms\n'; tsRound(slice.duration) + ' ms\n';
text += leftAlign('Duration (U)', c0Width) + ': ' + if (slice.durationInUserTime)
tsRound(slice.durationInUserTime) + ' ms\n'; text += leftAlign('Duration (U)', c0Width) + ': ' +
tsRound(slice.durationInUserTime) + ' ms\n';
var n = 0; var n = 0;
for (var argName in slice.args) { for (var argName in slice.args) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment