/*
 * Copyright (C) 2014 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * @implements {LayerViewer.LayerView}
 * @unrestricted
 */
export class Layers3DView extends UI.VBox {
  /**
   * @param {!LayerViewer.LayerViewHost} layerViewHost
   */
  constructor(layerViewHost) {
    super(true);
    this.registerRequiredCSS('layer_viewer/layers3DView.css');
    this.contentElement.classList.add('layers-3d-view');
    this._failBanner = new UI.VBox();
    this._failBanner.element.classList.add('full-widget-dimmed-banner');
    this._failBanner.element.createTextChild(Common.UIString('Layer information is not yet available.'));

    this._layerViewHost = layerViewHost;
    this._layerViewHost.registerView(this);

    this._transformController = new LayerViewer.TransformController(this.contentElement);
    this._transformController.addEventListener(
        LayerViewer.TransformController.Events.TransformChanged, this._update, this);
    this._initToolbar();

    this._canvasElement = this.contentElement.createChild('canvas');
    this._canvasElement.tabIndex = 0;
    this._canvasElement.addEventListener('dblclick', this._onDoubleClick.bind(this), false);
    this._canvasElement.addEventListener('mousedown', this._onMouseDown.bind(this), false);
    this._canvasElement.addEventListener('mouseup', this._onMouseUp.bind(this), false);
    this._canvasElement.addEventListener('mouseleave', this._onMouseMove.bind(this), false);
    this._canvasElement.addEventListener('mousemove', this._onMouseMove.bind(this), false);
    this._canvasElement.addEventListener('contextmenu', this._onContextMenu.bind(this), false);
    UI.ARIAUtils.setAccessibleName(this._canvasElement, ls`3D Layers View`);

    this._lastSelection = {};
    this._layerTree = null;

    this._textureManager = new LayerTextureManager(this._update.bind(this));

    /** @type Array.<!WebGLTexture|undefined> */
    this._chromeTextures = [];
    this._rects = [];

    /** @type Map<SDK.Layer, LayerViewer.LayerView.SnapshotSelection> */
    this._snapshotLayers = new Map();
    this._layerViewHost.setLayerSnapshotMap(this._snapshotLayers);

    this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update, this);
  }

  /**
   * @param {?SDK.LayerTreeBase} layerTree
   * @override
   */
  setLayerTree(layerTree) {
    this._layerTree = layerTree;
    this._layerTexture = null;
    delete this._oldTextureScale;
    if (this._showPaints()) {
      this._textureManager.setLayerTree(layerTree);
    }
    this._update();
  }

  /**
   * @param {!SDK.Layer} layer
   * @param {string=} imageURL
   */
  showImageForLayer(layer, imageURL) {
    if (!imageURL) {
      this._layerTexture = null;
      this._update();
      return;
    }
    UI.loadImage(imageURL).then(image => {
      const texture = image && LayerTextureManager._createTextureForImage(this._gl, image);
      this._layerTexture = texture ? {layer: layer, texture: texture} : null;
      this._update();
    });
  }

  /**
   * @override
   */
  onResize() {
    this._resizeCanvas();
    this._update();
  }

  /**
   * @override
   */
  willHide() {
    this._textureManager.suspend();
  }

  /**
   * @override
   */
  wasShown() {
    this._textureManager.resume();
    if (!this._needsUpdate) {
      return;
    }
    this._resizeCanvas();
    this._update();
  }

  /**
   * @param {!SDK.Layer} layer
   */
  updateLayerSnapshot(layer) {
    this._textureManager.layerNeedsUpdate(layer);
  }

  /**
   * @param {!LayerViewer.Layers3DView.OutlineType} type
   * @param {?LayerViewer.LayerView.Selection} selection
   */
  _setOutline(type, selection) {
    this._lastSelection[type] = selection;
    this._update();
  }

  /**
   * @param {?LayerViewer.LayerView.Selection} selection
   * @override
   */
  hoverObject(selection) {
    this._setOutline(OutlineType.Hovered, selection);
  }

  /**
   * @param {?LayerViewer.LayerView.Selection} selection
   * @override
   */
  selectObject(selection) {
    this._setOutline(OutlineType.Hovered, null);
    this._setOutline(OutlineType.Selected, selection);
  }

  /**
   * @param {!LayerViewer.LayerView.Selection} selection
   * @return {!Promise<?SDK.SnapshotWithRect>}
   */
  snapshotForSelection(selection) {
    if (selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot) {
      const snapshotWithRect = /** @type {!LayerViewer.LayerView.SnapshotSelection} */ (selection).snapshot();
      snapshotWithRect.snapshot.addReference();
      return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(snapshotWithRect));
    }
    if (selection.layer()) {
      const promise = selection.layer().snapshots()[0];
      if (promise) {
        return promise;
      }
    }
    return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(null));
  }

  /**
   * @param {!Element} canvas
   * @return {?WebGLRenderingContext}
   */
  _initGL(canvas) {
    const gl = canvas.getContext('webgl');
    if (!gl) {
      return null;
    }
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.enable(gl.BLEND);
    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    gl.enable(gl.DEPTH_TEST);
    return gl;
  }

  /**
   * @param {!Object} type
   * @param {string} script
   */
  _createShader(type, script) {
    const shader = this._gl.createShader(type);
    this._gl.shaderSource(shader, script);
    this._gl.compileShader(shader);
    this._gl.attachShader(this._shaderProgram, shader);
  }

  _initShaders() {
    this._shaderProgram = this._gl.createProgram();
    this._createShader(this._gl.FRAGMENT_SHADER, FragmentShader);
    this._createShader(this._gl.VERTEX_SHADER, VertexShader);
    this._gl.linkProgram(this._shaderProgram);
    this._gl.useProgram(this._shaderProgram);

    this._shaderProgram.vertexPositionAttribute = this._gl.getAttribLocation(this._shaderProgram, 'aVertexPosition');
    this._gl.enableVertexAttribArray(this._shaderProgram.vertexPositionAttribute);
    this._shaderProgram.vertexColorAttribute = this._gl.getAttribLocation(this._shaderProgram, 'aVertexColor');
    this._gl.enableVertexAttribArray(this._shaderProgram.vertexColorAttribute);
    this._shaderProgram.textureCoordAttribute = this._gl.getAttribLocation(this._shaderProgram, 'aTextureCoord');
    this._gl.enableVertexAttribArray(this._shaderProgram.textureCoordAttribute);

    this._shaderProgram.pMatrixUniform = this._gl.getUniformLocation(this._shaderProgram, 'uPMatrix');
    this._shaderProgram.samplerUniform = this._gl.getUniformLocation(this._shaderProgram, 'uSampler');
  }

  _resizeCanvas() {
    this._canvasElement.width = this._canvasElement.offsetWidth * window.devicePixelRatio;
    this._canvasElement.height = this._canvasElement.offsetHeight * window.devicePixelRatio;
  }

  _updateTransformAndConstraints() {
    const paddingFraction = 0.1;
    const viewport = this._layerTree.viewportSize();
    const baseWidth = viewport ? viewport.width : this._dimensionsForAutoscale.width;
    const baseHeight = viewport ? viewport.height : this._dimensionsForAutoscale.height;
    const canvasWidth = this._canvasElement.width;
    const canvasHeight = this._canvasElement.height;
    const paddingX = canvasWidth * paddingFraction;
    const paddingY = canvasHeight * paddingFraction;
    const scaleX = (canvasWidth - 2 * paddingX) / baseWidth;
    const scaleY = (canvasHeight - 2 * paddingY) / baseHeight;
    const viewScale = Math.min(scaleX, scaleY);
    const minScaleConstraint =
        Math.min(baseWidth / this._dimensionsForAutoscale.width, baseHeight / this._dimensionsForAutoscale.width) / 2;
    this._transformController.setScaleConstraints(
        minScaleConstraint,
        10 / viewScale);  // 1/viewScale is 1:1 in terms of pixels, so allow zooming to 10x of native size
    const scale = this._transformController.scale();
    const rotateX = this._transformController.rotateX();
    const rotateY = this._transformController.rotateY();

    this._scale = scale * viewScale;
    const textureScale = Number.constrain(this._scale, 0.1, 1);
    if (textureScale !== this._oldTextureScale) {
      this._oldTextureScale = textureScale;
      this._textureManager.setScale(textureScale);
      this.dispatchEventToListeners(Events.ScaleChanged, textureScale);
    }
    const scaleAndRotationMatrix = new WebKitCSSMatrix()
                                       .scale(scale, scale, scale)
                                       .translate(canvasWidth / 2, canvasHeight / 2, 0)
                                       .rotate(rotateX, rotateY, 0)
                                       .scale(viewScale, viewScale, viewScale)
                                       .translate(-baseWidth / 2, -baseHeight / 2, 0);

    let bounds;
    for (let i = 0; i < this._rects.length; ++i) {
      bounds = UI.Geometry.boundsForTransformedPoints(scaleAndRotationMatrix, this._rects[i].vertices, bounds);
    }

    this._transformController.clampOffsets(
        (paddingX - bounds.maxX) / window.devicePixelRatio,
        (canvasWidth - paddingX - bounds.minX) / window.devicePixelRatio,
        (paddingY - bounds.maxY) / window.devicePixelRatio,
        (canvasHeight - paddingY - bounds.minY) / window.devicePixelRatio);
    const offsetX = this._transformController.offsetX() * window.devicePixelRatio;
    const offsetY = this._transformController.offsetY() * window.devicePixelRatio;
    // Multiply to translation matrix on the right rather than translate (which would implicitly multiply on the left).
    this._projectionMatrix = new WebKitCSSMatrix().translate(offsetX, offsetY, 0).multiply(scaleAndRotationMatrix);

    const glProjectionMatrix = new WebKitCSSMatrix()
                                   .scale(1, -1, -1)
                                   .translate(-1, -1, 0)
                                   .scale(2 / this._canvasElement.width, 2 / this._canvasElement.height, 1 / 1000000)
                                   .multiply(this._projectionMatrix);
    this._gl.uniformMatrix4fv(this._shaderProgram.pMatrixUniform, false, this._arrayFromMatrix(glProjectionMatrix));
  }

  /**
   * @param {!CSSMatrix} m
   * @return {!Float32Array}
   */
  _arrayFromMatrix(m) {
    return new Float32Array([
      m.m11, m.m12, m.m13, m.m14, m.m21, m.m22, m.m23, m.m24, m.m31, m.m32, m.m33, m.m34, m.m41, m.m42, m.m43, m.m44
    ]);
  }

  _initWhiteTexture() {
    this._whiteTexture = this._gl.createTexture();
    this._gl.bindTexture(this._gl.TEXTURE_2D, this._whiteTexture);
    const whitePixel = new Uint8Array([255, 255, 255, 255]);
    this._gl.texImage2D(
        this._gl.TEXTURE_2D, 0, this._gl.RGBA, 1, 1, 0, this._gl.RGBA, this._gl.UNSIGNED_BYTE, whitePixel);
  }

  _initChromeTextures() {
    /**
     * @this {LayerViewer.Layers3DView}
     * @param {!LayerViewer.Layers3DView.ChromeTexture} index
     * @param {string} url
     */
    function loadChromeTexture(index, url) {
      UI.loadImage(url).then(image => {
        this._chromeTextures[index] = image && LayerTextureManager._createTextureForImage(this._gl, image) || undefined;
      });
    }
    loadChromeTexture.call(this, ChromeTexture.Left, 'Images/chromeLeft.png');
    loadChromeTexture.call(this, ChromeTexture.Middle, 'Images/chromeMiddle.png');
    loadChromeTexture.call(this, ChromeTexture.Right, 'Images/chromeRight.png');
  }

  /**
   * @return {?WebGLRenderingContext}
   */
  _initGLIfNecessary() {
    if (this._gl) {
      return this._gl;
    }
    this._gl = this._initGL(this._canvasElement);
    if (!this._gl) {
      return null;
    }
    this._initShaders();
    this._initWhiteTexture();
    this._initChromeTextures();
    this._textureManager.setContext(this._gl);
    return this._gl;
  }

  _calculateDepthsAndVisibility() {
    this._depthByLayerId = {};
    let depth = 0;
    const showInternalLayers = this._layerViewHost.showInternalLayersSetting().get();
    const root =
        showInternalLayers ? this._layerTree.root() : (this._layerTree.contentRoot() || this._layerTree.root());
    const queue = [root];
    this._depthByLayerId[root.id()] = 0;
    /** @type {!Set<!SDK.Layer>} */
    this._visibleLayers = new Set();
    while (queue.length > 0) {
      const layer = queue.shift();
      if (showInternalLayers || layer.drawsContent()) {
        this._visibleLayers.add(layer);
      }
      const children = layer.children();
      for (let i = 0; i < children.length; ++i) {
        this._depthByLayerId[children[i].id()] = ++depth;
        queue.push(children[i]);
      }
    }
    this._maxDepth = depth;
  }

  /**
   * @param {!SDK.Layer} layer
   * @return {number}
   */
  _depthForLayer(layer) {
    return this._depthByLayerId[layer.id()] * LayerSpacing;
  }

  /**
   * @param {!SDK.Layer} layer
   * @param {number} index
   * @return {number}
   */
  _calculateScrollRectDepth(layer, index) {
    return this._depthForLayer(layer) + index * ScrollRectSpacing + 1;
  }

  /**
   * @param {!SDK.Layer} layer
   */
  _updateDimensionsForAutoscale(layer) {
    // We don't want to be precise, but rather pick something least affected by
    // animationtransforms, so that we don't change scale too often. So let's
    // disregard transforms, scrolling and relative layer positioning and choose
    // the largest dimensions of all layers.
    this._dimensionsForAutoscale.width = Math.max(layer.width(), this._dimensionsForAutoscale.width);
    this._dimensionsForAutoscale.height = Math.max(layer.height(), this._dimensionsForAutoscale.height);
  }

  /**
   * @param {!SDK.Layer} layer
   */
  _calculateLayerRect(layer) {
    if (!this._visibleLayers.has(layer)) {
      return;
    }
    const selection = new LayerViewer.LayerView.LayerSelection(layer);
    const rect = new Rectangle(selection);
    rect.setVertices(layer.quad(), this._depthForLayer(layer));
    this._appendRect(rect);
    this._updateDimensionsForAutoscale(layer);
  }

  /**
   * @param {!LayerViewer.Layers3DView.Rectangle} rect
   */
  _appendRect(rect) {
    const selection = rect.relatedObject;
    const isSelected = LayerViewer.LayerView.Selection.isEqual(this._lastSelection[OutlineType.Selected], selection);
    const isHovered = LayerViewer.LayerView.Selection.isEqual(this._lastSelection[OutlineType.Hovered], selection);
    if (isSelected) {
      rect.borderColor = SelectedBorderColor;
    } else if (isHovered) {
      rect.borderColor = HoveredBorderColor;
      const fillColor = rect.fillColor || [255, 255, 255, 1];
      const maskColor = HoveredImageMaskColor;
      rect.fillColor = [
        fillColor[0] * maskColor[0] / 255, fillColor[1] * maskColor[1] / 255, fillColor[2] * maskColor[2] / 255,
        fillColor[3] * maskColor[3]
      ];
    } else {
      rect.borderColor = BorderColor;
    }
    rect.lineWidth = isSelected ? SelectedBorderWidth : BorderWidth;
    this._rects.push(rect);
  }

  /**
   * @param {!SDK.Layer} layer
   */
  _calculateLayerScrollRects(layer) {
    const scrollRects = layer.scrollRects();
    for (let i = 0; i < scrollRects.length; ++i) {
      const selection = new LayerViewer.LayerView.ScrollRectSelection(layer, i);
      const rect = new Rectangle(selection);
      rect.calculateVerticesFromRect(layer, scrollRects[i].rect, this._calculateScrollRectDepth(layer, i));
      rect.fillColor = ScrollRectBackgroundColor;
      this._appendRect(rect);
    }
  }

  /**
   * @param {!SDK.Layer} layer
   */
  _calculateLayerTileRects(layer) {
    const tiles = this._textureManager.tilesForLayer(layer);
    for (let i = 0; i < tiles.length; ++i) {
      const tile = tiles[i];
      if (!tile.texture) {
        continue;
      }
      const selection = new LayerViewer.LayerView.SnapshotSelection(layer, {rect: tile.rect, snapshot: tile.snapshot});
      const rect = new Rectangle(selection);
      if (!this._snapshotLayers.has(layer)) {
        this._snapshotLayers.set(layer, selection);
      }

      rect.calculateVerticesFromRect(layer, tile.rect, this._depthForLayer(layer) + 1);
      rect.texture = tile.texture;
      this._appendRect(rect);
    }
  }

  _calculateRects() {
    this._rects = [];
    this._snapshotLayers.clear();
    this._dimensionsForAutoscale = {width: 0, height: 0};
    this._layerTree.forEachLayer(this._calculateLayerRect.bind(this));

    if (this._showSlowScrollRectsSetting.get()) {
      this._layerTree.forEachLayer(this._calculateLayerScrollRects.bind(this));
    }

    if (this._layerTexture && this._visibleLayers.has(this._layerTexture.layer)) {
      const layer = this._layerTexture.layer;
      const selection = new LayerViewer.LayerView.LayerSelection(layer);
      const rect = new Rectangle(selection);
      rect.setVertices(layer.quad(), this._depthForLayer(layer));
      rect.texture = this._layerTexture.texture;
      this._appendRect(rect);
    } else if (this._showPaints()) {
      this._layerTree.forEachLayer(this._calculateLayerTileRects.bind(this));
    }
  }

  /**
   * @param {!Array.<number>} color
   * @return {!Array.<number>}
   */
  _makeColorsArray(color) {
    let colors = [];
    const normalizedColor = [color[0] / 255, color[1] / 255, color[2] / 255, color[3]];
    for (let i = 0; i < 4; i++) {
      colors = colors.concat(normalizedColor);
    }
    return colors;
  }

  /**
   * @param {!Object} attribute
   * @param {!Array.<number>} array
   * @param {number} length
   */
  _setVertexAttribute(attribute, array, length) {
    const gl = this._gl;
    const buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(array), gl.STATIC_DRAW);
    gl.vertexAttribPointer(attribute, length, gl.FLOAT, false, 0, 0);
  }

  /**
   * @param {!Array.<number>} vertices
   * @param {number} mode
   * @param {!Array.<number>=} color
   * @param {!Object=} texture
   */
  _drawRectangle(vertices, mode, color, texture) {
    const gl = this._gl;
    const white = [255, 255, 255, 1];
    color = color || white;
    this._setVertexAttribute(this._shaderProgram.vertexPositionAttribute, vertices, 3);
    this._setVertexAttribute(this._shaderProgram.textureCoordAttribute, [0, 1, 1, 1, 1, 0, 0, 0], 2);
    this._setVertexAttribute(this._shaderProgram.vertexColorAttribute, this._makeColorsArray(color), color.length);

    if (texture) {
      gl.activeTexture(gl.TEXTURE0);
      gl.bindTexture(gl.TEXTURE_2D, texture);
      gl.uniform1i(this._shaderProgram.samplerUniform, 0);
    } else {
      gl.bindTexture(gl.TEXTURE_2D, this._whiteTexture);
    }

    const numberOfVertices = vertices.length / 3;
    gl.drawArrays(mode, 0, numberOfVertices);
  }

  /**
   * @param {!Array.<number>} vertices
   * @param {!WebGLTexture} texture
   * @param {!Array.<number>=} color
   */
  _drawTexture(vertices, texture, color) {
    this._drawRectangle(vertices, this._gl.TRIANGLE_FAN, color, texture);
  }

  _drawViewportAndChrome() {
    const viewport = this._layerTree.viewportSize();
    if (!viewport) {
      return;
    }

    const drawChrome = !Common.moduleSetting('frameViewerHideChromeWindow').get() && this._chromeTextures.length >= 3 &&
        this._chromeTextures.indexOf(undefined) < 0;
    const z = (this._maxDepth + 1) * LayerSpacing;
    const borderWidth = Math.ceil(ViewportBorderWidth * this._scale);
    let vertices = [viewport.width, 0, z, viewport.width, viewport.height, z, 0, viewport.height, z, 0, 0, z];
    this._gl.lineWidth(borderWidth);
    this._drawRectangle(vertices, drawChrome ? this._gl.LINE_STRIP : this._gl.LINE_LOOP, ViewportBorderColor);

    if (!drawChrome) {
      return;
    }

    const borderAdjustment = ViewportBorderWidth / 2;
    const viewportWidth = this._layerTree.viewportSize().width + 2 * borderAdjustment;
    const chromeHeight = this._chromeTextures[0].image.naturalHeight;
    const middleFragmentWidth =
        viewportWidth - this._chromeTextures[0].image.naturalWidth - this._chromeTextures[2].image.naturalWidth;
    let x = -borderAdjustment;
    const y = -chromeHeight;
    for (let i = 0; i < this._chromeTextures.length; ++i) {
      const width = i === ChromeTexture.Middle ? middleFragmentWidth : this._chromeTextures[i].image.naturalWidth;
      if (width < 0 || x + width > viewportWidth) {
        break;
      }
      vertices = [x, y, z, x + width, y, z, x + width, y + chromeHeight, z, x, y + chromeHeight, z];
      this._drawTexture(vertices, /** @type {!WebGLTexture} */ (this._chromeTextures[i]));
      x += width;
    }
  }

  /**
   * @param {!LayerViewer.Layers3DView.Rectangle} rect
   */
  _drawViewRect(rect) {
    const vertices = rect.vertices;
    if (rect.texture) {
      this._drawTexture(vertices, rect.texture, rect.fillColor || undefined);
    } else if (rect.fillColor) {
      this._drawRectangle(vertices, this._gl.TRIANGLE_FAN, rect.fillColor);
    }
    this._gl.lineWidth(rect.lineWidth);
    if (rect.borderColor) {
      this._drawRectangle(vertices, this._gl.LINE_LOOP, rect.borderColor);
    }
  }

  _update() {
    if (!this.isShowing()) {
      this._needsUpdate = true;
      return;
    }
    if (!this._layerTree || !this._layerTree.root()) {
      this._failBanner.show(this.contentElement);
      return;
    }
    const gl = this._initGLIfNecessary();
    if (!gl) {
      this._failBanner.element.removeChildren();
      this._failBanner.element.appendChild(this._webglDisabledBanner());
      this._failBanner.show(this.contentElement);
      return;
    }
    this._failBanner.detach();
    this._gl.viewportWidth = this._canvasElement.width;
    this._gl.viewportHeight = this._canvasElement.height;

    this._calculateDepthsAndVisibility();
    this._calculateRects();
    this._updateTransformAndConstraints();

    gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    this._rects.forEach(this._drawViewRect.bind(this));
    this._drawViewportAndChrome();
  }

  /**
   * @return {!Node}
   */
  _webglDisabledBanner() {
    const fragment = this.contentElement.ownerDocument.createDocumentFragment();
    fragment.createChild('div').textContent = Common.UIString('Can\'t display layers,');
    fragment.createChild('div').textContent = Common.UIString('WebGL support is disabled in your browser.');
    fragment.appendChild(UI.formatLocalized('Check %s for possible reasons.', [UI.XLink.create('about:gpu')]));
    return fragment;
  }

  /**
   * @param {!Event} event
   * @return {?LayerViewer.LayerView.Selection}
   */
  _selectionFromEventPoint(event) {
    if (!this._layerTree) {
      return null;
    }
    let closestIntersectionPoint = Infinity;
    let closestObject = null;
    const projectionMatrix =
        new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0).multiply(this._projectionMatrix);
    const x0 = (event.clientX - this._canvasElement.totalOffsetLeft()) * window.devicePixelRatio;
    const y0 = -(event.clientY - this._canvasElement.totalOffsetTop()) * window.devicePixelRatio;

    /**
     * @param {!LayerViewer.Layers3DView.Rectangle} rect
     */
    function checkIntersection(rect) {
      if (!rect.relatedObject) {
        return;
      }
      const t = rect.intersectWithLine(projectionMatrix, x0, y0);
      if (t < closestIntersectionPoint) {
        closestIntersectionPoint = t;
        closestObject = rect.relatedObject;
      }
    }

    this._rects.forEach(checkIntersection);
    return closestObject;
  }

  /**
   * @param {string} caption
   * @param {string} name
   * @param {boolean} value
   * @param {!UI.Toolbar} toolbar
   * @return {!Common.Setting}
   */
  _createVisibilitySetting(caption, name, value, toolbar) {
    const setting = Common.settings.createSetting(name, value);
    setting.setTitle(Common.UIString(caption));
    setting.addChangeListener(this._update, this);
    toolbar.appendToolbarItem(new UI.ToolbarSettingCheckbox(setting));
    return setting;
  }

  _initToolbar() {
    this._panelToolbar = this._transformController.toolbar();
    this.contentElement.appendChild(this._panelToolbar.element);
    this._showSlowScrollRectsSetting = this._createVisibilitySetting(
        ls`Slow scroll rects`, 'frameViewerShowSlowScrollRects', true, this._panelToolbar);
    this._showPaintsSetting =
        this._createVisibilitySetting(ls`Paints`, 'frameViewerShowPaints', true, this._panelToolbar);
    this._showPaintsSetting.addChangeListener(this._updatePaints, this);
    Common.moduleSetting('frameViewerHideChromeWindow').addChangeListener(this._update, this);
  }

  /**
   * @param {!Event} event
   */
  _onContextMenu(event) {
    const contextMenu = new UI.ContextMenu(event);
    contextMenu.defaultSection().appendItem(
        Common.UIString('Reset View'), this._transformController.resetAndNotify.bind(this._transformController), false);
    const selection = this._selectionFromEventPoint(event);
    if (selection && selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot) {
      contextMenu.defaultSection().appendItem(
          Common.UIString('Show Paint Profiler'),
          this.dispatchEventToListeners.bind(this, Events.PaintProfilerRequested, selection), false);
    }
    this._layerViewHost.showContextMenu(contextMenu, selection);
  }

  /**
   * @param {!Event} event
   */
  _onMouseMove(event) {
    if (event.which) {
      return;
    }
    this._layerViewHost.hoverObject(this._selectionFromEventPoint(event));
  }

  /**
   * @param {!Event} event
   */
  _onMouseDown(event) {
    this._mouseDownX = event.clientX;
    this._mouseDownY = event.clientY;
  }

  /**
   * @param {!Event} event
   */
  _onMouseUp(event) {
    const maxDistanceInPixels = 6;
    if (this._mouseDownX && Math.abs(event.clientX - this._mouseDownX) < maxDistanceInPixels &&
        Math.abs(event.clientY - this._mouseDownY) < maxDistanceInPixels) {
      this._layerViewHost.selectObject(this._selectionFromEventPoint(event));
    }
    delete this._mouseDownX;
    delete this._mouseDownY;
  }

  /**
   * @param {!Event} event
   */
  _onDoubleClick(event) {
    const selection = this._selectionFromEventPoint(event);
    if (selection && (selection.type() === LayerViewer.LayerView.Selection.Type.Snapshot || selection.layer())) {
      this.dispatchEventToListeners(Events.PaintProfilerRequested, selection);
    }
    event.stopPropagation();
  }

  _updatePaints() {
    if (this._showPaints()) {
      this._textureManager.setLayerTree(this._layerTree);
      this._textureManager.forceUpdate();
    } else {
      this._textureManager.reset();
    }
    this._update();
  }

  /**
   * @return {boolean}
   */
  _showPaints() {
    return this._showPaintsSetting.get();
  }
}

