Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / tracks / counter_track.js
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 tvcm.requireStylesheet('tracing.tracks.counter_track');
8
9 tvcm.require('tracing.trace_model.event');
10 tvcm.require('tracing.tracks.heading_track');
11 tvcm.require('tracing.color_scheme');
12 tvcm.require('tvcm.ui');
13
14 tvcm.exportTo('tracing.tracks', function() {
15
16   var SelectionState = tracing.trace_model.SelectionState;
17   var EventPresenter = tracing.EventPresenter;
18   var LAST_SAMPLE_PIXELS = 8;
19
20   /**
21    * A track that displays a Counter object.
22    * @constructor
23    * @extends {HeadingTrack}
24    */
25
26   var CounterTrack =
27       tvcm.ui.define('counter-track', tracing.tracks.HeadingTrack);
28
29   CounterTrack.prototype = {
30     __proto__: tracing.tracks.HeadingTrack.prototype,
31
32     decorate: function(viewport) {
33       tracing.tracks.HeadingTrack.prototype.decorate.call(this, viewport);
34       this.classList.add('counter-track');
35     },
36
37     get counter() {
38       return this.counter_;
39     },
40
41     set counter(counter) {
42       this.counter_ = counter;
43       this.heading = counter.name + ': ';
44     },
45
46     draw: function(type, viewLWorld, viewRWorld) {
47       switch (type) {
48         case tracing.tracks.DrawType.SLICE:
49           this.drawSlices_(viewLWorld, viewRWorld);
50           break;
51       }
52     },
53
54     drawSlices_: function(viewLWorld, viewRWorld) {
55       var ctx = this.context();
56       var pixelRatio = window.devicePixelRatio || 1;
57
58       var bounds = this.getBoundingClientRect();
59       var height = bounds.height * pixelRatio;
60
61       var counter = this.counter_;
62
63       // Culling parametrs.
64       var vp = this.viewport;
65       var dt = vp.currentDisplayTransform;
66       var pixWidth = dt.xViewVectorToWorld(1);
67
68       // Drop sampels that are less than skipDistancePix apart.
69       var skipDistancePix = 1;
70       var skipDistanceWorld = dt.xViewVectorToWorld(skipDistancePix);
71
72       // Begin rendering in world space.
73       ctx.save();
74       dt.applyTransformToCanvas(ctx);
75
76       // Figure out where drawing should begin.
77       var numSeries = counter.numSeries;
78       var numSamples = counter.numSamples;
79       var startIndex = tvcm.findLowIndexInSortedArray(
80           counter.timestamps,
81           function(x) { return x; },
82           viewLWorld);
83       var timestamps = counter.timestamps;
84
85       startIndex = startIndex - 1 > 0 ? startIndex - 1 : 0;
86       // Draw indices one by one until we fall off the viewRWorld.
87       var yScale = height / counter.maxTotal;
88       for (var seriesIndex = counter.numSeries - 1;
89            seriesIndex >= 0; seriesIndex--) {
90         var series = counter.series[seriesIndex];
91
92         // For performance reasons we only check the SelectionState of the first
93         // sample. If it's DIMMED we assume that the whole series is DIMMED.
94         // TODO(egraether): Allow partial highlight.
95         var selectionState = SelectionState.NONE;
96         if (series.samples.length &&
97             series.samples[0].selectionState === SelectionState.DIMMED) {
98           selectionState = SelectionState.DIMMED;
99         }
100
101         ctx.fillStyle = EventPresenter.getCounterSeriesColor(
102             series.color, selectionState);
103         ctx.beginPath();
104
105         // Set iLast and xLast such that the first sample we draw is the
106         // startIndex sample.
107         var iLast = startIndex - 1;
108         var xLast = iLast >= 0 ?
109             timestamps[iLast] - skipDistanceWorld : -1;
110         var yLastView = height;
111
112         // Iterate over samples from iLast onward until we either fall off the
113         // viewRWorld or we run out of samples. To avoid drawing too much, after
114         // drawing a sample at xLast, skip subsequent samples that are less than
115         // skipDistanceWorld from xLast.
116         var hasMoved = false;
117
118         while (true) {
119           var i = iLast + 1;
120           if (i >= numSamples) {
121             ctx.lineTo(xLast, yLastView);
122             ctx.lineTo(xLast + LAST_SAMPLE_PIXELS * pixWidth, yLastView);
123             ctx.lineTo(xLast + LAST_SAMPLE_PIXELS * pixWidth, height);
124             break;
125           }
126
127           var x = timestamps[i];
128           var y = counter.totals[i * numSeries + seriesIndex];
129           var yView = height - (yScale * y);
130
131           if (x > viewRWorld) {
132             ctx.lineTo(x, yLastView);
133             ctx.lineTo(x, height);
134             break;
135           }
136
137           if (i + 1 < numSamples) {
138             var xNext = timestamps[i + 1];
139             if (xNext - xLast <= skipDistanceWorld && xNext < viewRWorld) {
140               iLast = i;
141               continue;
142             }
143           }
144
145           if (!hasMoved) {
146             ctx.moveTo(viewLWorld, height);
147             hasMoved = true;
148           }
149
150           if (x - xLast < skipDistanceWorld) {
151             // We know that xNext > xLast + skipDistanceWorld, so we can
152             // safely move this sample's x over that much without passing
153             // xNext.  This ensure that the previous sample is visible when
154             // zoomed out very far.
155             x = xLast + skipDistanceWorld;
156           }
157           ctx.lineTo(x, yLastView);
158           ctx.lineTo(x, yView);
159
160           iLast = i;
161           xLast = x;
162           yLastView = yView;
163         }
164         ctx.closePath();
165         ctx.fill();
166
167       }
168
169       ctx.fillStyle = 'rgba(255, 0, 0, 1)';
170       for (var seriesIndex = counter.numSeries - 1;
171            seriesIndex >= 0; seriesIndex--) {
172         var series = counter.series[seriesIndex];
173         var seriesSamples = series.samples;
174         for (var i = startIndex; timestamps[i] < viewRWorld; i++) {
175           if (!seriesSamples[i].selected)
176             continue;
177           var x = timestamps[i];
178           for (var seriesIndex = counter.numSeries - 1;
179                seriesIndex >= 0; seriesIndex--) {
180             var y = counter.totals[i * numSeries + seriesIndex];
181             var yView = height - (yScale * y);
182             ctx.fillRect(x - pixWidth, yView - 1, 3 * pixWidth, 3);
183           }
184         }
185       }
186       ctx.restore();
187     },
188
189     addEventsToTrackMap: function(eventToTrackMap) {
190       var allSeries = this.counter_.series;
191       for (var seriesIndex = 0; seriesIndex < allSeries.length; seriesIndex++) {
192         var samples = allSeries[seriesIndex].samples;
193         for (var i = 0; i < samples.length; i++)
194           eventToTrackMap.addEvent(samples[i], this);
195       }
196     },
197
198     addIntersectingItemsInRangeToSelectionInWorldSpace: function(
199         loWX, hiWX, viewPixWidthWorld, selection) {
200
201       function getSampleWidth(x, i) {
202         if (i === counter.timestamps.length - 1) {
203           var dt = this.viewport.currentDisplayTransform;
204           var pixWidth = dt.xViewVectorToWorld(1);
205           return LAST_SAMPLE_PIXELS * pixWidth;
206         }
207         return counter.timestamps[i + 1] - counter.timestamps[i];
208       }
209
210       var counter = this.counter_;
211       var iLo = tvcm.findLowIndexInSortedIntervals(counter.timestamps,
212                                                    function(x) { return x; },
213                                                    getSampleWidth.bind(this),
214                                                    loWX);
215       var iHi = tvcm.findLowIndexInSortedIntervals(counter.timestamps,
216                                                    function(x) { return x; },
217                                                    getSampleWidth.bind(this),
218                                                    hiWX);
219
220       // Iterate over every sample intersecting..
221       for (var sampleIndex = iLo; sampleIndex <= iHi; sampleIndex++) {
222         if (sampleIndex < 0)
223           continue;
224         if (sampleIndex >= counter.timestamps.length)
225           continue;
226
227         // TODO(nduca): Pick the seriesIndexHit based on the loY - hiY values.
228         for (var seriesIndex = 0;
229              seriesIndex < this.counter.numSeries;
230              seriesIndex++) {
231           var series = this.counter.series[seriesIndex];
232           selection.push(series.samples[sampleIndex]);
233         }
234       }
235     },
236
237     addItemNearToProvidedEventToSelection: function(sample, offset, selection) {
238       var index = sample.getSampleIndex();
239       var newIndex = index + offset;
240       if (newIndex < 0 || newIndex >= sample.series.samples.length)
241         return false;
242
243       selection.push(sample.series.samples[newIndex]);
244       return true;
245     },
246
247     addAllObjectsMatchingFilterToSelection: function(filter, selection) {
248     },
249
250     addClosestEventToSelection: function(worldX, worldMaxDist, loY, hiY,
251                                          selection) {
252       var counter = this.counter;
253       if (!counter.numSeries)
254         return;
255
256       var stackHeight = 0;
257
258       for (var i = 0; i < counter.numSeries; i++) {
259         var counterSample = tvcm.findClosestElementInSortedArray(
260             counter.series_[i].samples_,
261             function(x) { return x.timestamp; },
262             worldX,
263             worldMaxDist);
264
265         if (!counterSample)
266           continue;
267
268         selection.push(counterSample);
269       }
270     }
271   };
272
273   return {
274     CounterTrack: CounterTrack
275   };
276 });