Commit e0f4a6eb authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[devtools] Display coverage in timeline

Sample: https://imgur.com/a/NmdDrkc

Bug: chromium:1004203
Change-Id: I8bae4fcd3db4ad54322883c673002e28f67be3f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1818524
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: default avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699781}
parent 2c3a7f3d
...@@ -36,6 +36,13 @@ Timeline.PerformanceModel = class extends Common.Object { ...@@ -36,6 +36,13 @@ Timeline.PerformanceModel = class extends Common.Object {
this._mainTarget = target; this._mainTarget = target;
} }
/**
* @return {?SDK.Target}
*/
mainTarget() {
return this._mainTarget;
}
/** /**
* @param {number} time * @param {number} time
*/ */
......
...@@ -704,3 +704,113 @@ Timeline.Quantizer = class { ...@@ -704,3 +704,113 @@ Timeline.Quantizer = class {
this._remainder = this._quantDuration - interval; this._remainder = this._quantDuration - interval;
} }
}; };
/**
* @unrestricted
*/
Timeline.TimelineEventOverviewCoverage = class extends Timeline.TimelineEventOverview {
constructor() {
super('coverage', Common.UIString('COVERAGE'));
this._heapSizeLabel = this.element.createChild('div', 'timeline-overview-coverage-label');
}
resetHeapSizeLabels() {
this._heapSizeLabel.textContent = '';
}
/**
* @override
* @param {?Timeline.PerformanceModel} model
*/
setModel(model) {
super.setModel(model);
if (this._model)
this._coverageModel = model.mainTarget().model(Coverage.CoverageModel);
}
/**
* @override
*/
update() {
super.update();
const ratio = window.devicePixelRatio;
if (!this._coverageModel)
return;
let total = 0;
let total_used = 0;
const usedByTimestamp = new Map();
for (const urlInfo of this._coverageModel.entries()) {
for (const info of urlInfo.entries()) {
total += info.size();
for (const [stamp, used] of info.usedByTimestamp()) {
total_used += used;
if (!usedByTimestamp.has(stamp))
usedByTimestamp.set(stamp, used);
else
usedByTimestamp.set(stamp, usedByTimestamp.get(stamp) + used);
}
}
}
const percentUsed = total ? Math.round(100 * total_used / total) : 0;
const lowerOffset = 3 * ratio;
const minTime = this._model.recordStartTime();
const maxTime =
minTime + (this._model.timelineModel().maximumRecordTime() - this._model.timelineModel().minimumRecordTime());
const lineWidth = 1;
const width = this.width();
const height = this.height() - lowerOffset;
const xFactor = width / (maxTime - minTime);
const yFactor = (height - lineWidth) / Math.max(total, 1);
let y = 0;
const ctx = this.context();
const heightBeyondView = height + lowerOffset + lineWidth;
ctx.translate(0.5, 0.5);
ctx.beginPath();
ctx.moveTo(-lineWidth, heightBeyondView);
ctx.lineTo(-lineWidth, height - y);
const entries = Array.from(usedByTimestamp.entries()).sort((a, b) => a[0] - b[0]);
let cummulative_used = 0;
for (const [stamp, used] of entries) {
if (stamp > maxTime)
break;
const x = (stamp - minTime) * xFactor;
cummulative_used += used;
y = cummulative_used * yFactor;
ctx.lineTo(x, height - y);
}
ctx.lineTo(width + lineWidth, height - y);
ctx.lineTo(width + lineWidth, heightBeyondView);
ctx.closePath();
ctx.fillStyle = 'hsla(220, 90%, 70%, 0.2)';
ctx.fill();
ctx.lineWidth = lineWidth;
ctx.strokeStyle = 'hsl(220, 90%, 70%)';
ctx.stroke();
cummulative_used = 0;
for (const [stamp, used] of entries) {
if (stamp > maxTime)
break;
cummulative_used += used;
ctx.beginPath();
const x = (stamp - minTime) * xFactor;
ctx.arc(x, height - cummulative_used * yFactor, 2 * lineWidth, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.stroke();
ctx.fill();
}
this._heapSizeLabel.textContent = `${percentUsed}% used`;
}
};
...@@ -430,6 +430,8 @@ Timeline.TimelinePanel = class extends UI.Panel { ...@@ -430,6 +430,8 @@ Timeline.TimelinePanel = class extends UI.Panel {
this._overviewControls.push(new Timeline.TimelineFilmStripOverview()); this._overviewControls.push(new Timeline.TimelineFilmStripOverview());
if (this._showMemorySetting.get()) if (this._showMemorySetting.get())
this._overviewControls.push(new Timeline.TimelineEventOverviewMemory()); this._overviewControls.push(new Timeline.TimelineEventOverviewMemory());
if (this._startCoverage.get())
this._overviewControls.push(new Timeline.TimelineEventOverviewCoverage());
for (const control of this._overviewControls) for (const control of this._overviewControls)
control.setModel(this._performanceModel); control.setModel(this._performanceModel);
this._overviewPane.setOverviewControls(this._overviewControls); this._overviewPane.setOverviewControls(this._overviewControls);
...@@ -771,7 +773,8 @@ Timeline.TimelinePanel = class extends UI.Panel { ...@@ -771,7 +773,8 @@ Timeline.TimelinePanel = class extends UI.Panel {
if (this._startCoverage.get()) { if (this._startCoverage.get()) {
UI.viewManager.showView('coverage') UI.viewManager.showView('coverage')
.then(() => UI.viewManager.view('coverage').widget()) .then(() => UI.viewManager.view('coverage').widget())
.then(widget => widget.stopRecording()); .then(widget => widget.stopRecording())
.then(() => this._updateOverviewControls());
} }
} }
......
...@@ -220,6 +220,7 @@ ...@@ -220,6 +220,7 @@
], ],
"dependencies": [ "dependencies": [
"components", "components",
"coverage",
"layer_viewer", "layer_viewer",
"timeline_model", "timeline_model",
"perf_ui", "perf_ui",
......
...@@ -240,6 +240,21 @@ ...@@ -240,6 +240,21 @@
line-height: 18px; line-height: 18px;
} }
#timeline-overview-coverage {
flex-basis: 20px;
}
.timeline-overview-coverage-label {
position: absolute;
right: 0;
bottom: 0;
font-size: 9px;
color: #888;
white-space: nowrap;
padding: 0 4px;
background-color: hsla(0, 0%, 100%, 0.8);
}
.timeline-details { .timeline-details {
vertical-align: top; vertical-align: top;
} }
......
...@@ -639,6 +639,9 @@ Then, zoom and pan the timeline with the mousewheel or <ph name="NAVIGATENODE">$ ...@@ -639,6 +639,9 @@ Then, zoom and pan the timeline with the mousewheel or <ph name="NAVIGATENODE">$
<message name="IDS_DEVTOOLS_a580a76abe8b0912889d80f5c4cb9559" desc="Text in Timeline Tree View of the Performance panel"> <message name="IDS_DEVTOOLS_a580a76abe8b0912889d80f5c4cb9559" desc="Text in Timeline Tree View of the Performance panel">
Group by Product Group by Product
</message> </message>
<message name="IDS_DEVTOOLS_a5d91e1697b7c75863fb9c6163a3446e" desc="Text in Timeline Event Overview of the Performance panel">
COVERAGE
</message>
<message name="IDS_DEVTOOLS_a6f22a2373839a1d417d7a4078f0383a" desc="Text in Timeline Panel of the Performance panel"> <message name="IDS_DEVTOOLS_a6f22a2373839a1d417d7a4078f0383a" desc="Text in Timeline Panel of the Performance panel">
- CPU throttling is enabled - CPU throttling is enabled
</message> </message>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment