Improve chrome_slice rendering perf
The slow rendering was caused by using
CanvasRenderingContext2D.createLinearGradient
Instead, we'll now draw 2 distinct rectangles.
Bug: 200161775
Change-Id: I20b342b0eca8dbeede66f997c02e047c66c5ee64
diff --git a/ui/src/common/canvas_utils.ts b/ui/src/common/canvas_utils.ts
index 96c0fc9..0835bad 100644
--- a/ui/src/common/canvas_utils.ts
+++ b/ui/src/common/canvas_utils.ts
@@ -71,22 +71,22 @@
ctx: CanvasRenderingContext2D,
x: number,
y: number,
- length: number,
width: number,
+ height: number,
color: string) {
ctx.beginPath();
ctx.fillStyle = color;
- const triangleSize = width / 4;
+ const triangleSize = height / 4;
ctx.moveTo(x, y);
- ctx.lineTo(x + length, y);
- ctx.lineTo(x + length - 3, y + triangleSize * 0.5);
- ctx.lineTo(x + length, y + triangleSize);
- ctx.lineTo(x + length - 3, y + (triangleSize * 1.5));
- ctx.lineTo(x + length, y + 2 * triangleSize);
- ctx.lineTo(x + length - 3, y + (triangleSize * 2.5));
- ctx.lineTo(x + length, y + 3 * triangleSize);
- ctx.lineTo(x + length - 3, y + (triangleSize * 3.5));
- ctx.lineTo(x + length, y + 4 * triangleSize);
- ctx.lineTo(x, y + width);
+ ctx.lineTo(x + width, y);
+ ctx.lineTo(x + width - 3, y + triangleSize * 0.5);
+ ctx.lineTo(x + width, y + triangleSize);
+ ctx.lineTo(x + width - 3, y + (triangleSize * 1.5));
+ ctx.lineTo(x + width, y + 2 * triangleSize);
+ ctx.lineTo(x + width - 3, y + (triangleSize * 2.5));
+ ctx.lineTo(x + width, y + 3 * triangleSize);
+ ctx.lineTo(x + width - 3, y + (triangleSize * 3.5));
+ ctx.lineTo(x + width, y + 4 * triangleSize);
+ ctx.lineTo(x, y + height);
ctx.fill();
}
\ No newline at end of file
diff --git a/ui/src/tracks/chrome_slices/frontend.ts b/ui/src/tracks/chrome_slices/frontend.ts
index e5990bb..125d9c4 100644
--- a/ui/src/tracks/chrome_slices/frontend.ts
+++ b/ui/src/tracks/chrome_slices/frontend.ts
@@ -115,16 +115,6 @@
}
ctx.fillStyle = color;
- if (isThreadSlice) {
- const cpuTimeRatio = data.cpuTimeRatio![i];
- const [GradientHue, GradientSaturation, GradientLightness] =
- hslForThreadIdleSlice(hue, saturation, lightness, hasFocus);
- const gradientColor =
- hsluvToHex([GradientHue, GradientSaturation, GradientLightness]);
- ctx.fillStyle = this.createGradientForThreadSlice(
- tStart, tEnd, cpuTimeRatio, color, gradientColor, ctx);
- }
-
// We draw instant events as upward facing chevrons starting at A:
// A
// ###
@@ -161,12 +151,28 @@
}
continue;
}
+
if (isIncomplete && rect.width > SLICE_HEIGHT / 4) {
drawIncompleteSlice(
ctx, rect.left, rect.top, rect.width, SLICE_HEIGHT, color);
+ } else if (isThreadSlice) {
+ // We draw two rectangles, representing the ratio between wall time and
+ // time spent on cpu.
+ const cpuTimeRatio = data.cpuTimeRatio![i];
+ const firstPartWidth = rect.width * cpuTimeRatio;
+ const secondPartWidth = rect.width * (1 - cpuTimeRatio);
+ ctx.fillRect(rect.left, rect.top, firstPartWidth, SLICE_HEIGHT);
+ ctx.fillStyle = hsluvToHex(
+ hslForThreadIdleSlice(hue, saturation, lightness, hasFocus));
+ ctx.fillRect(
+ rect.left + firstPartWidth,
+ rect.top,
+ secondPartWidth,
+ SLICE_HEIGHT);
} else {
ctx.fillRect(rect.left, rect.top, rect.width, SLICE_HEIGHT);
}
+
// Selected case
if (isSelected) {
drawRectOnSelected = () => {
@@ -282,23 +288,6 @@
!(tEnd <= visibleWindowTime.start || tStart >= visibleWindowTime.end)
};
}
-
- createGradientForThreadSlice(
- tStart: number, tEnd: number, cpuTimeRatio: number, color: string,
- gradientColor: string, ctx: CanvasRenderingContext2D): CanvasGradient {
- const timeScale = globals.frontendLocalState.timeScale;
- const {start: windowStart, end: windowEnd} =
- globals.frontendLocalState.visibleWindowTime;
- const start = isFinite(timeScale.timeToPx(tStart)) ?
- timeScale.timeToPx(tStart) :
- windowStart;
- const end = isFinite(timeScale.timeToPx(tEnd)) ? timeScale.timeToPx(tEnd) :
- windowEnd;
- const gradient = ctx.createLinearGradient(start, 0, end, 0);
- gradient.addColorStop(cpuTimeRatio, color);
- gradient.addColorStop(cpuTimeRatio, gradientColor);
- return gradient;
- }
}
trackRegistry.register(ChromeSliceTrack);