/**
 * @enum {string}
 */
export const OutlineType = {
  Hovered: 'hovered',
  Selected: 'selected'
};

/** @enum {symbol} */
export const Events = {
  PaintProfilerRequested: Symbol('PaintProfilerRequested'),
  ScaleChanged: Symbol('ScaleChanged')
};

/**
 * @enum {number}
 */
export const ChromeTexture = {
  Left: 0,
  Middle: 1,
  Right: 2
};

/**
 * @enum {string}
 */
export const ScrollRectTitles = {
  RepaintsOnScroll: Common.UIString('repaints on scroll'),
  TouchEventHandler: Common.UIString('touch event listener'),
  WheelEventHandler: Common.UIString('mousewheel event listener')
};

export const FragmentShader = '' +
    'precision mediump float;\n' +
    'varying vec4 vColor;\n' +
    'varying vec2 vTextureCoord;\n' +
    'uniform sampler2D uSampler;\n' +
    'void main(void)\n' +
    '{\n' +
    '    gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;\n' +
    '}';

export const VertexShader = '' +
    'attribute vec3 aVertexPosition;\n' +
    'attribute vec2 aTextureCoord;\n' +
    'attribute vec4 aVertexColor;\n' +
    'uniform mat4 uPMatrix;\n' +
    'varying vec2 vTextureCoord;\n' +
    'varying vec4 vColor;\n' +
    'void main(void)\n' +
    '{\n' +
    'gl_Position = uPMatrix * vec4(aVertexPosition, 1.0);\n' +
    'vColor = aVertexColor;\n' +
    'vTextureCoord = aTextureCoord;\n' +
    '}';

