Always relayout when an object gets or loses a PaintLayer.

This rids us of some crufty code, and also fixes bugs. The approach was also
broken for multicol, because we started UpdatePaginationRecursive() in the
middle of the tree without looking for a containing flow thread (pagination
layer). This would result in the new layer erroneously not becoming paginated.

Also had to update a unit test, to satisfy its requirement that the style change
won't trigger layout.

BUG=616596

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I50ed61a7174e360259b7b786bab01cf74616fc32
Reviewed-on: https://chromium-review.googlesource.com/542915
Commit-Queue: Morten Stenshorne <mstensho@opera.com>
Reviewed-by: Steve Kobes <skobes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488768}
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index 8b1c5def..c56a151 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -668,6 +668,7 @@
 Bug(none) fast/multicol/doubly-nested-with-top-padding-crossing-row-boundaries.html [ Failure ]
 Bug(none) fast/multicol/relpos-inside-inline-block.html [ Failure ]
 Bug(none) fast/multicol/dynamic/abspos-multicol-with-spanner-becomes-spanner.html [ Failure ]
+Bug(none) fast/multicol/dynamic/add-will-change-transform.html [ Failure ]
 Bug(none) fast/multicol/dynamic/change-spanner-display.html [ Failure ]
 Bug(none) fast/multicol/dynamic/change-spanner-parent-display.html [ Failure ]
 Bug(none) fast/multicol/dynamic/insert-block-among-text-in-anonymous-wrapper.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/dynamic/add-will-change-transform-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/dynamic/add-will-change-transform-expected.html
new file mode 100644
index 0000000..e919e2c5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/dynamic/add-will-change-transform-expected.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<p>There should be a blue square below.</p>
+<div style="width:60px; height:60px; background:blue;"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/dynamic/add-will-change-transform.html b/third_party/WebKit/LayoutTests/fast/multicol/dynamic/add-will-change-transform.html
new file mode 100644
index 0000000..eff1b7d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/multicol/dynamic/add-will-change-transform.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<style>
+.multicol {
+    width: 60px;
+    columns: 20px;
+    column-gap: 0;
+    column-fill: auto;
+    height: 60px;
+}
+.square {
+    width: 20px;
+    height: 20px;
+    background: blue;
+}
+</style>
+
+<p>There should be a blue square below.</p>
+<div class="multicol">
+    <div class="square"></div>
+    <div class="square"></div>
+    <div class="square"></div>
+    <div class="square"></div>
+    <div id="elm">
+        <div class="square"></div>
+    </div>
+    <div class="square"></div>
+    <div class="square"></div>
+    <div class="square"></div>
+    <div class="square"></div>
+</div>
+
+<script>
+    document.body.offsetTop;
+    var elm = document.getElementById("elm");
+    elm.style.willChange = "transform";
+</script>
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index 0bc6b6c..dbda7548 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -88,28 +88,6 @@
 }
 }  // namespace
 
-class FloatStateForStyleChange {
- public:
-  static void SetWasFloating(LayoutBoxModelObject* box_model_object,
-                             bool was_floating) {
-    was_floating_ = was_floating;
-    box_model_object_ = box_model_object;
-  }
-
-  static bool WasFloating(LayoutBoxModelObject* box_model_object) {
-    DCHECK_EQ(box_model_object, box_model_object_);
-    return was_floating_;
-  }
-
- private:
-  // Used to store state between styleWillChange and styleDidChange
-  static bool was_floating_;
-  static LayoutBoxModelObject* box_model_object_;
-};
-
-bool FloatStateForStyleChange::was_floating_ = false;
-LayoutBoxModelObject* FloatStateForStyleChange::box_model_object_ = nullptr;
-
 // The HashMap for storing continuation pointers.
 // The continuation chain is a singly linked list. As such, the HashMap's value
 // is the next pointer associated with the key.
@@ -284,8 +262,6 @@
         .InvalidatePaintIncludingNonCompositingDescendants();
   }
 
-  FloatStateForStyleChange::SetWasFloating(this, IsFloating());
-
   if (HasLayer() && diff.CssClipChanged())
     Layer()->ClearClipRects();
 
@@ -298,8 +274,6 @@
   bool had_transform_related_property = HasTransformRelatedProperty();
   bool had_layer = HasLayer();
   bool layer_was_self_painting = had_layer && Layer()->IsSelfPaintingLayer();
-  bool was_floating_before_style_changed =
-      FloatStateForStyleChange::WasFloating(this);
   bool was_horizontal_writing_mode = IsHorizontalWritingMode();
 
   LayoutObject::StyleDidChange(diff, old_style);
@@ -329,14 +303,15 @@
   PaintLayerType type = LayerTypeRequired();
   if (type != kNoPaintLayer) {
     if (!Layer()) {
-      if (was_floating_before_style_changed && IsFloating())
+      // In order to update this object properly, we need to lay it out again.
+      // However, if we have never laid it out, don't mark it for layout. If
+      // this is a new object, it may not yet have been inserted into the tree,
+      // and if we mark it for layout then, we risk upsetting the tree
+      // insertion machinery.
+      if (EverHadLayout())
         SetChildNeedsLayout();
+
       CreateLayerAfterStyleChange();
-      if (Parent() && !NeedsLayout()) {
-        Layer()->UpdateSize();
-        // FIXME: We should call a specialized versions of this function.
-        Layer()->UpdateLayerPositionsAfterLayout();
-      }
     }
   } else if (Layer() && Layer()->Parent()) {
     PaintLayer* parent_layer = Layer()->Parent();
@@ -348,7 +323,7 @@
     Layer()->UpdateClipPath(old_style, StyleRef());
     // Calls DestroyLayer() which clears the layer.
     Layer()->RemoveOnlyThisLayerAfterStyleChange();
-    if (was_floating_before_style_changed && IsFloating())
+    if (EverHadLayout())
       SetChildNeedsLayout();
     if (had_transform_related_property) {
       SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp
index a3792189..3b15c04 100644
--- a/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidationTest.cpp
@@ -49,6 +49,7 @@
       "    margin: 0px;"
       "  }"
       "  #container {"
+      "    will-change: transform;"
       "    width: 100%;"
       "    height: 100%;"
       "  }"