Home | History | Annotate | Download | only in timeline
      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  */
     37 WebInspector.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 
     46 WebInspector.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