Title: [122706] trunk/Source/WebCore
Revision
122706
Author
[email protected]
Date
2012-07-16 01:53:27 -0700 (Mon, 16 Jul 2012)

Log Message

Web Inspector: Implement message loop instrumentation for timeline
https://bugs.webkit.org/show_bug.cgi?id=88325

Patch by Eugene Klyuchnikov <[email protected]> on 2012-07-16
Reviewed by Pavel Feldman.

Message loop instrumentation will show when the render thread is busy.

* inspector/front-end/Settings.js:
(WebInspector.ExperimentsSettings):
Added new experiment.
* inspector/front-end/TimelineGrid.js:
(WebInspector.TimelineGrid.prototype.get dividersLabelBarElement):
Exposed label bar element.
* inspector/front-end/TimelinePanel.js:
(WebInspector.TimelinePanel):
(WebInspector.TimelinePanel.prototype._resetPanel):
Cleanups recorded tasks.
(WebInspector.TimelinePanel.prototype._refresh):
Updates CPU bar.
(WebInspector.TimelinePanel.prototype._refreshRecords):
Ditto.
(WebInspector.TimelinePanel.prototype._refreshCpuBars.compareEndTime):
Ditto.
(WebInspector.TimelinePanel.prototype._refreshCpuBars):
Ditto.
(WebInspector.TimelinePanel.prototype._enableMainThreadMonitoringExperiment):
Adds CPU bar to UI.
(WebInspector.TimelinePanel.prototype._showPopover):
Fix NPE.
(WebInspector.TimelineCalculator.prototype.computeTime):
Utility for position to time conversion.
(WebInspector.TimelineCalculator.prototype.setDisplayWindow):
Remenbers clientWidth.
* inspector/front-end/TimelinePresentationModel.js:
(WebInspector.TimelinePresentationModel.categories):
Define CPU bar colors.
* inspector/front-end/timelinePanel.css:
(.timeline-cpu-bars):
CPU bar styles.
(.timeline-cpu-bars-label):
Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (122705 => 122706)


--- trunk/Source/WebCore/ChangeLog	2012-07-16 08:41:48 UTC (rev 122705)
+++ trunk/Source/WebCore/ChangeLog	2012-07-16 08:53:27 UTC (rev 122706)
@@ -1,3 +1,47 @@
+2012-07-16  Eugene Klyuchnikov  <[email protected]>
+
+        Web Inspector: Implement message loop instrumentation for timeline
+        https://bugs.webkit.org/show_bug.cgi?id=88325
+
+        Reviewed by Pavel Feldman.
+
+        Message loop instrumentation will show when the render thread is busy.
+
+        * inspector/front-end/Settings.js:
+        (WebInspector.ExperimentsSettings):
+        Added new experiment.
+        * inspector/front-end/TimelineGrid.js:
+        (WebInspector.TimelineGrid.prototype.get dividersLabelBarElement):
+        Exposed label bar element.
+        * inspector/front-end/TimelinePanel.js:
+        (WebInspector.TimelinePanel):
+        (WebInspector.TimelinePanel.prototype._resetPanel):
+        Cleanups recorded tasks.
+        (WebInspector.TimelinePanel.prototype._refresh):
+        Updates CPU bar.
+        (WebInspector.TimelinePanel.prototype._refreshRecords):
+        Ditto.
+        (WebInspector.TimelinePanel.prototype._refreshCpuBars.compareEndTime):
+        Ditto.
+        (WebInspector.TimelinePanel.prototype._refreshCpuBars):
+        Ditto.
+        (WebInspector.TimelinePanel.prototype._enableMainThreadMonitoringExperiment):
+        Adds CPU bar to UI.
+        (WebInspector.TimelinePanel.prototype._showPopover):
+        Fix NPE.
+        (WebInspector.TimelineCalculator.prototype.computeTime):
+        Utility for position to time conversion.
+        (WebInspector.TimelineCalculator.prototype.setDisplayWindow):
+        Remenbers clientWidth.
+        * inspector/front-end/TimelinePresentationModel.js:
+        (WebInspector.TimelinePresentationModel.categories):
+        Define CPU bar colors.
+        * inspector/front-end/timelinePanel.css:
+        (.timeline-cpu-bars):
+        CPU bar styles.
+        (.timeline-cpu-bars-label):
+        Ditto.
+
 2012-07-16  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r122681.

