Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / tracks / object_instance_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/object_instance_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/sorted_array_utils.html">
14 <link rel="import" href="/tvcm/ui.html">
15
16 <script>
17 'use strict';
18
19 tvcm.exportTo('tracing.tracks', function() {
20
21   var SelectionState = tracing.trace_model.SelectionState;
22   var EventPresenter = tracing.EventPresenter;
23
24   /**
25    * A track that displays an array of Slice objects.
26    * @constructor
27    * @extends {HeadingTrack}
28    */
29
30   var ObjectInstanceTrack = tvcm.ui.define(
31       'object-instance-track', tracing.tracks.HeadingTrack);
32
33   ObjectInstanceTrack.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('object-instance-track');
39       this.objectInstances_ = [];
40       this.objectSnapshots_ = [];
41     },
42
43     get objectInstances() {
44       return this.objectInstances_;
45     },
46
47     set objectInstances(objectInstances) {
48       if (!objectInstances || objectInstances.length == 0) {
49         this.heading = '';
50         this.objectInstances_ = [];
51         this.objectSnapshots_ = [];
52         return;
53       }
54       this.heading = objectInstances[0].typeName;
55       this.objectInstances_ = objectInstances;
56       this.objectSnapshots_ = [];
57       this.objectInstances_.forEach(function(instance) {
58         this.objectSnapshots_.push.apply(
59             this.objectSnapshots_, instance.snapshots);
60       }, this);
61       this.objectSnapshots_.sort(function(a, b) {
62         return a.ts - b.ts;
63       });
64     },
65
66     get height() {
67       return window.getComputedStyle(this).height;
68     },
69
70     set height(height) {
71       this.style.height = height;
72     },
73
74     get snapshotRadiusView() {
75       return 7 * (window.devicePixelRatio || 1);
76     },
77
78     draw: function(type, viewLWorld, viewRWorld) {
79       switch (type) {
80         case tracing.tracks.DrawType.SLICE:
81           this.drawSlices_(viewLWorld, viewRWorld);
82           break;
83       }
84     },
85
86     drawSlices_: function(viewLWorld, viewRWorld) {
87       var ctx = this.context();
88       var pixelRatio = window.devicePixelRatio || 1;
89
90       var bounds = this.getBoundingClientRect();
91       var height = bounds.height * pixelRatio;
92       var halfHeight = height * 0.5;
93       var twoPi = Math.PI * 2;
94
95       // Culling parameters.
96       var dt = this.viewport.currentDisplayTransform;
97       var snapshotRadiusView = this.snapshotRadiusView;
98       var snapshotRadiusWorld = dt.xViewVectorToWorld(height);
99       var loI;
100
101       // Begin rendering in world space.
102       ctx.save();
103       dt.applyTransformToCanvas(ctx);
104
105       // Instances
106       var objectInstances = this.objectInstances_;
107       var loI = tvcm.findLowIndexInSortedArray(
108           objectInstances,
109           function(instance) {
110             return instance.deletionTs;
111           },
112           viewLWorld);
113       ctx.strokeStyle = 'rgb(0,0,0)';
114       for (var i = loI; i < objectInstances.length; ++i) {
115         var instance = objectInstances[i];
116         var x = instance.creationTs;
117         if (x > viewRWorld)
118           break;
119
120         var right = instance.deletionTs == Number.MAX_VALUE ?
121             viewRWorld : instance.deletionTs;
122         ctx.fillStyle = EventPresenter.getObjectInstanceColor(instance);
123         ctx.fillRect(x, pixelRatio, right - x, height - 2 * pixelRatio);
124       }
125       ctx.restore();
126
127       // Snapshots. Has to run in worldspace because ctx.arc gets transformed.
128       var objectSnapshots = this.objectSnapshots_;
129       loI = tvcm.findLowIndexInSortedArray(
130           objectSnapshots,
131           function(snapshot) {
132             return snapshot.ts + snapshotRadiusWorld;
133           },
134           viewLWorld);
135       for (var i = loI; i < objectSnapshots.length; ++i) {
136         var snapshot = objectSnapshots[i];
137         var x = snapshot.ts;
138         if (x - snapshotRadiusWorld > viewRWorld)
139           break;
140         var xView = dt.xWorldToView(x);
141
142         ctx.fillStyle = EventPresenter.getObjectSnapshotColor(snapshot);
143         ctx.beginPath();
144         ctx.arc(xView, halfHeight, snapshotRadiusView, 0, twoPi);
145         ctx.fill();
146         if (snapshot.selected) {
147           ctx.lineWidth = 5;
148           ctx.strokeStyle = 'rgb(100,100,0)';
149           ctx.stroke();
150
151           ctx.beginPath();
152           ctx.arc(xView, halfHeight, snapshotRadiusView - 1, 0, twoPi);
153           ctx.lineWidth = 2;
154           ctx.strokeStyle = 'rgb(255,255,0)';
155           ctx.stroke();
156         } else {
157           ctx.lineWidth = 1;
158           ctx.strokeStyle = 'rgb(0,0,0)';
159           ctx.stroke();
160         }
161       }
162       ctx.lineWidth = 1;
163
164       // For performance reasons we only check the SelectionState of the first
165       // instance. If it's DIMMED we assume that all are DIMMED.
166       // TODO(egraether): Allow partial highlight.
167       var selectionState = SelectionState.NONE;
168       if (objectInstances.length &&
169           objectInstances[0].selectionState === SelectionState.DIMMED) {
170         selectionState = SelectionState.DIMMED;
171       }
172
173       // Dim the track when there is an active highlight.
174       if (selectionState === SelectionState.DIMMED) {
175         var width = bounds.width * pixelRatio;
176         ctx.fillStyle = 'rgba(255,255,255,0.5)';
177         ctx.fillRect(0, 0, width, height);
178         ctx.restore();
179       }
180     },
181
182     addEventsToTrackMap: function(eventToTrackMap) {
183       if (this.objectInstance_ !== undefined) {
184         this.objectInstance_.forEach(function(obj) {
185           eventToTrackMap.addEvent(obj, this);
186         }, this);
187       }
188
189       if (this.objectSnapshots_ !== undefined) {
190         this.objectSnapshots_.forEach(function(obj) {
191           eventToTrackMap.addEvent(obj, this);
192         }, this);
193       }
194     },
195
196     addIntersectingItemsInRangeToSelectionInWorldSpace: function(
197         loWX, hiWX, viewPixWidthWorld, selection) {
198       // Pick snapshots first.
199       var foundSnapshot = false;
200       function onSnapshot(snapshot) {
201         selection.push(snapshot);
202         foundSnapshot = true;
203       }
204       var snapshotRadiusView = this.snapshotRadiusView;
205       var snapshotRadiusWorld = viewPixWidthWorld * snapshotRadiusView;
206       tvcm.iterateOverIntersectingIntervals(
207           this.objectSnapshots_,
208           function(x) { return x.ts - snapshotRadiusWorld; },
209           function(x) { return 2 * snapshotRadiusWorld; },
210           loWX, hiWX,
211           onSnapshot);
212       if (foundSnapshot)
213         return;
214
215       // Try picking instances.
216       tvcm.iterateOverIntersectingIntervals(
217           this.objectInstances_,
218           function(x) { return x.creationTs; },
219           function(x) { return x.deletionTs - x.creationTs; },
220           loWX, hiWX,
221           selection.push.bind(selection));
222     },
223
224     /**
225      * Add the item to the left or right of the provided event, if any, to the
226      * selection.
227      * @param {event} The current event item.
228      * @param {Number} offset Number of slices away from the event to look.
229      * @param {Selection} selection The selection to add an event to,
230      * if found.
231      * @return {boolean} Whether an event was found.
232      * @private
233      */
234     addItemNearToProvidedEventToSelection: function(event, offset, selection) {
235       var events;
236       if (event instanceof tracing.trace_model.ObjectSnapshot)
237         events = this.objectSnapshots_;
238       else if (event instanceof tracing.trace_model.ObjectInstance)
239         events = this.objectInstances_;
240       else
241         throw new Error('Unrecognized event');
242
243       var index = events.indexOf(event);
244       var newIndex = index + offset;
245       if (newIndex >= 0 && newIndex < events.length) {
246         selection.push(events[newIndex]);
247         return true;
248       }
249       return false;
250     },
251
252     addAllObjectsMatchingFilterToSelection: function(filter, selection) {
253     },
254
255     addClosestEventToSelection: function(worldX, worldMaxDist, loY, hiY,
256                                          selection) {
257       var snapshot = tvcm.findClosestElementInSortedArray(
258           this.objectSnapshots_,
259           function(x) { return x.ts; },
260           worldX,
261           worldMaxDist);
262
263       if (!snapshot)
264         return;
265
266       selection.push(snapshot);
267
268       // TODO(egraether): Search for object instances as well, which was not
269       // implemented because it makes little sense with the current visual and
270       // needs to take care of overlapping intervals.
271     }
272   };
273
274   ObjectInstanceTrack.typeNameToTrackConstructorMap = {};
275   ObjectInstanceTrack.register = function(typeName, constructor) {
276     if (ObjectInstanceTrack.typeNameToTrackConstructorMap[typeName])
277       throw new Error('Handler already registered for ' + typeName);
278     ObjectInstanceTrack.typeNameToTrackConstructorMap[typeName] =
279         constructor;
280   };
281
282   ObjectInstanceTrack.getTrackConstructor = function(typeName) {
283     return ObjectInstanceTrack.typeNameToTrackConstructorMap[typeName];
284   };
285
286   return {
287     ObjectInstanceTrack: ObjectInstanceTrack
288   };
289 });
290 </script>