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);