Modified: trunk/Source/WebCore/English.lproj/localizedStrings.js (122705 => 122706)


--- trunk/Source/WebCore/English.lproj/localizedStrings.js	2012-07-16 08:41:48 UTC (rev 122705)
+++ trunk/Source/WebCore/English.lproj/localizedStrings.js	2012-07-16 08:53:27 UTC (rev 122706)
@@ -715,6 +715,7 @@
 localizedStrings["apply original content"] = "apply original content";
 localizedStrings["apply revision content"] = "apply revision content";
 localizedStrings["revert"] = "revert";
+localizedStrings["CPU"] = "CPU";
 localizedStrings["CPU Time"] = "CPU Time";
 localizedStrings["Encoded Data Length"] = "Encoded Data Length";
 localizedStrings["%d Bytes"] = "%d Bytes";

Modified: trunk/Source/WebCore/inspector/front-end/Settings.js (122705 => 122706)


--- trunk/Source/WebCore/inspector/front-end/Settings.js	2012-07-16 08:41:48 UTC (rev 122705)
+++ trunk/Source/WebCore/inspector/front-end/Settings.js	2012-07-16 08:53:27 UTC (rev 122706)
@@ -187,6 +187,7 @@
     this.nativeMemorySnapshots = this._createExperiment("nativeMemorySnapshots", "Native memory profiling");
     this.liveNativeMemoryChart = this._createExperiment("liveNativeMemoryChart", "Live native memory chart");
     this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
+    this.mainThreadMonitoring = this._createExperiment("mainThreadMonitoring", "Show CPU activity in Timeline");
 
     this._cleanUpSetting();
 }

Modified: trunk/Source/WebCore/inspector/front-end/TimelineGrid.js (122705 => 122706)


--- trunk/Source/WebCore/inspector/front-end/TimelineGrid.js	2012-07-16 08:41:48 UTC (rev 122705)
+++ trunk/Source/WebCore/inspector/front-end/TimelineGrid.js	2012-07-16 08:53:27 UTC (rev 122706)
@@ -67,6 +67,11 @@
         return this._dividersElement;
     },
 
+    get dividersLabelBarElement()
+    {
+        return this._dividersLabelBarElement;
+    },
+
     get gridHeaderElement()
     {
         return this._gridHeaderElement;

Modified: trunk/Source/WebCore/inspector/front-end/TimelinePanel.js (122705 => 122706)


--- trunk/Source/WebCore/inspector/front-end/TimelinePanel.js	2012-07-16 08:41:48 UTC (rev 122705)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePanel.js	2012-07-16 08:53:27 UTC (rev 122706)
@@ -120,6 +120,13 @@
     this._timeStampRecords = [];
     this._expandOffset = 15;
 
+    this._headerLineCount = 1;
+
+    this._mainThreadTasks = [];
+    this._mainThreadMonitoringEnabled = false;
+    if (WebInspector.experimentsSettings.mainThreadMonitoring.isEnabled())
+        this._enableMainThreadMonitoring();
+
     this._createFileSelector();
 
     this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this);
@@ -365,9 +372,11 @@
         if (this._frameContainer)
             this._frameContainer.removeChildren();
         else {
+            const frameContainerBorderWidth = 1;
             this._frameContainer = document.createElement("div");
             this._frameContainer.addStyleClass("fill");
             this._frameContainer.addStyleClass("timeline-frame-container");
+            this._frameContainer.style.height = this._headerLineCount * WebInspector.TimelinePanel.rowHeight + frameContainerBorderWidth + "px";
             this._frameContainer.addEventListener("dblclick", this._onFrameDoubleClicked.bind(this), false);
         }
 
