Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / TimelineFlameChart.js
1 /*
2  * Copyright (C) 2014 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /**
32  * @constructor
33  * @implements {WebInspector.FlameChartDataProvider}
34  * @param {!WebInspector.TimelineModel} model
35  * @param {!WebInspector.FlameChart.ColorGenerator} colorGenerator
36  * @param {boolean} mainThread
37  */
38 WebInspector.TimelineFlameChartDataProvider = function(model, colorGenerator, mainThread)
39 {
40     WebInspector.FlameChartDataProvider.call(this);
41     this._model = model;
42     this._mainThread = mainThread;
43     this._colorGenerator = colorGenerator;
44     this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._invalidate, this);
45 }
46
47 WebInspector.TimelineFlameChartDataProvider.prototype = {
48     reset: function()
49     {
50         this._invalidate();
51     },
52
53     _invalidate: function()
54     {
55         this._timelineData = null;
56     },
57
58     /**
59      * @return {!WebInspector.FlameChart.ColorGenerator}
60      */
61     colorGenerator: function()
62     {
63         return this._colorGenerator;
64     },
65
66     /**
67      * @return {!WebInspector.FlameChart.TimelineData}
68      */
69     timelineData: function()
70     {
71         if (!this._timelineData) {
72             this._resetData();
73             WebInspector.TimelinePresentationModel.forAllRecords(this._model.records, this._appendRecord.bind(this));
74         }
75         return this._timelineData;
76     },
77
78     _resetData: function()
79     {
80         this._startTime = 0;
81         this._endTime = 0;
82         this._timelineData = {
83             maxStackDepth: 5,
84             totalTime: 1000,
85             entryLevels: [],
86             entryTotalTimes: [],
87             entrySelfTimes: [],
88             entryOffsets: [],
89             colorEntryIndexes: [],
90             entryTitles: [],
91             entryDeoptFlags: []
92         };
93     },
94
95     _appendRecord: function(record, depth)
96     {
97         var timelineData = this._timelineData;
98
99         this._startTime = this._startTime ? Math.min(this._startTime, record.startTime) : record.startTime;
100         var startTime = this._startTime;
101         var endTime = record.endTime || record.startTime - startTime;
102         this._endTime = Math.max(this._endTime, endTime);
103         timelineData.totalTime = Math.max(1000, this._endTime - this._startTime);
104
105         if (this._mainThread) {
106             if (record.type === WebInspector.TimelineModel.RecordType.GPUTask || !!record.thread)
107                 return;
108         } else {
109             if (record.type === WebInspector.TimelineModel.RecordType.Program || !record.thread)
110                 return;
111         }
112
113         var index = timelineData.entryTitles.length;
114         timelineData.entryTitles[index] = record.type;
115         timelineData.entryOffsets[index] = record.startTime - startTime;
116         timelineData.entryLevels[index] = depth - 1;
117         timelineData.entryTotalTimes[index] = endTime - record.startTime;
118         timelineData.entryDeoptFlags[index] = 0;
119
120         var colorPair = this._colorGenerator.colorPairForID(WebInspector.TimelinePresentationModel.categoryForRecord(record).name);
121         var indexesForColor = timelineData.colorEntryIndexes[colorPair.index];
122         if (!indexesForColor)
123             indexesForColor = timelineData.colorEntryIndexes[colorPair.index] = [];
124         indexesForColor.push(index);
125
126         timelineData.maxStackDepth = Math.max(timelineData.maxStackDepth, depth + 1);
127     },
128
129     /**
130      * @param {number} entryIndex
131      * @return {?Array.<!{title: string, text: string}>}
132      */
133     prepareHighlightedEntryInfo: function(entryIndex)
134     {
135         return null;
136     },
137
138     /**
139      * @param {number} entryIndex
140      * @return {boolean}
141      */
142     canJumpToEntry: function(entryIndex)
143     {
144         return false;
145     },
146
147     /**
148      * @param {number} entryIndex
149      * @return {?Object}
150      */
151     entryData: function(entryIndex)
152     {
153         return null;
154     }
155 }
156
157 /**
158  * @constructor
159  * @extends {WebInspector.View}
160  * @param {!WebInspector.TimelinePanel} panel
161  * @param {!WebInspector.TimelineModel} model
162  * @param {!WebInspector.FlameChartDataProvider} dataProvider
163  */
164 WebInspector.TimelineFlameChart = function(panel, model, dataProvider)
165 {
166     WebInspector.View.call(this);
167     this._panel = panel;
168     this._model = model;
169     this._dataProvider = dataProvider;
170     this._mainView = new WebInspector.FlameChart.MainPane(dataProvider, null, true);
171     this._mainView.show(this.element);
172     this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStarted, this._onRecordingStarted, this);
173     this._model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._onRecordAdded, this);
174 }
175
176 /**
177  * @param {!Object.<string, !CanvasGradient>} fillStyles
178  */
179 WebInspector.TimelineFlameChart.colorGenerator = function(fillStyles)
180 {
181     if (!WebInspector.TimelineFlameChart._colorGenerator) {
182         var colorGenerator = new WebInspector.FlameChart.ColorGenerator();
183         for (var category in fillStyles) {
184             if (fillStyles.hasOwnProperty(category))
185                 colorGenerator.setColorPairForID(category, fillStyles[category], fillStyles[category]);
186         }
187         WebInspector.TimelineFlameChart._colorGenerator = colorGenerator;
188     }
189     return WebInspector.TimelineFlameChart._colorGenerator;
190 }
191
192 WebInspector.TimelineFlameChart.prototype = {
193     reset: function()
194     {
195         this._dataProvider.reset();
196         this._mainView.changeWindow(0, 1);
197     },
198
199     _onRecordingStarted: function()
200     {
201         this._gotFirstRecord = false;
202     },
203
204     _onRecordAdded: function()
205     {
206         if (!this._gotFirstRecord) {
207             this._gotFirstRecord = true;
208             var minimumRecordTime = this._model.minimumRecordTime();
209             this._panel.setWindowTimes(minimumRecordTime, minimumRecordTime + 1000);
210         }
211         this._mainView._scheduleUpdate();
212     },
213
214     /**
215      * @param {number} startTime
216      * @param {number} endTime
217      */
218     setWindowTimes: function(startTime, endTime)
219     {
220         var minimumRecordTime = this._model.minimumRecordTime();
221         var timeRange = this._model.maximumRecordTime() - minimumRecordTime;
222         if (timeRange === 0)
223             this._mainView.changeWindow(0, 1);
224         else
225             this._mainView.changeWindow((startTime - minimumRecordTime) / timeRange, (endTime - minimumRecordTime) / timeRange);
226     },
227
228     /**
229      * @return {boolean}
230      */
231     supportsGlueParentMode: function()
232     {
233         return false;
234     },
235
236     setSidebarSize: function()
237     {
238     },
239
240     /**
241      * @param {!WebInspector.FilterBar} filterBar
242      * @return {boolean}
243      */
244     createUIFilters: function(filterBar)
245     {
246         return false;
247     },
248
249     /**
250      * @return {?WebInspector.View}
251      */
252     searchableView: function()
253     {
254         return null;
255     },
256
257     __proto__: WebInspector.View.prototype
258 }