export const HoveredBorderColor = [0, 0, 255, 1];
export const SelectedBorderColor = [0, 255, 0, 1];
export const BorderColor = [0, 0, 0, 1];
export const ViewportBorderColor = [160, 160, 160, 1];
export const ScrollRectBackgroundColor = [178, 100, 100, 0.6];
export const HoveredImageMaskColor = [200, 200, 255, 1];
export const BorderWidth = 1;
export const SelectedBorderWidth = 2;
export const ViewportBorderWidth = 3;

export const LayerSpacing = 20;
export const ScrollRectSpacing = 4;

/**
 * @unrestricted
 */
export class LayerTextureManager {
  /**
   * @param {function()} textureUpdatedCallback
   */
  constructor(textureUpdatedCallback) {
    this._textureUpdatedCallback = textureUpdatedCallback;
    this._throttler = new Common.Throttler(0);
    this._scale = 0;
    this._active = false;
    this.reset();
  }

  /**
   * @param {!Image} image
   * @param {!WebGLRenderingContext} gl
   * @return {!WebGLTexture} texture
   */
  static _createTextureForImage(gl, image) {
    const texture = gl.createTexture();
    texture.image = image;
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.bindTexture(gl.TEXTURE_2D, null);
    return texture;
  }

  reset() {
    if (this._tilesByLayer) {
      this.setLayerTree(null);
    }

    /** @type {!Map<!SDK.Layer, !Array<!LayerViewer.LayerTextureManager.Tile>>} */
    this._tilesByLayer = new Map();
    /** @type {!Array<!SDK.Layer>} */
    this._queue = [];
  }

