00f00176148d559f417cd7f572df92692e09c686
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / cc / layer_picker.js
1 // Copyright (c) 2013 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('cc.layer_picker');
8
9 tvcm.require('cc.constants');
10 tvcm.require('cc.layer_tree_host_impl');
11 tvcm.require('cc.selection');
12 tvcm.require('tracing.analysis.generic_object_view');
13 tvcm.require('tracing.trace_model.event');
14 tvcm.require('tvcm.ui.drag_handle');
15 tvcm.require('tvcm.ui.list_view');
16 tvcm.require('tvcm.ui.dom_helpers');
17
18 tvcm.exportTo('cc', function() {
19   var constants = cc.constants;
20   var RENDER_PASS_QUADS =
21       Math.max(constants.ACTIVE_TREE, constants.PENDING_TREE) + 1;
22
23   /**
24    * @constructor
25    */
26   var LayerPicker = tvcm.ui.define('layer-picker');
27
28   LayerPicker.prototype = {
29     __proto__: HTMLUnknownElement.prototype,
30
31     decorate: function() {
32       this.lthi_ = undefined;
33       this.controls_ = document.createElement('top-controls');
34       this.renderPassQuads_ = false;
35
36
37       this.itemList_ = new tvcm.ui.ListView();
38       this.appendChild(this.controls_);
39
40       this.appendChild(this.itemList_);
41
42       this.itemList_.addEventListener(
43           'selection-changed', this.onItemSelectionChanged_.bind(this));
44
45       this.controls_.appendChild(tvcm.ui.createSelector(
46           this, 'whichTree',
47           'layerPicker.whichTree', constants.ACTIVE_TREE,
48           [{label: 'Active tree', value: constants.ACTIVE_TREE},
49            {label: 'Pending tree', value: constants.PENDING_TREE},
50            {label: 'Render pass quads', value: RENDER_PASS_QUADS}]));
51
52       this.showPureTransformLayers_ = false;
53       var showPureTransformLayers = tvcm.ui.createCheckBox(
54           this, 'showPureTransformLayers',
55           'layerPicker.showPureTransformLayers', false,
56           'Transform layers');
57       showPureTransformLayers.classList.add('show-transform-layers');
58       showPureTransformLayers.title =
59           'When checked, pure transform layers are shown';
60       this.controls_.appendChild(showPureTransformLayers);
61     },
62
63     get lthiSnapshot() {
64       return this.lthiSnapshot_;
65     },
66
67     set lthiSnapshot(lthiSnapshot) {
68       this.lthiSnapshot_ = lthiSnapshot;
69       this.updateContents_();
70     },
71
72     get whichTree() {
73       return this.renderPassQuads_ ? constants.ACTIVE_TREE : this.whichTree_;
74     },
75
76     set whichTree(whichTree) {
77       this.whichTree_ = whichTree;
78       this.renderPassQuads_ = (whichTree == RENDER_PASS_QUADS);
79       this.updateContents_();
80       tvcm.dispatchSimpleEvent(this, 'selection-changed', false);
81     },
82
83     get isRenderPassQuads() {
84       return this.renderPassQuads_;
85     },
86
87     get showPureTransformLayers() {
88       return this.showPureTransformLayers_;
89     },
90
91     set showPureTransformLayers(show) {
92       if (this.showPureTransformLayers_ === show)
93         return;
94       this.showPureTransformLayers_ = show;
95       this.updateContents_();
96     },
97
98     getRenderPassInfos_: function() {
99       if (!this.lthiSnapshot_)
100         return [];
101
102       var renderPassInfo = [];
103       if (!this.lthiSnapshot_.args.frame ||
104           !this.lthiSnapshot_.args.frame.renderPasses)
105         return renderPassInfo;
106
107       var renderPasses = this.lthiSnapshot_.args.frame.renderPasses;
108       for (var i = 0; i < renderPasses.length; ++i) {
109         var info = {renderPass: renderPasses[i],
110                      depth: 0,
111                      id: i,
112                      name: 'cc::RenderPass'};
113         renderPassInfo.push(info);
114       }
115       return renderPassInfo;
116     },
117
118     getLayerInfos_: function() {
119       if (!this.lthiSnapshot_)
120         return [];
121
122       var tree = this.lthiSnapshot_.getTree(this.whichTree_);
123       if (!tree)
124         return [];
125
126       var layerInfos = [];
127
128       var showPureTransformLayers = this.showPureTransformLayers_;
129
130       function isPureTransformLayer(layer) {
131         if (layer.args.compositingReasons &&
132             layer.args.compositingReasons.length != 1 &&
133             layer.args.compositingReasons[0] != 'No reasons given')
134           return false;
135
136         if (layer.args.drawsContent)
137           return false;
138
139         return true;
140       }
141       var visitedLayers = {};
142       function visitLayer(layer, depth, isMask, isReplica) {
143         if (visitedLayers[layer.layerId])
144           return;
145         visitedLayers[layer.layerId] = true;
146         var info = {layer: layer,
147           depth: depth};
148
149         if (layer.args.drawsContent)
150           info.name = layer.objectInstance.name;
151         else
152           info.name = 'cc::LayerImpl';
153
154         if (layer.usingGpuRasterization)
155           info.name += ' (G)';
156
157         info.isMaskLayer = isMask;
158         info.replicaLayer = isReplica;
159
160         if (showPureTransformLayers || !isPureTransformLayer(layer))
161           layerInfos.push(info);
162
163       };
164       tree.iterLayers(visitLayer);
165       return layerInfos;
166     },
167
168     updateContents_: function() {
169       if (this.renderPassQuads_)
170         this.updateRenderPassContents_();
171       else
172         this.updateLayerContents_();
173
174     },
175
176     updateRenderPassContents_: function() {
177       this.itemList_.clear();
178
179       var selectedRenderPassId;
180       if (this.selection_ && this.selection_.associatedRenderPassId)
181         selectedRenderPassId = this.selection_.associatedRenderPassId;
182
183       var renderPassInfos = this.getRenderPassInfos_();
184       renderPassInfos.forEach(function(renderPassInfo) {
185         var renderPass = renderPassInfo.renderPass;
186         var id = renderPassInfo.id;
187
188         var item = this.createElementWithDepth_(renderPassInfo.depth);
189         var labelEl = item.appendChild(tvcm.ui.createSpan());
190
191         labelEl.textContent = renderPassInfo.name + ' ' + id;
192         item.renderPass = renderPass;
193         item.renderPassId = id;
194         this.itemList_.appendChild(item);
195
196         if (id == selectedRenderPassId) {
197           renderPass.selectionState =
198               tracing.trace_model.SelectionState.SELECTED;
199         }
200       }, this);
201     },
202
203     updateLayerContents_: function() {
204       this.itemList_.clear();
205
206       var selectedLayerId;
207       if (this.selection_ && this.selection_.associatedLayerId)
208         selectedLayerId = this.selection_.associatedLayerId;
209
210       var layerInfos = this.getLayerInfos_();
211       layerInfos.forEach(function(layerInfo) {
212         var layer = layerInfo.layer;
213         var id = layer.layerId;
214
215         var item = this.createElementWithDepth_(layerInfo.depth);
216         var labelEl = item.appendChild(tvcm.ui.createSpan());
217
218         labelEl.textContent = layerInfo.name + ' ' + id;
219
220         var notesEl = item.appendChild(tvcm.ui.createSpan());
221         if (layerInfo.isMaskLayer)
222           notesEl.textContent += '(mask)';
223         if (layerInfo.isReplicaLayer)
224           notesEl.textContent += '(replica)';
225
226         item.layer = layer;
227         this.itemList_.appendChild(item);
228
229         if (layer.layerId == selectedLayerId)
230           layer.selectionState = tracing.trace_model.SelectionState.SELECTED;
231       }, this);
232     },
233
234     createElementWithDepth_: function(depth) {
235       var item = document.createElement('div');
236
237       var indentEl = item.appendChild(tvcm.ui.createSpan());
238       indentEl.style.whiteSpace = 'pre';
239       for (var i = 0; i < depth; i++)
240         indentEl.textContent = indentEl.textContent + ' ';
241       return item;
242     },
243
244     onItemSelectionChanged_: function(e) {
245       if (this.renderPassQuads_)
246         this.onRenderPassSelected_(e);
247       else
248         this.onLayerSelected_(e);
249       tvcm.dispatchSimpleEvent(this, 'selection-changed', false);
250     },
251
252     onRenderPassSelected_: function(e) {
253       var selectedRenderPass;
254       var selectedRenderPassId;
255       if (this.itemList_.selectedElement) {
256         selectedRenderPass = this.itemList_.selectedElement.renderPass;
257         selectedRenderPassId =
258             this.itemList_.selectedElement.renderPassId;
259       }
260
261       if (selectedRenderPass) {
262         this.selection_ = new cc.RenderPassSelection(
263             selectedRenderPass, selectedRenderPassId);
264       } else {
265         this.selection_ = undefined;
266       }
267     },
268
269     onLayerSelected_: function(e) {
270       var selectedLayer;
271       if (this.itemList_.selectedElement)
272         selectedLayer = this.itemList_.selectedElement.layer;
273
274       if (selectedLayer)
275         this.selection_ = new cc.LayerSelection(selectedLayer);
276       else
277         this.selection_ = undefined;
278     },
279
280     get selection() {
281       return this.selection_;
282     },
283
284     set selection(selection) {
285       this.selection_ = selection;
286       this.updateContents_();
287     }
288   };
289
290   return {
291     LayerPicker: LayerPicker
292   };
293 });