1<!DOCTYPE html>
2<!--
3Copyright (c) 2013 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/ui/analysis/generic_object_view.html">
9
10<script>
11'use strict';
12
13tr.exportTo('tr.ui.e.chrome.cc', function() {
14  function Selection() {
15    this.selectionToSetIfClicked = undefined;
16  };
17  Selection.prototype = {
18    /**
19     * When two things are picked in the UI, one must occasionally tie-break
20     * between them to decide what was really clicked. Things with higher
21     * specicifity will win.
22     */
23    get specicifity() {
24      throw new Error('Not implemented');
25    },
26
27    /**
28     * If a selection is related to a specific layer, then this returns the
29     * layerId of that layer. If the selection is not related to a layer, for
30     * example if the device viewport is selected, then this returns undefined.
31     */
32    get associatedLayerId() {
33      throw new Error('Not implemented');
34    },
35
36    /**
37     * If a selection is related to a specific render pass, then this returns
38     * the layerId of that layer. If the selection is not related to a layer,
39     * for example if the device viewport is selected, then this returns
40     * undefined.
41     */
42    get associatedRenderPassId() {
43      throw new Error('Not implemented');
44    },
45
46
47    get highlightsByLayerId() {
48      return {};
49    },
50
51    /**
52     * Called when the selection is made active in the layer view. Must return
53     * an HTMLElement that explains this selection in detail.
54     */
55    createAnalysis: function() {
56      throw new Error('Not implemented');
57    },
58
59    /**
60     * Should try to create the equivalent selection in the provided LTHI,
61     * or undefined if it can't be done.
62     */
63    findEquivalent: function(lthi) {
64      throw new Error('Not implemented');
65    }
66  };
67
68  /**
69   * @constructor
70   */
71  function RenderPassSelection(renderPass, renderPassId) {
72    if (!renderPass || (renderPassId === undefined))
73      throw new Error('Render pass (with id) is required');
74    this.renderPass_ = renderPass;
75    this.renderPassId_ = renderPassId;
76  }
77
78  RenderPassSelection.prototype = {
79    __proto__: Selection.prototype,
80
81    get specicifity() {
82      return 1;
83    },
84
85    get associatedLayerId() {
86      return undefined;
87    },
88
89    get associatedRenderPassId() {
90      return this.renderPassId_;
91    },
92
93    get renderPass() {
94      return this.renderPass_;
95    },
96
97    createAnalysis: function() {
98      var dataView = document.createElement(
99          'tr-ui-a-generic-object-view-with-label');
100      dataView.label = 'RenderPass ' + this.renderPassId_;
101      dataView.object = this.renderPass_.args;
102      return dataView;
103    },
104
105    get title() {
106      return this.renderPass_.objectInstance.typeName;
107    }
108  };
109
110  /**
111   * @constructor
112   */
113  function LayerSelection(layer) {
114    if (!layer)
115      throw new Error('Layer is required');
116    this.layer_ = layer;
117  }
118
119  LayerSelection.prototype = {
120    __proto__: Selection.prototype,
121
122    get specicifity() {
123      return 1;
124    },
125
126    get associatedLayerId() {
127      return this.layer_.layerId;
128    },
129
130    get associatedRenderPassId() {
131      return undefined;
132    },
133
134    get layer() {
135      return this.layer_;
136    },
137
138    createAnalysis: function() {
139      var dataView = document.createElement(
140          'tr-ui-a-generic-object-view-with-label');
141      dataView.label = 'Layer ' + this.layer_.layerId;
142      if (this.layer_.usingGpuRasterization)
143        dataView.label += ' (GPU-rasterized)';
144      dataView.object = this.layer_.args;
145      return dataView;
146    },
147
148    get title() {
149      return this.layer_.objectInstance.typeName;
150    },
151
152    findEquivalent: function(lthi) {
153      var layer = lthi.activeTree.findLayerWithId(this.layer_.layerId) ||
154          lthi.pendingTree.findLayerWithId(this.layer_.layerId);
155      if (!layer)
156        return undefined;
157      return new LayerSelection(layer);
158    }
159  };
160
161  /**
162   * @constructor
163   */
164  function TileSelection(tile, opt_data) {
165    this.tile_ = tile;
166    this.data_ = opt_data || {};
167  }
168
169  TileSelection.prototype = {
170    __proto__: Selection.prototype,
171
172    get specicifity() {
173      return 2;
174    },
175
176    get associatedLayerId() {
177      return this.tile_.layerId;
178    },
179
180    get highlightsByLayerId() {
181      var highlights = {};
182      highlights[this.tile_.layerId] = [
183        {
184          colorKey: this.tile_.objectInstance.typeName,
185          rect: this.tile_.layerRect
186        }
187      ];
188      return highlights;
189    },
190
191    createAnalysis: function() {
192      var analysis = document.createElement(
193          'tr-ui-a-generic-object-view-with-label');
194      analysis.label = 'Tile ' + this.tile_.objectInstance.id + ' on layer ' +
195          this.tile_.layerId;
196      if (this.data_) {
197        analysis.object = {
198          moreInfo: this.data_,
199          tileArgs: this.tile_.args
200        };
201      } else {
202        analysis.object = this.tile_.args;
203      }
204      return analysis;
205    },
206
207    findEquivalent: function(lthi) {
208      var tileInstance = this.tile_.tileInstance;
209      if (lthi.ts < tileInstance.creationTs ||
210          lthi.ts >= tileInstance.deletionTs)
211        return undefined;
212      var tileSnapshot = tileInstance.getSnapshotAt(lthi.ts);
213      if (!tileSnapshot)
214        return undefined;
215      return new TileSelection(tileSnapshot);
216    }
217  };
218
219  /**
220   * @constructor
221   */
222  function LayerRectSelection(layer, rectType, rect, opt_data) {
223    this.layer_ = layer;
224    this.rectType_ = rectType;
225    this.rect_ = rect;
226    this.data_ = opt_data !== undefined ? opt_data : rect;
227  }
228
229  LayerRectSelection.prototype = {
230    __proto__: Selection.prototype,
231
232    get specicifity() {
233      return 2;
234    },
235
236    get associatedLayerId() {
237      return this.layer_.layerId;
238    },
239
240
241    get highlightsByLayerId() {
242      var highlights = {};
243      highlights[this.layer_.layerId] = [
244        {
245          colorKey: this.rectType_,
246          rect: this.rect_
247        }
248      ];
249      return highlights;
250    },
251
252    createAnalysis: function() {
253      var analysis = document.createElement(
254          'tr-ui-a-generic-object-view-with-label');
255      analysis.label = this.rectType_ + ' on layer ' + this.layer_.layerId;
256      analysis.object = this.data_;
257      return analysis;
258    },
259
260    findEquivalent: function(lthi) {
261      return undefined;
262    }
263  };
264
265  /**
266   * @constructor
267   */
268  function AnimationRectSelection(layer, rect) {
269    this.layer_ = layer;
270    this.rect_ = rect;
271  }
272
273  AnimationRectSelection.prototype = {
274    __proto__: Selection.prototype,
275
276    get specicifity() {
277      return 0;
278    },
279
280    get associatedLayerId() {
281      return this.layer_.layerId;
282    },
283
284    createAnalysis: function() {
285      var analysis = document.createElement(
286          'tr-ui-a-generic-object-view-with-label');
287      analysis.label = 'Animation Bounds of layer ' + this.layer_.layerId;
288      analysis.object = this.rect_;
289      return analysis;
290    }
291  };
292
293  return {
294    Selection: Selection,
295    RenderPassSelection: RenderPassSelection,
296    LayerSelection: LayerSelection,
297    TileSelection: TileSelection,
298    LayerRectSelection: LayerRectSelection,
299    AnimationRectSelection: AnimationRectSelection
300  };
301});
302</script>
303