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 @@
<include src="tracing/tracing_controller.js">
<include src="tracing/timeline_model.js">
<include src="tracing/sorted_array_utils.js">
<include src="tracing/measuring_stick.js">
<include src="tracing/timeline.js">
<include src="tracing/timeline_track.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.
*/
.timeline-drag-box {
position: fixed;
background-color: rgba(0, 0, 255, 0.25);
border: 1px solid rgb(0, 0, 96);
border: 1px solid #000060
font-size: 75%;
position: fixed;
}
.timeline-thread-track {
display: -webkit-box;
-webkit-box-orient: vertical;
padding-top: 1px;
padding-bottom: 1px;
display: -webkit-box;
padding: 1px 0;
}
.timeline-thread-track:not(:first-child) {
......@@ -23,21 +22,22 @@ found in the LICENSE file.
}
.timeline-slice-track {
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-align: stretch;
background-color: white;
padding-right: 5px;
display: -webkit-box;
height: 18px;
margin: 0;
padding: 0;
height: 18px;
padding-right: 5px;
}
.timeline-slice-track-title {
text-align: right;
overflow: visible;
width: 300px;
overflow: hidden;
padding-right: 5px;
text-align: right;
text-overflow: ellipsis;
white-space: nowrap;
}
.timeline-slice-track-canvas-container {
......@@ -47,6 +47,6 @@ found in the LICENSE file.
.timeline-slice-track-canvas {
-webkit-box-flex: 1;
width: 100%;
height: 100%;
width: 100%;
}
......@@ -282,8 +282,8 @@ cr.define('tracing', function() {
slice.durationInUserTime = event.uts - slice.slice.startInUserTime;
// Store the slice in a non-nested subrow.
var thread = self.getOrCreateProcess(event.pid).
getOrCreateThread(event.tid);
var thread =
self.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);
thread.addNonNestedSlice(slice.slice);
delete state.openNonNestedSlices[name];
} else {
......@@ -298,7 +298,7 @@ cr.define('tracing', function() {
// Store the slice on the correct subrow.
var thread = self.getOrCreateProcess(event.pid)
.getOrCreateThread(event.tid);
.getOrCreateThread(event.tid);
var subRowIndex = state.openSlices.length;
thread.getSubrow(subRowIndex).push(slice);
......@@ -338,7 +338,7 @@ cr.define('tracing', function() {
}
} else {
this.importErrors.push('Unrecognized event phase: ' + event.ph +
'(' + event.name + ')');
'(' + event.name + ')');
}
}
this.pruneEmptyThreads();
......
......@@ -275,9 +275,9 @@ function testUserTime() {
];
var m = new tracing.TimelineModel(events);
var subRow = m.processes[1].threads[1].subRows[0];
assertEquals(subRow[0].startInUserTime, 70);
assertEquals(subRow[0].durationInUserTime, 7);
assertEquals(subRow[1].startInUserTime, 80);
assertEquals(subRow[0].startInUserTime, 0.07);
assertEquals(subRow[0].durationInUserTime, 0.007);
assertEquals(subRow[1].startInUserTime, 0.08);
assertEquals(subRow[1].durationInUserTime, 0);
}
......
......@@ -93,6 +93,22 @@ cr.define('tracing', function() {
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) {
this.viewport_ = v;
for (var i = 0; i < this.tracks_.length; i++)
......@@ -132,9 +148,7 @@ cr.define('tracing', function() {
addTrack(this, this.thread_.subRows[srI]);
}
if (this.tracks_.length > 0) {
var tname = this.thread_.name || this.thread_.tid;
this.tracks_[0].heading = this.thread_.parent.pid + ': ' +
tname + ':';
this.tracks_[0].heading = this.heading;
this.tracks_[0].tooltip = 'pid: ' + this.thread_.parent.pid +
', tid: ' + this.thread_.tid +
(this.thread_.name ? ', name: ' + this.thread_.name : '');
......@@ -212,6 +226,14 @@ cr.define('tracing', function() {
this.ctx_ = this.canvas_.getContext('2d');
},
set headingWidth(width) {
this.headingDiv_.style.width = width;
},
get heading() {
return this.headingDiv_.textContent;
},
set heading(text) {
this.headingDiv_.textContent = text;
},
......@@ -335,21 +357,13 @@ cr.define('tracing', function() {
if (slice.didNotFinish) {
title += ' (Did Not Finish)';
}
function labelWidth() {
return quickMeasureText(ctx, title) + 2;
}
function labelWidthWorld() {
return pixWidth * labelWidth();
}
var elided = false;
while (labelWidthWorld() > slice.duration) {
title = title.substring(0, title.length * 0.75);
elided = true;
var labelWidth = quickMeasureText(ctx, title) + 2;
var labelWidthWorld = pixWidth * labelWidth;
if (labelWidthWorld < slice.duration) {
var cX = vp.xWorldToView(slice.start + 0.5 * slice.duration);
ctx.fillText(title, cX, 2.5, labelWidthWorld);
}
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() {
return index != undefined ? this.slices_[index] : undefined;
},
/**
/**
* Return the previous slice, if any, before the given slice.
* @param {slice} A slice.
* @return {slice} The previous slice, or undefined.
......@@ -455,7 +469,7 @@ cr.define('tracing', function() {
else if ((index != undefined) && (index > 0))
index--;
return index != undefined ? this.slices_[index] : undefined;
},
}
};
......
......@@ -64,7 +64,6 @@ cr.define('tracing', function() {
},
set traceEvents(traceEvents) {
console.log('TimelineView.refresh');
this.timelineModel_ = new tracing.TimelineModel(traceEvents);
// remove old timeline
......@@ -72,10 +71,11 @@ cr.define('tracing', function() {
// create new timeline if needed
if (traceEvents.length) {
if (this.timeline_)
this.timeline_.detach();
this.timeline_ = new tracing.Timeline();
this.timeline_.model = this.timelineModel_;
this.timelineContainer_.appendChild(this.timeline_);
this.timeline_.onResize();
this.timeline_.addEventListener('selectionChange',
this.onSelectionChangedBoundToThis_);
this.onSelectionChanged_();
......@@ -85,7 +85,6 @@ cr.define('tracing', function() {
},
onSelectionChanged_: function(e) {
console.log('selection changed');
var timeline = this.timeline_;
var selection = timeline.selection;
if (!selection.length) {
......@@ -105,8 +104,9 @@ cr.define('tracing', function() {
tsRound(slice.start) + ' ms\n';
text += leftAlign('Duration', c0Width) + ': ' +
tsRound(slice.duration) + ' ms\n';
text += leftAlign('Duration (U)', c0Width) + ': ' +
tsRound(slice.durationInUserTime) + ' ms\n';
if (slice.durationInUserTime)
text += leftAlign('Duration (U)', c0Width) + ': ' +
tsRound(slice.durationInUserTime) + ' ms\n';
var n = 0;
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