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

Unified Diff: chrome/browser/resources/tracing/timeline_track.js

Issue 10543144: Remove old tracing code now that it has moved to third_party. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/tracing/timeline_track.js
diff --git a/chrome/browser/resources/tracing/timeline_track.js b/chrome/browser/resources/tracing/timeline_track.js
deleted file mode 100644
index 1517504dfc7851fa7409798be78e717272e84edc..0000000000000000000000000000000000000000
--- a/chrome/browser/resources/tracing/timeline_track.js
+++ /dev/null
@@ -1,1199 +0,0 @@
-// Copyright (c) 2012 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.
-
-
-/**
- * @fileoverview Renders an array of slices into the provided div,
- * using a child canvas element. Uses a FastRectRenderer to draw only
- * the visible slices.
- */
-cr.define('tracing', function() {
-
- var pallette = tracing.getPallette();
- var highlightIdBoost = tracing.getPalletteHighlightIdBoost();
-
- // TODO(jrg): possibly obsoleted with the elided string cache.
- // Consider removing.
- var textWidthMap = { };
- function quickMeasureText(ctx, text) {
- var w = textWidthMap[text];
- if (!w) {
- w = ctx.measureText(text).width;
- textWidthMap[text] = w;
- }
- return w;
- }
-
- /**
- * Cache for elided strings.
- * Moved from the ElidedTitleCache protoype to a "global" for speed
- * (variable reference is 100x faster).
- * key: String we wish to elide.
- * value: Another dict whose key is width
- * and value is an ElidedStringWidthPair.
- */
- var elidedTitleCacheDict = {};
-
- /**
- * A generic track that contains other tracks as its children.
- * @constructor
- */
- var TimelineContainerTrack = cr.ui.define('div');
- TimelineContainerTrack.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- decorate: function() {
- this.tracks_ = [];
- },
-
- detach: function() {
- for (var i = 0; i < this.tracks_.length; i++)
- this.tracks_[i].detach();
- },
-
- get viewport() {
- return this.viewport_;
- },
-
- set viewport(v) {
- this.viewport_ = v;
- for (var i = 0; i < this.tracks_.length; i++)
- this.tracks_[i].viewport = v;
- this.updateChildTracks_();
- },
-
- get firstCanvas() {
- if (this.tracks_.length)
- return this.tracks_[0].firstCanvas;
- return undefined;
- },
-
- /**
- * Adds items intersecting a point to a selection.
- * @param {number} wX X location to search at, in worldspace.
- * @param {number} wY Y location to search at, in offset space.
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- * @return {boolean} true if a slice was found, otherwise false.
- */
- addIntersectingItemsToSelection: function(wX, wY, selection) {
- for (var i = 0; i < this.tracks_.length; i++) {
- var trackClientRect = this.tracks_[i].getBoundingClientRect();
- if (wY >= trackClientRect.top && wY < trackClientRect.bottom)
- this.tracks_[i].addIntersectingItemsToSelection(wX, wY, selection);
- }
- return false;
- },
-
- /**
- * Adds items intersecting the given range to a selection.
- * @param {number} loWX Lower X bound of the interval to search, in
- * worldspace.
- * @param {number} hiWX Upper X bound of the interval to search, in
- * worldspace.
- * @param {number} loY Lower Y bound of the interval to search, in
- * offset space.
- * @param {number} hiY Upper Y bound of the interval to search, in
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- */
- addIntersectingItemsInRangeToSelection: function(
- loWX, hiWX, loY, hiY, selection) {
- for (var i = 0; i < this.tracks_.length; i++) {
- var trackClientRect = this.tracks_[i].getBoundingClientRect();
- var a = Math.max(loY, trackClientRect.top);
- var b = Math.min(hiY, trackClientRect.bottom);
- if (a <= b)
- this.tracks_[i].addIntersectingItemsInRangeToSelection(
- loWX, hiWX, loY, hiY, selection);
- }
- },
-
- addAllObjectsMatchingFilterToSelection: function(filter, selection) {
- for (var i = 0; i < this.tracks_.length; i++)
- this.tracks_[i].addAllObjectsMatchingFilterToSelection(
- filter, selection);
- }
- };
-
- function addControlButtonElements(el, canCollapse) {
- var closeEl = document.createElement('div');
- closeEl.classList.add('timeline-track-button');
- closeEl.classList.add('timeline-track-close-button');
- closeEl.textContent = String.fromCharCode(215); // &times;
- closeEl.addEventListener('click', function() {
- el.style.display = 'None';
- });
- el.appendChild(closeEl);
-
- if (canCollapse) {
- var collapseEl = document.createElement('div');
- collapseEl.classList.add('timeline-track-button');
- collapseEl.classList.add('timeline-track-collapse-button');
- var minus = '\u2212'; // minus sign;
- var plus = '\u002b'; // plus sign;
- collapseEl.textContent = minus;
- var collapsed = false;
- collapseEl.addEventListener('click', function() {
- collapsed = !collapsed;
- el.collapsedDidChange(collapsed);
- collapseEl.textContent = collapsed ? plus : minus;
- });
- el.appendChild(collapseEl);
- }
- }
-
- /**
- * Visualizes a TimelineThread using a series of of TimelineSliceTracks.
- * @constructor
- */
- var TimelineThreadTrack = cr.ui.define(TimelineContainerTrack);
- TimelineThreadTrack.prototype = {
- __proto__: TimelineContainerTrack.prototype,
-
- decorate: function() {
- this.classList.add('timeline-thread-track');
- },
-
- get thread() {
- return this.thread_;
- },
-
- set thread(thread) {
- this.thread_ = thread;
- this.updateChildTracks_();
- },
-
- get tooltip() {
- return this.tooltip_;
- },
-
- set tooltip(value) {
- this.tooltip_ = value;
- this.updateChildTracks_();
- },
-
- get heading() {
- return this.heading_;
- },
-
- set heading(h) {
- this.heading_ = h;
- this.updateChildTracks_();
- },
-
- get headingWidth() {
- return this.headingWidth_;
- },
-
- set headingWidth(width) {
- this.headingWidth_ = width;
- this.updateChildTracks_();
- },
-
- addTrack_: function(slices) {
- var track = new TimelineSliceTrack();
- track.heading = '';
- track.slices = slices;
- track.headingWidth = this.headingWidth_;
- track.viewport = this.viewport_;
-
- this.tracks_.push(track);
- this.appendChild(track);
- return track;
- },
-
- updateChildTracks_: function() {
- this.detach();
- this.textContent = '';
- this.tracks_ = [];
- if (this.thread_) {
- if (this.thread_.cpuSlices) {
- var track = this.addTrack_(this.thread_.cpuSlices);
- track.height = '4px';
- track.decorateHit = function(hit) {
- hit.thread = this.thread_;
- }
- }
-
- if (this.thread_.asyncSlices.length) {
- var subRows = this.thread_.asyncSlices.subRows;
- for (var srI = 0; srI < subRows.length; srI++) {
- var track = this.addTrack_(subRows[srI]);
- track.decorateHit = function(hit) {
- // TODO(simonjam): figure out how to associate subSlice hits back
- // to their parent slice.
- }
- track.asyncStyle = true;
- }
- }
-
- for (var srI = 0; srI < this.thread_.subRows.length; srI++) {
- var track = this.addTrack_(this.thread_.subRows[srI]);
- track.decorateHit = function(hit) {
- hit.thread = this.thread_;
- }
- }
-
- if (this.tracks_.length > 0) {
- if (this.thread_.cpuSlices) {
- this.tracks_[1].heading = this.heading_;
- this.tracks_[1].tooltip = this.tooltip_;
- } else {
- this.tracks_[0].heading = this.heading_;
- this.tracks_[0].tooltip = this.tooltip_;
- }
- }
- }
- addControlButtonElements(this, this.tracks_.length >= 4);
- },
-
- collapsedDidChange: function(collapsed) {
- if (collapsed) {
- var h = parseInt(this.tracks_[0].height);
- for (var i = 0; i < this.tracks_.length; ++i) {
- if (h > 2) {
- this.tracks_[i].height = Math.floor(h) + 'px';
- } else {
- this.tracks_[i].style.display = 'None';
- }
- h = h * 0.5;
- }
- } else {
- for (var i = 0; i < this.tracks_.length; ++i) {
- this.tracks_[i].height = this.tracks_[0].height;
- this.tracks_[i].style.display = '';
- }
- }
- }
- };
-
- /**
- * Visualizes a TimelineCpu using a series of of TimelineSliceTracks.
- * @constructor
- */
- var TimelineCpuTrack = cr.ui.define(TimelineContainerTrack);
- TimelineCpuTrack.prototype = {
- __proto__: TimelineContainerTrack.prototype,
-
- decorate: function() {
- this.classList.add('timeline-thread-track');
- },
-
- get cpu() {
- return this.cpu_;
- },
-
- set cpu(cpu) {
- this.cpu_ = cpu;
- this.updateChildTracks_();
- },
-
- get tooltip() {
- return this.tooltip_;
- },
-
- set tooltip(value) {
- this.tooltip_ = value;
- this.updateChildTracks_();
- },
-
- get heading() {
- return this.heading_;
- },
-
- set heading(h) {
- this.heading_ = h;
- this.updateChildTracks_();
- },
-
- get headingWidth() {
- return this.headingWidth_;
- },
-
- set headingWidth(width) {
- this.headingWidth_ = width;
- this.updateChildTracks_();
- },
-
- updateChildTracks_: function() {
- this.detach();
- this.textContent = '';
- this.tracks_ = [];
- if (this.cpu_) {
- var track = new TimelineSliceTrack();
- track.slices = this.cpu_.slices;
- track.headingWidth = this.headingWidth_;
- track.viewport = this.viewport_;
-
- this.tracks_.push(track);
- this.appendChild(track);
-
- this.tracks_[0].heading = this.heading_;
- this.tracks_[0].tooltip = this.tooltip_;
- }
- addControlButtonElements(this, false);
- }
- };
-
- /**
- * A canvas-based track constructed. Provides the basic heading and
- * invalidation-managment infrastructure. Subclasses must implement drawing
- * and picking code.
- * @constructor
- * @extends {HTMLDivElement}
- */
- var CanvasBasedTrack = cr.ui.define('div');
-
- CanvasBasedTrack.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- decorate: function() {
- this.className = 'timeline-canvas-based-track';
- this.slices_ = null;
-
- this.headingDiv_ = document.createElement('div');
- this.headingDiv_.className = 'timeline-canvas-based-track-title';
- this.appendChild(this.headingDiv_);
-
- this.canvasContainer_ = document.createElement('div');
- this.canvasContainer_.className =
- 'timeline-canvas-based-track-canvas-container';
- this.appendChild(this.canvasContainer_);
- this.canvas_ = document.createElement('canvas');
- this.canvas_.className = 'timeline-canvas-based-track-canvas';
- this.canvasContainer_.appendChild(this.canvas_);
-
- this.ctx_ = this.canvas_.getContext('2d');
- },
-
- detach: function() {
- if (this.viewport_)
- this.viewport_.removeEventListener('change',
- this.viewportChangeBoundToThis_);
- },
-
- set headingWidth(width) {
- this.headingDiv_.style.width = width;
- },
-
- get heading() {
- return this.headingDiv_.textContent;
- },
-
- set heading(text) {
- this.headingDiv_.textContent = text;
- },
-
- set tooltip(text) {
- this.headingDiv_.title = text;
- },
-
- get viewport() {
- return this.viewport_;
- },
-
- set viewport(v) {
- this.viewport_ = v;
- if (this.viewport_)
- this.viewport_.removeEventListener('change',
- this.viewportChangeBoundToThis_);
- this.viewport_ = v;
- if (this.viewport_) {
- this.viewportChangeBoundToThis_ = this.viewportChange_.bind(this);
- this.viewport_.addEventListener('change',
- this.viewportChangeBoundToThis_);
- }
- this.invalidate();
- },
-
- viewportChange_: function() {
- this.invalidate();
- },
-
- invalidate: function() {
- if (this.rafPending_)
- return;
- webkitRequestAnimationFrame(function() {
- this.rafPending_ = false;
- if (!this.viewport_)
- return;
-
- var style = window.getComputedStyle(this.canvasContainer_);
- var style_width = parseInt(style.width);
- var style_height = parseInt(style.height);
- if (this.canvas_.width != style_width)
- this.canvas_.width = style_width;
- if (this.canvas_.height != style_height)
- this.canvas_.height = style_height;
-
- this.redraw();
- }.bind(this), this);
- this.rafPending_ = true;
- },
-
- get firstCanvas() {
- return this.canvas_;
- }
-
- };
-
- /**
- * A pair representing an elided string and world-coordinate width
- * to draw it.
- * @constructor
- */
- function ElidedStringWidthPair(string, width) {
- this.string = string;
- this.width = width;
- }
-
- /**
- * A cache for elided strings.
- * @constructor
- */
- function ElidedTitleCache() {
- }
-
- ElidedTitleCache.prototype = {
- /**
- * Return elided text.
- * @param {track} A timeline slice track or other object that defines
- * functions labelWidth() and labelWidthWorld().
- * @param {pixWidth} Pixel width.
- * @param {title} Original title text.
- * @param {width} Drawn width in world coords.
- * @param {sliceDuration} Where the title must fit (in world coords).
- * @return {ElidedStringWidthPair} Elided string and width.
- */
- get: function(track, pixWidth, title, width, sliceDuration) {
- var elidedDict = elidedTitleCacheDict[title];
- if (!elidedDict) {
- elidedDict = {};
- elidedTitleCacheDict[title] = elidedDict;
- }
- var elidedDictForPixWidth = elidedDict[pixWidth];
- if (!elidedDictForPixWidth) {
- elidedDict[pixWidth] = {};
- elidedDictForPixWidth = elidedDict[pixWidth];
- }
- var stringWidthPair = elidedDictForPixWidth[sliceDuration];
- if (stringWidthPair === undefined) {
- var newtitle = title;
- var elided = false;
- while (track.labelWidthWorld(newtitle, pixWidth) > sliceDuration) {
- newtitle = newtitle.substring(0, newtitle.length * 0.75);
- elided = true;
- }
- if (elided && newtitle.length > 3)
- newtitle = newtitle.substring(0, newtitle.length - 3) + '...';
- stringWidthPair = new ElidedStringWidthPair(
- newtitle,
- track.labelWidth(newtitle));
- elidedDictForPixWidth[sliceDuration] = stringWidthPair;
- }
- return stringWidthPair;
- }
- };
-
- /**
- * A track that displays an array of TimelineSlice objects.
- * @constructor
- * @extends {CanvasBasedTrack}
- */
-
- var TimelineSliceTrack = cr.ui.define(CanvasBasedTrack);
-
- TimelineSliceTrack.prototype = {
-
- __proto__: CanvasBasedTrack.prototype,
-
- /**
- * Should we elide text on trace labels?
- * Without eliding, text that is too wide isn't drawn at all.
- * Disable if you feel this causes a performance problem.
- * This is a default value that can be overridden in tracks for testing.
- * @const
- */
- SHOULD_ELIDE_TEXT: true,
-
- decorate: function() {
- this.classList.add('timeline-slice-track');
- this.elidedTitleCache = new ElidedTitleCache();
- this.asyncStyle_ = false;
- },
-
- /**
- * Called by all the addToSelection functions on the created selection
- * hit objects. Override this function on parent classes to add
- * context-specific information to the hit.
- */
- decorateHit: function(hit) {
- },
-
- get asyncStyle() {
- return this.asyncStyle_;
- },
-
- set asyncStyle(v) {
- this.asyncStyle_ = !!v;
- this.invalidate();
- },
-
- get slices() {
- return this.slices_;
- },
-
- set slices(slices) {
- this.slices_ = slices;
- this.invalidate();
- },
-
- get height() {
- return window.getComputedStyle(this).height;
- },
-
- set height(height) {
- this.style.height = height;
- this.invalidate();
- },
-
- labelWidth: function(title) {
- return quickMeasureText(this.ctx_, title) + 2;
- },
-
- labelWidthWorld: function(title, pixWidth) {
- return this.labelWidth(title) * pixWidth;
- },
-
- redraw: function() {
- var ctx = this.ctx_;
- var canvasW = this.canvas_.width;
- var canvasH = this.canvas_.height;
-
- ctx.clearRect(0, 0, canvasW, canvasH);
-
- // Culling parameters.
- var vp = this.viewport_;
- var pixWidth = vp.xViewVectorToWorld(1);
- var viewLWorld = vp.xViewToWorld(0);
- var viewRWorld = vp.xViewToWorld(canvasW);
-
- // Draw grid without a transform because the scale
- // affects line width.
- if (vp.gridEnabled) {
- var x = vp.gridTimebase;
- ctx.beginPath();
- while (x < viewRWorld) {
- if (x >= viewLWorld) {
- // Do conversion to viewspace here rather than on
- // x to avoid precision issues.
- var vx = vp.xWorldToView(x);
- ctx.moveTo(vx, 0);
- ctx.lineTo(vx, canvasH);
- }
- x += vp.gridStep;
- }
- ctx.strokeStyle = 'rgba(255,0,0,0.25)';
- ctx.stroke();
- }
-
- // Begin rendering in world space.
- ctx.save();
- vp.applyTransformToCanavs(ctx);
-
- // Slices.
- if (this.asyncStyle_)
- ctx.globalAlpha = 0.25;
- var tr = new tracing.FastRectRenderer(ctx, viewLWorld, 2 * pixWidth,
- 2 * pixWidth, viewRWorld, pallette);
- tr.setYandH(0, canvasH);
- var slices = this.slices_;
- for (var i = 0; i < slices.length; ++i) {
- var slice = slices[i];
- var x = slice.start;
- // Less than 0.001 causes short events to disappear when zoomed in.
- var w = Math.max(slice.duration, 0.001);
- var colorId = slice.selected ?
- slice.colorId + highlightIdBoost :
- slice.colorId;
-
- if (w < pixWidth)
- w = pixWidth;
- if (slice.duration > 0) {
- tr.fillRect(x, w, colorId);
- } else {
- // Instant: draw a triangle. If zoomed too far, collapse
- // into the FastRectRenderer.
- if (pixWidth > 0.001) {
- tr.fillRect(x, pixWidth, colorId);
- } else {
- ctx.fillStyle = pallette[colorId];
- ctx.beginPath();
- ctx.moveTo(x - (4 * pixWidth), canvasH);
- ctx.lineTo(x, 0);
- ctx.lineTo(x + (4 * pixWidth), canvasH);
- ctx.closePath();
- ctx.fill();
- }
- }
- }
- tr.flush();
- ctx.restore();
-
- // Labels.
- if (canvasH > 8) {
- ctx.textAlign = 'center';
- ctx.textBaseline = 'top';
- ctx.font = '10px sans-serif';
- ctx.strokeStyle = 'rgb(0,0,0)';
- ctx.fillStyle = 'rgb(0,0,0)';
- // Don't render text until until it is 20px wide
- var quickDiscardThresshold = pixWidth * 20;
- var shouldElide = this.SHOULD_ELIDE_TEXT;
- for (var i = 0; i < slices.length; ++i) {
- var slice = slices[i];
- if (slice.duration > quickDiscardThresshold) {
- var title = slice.title;
- if (slice.didNotFinish) {
- title += ' (Did Not Finish)';
- }
- var drawnTitle = title;
- var drawnWidth = this.labelWidth(drawnTitle);
- if (shouldElide &&
- this.labelWidthWorld(drawnTitle, pixWidth) > slice.duration) {
- var elidedValues = this.elidedTitleCache.get(
- this, pixWidth,
- drawnTitle, drawnWidth,
- slice.duration);
- drawnTitle = elidedValues.string;
- drawnWidth = elidedValues.width;
- }
- if (drawnWidth * pixWidth < slice.duration) {
- var cX = vp.xWorldToView(slice.start + 0.5 * slice.duration);
- ctx.fillText(drawnTitle, cX, 2.5, drawnWidth);
- }
- }
- }
- }
- },
-
- /**
- * Finds slices intersecting the given interval.
- * @param {number} wX X location to search at, in worldspace.
- * @param {number} wY Y location to search at, in offset space.
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- * @return {boolean} true if a slice was found, otherwise false.
- */
- addIntersectingItemsToSelection: function(wX, wY, selection) {
- var clientRect = this.getBoundingClientRect();
- if (wY < clientRect.top || wY >= clientRect.bottom)
- return false;
- var x = tracing.findLowIndexInSortedIntervals(this.slices_,
- function(x) { return x.start; },
- function(x) { return x.duration; },
- wX);
- if (x >= 0 && x < this.slices_.length) {
- var hit = selection.addSlice(this, this.slices_[x]);
- this.decorateHit(hit);
- return true;
- }
- return false;
- },
-
- /**
- * Adds items intersecting the given range to a selection.
- * @param {number} loWX Lower X bound of the interval to search, in
- * worldspace.
- * @param {number} hiWX Upper X bound of the interval to search, in
- * worldspace.
- * @param {number} loY Lower Y bound of the interval to search, in
- * offset space.
- * @param {number} hiY Upper Y bound of the interval to search, in
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- */
- addIntersectingItemsInRangeToSelection: function(
- loWX, hiWX, loY, hiY, selection) {
- var clientRect = this.getBoundingClientRect();
- var a = Math.max(loY, clientRect.top);
- var b = Math.min(hiY, clientRect.bottom);
- if (a > b)
- return;
-
- var that = this;
- function onPickHit(slice) {
- var hit = selection.addSlice(that, slice);
- that.decorateHit(hit);
- }
- tracing.iterateOverIntersectingIntervals(this.slices_,
- function(x) { return x.start; },
- function(x) { return x.duration; },
- loWX, hiWX,
- onPickHit);
- },
-
- /**
- * Find the index for the given slice.
- * @return {index} Index of the given slice, or undefined.
- * @private
- */
- indexOfSlice_: function(slice) {
- var index = tracing.findLowIndexInSortedArray(this.slices_,
- function(x) { return x.start; },
- slice.start);
- while (index < this.slices_.length &&
- slice.start == this.slices_[index].start &&
- slice.colorId != this.slices_[index].colorId) {
- index++;
- }
- return index < this.slices_.length ? index : undefined;
- },
-
- /**
- * Add the item to the left or right of the provided hit, if any, to the
- * selection.
- * @param {slice} The current slice.
- * @param {Number} offset Number of slices away from the hit to look.
- * @param {TimelineSelection} selection The selection to add a hit to,
- * if found.
- * @return {boolean} Whether a hit was found.
- * @private
- */
- addItemNearToProvidedHitToSelection: function(hit, offset, selection) {
- if (!hit.slice)
- return false;
-
- var index = this.indexOfSlice_(hit.slice);
- if (index === undefined)
- return false;
-
- var newIndex = index + offset;
- if (newIndex < 0 || newIndex >= this.slices_.length)
- return false;
-
- var hit = selection.addSlice(this, this.slices_[newIndex]);
- this.decorateHit(hit);
- return true;
- },
-
- addAllObjectsMatchingFilterToSelection: function(filter, selection) {
- for (var i = 0; i < this.slices_.length; ++i) {
- if (filter.matchSlice(this.slices_[i])) {
- var hit = selection.addSlice(this, this.slices_[i]);
- this.decorateHit(hit);
- }
- }
- }
- };
-
- /**
- * A track that displays the viewport size and scale.
- * @constructor
- * @extends {CanvasBasedTrack}
- */
-
- var TimelineViewportTrack = cr.ui.define(CanvasBasedTrack);
-
- var logOf10 = Math.log(10);
- function log10(x) {
- return Math.log(x) / logOf10;
- }
-
- TimelineViewportTrack.prototype = {
-
- __proto__: CanvasBasedTrack.prototype,
-
- decorate: function() {
- this.classList.add('timeline-viewport-track');
- this.strings_secs_ = [];
- this.strings_msecs_ = [];
- },
-
- redraw: function() {
- var ctx = this.ctx_;
- var canvasW = this.canvas_.width;
- var canvasH = this.canvas_.height;
-
- ctx.clearRect(0, 0, canvasW, canvasH);
-
- // Culling parametrs.
- var vp = this.viewport_;
- var pixWidth = vp.xViewVectorToWorld(1);
- var viewLWorld = vp.xViewToWorld(0);
- var viewRWorld = vp.xViewToWorld(canvasW);
-
- var idealMajorMarkDistancePix = 150;
- var idealMajorMarkDistanceWorld =
- vp.xViewVectorToWorld(idealMajorMarkDistancePix);
-
- // The conservative guess is the nearest enclosing 0.1, 1, 10, 100, etc
- var conservativeGuess =
- Math.pow(10, Math.ceil(log10(idealMajorMarkDistanceWorld)));
-
- // Once we have a conservative guess, consider things that evenly add up
- // to the conservative guess, e.g. 0.5, 0.2, 0.1 Pick the one that still
- // exceeds the ideal mark distance.
- var divisors = [10, 5, 2, 1];
- for (var i = 0; i < divisors.length; ++i) {
- var tightenedGuess = conservativeGuess / divisors[i];
- if (vp.xWorldVectorToView(tightenedGuess) < idealMajorMarkDistancePix)
- continue;
- majorMarkDistanceWorld = conservativeGuess / divisors[i - 1];
- break;
- }
- var tickLabels = undefined;
- if (majorMarkDistanceWorld < 100) {
- unit = 'ms';
- unitDivisor = 1;
- tickLabels = this.strings_msecs_;
- } else {
- unit = 's';
- unitDivisor = 1000;
- tickLabels = this.strings_secs_;
- }
-
- var numTicksPerMajor = 5;
- var minorMarkDistanceWorld = majorMarkDistanceWorld / numTicksPerMajor;
- var minorMarkDistancePx = vp.xWorldVectorToView(minorMarkDistanceWorld);
-
- var firstMajorMark =
- Math.floor(viewLWorld / majorMarkDistanceWorld) *
- majorMarkDistanceWorld;
-
- var minorTickH = Math.floor(canvasH * 0.25);
-
- ctx.fillStyle = 'rgb(0, 0, 0)';
- ctx.strokeStyle = 'rgb(0, 0, 0)';
- ctx.textAlign = 'left';
- ctx.textBaseline = 'top';
- ctx.font = '9px sans-serif';
-
- // Each iteration of this loop draws one major mark
- // and numTicksPerMajor minor ticks.
- //
- // Rendering can't be done in world space because canvas transforms
- // affect line width. So, do the conversions manually.
- for (var curX = firstMajorMark;
- curX < viewRWorld;
- curX += majorMarkDistanceWorld) {
-
- var curXView = Math.floor(vp.xWorldToView(curX));
-
- var unitValue = curX / unitDivisor;
- var roundedUnitValue = Math.floor(unitValue * 100000) / 100000;
- if (!tickLabels[roundedUnitValue])
- tickLabels[roundedUnitValue] = roundedUnitValue + ' ' + unit;
- ctx.fillText(tickLabels[roundedUnitValue], curXView + 2, 0);
- ctx.beginPath();
-
- // Major mark
- ctx.moveTo(curXView, 0);
- ctx.lineTo(curXView, canvasW);
-
- // Minor marks
- for (var i = 1; i < numTicksPerMajor; ++i) {
- var xView = Math.floor(curXView + minorMarkDistancePx * i);
- ctx.moveTo(xView, canvasH - minorTickH);
- ctx.lineTo(xView, canvasH);
- }
-
- ctx.stroke();
- }
- },
-
- /**
- * Adds items intersecting a point to a selection.
- * @param {number} wX X location to search at, in worldspace.
- * @param {number} wY Y location to search at, in offset space.
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- * @return {boolean} true if a slice was found, otherwise false.
- */
- addIntersectingItemsToSelection: function(wX, wY, selection) {
- // Does nothing. There's nothing interesting to pick on the viewport
- // track.
- },
-
- /**
- * Adds items intersecting the given range to a selection.
- * @param {number} loWX Lower X bound of the interval to search, in
- * worldspace.
- * @param {number} hiWX Upper X bound of the interval to search, in
- * worldspace.
- * @param {number} loY Lower Y bound of the interval to search, in
- * offset space.
- * @param {number} hiY Upper Y bound of the interval to search, in
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- */
- addIntersectingItemsInRangeToSelection: function(
- loWX, hiWX, loY, hiY, selection) {
- // Does nothing. There's nothing interesting to pick on the viewport
- // track.
- },
-
- addAllObjectsMatchingFilterToSelection: function(filter, selection) {
- }
-
- };
-
- /**
- * A track that displays a TimelineCounter object.
- * @constructor
- * @extends {CanvasBasedTrack}
- */
-
- var TimelineCounterTrack = cr.ui.define(CanvasBasedTrack);
-
- TimelineCounterTrack.prototype = {
-
- __proto__: CanvasBasedTrack.prototype,
-
- decorate: function() {
- this.classList.add('timeline-counter-track');
- addControlButtonElements(this, false);
- this.selectedSamples_ = {};
- },
-
- /**
- * Called by all the addToSelection functions on the created selection
- * hit objects. Override this function on parent classes to add
- * context-specific information to the hit.
- */
- decorateHit: function(hit) {
- },
-
- get counter() {
- return this.counter_;
- },
-
- set counter(counter) {
- this.counter_ = counter;
- this.invalidate();
- },
-
- /**
- * @return {Object} A sparce, mutable map from sample index to bool. Samples
- * indices the map that are true are drawn as selected. Callers that mutate
- * the map must manually call invalidate on the track to trigger a redraw.
- */
- get selectedSamples() {
- return this.selectedSamples_;
- },
-
- redraw: function() {
- var ctr = this.counter_;
- var ctx = this.ctx_;
- var canvasW = this.canvas_.width;
- var canvasH = this.canvas_.height;
-
- ctx.clearRect(0, 0, canvasW, canvasH);
-
- // Culling parametrs.
- var vp = this.viewport_;
- var pixWidth = vp.xViewVectorToWorld(1);
- var viewLWorld = vp.xViewToWorld(0);
- var viewRWorld = vp.xViewToWorld(canvasW);
-
- // Drop sampels that are less than skipDistancePix apart.
- var skipDistancePix = 1;
- var skipDistanceWorld = vp.xViewVectorToWorld(skipDistancePix);
-
- // Begin rendering in world space.
- ctx.save();
- vp.applyTransformToCanavs(ctx);
-
- // Figure out where drawing should begin.
- var numSeries = ctr.numSeries;
- var numSamples = ctr.numSamples;
- var startIndex = tracing.findLowIndexInSortedArray(ctr.timestamps,
- function() {
- },
- viewLWorld);
-
- // Draw indices one by one until we fall off the viewRWorld.
- var yScale = canvasH / ctr.maxTotal;
- for (var seriesIndex = ctr.numSeries - 1;
- seriesIndex >= 0; seriesIndex--) {
- var colorId = ctr.seriesColors[seriesIndex];
- ctx.fillStyle = pallette[colorId];
- ctx.beginPath();
-
- // Set iLast and xLast such that the first sample we draw is the
- // startIndex sample.
- var iLast = startIndex - 1;
- var xLast = iLast >= 0 ? ctr.timestamps[iLast] - skipDistanceWorld : -1;
- var yLastView = canvasH;
-
- // Iterate over samples from iLast onward until we either fall off the
- // viewRWorld or we run out of samples. To avoid drawing too much, after
- // drawing a sample at xLast, skip subsequent samples that are less than
- // skipDistanceWorld from xLast.
- var hasMoved = false;
- while (true) {
- var i = iLast + 1;
- if (i >= numSamples) {
- ctx.lineTo(xLast, yLastView);
- ctx.lineTo(xLast + 8 * pixWidth, yLastView);
- ctx.lineTo(xLast + 8 * pixWidth, canvasH);
- break;
- }
-
- var x = ctr.timestamps[i];
-
- var y = ctr.totals[i * numSeries + seriesIndex];
- var yView = canvasH - (yScale * y);
-
- if (x > viewRWorld) {
- ctx.lineTo(x, yLastView);
- ctx.lineTo(x, canvasH);
- break;
- }
-
- if (x - xLast < skipDistanceWorld) {
- iLast = i;
- continue;
- }
-
- if (!hasMoved) {
- ctx.moveTo(viewLWorld, canvasH);
- hasMoved = true;
- }
- ctx.lineTo(x, yLastView);
- ctx.lineTo(x, yView);
- iLast = i;
- xLast = x;
- yLastView = yView;
- }
- ctx.closePath();
- ctx.fill();
- }
- ctx.fillStyle = 'rgba(255, 0, 0, 1)';
- for (var i in this.selectedSamples_) {
- if (!this.selectedSamples_[i])
- continue;
-
- var x = ctr.timestamps[i];
- for (var seriesIndex = ctr.numSeries - 1;
- seriesIndex >= 0; seriesIndex--) {
- var y = ctr.totals[i * numSeries + seriesIndex];
- var yView = canvasH - (yScale * y);
- ctx.fillRect(x - pixWidth, yView - 1, 3 * pixWidth, 3);
- }
- }
- ctx.restore();
- },
-
- /**
- * Adds items intersecting a point to a selection.
- * @param {number} wX X location to search at, in worldspace.
- * @param {number} wY Y location to search at, in offset space.
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- * @return {boolean} true if a slice was found, otherwise false.
- */
- addIntersectingItemsToSelection: function(wX, wY, selection) {
- var clientRect = this.getBoundingClientRect();
- if (wY < clientRect.top || wY >= clientRect.bottom)
- return false;
- var ctr = this.counter_;
- if (wX < this.counter_.timestamps[0])
- return false;
- var i = tracing.findLowIndexInSortedArray(ctr.timestamps,
- function(x) { return x; },
- wX);
- if (i < 0 || i >= ctr.timestamps.length)
- return false;
-
- // Sample i is going to either be exactly at wX or slightly above it,
- // E.g. asking for 7.5 in [7,8] gives i=1. So bump i back by 1 if needed.
- if (i > 0 && wX > this.counter_.timestamps[i - 1])
- i--;
-
- // Some preliminaries.
- var canvasH = this.getBoundingClientRect().height;
- var yScale = canvasH / ctr.maxTotal;
-
- /*
- // Figure out which sample we hit
- var seriesIndexHit;
- for (var seriesIndex = 0; seriesIndex < ctr.numSeries; seriesIndex++) {
- var y = ctr.totals[i * ctr.numSeries + seriesIndex];
- var yView = canvasH - (yScale * y) + clientRect.top;
- if (wY >= yView) {
- seriesIndexHit = seriesIndex;
- break;
- }
- }
- if (seriesIndexHit === undefined)
- return false;
- */
- var hit = selection.addCounterSample(this, this.counter, i);
- this.decorateHit(hit);
- return true;
- },
-
- /**
- * Adds items intersecting the given range to a selection.
- * @param {number} loWX Lower X bound of the interval to search, in
- * worldspace.
- * @param {number} hiWX Upper X bound of the interval to search, in
- * worldspace.
- * @param {number} loY Lower Y bound of the interval to search, in
- * offset space.
- * @param {number} hiY Upper Y bound of the interval to search, in
- * offset space.
- * @param {TimelineSelection} selection Selection to which to add hits.
- */
- addIntersectingItemsInRangeToSelection: function(
- loWX, hiWX, loY, hiY, selection) {
-
- var clientRect = this.getBoundingClientRect();
- var a = Math.max(loY, clientRect.top);
- var b = Math.min(hiY, clientRect.bottom);
- if (a > b)
- return;
-
- var ctr = this.counter_;
-
- var iLo = tracing.findLowIndexInSortedArray(ctr.timestamps,
- function(x) { return x; },
- loWX);
- var iHi = tracing.findLowIndexInSortedArray(ctr.timestamps,
- function(x) { return x; },
- hiWX);
-
- // Sample i is going to either be exactly at wX or slightly above it,
- // E.g. asking for 7.5 in [7,8] gives i=1. So bump i back by 1 if needed.
- if (iLo > 0 && loWX > ctr.timestamps[iLo - 1])
- iLo--;
- if (iHi > 0 && hiWX > ctr.timestamps[iHi - 1])
- iHi--;
-
- // Iterate over every sample intersecting..
- for (var i = iLo; i <= iHi; i++) {
- if (i >= ctr.timestamps.length)
- continue;
-
- // TODO(nduca): Pick the seriesIndexHit based on the loY - hiY values.
- var hit = selection.addCounterSample(this, this.counter, i);
- this.decorateHit(hit);
- }
- },
-
- addAllObjectsMatchingFilterToSelection: function(filter, selection) {
- }
-
- };
-
- return {
- TimelineCounterTrack: TimelineCounterTrack,
- TimelineSliceTrack: TimelineSliceTrack,
- TimelineThreadTrack: TimelineThreadTrack,
- TimelineViewportTrack: TimelineViewportTrack,
- TimelineCpuTrack: TimelineCpuTrack
- };
-});
« no previous file with comments | « chrome/browser/resources/tracing/timeline_test.html ('k') | chrome/browser/resources/tracing/timeline_track_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698