Enable compositing multiple transform properties.

Bug: 696374
Change-Id: Idcd0982147f2f6d748b11ecf4584fd7f00821f90
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3677382
Reviewed-by: Robert Flack <flackr@chromium.org>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1011015}
diff --git a/css/css-transforms/individual-transform/animation/individual-transform-combine-ref.html b/css/css-transforms/individual-transform/animation/individual-transform-combine-ref.html
new file mode 100644
index 0000000..7c8eb20
--- /dev/null
+++ b/css/css-transforms/individual-transform/animation/individual-transform-combine-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Individual transform: combine individual transform properties</title>
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
+    <style>
+      .block {
+        display:  inline-block;
+        width: 50px;
+        height: 50px;
+        margin:  50px;
+        padding:  0;
+        transform-origin: center center;
+        background:  lime;
+        transform: rotate(90deg) scale(2, 1);
+      }
+    </style>
+  </head>
+  <body>
+    <div>
+      <div class="block"></div>
+      <div class="block"></div>
+    </div>
+    <div>
+      <div class="block"></div>
+      <div class="block"></div>
+    </div>
+    <div>
+      <div class="block"></div>
+      <div class="block"></div>
+    </div>
+  </body>
+</html>
diff --git a/css/css-transforms/individual-transform/animation/individual-transform-combine.html b/css/css-transforms/individual-transform/animation/individual-transform-combine.html
new file mode 100644
index 0000000..9551a3a
--- /dev/null
+++ b/css/css-transforms/individual-transform/animation/individual-transform-combine.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Individual transform: combine individual transform properties</title>
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
+    <meta name="assert" content="Tests that we combine animated transformations with the underlying style correctly."/>
+    <link rel="match" href="individual-transform-combine-ref.html">
+    <style>
+      .block {
+        display:  inline-block;
+        width: 50px;
+        height: 50px;
+        margin:  50px;
+        padding:  0;
+        transform-origin: center center;
+        background:  lime;
+        /* Freeze the animation at the midpoint. */
+        animation-timing-function: cubic-bezier(0, 1, 1, 0);
+        animation-duration:  1000000s;
+        animation-delay:  -500000s;
+      }
+
+      @keyframes anim-1 {
+        to { rotate: 180deg; }
+      }
+      #div-1 {
+        scale:  2 1;
+        animation-name: anim-1;
+      }
+
+      @keyframes anim-2 {
+        from { scale: 1 1; }
+        to { scale: 3 1; }
+      }
+      #div-2 {
+        /* The scale property is replaced in the animation. */
+        scale: 1 3;
+        rotate: 90deg;
+        animation-name:  anim-2;
+      }
+
+      @keyframes anim-3 {
+        to { rotate: 180deg; }
+      }
+      #div-3 {
+        transform: scale(2, 1);
+        animation-name:  anim-3;
+      }
+
+      @keyframes anim-4 {
+        to { transform: scale(7, 1); }
+      }
+      #div-4 {
+        rotate:  90deg;
+        /* As transform is a separate property from scale, the two scales are
+           chained together. */
+        scale:  0.5 1;
+        animation-name: anim-4;
+      }
+
+      /* transform origin tests */
+
+      @keyframes anim-5 {
+        to { rotate: 180deg; translate: 100px -50px; }
+      }
+      #div-5 {
+        transform-origin: top left;
+        scale:  2 1;
+        animation-name: anim-5;
+      }
+
+      @keyframes anim-6 {
+        to { rotate: 180deg; translate: -100px 50px; }
+      }
+      #div-6 {
+        transform-origin: bottom right;
+        scale:  2 1;
+        animation-name: anim-6;
+      }
+
+    </style>
+  </head>
+  <body>
+    <div>
+      <div id="div-1" class="block"></div>
+      <div id="div-2" class="block"></div>
+    </div>
+    <div>
+      <div id="div-3" class="block"></div>
+      <div id="div-4" class="block"></div>
+    </div>
+    <div>
+      <div id="div-5" class="block"></div>
+      <div id="div-6" class="block"></div>
+    </div>
+
+  </body>
+</html>
diff --git a/css/css-transforms/individual-transform/animation/individual-transform-ordering-ref.html b/css/css-transforms/individual-transform/animation/individual-transform-ordering-ref.html
new file mode 100644
index 0000000..b7dce51
--- /dev/null
+++ b/css/css-transforms/individual-transform/animation/individual-transform-ordering-ref.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Individual transform: combine individual transform properties</title>
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
+    <style>
+      @keyframes anim {
+        to {
+          transform: translate(50px, 50px) rotate(45deg) scale(2, 1);
+        }
+      }
+      .block {
+        display:  inline-block;
+        width: 50px;
+        height: 50px;
+        margin:  50px;
+        padding:  0;
+        transform-origin: 0 0;
+        background:  lime;
+        /* Freeze the animation at the midpoint. */
+        animation-timing-function: cubic-bezier(0, 1, 1, 0);
+        animation-duration:  1000000s;
+        animation-delay:  -500000s;
+        animation-name:  anim;
+      }
+    </style>
+  </head>
+  <body>
+    <div>
+      <div class="block"></div>
+      <div class="block"></div>
+    </div>
+    <div>
+      <div class="block"></div>
+      <div class="block"></div>
+    </div>
+    <div>
+      <div class="block"></div>
+      <div class="block"></div>
+    </div>
+  </body>
+</html>
diff --git a/css/css-transforms/individual-transform/animation/individual-transform-ordering.html b/css/css-transforms/individual-transform/animation/individual-transform-ordering.html
new file mode 100644
index 0000000..9d127f1
--- /dev/null
+++ b/css/css-transforms/individual-transform/animation/individual-transform-ordering.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Individual transform: combine individual transform properties</title>
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
+    <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
+    <meta name="assert" content="Tests that we combine transforms in the correct order when animating."/>
+    <link rel="match" href="individual-transform-ordering-ref.html">
+    <style>
+      .block {
+        display:  inline-block;
+        width: 50px;
+        height: 50px;
+        margin:  50px;
+        padding:  0;
+        transform-origin: 0 0;
+        background:  lime;
+        /* Freeze the animation at the midpoint. */
+        animation-timing-function: cubic-bezier(0, 1, 1, 0);
+        animation-duration:  1000000s;
+        animation-delay:  -500000s;
+      }
+      @keyframes anim-1 {
+        to {
+          translate: 50px 50px;
+          rotate: 45deg;
+          scale: 2 1;
+        }
+      }
+      #div-1 {
+        animation-name: anim-1;
+      }
+      @keyframes anim-2 {
+        to {
+          rotate: 45deg;
+          scale: 2 1;
+          translate: 50px 50px;
+        }
+      }
+      #div-2 {
+        animation-name:  anim-2;
+      }
+      @keyframes anim-3 {
+        to {
+          transform: scale(2, 1);
+          translate: 50px 50px;
+          rotate: 45deg;
+        }
+      }
+      #div-3 {
+        animation-name:  anim-3;
+      }
+      @keyframes anim-4 {
+        to {
+          transform: rotate(45deg) scale(2, 1);
+          translate: 50px 50px;
+        }
+      }
+      #div-4 {
+        animation-name: anim-4;
+      }
+      @Keyframes anim-5 {
+        to { transform: rotate(45deg); }
+      }
+      @Keyframes anim-6 {
+        from { transform:  none; }
+        to { transform: translate(50px, 50px) rotate(45deg) scale(2, 1); }
+      }
+      /* anim-6 replaces anim-5 since both updating the transform property. */
+      #div-5 {
+        animation-name: anim-5, anim-6;
+      }
+      @keyframes anim-7 {
+        to {
+          rotate: 45deg;
+          scale:  2 2;
+        }
+      }
+      @keyframes anim-8 {
+        from {
+          translate: 0px 0px;
+          scale: 1 1;
+        }
+        to {
+          translate: 50px 50px;
+          scale: 2 1;
+        }
+      }
+      /*
+       * The scale property is overridden in anim-8, but the rotate property
+       * from anim-7 is still relevant and must be applied in the correct order
+       * (after translate but before scale).
+       */
+      #div-6 {
+        animation-name: anim-7, anim-8;
+      }
+    </style>
+  </head>
+  <body>
+    <div>
+      <div id="div-1" class="block"></div>
+      <div id="div-2" class="block"></div>
+    </div>
+    <div>
+      <div id="div-3" class="block"></div>
+      <div id="div-4" class="block"></div>
+    </div>
+    <div>
+      <div id="div-5" class="block"></div>
+      <div id="div-6" class="block"></div>
+    </div>
+  </body>
+</html>