Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 5 | import * as LayerViewer from '../layer_viewer/layer_viewer.js'; |
| 6 | import * as SDK from '../sdk/sdk.js'; // eslint-disable-line no-unused-vars |
| 7 | import * as TimelineModel from '../timeline_model/timeline_model.js'; |
| 8 | import * as UI from '../ui/ui.js'; |
| 9 | |
| 10 | export class TimelinePaintProfilerView extends UI.SplitWidget.SplitWidget { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 11 | /** |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 12 | * @param {!TimelineModel.TimelineFrameModel.TimelineFrameModel} frameModel |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 13 | */ |
| 14 | constructor(frameModel) { |
| 15 | super(false, false); |
| 16 | this.element.classList.add('timeline-paint-profiler-view'); |
| 17 | this.setSidebarSize(60); |
| 18 | this.setResizable(false); |
| 19 | |
| 20 | this._frameModel = frameModel; |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 21 | this._logAndImageSplitWidget = new UI.SplitWidget.SplitWidget(true, false); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 22 | this._logAndImageSplitWidget.element.classList.add('timeline-paint-profiler-log-split'); |
| 23 | this.setMainWidget(this._logAndImageSplitWidget); |
Tim van der Lippe | 0176f6c | 2020-01-08 11:07:01 | [diff] [blame] | 24 | this._imageView = new TimelinePaintImageView(); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 25 | this._logAndImageSplitWidget.setMainWidget(this._imageView); |
| 26 | |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 27 | this._paintProfilerView = |
| 28 | new LayerViewer.PaintProfilerView.PaintProfilerView(this._imageView.showImage.bind(this._imageView)); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 29 | this._paintProfilerView.addEventListener( |
| 30 | LayerViewer.PaintProfilerView.Events.WindowChanged, this._onWindowChanged, this); |
| 31 | this.setSidebarWidget(this._paintProfilerView); |
| 32 | |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 33 | this._logTreeView = new LayerViewer.PaintProfilerView.PaintProfilerCommandLogView(); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 34 | this._logAndImageSplitWidget.setSidebarWidget(this._logTreeView); |
| 35 | |
| 36 | this._needsUpdateWhenVisible = false; |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 37 | /** @type {?SDK.PaintProfiler.PaintProfilerSnapshot} */ |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 38 | this._pendingSnapshot = null; |
| 39 | /** @type {?SDK.TracingModel.Event} */ |
| 40 | this._event = null; |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 41 | /** @type {?SDK.PaintProfiler.PaintProfilerModel} */ |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 42 | this._paintProfilerModel = null; |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 43 | /** @type {?SDK.PaintProfiler.PaintProfilerSnapshot} */ |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 44 | this._lastLoadedSnapshot = null; |
| 45 | } |
| 46 | |
| 47 | /** |
| 48 | * @override |
| 49 | */ |
| 50 | wasShown() { |
| 51 | if (this._needsUpdateWhenVisible) { |
| 52 | this._needsUpdateWhenVisible = false; |
| 53 | this._update(); |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | /** |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 58 | * @param {!SDK.PaintProfiler.PaintProfilerSnapshot} snapshot |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 59 | */ |
| 60 | setSnapshot(snapshot) { |
| 61 | this._releaseSnapshot(); |
| 62 | this._pendingSnapshot = snapshot; |
| 63 | this._event = null; |
| 64 | this._updateWhenVisible(); |
| 65 | } |
| 66 | |
| 67 | /** |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 68 | * @param {!SDK.PaintProfiler.PaintProfilerModel} paintProfilerModel |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 69 | * @param {!SDK.TracingModel.Event} event |
| 70 | * @return {boolean} |
| 71 | */ |
| 72 | setEvent(paintProfilerModel, event) { |
| 73 | this._releaseSnapshot(); |
| 74 | this._paintProfilerModel = paintProfilerModel; |
| 75 | this._pendingSnapshot = null; |
| 76 | this._event = event; |
| 77 | |
| 78 | this._updateWhenVisible(); |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 79 | if (this._event.name === TimelineModel.TimelineModel.RecordType.Paint) { |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 80 | return !!TimelineModel.TimelineModel.TimelineData.forEvent(event).picture; |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 81 | } |
| 82 | if (this._event.name === TimelineModel.TimelineModel.RecordType.RasterTask) { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 83 | return this._frameModel.hasRasterTile(this._event); |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 84 | } |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 85 | return false; |
| 86 | } |
| 87 | |
| 88 | _updateWhenVisible() { |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 89 | if (this.isShowing()) { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 90 | this._update(); |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 91 | } else { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 92 | this._needsUpdateWhenVisible = true; |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 93 | } |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | _update() { |
| 97 | this._logTreeView.setCommandLog([]); |
| 98 | this._paintProfilerView.setSnapshotAndLog(null, [], null); |
| 99 | |
Simon Zünd | b1a8ca5 | 2020-09-29 07:47:22 | [diff] [blame] | 100 | /** @type {!Promise<?{rect: ?Protocol.DOM.Rect, snapshot: !SDK.PaintProfiler.PaintProfilerSnapshot}>} */ |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 101 | let snapshotPromise; |
| 102 | if (this._pendingSnapshot) { |
| 103 | snapshotPromise = Promise.resolve({rect: null, snapshot: this._pendingSnapshot}); |
Simon Zünd | b1a8ca5 | 2020-09-29 07:47:22 | [diff] [blame] | 104 | } else if (this._event && this._event.name === TimelineModel.TimelineModel.RecordType.Paint) { |
| 105 | /** @type {!SDK.TracingModel.ObjectSnapshot} */ |
| 106 | const picture = /** @type {!SDK.TracingModel.ObjectSnapshot} */ ( |
| 107 | TimelineModel.TimelineModel.TimelineData.forEvent(this._event).picture); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 108 | snapshotPromise = picture.objectPromise() |
Simon Zünd | b1a8ca5 | 2020-09-29 07:47:22 | [diff] [blame] | 109 | .then( |
| 110 | data => /** @type {!SDK.PaintProfiler.PaintProfilerModel} */ (this._paintProfilerModel) |
| 111 | .loadSnapshot(data['skp64'])) |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 112 | .then(snapshot => snapshot && {rect: null, snapshot: snapshot}); |
Simon Zünd | b1a8ca5 | 2020-09-29 07:47:22 | [diff] [blame] | 113 | } else if (this._event && this._event.name === TimelineModel.TimelineModel.RecordType.RasterTask) { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 114 | snapshotPromise = this._frameModel.rasterTilePromise(this._event); |
| 115 | } else { |
| 116 | console.assert(false, 'Unexpected event type or no snapshot'); |
| 117 | return; |
| 118 | } |
| 119 | snapshotPromise.then(snapshotWithRect => { |
| 120 | this._releaseSnapshot(); |
| 121 | if (!snapshotWithRect) { |
| 122 | this._imageView.showImage(); |
| 123 | return; |
| 124 | } |
| 125 | const snapshot = snapshotWithRect.snapshot; |
| 126 | this._lastLoadedSnapshot = snapshot; |
| 127 | this._imageView.setMask(snapshotWithRect.rect); |
Simon Zünd | b1a8ca5 | 2020-09-29 07:47:22 | [diff] [blame] | 128 | snapshot.commandLog().then(log => onCommandLogDone.call(this, snapshot, snapshotWithRect.rect, log || [])); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 129 | }); |
| 130 | |
| 131 | /** |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 132 | * @param {!SDK.PaintProfiler.PaintProfilerSnapshot} snapshot |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 133 | * @param {?Protocol.DOM.Rect} clipRect |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 134 | * @param {!Array.<!SDK.PaintProfiler.PaintProfilerLogItem>=} log |
Tim van der Lippe | 0176f6c | 2020-01-08 11:07:01 | [diff] [blame] | 135 | * @this {TimelinePaintProfilerView} |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 136 | */ |
| 137 | function onCommandLogDone(snapshot, clipRect, log) { |
| 138 | this._logTreeView.setCommandLog(log || []); |
| 139 | this._paintProfilerView.setSnapshotAndLog(snapshot, log || [], clipRect); |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | _releaseSnapshot() { |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 144 | if (!this._lastLoadedSnapshot) { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 145 | return; |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 146 | } |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 147 | this._lastLoadedSnapshot.release(); |
| 148 | this._lastLoadedSnapshot = null; |
| 149 | } |
| 150 | |
| 151 | _onWindowChanged() { |
| 152 | this._logTreeView.updateWindow(this._paintProfilerView.selectionWindow()); |
| 153 | } |
Tim van der Lippe | 0176f6c | 2020-01-08 11:07:01 | [diff] [blame] | 154 | } |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 155 | |
| 156 | /** |
| 157 | * @unrestricted |
| 158 | */ |
Tim van der Lippe | cec9b76 | 2020-02-13 15:31:22 | [diff] [blame] | 159 | export class TimelinePaintImageView extends UI.Widget.Widget { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 160 | constructor() { |
| 161 | super(true); |
Jack Franklin | 71519f8 | 2020-11-03 12:08:59 | [diff] [blame^] | 162 | this.registerRequiredCSS('timeline/timelinePaintProfiler.css', {enableLegacyPatching: true}); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 163 | this.contentElement.classList.add('fill', 'paint-profiler-image-view'); |
| 164 | this._imageContainer = this.contentElement.createChild('div', 'paint-profiler-image-container'); |
Simon Zünd | b1a8ca5 | 2020-09-29 07:47:22 | [diff] [blame] | 165 | /** @type {!HTMLImageElement} */ |
| 166 | this._imageElement = /** @type {!HTMLImageElement} */ (this._imageContainer.createChild('img')); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 167 | this._maskElement = this._imageContainer.createChild('div'); |
| 168 | this._imageElement.addEventListener('load', this._updateImagePosition.bind(this), false); |
| 169 | |
Alex Rudenko | b151cb2 | 2020-10-12 13:47:05 | [diff] [blame] | 170 | this._transformController = new LayerViewer.TransformController.TransformController( |
| 171 | /** @type {!HTMLElement} */ (this.contentElement), true); |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 172 | this._transformController.addEventListener( |
| 173 | LayerViewer.TransformController.Events.TransformChanged, this._updateImagePosition, this); |
| 174 | } |
| 175 | |
| 176 | /** |
| 177 | * @override |
| 178 | */ |
| 179 | onResize() { |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 180 | if (this._imageElement.src) { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 181 | this._updateImagePosition(); |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 182 | } |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | _updateImagePosition() { |
| 186 | const width = this._imageElement.naturalWidth; |
| 187 | const height = this._imageElement.naturalHeight; |
| 188 | const clientWidth = this.contentElement.clientWidth; |
| 189 | const clientHeight = this.contentElement.clientHeight; |
| 190 | |
| 191 | const paddingFraction = 0.1; |
| 192 | const paddingX = clientWidth * paddingFraction; |
| 193 | const paddingY = clientHeight * paddingFraction; |
| 194 | const scaleX = (clientWidth - paddingX) / width; |
| 195 | const scaleY = (clientHeight - paddingY) / height; |
| 196 | const scale = Math.min(scaleX, scaleY); |
| 197 | |
| 198 | if (this._maskRectangle) { |
| 199 | const style = this._maskElement.style; |
| 200 | style.width = width + 'px'; |
| 201 | style.height = height + 'px'; |
| 202 | style.borderLeftWidth = this._maskRectangle.x + 'px'; |
| 203 | style.borderTopWidth = this._maskRectangle.y + 'px'; |
| 204 | style.borderRightWidth = (width - this._maskRectangle.x - this._maskRectangle.width) + 'px'; |
| 205 | style.borderBottomWidth = (height - this._maskRectangle.y - this._maskRectangle.height) + 'px'; |
| 206 | } |
| 207 | this._transformController.setScaleConstraints(0.5, 10 / scale); |
| 208 | let matrix = new WebKitCSSMatrix() |
| 209 | .scale(this._transformController.scale(), this._transformController.scale()) |
| 210 | .translate(clientWidth / 2, clientHeight / 2) |
| 211 | .scale(scale, scale) |
| 212 | .translate(-width / 2, -height / 2); |
| 213 | const bounds = UI.Geometry.boundsForTransformedPoints(matrix, [0, 0, 0, width, height, 0]); |
| 214 | this._transformController.clampOffsets( |
| 215 | paddingX - bounds.maxX, clientWidth - paddingX - bounds.minX, paddingY - bounds.maxY, |
| 216 | clientHeight - paddingY - bounds.minY); |
| 217 | matrix = new WebKitCSSMatrix() |
| 218 | .translate(this._transformController.offsetX(), this._transformController.offsetY()) |
| 219 | .multiply(matrix); |
| 220 | this._imageContainer.style.webkitTransform = matrix.toString(); |
| 221 | } |
| 222 | |
| 223 | /** |
| 224 | * @param {string=} imageURL |
| 225 | */ |
| 226 | showImage(imageURL) { |
| 227 | this._imageContainer.classList.toggle('hidden', !imageURL); |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 228 | if (imageURL) { |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 229 | this._imageElement.src = imageURL; |
Tim van der Lippe | 1d6e57a | 2019-09-30 11:55:34 | [diff] [blame] | 230 | } |
Blink Reformat | 4c46d09 | 2018-04-07 15:32:37 | [diff] [blame] | 231 | } |
| 232 | |
| 233 | /** |
| 234 | * @param {?Protocol.DOM.Rect} maskRectangle |
| 235 | */ |
| 236 | setMask(maskRectangle) { |
| 237 | this._maskRectangle = maskRectangle; |
| 238 | this._maskElement.classList.toggle('hidden', !maskRectangle); |
| 239 | } |
Tim van der Lippe | 0176f6c | 2020-01-08 11:07:01 | [diff] [blame] | 240 | } |