Changeset 119197 in webkit


Ignore:
Timestamp:
Jun 1, 2012 1:17:52 AM (12 years ago)
Author:
yurys@chromium.org
Message:

Web Inspector: draw pie-chart based on memory data received from backend
https://bugs.webkit.org/show_bug.cgi?id=87737

Reviewed by Pavel Feldman.

Added pie chart for memory data received from inspector memory agent.

  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • inspector/front-end/NativeMemorySnapshotView.js:

(WebInspector.NativeMemorySnapshotView):
(WebInspector.NativeMemoryProfileType):
(WebInspector.NativeMemoryProfileType.prototype.buttonClicked.didReceiveMemorySnapshot):
(WebInspector.NativeMemoryProfileType.prototype.buttonClicked):
(WebInspector.NativeMemoryProfileHeader):
(WebInspector.MemoryBlockViewProperties):
(WebInspector.MemoryBlockViewProperties._initialize):
(WebInspector.MemoryBlockViewProperties._forMemoryBlock):
(WebInspector.NativeMemoryPieChart):
(WebInspector.NativeMemoryPieChart.prototype.onResize):
(WebInspector.NativeMemoryPieChart.prototype._updateSize):
(WebInspector.NativeMemoryPieChart.prototype._addBlockLabels):
(WebInspector.NativeMemoryPieChart.prototype._paint.paintPercentAndLabel):
(WebInspector.NativeMemoryPieChart.prototype._paint):
(WebInspector.NativeMemoryPieChart.prototype._clear):

  • inspector/front-end/WebKit.qrc:
  • inspector/front-end/nativeMemoryProfiler.css: Added.

(.memory-pie-chart-container):
(.memory-pie-chart):
(.memory-blocks-list .swatch):
(.memory-blocks-list):
(.memory-blocks-list .item):

