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

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: Tune PID to hue magic const 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._cpuBarsElement = this._timelineGrid.gridHeaderElement.createChild("div ", "timeline-cpu-bars"); 137 this._gpuTasks = /** @type {!Array.<{startTime: number, endTime: number, pid : number}>} */ ([]);
138 var utilizationStripsElement = this._timelineGrid.gridHeaderElement.createCh ild("div", "timeline-utilization-strips vbox");
139 this._cpuBarsElement = utilizationStripsElement.createChild("div", "timeline -utilization-strip");
140 if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
141 this._gpuBarsElement = utilizationStripsElement.createChild("div", "time line-utilization-strip gpu");
138 this._mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelineR uler.get(); 142 this._mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelineR uler.get();
139 WebInspector.settings.showCpuOnTimelineRuler.addChangeListener(this._showCpu OnTimelineRulerChanged, this); 143 WebInspector.settings.showCpuOnTimelineRuler.addChangeListener(this._showCpu OnTimelineRulerChanged, this);
140 144
141 this._createFileSelector(); 145 this._createFileSelector();
142 146
143 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this); 147 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onTimelineEventRecorded, this);
144 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleare d, this._onRecordsCleared, this); 148 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleare d, this._onRecordsCleared, this);
145 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStar ted, this._onRecordingStarted, this); 149 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStar ted, this._onRecordingStarted, this);
146 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStop ped, this._onRecordingStopped, this); 150 this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStop ped, this._onRecordingStopped, this);
147 151
148 this._registerShortcuts(); 152 this._registerShortcuts();
149 153
150 this._allRecordsCount = 0; 154 this._allRecordsCount = 0;
151 155
152 this._presentationModel.addFilter(new WebInspector.TimelineWindowFilter(this ._overviewPane)); 156 this._presentationModel.addFilter(new WebInspector.TimelineWindowFilter(this ._overviewPane));
153 this._presentationModel.addFilter(new WebInspector.TimelineCategoryFilter()) ; 157 this._presentationModel.addFilter(new WebInspector.TimelineCategoryFilter()) ;
154 this._presentationModel.addFilter(this._durationFilter); 158 this._presentationModel.addFilter(this._durationFilter);
155 } 159 }
156 160
157 // Define row and header height, should be in sync with styles for timeline grap hs. 161 // Define row and header height, should be in sync with styles for timeline grap hs.
158 WebInspector.TimelinePanel.rowHeight = 18; 162 WebInspector.TimelinePanel.rowHeight = 18;
159 WebInspector.TimelinePanel.headerHeight = 19; 163 WebInspector.TimelinePanel.headerHeight = 19;
160 164
161 WebInspector.TimelinePanel.durationFilterPresetsMs = [0, 1, 15]; 165 WebInspector.TimelinePanel.durationFilterPresetsMs = [0, 1, 15];
162 166
163 WebInspector.TimelinePanel.prototype = { 167 WebInspector.TimelinePanel.prototype = {
164 _showCpuOnTimelineRulerChanged: function() 168 _showCpuOnTimelineRulerChanged: function()
165 { 169 {
166 var mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelin eRuler.get(); 170 var mainThreadMonitoringEnabled = WebInspector.settings.showCpuOnTimelin eRuler.get();
167 if (this._mainThreadMonitoringEnabled !== mainThreadMonitoringEnabled) { 171 if (this._mainThreadMonitoringEnabled !== mainThreadMonitoringEnabled) {
168 this._mainThreadMonitoringEnabled = mainThreadMonitoringEnabled; 172 this._mainThreadMonitoringEnabled = mainThreadMonitoringEnabled;
169 this._refreshMainThreadBars(); 173 this._refreshAllUtilizationBars();
170 } 174 }
171 }, 175 },
172 176
173 /** 177 /**
174 * @param {Event} event 178 * @param {Event} event
175 * @return {boolean} 179 * @return {boolean}
176 */ 180 */
177 _startSplitterDragging: function(event) 181 _startSplitterDragging: function(event)
178 { 182 {
179 this._dragOffset = this.element.offsetHeight - this._timelineMemorySplit ter.offsetTop - 2 + event.pageY; 183 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 */ 649 */
646 _innerAddRecordToTimeline: function(record) 650 _innerAddRecordToTimeline: function(record)
647 { 651 {
648 if (record.type === WebInspector.TimelineModel.RecordType.Program) { 652 if (record.type === WebInspector.TimelineModel.RecordType.Program) {
649 this._mainThreadTasks.push({ 653 this._mainThreadTasks.push({
650 startTime: WebInspector.TimelineModel.startTimeInSeconds(record) , 654 startTime: WebInspector.TimelineModel.startTimeInSeconds(record) ,
651 endTime: WebInspector.TimelineModel.endTimeInSeconds(record) 655 endTime: WebInspector.TimelineModel.endTimeInSeconds(record)
652 }); 656 });
653 } 657 }
654 658
659 if (record.type === WebInspector.TimelineModel.RecordType.GPUTask) {
660 this._gpuTasks.push({
661 startTime: WebInspector.TimelineModel.startTimeInSeconds(record) ,
662 endTime: WebInspector.TimelineModel.endTimeInSeconds(record),
663 pid: record.data["ownerPID"]
664 });
665 return WebInspector.TimelineModel.startTimeInSeconds(record) < this. _overviewPane.windowEndTime();
666 }
667
655 var records = this._presentationModel.addRecord(record); 668 var records = this._presentationModel.addRecord(record);
656 this._allRecordsCount += records.length; 669 this._allRecordsCount += records.length;
657 var hasVisibleRecords = false; 670 var hasVisibleRecords = false;
658 var presentationModel = this._presentationModel; 671 var presentationModel = this._presentationModel;
659 function checkVisible(record) 672 function checkVisible(record)
660 { 673 {
661 hasVisibleRecords |= presentationModel.isVisible(record); 674 hasVisibleRecords |= presentationModel.isVisible(record);
662 } 675 }
663 WebInspector.TimelinePresentationModel.forAllRecords(records, checkVisib le); 676 WebInspector.TimelinePresentationModel.forAllRecords(records, checkVisib le);
664 677
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 734
722 _resetPanel: function() 735 _resetPanel: function()
723 { 736 {
724 this._presentationModel.reset(); 737 this._presentationModel.reset();
725 this._boundariesAreValid = false; 738 this._boundariesAreValid = false;
726 this._adjustScrollPosition(0); 739 this._adjustScrollPosition(0);
727 this._closeRecordDetails(); 740 this._closeRecordDetails();
728 this._allRecordsCount = 0; 741 this._allRecordsCount = 0;
729 this._automaticallySizeWindow = true; 742 this._automaticallySizeWindow = true;
730 this._mainThreadTasks = []; 743 this._mainThreadTasks = [];
744 this._gpuTasks = [];
745 this._pidToHue = {};
731 }, 746 },
732 747
733 elementsToRestoreScrollPositionsFor: function() 748 elementsToRestoreScrollPositionsFor: function()
734 { 749 {
735 return [this._containerElement]; 750 return [this._containerElement];
736 }, 751 },
737 752
738 wasShown: function() 753 wasShown: function()
739 { 754 {
740 WebInspector.Panel.prototype.wasShown.call(this); 755 WebInspector.Panel.prototype.wasShown.call(this);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 if (frames) { 826 if (frames) {
812 this._updateFrameStatistics(frames); 827 this._updateFrameStatistics(frames);
813 const maxFramesForFrameBars = 30; 828 const maxFramesForFrameBars = 30;
814 if (frames.length && frames.length < maxFramesForFrameBars) { 829 if (frames.length && frames.length < maxFramesForFrameBars) {
815 this._timelineGrid.removeDividers(); 830 this._timelineGrid.removeDividers();
816 this._updateFrameBars(frames); 831 this._updateFrameBars(frames);
817 } else 832 } else
818 this._timelineGrid.updateDividers(this._calculator); 833 this._timelineGrid.updateDividers(this._calculator);
819 } else 834 } else
820 this._timelineGrid.updateDividers(this._calculator); 835 this._timelineGrid.updateDividers(this._calculator);
821 if (this._mainThreadMonitoringEnabled) 836 this._refreshAllUtilizationBars();
822 this._refreshMainThreadBars();
823 } 837 }
824 if (this._memoryStatistics.visible()) 838 if (this._memoryStatistics.visible())
825 this._memoryStatistics.refresh(); 839 this._memoryStatistics.refresh();
826 this._boundariesAreValid = true; 840 this._boundariesAreValid = true;
827 }, 841 },
828 842
829 revealRecordAt: function(time) 843 revealRecordAt: function(time)
830 { 844 {
831 var recordToReveal; 845 var recordToReveal;
832 function findRecordToReveal(record) 846 function findRecordToReveal(record)
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 this._updateSearchHighlight(false, true); 986 this._updateSearchHighlight(false, true);
973 987
974 if (highlightedListRowElement) { 988 if (highlightedListRowElement) {
975 highlightedListRowElement.addStyleClass("highlighted-timeline-record "); 989 highlightedListRowElement.addStyleClass("highlighted-timeline-record ");
976 highlightedGraphRowElement.addStyleClass("highlighted-timeline-recor d"); 990 highlightedGraphRowElement.addStyleClass("highlighted-timeline-recor d");
977 } 991 }
978 992
979 return recordsInWindow.length; 993 return recordsInWindow.length;
980 }, 994 },
981 995
982 _refreshMainThreadBars: function() 996 _refreshAllUtilizationBars: function()
983 { 997 {
998 this._refreshUtilizationBars(WebInspector.UIString("CPU"), this._mainThr eadMonitoringEnabled ? this._mainThreadTasks : [], this._cpuBarsElement);
999 if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
1000 this._refreshUtilizationBars(WebInspector.UIString("GPU"), this._gpu Tasks, this._gpuBarsElement);
1001 },
1002
1003 /**
1004 * @param {string} name
1005 * @param {!Array.<{startTime: number, endTime: number, pid: number}>} tasks
1006 * @param {?Element} container
1007 */
1008 _refreshUtilizationBars: function(name, tasks, container)
1009 {
1010 if (!container)
1011 return;
1012
984 const barOffset = 3; 1013 const barOffset = 3;
985 const minGap = 3; 1014 const minGap = 3;
986 1015
987 var minWidth = WebInspector.TimelineCalculator._minWidth; 1016 var minWidth = WebInspector.TimelineCalculator._minWidth;
988 var widthAdjustment = minWidth / 2; 1017 var widthAdjustment = minWidth / 2;
989 1018
990 var width = this._graphRowsElementWidth; 1019 var width = this._graphRowsElementWidth;
991 var boundarySpan = this._overviewPane.windowEndTime() - this._overviewPa ne.windowStartTime(); 1020 var boundarySpan = this._overviewPane.windowEndTime() - this._overviewPa ne.windowStartTime();
992 var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft ); 1021 var scale = boundarySpan / (width - minWidth - this._timelinePaddingLeft );
993 var startTime = this._overviewPane.windowStartTime() - this._timelinePad dingLeft * scale; 1022 var startTime = this._overviewPane.windowStartTime() - this._timelinePad dingLeft * scale;
994 var endTime = startTime + width * scale; 1023 var endTime = startTime + width * scale;
995 1024
996 var tasks = this._mainThreadMonitoringEnabled ? this._mainThreadTasks : [];
997
998 /** 1025 /**
999 * @param {number} value 1026 * @param {number} value
1000 * @param {{startTime: number, endTime: number}} task 1027 * @param {{startTime: number, endTime: number}} task
1001 * @return {number} 1028 * @return {number}
1002 */ 1029 */
1003 function compareEndTime(value, task) 1030 function compareEndTime(value, task)
1004 { 1031 {
1005 return value < task.endTime ? -1 : 1; 1032 return value < task.endTime ? -1 : 1;
1006 } 1033 }
1007 1034
1008 var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime); 1035 var taskIndex = insertionIndexForObjectInListSortedByFunction(startTime, tasks, compareEndTime);
1009 1036
1010 var container = this._cpuBarsElement;
1011 var element = container.firstChild; 1037 var element = container.firstChild;
1012 var lastElement; 1038 var lastElement;
1013 var lastLeft; 1039 var lastLeft;
1014 var lastRight; 1040 var lastRight;
1015 1041
1042 if (!this._pidToHue)
1043 this._pidToHue = {};
1044 var pidToHue = this._pidToHue;
1045
1016 for (; taskIndex < tasks.length; ++taskIndex) { 1046 for (; taskIndex < tasks.length; ++taskIndex) {
1017 var task = tasks[taskIndex]; 1047 var task = tasks[taskIndex];
1018 if (task.startTime > endTime) 1048 if (task.startTime > endTime)
1019 break; 1049 break;
1020 1050
1021 var left = Math.max(0, this._calculator.computePosition(task.startTi me) + barOffset - widthAdjustment); 1051 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); 1052 var right = Math.min(width, this._calculator.computePosition(task.en dTime) + barOffset + widthAdjustment);
1023 1053
1024 if (lastElement) { 1054 if (lastElement) {
1025 var gap = Math.floor(left) - Math.ceil(lastRight); 1055 var gap = Math.floor(left) - Math.ceil(lastRight);
1026 if (gap < minGap) { 1056 if (gap < minGap
1057 && (!task.pid || tasks[lastElement._tasksInfo.firstTaskIndex ].pid === task.pid)) {
1027 lastRight = right; 1058 lastRight = right;
1028 lastElement._tasksInfo.lastTaskIndex = taskIndex; 1059 lastElement._tasksInfo.lastTaskIndex = taskIndex;
1029 continue; 1060 continue;
1030 } 1061 }
1031 lastElement.style.width = (lastRight - lastLeft) + "px"; 1062 lastElement.style.width = (lastRight - lastLeft) + "px";
1032 } 1063 }
1033 1064
1034 if (!element) 1065 if (!element)
1035 element = container.createChild("div", "timeline-graph-bar"); 1066 element = container.createChild("div", "timeline-graph-bar");
1036 1067
1068 if (task.pid) {
1069 if (!(task.pid in pidToHue))
1070 pidToHue[task.pid] = (Object.keys(pidToHue).length * 101) % 360;
1071 var hue = pidToHue[task.pid];
1072 element.style.backgroundColor = "hsla(" + hue + ",50%,50%,0.2)";
1073 }
1037 element.style.left = left + "px"; 1074 element.style.left = left + "px";
1038 element._tasksInfo = {tasks: tasks, firstTaskIndex: taskIndex, lastT askIndex: taskIndex}; 1075 element._tasksInfo = {name: name, tasks: tasks, firstTaskIndex: task Index, lastTaskIndex: taskIndex};
1039 lastLeft = left; 1076 lastLeft = left;
1040 lastRight = right; 1077 lastRight = right;
1041 1078
1042 lastElement = element; 1079 lastElement = element;
1043 element = element.nextSibling; 1080 element = element.nextSibling;
1044 } 1081 }
1045 1082
1046 if (lastElement) 1083 if (lastElement)
1047 lastElement.style.width = (lastRight - lastLeft) + "px"; 1084 lastElement.style.width = (lastRight - lastLeft) + "px";
1048 1085
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 1654
1618 /** 1655 /**
1619 * @param {!WebInspector.TimelinePresentationModel.Record} record 1656 * @param {!WebInspector.TimelinePresentationModel.Record} record
1620 * @return {boolean} 1657 * @return {boolean}
1621 */ 1658 */
1622 accept: function(record) 1659 accept: function(record)
1623 { 1660 {
1624 return WebInspector.TimelineRecordListRow.testContentMatching(record, th is._regExp); 1661 return WebInspector.TimelineRecordListRow.testContentMatching(record, th is._regExp);
1625 } 1662 }
1626 } 1663 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/TimelineModel.js ('k') | Source/devtools/front_end/TimelinePresentationModel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698