  /**
   * @param {!WebGLRenderingContext} glContext
   */
  setContext(glContext) {
    this._gl = glContext;
    if (this._scale) {
      this._updateTextures();
    }
  }

  suspend() {
    this._active = false;
  }

  resume() {
    this._active = true;
    if (this._queue.length) {
      this._update();
    }
  }

  /**
   * @param {?SDK.LayerTreeBase} layerTree
   */
  setLayerTree(layerTree) {
    const newLayers = new Set();
    const oldLayers = Array.from(this._tilesByLayer.keys());
    if (layerTree) {
      layerTree.forEachLayer(layer => {
        if (!layer.drawsContent()) {
          return;
        }
        newLayers.add(layer);
        if (!this._tilesByLayer.has(layer)) {
          this._tilesByLayer.set(layer, []);
          this.layerNeedsUpdate(layer);
        }
      });
    }
    if (!oldLayers.length) {
      this.forceUpdate();
    }
    for (const layer of oldLayers) {
      if (newLayers.has(layer)) {
        continue;
      }
      this._tilesByLayer.get(layer).forEach(tile => tile.dispose());
      this._tilesByLayer.delete(layer);
    }
  }

  /**
   * @param {!SDK.Layer} layer
   * @param {!Array<!SDK.SnapshotWithRect>} snapshots
   * @return {!Promise}
   */
  _setSnapshotsForLayer(layer, snapshots) {
    const oldSnapshotsToTiles = new Map((this._tilesByLayer.get(layer) || []).map(tile => [tile.snapshot, tile]));
    const newTiles = [];
    const reusedTiles = [];
    for (const snapshot of snapshots) {
      const oldTile = oldSnapshotsToTiles.get(snapshot);
      if (oldTile) {
        reusedTiles.push(oldTile);
        oldSnapshotsToTiles.delete(oldTile);
      } else {
        newTiles.push(new Tile(snapshot));
      }
    }
    this._tilesByLayer.set(layer, reusedTiles.concat(newTiles));
    for (const tile of oldSnapshotsToTiles.values()) {
      tile.dispose();
    }
    if (!this._gl || !this._scale) {
      return Promise.resolve();
    }
    return Promise.all(newTiles.map(tile => tile.update(this._gl, this._scale))).then(this._textureUpdatedCallback);
  }

