Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(610)

Unified Diff: third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js
diff --git a/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js b/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js
index dd732f287b572d585166798a705e5debb1c64d07..b21772bd822be71d417d8126955648ec7f235695 100644
--- a/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js
+++ b/third_party/WebKit/Source/devtools/front_end/layer_viewer/Layers3DView.js
@@ -27,37 +27,38 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
/**
- * @constructor
- * @extends {WebInspector.VBox}
- * @param {!WebInspector.LayerViewHost} layerViewHost
* @implements {WebInspector.LayerView}
+ * @unrestricted
*/
-WebInspector.Layers3DView = function(layerViewHost)
-{
- WebInspector.VBox.call(this, true);
- this.registerRequiredCSS("layer_viewer/layers3DView.css");
- this.contentElement.classList.add("layers-3d-view");
+WebInspector.Layers3DView = class extends WebInspector.VBox {
+ /**
+ * @param {!WebInspector.LayerViewHost} layerViewHost
+ */
+ constructor(layerViewHost) {
+ super(true);
+ this.registerRequiredCSS('layer_viewer/layers3DView.css');
+ this.contentElement.classList.add('layers-3d-view');
this._failBanner = new WebInspector.VBox();
- this._failBanner.element.classList.add("full-widget-dimmed-banner");
- this._failBanner.element.createTextChild(WebInspector.UIString("Layer information is not yet available."));
+ this._failBanner.element.classList.add('full-widget-dimmed-banner');
+ this._failBanner.element.createTextChild(WebInspector.UIString('Layer information is not yet available.'));
this._layerViewHost = layerViewHost;
this._layerViewHost.registerView(this);
this._transformController = new WebInspector.TransformController(this.contentElement);
- this._transformController.addEventListener(WebInspector.TransformController.Events.TransformChanged, this._update, this);
+ this._transformController.addEventListener(
+ WebInspector.TransformController.Events.TransformChanged, this._update, this);
this._initToolbar();
- this._canvasElement = this.contentElement.createChild("canvas");
+ 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);
+ 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);
this._lastSelection = {};
this._layerTree = null;
@@ -69,6 +70,697 @@ WebInspector.Layers3DView = function(layerViewHost)
this._rects = [];
this._layerViewHost.showInternalLayersSetting().addChangeListener(this._update, this);
+ }
+
+ /**
+ * @param {?WebInspector.LayerTreeBase} layerTree
+ * @override
+ */
+ setLayerTree(layerTree) {
+ this._layerTree = layerTree;
+ this._layerTexture = null;
+ delete this._oldTextureScale;
+ if (this._showPaints())
+ this._textureManager.setLayerTree(layerTree);
+ this._update();
+ }
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {string=} imageURL
+ */
+ showImageForLayer(layer, imageURL) {
+ if (!imageURL) {
+ this._layerTexture = null;
+ this._update();
+ return;
+ }
+ WebInspector.loadImage(imageURL).then(image => {
+ var texture = image && WebInspector.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 {!WebInspector.Layer} layer
+ */
+ updateLayerSnapshot(layer) {
+ this._textureManager.layerNeedsUpdate(layer);
+ }
+
+ /**
+ * @param {!WebInspector.Layers3DView.OutlineType} type
+ * @param {?WebInspector.LayerView.Selection} selection
+ */
+ _setOutline(type, selection) {
+ this._lastSelection[type] = selection;
+ this._update();
+ }
+
+ /**
+ * @param {?WebInspector.LayerView.Selection} selection
+ * @override
+ */
+ hoverObject(selection) {
+ this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, selection);
+ }
+
+ /**
+ * @param {?WebInspector.LayerView.Selection} selection
+ * @override
+ */
+ selectObject(selection) {
+ this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, null);
+ this._setOutline(WebInspector.Layers3DView.OutlineType.Selected, selection);
+ }
+
+ /**
+ * @param {!WebInspector.LayerView.Selection} selection
+ * @return {!Promise<?WebInspector.SnapshotWithRect>}
+ */
+ snapshotForSelection(selection) {
+ if (selection.type() === WebInspector.LayerView.Selection.Type.Snapshot) {
+ var snapshotWithRect = /** @type {!WebInspector.LayerView.SnapshotSelection} */ (selection).snapshot();
+ snapshotWithRect.snapshot.addReference();
+ return /** @type {!Promise<?WebInspector.SnapshotWithRect>} */ (Promise.resolve(snapshotWithRect));
+ }
+ if (selection.layer()) {
+ var promise = selection.layer().snapshots()[0];
+ if (promise)
+ return promise;
+ }
+ return /** @type {!Promise<?WebInspector.SnapshotWithRect>} */ (Promise.resolve(null));
+ }
+
+ /**
+ * @param {!Element} canvas
+ * @return {?WebGLRenderingContext}
+ */
+ _initGL(canvas) {
+ var 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) {
+ var 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, WebInspector.Layers3DView.FragmentShader);
+ this._createShader(this._gl.VERTEX_SHADER, WebInspector.Layers3DView.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() {
+ var paddingFraction = 0.1;
+ var viewport = this._layerTree.viewportSize();
+ var root = this._layerTree.root();
+ var baseWidth = viewport ? viewport.width : this._dimensionsForAutoscale.width;
+ var baseHeight = viewport ? viewport.height : this._dimensionsForAutoscale.height;
+ var canvasWidth = this._canvasElement.width;
+ var canvasHeight = this._canvasElement.height;
+ var paddingX = canvasWidth * paddingFraction;
+ var paddingY = canvasHeight * paddingFraction;
+ var scaleX = (canvasWidth - 2 * paddingX) / baseWidth;
+ var scaleY = (canvasHeight - 2 * paddingY) / baseHeight;
+ var viewScale = Math.min(scaleX, scaleY);
+ var 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
+ var scale = this._transformController.scale();
+ var rotateX = this._transformController.rotateX();
+ var rotateY = this._transformController.rotateY();
+
+ this._scale = scale * viewScale;
+ var textureScale = Number.constrain(this._scale, 0.1, 1);
+ if (textureScale !== this._oldTextureScale) {
+ this._oldTextureScale = textureScale;
+ this._textureManager.setScale(textureScale);
+ this.dispatchEventToListeners(WebInspector.Layers3DView.Events.ScaleChanged, textureScale);
+ }
+ var 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);
+
+ var bounds;
+ for (var i = 0; i < this._rects.length; ++i)
+ bounds =
+ WebInspector.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);
+ var offsetX = this._transformController.offsetX() * window.devicePixelRatio;
+ var 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);
+
+ var 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);
+ var 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 {WebInspector.Layers3DView}
+ * @param {!WebInspector.Layers3DView.ChromeTexture} index
+ * @param {string} url
+ */
+ function loadChromeTexture(index, url) {
+ WebInspector.loadImage(url).then(image => {
+ this._chromeTextures[index] =
+ image && WebInspector.LayerTextureManager._createTextureForImage(this._gl, image) || undefined;
+ });
+ }
+ loadChromeTexture.call(this, WebInspector.Layers3DView.ChromeTexture.Left, 'Images/chromeLeft.png');
+ loadChromeTexture.call(this, WebInspector.Layers3DView.ChromeTexture.Middle, 'Images/chromeMiddle.png');
+ loadChromeTexture.call(this, WebInspector.Layers3DView.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 = {};
+ var depth = 0;
+ var showInternalLayers = this._layerViewHost.showInternalLayersSetting().get();
+ var root = showInternalLayers ? this._layerTree.root() : (this._layerTree.contentRoot() || this._layerTree.root());
+ var queue = [root];
+ this._depthByLayerId[root.id()] = 0;
+ /** @type {!Set<!WebInspector.Layer>} */
+ this._visibleLayers = new Set();
+ while (queue.length > 0) {
+ var layer = queue.shift();
+ if (showInternalLayers || layer.drawsContent())
+ this._visibleLayers.add(layer);
+ var children = layer.children();
+ for (var i = 0; i < children.length; ++i) {
+ this._depthByLayerId[children[i].id()] = ++depth;
+ queue.push(children[i]);
+ }
+ }
+ this._maxDepth = depth;
+ }
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @return {number}
+ */
+ _depthForLayer(layer) {
+ return this._depthByLayerId[layer.id()] * WebInspector.Layers3DView.LayerSpacing;
+ }
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {number} index
+ * @return {number}
+ */
+ _calculateScrollRectDepth(layer, index) {
+ return this._depthForLayer(layer) + index * WebInspector.Layers3DView.ScrollRectSpacing + 1;
+ }
+
+ /**
+ * @param {!WebInspector.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 {!WebInspector.Layer} layer
+ */
+ _calculateLayerRect(layer) {
+ if (!this._visibleLayers.has(layer))
+ return;
+ var selection = new WebInspector.LayerView.LayerSelection(layer);
+ var rect = new WebInspector.Layers3DView.Rectangle(selection);
+ rect.setVertices(layer.quad(), this._depthForLayer(layer));
+ this._appendRect(rect);
+ this._updateDimensionsForAutoscale(layer);
+ }
+
+ /**
+ * @param {!WebInspector.Layers3DView.Rectangle} rect
+ */
+ _appendRect(rect) {
+ var selection = rect.relatedObject;
+ var isSelected = WebInspector.LayerView.Selection.isEqual(
+ this._lastSelection[WebInspector.Layers3DView.OutlineType.Selected], selection);
+ var isHovered = WebInspector.LayerView.Selection.isEqual(
+ this._lastSelection[WebInspector.Layers3DView.OutlineType.Hovered], selection);
+ if (isSelected) {
+ rect.borderColor = WebInspector.Layers3DView.SelectedBorderColor;
+ } else if (isHovered) {
+ rect.borderColor = WebInspector.Layers3DView.HoveredBorderColor;
+ var fillColor = rect.fillColor || [255, 255, 255, 1];
+ var maskColor = WebInspector.Layers3DView.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 = WebInspector.Layers3DView.BorderColor;
+ }
+ rect.lineWidth = isSelected ? WebInspector.Layers3DView.SelectedBorderWidth : WebInspector.Layers3DView.BorderWidth;
+ this._rects.push(rect);
+ }
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ */
+ _calculateLayerScrollRects(layer) {
+ var scrollRects = layer.scrollRects();
+ for (var i = 0; i < scrollRects.length; ++i) {
+ var selection = new WebInspector.LayerView.ScrollRectSelection(layer, i);
+ var rect = new WebInspector.Layers3DView.Rectangle(selection);
+ rect.calculateVerticesFromRect(layer, scrollRects[i].rect, this._calculateScrollRectDepth(layer, i));
+ rect.fillColor = WebInspector.Layers3DView.ScrollRectBackgroundColor;
+ this._appendRect(rect);
+ }
+ }
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ */
+ _calculateLayerTileRects(layer) {
+ var tiles = this._textureManager.tilesForLayer(layer);
+ for (var i = 0; i < tiles.length; ++i) {
+ var tile = tiles[i];
+ if (!tile.texture)
+ continue;
+ var selection = new WebInspector.LayerView.SnapshotSelection(layer, {rect: tile.rect, snapshot: tile.snapshot});
+ var rect = new WebInspector.Layers3DView.Rectangle(selection);
+ rect.calculateVerticesFromRect(layer, tile.rect, this._depthForLayer(layer) + 1);
+ rect.texture = tile.texture;
+ this._appendRect(rect);
+ }
+ }
+
+ _calculateRects() {
+ this._rects = [];
+ 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)) {
+ var layer = this._layerTexture.layer;
+ var selection = new WebInspector.LayerView.LayerSelection(layer);
+ var rect = new WebInspector.Layers3DView.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) {
+ var colors = [];
+ var normalizedColor = [color[0] / 255, color[1] / 255, color[2] / 255, color[3]];
+ for (var 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) {
+ var gl = this._gl;
+ var 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) {
+ var gl = this._gl;
+ var 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);
+ }
+
+ var 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() {
+ var viewport = this._layerTree.viewportSize();
+ if (!viewport)
+ return;
+
+ var drawChrome = !WebInspector.moduleSetting('frameViewerHideChromeWindow').get() &&
+ this._chromeTextures.length >= 3 && this._chromeTextures.indexOf(undefined) < 0;
+ var z = (this._maxDepth + 1) * WebInspector.Layers3DView.LayerSpacing;
+ var borderWidth = Math.ceil(WebInspector.Layers3DView.ViewportBorderWidth * this._scale);
+ var 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, WebInspector.Layers3DView.ViewportBorderColor);
+
+ if (!drawChrome)
+ return;
+
+ var borderAdjustment = WebInspector.Layers3DView.ViewportBorderWidth / 2;
+ var viewportWidth = this._layerTree.viewportSize().width + 2 * borderAdjustment;
+ var chromeHeight = this._chromeTextures[0].image.naturalHeight;
+ var middleFragmentWidth =
+ viewportWidth - this._chromeTextures[0].image.naturalWidth - this._chromeTextures[2].image.naturalWidth;
+ var x = -borderAdjustment;
+ var y = -chromeHeight;
+ for (var i = 0; i < this._chromeTextures.length; ++i) {
+ var width = i === WebInspector.Layers3DView.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 {!WebInspector.Layers3DView.Rectangle} rect
+ */
+ _drawViewRect(rect) {
+ var 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;
+ }
+ var 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() {
+ var fragment = this.contentElement.ownerDocument.createDocumentFragment();
+ fragment.createChild('div').textContent = WebInspector.UIString('Can\'t display layers,');
+ fragment.createChild('div').textContent = WebInspector.UIString('WebGL support is disabled in your browser.');
+ fragment.appendChild(WebInspector.formatLocalized(
+ 'Check %s for possible reasons.', [WebInspector.linkifyURLAsNode('about:gpu', undefined, undefined, true)]));
+ return fragment;
+ }
+
+ /**
+ * @param {!Event} event
+ * @return {?WebInspector.LayerView.Selection}
+ */
+ _selectionFromEventPoint(event) {
+ if (!this._layerTree)
+ return null;
+ var closestIntersectionPoint = Infinity;
+ var closestObject = null;
+ var projectionMatrix = new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0).multiply(this._projectionMatrix);
+ var x0 = (event.clientX - this._canvasElement.totalOffsetLeft()) * window.devicePixelRatio;
+ var y0 = -(event.clientY - this._canvasElement.totalOffsetTop()) * window.devicePixelRatio;
+
+ /**
+ * @param {!WebInspector.Layers3DView.Rectangle} rect
+ */
+ function checkIntersection(rect) {
+ if (!rect.relatedObject)
+ return;
+ var 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 {!WebInspector.Toolbar} toolbar
+ * @return {!WebInspector.Setting}
+ */
+ _createVisibilitySetting(caption, name, value, toolbar) {
+ var checkbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString(caption));
+ toolbar.appendToolbarItem(checkbox);
+ var setting = WebInspector.settings.createSetting(name, value);
+ WebInspector.SettingsUI.bindCheckbox(checkbox.inputElement, setting);
+ setting.addChangeListener(this._update, this);
+ return setting;
+ }
+
+ _initToolbar() {
+ this._panelToolbar = this._transformController.toolbar();
+ this.contentElement.appendChild(this._panelToolbar.element);
+ this._showSlowScrollRectsSetting =
+ this._createVisibilitySetting('Slow scroll rects', 'frameViewerShowSlowScrollRects', true, this._panelToolbar);
+ this._showPaintsSetting =
+ this._createVisibilitySetting('Paints', 'frameViewerShowPaints', true, this._panelToolbar);
+ this._showPaintsSetting.addChangeListener(this._updatePaints, this);
+ WebInspector.moduleSetting('frameViewerHideChromeWindow').addChangeListener(this._update, this);
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ _onContextMenu(event) {
+ var contextMenu = new WebInspector.ContextMenu(event);
+ contextMenu.appendItem(
+ WebInspector.UIString('Reset View'), this._transformController.resetAndNotify.bind(this._transformController),
+ false);
+ var selection = this._selectionFromEventPoint(event);
+ if (selection && selection.type() === WebInspector.LayerView.Selection.Type.Snapshot)
+ contextMenu.appendItem(
+ WebInspector.UIString('Show Paint Profiler'),
+ this.dispatchEventToListeners.bind(
+ this, WebInspector.Layers3DView.Events.PaintProfilerRequested, selection.snapshot()),
+ 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) {
+ var selection = this._selectionFromEventPoint(event);
+ if (selection && (selection.type() === WebInspector.LayerView.Selection.Type.Snapshot || selection.layer()))
+ this.dispatchEventToListeners(WebInspector.Layers3DView.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();
+ }
};
/** @typedef {{borderColor: !Array<number>, borderWidth: number}} */
@@ -78,8 +770,8 @@ WebInspector.Layers3DView.LayerStyle;
* @enum {string}
*/
WebInspector.Layers3DView.OutlineType = {
- Hovered: "hovered",
- Selected: "selected"
+ Hovered: 'hovered',
+ Selected: 'selected'
};
/**
@@ -87,51 +779,51 @@ WebInspector.Layers3DView.OutlineType = {
*/
/** @enum {symbol} */
WebInspector.Layers3DView.Events = {
- PaintProfilerRequested: Symbol("PaintProfilerRequested"),
- ScaleChanged: Symbol("ScaleChanged")
+ PaintProfilerRequested: Symbol('PaintProfilerRequested'),
+ ScaleChanged: Symbol('ScaleChanged')
};
/**
* @enum {number}
*/
WebInspector.Layers3DView.ChromeTexture = {
- Left: 0,
- Middle: 1,
- Right: 2
+ Left: 0,
+ Middle: 1,
+ Right: 2
};
/**
* @enum {string}
*/
WebInspector.Layers3DView.ScrollRectTitles = {
- RepaintsOnScroll: WebInspector.UIString("repaints on scroll"),
- TouchEventHandler: WebInspector.UIString("touch event listener"),
- WheelEventHandler: WebInspector.UIString("mousewheel event listener")
+ RepaintsOnScroll: WebInspector.UIString('repaints on scroll'),
+ TouchEventHandler: WebInspector.UIString('touch event listener'),
+ WheelEventHandler: WebInspector.UIString('mousewheel event listener')
};
-WebInspector.Layers3DView.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" +
- "}";
-
-WebInspector.Layers3DView.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" +
- "}";
+WebInspector.Layers3DView.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' +
+ '}';
+
+WebInspector.Layers3DView.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' +
+ '}';
WebInspector.Layers3DView.HoveredBorderColor = [0, 0, 255, 1];
WebInspector.Layers3DView.SelectedBorderColor = [0, 255, 0, 1];
@@ -146,894 +838,201 @@ WebInspector.Layers3DView.ViewportBorderWidth = 3;
WebInspector.Layers3DView.LayerSpacing = 20;
WebInspector.Layers3DView.ScrollRectSpacing = 4;
-WebInspector.Layers3DView.prototype = {
- /**
- * @param {?WebInspector.LayerTreeBase} layerTree
- * @override
- */
- setLayerTree: function(layerTree)
- {
- this._layerTree = layerTree;
- this._layerTexture = null;
- delete this._oldTextureScale;
- if (this._showPaints())
- this._textureManager.setLayerTree(layerTree);
- this._update();
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @param {string=} imageURL
- */
- showImageForLayer: function(layer, imageURL)
- {
- if (!imageURL) {
- this._layerTexture = null;
- this._update();
- return;
- }
- WebInspector.loadImage(imageURL).then(image => {
- var texture = image && WebInspector.LayerTextureManager._createTextureForImage(this._gl, image);
- this._layerTexture = texture ? {layer: layer, texture: texture} : null;
- this._update();
- });
- },
-
- onResize: function()
- {
- this._resizeCanvas();
- this._update();
- },
-
- /**
- * @override
- */
- willHide: function()
- {
- this._textureManager.suspend();
- },
-
- /**
- * @override
- */
- wasShown: function()
- {
- this._textureManager.resume();
- if (!this._needsUpdate)
- return;
- this._resizeCanvas();
- this._update();
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- */
- updateLayerSnapshot: function(layer)
- {
- this._textureManager.layerNeedsUpdate(layer);
- },
-
- /**
- * @param {!WebInspector.Layers3DView.OutlineType} type
- * @param {?WebInspector.LayerView.Selection} selection
- */
- _setOutline: function(type, selection)
- {
- this._lastSelection[type] = selection;
- this._update();
- },
-
- /**
- * @param {?WebInspector.LayerView.Selection} selection
- * @override
- */
- hoverObject: function(selection)
- {
- this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, selection);
- },
-
- /**
- * @param {?WebInspector.LayerView.Selection} selection
- * @override
- */
- selectObject: function(selection)
- {
- this._setOutline(WebInspector.Layers3DView.OutlineType.Hovered, null);
- this._setOutline(WebInspector.Layers3DView.OutlineType.Selected, selection);
- },
-
- /**
- * @param {!WebInspector.LayerView.Selection} selection
- * @return {!Promise<?WebInspector.SnapshotWithRect>}
- */
- snapshotForSelection: function(selection)
- {
- if (selection.type() === WebInspector.LayerView.Selection.Type.Snapshot) {
- var snapshotWithRect = /** @type {!WebInspector.LayerView.SnapshotSelection} */ (selection).snapshot();
- snapshotWithRect.snapshot.addReference();
- return /** @type {!Promise<?WebInspector.SnapshotWithRect>} */ (Promise.resolve(snapshotWithRect));
- }
- if (selection.layer()) {
- var promise = selection.layer().snapshots()[0];
- if (promise)
- return promise;
- }
- return /** @type {!Promise<?WebInspector.SnapshotWithRect>} */ (Promise.resolve(null));
- },
-
- /**
- * @param {!Element} canvas
- * @return {?WebGLRenderingContext}
- */
- _initGL: function(canvas)
- {
- var 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: function(type, script)
- {
- var shader = this._gl.createShader(type);
- this._gl.shaderSource(shader, script);
- this._gl.compileShader(shader);
- this._gl.attachShader(this._shaderProgram, shader);
- },
-
- _initShaders: function()
- {
- this._shaderProgram = this._gl.createProgram();
- this._createShader(this._gl.FRAGMENT_SHADER, WebInspector.Layers3DView.FragmentShader);
- this._createShader(this._gl.VERTEX_SHADER, WebInspector.Layers3DView.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: function()
- {
- this._canvasElement.width = this._canvasElement.offsetWidth * window.devicePixelRatio;
- this._canvasElement.height = this._canvasElement.offsetHeight * window.devicePixelRatio;
- },
-
- _updateTransformAndConstraints: function()
- {
- var paddingFraction = 0.1;
- var viewport = this._layerTree.viewportSize();
- var root = this._layerTree.root();
- var baseWidth = viewport ? viewport.width : this._dimensionsForAutoscale.width;
- var baseHeight = viewport ? viewport.height : this._dimensionsForAutoscale.height;
- var canvasWidth = this._canvasElement.width;
- var canvasHeight = this._canvasElement.height;
- var paddingX = canvasWidth * paddingFraction;
- var paddingY = canvasHeight * paddingFraction;
- var scaleX = (canvasWidth - 2 * paddingX) / baseWidth;
- var scaleY = (canvasHeight - 2 * paddingY) / baseHeight;
- var viewScale = Math.min(scaleX, scaleY);
- var 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
- var scale = this._transformController.scale();
- var rotateX = this._transformController.rotateX();
- var rotateY = this._transformController.rotateY();
-
- this._scale = scale * viewScale;
- var textureScale = Number.constrain(this._scale, 0.1, 1);
- if (textureScale !== this._oldTextureScale) {
- this._oldTextureScale = textureScale;
- this._textureManager.setScale(textureScale);
- this.dispatchEventToListeners(WebInspector.Layers3DView.Events.ScaleChanged, textureScale);
- }
- var 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);
-
- var bounds;
- for (var i = 0; i < this._rects.length; ++i)
- bounds = WebInspector.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);
- var offsetX = this._transformController.offsetX() * window.devicePixelRatio;
- var 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);
-
- var 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: function(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: function()
- {
- this._whiteTexture = this._gl.createTexture();
- this._gl.bindTexture(this._gl.TEXTURE_2D, this._whiteTexture);
- var 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: function()
- {
- /**
- * @this {WebInspector.Layers3DView}
- * @param {!WebInspector.Layers3DView.ChromeTexture} index
- * @param {string} url
- */
- function loadChromeTexture(index, url)
- {
- WebInspector.loadImage(url).then(image => {
- this._chromeTextures[index] = image && WebInspector.LayerTextureManager._createTextureForImage(this._gl, image) || undefined;
- });
- }
- loadChromeTexture.call(this, WebInspector.Layers3DView.ChromeTexture.Left, "Images/chromeLeft.png");
- loadChromeTexture.call(this, WebInspector.Layers3DView.ChromeTexture.Middle, "Images/chromeMiddle.png");
- loadChromeTexture.call(this, WebInspector.Layers3DView.ChromeTexture.Right, "Images/chromeRight.png");
- },
-
- /**
- * @return {?WebGLRenderingContext}
- */
- _initGLIfNecessary: function()
- {
- 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: function()
- {
- this._depthByLayerId = {};
- var depth = 0;
- var showInternalLayers = this._layerViewHost.showInternalLayersSetting().get();
- var root = showInternalLayers ? this._layerTree.root() : (this._layerTree.contentRoot() || this._layerTree.root());
- var queue = [root];
- this._depthByLayerId[root.id()] = 0;
- /** @type {!Set<!WebInspector.Layer>} */
- this._visibleLayers = new Set();
- while (queue.length > 0) {
- var layer = queue.shift();
- if (showInternalLayers || layer.drawsContent())
- this._visibleLayers.add(layer);
- var children = layer.children();
- for (var i = 0; i < children.length; ++i) {
- this._depthByLayerId[children[i].id()] = ++depth;
- queue.push(children[i]);
- }
- }
- this._maxDepth = depth;
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @return {number}
- */
- _depthForLayer: function(layer)
- {
- return this._depthByLayerId[layer.id()] * WebInspector.Layers3DView.LayerSpacing;
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @param {number} index
- * @return {number}
- */
- _calculateScrollRectDepth: function(layer, index)
- {
- return this._depthForLayer(layer) + index * WebInspector.Layers3DView.ScrollRectSpacing + 1;
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- */
- _updateDimensionsForAutoscale: function(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 {!WebInspector.Layer} layer
- */
- _calculateLayerRect: function(layer)
- {
- if (!this._visibleLayers.has(layer))
- return;
- var selection = new WebInspector.LayerView.LayerSelection(layer);
- var rect = new WebInspector.Layers3DView.Rectangle(selection);
- rect.setVertices(layer.quad(), this._depthForLayer(layer));
- this._appendRect(rect);
- this._updateDimensionsForAutoscale(layer);
- },
-
- /**
- * @param {!WebInspector.Layers3DView.Rectangle} rect
- */
- _appendRect: function(rect)
- {
- var selection = rect.relatedObject;
- var isSelected = WebInspector.LayerView.Selection.isEqual(this._lastSelection[WebInspector.Layers3DView.OutlineType.Selected], selection);
- var isHovered = WebInspector.LayerView.Selection.isEqual(this._lastSelection[WebInspector.Layers3DView.OutlineType.Hovered], selection);
- if (isSelected) {
- rect.borderColor = WebInspector.Layers3DView.SelectedBorderColor;
- } else if (isHovered) {
- rect.borderColor = WebInspector.Layers3DView.HoveredBorderColor;
- var fillColor = rect.fillColor || [255, 255, 255, 1];
- var maskColor = WebInspector.Layers3DView.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 = WebInspector.Layers3DView.BorderColor;
- }
- rect.lineWidth = isSelected ? WebInspector.Layers3DView.SelectedBorderWidth : WebInspector.Layers3DView.BorderWidth;
- this._rects.push(rect);
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- */
- _calculateLayerScrollRects: function(layer)
- {
- var scrollRects = layer.scrollRects();
- for (var i = 0; i < scrollRects.length; ++i) {
- var selection = new WebInspector.LayerView.ScrollRectSelection(layer, i);
- var rect = new WebInspector.Layers3DView.Rectangle(selection);
- rect.calculateVerticesFromRect(layer, scrollRects[i].rect, this._calculateScrollRectDepth(layer, i));
- rect.fillColor = WebInspector.Layers3DView.ScrollRectBackgroundColor;
- this._appendRect(rect);
- }
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- */
- _calculateLayerTileRects: function(layer)
- {
- var tiles = this._textureManager.tilesForLayer(layer);
- for (var i = 0; i < tiles.length; ++i) {
- var tile = tiles[i];
- if (!tile.texture)
- continue;
- var selection = new WebInspector.LayerView.SnapshotSelection(layer, {rect: tile.rect, snapshot: tile.snapshot});
- var rect = new WebInspector.Layers3DView.Rectangle(selection);
- rect.calculateVerticesFromRect(layer, tile.rect, this._depthForLayer(layer) + 1);
- rect.texture = tile.texture;
- this._appendRect(rect);
- }
- },
-
- _calculateRects: function()
- {
- this._rects = [];
- 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)) {
- var layer = this._layerTexture.layer;
- var selection = new WebInspector.LayerView.LayerSelection(layer);
- var rect = new WebInspector.Layers3DView.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: function(color)
- {
- var colors = [];
- var normalizedColor = [color[0] / 255, color[1] / 255, color[2] / 255, color[3]];
- for (var i = 0; i < 4; i++)
- colors = colors.concat(normalizedColor);
- return colors;
- },
-
- /**
- * @param {!Object} attribute
- * @param {!Array.<number>} array
- * @param {number} length
- */
- _setVertexAttribute: function(attribute, array, length)
- {
- var gl = this._gl;
- var 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: function(vertices, mode, color, texture)
- {
- var gl = this._gl;
- var 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);
- }
-
- var numberOfVertices = vertices.length / 3;
- gl.drawArrays(mode, 0, numberOfVertices);
- },
-
- /**
- * @param {!Array.<number>} vertices
- * @param {!WebGLTexture} texture
- * @param {!Array.<number>=} color
- */
- _drawTexture: function(vertices, texture, color)
- {
- this._drawRectangle(vertices, this._gl.TRIANGLE_FAN, color, texture);
- },
-
- _drawViewportAndChrome: function()
- {
- var viewport = this._layerTree.viewportSize();
- if (!viewport)
- return;
-
- var drawChrome = !WebInspector.moduleSetting("frameViewerHideChromeWindow").get() && this._chromeTextures.length >= 3 && this._chromeTextures.indexOf(undefined) < 0;
- var z = (this._maxDepth + 1) * WebInspector.Layers3DView.LayerSpacing;
- var borderWidth = Math.ceil(WebInspector.Layers3DView.ViewportBorderWidth * this._scale);
- var 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, WebInspector.Layers3DView.ViewportBorderColor);
-
- if (!drawChrome)
- return;
-
- var borderAdjustment = WebInspector.Layers3DView.ViewportBorderWidth / 2;
- var viewportWidth = this._layerTree.viewportSize().width + 2 * borderAdjustment;
- var chromeHeight = this._chromeTextures[0].image.naturalHeight;
- var middleFragmentWidth = viewportWidth - this._chromeTextures[0].image.naturalWidth - this._chromeTextures[2].image.naturalWidth;
- var x = -borderAdjustment;
- var y = -chromeHeight;
- for (var i = 0; i < this._chromeTextures.length; ++i) {
- var width = i === WebInspector.Layers3DView.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 {!WebInspector.Layers3DView.Rectangle} rect
- */
- _drawViewRect: function(rect)
- {
- var 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: function()
- {
- if (!this.isShowing()) {
- this._needsUpdate = true;
- return;
- }
- if (!this._layerTree || !this._layerTree.root()) {
- this._failBanner.show(this.contentElement);
- return;
- }
- var 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: function()
- {
- var fragment = this.contentElement.ownerDocument.createDocumentFragment();
- fragment.createChild("div").textContent = WebInspector.UIString("Can't display layers,");
- fragment.createChild("div").textContent = WebInspector.UIString("WebGL support is disabled in your browser.");
- fragment.appendChild(WebInspector.formatLocalized("Check %s for possible reasons.", [WebInspector.linkifyURLAsNode("about:gpu", undefined, undefined, true)]));
- return fragment;
- },
-
- /**
- * @param {!Event} event
- * @return {?WebInspector.LayerView.Selection}
- */
- _selectionFromEventPoint: function(event)
- {
- if (!this._layerTree)
- return null;
- var closestIntersectionPoint = Infinity;
- var closestObject = null;
- var projectionMatrix = new WebKitCSSMatrix().scale(1, -1, -1).translate(-1, -1, 0).multiply(this._projectionMatrix);
- var x0 = (event.clientX - this._canvasElement.totalOffsetLeft()) * window.devicePixelRatio;
- var y0 = -(event.clientY - this._canvasElement.totalOffsetTop()) * window.devicePixelRatio;
-
- /**
- * @param {!WebInspector.Layers3DView.Rectangle} rect
- */
- function checkIntersection(rect)
- {
- if (!rect.relatedObject)
- return;
- var 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 {!WebInspector.Toolbar} toolbar
- * @return {!WebInspector.Setting}
- */
- _createVisibilitySetting: function(caption, name, value, toolbar)
- {
- var checkbox = new WebInspector.ToolbarCheckbox(WebInspector.UIString(caption));
- toolbar.appendToolbarItem(checkbox);
- var setting = WebInspector.settings.createSetting(name, value);
- WebInspector.SettingsUI.bindCheckbox(checkbox.inputElement, setting);
- setting.addChangeListener(this._update, this);
- return setting;
- },
-
- _initToolbar: function()
- {
- this._panelToolbar = this._transformController.toolbar();
- this.contentElement.appendChild(this._panelToolbar.element);
- this._showSlowScrollRectsSetting = this._createVisibilitySetting("Slow scroll rects", "frameViewerShowSlowScrollRects", true, this._panelToolbar);
- this._showPaintsSetting = this._createVisibilitySetting("Paints", "frameViewerShowPaints", true, this._panelToolbar);
- this._showPaintsSetting.addChangeListener(this._updatePaints, this);
- WebInspector.moduleSetting("frameViewerHideChromeWindow").addChangeListener(this._update, this);
- },
-
- /**
- * @param {!Event} event
- */
- _onContextMenu: function(event)
- {
- var contextMenu = new WebInspector.ContextMenu(event);
- contextMenu.appendItem(WebInspector.UIString("Reset View"), this._transformController.resetAndNotify.bind(this._transformController), false);
- var selection = this._selectionFromEventPoint(event);
- if (selection && selection.type() === WebInspector.LayerView.Selection.Type.Snapshot)
- contextMenu.appendItem(WebInspector.UIString("Show Paint Profiler"), this.dispatchEventToListeners.bind(this, WebInspector.Layers3DView.Events.PaintProfilerRequested, selection.snapshot()), false);
- this._layerViewHost.showContextMenu(contextMenu, selection);
- },
-
- /**
- * @param {!Event} event
- */
- _onMouseMove: function(event)
- {
- if (event.which)
- return;
- this._layerViewHost.hoverObject(this._selectionFromEventPoint(event));
- },
-
- /**
- * @param {!Event} event
- */
- _onMouseDown: function(event)
- {
- this._mouseDownX = event.clientX;
- this._mouseDownY = event.clientY;
- },
-
- /**
- * @param {!Event} event
- */
- _onMouseUp: function(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: function(event)
- {
- var selection = this._selectionFromEventPoint(event);
- if (selection && (selection.type() === WebInspector.LayerView.Selection.Type.Snapshot || selection.layer()))
- this.dispatchEventToListeners(WebInspector.Layers3DView.Events.PaintProfilerRequested, selection);
- event.stopPropagation();
- },
-
- _updatePaints: function()
- {
- if (this._showPaints()) {
- this._textureManager.setLayerTree(this._layerTree);
- this._textureManager.forceUpdate();
- } else {
- this._textureManager.reset();
- }
- this._update();
- },
-
- /**
- * @return {boolean}
- */
- _showPaints: function()
- {
- return this._showPaintsSetting.get();
- },
-
- __proto__: WebInspector.VBox.prototype
-};
-
/**
- * @constructor
- * @param {function()} textureUpdatedCallback
+ * @unrestricted
*/
-WebInspector.LayerTextureManager = function(textureUpdatedCallback)
-{
+WebInspector.LayerTextureManager = class {
+ /**
+ * @param {function()} textureUpdatedCallback
+ */
+ constructor(textureUpdatedCallback) {
this._textureUpdatedCallback = textureUpdatedCallback;
this._throttler = new WebInspector.Throttler(0);
this._scale = 0;
this._active = false;
this.reset();
-};
-
-WebInspector.LayerTextureManager.prototype = {
- reset: function()
- {
- if (this._tilesByLayer)
- this.setLayerTree(null);
-
- /** @type {!Map<!WebInspector.Layer, !Array<!WebInspector.LayerTextureManager.Tile>>} */
- this._tilesByLayer = new Map();
- /** @type {!Array<!WebInspector.Layer>} */
- this._queue = [];
- },
-
- /**
- * @param {!WebGLRenderingContext} glContext
- */
- setContext: function(glContext)
- {
- this._gl = glContext;
- if (this._scale)
- this._updateTextures();
- },
-
- suspend: function()
- {
- this._active = false;
- },
-
- resume: function()
- {
- this._active = true;
- if (this._queue.length)
- this._update();
- },
-
- /**
- * @param {?WebInspector.LayerTreeBase} layerTree
- */
- setLayerTree: function(layerTree)
- {
- var newLayers = new Set();
- var 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 (var layer of oldLayers) {
- if (newLayers.has(layer))
- continue;
- this._tilesByLayer.get(layer).forEach(tile => tile.dispose());
- this._tilesByLayer.delete(layer);
- }
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @param {!Array<!WebInspector.SnapshotWithRect>} snapshots
- * @return {!Promise}
- */
- _setSnapshotsForLayer: function(layer, snapshots)
- {
- var oldSnapshotsToTiles = new Map((this._tilesByLayer.get(layer) || []).map(tile => [tile.snapshot, tile]));
- var newTiles = [];
- var reusedTiles = [];
- for (var snapshot of snapshots) {
- var oldTile = oldSnapshotsToTiles.get(snapshot);
- if (oldTile) {
- reusedTiles.push(oldTile);
- oldSnapshotsToTiles.delete(oldTile);
- } else {
- newTiles.push(new WebInspector.LayerTextureManager.Tile(snapshot));
- }
- }
- this._tilesByLayer.set(layer, reusedTiles.concat(newTiles));
- for (var 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: function(scale)
- {
- if (this._scale && this._scale >= scale)
- return;
- this._scale = scale;
- this._updateTextures();
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @return {!Array<!WebInspector.LayerTextureManager.Tile>}
- */
- tilesForLayer: function(layer)
- {
- return this._tilesByLayer.get(layer) || [];
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- */
- layerNeedsUpdate: function(layer)
- {
- if (this._queue.indexOf(layer) < 0)
- this._queue.push(layer);
- if (this._active)
- this._throttler.schedule(this._update.bind(this));
- },
-
- forceUpdate: function()
- {
- this._queue.forEach(layer => this._updateLayer(layer));
- this._queue = [];
- this._throttler.flush();
- },
-
- /**
- * @return {!Promise}
- */
- _update: function()
- {
- var 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 {!WebInspector.Layer} layer
- * @return {!Promise}
- */
- _updateLayer: function(layer)
- {
- return Promise.all(layer.snapshots()).then(snapshots =>
- this._setSnapshotsForLayer(layer, snapshots.filter(snapshot => !!snapshot)));
- },
-
- _updateTextures: function()
- {
- if (!this._gl)
- return;
- if (!this._scale)
- return;
-
- for (var tiles of this._tilesByLayer.values()) {
- for (var tile of tiles) {
- var promise = tile.updateScale(this._gl, this._scale);
- if (promise)
- promise.then(this._textureUpdatedCallback);
- }
+ }
+
+ /**
+ * @param {!Image} image
+ * @param {!WebGLRenderingContext} gl
+ * @return {!WebGLTexture} texture
+ */
+ static _createTextureForImage(gl, image) {
+ var 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<!WebInspector.Layer, !Array<!WebInspector.LayerTextureManager.Tile>>} */
+ this._tilesByLayer = new Map();
+ /** @type {!Array<!WebInspector.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 {?WebInspector.LayerTreeBase} layerTree
+ */
+ setLayerTree(layerTree) {
+ var newLayers = new Set();
+ var 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 (var layer of oldLayers) {
+ if (newLayers.has(layer))
+ continue;
+ this._tilesByLayer.get(layer).forEach(tile => tile.dispose());
+ this._tilesByLayer.delete(layer);
+ }
+ }
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {!Array<!WebInspector.SnapshotWithRect>} snapshots
+ * @return {!Promise}
+ */
+ _setSnapshotsForLayer(layer, snapshots) {
+ var oldSnapshotsToTiles = new Map((this._tilesByLayer.get(layer) || []).map(tile => [tile.snapshot, tile]));
+ var newTiles = [];
+ var reusedTiles = [];
+ for (var snapshot of snapshots) {
+ var oldTile = oldSnapshotsToTiles.get(snapshot);
+ if (oldTile) {
+ reusedTiles.push(oldTile);
+ oldSnapshotsToTiles.delete(oldTile);
+ } else {
+ newTiles.push(new WebInspector.LayerTextureManager.Tile(snapshot));
+ }
+ }
+ this._tilesByLayer.set(layer, reusedTiles.concat(newTiles));
+ for (var 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 {!WebInspector.Layer} layer
+ * @return {!Array<!WebInspector.LayerTextureManager.Tile>}
+ */
+ tilesForLayer(layer) {
+ return this._tilesByLayer.get(layer) || [];
+ }
+
+ /**
+ * @param {!WebInspector.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._throttler.flush();
+ }
+
+ /**
+ * @return {!Promise}
+ */
+ _update() {
+ var 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 {!WebInspector.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 (var tiles of this._tilesByLayer.values()) {
+ for (var tile of tiles) {
+ var promise = tile.updateScale(this._gl, this._scale);
+ if (promise)
+ promise.then(this._textureUpdatedCallback);
+ }
}
+ }
};
/**
- * @constructor
- * @param {?WebInspector.LayerView.Selection} relatedObject
+ * @unrestricted
*/
-WebInspector.Layers3DView.Rectangle = function(relatedObject)
-{
+WebInspector.Layers3DView.Rectangle = class {
+ /**
+ * @param {?WebInspector.LayerView.Selection} relatedObject
+ */
+ constructor(relatedObject) {
this.relatedObject = relatedObject;
/** @type {number} */
this.lineWidth = 1;
@@ -1043,170 +1042,150 @@ WebInspector.Layers3DView.Rectangle = function(relatedObject)
this.fillColor = null;
/** @type {?WebGLTexture} */
this.texture = null;
-};
-
-WebInspector.Layers3DView.Rectangle.prototype = {
- /**
- * @param {!Array.<number>} quad
- * @param {number} z
- */
- setVertices: function(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: function(quad, ratioX, ratioY)
- {
- var x0 = quad[0];
- var y0 = quad[1];
- var x1 = quad[2];
- var y1 = quad[3];
- var x2 = quad[4];
- var y2 = quad[5];
- var x3 = quad[6];
- var y3 = quad[7];
- // Point on the first quad side clockwise
- var firstSidePointX = x0 + ratioX * (x1 - x0);
- var firstSidePointY = y0 + ratioX * (y1 - y0);
- // Point on the third quad side clockwise
- var thirdSidePointX = x3 + ratioX * (x2 - x3);
- var thirdSidePointY = y3 + ratioX * (y2 - y3);
- var x = firstSidePointX + ratioY * (thirdSidePointX - firstSidePointX);
- var y = firstSidePointY + ratioY * (thirdSidePointY - firstSidePointY);
- return [x, y];
- },
-
- /**
- * @param {!WebInspector.Layer} layer
- * @param {!DOMAgent.Rect} rect
- * @param {number} z
- */
- calculateVerticesFromRect: function(layer, rect, z)
- {
- var quad = layer.quad();
- var rx1 = rect.x / layer.width();
- var rx2 = (rect.x + rect.width) / layer.width();
- var ry1 = rect.y / layer.height();
- var ry2 = (rect.y + rect.height) / layer.height();
- var 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: function(matrix, x0, y0)
- {
- var i;
- // Vertices of the quad with transform matrix applied
- var points = [];
- for (i = 0; i < 4; ++i)
- points[i] = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(new WebInspector.Geometry.Vector(this.vertices[i * 3], this.vertices[i * 3 + 1], this.vertices[i * 3 + 2]), matrix);
- // Calculating quad plane normal
- var normal = WebInspector.Geometry.crossProduct(WebInspector.Geometry.subtract(points[1], points[0]), WebInspector.Geometry.subtract(points[2], points[1]));
- // General form of the equation of the quad plane: A * x + B * y + C * z + D = 0
- var A = normal.x;
- var B = normal.y;
- var C = normal.z;
- var D = -(A * points[0].x + B * points[0].y + C * points[0].z);
- // Finding t from the equation
- var t = -(D + A * x0 + B * y0) / C;
- // Point of the intersection
- var pt = new WebInspector.Geometry.Vector(x0, y0, t);
- // Vectors from the intersection point to vertices of the quad
- var tVects = points.map(WebInspector.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) {
- var product = WebInspector.Geometry.scalarProduct(normal, WebInspector.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
- if (product < 0)
- return undefined;
- }
- return t;
+ }
+
+ /**
+ * @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) {
+ var x0 = quad[0];
+ var y0 = quad[1];
+ var x1 = quad[2];
+ var y1 = quad[3];
+ var x2 = quad[4];
+ var y2 = quad[5];
+ var x3 = quad[6];
+ var y3 = quad[7];
+ // Point on the first quad side clockwise
+ var firstSidePointX = x0 + ratioX * (x1 - x0);
+ var firstSidePointY = y0 + ratioX * (y1 - y0);
+ // Point on the third quad side clockwise
+ var thirdSidePointX = x3 + ratioX * (x2 - x3);
+ var thirdSidePointY = y3 + ratioX * (y2 - y3);
+ var x = firstSidePointX + ratioY * (thirdSidePointX - firstSidePointX);
+ var y = firstSidePointY + ratioY * (thirdSidePointY - firstSidePointY);
+ return [x, y];
+ }
+
+ /**
+ * @param {!WebInspector.Layer} layer
+ * @param {!DOMAgent.Rect} rect
+ * @param {number} z
+ */
+ calculateVerticesFromRect(layer, rect, z) {
+ var quad = layer.quad();
+ var rx1 = rect.x / layer.width();
+ var rx2 = (rect.x + rect.width) / layer.width();
+ var ry1 = rect.y / layer.height();
+ var ry2 = (rect.y + rect.height) / layer.height();
+ var 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) {
+ var i;
+ // Vertices of the quad with transform matrix applied
+ var points = [];
+ for (i = 0; i < 4; ++i)
+ points[i] = WebInspector.Geometry.multiplyVectorByMatrixAndNormalize(
+ new WebInspector.Geometry.Vector(this.vertices[i * 3], this.vertices[i * 3 + 1], this.vertices[i * 3 + 2]),
+ matrix);
+ // Calculating quad plane normal
+ var normal = WebInspector.Geometry.crossProduct(
+ WebInspector.Geometry.subtract(points[1], points[0]), WebInspector.Geometry.subtract(points[2], points[1]));
+ // General form of the equation of the quad plane: A * x + B * y + C * z + D = 0
+ var A = normal.x;
+ var B = normal.y;
+ var C = normal.z;
+ var D = -(A * points[0].x + B * points[0].y + C * points[0].z);
+ // Finding t from the equation
+ var t = -(D + A * x0 + B * y0) / C;
+ // Point of the intersection
+ var pt = new WebInspector.Geometry.Vector(x0, y0, t);
+ // Vectors from the intersection point to vertices of the quad
+ var tVects = points.map(WebInspector.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) {
+ var product = WebInspector.Geometry.scalarProduct(
+ normal, WebInspector.Geometry.crossProduct(tVects[i], tVects[(i + 1) % tVects.length]));
+ if (product < 0)
+ return undefined;
}
+ return t;
+ }
};
-/**
- * @param {!Image} image
- * @param {!WebGLRenderingContext} gl
- * @return {!WebGLTexture} texture
- */
-WebInspector.LayerTextureManager._createTextureForImage = function(gl, image)
-{
- var 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;
-};
/**
- * @constructor
- * @param {!WebInspector.SnapshotWithRect} snapshotWithRect
+ * @unrestricted
*/
-WebInspector.LayerTextureManager.Tile = function(snapshotWithRect)
-{
+WebInspector.LayerTextureManager.Tile = class {
+ /**
+ * @param {!WebInspector.SnapshotWithRect} snapshotWithRect
+ */
+ constructor(snapshotWithRect) {
this.snapshot = snapshotWithRect.snapshot;
this.rect = snapshotWithRect.rect;
this.scale = 0;
/** @type {?WebGLTexture} */
this.texture = null;
-};
+ }
-WebInspector.LayerTextureManager.Tile.prototype = {
- dispose: function()
- {
- this.snapshot.release();
- if (this.texture) {
- this._gl.deleteTexture(this.texture);
- this.texture = null;
- }
- },
-
- /**
- * @param {!WebGLRenderingContext} glContext
- * @param {number} scale
- * @return {?Promise}
- */
- updateScale: function(glContext, scale)
- {
- if (this.texture && this.scale >= scale)
- return null;
- return this.update(glContext, scale);
- },
-
- /**
- * @param {!WebGLRenderingContext} glContext
- * @param {number} scale
- * @return {!Promise}
- */
- update: function(glContext, scale)
- {
- this._gl = glContext;
- this.scale = scale;
- return this.snapshot.replay(null, null, scale)
- .then(imageURL => imageURL && WebInspector.loadImage(imageURL))
- .then(image => {
- this.texture = image && WebInspector.LayerTextureManager._createTextureForImage(glContext, image);
- });
+ 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}
+ */
+ update(glContext, scale) {
+ this._gl = glContext;
+ this.scale = scale;
+ return this.snapshot.replay(null, null, scale)
+ .then(imageURL => imageURL && WebInspector.loadImage(imageURL))
+ .then(image => {
+ this.texture = image && WebInspector.LayerTextureManager._createTextureForImage(glContext, image);
+ });
+ }
};

Powered by Google App Engine
This is Rietveld 408576698