@@ -497,9 +506,15 @@
 
     _innerAddRecordToTimeline: function(record, parentRecord)
     {
+        if (record.type === WebInspector.TimelineModel.RecordType.Program) {
+            this._mainThreadTasks.push({
+                startTime: WebInspector.TimelineModel.startTimeInSeconds(record),
+                endTime: WebInspector.TimelineModel.endTimeInSeconds(record)
+            });
+        }
+
         var records = this._presentationModel.addRecord(record, parentRecord);
         this._allRecordsCount += records.length;
-        var recordTypes = WebInspector.TimelineModel.RecordType;
         var timeStampRecords = this._timeStampRecords;
         var hasVisibleRecords = false;
         var presentationModel = this._presentationModel;
@@ -560,6 +575,7 @@
         this._closeRecordDetails();
         this._allRecordsCount = 0;
         this._automaticallySizeWindow = true;
+        this._mainThreadTasks = [];
     },
 
     elementsToRestoreScrollPositionsFor: function()
@@ -618,8 +634,9 @@
             delete this._refreshTimeout;
         }
 
+        this._timelinePaddingLeft = !this._overviewPane.windowLeft() ? this._expandOffset : 0;
         this._calculator.setWindow(this._overviewPane.windowStartTime(), this._overviewPane.windowEndTime());
-        this._calculator.setDisplayWindow(!this._overviewPane.windowLeft() ? this._expandOffset : 0, this._graphRowsElementWidth);
+        this._calculator.setDisplayWindow(this._timelinePaddingLeft, this._graphRowsElementWidth);
 
         var recordsInWindowCount = this._refreshRecords();
         this._updateRecordsCounter(recordsInWindowCount);
@@ -631,6 +648,8 @@
             } else {
                 this._timelineGrid.updateDividers(this._calculator);
             }
+            if (this._mainThreadMonitoringEnabled)
+                this._refreshMainThreadBars();
         }
         if (this._memoryStatistics.visible())
             this._memoryStatistics.refresh();
@@ -676,9 +695,9 @@
         const rowHeight = WebInspector.TimelinePanel.rowHeight;
 
         // Convert visible area to visible indexes. Always include top-level record for a visible nested record.
-        var startIndex = Math.max(0, Math.min(Math.floor(visibleTop / rowHeight) - 1, recordsInWindow.length - 1));
+        var startIndex = Math.max(0, Math.min(Math.floor(visibleTop / rowHeight) - this._headerLineCount, recordsInWindow.length - 1));
         var endIndex = Math.min(recordsInWindow.length, Math.ceil(visibleBottom / rowHeight));
-        var lastVisibleLine = Math.max(0, Math.floor(visibleBottom / rowHeight) - 1);
+        var lastVisibleLine = Math.max(0, Math.floor(visibleBottom / rowHeight) - this._headerLineCount);
         if (this._automaticallySizeWindow && recordsInWindow.length > lastVisibleLine) {
             this._automaticallySizeWindow = false;
             // If we're at the top, always use real timeline start as a left window bound so that expansion arrow padding logic works.
@@ -746,11 +765,103 @@
 
         this._itemsGraphsElement.insertBefore(this._graphRowsElement, this._bottomGapElement);
         this._itemsGraphsElement.appendChild(this._expandElements);
-        this._adjustScrollPosition((recordsInWindow.length + 1) * rowHeight);
+        this._adjustScrollPosition((recordsInWindow.length + this._headerLineCount) * rowHeight);
 
         return recordsInWindow.length;
     },
 