  /**
   * @param {number} scale
   */
  setScale(scale) {
    if (this._scale && this._scale >= scale) {
      return;
    }
    this._scale = scale;
    this._updateTextures();
  }

  /**
   * @param {!SDK.Layer} layer
   * @return {!Array<!LayerViewer.LayerTextureManager.Tile>}
   */
  tilesForLayer(layer) {
    return this._tilesByLayer.get(layer) || [];
  }

  /**
   * @param {!SDK.Layer} layer
   */
  layerNeedsUpdate(layer) {
    if (this._queue.indexOf(layer) < 0) {
      this._queue.push(layer);
    }
    if (this._active) {
      this._throttler.schedule(this._update.bind(this));
    }
  }

  forceUpdate() {
    this._queue.forEach(layer => this._updateLayer(layer));
    this._queue = [];
    this._update();
  }

  /**
   * @return {!Promise}
   */
  _update() {
    const layer = this._queue.shift();
    if (!layer) {
      return Promise.resolve();
    }
    if (this._queue.length) {
      this._throttler.schedule(this._update.bind(this));
    }
    return this._updateLayer(layer);
  }

  /**
   * @param {!SDK.Layer} layer
   * @return {!Promise}
   */
  _updateLayer(layer) {
    return Promise.all(layer.snapshots())
        .then(snapshots => this._setSnapshotsForLayer(layer, snapshots.filter(snapshot => !!snapshot)));
  }

