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.
8 <link rel="stylesheet" href="/cc/layer_picker.css">
10 <link rel="import" href="/cc/constants.html">
11 <link rel="import" href="/cc/layer_tree_host_impl.html">
12 <link rel="import" href="/cc/selection.html">
13 <link rel="import" href="/cc/util.html">
14 <link rel="import" href="/tracing/analysis/generic_object_view.html">
15 <link rel="import" href="/tracing/trace_model/event.html">
16 <link rel="import" href="/tvcm/ui/drag_handle.html">
17 <link rel="import" href="/tvcm/ui/list_view.html">
18 <link rel="import" href="/tvcm/ui/dom_helpers.html">
23 tvcm.exportTo('cc', function() {
24 var constants = cc.constants;
25 var bytesToRoundedMegabytes = cc.bytesToRoundedMegabytes;
26 var RENDER_PASS_QUADS =
27 Math.max(constants.ACTIVE_TREE, constants.PENDING_TREE) + 1;
32 var LayerPicker = tvcm.ui.define('layer-picker');
34 LayerPicker.prototype = {
35 __proto__: HTMLUnknownElement.prototype,
37 decorate: function() {
38 this.lthi_ = undefined;
39 this.controls_ = document.createElement('top-controls');
40 this.renderPassQuads_ = false;
43 this.itemList_ = new tvcm.ui.ListView();
44 this.appendChild(this.controls_);
46 this.appendChild(this.itemList_);
48 this.itemList_.addEventListener(
49 'selection-changed', this.onItemSelectionChanged_.bind(this));
51 this.controls_.appendChild(tvcm.ui.createSelector(
53 'layerPicker.whichTree', constants.ACTIVE_TREE,
54 [{label: 'Active tree', value: constants.ACTIVE_TREE},
55 {label: 'Pending tree', value: constants.PENDING_TREE},
56 {label: 'Render pass quads', value: RENDER_PASS_QUADS}]));
58 this.showPureTransformLayers_ = false;
59 var showPureTransformLayers = tvcm.ui.createCheckBox(
60 this, 'showPureTransformLayers',
61 'layerPicker.showPureTransformLayers', false,
63 showPureTransformLayers.classList.add('show-transform-layers');
64 showPureTransformLayers.title =
65 'When checked, pure transform layers are shown';
66 this.controls_.appendChild(showPureTransformLayers);
70 return this.lthiSnapshot_;
73 set lthiSnapshot(lthiSnapshot) {
74 this.lthiSnapshot_ = lthiSnapshot;
75 this.updateContents_();
79 return this.renderPassQuads_ ? constants.ACTIVE_TREE : this.whichTree_;
82 set whichTree(whichTree) {
83 this.whichTree_ = whichTree;
84 this.renderPassQuads_ = (whichTree == RENDER_PASS_QUADS);
85 this.updateContents_();
86 tvcm.dispatchSimpleEvent(this, 'selection-changed', false);
90 if (this.lthiSnapshot === undefined)
92 return this.lthiSnapshot.getTree(this.whichTree);
95 get isRenderPassQuads() {
96 return this.renderPassQuads_;
99 get showPureTransformLayers() {
100 return this.showPureTransformLayers_;
103 set showPureTransformLayers(show) {
104 if (this.showPureTransformLayers_ === show)
106 this.showPureTransformLayers_ = show;
107 this.updateContents_();
110 getRenderPassInfos_: function() {
111 if (!this.lthiSnapshot_)
114 var renderPassInfo = [];
115 if (!this.lthiSnapshot_.args.frame ||
116 !this.lthiSnapshot_.args.frame.renderPasses)
117 return renderPassInfo;
119 var renderPasses = this.lthiSnapshot_.args.frame.renderPasses;
120 for (var i = 0; i < renderPasses.length; ++i) {
121 var info = {renderPass: renderPasses[i],
124 name: 'cc::RenderPass'};
125 renderPassInfo.push(info);
127 return renderPassInfo;
130 getLayerInfos_: function() {
131 if (!this.lthiSnapshot_)
134 var tree = this.lthiSnapshot_.getTree(this.whichTree_);
140 var showPureTransformLayers = this.showPureTransformLayers_;
142 function isPureTransformLayer(layer) {
143 if (layer.args.compositingReasons &&
144 layer.args.compositingReasons.length != 1 &&
145 layer.args.compositingReasons[0] != 'No reasons given')
148 if (layer.args.drawsContent)
153 var visitedLayers = {};
154 function visitLayer(layer, depth, isMask, isReplica) {
155 if (visitedLayers[layer.layerId])
157 visitedLayers[layer.layerId] = true;
158 var info = {layer: layer,
161 if (layer.args.drawsContent)
162 info.name = layer.objectInstance.name;
164 info.name = 'cc::LayerImpl';
166 if (layer.usingGpuRasterization)
169 info.isMaskLayer = isMask;
170 info.replicaLayer = isReplica;
172 if (showPureTransformLayers || !isPureTransformLayer(layer))
173 layerInfos.push(info);
176 tree.iterLayers(visitLayer);
180 updateContents_: function() {
181 if (this.renderPassQuads_)
182 this.updateRenderPassContents_();
184 this.updateLayerContents_();
187 updateRenderPassContents_: function() {
188 this.itemList_.clear();
190 var selectedRenderPassId;
191 if (this.selection_ && this.selection_.associatedRenderPassId)
192 selectedRenderPassId = this.selection_.associatedRenderPassId;
194 var renderPassInfos = this.getRenderPassInfos_();
195 renderPassInfos.forEach(function(renderPassInfo) {
196 var renderPass = renderPassInfo.renderPass;
197 var id = renderPassInfo.id;
199 var item = this.createElementWithDepth_(renderPassInfo.depth);
200 var labelEl = item.appendChild(tvcm.ui.createSpan());
202 labelEl.textContent = renderPassInfo.name + ' ' + id;
203 item.renderPass = renderPass;
204 item.renderPassId = id;
205 this.itemList_.appendChild(item);
207 if (id == selectedRenderPassId) {
208 renderPass.selectionState =
209 tracing.trace_model.SelectionState.SELECTED;
214 updateLayerContents_: function() {
215 this.itemList_.clear();
218 if (this.selection_ && this.selection_.associatedLayerId)
219 selectedLayerId = this.selection_.associatedLayerId;
221 var layerInfos = this.getLayerInfos_();
222 layerInfos.forEach(function(layerInfo) {
223 var layer = layerInfo.layer;
224 var id = layer.layerId;
226 var item = this.createElementWithDepth_(layerInfo.depth);
227 var labelEl = item.appendChild(tvcm.ui.createSpan());
229 labelEl.textContent = layerInfo.name + ' ' + id;
231 var notesEl = item.appendChild(tvcm.ui.createSpan());
232 if (layerInfo.isMaskLayer)
233 notesEl.textContent += '(mask)';
234 if (layerInfo.isReplicaLayer)
235 notesEl.textContent += '(replica)';
237 if (layer.gpuMemoryUsageInBytes !== undefined) {
238 var rounded = bytesToRoundedMegabytes(layer.gpuMemoryUsageInBytes);
240 notesEl.textContent += ' (' + rounded + ' MB)';
244 this.itemList_.appendChild(item);
246 if (layer.layerId == selectedLayerId)
247 layer.selectionState = tracing.trace_model.SelectionState.SELECTED;
251 createElementWithDepth_: function(depth) {
252 var item = document.createElement('div');
254 var indentEl = item.appendChild(tvcm.ui.createSpan());
255 indentEl.style.whiteSpace = 'pre';
256 for (var i = 0; i < depth; i++)
257 indentEl.textContent = indentEl.textContent + ' ';
261 onItemSelectionChanged_: function(e) {
262 if (this.renderPassQuads_)
263 this.onRenderPassSelected_(e);
265 this.onLayerSelected_(e);
266 tvcm.dispatchSimpleEvent(this, 'selection-changed', false);
269 onRenderPassSelected_: function(e) {
270 var selectedRenderPass;
271 var selectedRenderPassId;
272 if (this.itemList_.selectedElement) {
273 selectedRenderPass = this.itemList_.selectedElement.renderPass;
274 selectedRenderPassId =
275 this.itemList_.selectedElement.renderPassId;
278 if (selectedRenderPass) {
279 this.selection_ = new cc.RenderPassSelection(
280 selectedRenderPass, selectedRenderPassId);
282 this.selection_ = undefined;
286 onLayerSelected_: function(e) {
288 if (this.itemList_.selectedElement)
289 selectedLayer = this.itemList_.selectedElement.layer;
292 this.selection_ = new cc.LayerSelection(selectedLayer);
294 this.selection_ = undefined;
298 return this.selection_;
301 set selection(selection) {
302 this.selection_ = selection;
303 this.updateContents_();
308 LayerPicker: LayerPicker