123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /*
- * 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.
- */
- /**
- * @param {WebInspector.TimelinePanel} timelinePanel
- * @param {WebInspector.TimelineModel} model
- * @param {number} sidebarWidth
- * @constructor
- * @extends {WebInspector.MemoryStatistics}
- */
- WebInspector.NativeMemoryGraph = function(timelinePanel, model, sidebarWidth)
- {
- WebInspector.MemoryStatistics.call(this, timelinePanel, model, sidebarWidth);
- }
- /**
- * @constructor
- * @extends {WebInspector.MemoryStatistics.Counter}
- */
- WebInspector.NativeMemoryGraph.Counter = function(time, nativeCounters)
- {
- WebInspector.MemoryStatistics.Counter.call(this, time);
- this.nativeCounters = nativeCounters;
- }
- /**
- * @constructor
- * @extends {WebInspector.CounterUIBase}
- * @param {WebInspector.NativeMemoryGraph} memoryCountersPane
- * @param {string} title
- * @param {Array.<number>} hsl
- * @param {function(WebInspector.NativeMemoryGraph.Counter):number} valueGetter
- */
- WebInspector.NativeMemoryCounterUI = function(memoryCountersPane, title, hsl, valueGetter)
- {
- var swatchColor = this._hslToString(hsl);
- WebInspector.CounterUIBase.call(this, memoryCountersPane, title, swatchColor, valueGetter);
- this._value = this._swatch.element.createChild("span", "memory-category-value");
- const borderLightnessDifference = 3;
- hsl[2] -= borderLightnessDifference;
- this.strokeColor = this._hslToString(hsl);
- this.graphYValues = [];
- }
- WebInspector.NativeMemoryCounterUI.prototype = {
- _hslToString: function(hsl)
- {
- return "hsl(" + hsl[0] + "," + hsl[1] + "%," + hsl[2] + "%)";
- },
- updateCurrentValue: function(countersEntry)
- {
- var bytes = this.valueGetter(countersEntry);
- var megabytes = bytes / (1024 * 1024);
- this._value.textContent = WebInspector.UIString("%.1f\u2009MB", megabytes);
- },
- clearCurrentValueAndMarker: function(ctx)
- {
- this._value.textContent = "";
- },
- __proto__: WebInspector.CounterUIBase.prototype
- }
- WebInspector.NativeMemoryGraph.prototype = {
- _createCurrentValuesBar: function()
- {
- },
- _createCounterUIList: function()
- {
- var nativeCounters = [
- "JSExternalResources",
- "CSS",
- "GlyphCache",
- "Image",
- "Resources",
- "DOM",
- "Rendering",
- "Audio",
- "WebInspector",
- "JSHeap.Used",
- "JSHeap.Unused",
- "MallocWaste",
- "Other",
- "PrivateBytes",
- ];
- /**
- * @param {string} name
- * @return {number}
- */
- function getCounterValue(name, entry)
- {
- return (entry.nativeCounters && entry.nativeCounters[name]) || 0;
- }
- var list = [];
- for (var i = nativeCounters.length - 1; i >= 0; i--) {
- var name = nativeCounters[i];
- if ("PrivateBytes" === name) {
- var counterUI = new WebInspector.NativeMemoryCounterUI(this, "Total", [0, 0, 0], getCounterValue.bind(this, name))
- this._privateBytesCounter = counterUI;
- } else {
- var counterUI = new WebInspector.NativeMemoryCounterUI(this, name, [i * 20, 65, 63], getCounterValue.bind(this, name))
- list.push(counterUI);
- }
- }
- return list.reverse();
- },
- _canvasHeight: function()
- {
- return this._canvasContainer.offsetHeight;
- },
- /**
- * @param {WebInspector.Event} event
- */
- _onRecordAdded: function(event)
- {
- var statistics = this._counters;
- function addStatistics(record)
- {
- var nativeCounters = record["nativeHeapStatistics"];
- if (!nativeCounters)
- return;
- var knownSize = 0;
- for (var name in nativeCounters) {
- if (name === "PrivateBytes")
- continue;
- knownSize += nativeCounters[name];
- }
- nativeCounters["Other"] = nativeCounters["PrivateBytes"] - knownSize;
- statistics.push(new WebInspector.NativeMemoryGraph.Counter(
- record.endTime || record.startTime,
- nativeCounters
- ));
- }
- WebInspector.TimelinePresentationModel.forAllRecords([event.data], null, addStatistics);
- },
- _draw: function()
- {
- WebInspector.MemoryStatistics.prototype._draw.call(this);
- var maxValue = this._maxCounterValue();
- this._resetTotalValues();
- var previousCounterUI;
- for (var i = 0; i < this._counterUI.length; i++) {
- this._drawGraph(this._counterUI[i], previousCounterUI, maxValue);
- if (this._counterUI[i].visible)
- previousCounterUI = this._counterUI[i];
- }
- },
- /**
- * @param {CanvasRenderingContext2D} ctx
- */
- _clearCurrentValueAndMarker: function(ctx)
- {
- WebInspector.MemoryStatistics.prototype._clearCurrentValueAndMarker.call(this, ctx);
- this._privateBytesCounter.clearCurrentValueAndMarker(ctx);
- },
- _updateCurrentValue: function(counterEntry)
- {
- WebInspector.MemoryStatistics.prototype._updateCurrentValue.call(this, counterEntry);
- this._privateBytesCounter.updateCurrentValue(counterEntry);
- },
- /**
- * @param {CanvasRenderingContext2D} ctx
- */
- _restoreImageUnderMarker: function(ctx)
- {
- if (this._imageUnderMarker)
- ctx.putImageData(this._imageUnderMarker.imageData, this._imageUnderMarker.x, this._imageUnderMarker.y);
- this._discardImageUnderMarker();
- },
- /**
- * @param {CanvasRenderingContext2D} ctx
- * @param {number} left
- * @param {number} top
- * @param {number} right
- * @param {number} bottom
- */
- _saveImageUnderMarker: function(ctx, left, top, right, bottom)
- {
- var imageData = ctx.getImageData(left, top, right, bottom);
- this._imageUnderMarker = {
- x: left,
- y: top,
- imageData: imageData
- };
- },
- /**
- * @param {CanvasRenderingContext2D} ctx
- * @param {number} x
- * @param {number} index
- */
- _drawMarker: function(ctx, x, index)
- {
- var left = this._counters[index].x;
- var right = index + 1 < this._counters.length ? this._counters[index + 1].x : left;
- var top = this._originY;
- top = 0;
- var bottom = top + this._clippedHeight;
- bottom += this._originY;
- this._saveImageUnderMarker(ctx, left, top, right, bottom);
- ctx.beginPath();
- ctx.moveTo(left, top);
- ctx.lineTo(right, top);
- ctx.lineTo(right, bottom);
- ctx.lineTo(left, bottom);
- ctx.lineWidth = 1;
- ctx.closePath();
- ctx.fillStyle = "rgba(220,220,220,0.3)";
- ctx.fill();
- },
- /**
- * @return {number}
- */
- _maxCounterValue: function()
- {
- if (!this._counters.length)
- return 0;
- var valueGetter = this._privateBytesCounter.valueGetter;
- var result = 0;
- for (var i = this._minimumIndex; i < this._maximumIndex; i++) {
- var counter = this._counters[i];
- var value = valueGetter(counter);
- if (value > result)
- result = value;
- }
- return result;
- },
- _resetTotalValues: function()
- {
- for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
- var counter = this._counters[i];
- counter.total = 0;
- }
- },
- /**
- * @param {WebInspector.CounterUIBase} counterUI
- * @param {WebInspector.CounterUIBase} previousCounterUI
- * @param {number} maxTotalValue
- */
- _drawGraph: function(counterUI, previousCounterUI, maxTotalValue)
- {
- var canvas = this._canvas;
- var ctx = canvas.getContext("2d");
- var width = canvas.width;
- var height = this._clippedHeight;
- var originY = this._originY;
- var valueGetter = counterUI.valueGetter;
- if (!this._counters.length)
- return;
- if (!counterUI.visible)
- return;
- for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
- var counter = this._counters[i];
- var value = valueGetter(counter);
- counter.total += value;
- }
- var yValues = counterUI.graphYValues;
- yValues.length = this._counters.length;
- var maxYRange = maxTotalValue;
- var yFactor = maxYRange ? height / (maxYRange) : 1;
- ctx.beginPath();
- if (previousCounterUI) {
- var prevYValues = previousCounterUI.graphYValues;
- var currentY = prevYValues[this._maximumIndex];
- ctx.moveTo(width, currentY);
- var currentX = width;
- for (var i = this._maximumIndex - 1; i >= this._minimumIndex; i--) {
- currentY = prevYValues[i];
- currentX = this._counters[i].x;
- ctx.lineTo(currentX, currentY);
- }
- } else {
- var lastY = originY + height;
- ctx.moveTo(width, lastY);
- ctx.lineTo(0, lastY);
- }
- var currentY = originY + (height - this._counters[this._minimumIndex].total * yFactor);
- ctx.lineTo(0, currentY);
- for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
- var counter = this._counters[i];
- var x = counter.x;
- currentY = originY + (height - counter.total * yFactor);
- ctx.lineTo(x, currentY);
- yValues[i] = currentY;
- }
- ctx.lineTo(width, currentY);
- ctx.closePath();
- ctx.lineWidth = 1;
- ctx.strokeStyle = counterUI.strokeColor;
- ctx.fillStyle = counterUI.graphColor;
- ctx.fill();
- ctx.stroke();
- },
- _discardImageUnderMarker: function()
- {
- delete this._imageUnderMarker;
- },
- __proto__: WebInspector.MemoryStatistics.prototype
- }
|