blob: f0c1a91f76a7411b0f041e8ad4da8e732669c4b8 [file] [log] [blame]
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.TimelineOverviewBase}
* @param {!WebInspector.TimelineModel} model
* @param {!WebInspector.TimelineUIUtils} uiUtils
*/
WebInspector.TimelineMemoryOverview = function(model, uiUtils)
{
WebInspector.TimelineOverviewBase.call(this, model);
this._uiUtils = uiUtils;
this.element.id = "timeline-overview-memory";
this._heapSizeLabel = this.element.createChild("div", "memory-graph-label");
}
WebInspector.TimelineMemoryOverview.prototype = {
resetHeapSizeLabels: function()
{
this._heapSizeLabel.textContent = "";
},
update: function()
{
this.resetCanvas();
var ratio = window.devicePixelRatio;
var records = this._model.records();
if (!records.length) {
this.resetHeapSizeLabels();
return;
}
var lowerOffset = 3 * ratio;
var maxUsedHeapSize = 0;
var minUsedHeapSize = 100000000000;
var minTime = this._model.minimumRecordTime();
var maxTime = this._model.maximumRecordTime();
var uiUtils = this._uiUtils;
/**
* @param {!WebInspector.TimelineModel.Record} record
*/
function calculateMinMaxSizes(record)
{
var counters = uiUtils.countersForRecord(record);
if (!counters || !counters.jsHeapSizeUsed)
return;
maxUsedHeapSize = Math.max(maxUsedHeapSize, counters.jsHeapSizeUsed);
minUsedHeapSize = Math.min(minUsedHeapSize, counters.jsHeapSizeUsed);
}
this._model.forAllRecords(calculateMinMaxSizes);
minUsedHeapSize = Math.min(minUsedHeapSize, maxUsedHeapSize);
var lineWidth = 1;
var width = this._canvas.width;
var height = this._canvas.height - lowerOffset;
var xFactor = width / (maxTime - minTime);
var yFactor = (height - lineWidth) / Math.max(maxUsedHeapSize - minUsedHeapSize, 1);
var histogram = new Array(width);
/**
* @param {!WebInspector.TimelineModel.Record} record
*/
function buildHistogram(record)
{
var counters = uiUtils.countersForRecord(record);
if (!counters || !counters.jsHeapSizeUsed)
return;
var x = Math.round((record.endTime() - minTime) * xFactor);
var y = Math.round((counters.jsHeapSizeUsed - minUsedHeapSize) * yFactor);
histogram[x] = Math.max(histogram[x] || 0, y);
}
this._model.forAllRecords(buildHistogram);
var ctx = this._context;
var heightBeyondView = height + lowerOffset + lineWidth;
ctx.translate(0.5, 0.5);
ctx.beginPath();
ctx.moveTo(-lineWidth, heightBeyondView);
var y = 0;
var isFirstPoint = true;
var lastX = 0;
for (var x = 0; x < histogram.length; x++) {
if (typeof histogram[x] === "undefined")
continue;
if (isFirstPoint) {
isFirstPoint = false;
y = histogram[x];
ctx.lineTo(-lineWidth, height - y);
}
var nextY = histogram[x];
if (Math.abs(nextY - y) > 2 && Math.abs(x - lastX) > 1)
ctx.lineTo(x, height - y);
y = nextY;
ctx.lineTo(x, height - y);
lastX = x;
}
ctx.lineTo(width + lineWidth, height - y);
ctx.lineTo(width + lineWidth, heightBeyondView);
ctx.closePath();
ctx.fillStyle = "hsla(220, 90%, 70%, 0.2)";
ctx.fill();
ctx.lineWidth = lineWidth;
ctx.strokeStyle = "hsl(220, 90%, 70%)";
ctx.stroke();
this._heapSizeLabel.textContent = WebInspector.UIString("%s \u2013 %s", Number.bytesToString(minUsedHeapSize), Number.bytesToString(maxUsedHeapSize));
},
__proto__: WebInspector.TimelineOverviewBase.prototype
}