  _updateTextures() {
    if (!this._gl) {
      return;
    }
    if (!this._scale) {
      return;
    }

    for (const tiles of this._tilesByLayer.values()) {
      for (const tile of tiles) {
        const promise = tile.updateScale(this._gl, this._scale);
        if (promise) {
          promise.then(this._textureUpdatedCallback);
        }
      }
    }
  }
}

/**
 * @unrestricted
 */
export class Rectangle {
  /**
   * @param {?LayerViewer.LayerView.Selection} relatedObject
   */
  constructor(relatedObject) {
    this.relatedObject = relatedObject;
    /** @type {number} */
    this.lineWidth = 1;
    /** @type {?Array.<number>} */
    this.borderColor = null;
    /** @type {?Array.<number>} */
    this.fillColor = null;
    /** @type {?WebGLTexture} */
    this.texture = null;
  }

  /**
   * @param {!Array.<number>} quad
   * @param {number} z
   */
  setVertices(quad, z) {
    this.vertices = [quad[0], quad[1], z, quad[2], quad[3], z, quad[4], quad[5], z, quad[6], quad[7], z];
  }

  /**
   * Finds coordinates of point on layer quad, having offsets (ratioX * width) and (ratioY * height)
   * from the left corner of the initial layer rect, where width and heigth are layer bounds.
   * @param {!Array.<number>} quad
   * @param {number} ratioX
   * @param {number} ratioY
   * @return {!Array.<number>}
   */
  _calculatePointOnQuad(quad, ratioX, ratioY) {
    const x0 = quad[0];
    const y0 = quad[1];
    const x1 = quad[2];
    const y1 = quad[3];
    const x2 = quad[4];
    const y2 = quad[5];
    const x3 = quad[6];
    const y3 = quad[7];
    // Point on the first quad side clockwise
    const firstSidePointX = x0 + ratioX * (x1 - x0);
    const firstSidePointY = y0 + ratioX * (y1 - y0);
    // Point on the third quad side clockwise
    const thirdSidePointX = x3 + ratioX * (x2 - x3);
    const thirdSidePointY = y3 + ratioX * (y2 - y3);
    const x = firstSidePointX + ratioY * (thirdSidePointX - firstSidePointX);
    const y = firstSidePointY + ratioY * (thirdSidePointY - firstSidePointY);
    return [x, y];
  }

