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