Location:
trunk/Source/WebCore
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r119196 r119197  
     12012-05-29  Yury Semikhatsky  <yurys@chromium.org>
     2
     3        Web Inspector: draw pie-chart based on memory data received from backend
     4        https://bugs.webkit.org/show_bug.cgi?id=87737
     5
     6        Reviewed by Pavel Feldman.
     7
     8        Added pie chart for memory data received from inspector memory agent.
     9
     10        * WebCore.gypi:
     11        * WebCore.vcproj/WebCore.vcproj:
     12        * inspector/front-end/NativeMemorySnapshotView.js:
     13        (WebInspector.NativeMemorySnapshotView):
     14        (WebInspector.NativeMemoryProfileType):
     15        (WebInspector.NativeMemoryProfileType.prototype.buttonClicked.didReceiveMemorySnapshot):
     16        (WebInspector.NativeMemoryProfileType.prototype.buttonClicked):
     17        (WebInspector.NativeMemoryProfileHeader):
     18        (WebInspector.MemoryBlockViewProperties):
     19        (WebInspector.MemoryBlockViewProperties._initialize):
     20        (WebInspector.MemoryBlockViewProperties._forMemoryBlock):
     21        (WebInspector.NativeMemoryPieChart):
     22        (WebInspector.NativeMemoryPieChart.prototype.onResize):
     23        (WebInspector.NativeMemoryPieChart.prototype._updateSize):
     24        (WebInspector.NativeMemoryPieChart.prototype._addBlockLabels):
     25        (WebInspector.NativeMemoryPieChart.prototype._paint.paintPercentAndLabel):
     26        (WebInspector.NativeMemoryPieChart.prototype._paint):
     27        (WebInspector.NativeMemoryPieChart.prototype._clear):
     28        * inspector/front-end/WebKit.qrc:
     29        * inspector/front-end/nativeMemoryProfiler.css: Added.
     30        (.memory-pie-chart-container):
     31        (.memory-pie-chart):
     32        (.memory-blocks-list .swatch):
     33        (.memory-blocks-list):
     34        (.memory-blocks-list .item):
     35
    1362012-05-31  Dominic Cooney  <dominicc@chromium.org>
    237
  • trunk/Source/WebCore/WebCore.gypi

    r119121 r119197  
    65506550            'inspector/front-end/indexedDBViews.css',
    65516551            'inspector/front-end/inspectorCommon.css',
     6552            'inspector/front-end/nativeMemoryProfiler.css',
    65526553            'inspector/front-end/navigatorView.css',
    65536554            'inspector/front-end/networkLogView.css',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r119073 r119197  
    7469974699                                </File>
    7470074700                                <File
     74701                                        RelativePath="..\inspector\front-end\nativeMemoryProfiler.css"
     74702                                        >
     74703                                </File>
     74704                                <File
    7470174705                                        RelativePath="..\inspector\front-end\navigatorView.css"
    7470274706                                        >
  • trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp

    r119068 r119197  
    6161
    6262namespace MemoryBlockName {
    63 static const char totalJsHeap[] = "TotalJSHeap";
     63static const char jsHeapAllocated[] = "JSHeapAllocated";
     64static const char jsHeapUsed[] = "JSHeapUsed";
    6465static const char processPrivateMemory[] = "ProcessPrivateMemory";
    65 static const char usedJsHeap[] = "UsedJSHeap";
    6666}
    6767
     
    323323    ScriptGCEvent::getHeapSize(usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit);
    324324
    325     RefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> totalJsHeap = WebCore::TypeBuilder::Memory::MemoryBlock::create().setName(MemoryBlockName::totalJsHeap);
    326     totalJsHeap->setSize(static_cast<int>(totalJSHeapSize));
     325    RefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> jsHeapAllocated = WebCore::TypeBuilder::Memory::MemoryBlock::create().setName(MemoryBlockName::jsHeapAllocated);
     326    jsHeapAllocated->setSize(static_cast<int>(totalJSHeapSize));
    327327
    328328    RefPtr<TypeBuilder::Array<WebCore::TypeBuilder::Memory::MemoryBlock> > children = TypeBuilder::Array<WebCore::TypeBuilder::Memory::MemoryBlock>::create();
    329     RefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> usedJsHeap = WebCore::TypeBuilder::Memory::MemoryBlock::create().setName(MemoryBlockName::usedJsHeap);
    330     usedJsHeap->setSize(static_cast<int>(usedJSHeapSize));
    331     children->addItem(usedJsHeap);
    332 
    333     totalJsHeap->setChildren(children);
    334     return totalJsHeap.release();
     329    RefPtr<WebCore::TypeBuilder::Memory::MemoryBlock> jsHeapUsed = WebCore::TypeBuilder::Memory::MemoryBlock::create().setName(MemoryBlockName::jsHeapUsed);
     330    jsHeapUsed->setSize(static_cast<int>(usedJSHeapSize));
     331    children->addItem(jsHeapUsed);
     332
     333    jsHeapAllocated->setChildren(children);
     334    return jsHeapAllocated.release();
    335335}
    336336
  • trunk/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js

    r118519 r119197  
    3636{
    3737    WebInspector.View.call(this);
     38    this.registerRequiredCSS("nativeMemoryProfiler.css");
     39    this._profile = profile;
    3840    this.element.addStyleClass("memory-chart-view");
    39     this.element.createChild("div").textContent = "Memory chart";
    40     this._profile = profile;
     41
     42    var pieChart = new WebInspector.NativeMemoryPieChart(profile._memoryBlock);
     43    pieChart.element.addStyleClass("fill");
     44    pieChart.show(this.element);
    4145}
    4246
     
    6670{
    6771    WebInspector.ProfileType.call(this, WebInspector.NativeMemoryProfileType.TypeId, WebInspector.UIString("Take Native Memory Snapshot"));
    68     this._profileIndex = 1;
     72    this._nextProfileUid = 1;
    6973}
    7074
     
    8488    {
    8589        var profilesPanel = WebInspector.panels.profiles;
    86         var profileHeader = new WebInspector.NativeMemoryProfileHeader(this, WebInspector.UIString("Snapshot %d", this._profileIndex++), -1);
     90        var profileHeader = new WebInspector.NativeMemoryProfileHeader(this, WebInspector.UIString("Snapshot %d", this._nextProfileUid), this._nextProfileUid);
     91        ++this._nextProfileUid;
     92        profileHeader.isTemporary = true;
    8793        profilesPanel.addProfileHeader(profileHeader);
     94        function didReceiveMemorySnapshot(error, memoryBlock)
     95        {
     96            profileHeader._memoryBlock = memoryBlock;
     97            profileHeader.isTemporary = false;
     98        }
     99        MemoryAgent.getProcessMemoryDistribution(didReceiveMemorySnapshot.bind(this));
    88100        return false;
    89101    },
     
    133145{
    134146    WebInspector.ProfileHeader.call(this, type, title, uid);
     147
     148    /**
     149     * @type {MemoryAgent.MemoryBlock}
     150     */
     151    this._memoryBlock = null;
    135152}
    136153
     
    154171
    155172WebInspector.NativeMemoryProfileHeader.prototype.__proto__ = WebInspector.ProfileHeader.prototype;
     173
     174/**
     175 * @constructor
     176 * @param {string} fillStyle
     177 * @param {string} name
     178 * @param {string} description
     179 */
     180WebInspector.MemoryBlockViewProperties = function(fillStyle, name, description)
     181{
     182    this._fillStyle = fillStyle;
     183    this._name = name;
     184    this._description = description;
     185}
     186
     187/**
     188 * @type {Object.<string, WebInspector.MemoryBlockViewProperties>}
     189 */
     190WebInspector.MemoryBlockViewProperties._standardBlocks = null;
     191
     192WebInspector.MemoryBlockViewProperties._initialize = function()
     193{
     194    if (WebInspector.MemoryBlockViewProperties._standardBlocks)
     195        return;
     196    WebInspector.MemoryBlockViewProperties._standardBlocks = {};
     197    function addBlock(fillStyle, name, description)
     198    {
     199        WebInspector.MemoryBlockViewProperties._standardBlocks[name] = new WebInspector.MemoryBlockViewProperties(fillStyle, name, WebInspector.UIString(description));
     200    }
     201    addBlock("rgba(240, 240, 250, 0.8)", "ProcessPrivateMemory", "Total");
     202    addBlock("rgba(250, 200, 200, 0.8)", "JSHeapAllocated", "JavaScript heap");
     203    addBlock("rgba(200, 250, 200, 0.8)", "JSHeapUsed", "Used JavaScript heap");
     204}
     205
     206WebInspector.MemoryBlockViewProperties._forMemoryBlock = function(memoryBlock)
     207{
     208    WebInspector.MemoryBlockViewProperties._initialize();
     209    var result = WebInspector.MemoryBlockViewProperties._standardBlocks[memoryBlock.name];
     210    if (result)
     211        return result;
     212    return new WebInspector.MemoryBlockViewProperties("rgba(20, 200, 20, 0.8)", memoryBlock.name, memoryBlock.name);
     213}
     214
     215
     216/**
     217 * @constructor
     218 * @extends {WebInspector.View}
     219 * @param {MemoryAgent.MemoryBlock} memorySnapshot
     220 */
     221WebInspector.NativeMemoryPieChart = function(memorySnapshot)
     222{
     223    WebInspector.View.call(this);
     224    this._memorySnapshot = memorySnapshot;
     225    this.element = document.createElement("div");
     226    this.element.addStyleClass("memory-pie-chart-container");
     227    this._memoryBlockList = this.element.createChild("div", "memory-blocks-list");
     228
     229    this._canvasContainer = this.element.createChild("div", "memory-pie-chart");
     230    this._canvas = this._canvasContainer.createChild("canvas");
     231    this._addBlockLabels(memorySnapshot, true);
     232}
     233
     234WebInspector.NativeMemoryPieChart.prototype = {
     235    /**
     236     * @override
     237     */
     238    onResize: function()
     239    {
     240        this._updateSize();
     241        this._paint();
     242    },
     243
     244    _updateSize: function()
     245    {
     246        var width = this._canvasContainer.clientWidth - 5;
     247        var height = this._canvasContainer.clientHeight - 5;
     248        this._canvas.width = width;
     249        this._canvas.height = height;
     250    },
     251
     252    _addBlockLabels: function(memoryBlock, includeChildren)
     253    {
     254        var viewProperties = WebInspector.MemoryBlockViewProperties._forMemoryBlock(memoryBlock);
     255        var title = viewProperties._description + ": " + Number.bytesToString(memoryBlock.size);
     256
     257        var swatchElement = this._memoryBlockList.createChild("div", "item");
     258        swatchElement.createChild("div", "swatch").style.backgroundColor = viewProperties._fillStyle;
     259        swatchElement.createChild("span", "title").textContent = WebInspector.UIString(title);
     260
     261        if (!memoryBlock.children || !includeChildren)
     262            return;
     263        for (var i = 0; i < memoryBlock.children.length; i++)
     264            this._addBlockLabels(memoryBlock.children[i], false);
     265    },
     266
     267    _paint: function()
     268    {
     269        this._clear();
     270        var width = this._canvas.width;
     271        var height = this._canvas.height;
     272
     273        var x = width / 2;
     274        var y = height / 2;
     275        var radius = 200;
     276
     277        var ctx = this._canvas.getContext("2d");
     278        ctx.beginPath();
     279        ctx.arc(x, y, radius, 0, Math.PI*2, false);
     280        ctx.lineWidth = 1;
     281        ctx.fillStyle = WebInspector.MemoryBlockViewProperties._forMemoryBlock(this._memorySnapshot)._fillStyle;
     282        ctx.strokeStyle = "rgba(130, 130, 130, 0.8)";
     283        ctx.fill();
     284        ctx.stroke();
     285        ctx.closePath();
     286
     287        var startAngle = - Math.PI / 2;
     288        var currentAngle = startAngle;
     289        var memoryBlock = this._memorySnapshot;
     290
     291        function paintPercentAndLabel(fraction, title, midAngle)
     292        {
     293            ctx.beginPath();
     294            ctx.font = "14px Arial";
     295            ctx.fillStyle = "rgba(10, 10, 10, 0.8)";
     296
     297            var textX = x + radius * Math.cos(midAngle) / 2;
     298            var textY = y + radius * Math.sin(midAngle) / 2;
     299            ctx.fillText((100 * fraction).toFixed(0) + "%", textX, textY);
     300
     301            textX = x + radius * Math.cos(midAngle);
     302            textY = y + radius * Math.sin(midAngle);
     303            if (midAngle <= startAngle + Math.PI) {
     304                textX += 10;
     305                textY += 10;
     306            } else {
     307                var metrics = ctx.measureText(title);
     308                textX -= metrics.width + 10;
     309            }
     310            ctx.fillText(title, textX, textY);
     311            ctx.closePath();
     312        }
     313
     314        if (memoryBlock.children) {
     315            var total = memoryBlock.size;
     316            for (var i = 0; i < memoryBlock.children.length; i++) {
     317                var child = memoryBlock.children[i];
     318                if (!child.size)
     319                    continue;
     320                var viewProperties = WebInspector.MemoryBlockViewProperties._forMemoryBlock(child);
     321                var angleSpan = Math.PI * 2 * (child.size / total);
     322                ctx.beginPath();
     323                ctx.moveTo(x, y);
     324                ctx.lineTo(x + radius * Math.cos(currentAngle), y + radius * Math.sin(currentAngle));
     325                ctx.arc(x, y, radius, currentAngle, currentAngle + angleSpan, false);
     326                ctx.lineWidth = 0.5;
     327                ctx.lineTo(x, y);
     328                ctx.fillStyle = viewProperties._fillStyle;
     329                ctx.strokeStyle = "rgba(100, 100, 100, 0.8)";
     330                ctx.fill();
     331                ctx.stroke();
     332                ctx.closePath();
     333
     334                paintPercentAndLabel(child.size / total, viewProperties._description, currentAngle + angleSpan / 2);
     335
     336                currentAngle += angleSpan;
     337            }
     338        }
     339
     340        var fraction = 1 - (currentAngle - startAngle) / (2 * Math.PI);
     341        var midAngle = (currentAngle + startAngle + 2 * Math.PI) / 2;
     342        paintPercentAndLabel(fraction, WebInspector.UIString("Unknown"), midAngle);
     343    },
     344
     345    _clear: function() {
     346        var ctx = this._canvas.getContext("2d");
     347        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
     348    }
     349}
     350
     351WebInspector.NativeMemoryPieChart.prototype.__proto__ = WebInspector.View.prototype;
  • trunk/Source/WebCore/inspector/front-end/WebKit.qrc

    r118527 r119197  
    198198    <file>inspectorCommon.css</file>
    199199    <file>inspectorSyntaxHighlight.css</file>
     200    <file>nativeMemoryProfiler.css</file>
    200201    <file>navigatorView.css</file>
    201202    <file>networkLogView.css</file>
Note: See TracChangeset for help on using the changeset viewer.