• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * @constructor
33 * @extends {WebInspector.TimelineOverviewBase}
34 * @param {!WebInspector.TimelineModel} model
35 * @param {!WebInspector.TimelineUIUtils} uiUtils
36 */
37WebInspector.TimelineMemoryOverview = function(model, uiUtils)
38{
39    WebInspector.TimelineOverviewBase.call(this, model);
40    this._uiUtils = uiUtils;
41    this.element.id = "timeline-overview-memory";
42
43    this._heapSizeLabel = this.element.createChild("div", "memory-graph-label");
44}
45
46WebInspector.TimelineMemoryOverview.prototype = {
47    resetHeapSizeLabels: function()
48    {
49        this._heapSizeLabel.textContent = "";
50    },
51
52    update: function()
53    {
54        this.resetCanvas();
55        var ratio = window.devicePixelRatio;
56
57        var records = this._model.records();
58        if (!records.length) {
59            this.resetHeapSizeLabels();
60            return;
61        }
62
63        var lowerOffset = 3 * ratio;
64        var maxUsedHeapSize = 0;
65        var minUsedHeapSize = 100000000000;
66        var minTime = this._model.minimumRecordTime();
67        var maxTime = this._model.maximumRecordTime();
68        var uiUtils = this._uiUtils;
69        /**
70         * @param {!WebInspector.TimelineModel.Record} record
71         */
72        function calculateMinMaxSizes(record)
73        {
74            var counters = uiUtils.countersForRecord(record);
75            if (!counters || !counters.jsHeapSizeUsed)
76                return;
77            maxUsedHeapSize = Math.max(maxUsedHeapSize, counters.jsHeapSizeUsed);
78            minUsedHeapSize = Math.min(minUsedHeapSize, counters.jsHeapSizeUsed);
79        }
80        this._model.forAllRecords(calculateMinMaxSizes);
81        minUsedHeapSize = Math.min(minUsedHeapSize, maxUsedHeapSize);
82
83        var lineWidth = 1;
84        var width = this._canvas.width;
85        var height = this._canvas.height - lowerOffset;
86        var xFactor = width / (maxTime - minTime);
87        var yFactor = (height - lineWidth) / Math.max(maxUsedHeapSize - minUsedHeapSize, 1);
88
89        var histogram = new Array(width);
90
91        /**
92         * @param {!WebInspector.TimelineModel.Record} record
93         */
94        function buildHistogram(record)
95        {
96            var counters = uiUtils.countersForRecord(record);
97            if (!counters || !counters.jsHeapSizeUsed)
98                return;
99            var x = Math.round((record.endTime() - minTime) * xFactor);
100            var y = Math.round((counters.jsHeapSizeUsed - minUsedHeapSize) * yFactor);
101            histogram[x] = Math.max(histogram[x] || 0, y);
102        }
103        this._model.forAllRecords(buildHistogram);
104
105        var ctx = this._context;
106        var heightBeyondView = height + lowerOffset + lineWidth;
107
108        ctx.translate(0.5, 0.5);
109        ctx.beginPath();
110        ctx.moveTo(-lineWidth, heightBeyondView);
111        var y = 0;
112        var isFirstPoint = true;
113        var lastX = 0;
114        for (var x = 0; x < histogram.length; x++) {
115            if (typeof histogram[x] === "undefined")
116                continue;
117            if (isFirstPoint) {
118                isFirstPoint = false;
119                y = histogram[x];
120                ctx.lineTo(-lineWidth, height - y);
121            }
122            var nextY = histogram[x];
123            if (Math.abs(nextY - y) > 2 && Math.abs(x - lastX) > 1)
124                ctx.lineTo(x, height - y);
125            y = nextY;
126            ctx.lineTo(x, height - y);
127            lastX = x;
128        }
129        ctx.lineTo(width + lineWidth, height - y);
130        ctx.lineTo(width + lineWidth, heightBeyondView);
131        ctx.closePath();
132
133        ctx.fillStyle = "hsla(220, 90%, 70%, 0.2)";
134        ctx.fill();
135        ctx.lineWidth = lineWidth;
136        ctx.strokeStyle = "hsl(220, 90%, 70%)";
137        ctx.stroke();
138
139        this._heapSizeLabel.textContent = WebInspector.UIString("%s \u2013 %s", Number.bytesToString(minUsedHeapSize), Number.bytesToString(maxUsedHeapSize));
140    },
141
142    __proto__: WebInspector.TimelineOverviewBase.prototype
143}
144