[system-analyzer] Support thin ticks
Add better support for lots of thin ticks by: * Removing stroke on ticks (so that the stroke isn't thicker than the tick itself) * Alternating colours of the ticks between light and dark (so that neighbouring ticks are still distinguishable) * Making selection drawing use isInputPending to allow faster looping over multiple ticks. Change-Id: Iaa13fe4820d3d3168e085dfc01d7581cbc1739f0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2959626 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Auto-Submit: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#75146}
This commit is contained in:
parent
9468be4ab7
commit
79b6158757
@ -62,7 +62,7 @@ DOM.defineCustomElement('view/code-panel',
|
|||||||
for (const code of this._selectedEntries) {
|
for (const code of this._selectedEntries) {
|
||||||
const option = DOM.element('option');
|
const option = DOM.element('option');
|
||||||
option.text =
|
option.text =
|
||||||
`${code.name}(...) t=${formatMicroSeconds(code.time)} size=${
|
`${code.functionName}(...) t=${formatMicroSeconds(code.time)} size=${
|
||||||
formatBytes(code.size)} script=${code.script?.toString()}`;
|
formatBytes(code.size)} script=${code.script?.toString()}`;
|
||||||
option.data = code;
|
option.data = code;
|
||||||
select.add(option);
|
select.add(option);
|
||||||
|
@ -185,9 +185,7 @@ found in the LICENSE file. -->
|
|||||||
font-size: 9px;
|
font-size: 9px;
|
||||||
}
|
}
|
||||||
.flame {
|
.flame {
|
||||||
stroke: var(--background-color);
|
stroke-width: 0;
|
||||||
stroke-width: 1;
|
|
||||||
vector-effect: non-scaling-stroke;
|
|
||||||
}
|
}
|
||||||
.flameSelected {
|
.flameSelected {
|
||||||
fill: var(--on-background-color);
|
fill: var(--on-background-color);
|
||||||
|
@ -6,11 +6,11 @@ import {delay} from '../../helper.mjs';
|
|||||||
import {TickLogEntry} from '../../log/tick.mjs';
|
import {TickLogEntry} from '../../log/tick.mjs';
|
||||||
import {Timeline} from '../../timeline.mjs';
|
import {Timeline} from '../../timeline.mjs';
|
||||||
import {SelectTimeEvent} from '../events.mjs';
|
import {SelectTimeEvent} from '../events.mjs';
|
||||||
import {DOM, SVG} from '../helper.mjs';
|
import {CSSColor, DOM, SVG} from '../helper.mjs';
|
||||||
|
|
||||||
import {TimelineTrackBase} from './timeline-track-base.mjs'
|
import {TimelineTrackBase} from './timeline-track-base.mjs'
|
||||||
|
|
||||||
const kFlameHeight = 10;
|
const kFlameHeight = 8;
|
||||||
|
|
||||||
class Flame {
|
class Flame {
|
||||||
constructor(time, entry, depth, id) {
|
constructor(time, entry, depth, id) {
|
||||||
@ -187,22 +187,25 @@ DOM.defineCustomElement('view/timeline/timeline-track', 'timeline-track-tick',
|
|||||||
add();
|
add();
|
||||||
await delay(50);
|
await delay(50);
|
||||||
}
|
}
|
||||||
buffer += this.drawFlame(rawFlames[i]);
|
buffer += this.drawFlame(rawFlames[i], i);
|
||||||
}
|
}
|
||||||
add();
|
add();
|
||||||
}
|
}
|
||||||
|
|
||||||
drawFlame(flame, outline = false) {
|
drawFlame(flame, i, outline = false) {
|
||||||
const x = this.timeToPosition(flame.time);
|
const x = this.timeToPosition(flame.time);
|
||||||
const y = (flame.depth + 1) * kFlameHeight;
|
const y = (flame.depth + 1) * kFlameHeight;
|
||||||
let width = flame.duration * this._timeToPixel;
|
let width = flame.duration * this._timeToPixel;
|
||||||
if (outline) {
|
if (outline) {
|
||||||
return `<rect x=${x} y=${y} width=${width} height=${
|
return `<rect x=${x} y=${y} width=${width} height=${
|
||||||
kFlameHeight} class=flameSelected />`;
|
kFlameHeight - 1} class=flameSelected />`;
|
||||||
}
|
}
|
||||||
const color = this._legend.colorForType(flame.type);
|
let color = this._legend.colorForType(flame.type);
|
||||||
return `<rect x=${x} y=${y} width=${width} height=${kFlameHeight} fill=${
|
if (i % 2 == 1) {
|
||||||
color} class=flame />`;
|
color = CSSColor.darken(color, 20);
|
||||||
|
}
|
||||||
|
return `<rect x=${x} y=${y} width=${width} height=${
|
||||||
|
kFlameHeight - 1} fill=${color} class=flame />`;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawFlameText(flame) {
|
drawFlameText(flame) {
|
||||||
@ -258,29 +261,41 @@ class Annotations {
|
|||||||
const start = this._flames.find(time);
|
const start = this._flames.find(time);
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
// Draw annotations gradually outwards starting form the given time.
|
// Draw annotations gradually outwards starting form the given time.
|
||||||
|
let deadline = performance.now() + 500;
|
||||||
for (let range = 0; range < this._flames.length; range += 10000) {
|
for (let range = 0; range < this._flames.length; range += 10000) {
|
||||||
this._markFlames(start - range, start - offset);
|
this._markFlames(start - range, start - offset);
|
||||||
this._markFlames(start + offset, start + range);
|
this._markFlames(start + offset, start + range);
|
||||||
offset = range;
|
offset = range;
|
||||||
await delay(50);
|
if (navigator.scheduling.isInputPending({includeContinuous: true}) ||
|
||||||
// Abort if we started another update asynchronously.
|
performance.now() >= deadline) {
|
||||||
if (this._logEntry != logEntry) return;
|
// Yield if we have to handle an input event, or we're out of time.
|
||||||
|
await delay(50);
|
||||||
|
// Abort if we started another update asynchronously.
|
||||||
|
if (this._logEntry != logEntry) return;
|
||||||
|
|
||||||
|
deadline = performance.now() + 500;
|
||||||
|
}
|
||||||
|
this._drawBuffer();
|
||||||
}
|
}
|
||||||
|
this._drawBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
_markFlames(start, end) {
|
_markFlames(start, end) {
|
||||||
const rawFlames = this._flames.values;
|
const rawFlames = this._flames.values;
|
||||||
if (start < 0) start = 0;
|
if (start < 0) start = 0;
|
||||||
if (end > rawFlames.length) end = rawFlames.length;
|
if (end > rawFlames.length) end = rawFlames.length;
|
||||||
const code = this._logEntry.entry;
|
const logEntry = this._logEntry;
|
||||||
// Also compare against the function
|
// Also compare against the function, if any.
|
||||||
const func = code.func ?? 0;
|
const func = logEntry.entry?.func;
|
||||||
for (let i = start; i < end; i++) {
|
for (let i = start; i < end; i++) {
|
||||||
const flame = rawFlames[i];
|
const flame = rawFlames[i];
|
||||||
if (flame.entry !== code && flame.entry?.func !== func) continue;
|
if (!flame.entry) continue;
|
||||||
this._buffer += this._track.drawFlame(flame, true);
|
if (flame.entry.logEntry !== logEntry &&
|
||||||
|
(!func || flame.entry.func !== func)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this._buffer += this._track.drawFlame(flame, i, true);
|
||||||
}
|
}
|
||||||
this._drawBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_drawBuffer() {
|
_drawBuffer() {
|
||||||
|
Loading…
Reference in New Issue
Block a user