summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/trace-viewer/src/ui/quad_stack_view.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/trace-viewer/src/ui/quad_stack_view.js')
-rw-r--r--chromium/third_party/trace-viewer/src/ui/quad_stack_view.js603
1 files changed, 0 insertions, 603 deletions
diff --git a/chromium/third_party/trace-viewer/src/ui/quad_stack_view.js b/chromium/third_party/trace-viewer/src/ui/quad_stack_view.js
deleted file mode 100644
index fdd185547ef..00000000000
--- a/chromium/third_party/trace-viewer/src/ui/quad_stack_view.js
+++ /dev/null
@@ -1,603 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @fileoverview QuadStackView controls the content and viewing angle a
- * QuadStack.
- */
-base.requireStylesheet('ui.quad_stack_view');
-
-base.requireTemplate('ui.quad_stack_view');
-
-base.require('base.bbox2');
-base.require('base.gl_matrix');
-base.require('base.quad');
-base.require('base.raf');
-base.require('base.rect');
-base.require('base.settings');
-base.require('ui.camera');
-base.require('ui.mouse_mode_selector');
-base.require('ui.mouse_tracker');
-
-base.exportTo('ui', function() {
- var constants = {};
- constants.IMAGE_LOAD_RETRY_TIME_MS = 500;
- constants.SUBDIVISION_MINIMUM = 1;
- constants.SUBDIVISION_RECURSION_DEPTH = 3;
- constants.SUBDIVISION_DEPTH_THRESHOLD = 100;
- constants.FAR_PLANE_DISTANCE = 10000;
-
- // Care of bckenney@ via
- // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
- function drawTexturedTriangle(ctx, img, p0, p1, p2, t0, t1, t2) {
- var tmp_p0 = [p0[0], p0[1]];
- var tmp_p1 = [p1[0], p1[1]];
- var tmp_p2 = [p2[0], p2[1]];
- var tmp_t0 = [t0[0], t0[1]];
- var tmp_t1 = [t1[0], t1[1]];
- var tmp_t2 = [t2[0], t2[1]];
-
- ctx.beginPath();
- ctx.moveTo(tmp_p0[0], tmp_p0[1]);
- ctx.lineTo(tmp_p1[0], tmp_p1[1]);
- ctx.lineTo(tmp_p2[0], tmp_p2[1]);
- ctx.closePath();
-
- tmp_p1[0] -= tmp_p0[0];
- tmp_p1[1] -= tmp_p0[1];
- tmp_p2[0] -= tmp_p0[0];
- tmp_p2[1] -= tmp_p0[1];
-
- tmp_t1[0] -= tmp_t0[0];
- tmp_t1[1] -= tmp_t0[1];
- tmp_t2[0] -= tmp_t0[0];
- tmp_t2[1] -= tmp_t0[1];
-
- var det = 1 / (tmp_t1[0] * tmp_t2[1] - tmp_t2[0] * tmp_t1[1]),
-
- // linear transformation
- a = (tmp_t2[1] * tmp_p1[0] - tmp_t1[1] * tmp_p2[0]) * det,
- b = (tmp_t2[1] * tmp_p1[1] - tmp_t1[1] * tmp_p2[1]) * det,
- c = (tmp_t1[0] * tmp_p2[0] - tmp_t2[0] * tmp_p1[0]) * det,
- d = (tmp_t1[0] * tmp_p2[1] - tmp_t2[0] * tmp_p1[1]) * det,
-
- // translation
- e = tmp_p0[0] - a * tmp_t0[0] - c * tmp_t0[1],
- f = tmp_p0[1] - b * tmp_t0[0] - d * tmp_t0[1];
-
- ctx.save();
- ctx.transform(a, b, c, d, e, f);
- ctx.clip();
- ctx.drawImage(img, 0, 0);
- ctx.restore();
- }
-
- function drawTriangleSub(
- ctx, img, p0, p1, p2, t0, t1, t2, opt_recursion_depth) {
- var depth = opt_recursion_depth || 0;
-
- // We may subdivide if we are not at the limit of recursion.
- var subdivisionIndex = 0;
- if (depth < constants.SUBDIVISION_MINIMUM) {
- subdivisionIndex = 7;
- } else if (depth < constants.SUBDIVISION_RECURSION_DEPTH) {
- if (Math.abs(p0[2] - p1[2]) > constants.SUBDIVISION_DEPTH_THRESHOLD)
- subdivisionIndex += 1;
- if (Math.abs(p0[2] - p2[2]) > constants.SUBDIVISION_DEPTH_THRESHOLD)
- subdivisionIndex += 2;
- if (Math.abs(p1[2] - p2[2]) > constants.SUBDIVISION_DEPTH_THRESHOLD)
- subdivisionIndex += 4;
- }
-
- // These need to be created every time, since temporaries
- // outside of the scope will be rewritten in recursion.
- var p01 = vec4.create();
- var p02 = vec4.create();
- var p12 = vec4.create();
- var t01 = vec2.create();
- var t02 = vec2.create();
- var t12 = vec2.create();
-
- // Calculate the position before w-divide.
- for (var i = 0; i < 2; ++i) {
- p0[i] *= p0[2];
- p1[i] *= p1[2];
- p2[i] *= p2[2];
- }
-
- // Interpolate the 3d position.
- for (var i = 0; i < 4; ++i) {
- p01[i] = (p0[i] + p1[i]) / 2;
- p02[i] = (p0[i] + p2[i]) / 2;
- p12[i] = (p1[i] + p2[i]) / 2;
- }
-
- // Re-apply w-divide to the original points and the interpolated ones.
- for (var i = 0; i < 2; ++i) {
- p0[i] /= p0[2];
- p1[i] /= p1[2];
- p2[i] /= p2[2];
-
- p01[i] /= p01[2];
- p02[i] /= p02[2];
- p12[i] /= p12[2];
- }
-
- // Interpolate the texture coordinates.
- for (var i = 0; i < 2; ++i) {
- t01[i] = (t0[i] + t1[i]) / 2;
- t02[i] = (t0[i] + t2[i]) / 2;
- t12[i] = (t1[i] + t2[i]) / 2;
- }
-
- // Based on the index, we subdivide the triangle differently.
- // Assuming the triangle is p0, p1, p2 and points between i j
- // are represented as pij (that is, a point between p2 and p0
- // is p02, etc), then the new triangles are defined by
- // the 3rd 4th and 5th arguments into the function.
- switch (subdivisionIndex) {
- case 1:
- drawTriangleSub(ctx, img, p0, p01, p2, t0, t01, t2, depth + 1);
- drawTriangleSub(ctx, img, p01, p1, p2, t01, t1, t2, depth + 1);
- break;
- case 2:
- drawTriangleSub(ctx, img, p0, p1, p02, t0, t1, t02, depth + 1);
- drawTriangleSub(ctx, img, p1, p02, p2, t1, t02, t2, depth + 1);
- break;
- case 3:
- drawTriangleSub(ctx, img, p0, p01, p02, t0, t01, t02, depth + 1);
- drawTriangleSub(ctx, img, p02, p01, p2, t02, t01, t2, depth + 1);
- drawTriangleSub(ctx, img, p01, p1, p2, t01, t1, t2, depth + 1);
- break;
- case 4:
- drawTriangleSub(ctx, img, p0, p12, p2, t0, t12, t2, depth + 1);
- drawTriangleSub(ctx, img, p0, p1, p12, t0, t1, t12, depth + 1);
- break;
- case 5:
- drawTriangleSub(ctx, img, p0, p01, p2, t0, t01, t2, depth + 1);
- drawTriangleSub(ctx, img, p2, p01, p12, t2, t01, t12, depth + 1);
- drawTriangleSub(ctx, img, p01, p1, p12, t01, t1, t12, depth + 1);
- break;
- case 6:
- drawTriangleSub(ctx, img, p0, p12, p02, t0, t12, t02, depth + 1);
- drawTriangleSub(ctx, img, p0, p1, p12, t0, t1, t12, depth + 1);
- drawTriangleSub(ctx, img, p02, p12, p2, t02, t12, t2, depth + 1);
- break;
- case 7:
- drawTriangleSub(ctx, img, p0, p01, p02, t0, t01, t02, depth + 1);
- drawTriangleSub(ctx, img, p01, p12, p02, t01, t12, t02, depth + 1);
- drawTriangleSub(ctx, img, p01, p1, p12, t01, t1, t12, depth + 1);
- drawTriangleSub(ctx, img, p02, p12, p2, t02, t12, t2, depth + 1);
- break;
- default:
- // In the 0 case and all other cases, we simply draw the triangle.
- drawTexturedTriangle(ctx, img, p0, p1, p2, t0, t1, t2);
- break;
- }
- }
-
- // Created to avoid creating garbage when doing bulk transforms.
- var tmp_vec4 = vec4.create();
- function transform(transformed, point, matrix, viewport) {
- vec4.set(tmp_vec4, point[0], point[1], 0, 1);
- vec4.transformMat4(tmp_vec4, tmp_vec4, matrix);
-
- var w = tmp_vec4[3];
- if (w < 1e-6) w = 1e-6;
-
- transformed[0] = ((tmp_vec4[0] / w) + 1) * viewport.width / 2;
- transformed[1] = ((tmp_vec4[1] / w) + 1) * viewport.height / 2;
- transformed[2] = w;
- }
-
- function drawProjectedQuadBackgroundToContext(
- quad, p1, p2, p3, p4, ctx, quadCanvas) {
- if (quad.imageData) {
- quadCanvas.width = quad.imageData.width;
- quadCanvas.height = quad.imageData.height;
- quadCanvas.getContext('2d').putImageData(quad.imageData, 0, 0);
- var quadBBox = new base.BBox2();
- quadBBox.addQuad(quad);
- var iw = quadCanvas.width;
- var ih = quadCanvas.height;
- drawTriangleSub(
- ctx, quadCanvas,
- p1, p2, p4,
- [0, 0], [iw, 0], [0, ih]);
- drawTriangleSub(
- ctx, quadCanvas,
- p2, p3, p4,
- [iw, 0], [iw, ih], [0, ih]);
- }
-
- if (quad.backgroundColor) {
- ctx.fillStyle = quad.backgroundColor;
- ctx.beginPath();
- ctx.moveTo(p1[0], p1[1]);
- ctx.lineTo(p2[0], p2[1]);
- ctx.lineTo(p3[0], p3[1]);
- ctx.lineTo(p4[0], p4[1]);
- ctx.closePath();
- ctx.fill();
- }
- }
-
- function drawProjectedQuadOutlineToContext(
- quad, p1, p2, p3, p4, ctx, quadCanvas) {
- ctx.beginPath();
- ctx.moveTo(p1[0], p1[1]);
- ctx.lineTo(p2[0], p2[1]);
- ctx.lineTo(p3[0], p3[1]);
- ctx.lineTo(p4[0], p4[1]);
- ctx.closePath();
- ctx.save();
- if (quad.borderColor)
- ctx.strokeStyle = quad.borderColor;
- else
- ctx.strokeStyle = 'rgb(128,128,128)';
-
- if (quad.shadowOffset) {
- ctx.shadowColor = 'rgb(0, 0, 0)';
- ctx.shadowOffsetX = quad.shadowOffset[0];
- ctx.shadowOffsetY = quad.shadowOffset[1];
- if (quad.shadowBlur)
- ctx.shadowBlur = quad.shadowBlur;
- }
-
- if (quad.borderWidth)
- ctx.lineWidth = quad.borderWidth;
- else
- ctx.lineWidth = 1;
-
- ctx.stroke();
- ctx.restore();
- }
-
- function drawProjectedQuadSelectionOutlineToContext(
- quad, p1, p2, p3, p4, ctx, quadCanvas) {
- if (!quad.upperBorderColor)
- return;
-
- ctx.lineWidth = 8;
- ctx.strokeStyle = quad.upperBorderColor;
-
- ctx.beginPath();
- ctx.moveTo(p1[0], p1[1]);
- ctx.lineTo(p2[0], p2[1]);
- ctx.lineTo(p3[0], p3[1]);
- ctx.lineTo(p4[0], p4[1]);
- ctx.closePath();
- ctx.stroke();
- }
-
- function drawProjectedQuadToContext(
- passNumber, quad, p1, p2, p3, p4, ctx, quadCanvas) {
- if (passNumber === 0) {
- drawProjectedQuadBackgroundToContext(
- quad, p1, p2, p3, p4, ctx, quadCanvas);
- } else if (passNumber === 1) {
- drawProjectedQuadOutlineToContext(
- quad, p1, p2, p3, p4, ctx, quadCanvas);
- } else if (passNumber === 2) {
- drawProjectedQuadSelectionOutlineToContext(
- quad, p1, p2, p3, p4, ctx, quadCanvas);
- } else {
- throw new Error('Invalid pass number');
- }
- }
-
- var tmp_p1 = vec3.create();
- var tmp_p2 = vec3.create();
- var tmp_p3 = vec3.create();
- var tmp_p4 = vec3.create();
- function transformAndProcessQuads(
- matrix, viewport, quads, numPasses, handleQuadFunc, opt_arg1, opt_arg2) {
-
- for (var passNumber = 0; passNumber < numPasses; passNumber++) {
- for (var i = 0; i < quads.length; i++) {
- var quad = quads[i];
- transform(tmp_p1, quad.p1, matrix, viewport);
- transform(tmp_p2, quad.p2, matrix, viewport);
- transform(tmp_p3, quad.p3, matrix, viewport);
- transform(tmp_p4, quad.p4, matrix, viewport);
- handleQuadFunc(passNumber, quad,
- tmp_p1, tmp_p2, tmp_p3, tmp_p4,
- opt_arg1, opt_arg2);
- }
- }
- }
-
- /**
- * @constructor
- */
- var QuadStackView = ui.define('quad-stack-view');
-
- QuadStackView.prototype = {
- __proto__: HTMLUnknownElement.prototype,
-
- decorate: function() {
- this.className = 'quad-stack-view';
-
- var node = base.instantiateTemplate('#quad-stack-view-template');
- this.appendChild(node);
-
- this.canvas_ = this.querySelector('#canvas');
- this.chromeImages_ = {
- left: this.querySelector('#chrome-left'),
- mid: this.querySelector('#chrome-mid'),
- right: this.querySelector('#chrome-right')
- };
-
- this.trackMouse_();
-
- this.camera_ = new ui.Camera(this.mouseModeSelector_);
- this.camera_.addEventListener('renderrequired',
- this.onRenderRequired_.bind(this));
- this.cameraWasReset_ = false;
- this.camera_.canvas = this.canvas_;
-
- this.viewportRect_ = base.Rect.fromXYWH(0, 0, 0, 0);
-
- this.stackingDistance_ = 45;
- this.pixelRatio_ = window.devicePixelRatio || 1;
- },
-
- onStackingDistanceChange: function(e) {
- this.stackingDistance_ = parseInt(e.target.value);
- this.scheduleRender();
- },
-
- get mouseModeSelector() {
- return this.mouseModeSelector_;
- },
-
- get camera() {
- return this.camera_;
- },
-
- set quads(q) {
- this.quads_ = q;
- this.scheduleRender();
- },
-
- set deviceRect(rect) {
- if (!rect || rect.equalTo(this.deviceRect_))
- return;
-
- this.deviceRect_ = rect;
- this.camera_.deviceRect = rect;
- this.chromeQuad_ = undefined;
- },
-
- resize: function() {
- if (!this.offsetParent)
- return true;
-
- var width = parseInt(window.getComputedStyle(this.offsetParent).width);
- var height = parseInt(window.getComputedStyle(this.offsetParent).height);
- var rect = base.Rect.fromXYWH(0, 0, width, height);
-
- if (rect.equalTo(this.viewportRect_))
- return false;
-
- this.viewportRect_ = rect;
- this.style.width = width + 'px';
- this.style.height = height + 'px';
- this.canvas_.style.width = width + 'px';
- this.canvas_.style.height = height + 'px';
- this.canvas_.width = this.pixelRatio_ * width;
- this.canvas_.height = this.pixelRatio_ * height;
- if (!this.cameraWasReset_) {
- this.camera_.resetCamera();
- this.cameraWasReset_ = true;
- }
- return true;
- },
-
- readyToDraw: function() {
- // If src isn't set yet, set it to ensure we can use
- // the image to draw onto a canvas.
- if (!this.chromeImages_.left.src) {
- var leftContent =
- window.getComputedStyle(this.chromeImages_.left).content;
- leftContent = leftContent.replace(/url\((.*)\)/, '$1');
-
- var midContent =
- window.getComputedStyle(this.chromeImages_.mid).content;
- midContent = midContent.replace(/url\((.*)\)/, '$1');
-
- var rightContent =
- window.getComputedStyle(this.chromeImages_.right).content;
- rightContent = rightContent.replace(/url\((.*)\)/, '$1');
-
- this.chromeImages_.left.src = leftContent;
- this.chromeImages_.mid.src = midContent;
- this.chromeImages_.right.src = rightContent;
- }
-
- // If all of the images are loaded (height > 0), then
- // we are ready to draw.
- return (this.chromeImages_.left.height > 0) &&
- (this.chromeImages_.mid.height > 0) &&
- (this.chromeImages_.right.height > 0);
- },
-
- get chromeQuad() {
- if (this.chromeQuad_)
- return this.chromeQuad_;
-
- // Draw the chrome border into a separate canvas.
- var chromeCanvas = document.createElement('canvas');
- var offsetY = this.chromeImages_.left.height;
-
- chromeCanvas.width = this.deviceRect_.width;
- chromeCanvas.height = this.deviceRect_.height + offsetY;
-
- var leftWidth = this.chromeImages_.left.width;
- var midWidth = this.chromeImages_.mid.width;
- var rightWidth = this.chromeImages_.right.width;
-
- var chromeCtx = chromeCanvas.getContext('2d');
- chromeCtx.drawImage(this.chromeImages_.left, 0, 0);
-
- chromeCtx.save();
- chromeCtx.translate(leftWidth, 0);
-
- // Calculate the scale of the mid image.
- var s = (this.deviceRect_.width - leftWidth - rightWidth) / midWidth;
- chromeCtx.scale(s, 1);
-
- chromeCtx.drawImage(this.chromeImages_.mid, 0, 0);
- chromeCtx.restore();
-
- chromeCtx.drawImage(
- this.chromeImages_.right, leftWidth + s * midWidth, 0);
-
- // Construct the quad.
- var chromeRect = base.Rect.fromXYWH(
- this.deviceRect_.x,
- this.deviceRect_.y - offsetY,
- this.deviceRect_.width,
- this.deviceRect_.height + offsetY);
- var chromeQuad = base.Quad.fromRect(chromeRect);
- chromeQuad.stackingGroupId = this.maxStackingGroupId_ + 1;
- chromeQuad.imageData = chromeCtx.getImageData(
- 0, 0, chromeCanvas.width, chromeCanvas.height);
- chromeQuad.shadowOffset = [0, 0];
- chromeQuad.shadowBlur = 5;
- chromeQuad.borderWidth = 3;
- this.chromeQuad_ = chromeQuad;
- return this.chromeQuad_;
- },
-
- scheduleRender: function() {
- if (this.redrawScheduled_)
- return false;
- this.redrawScheduled_ = true;
- base.requestAnimationFrame(this.render, this);
- },
-
- onRenderRequired_: function(e) {
- this.scheduleRender();
- },
-
- stackTransformAndProcessQuads_: function(
- numPasses, handleQuadFunc, includeChromeQuad, opt_arg1, opt_arg2) {
- var mv = this.camera_.modelViewMatrix;
- var p = this.camera_.projectionMatrix;
-
- var viewport = base.Rect.fromXYWH(
- 0, 0, this.canvas_.width, this.canvas_.height);
-
- // Calculate the quad stacks.
- var quadStacks = [];
- for (var i = 0; i < this.quads_.length; ++i) {
- var quad = this.quads_[i];
- var stackingId = quad.stackingGroupId || 0;
- while (stackingId >= quadStacks.length)
- quadStacks.push([]);
-
- quadStacks[stackingId].push(quad);
- }
-
- var mvp = mat4.create();
- this.maxStackingGroupId_ = quadStacks.length;
- var stackingDistance =
- this.stackingDistance_ * this.camera_.stackingDistanceDampening;
-
- // Draw the quad stacks, raising each subsequent level.
- mat4.multiply(mvp, p, mv);
- for (var i = 0; i < quadStacks.length; ++i) {
- transformAndProcessQuads(mvp, viewport, quadStacks[i],
- numPasses, handleQuadFunc,
- opt_arg1, opt_arg2);
-
- mat4.translate(mv, mv, [0, 0, stackingDistance]);
- mat4.multiply(mvp, p, mv);
- }
-
- if (includeChromeQuad && this.deviceRect_) {
- transformAndProcessQuads(mvp, viewport, [this.chromeQuad],
- numPasses, drawProjectedQuadToContext,
- opt_arg1, opt_arg2);
- }
- },
-
- render: function() {
- this.redrawScheduled_ = false;
-
- if (!this.readyToDraw()) {
- setTimeout(this.scheduleRender.bind(this),
- constants.IMAGE_LOAD_RETRY_TIME_MS);
- return;
- }
-
- if (!this.quads_)
- return;
-
- var canvasCtx = this.canvas_.getContext('2d');
- if (!this.resize())
- canvasCtx.clearRect(0, 0, this.canvas_.width, this.canvas_.height);
-
- var quadCanvas = document.createElement('canvas');
- this.stackTransformAndProcessQuads_(
- 3, drawProjectedQuadToContext, true,
- canvasCtx, quadCanvas);
- quadCanvas.width = 0; // Hack: Frees the quadCanvas' resources.
- },
-
- trackMouse_: function() {
- this.mouseModeSelector_ = new ui.MouseModeSelector(this);
- this.mouseModeSelector_.supportedModeMask =
- ui.MOUSE_SELECTOR_MODE.SELECTION |
- ui.MOUSE_SELECTOR_MODE.PANSCAN |
- ui.MOUSE_SELECTOR_MODE.ZOOM |
- ui.MOUSE_SELECTOR_MODE.ROTATE;
- this.mouseModeSelector_.mode = ui.MOUSE_SELECTOR_MODE.PANSCAN;
- this.mouseModeSelector_.pos = {x: 0, y: 100};
- this.appendChild(this.mouseModeSelector_);
- this.mouseModeSelector_.settingsKey =
- 'quadStackView.mouseModeSelector';
-
- this.mouseModeSelector_.setModifierForAlternateMode(
- ui.MOUSE_SELECTOR_MODE.ROTATE, ui.MODIFIER.SHIFT);
- this.mouseModeSelector_.setModifierForAlternateMode(
- ui.MOUSE_SELECTOR_MODE.PANSCAN, ui.MODIFIER.SPACE);
- this.mouseModeSelector_.setModifierForAlternateMode(
- ui.MOUSE_SELECTOR_MODE.ZOOM, ui.MODIFIER.CMD_OR_CTRL);
-
- this.mouseModeSelector_.addEventListener('updateselection',
- this.onSelectionUpdate_.bind(this));
- this.mouseModeSelector_.addEventListener('endselection',
- this.onSelectionUpdate_.bind(this));
- },
-
- extractRelativeMousePosition_: function(e) {
- var br = this.canvas_.getBoundingClientRect();
- return [
- this.pixelRatio_ * (e.clientX - this.canvas_.offsetLeft - br.left),
- this.pixelRatio_ * (e.clientY - this.canvas_.offsetTop - br.top)
- ];
- },
-
- onSelectionUpdate_: function(e) {
- var mousePos = this.extractRelativeMousePosition_(e);
- var res = [];
- function handleQuad(passNumber, quad, p1, p2, p3, p4) {
- if (base.pointInImplicitQuad(mousePos, p1, p2, p3, p4))
- res.push(quad);
- }
- this.stackTransformAndProcessQuads_(1, handleQuad, false);
- var e = new Event('selectionchange', false, false);
- e.quads = res;
- this.dispatchEvent(e);
- }
- };
-
- return {
- QuadStackView: QuadStackView
- };
-});