layer_tree_impl.html revision 4a4f2fe02baf385f6c24fc98c6e17bf6ac5e0724
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/extras/chrome/chrome_model_helper.html">
9<link rel="import" href="/tracing/extras/chrome/cc/constants.html">
10<link rel="import" href="/tracing/extras/chrome/cc/layer_impl.html">
11<link rel="import" href="/tracing/model/object_instance.html">
12
13<script>
14'use strict';
15
16tr.exportTo('tr.e.cc', function() {
17
18  var constants = tr.e.cc.constants;
19  var ObjectSnapshot = tr.model.ObjectSnapshot;
20
21  /**
22   * @constructor
23   */
24  function LayerTreeImplSnapshot() {
25    ObjectSnapshot.apply(this, arguments);
26  }
27
28  LayerTreeImplSnapshot.prototype = {
29    __proto__: ObjectSnapshot.prototype,
30
31    preInitialize: function() {
32      tr.e.cc.preInitializeObject(this);
33      this.layerTreeHostImpl = undefined;
34      this.whichTree = undefined;
35      this.sourceFrameNumber = undefined;
36    },
37
38    initialize: function() {
39      tr.e.cc.moveRequiredFieldsFromArgsToToplevel(
40          this, ['rootLayer',
41            'renderSurfaceLayerList']);
42      if (this.args.sourceFrameNumber)
43        this.sourceFrameNumber = this.args.sourceFrameNumber;
44      this.rootLayer.layerTreeImpl = this;
45
46      if (this.args.swapPromiseTraceIds &&
47          this.args.swapPromiseTraceIds.length) {
48        this.tracedInputLatencies = [];
49
50        var ownProcess = this.objectInstance.parent;
51        var model = ownProcess.model;
52        if (tr.e.audits.ChromeModelHelper.supportsModel(model))
53          this._initializeTracedInputLatencies(model);
54      }
55    },
56
57    _initializeTracedInputLatencies: function(model) {
58      var modelHelper = new tr.e.audits.ChromeModelHelper(model);
59      if (!modelHelper.browserHelper)
60        return;
61
62      var latencyEvents = modelHelper.browserHelper.getLatencyEventsInRange(
63          model.bounds);
64
65      // Convert all ids to InputLatency Async objects.
66      latencyEvents.forEach(function(event) {
67        for (var i = 0; i < this.args.swapPromiseTraceIds.length; i++) {
68          if (!event.args.data || !event.args.data.trace_id)
69            continue;
70          if (parseInt(event.args.data.trace_id) ===
71              this.args.swapPromiseTraceIds[i])
72            this.tracedInputLatencies.push(event);
73        }
74      }, this);
75    },
76
77    get hasSourceFrameBeenDrawnBefore() {
78      if (this.whichTree == tr.e.cc.constants.PENDING_TREE)
79        return false;
80
81      // Old chrome's don't produce sourceFrameNumber.
82      if (this.sourceFrameNumber === undefined)
83        return;
84
85      var thisLTHI = this.layerTreeHostImpl;
86      var thisLTHIIndex = thisLTHI.objectInstance.snapshots.indexOf(
87        thisLTHI);
88      var prevLTHIIndex = thisLTHIIndex - 1;
89      if (prevLTHIIndex < 0 ||
90          prevLTHIIndex >= thisLTHI.objectInstance.snapshots.length)
91        return false;
92      var prevLTHI = thisLTHI.objectInstance.snapshots[prevLTHIIndex];
93      if (!prevLTHI.activeTree)
94        return false;
95
96      // Old chrome's don't produce sourceFrameNumber.
97      if (prevLTHI.activeTree.sourceFrameNumber === undefined)
98        return;
99      return prevLTHI.activeTree.sourceFrameNumber == this.sourceFrameNumber;
100    },
101
102    get otherTree() {
103      var other = this.whichTree == constants.ACTIVE_TREE ?
104          constants.PENDING_TREE : constants.ACTIVE_TREE;
105      return this.layerTreeHostImpl.getTree(other);
106    },
107
108    get gpuMemoryUsageInBytes() {
109      var totalBytes = 0;
110      this.iterLayers(function(layer) {
111        if (layer.gpuMemoryUsageInBytes !== undefined)
112          totalBytes += layer.gpuMemoryUsageInBytes;
113      });
114      return totalBytes;
115    },
116
117    iterLayers: function(func, thisArg) {
118      var visitedLayers = {};
119      function visitLayer(layer, depth, isMask, isReplica) {
120        if (visitedLayers[layer.layerId])
121          return;
122        visitedLayers[layer.layerId] = true;
123        func.call(thisArg, layer, depth, isMask, isReplica);
124        if (layer.children) {
125          for (var i = 0; i < layer.children.length; i++)
126            visitLayer(layer.children[i], depth + 1);
127        }
128        if (layer.maskLayer)
129          visitLayer(layer.maskLayer, depth + 1, true, false);
130        if (layer.replicaLayer)
131          visitLayer(layer.replicaLayer, depth + 1, false, true);
132      }
133      visitLayer(this.rootLayer, 0, false, false);
134    },
135    findLayerWithId: function(id) {
136      var foundLayer = undefined;
137      function visitLayer(layer) {
138        if (layer.layerId == id)
139          foundLayer = layer;
140      }
141      this.iterLayers(visitLayer);
142      return foundLayer;
143    }
144  };
145
146  ObjectSnapshot.register(
147      LayerTreeImplSnapshot,
148      {typeName: 'cc::LayerTreeImpl'});
149
150  return {
151    LayerTreeImplSnapshot: LayerTreeImplSnapshot
152  };
153});
154</script>
155