166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// Copyright (c) 2013 The Chromium Authors. All rights reserved.
266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// Use of this source code is governed by a BSD-style license that can be
366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis// found in the LICENSE file.
466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis'use strict';
666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis/**
866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * @fileoverview Graphical view of  LayerTreeImpl, with controls for
966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis * type of layer content shown and info bar for content-loading warnings.
1066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis */
1166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
1266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.requireStylesheet('cc.layer_tree_quad_stack_viewer');
1366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
1466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.properties');
1566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.raf');
1666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('cc.constants');
1766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('cc.picture');
1866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('ui.quad_stack_viewer');
1966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('ui.info_bar');
2066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
2166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
2266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.exportTo('cc', function() {
2366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  var constants = {
2466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    // The ratio of quad stack pixels to world pixels before CSS scaling.
2566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    QUAD_STACK_SCALE: 0.5
2666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  };
2766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
2866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  /**
2966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis   * @constructor
3066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis   */
3166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  var LayerTreeQuadStackViewer = ui.define('layer-tree-quad-stack-viewer');
3266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
3366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  LayerTreeQuadStackViewer.prototype = {
3466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    __proto__: HTMLDivElement.prototype,
3566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
3666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    decorate: function() {
376833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis      this.pictureAsCanvas_ = {}; // Maps picture.guid to PictureAsCanvas.
3866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.quads_ = [];
3966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.messages_ = [];
4066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.controls_ = document.createElement('top-controls');
4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.infoBar_ = new ui.InfoBar();
4266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.quadStackViewer_ = new ui.QuadStackViewer();
4366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
4466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.appendChild(this.controls_);
4566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.appendChild(this.infoBar_);
4666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.appendChild(this.quadStackViewer_);
4766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
4866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var scaleSelector = ui.createSelector(
4966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          this.quadStackViewer_, 'scale',
5066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          'layerViewer.scale', 0.375,
5166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          [{label: '6.25%', value: 0.0625},
5266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis           {label: '12.5%', value: 0.125},
5366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis           {label: '25%', value: 0.25},
5466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis           {label: '37.5%', value: 0.375},
5566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis           {label: '50%', value: 0.5},
5666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis           {label: '75%', value: 0.75},
5766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis           {label: '100%', value: 1},
5866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis           {label: '200%', value: 2}
5966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          ]);
6066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.controls_.appendChild(scaleSelector);
6166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
6266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var showOtherLayersCheckbox = ui.createCheckBox(
6366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          this, 'showOtherLayers',
6466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          'layerViewer.showOtherLayers', true,
6566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          'Show other layers');
6666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.controls_.appendChild(showOtherLayersCheckbox);
6766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
6866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var showInvalidationsCheckbox = ui.createCheckBox(
6966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          this, 'showInvalidations',
7066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          'layerViewer.showInvalidations', true,
7166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          'Show invalidations');
7266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.controls_.appendChild(showInvalidationsCheckbox);
7366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var showContentsCheckbox = ui.createCheckBox(
7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          this, 'showContents',
7666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          'layerViewer.showContents', true,
7766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          'Show contents');
7866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.controls_.appendChild(showContentsCheckbox);
7966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
8066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
8166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    get layerTreeImpl() {
8266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return this.layerTreeImpl_;
8366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
8466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
8566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    set layerTreeImpl(layerTreeImpl) {
866833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis      // FIXME(pdr): We may want to clear pictureAsCanvas_ here to save memory
876833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis      //             at the cost of performance. Note that pictureAsCanvas_ will
886833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis      //             be cleared when this is destructed, but this view might
896833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis      //             live for several layerTreeImpls.
9066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.layerTreeImpl_ = layerTreeImpl;
9166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.selection = null;
9266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateContents_();
9366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
9466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
9566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    get showOtherLayers() {
9666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return this.showOtherLayers_;
9766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
9866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
9966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    set showOtherLayers(show) {
10066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.showOtherLayers_ = show;
10166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateContents_();
10266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
10366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
10466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    get showContents() {
10566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return this.showContents_;
10666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
10766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
10866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    set showContents(show) {
10966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.showContents_ = show;
11066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateContents_();
11166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
11266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
11366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    get showInvalidations() {
11466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return this.showInvalidations_;
11566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
11666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
11766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    set showInvalidations(show) {
11866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.showInvalidations_ = show;
11966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateContents_();
12066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
12166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
12266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    get selection() {
12366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return this.selection_;
12466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
12566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
12666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    set selection(selection) {
12766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      base.setPropertyAndDispatchChange(this, 'selection', selection);
12866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateContents_();
12966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
13066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
13166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    scheduleUpdateContents_: function() {
13266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (this.updateContentsPending_)
13366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        return;
13466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateContentsPending_ = true;
13566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      base.requestAnimationFrameInThisFrameIfPossible(
13666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          this.updateContents_, this);
13766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
13866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
13966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    updateContents_: function() {
14066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (!this.layerTreeImpl_)
14166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        return;
14266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
14366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (this.pictureLoadingComplete_())
14466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.generateQuads_();
14566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
14666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
14766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    pictureLoadingComplete_: function() {
14866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      // Figure out if we can draw the quads yet. While we're at it, figure out
14966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      // if we have any warnings we need to show.
15066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var layers = this.layers;
15166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var messages = [];
15266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (this.showContents) {
15366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var hasPendingRasterizeImage = false;
15466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var firstPictureError = undefined;
15566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var hasMissingLayerRect = false;
15666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var hasUnresolvedPictureRef = false;
15766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        for (var i = 0; i < layers.length; i++) {
15866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          var layer = layers[i];
15966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          for (var ir = layer.pictures.length - 1; ir >= 0; ir--) {
16066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            var picture = layer.pictures[ir];
16166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
16266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            if (picture.idRef) {
16366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              hasUnresolvedPictureRef = true;
16466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              continue;
16566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            }
16666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            if (!picture.layerRect) {
16766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              hasMissingLayerRect = true;
16866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              continue;
16966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            }
17066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
1716833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis            var pictureAsCanvas = this.pictureAsCanvas_[picture.guid];
1726833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis            if (!pictureAsCanvas) {
17366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              hasPendingRasterizeImage = true;
1746833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis              this.pictureAsCanvas_[picture.guid] =
1756833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis                  cc.PictureAsCanvas.Pending(this);
17666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              picture.rasterize(
17766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis                  {stopIndex: undefined},
1786833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis                  function(pictureAsCanvas) {
1796833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis                    var picture_ = pictureAsCanvas.picture;
1806833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis                    this.pictureAsCanvas_[picture_.guid] = pictureAsCanvas;
18166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis                    this.scheduleUpdateContents_();
18266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis                  }.bind(this));
18366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              continue;
18466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            }
1856833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis            if (pictureAsCanvas.isPending()) {
18666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              hasPendingRasterizeImage = true;
18766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              continue;
18866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            }
1896833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis            if (pictureAsCanvas.error) {
19066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              if (!firstPictureError)
1916833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis                firstPictureError = pictureAsCanvas.error;
19266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis              break;
19366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            }
19466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          }
19566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        }
19666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (hasPendingRasterizeImage)
19766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          return false;
19866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
19966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (hasUnresolvedPictureRef) {
20066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          messages.push({
20166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            header: 'Missing picture',
20266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            details: 'Your trace didnt have pictures for every layer. ' +
20366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis                'Old chrome versions had this problem'});
20466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        }
20566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (hasMissingLayerRect) {
20666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          messages.push({
20766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            header: 'Missing layer rect',
20866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            details: 'Your trace may be corrupt or from a very old ' +
20966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis                'Chrome revision.'});
21066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        }
21166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (firstPictureError) {
21266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          messages.push({
21366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            header: 'Cannot rasterize',
21466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            details: firstPictureError});
21566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        }
21666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      }
21766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.messages_ = messages;
21866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return true;
21966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
22066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
22166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    get selectedLayer() {
22266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (this.selection) {
22366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var selectedLayerId = this.selection.associatedLayerId;
22466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        return this.layerTreeImpl_.findLayerWithId(selectedLayerId);
22566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      }
22666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
22766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
22866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    get layers() {
22966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var layers = this.layerTreeImpl.renderSurfaceLayerList;
23066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (!this.showOtherLayers) {
23166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var selectedLayer = this.selectedLayer;
23266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (selectedLayer)
23366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          layers = [selectedLayer];
23466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      }
23566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return layers;
23666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
23766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
23866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    appendImageQuads_: function(layer, layerQuad) {
23966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      // Generate image quads for the layer
24066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      for (var ir = layer.pictures.length - 1; ir >= 0; ir--) {
24166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var picture = layer.pictures[ir];
24266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (!picture.layerRect)
24366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          continue;
24466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
24566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var unitRect = picture.layerRect.asUVRectInside(layer.bounds);
24666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var iq = layerQuad.projectUnitRect(unitRect);
24766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
2486833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis        var pictureAsCanvas = this.pictureAsCanvas_[picture.guid];
2496833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis        if (this.showContents && pictureAsCanvas.canvas)
2506833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis          iq.canvas = pictureAsCanvas.canvas;
25166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        else
2526833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis          iq.canvas = undefined;
25366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
25466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        iq.stackingGroupId = layerQuad.stackingGroupId;
25566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.quads_.push(iq);
25666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      }
25766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
25866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
25966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    appendInvalidationQuads_: function(layer, layerQuad) {
26066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      // Generate the invalidation rect quads.
26166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      for (var ir = 0; ir < layer.invalidation.rects.length; ir++) {
26266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var rect = layer.invalidation.rects[ir];
26366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var unitRect = rect.asUVRectInside(layer.bounds);
26466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var iq = layerQuad.projectUnitRect(unitRect);
26566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        iq.backgroundColor = 'rgba(255, 0, 0, 0.1)';
26666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        iq.borderColor = 'rgba(255, 0, 0, 1)';
26766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        iq.stackingGroupId = layerQuad.stackingGroupId;
26866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.quads_.push(iq);
26966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      }
27066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
27166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
27266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    appendSelectionQuads_: function(layer, layerQuad) {
27366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var selection = this.selection;
27466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var quad = this.layerTreeImpl_.whichTree == constants.ACTIVE_TREE ?
27566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          selection.quadIfActive : selection.quadIfPending;
27666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (!quad)
27766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        return [];
27866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
27966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var colorId = tracing.getStringColorId(selection.title);
28066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      colorId += tracing.getColorPaletteHighlightIdBoost();
28166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
28266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var color = base.Color.fromString(tracing.getColorPalette()[colorId]);
28366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
28466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var quadForDrawing = quad.clone();
28566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      quadForDrawing.backgroundColor = color.withAlpha(0.5).toString();
28666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      quadForDrawing.borderColor = color.withAlpha(1.0).darken().toString();
28766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      quadForDrawing.stackingGroupId = layerQuad.stackingGroupId;
28866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      return [quadForDrawing];
28966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
29066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
29166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    generateQuads_: function() {
29266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateContentsPending_ = false;
29366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
29466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      // Generate the quads for the view.
29566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var layers = this.layers;
29666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.quads_ = [];
29766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      for (var i = 0; i < layers.length; i++) {
29866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var layer = layers[i];
29966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
30066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        var layerQuad = layer.layerQuad.clone();
30166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        layerQuad.borderColor = 'rgba(0,0,0,0.75)';
30266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        layerQuad.stackingGroupId = i;
30366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (this.showOtherLayers && this.selectedLayer == layer)
30466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          layerQuad.upperBorderColor = 'rgb(156,189,45)';
30566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
30666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.appendImageQuads_(layer, layerQuad);
30766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
30866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (this.showInvalidations) {
30966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          this.appendInvalidationQuads_(layer, layerQuad);
31066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        }
31166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
31266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        // Push the layer quad last.
31366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.quads_.push(layerQuad);
31466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
31566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        if (this.selectedLayer === layer) {
31666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          this.appendSelectionQuads_(layer, layerQuad);
31766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        }
31866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      }
31966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var lthi = this.layerTreeImpl_.layerTreeHostImpl;
32066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var lthiInstance = lthi.objectInstance;
32166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      var worldViewportRect = base.Rect.FromXYWH(0, 0,
32266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          lthi.deviceViewportSize.width, lthi.deviceViewportSize.height);
32366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.quadStackViewer_.quadStack.initialize(
32466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          lthiInstance.allLayersBBox.asRect(), worldViewportRect);
32566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
32666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.quadStackViewer_.quadStack.quads = this.quads_;
32766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
32866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      this.updateInfoBar_(this.messages_);
32966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    },
33066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
33166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    updateInfoBar_: function(infoBarMessages) {
33266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      if (infoBarMessages.length) {
33366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.infoBar_.removeAllButtons();
33466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.infoBar_.message = 'Some problems were encountered...';
33566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.infoBar_.addButton('More info...', function() {
33666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          var overlay = new ui.Overlay();
33766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          overlay.textContent = '';
33866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          infoBarMessages.forEach(function(message) {
33966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            var title = document.createElement('h3');
34066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            title.textContent = message.header;
34166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
34266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            var details = document.createElement('div');
34366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            details.textContent = message.details;
34466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
34566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            overlay.appendChild(title);
34666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            overlay.appendChild(details);
34766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          });
34866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          overlay.visible = true;
34966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis          overlay.obeyCloseEvents = true;
35066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        });
35166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.infoBar_.visible = true;
35266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      } else {
35366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.infoBar_.removeAllButtons();
35466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.infoBar_.message = '';
35566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        this.infoBar_.visible = false;
35666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      }
35766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    }
35866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  };
35966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
36066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  return {
36166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    LayerTreeQuadStackViewer: LayerTreeQuadStackViewer
36266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  };
36366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis});
364