  /**
   * @param {!SDK.Layer} layer
   * @param {!Protocol.DOM.Rect} rect
   * @param {number} z
   */
  calculateVerticesFromRect(layer, rect, z) {
    const quad = layer.quad();
    const rx1 = rect.x / layer.width();
    const rx2 = (rect.x + rect.width) / layer.width();
    const ry1 = rect.y / layer.height();
    const ry2 = (rect.y + rect.height) / layer.height();
    const rectQuad = this._calculatePointOnQuad(quad, rx1, ry1)
                         .concat(this._calculatePointOnQuad(quad, rx2, ry1))
                         .concat(this._calculatePointOnQuad(quad, rx2, ry2))
                         .concat(this._calculatePointOnQuad(quad, rx1, ry2));
    this.setVertices(rectQuad, z);
  }

  /**
   * Intersects quad with given transform matrix and line l(t) = (x0, y0, t)
   * @param {!CSSMatrix} matrix
   * @param {number} x0
   * @param {number} y0
   * @return {(number|undefined)}
   */
  intersectWithLine(matrix, x0, y0) {
    let i;
    // Vertices of the quad with transform matrix applied
    const points = [];
    for (i = 0; i < 4; ++i) {
      points[i] = UI.Geometry.multiplyVectorByMatrixAndNormalize(
          new UI.Geometry.Vector(this.vertices[i * 3], this.vertices[i * 3 + 1], this.vertices[i * 3 + 2]), matrix);
    }
    // Calculating quad plane normal
    const normal = UI.Geometry.crossProduct(
        UI.Geometry.subtract(points[1], points[0]), UI.Geometry.subtract(points[2], points[1]));
    // General form of the equation of the quad plane: A * x + B * y + C * z + D = 0
    const A = normal.x;
    const B = normal.y;
    const C = normal.z;
    const D = -(A * points[0].x + B * points[0].y + C * points[0].z);
    // Finding t from the equation
    const t = -(D + A * x0 + B * y0) / C;
    // Point of the intersection
    const pt = new UI.Geometry.Vector(x0, y0, t);
    // Vectors from the intersection point to vertices of the quad
    const tVects = points.map(UI.Geometry.subtract.bind(null, pt));
    // Intersection point lies inside of the polygon if scalar products of normal of the plane and
    // cross products of successive tVects are all nonstrictly above or all nonstrictly below zero
    for (i = 0; i < tVects.length; ++i) {
      const product =
          UI.Geometry.scalarProduct(normal, UI.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
      if (product < 0) {
        return undefined;
      }
    }
    return t;
  }
}

/**
 * @unrestricted
 */
export class Tile {
  /**
   * @param {!SDK.SnapshotWithRect} snapshotWithRect
   */
  constructor(snapshotWithRect) {
    this.snapshot = snapshotWithRect.snapshot;
    this.rect = snapshotWithRect.rect;
    this.scale = 0;
    /** @type {?WebGLTexture} */
    this.texture = null;
  }

