Keep offset for composite background color animation

At this moment, our implementation only keeps the first and the
last keyframes for composite background color animation. This is
wrong, for example, we can having multiple keyframes like:
0%: { background-color: red }
10%: { background-color: green}
100% { background-color: blue}

This CL fixes the issue. The idea is to keep the offset which
we stored in CompositorKeyframeValues. In the above case, the
offsets would be [0, 0.1, 1].

Once we have that, here is how we do interpolation. Say that
the current progress is 0.4, then we know that it falls in to
the range of [0.1, 1], which means we need to interpolate from
green to blue. We need to adjust the progress (0.4) based on the
offsets. Basically scale [0.1, 1] to [0, 1], then the adjusted
progress should be (0.4-0.1) / (1-0.1). Layout tests are added
to ensure correctness.

Bug: 1153671
Change-Id: I6dffc82b5821fdf418f2b94331f567a239079730
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2597844
Commit-Queue: Xida Chen <xidachen@chromium.org>
Reviewed-by: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#841476}
diff --git a/css/css-backgrounds/animations/one-element-three-keyframes-animation1.html b/css/css-backgrounds/animations/one-element-three-keyframes-animation1.html
new file mode 100644
index 0000000..380c5d3
--- /dev/null
+++ b/css/css-backgrounds/animations/one-element-three-keyframes-animation1.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#background-color">
+<link rel="match" href="one-element-animation-ref.html">
+<style>
+.container {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+  /* Use a long animation that start at 5% progress where the slope of the
+     selected timing function is zero. By setting up the animation in this way,
+     we accommodate lengthy delays in running the test without a potential drift
+     in the animated property value. This is important for avoiding flakes,
+     especially on debug builds. The screenshots are taken as soon as the
+     animation is ready, thus the long animation duration has no bearing on
+     the actual duration of the test. */
+  animation: bgcolor 1000000s cubic-bezier(0,1,1,0) -50000s;
+}
+@keyframes bgcolor {
+  0% { background-color: rgb(0, 200, 0); }
+  10% {
+    background-color: rgb(200, 0, 0);
+    animation-timing-function: cubic-bezier(0,1,1,0);
+  }
+  100% {
+    background-color: rgb(0, 0, 200);
+    animation-timing-function: cubic-bezier(0,1,1,0);
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<body>
+<div class="container"></div>
+
+<script>
+// This test and the "one-element-three-keyframes-animation2.html" ensure that
+// we select the correct start and end keyframes for interpolation. In this
+// test, the start delay of the animation makes it jump to 5% right away, and in
+// the "one-element-three-keyframes-animation2.html" the start delay makes it
+// jump to 50%. So for this test, we would choose the keyframes at 0% and 10%
+// for interpolation, where for the other test it would be 10% and 100%.
+document.getAnimations()[0].ready.then(() => {
+  takeScreenshot();
+});
+</script>
+</body>
+</html>
diff --git a/css/css-backgrounds/animations/one-element-three-keyframes-animation2-ref.html b/css/css-backgrounds/animations/one-element-three-keyframes-animation2-ref.html
new file mode 100644
index 0000000..823d8ac
--- /dev/null
+++ b/css/css-backgrounds/animations/one-element-three-keyframes-animation2-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<body>
+  <canvas id="canvas" width="100" height="100"></canvas>
+</body>
+<script>
+  var canvas = document.getElementById('canvas');
+  var ctx = canvas.getContext('2d');
+  ctx.fillStyle = 'rgb(100, 0, 100)';
+  ctx.fillRect(0, 0, 100, 100);
+</script>
diff --git a/css/css-backgrounds/animations/one-element-three-keyframes-animation2.html b/css/css-backgrounds/animations/one-element-three-keyframes-animation2.html
new file mode 100644
index 0000000..e71b858
--- /dev/null
+++ b/css/css-backgrounds/animations/one-element-three-keyframes-animation2.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#background-color">
+<link rel="match" href="one-element-three-keyframes-animation2-ref.html">
+<style>
+.container {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+  /* Use a long animation that start at 50% progress where the slope of the
+     selected timing function is zero. By setting up the animation in this way,
+     we accommodate lengthy delays in running the test without a potential drift
+     in the animated property value. This is important for avoiding flakes,
+     especially on debug builds. The screenshots are taken as soon as the
+     animation is ready, thus the long animation duration has no bearing on
+     the actual duration of the test. */
+  animation: bgcolor 1000000s cubic-bezier(0,1,1,0) -500000s;
+}
+@keyframes bgcolor {
+  0% { background-color: rgb(0, 200, 0); }
+  10% {
+    background-color: rgb(200, 0, 0);
+    animation-timing-function: cubic-bezier(0,1,1,0);
+  }
+  100% {
+    background-color: rgb(0, 0, 200);
+    animation-timing-function: cubic-bezier(0,1,1,0);
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<body>
+<div class="container"></div>
+
+<script>
+// The start delay of the animation makes it jump 50% of the animation, which
+// means we would select the keyframes at 10% and 100% for animation. The
+// progress would be (0.5-0.1) / (1-0.1) = 0.44. So a timing function input of
+// 0.44 results in an output of 0.5.
+document.getAnimations()[0].ready.then(() => {
+  takeScreenshot();
+});
+</script>
+</body>
+</html>
diff --git a/css/css-backgrounds/animations/one-element-three-keyframes-animation3.html b/css/css-backgrounds/animations/one-element-three-keyframes-animation3.html
new file mode 100644
index 0000000..080ed01
--- /dev/null
+++ b/css/css-backgrounds/animations/one-element-three-keyframes-animation3.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#background-color">
+<link rel="match" href="one-element-animation-ref.html">
+<style>
+.container {
+  width: 100px;
+  height: 100px;
+  background-color: green;
+  /* Use a long animation that start at 5% progress where the slope of the
+     selected timing function is zero. By setting up the animation in this way,
+     we accommodate lengthy delays in running the test without a potential drift
+     in the animated property value. This is important for avoiding flakes,
+     especially on debug builds. The screenshots are taken as soon as the
+     animation is ready, thus the long animation duration has no bearing on
+     the actual duration of the test. */
+  animation: bgcolor 1000000s cubic-bezier(0,1,1,0) -50000s;
+}
+@keyframes bgcolor {
+  10% {
+    background-color: rgb(200, 0, 0);
+    animation-timing-function: cubic-bezier(0,1,1,0);
+  }
+  0% { background-color: rgb(0, 200, 0); }
+  100% {
+    background-color: rgb(0, 0, 200);
+    animation-timing-function: cubic-bezier(0,1,1,0);
+  }
+}
+</style>
+<script src="/common/reftest-wait.js"></script>
+<body>
+<div class="container"></div>
+
+<script>
+document.getAnimations()[0].ready.then(() => {
+  takeScreenshot();
+});
+</script>
+</body>
+</html>