+    _refreshMainThreadBars: function()
+    {
+        const barOffset = 3;
+        const minGap = 3;
+
+        var minWidth = WebInspector.TimelineCalculator._minWidth;
+        var widthAdjustment = minWidth / 2;
+
+        var width = this._graphRowsElementWidth;
+        var boundarySpan = this._overviewPane.windowEndTime() - this._overviewPane.windowStartTime();
+        var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft);
+        var startTime = this._overviewPane.windowStartTime() - this._timelinePaddingLeft * scale;
+        var endTime = startTime + width * scale;
+
+        var tasks = this._mainThreadTasks;
+        if (!tasks.length)
+            return;
+
+        function compareEndTime(value, task)
+        {
+            return value < task.endTime ? -1 : 1;
+        }
+
+        var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime);
+        if (taskIndex === tasks.length)
+            return;
+
+        var container = this._cpuBarsElement;
+        var element = container.firstChild.nextSibling;
+        var lastElement;
+        var lastLeft;
+        var lastRight;
+
+        while (taskIndex < tasks.length) {
+            var task = tasks[taskIndex];
+            if (task.startTime > endTime)
+                break;
+            taskIndex++;
+
+            var left = Math.max(0, this._calculator.computePosition(task.startTime) + barOffset - widthAdjustment);
+            var right = Math.min(width, this._calculator.computePosition(task.endTime) + barOffset + widthAdjustment);
+
+            if (lastElement) {
+                var gap = Math.floor(left) - Math.ceil(lastRight);
+                if (gap < minGap) {
+                    lastRight = right;
+                    continue;
+                }
+                lastElement.style.width = (lastRight - lastLeft) + "px";
+            }
+
+            if (!element)
+                element = container.createChild("div", "timeline-graph-bar");
+
+            element.style.left = left + "px";
+            lastLeft = left;
+            lastRight = right;
+
+            lastElement = element;
+            element = element.nextSibling;
+        }
+
+        if (lastElement)
+            lastElement.style.width = (lastRight - lastLeft) + "px";
+
+        while (element) {
+            var nextElement = element.nextSibling;
+            container.removeChild(element);
+            element = nextElement;
+        }
+    },
+
+    _enableMainThreadMonitoring: function()
+    {
+        ++this._headerLineCount;
+
+        var container = this._timelineGrid.gridHeaderElement;
+        this._cpuBarsElement = container.createChild("div", "timeline-cpu-bars timeline-category-program");
+        var cpuBarsLabel = this._cpuBarsElement.createChild("span", "timeline-cpu-bars-label");
+        cpuBarsLabel.textContent = WebInspector.UIString("CPU");
+
+        const headerBorderWidth = 1;
+        const headerMargin = 2;
+
+        var headerHeight = this._headerLineCount * WebInspector.TimelinePanel.rowHeight;
+        this.sidebarElement.firstChild.style.height = headerHeight + "px";
+        this._timelineGrid.dividersLabelBarElement.style.height = headerHeight + headerMargin + "px";
+        this._itemsGraphsElement.style.top = headerHeight + headerBorderWidth + "px";
+
+        this._mainThreadMonitoringEnabled = true;
+    },
+
     _adjustScrollPosition: function(totalHeight)
     {
         // Prevent the container from being scrolled off the end.
@@ -806,8 +917,8 @@
             var frame = anchor._frame;
             popover.show(WebInspector.TimelinePresentationModel.generatePopupContentForFrame(frame), anchor);
         } else {
-            var record = anchor.row._record;
-            popover.show(record.generatePopupContent(), anchor);
+            if (anchor.row && anchor.row._record)
+                popover.show(anchor.row._record.generatePopupContent(), anchor);
         }
     },
 

Modified: trunk/Source/WebCore/inspector/front-end/timelinePanel.css (122705 => 122706)


--- trunk/Source/WebCore/inspector/front-end/timelinePanel.css	2012-07-16 08:41:48 UTC (rev 122705)
+++ trunk/Source/WebCore/inspector/front-end/timelinePanel.css	2012-07-16 08:53:27 UTC (rev 122706)
@@ -595,11 +595,6 @@
     border-color: transparent;
 }
 
-.timeline.timeline-frame-overview .resources-divider {
-    height: 19px;
-    bottom: auto;
-}
-
 .timeline .resources-event-divider.timeline-frame-divider {
     background-color: rgba(180, 180, 180, 0.8);
     border-style: none;
@@ -638,3 +633,25 @@
     bottom: 0;
     pointer-events: none;
 }
+
+.timeline-cpu-bars {
+    position: absolute;
+    top: 19px;
+    height: 18px;
+    z-index: 350;
+    width: 100%;
+    overflow: hidden;
+}
+
+.timeline-cpu-bars-label {
+    font-weight: bold;
+    font-family: monospace;
+    font-size: 9px;
+    line-height: 7px;
+    position: absolute;
+    top: 5px;
+    left: 4px;
+    color: rgb(51, 51, 51);
+    background-color: rgba(255, 255, 255, 0.75);
+    z-index: 350;
+}
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to