  dispose() {
    this.snapshot.release();
    if (this.texture) {
      this._gl.deleteTexture(this.texture);
      this.texture = null;
    }
  }

  /**
   * @param {!WebGLRenderingContext} glContext
   * @param {number} scale
   * @return {?Promise}
   */
  updateScale(glContext, scale) {
    if (this.texture && this.scale >= scale) {
      return null;
    }
    return this.update(glContext, scale);
  }

  /**
   * @param {!WebGLRenderingContext} glContext
   * @param {number} scale
   * @return {!Promise}
   */
  async update(glContext, scale) {
    this._gl = glContext;
    this.scale = scale;
    const imageURL = await this.snapshot.replay(scale);
    const image = imageURL ? await UI.loadImage(imageURL) : null;
    this.texture = image ? LayerTextureManager._createTextureForImage(glContext, image) : null;
  }
}

/* Legacy exported object */
self.LayerViewer = self.LayerViewer || {};

/* Legacy exported object */
LayerViewer = LayerViewer || {};

/**
 * @constructor
 */
LayerViewer.Layers3DView = Layers3DView;

/** @typedef {{borderColor: !Array<number>, borderWidth: number}} */
LayerViewer.Layers3DView.LayerStyle;

/**
 * @enum {string}
 */
LayerViewer.Layers3DView.OutlineType = OutlineType;

/**
 * @enum {symbol}
 */
LayerViewer.Layers3DView.Events = Events;

/**
 * @enum {number}
 */
LayerViewer.Layers3DView.ChromeTexture = ChromeTexture;

/**
 * @enum {string}
 */
LayerViewer.Layers3DView.ScrollRectTitles = ScrollRectTitles;

LayerViewer.Layers3DView.FragmentShader = FragmentShader;
LayerViewer.Layers3DView.VertexShader = VertexShader;

LayerViewer.Layers3DView.HoveredBorderColor = HoveredBorderColor;
LayerViewer.Layers3DView.SelectedBorderColor = SelectedBorderColor;
LayerViewer.Layers3DView.BorderColor = BorderColor;
LayerViewer.Layers3DView.ViewportBorderColor = ViewportBorderColor;
LayerViewer.Layers3DView.ScrollRectBackgroundColor = ScrollRectBackgroundColor;
LayerViewer.Layers3DView.HoveredImageMaskColor = HoveredImageMaskColor;
LayerViewer.Layers3DView.BorderWidth = BorderWidth;

LayerViewer.Layers3DView.SelectedBorderWidth = SelectedBorderWidth;
LayerViewer.Layers3DView.ViewportBorderWidth = ViewportBorderWidth;

LayerViewer.Layers3DView.LayerSpacing = LayerSpacing;
LayerViewer.Layers3DView.ScrollRectSpacing = ScrollRectSpacing;

/**
 * @constructor
 */
LayerViewer.Layers3DView.Rectangle = Rectangle;

/**
 * @constructor
 */
LayerViewer.LayerTextureManager = LayerTextureManager;

/**
 * @constructor
 */
LayerViewer.LayerTextureManager.Tile = Tile;
