Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(543)

Side by Side Diff: Source/devtools/front_end/TimelinePanel.js

Issue 46663010: DevTools: Show GPU utilization bar on timeline (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Intel Inc. All rights reserved. 3 * Copyright (C) 2012 Intel Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 127
128 // Short events filter is disabled by default. 128 // Short events filter is disabled by default.
129 this._durationFilter = new WebInspector.TimelineIsLongFilter(); 129 this._durationFilter = new WebInspector.TimelineIsLongFilter();
130 130
131 this._expandOffset = 15; 131 this._expandOffset = 15;
132 132
133 this._headerLineCount = 1; 133 this._headerLineCount = 1;
134 this._adjustHeaderHeight(); 134 this._adjustHeaderHeight();
135 135
136 this._mainThreadTasks = /** @type {!Array.<{startTime: number, endTime: numb er}>} */ ([]); 136 this._mainThreadTasks = /** @type {!Array.<{startTime: number, endTime: numb er}>} */ ([]);
137 this._gpuTasks = /** @type {!Array.<{startTime: number, endTime: number, pid : number}>} */ ([]);
137 this._cpuBarsElement = this._timelineGrid.gridHeaderElement.createChild("div ", "timeline-cpu-bars"); 138 this._cpuBarsElement = this._timelineGrid.gridHeaderElement.createChild("div ", "timeline-cpu-bars");
139 if (WebInspector.experimentsSettings.gpuTimeline.isEnabled()) {
140 this._cpuBarsElement.style.top = "1px";
yurys 2013/10/31 15:06:52 I'd rather do this in timelinePanel.css since you
alph 2013/10/31 16:58:00 Done.
141 this._cpuBarsElement.style.height = "9px";
142 this._gpuBarsElement = this._timelineGrid.gridHeaderElement.createChild( "div", "timeline-gpu-bars");
143 }
138 this._mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelineR uler.get(); 144 this._mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelineR uler.get();
139 WebInspector.settings.showCpuOnTimelineRuler.addChangeListener(this._showCpu OnTimelineRulerChanged, this); 145 WebInspector.settings.showCpuOnTimelineRuler.addChangeListener(this._showCpu OnTimelineRulerChanged, this);
140 146
141 this._createFileSelector(); 147 this._createFileSelector();
142 148
143 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this); 149 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this);
144 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleare d, this._onRecordsCleared, this); 150 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleare d, this._onRecordsCleared, this);
145 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStar ted, this._onRecordingStarted, this); 151 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStar ted, this._onRecordingStarted, this);
146 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStop ped, this._onRecordingStopped, this); 152 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStop ped, this._onRecordingStopped, this);
147 153
148 this._registerShortcuts(); 154 this._registerShortcuts();
149 155
150 this._allRecordsCount = 0; 156 this._allRecordsCount = 0;
151 157
152 this._presentationModel.addFilter(new WebInspector.TimelineWindowFilter(this ._overviewPane)); 158 this._presentationModel.addFilter(new WebInspector.TimelineWindowFilter(this ._overviewPane));
153 this._presentationModel.addFilter(new WebInspector.TimelineCategoryFilter()) ; 159 this._presentationModel.addFilter(new WebInspector.TimelineCategoryFilter()) ;
154 this._presentationModel.addFilter(this._durationFilter); 160 this._presentationModel.addFilter(this._durationFilter);
155 } 161 }
156 162
157 // Define row and header height, should be in sync with styles for timeline grap hs. 163 // Define row and header height, should be in sync with styles for timeline grap hs.
158 WebInspector.TimelinePanel.rowHeight = 18; 164 WebInspector.TimelinePanel.rowHeight = 18;
159 WebInspector.TimelinePanel.headerHeight = 19; 165 WebInspector.TimelinePanel.headerHeight = 19;
160 166
161 WebInspector.TimelinePanel.durationFilterPresetsMs = [0, 1, 15]; 167 WebInspector.TimelinePanel.durationFilterPresetsMs = [0, 1, 15];
162 168
163 WebInspector.TimelinePanel.prototype = { 169 WebInspector.TimelinePanel.prototype = {
164 _showCpuOnTimelineRulerChanged: function() 170 _showCpuOnTimelineRulerChanged: function()
165 { 171 {
166 var mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelin eRuler.get(); 172 var mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelin eRuler.get();
167 if (this._mainThreadMonitoringEnabled !== mainThreadMonitoringEnabled) { 173 if (this._mainThreadMonitoringEnabled !== mainThreadMonitoringEnabled) {
168 this._mainThreadMonitoringEnabled = mainThreadMonitoringEnabled; 174 this._mainThreadMonitoringEnabled = mainThreadMonitoringEnabled;
169 this._refreshMainThreadBars(); 175 this._refreshAllUtilizationBars();
170 } 176 }
171 }, 177 },
172 178
173 /** 179 /**
174 * @param {Event} event 180 * @param {Event} event
175 * @return {boolean} 181 * @return {boolean}
176 */ 182 */
177 _startSplitterDragging: function(event) 183 _startSplitterDragging: function(event)
178 { 184 {
179 this._dragOffset = this.element.offsetHeight - this._timelineMemorySplit ter.offsetTop - 2 + event.pageY; 185 this._dragOffset = this.element.offsetHeight - this._timelineMemorySplit ter.offsetTop - 2 + event.pageY;
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 */ 651 */
646 _innerAddRecordToTimeline: function(record) 652 _innerAddRecordToTimeline: function(record)
647 { 653 {
648 if (record.type === WebInspector.TimelineModel.RecordType.Program) { 654 if (record.type === WebInspector.TimelineModel.RecordType.Program) {
649 this._mainThreadTasks.push({ 655 this._mainThreadTasks.push({
650 startTime: WebInspector.TimelineModel.startTimeInSeconds(record) , 656 startTime: WebInspector.TimelineModel.startTimeInSeconds(record) ,
651 endTime: WebInspector.TimelineModel.endTimeInSeconds(record) 657 endTime: WebInspector.TimelineModel.endTimeInSeconds(record)
652 }); 658 });
653 } 659 }
654 660
661 if (record.type === WebInspector.TimelineModel.RecordType.GpuTask) {
662 this._gpuTasks.push({
663 startTime: WebInspector.TimelineModel.startTimeInSeconds(record) ,
664 endTime: WebInspector.TimelineModel.endTimeInSeconds(record),
665 pid: record.data["rendererPid"],
666 name: record.data["name"]
667 });
668 return true;
669 }
670
655 var records = this._presentationModel.addRecord(record); 671 var records = this._presentationModel.addRecord(record);
656 this._allRecordsCount += records.length; 672 this._allRecordsCount += records.length;
657 var hasVisibleRecords = false; 673 var hasVisibleRecords = false;
658 var presentationModel = this._presentationModel; 674 var presentationModel = this._presentationModel;
659 function checkVisible(record) 675 function checkVisible(record)
660 { 676 {
661 hasVisibleRecords |= presentationModel.isVisible(record); 677 hasVisibleRecords |= presentationModel.isVisible(record);
662 } 678 }
663 WebInspector.TimelinePresentationModel.forAllRecords(records, checkVisib le); 679 WebInspector.TimelinePresentationModel.forAllRecords(records, checkVisib le);
664 680
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 737
722 _resetPanel: function() 738 _resetPanel: function()
723 { 739 {
724 this._presentationModel.reset(); 740 this._presentationModel.reset();
725 this._boundariesAreValid = false; 741 this._boundariesAreValid = false;
726 this._adjustScrollPosition(0); 742 this._adjustScrollPosition(0);
727 this._closeRecordDetails(); 743 this._closeRecordDetails();
728 this._allRecordsCount = 0; 744 this._allRecordsCount = 0;
729 this._automaticallySizeWindow = true; 745 this._automaticallySizeWindow = true;
730 this._mainThreadTasks = []; 746 this._mainThreadTasks = [];
747 this._gpuTasks = [];
748 this._pidToHue = {};
731 }, 749 },
732 750
733 elementsToRestoreScrollPositionsFor: function() 751 elementsToRestoreScrollPositionsFor: function()
734 { 752 {
735 return [this._containerElement]; 753 return [this._containerElement];
736 }, 754 },
737 755
738 wasShown: function() 756 wasShown: function()
739 { 757 {
740 WebInspector.Panel.prototype.wasShown.call(this); 758 WebInspector.Panel.prototype.wasShown.call(this);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 if (frames) { 829 if (frames) {
812 this._updateFrameStatistics(frames); 830 this._updateFrameStatistics(frames);
813 const maxFramesForFrameBars = 30; 831 const maxFramesForFrameBars = 30;
814 if (frames.length && frames.length < maxFramesForFrameBars) { 832 if (frames.length && frames.length < maxFramesForFrameBars) {
815 this._timelineGrid.removeDividers(); 833 this._timelineGrid.removeDividers();
816 this._updateFrameBars(frames); 834 this._updateFrameBars(frames);
817 } else 835 } else
818 this._timelineGrid.updateDividers(this._calculator); 836 this._timelineGrid.updateDividers(this._calculator);
819 } else 837 } else
820 this._timelineGrid.updateDividers(this._calculator); 838 this._timelineGrid.updateDividers(this._calculator);
821 if (this._mainThreadMonitoringEnabled) 839 this._refreshAllUtilizationBars();
822 this._refreshMainThreadBars();
823 } 840 }
824 if (this._memoryStatistics.visible()) 841 if (this._memoryStatistics.visible())
825 this._memoryStatistics.refresh(); 842 this._memoryStatistics.refresh();
826 this._boundariesAreValid = true; 843 this._boundariesAreValid = true;
827 }, 844 },
828 845
829 revealRecordAt: function(time) 846 revealRecordAt: function(time)
830 { 847 {
831 var recordToReveal; 848 var recordToReveal;
832 function findRecordToReveal(record) 849 function findRecordToReveal(record)
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 this._updateSearchHighlight(false, true); 989 this._updateSearchHighlight(false, true);
973 990
974 if (highlightedListRowElement) { 991 if (highlightedListRowElement) {
975 highlightedListRowElement.addStyleClass("highlighted-timeline-record "); 992 highlightedListRowElement.addStyleClass("highlighted-timeline-record ");
976 highlightedGraphRowElement.addStyleClass("highlighted-timeline-recor d"); 993 highlightedGraphRowElement.addStyleClass("highlighted-timeline-recor d");
977 } 994 }
978 995
979 return recordsInWindow.length; 996 return recordsInWindow.length;
980 }, 997 },
981 998
982 _refreshMainThreadBars: function() 999 _refreshAllUtilizationBars: function()
983 { 1000 {
1001 this._refreshUtilizationBars(WebInspector.UIString("CPU"), this._mainThr eadMonitoringEnabled ? this._mainThreadTasks : [], this._cpuBarsElement);
1002 if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
1003 this._refreshUtilizationBars(WebInspector.UIString("GPU"), this._gpu Tasks, this._gpuBarsElement);
1004 },
1005
1006 /**
1007 * @param {string} name
1008 * @param {!Array.<{startTime: number, endTime: number, pid: number}>} tasks
1009 * @param {Element} container
1010 */
1011 _refreshUtilizationBars: function(name, tasks, container)
1012 {
1013 if (!container)
yurys 2013/10/31 15:06:52 This is always false.
alph 2013/10/31 16:58:00 Removed.
alph 2013/11/01 18:53:21 This might be true if the user is enabled the expe
1014 return;
1015
984 const barOffset = 3; 1016 const barOffset = 3;
985 const minGap = 3; 1017 const minGap = 3;
986 1018
987 var minWidth = WebInspector.TimelineCalculator._minWidth; 1019 var minWidth = WebInspector.TimelineCalculator._minWidth;
988 var widthAdjustment = minWidth / 2; 1020 var widthAdjustment = minWidth / 2;
989 1021
990 var width = this._graphRowsElementWidth; 1022 var width = this._graphRowsElementWidth;
991 var boundarySpan = this._overviewPane.windowEndTime() - this._overviewPa ne.windowStartTime(); 1023 var boundarySpan = this._overviewPane.windowEndTime() - this._overviewPa ne.windowStartTime();
992 var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft ); 1024 var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft );
993 var startTime = this._overviewPane.windowStartTime() - this._timelinePad dingLeft * scale; 1025 var startTime = this._overviewPane.windowStartTime() - this._timelinePad dingLeft * scale;
994 var endTime = startTime + width * scale; 1026 var endTime = startTime + width * scale;
995 1027
996 var tasks = this._mainThreadMonitoringEnabled ? this._mainThreadTasks : [];
997
998 /** 1028 /**
999 * @param {number} value 1029 * @param {number} value
1000 * @param {{startTime: number, endTime: number}} task 1030 * @param {{startTime: number, endTime: number}} task
1001 * @return {number} 1031 * @return {number}
1002 */ 1032 */
1003 function compareEndTime(value, task) 1033 function compareEndTime(value, task)
1004 { 1034 {
1005 return value < task.endTime ? -1 : 1; 1035 return value < task.endTime ? -1 : 1;
1006 } 1036 }
1007 1037
1008 var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime); 1038 var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime);
1009 1039
1010 var container = this._cpuBarsElement;
1011 var element = container.firstChild; 1040 var element = container.firstChild;
1012 var lastElement; 1041 var lastElement;
1013 var lastLeft; 1042 var lastLeft;
1014 var lastRight; 1043 var lastRight;
1015 1044
1045 if (typeof this._pidToHue === "undefined")
1046 this._pidToHue = {};
1047 var pidToHue = this._pidToHue;
1048
1016 for (; taskIndex < tasks.length; ++taskIndex) { 1049 for (; taskIndex < tasks.length; ++taskIndex) {
1017 var task = tasks[taskIndex]; 1050 var task = tasks[taskIndex];
1018 if (task.startTime > endTime) 1051 if (task.startTime > endTime)
1019 break; 1052 break;
1020 1053
1021 var left = Math.max(0, this._calculator.computePosition(task.startTi me) + barOffset - widthAdjustment); 1054 var left = Math.max(0, this._calculator.computePosition(task.startTi me) + barOffset - widthAdjustment);
1022 var right = Math.min(width, this._calculator.computePosition(task.en dTime) + barOffset + widthAdjustment); 1055 var right = Math.min(width, this._calculator.computePosition(task.en dTime) + barOffset + widthAdjustment);
1023 1056
1024 if (lastElement) { 1057 if (lastElement) {
1025 var gap = Math.floor(left) - Math.ceil(lastRight); 1058 var gap = Math.floor(left) - Math.ceil(lastRight);
1026 if (gap < minGap) { 1059 if (gap < minGap
1060 && (!task.pid || tasks[lastElement._tasksInfo.firstTaskIndex ].pid === task.pid)) {
1027 lastRight = right; 1061 lastRight = right;
1028 lastElement._tasksInfo.lastTaskIndex = taskIndex; 1062 lastElement._tasksInfo.lastTaskIndex = taskIndex;
1029 continue; 1063 continue;
1030 } 1064 }
1031 lastElement.style.width = (lastRight - lastLeft) + "px"; 1065 lastElement.style.width = (lastRight - lastLeft) + "px";
1032 } 1066 }
1033 1067
1034 if (!element) 1068 if (!element)
1035 element = container.createChild("div", "timeline-graph-bar"); 1069 element = container.createChild("div", "timeline-graph-bar");
1036 1070
1071 if (task.pid) {
1072 if (!(task.pid in pidToHue))
1073 pidToHue[task.pid] = (Object.keys(pidToHue).length * 113) % 360;
1074 var hue = pidToHue[task.pid];
1075 element.style.backgroundColor = "hsla(" + hue + ",50%,50%,0.2)";
1076 }
1037 element.style.left = left + "px"; 1077 element.style.left = left + "px";
1038 element._tasksInfo = {tasks: tasks, firstTaskIndex: taskIndex, lastT askIndex: taskIndex}; 1078 element._tasksInfo = {name: name, tasks: tasks, firstTaskIndex: task Index, lastTaskIndex: taskIndex};
1039 lastLeft = left; 1079 lastLeft = left;
1040 lastRight = right; 1080 lastRight = right;
1041 1081
1042 lastElement = element; 1082 lastElement = element;
1043 element = element.nextSibling; 1083 element = element.nextSibling;
1044 } 1084 }
1045 1085
1046 if (lastElement) 1086 if (lastElement)
1047 lastElement.style.width = (lastRight - lastLeft) + "px"; 1087 lastElement.style.width = (lastRight - lastLeft) + "px";
1048 1088
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 1657
1618 /** 1658 /**
1619 * @param {!WebInspector.TimelinePresentationModel.Record} record 1659 * @param {!WebInspector.TimelinePresentationModel.Record} record
1620 * @return {boolean} 1660 * @return {boolean}
1621 */ 1661 */
1622 accept: function(record) 1662 accept: function(record)
1623 { 1663 {
1624 return WebInspector.TimelineRecordListRow.testContentMatching(record, th is._regExp); 1664 return WebInspector.TimelineRecordListRow.testContentMatching(record, th is._regExp);
1625 } 1665 }
1626 } 1666 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698