Bug 1301258 - Part 1: Define macros for change hints always, never and sometimes handled for descendants. r=dbaron draft
authorCameron McCormack <cam@mcc.id.au>
Mon, 20 Mar 2017 16:29:31 +0800
changeset 501417 426b656b5aafc0bd72fdcfd1e1849f20f6752b92
parent 501295 1b9293be51637f841275541d8991314ca56561a5
child 501418 802e532de182f62af71d982d5e2153831fd60109
push id49976
push userbmo:cam@mcc.id.au
push dateMon, 20 Mar 2017 08:30:15 +0000
reviewersdbaron
bugs1301258
milestone55.0a1
Bug 1301258 - Part 1: Define macros for change hints always, never and sometimes handled for descendants. r=dbaron MozReview-Commit-ID: 1lOl7U6rlC5
layout/base/nsChangeHint.h
--- a/layout/base/nsChangeHint.h
+++ b/layout/base/nsChangeHint.h
@@ -214,20 +214,27 @@ enum nsChangeHint {
   nsChangeHint_UpdateBackgroundPosition = 1 << 26,
 
   /**
    * Indicates that a frame has changed to or from having the CSS
    * transform property set.
    */
   nsChangeHint_AddOrRemoveTransform = 1 << 27,
 
-  // IMPORTANT NOTE: When adding new hints, consider whether you need
-  // to add them to NS_HintsNotHandledForDescendantsIn() below. Please
-  // also add them to RestyleManager::ChangeHintToString and modify
-  // nsChangeHint_AllHints below accordingly.
+  // IMPORTANT NOTE: When adding a new hint, you will need to add it to
+  // one of:
+  //
+  //   * nsChangeHint_Hints_NeverHandledForDescendants
+  //   * nsChangeHint_Hints_AlwaysHandledForDescendants
+  //   * nsChangeHint_Hints_SometimesHandledForDescendants
+  //
+  // and you also may need to handle it in NS_HintsNotHandledForDescendantsIn.
+  //
+  // Please also add it to RestyleManager::ChangeHintToString and
+  // modify nsChangeHint_AllHints below accordingly.
 
   /**
    * Dummy hint value for all hints. It exists for compile time check.
    */
   nsChangeHint_AllHints = (1 << 28) - 1,
 };
 
 // Redefine these operators to return nothing. This will catch any use
@@ -293,56 +300,81 @@ inline nsChangeHint operator^=(nsChangeH
 /**
  * We have an optimization when processing change hints which prevents
  * us from visiting the descendants of a node when a hint on that node
  * is being processed.  This optimization does not apply in some of the
  * cases where applying a hint to an element does not necessarily result
  * in the same hint being handled on the descendants.
  */
 
+// The change hints that are always handled for descendants.
+#define nsChangeHint_Hints_AlwaysHandledForDescendants (   \
+  nsChangeHint_ClearDescendantIntrinsics |                 \
+  nsChangeHint_NeedDirtyReflow |                           \
+  nsChangeHint_NeutralChange |                             \
+  nsChangeHint_ReconstructFrame |                          \
+  nsChangeHint_RepaintFrame |                              \
+  nsChangeHint_SchedulePaint |                             \
+  nsChangeHint_SyncFrameView |                             \
+  nsChangeHint_UpdateCursor |                              \
+  nsChangeHint_UpdateSubtreeOverflow |                     \
+  nsChangeHint_UpdateTextPath                              \
+)
+
+// The change hints that are never handled for descendants.
+#define nsChangeHint_Hints_NeverHandledForDescendants (    \
+  nsChangeHint_BorderStyleNoneChange |                     \
+  nsChangeHint_ChildrenOnlyTransform |                     \
+  nsChangeHint_InvalidateRenderingObservers |              \
+  nsChangeHint_RecomputePosition |                         \
+  nsChangeHint_UpdateBackgroundPosition |                  \
+  nsChangeHint_UpdateComputedBSize |                       \
+  nsChangeHint_UpdateContainingBlock |                     \
+  nsChangeHint_UpdateEffects |                             \
+  nsChangeHint_UpdateOpacityLayer |                        \
+  nsChangeHint_UpdateOverflow |                            \
+  nsChangeHint_UpdateParentOverflow |                      \
+  nsChangeHint_UpdatePostTransformOverflow |               \
+  nsChangeHint_UpdateTransformLayer |                      \
+  nsChangeHint_UpdateUsesOpacity |                         \
+  nsChangeHint_AddOrRemoveTransform                        \
+)
+
+// The change hints that are sometimes considered to be handled for descendants.
+#define nsChangeHint_Hints_SometimesHandledForDescendants (\
+  nsChangeHint_ClearAncestorIntrinsics |                   \
+  nsChangeHint_NeedReflow |                                \
+  nsChangeHint_ReflowChangesSizeOrPosition                 \
+)
+
+static_assert(!(nsChangeHint_Hints_AlwaysHandledForDescendants &
+                nsChangeHint_Hints_NeverHandledForDescendants) &&
+              !(nsChangeHint_Hints_AlwaysHandledForDescendants &
+                nsChangeHint_Hints_SometimesHandledForDescendants) &&
+              !(nsChangeHint_Hints_NeverHandledForDescendants &
+                nsChangeHint_Hints_SometimesHandledForDescendants) &&
+              !(nsChangeHint_AllHints ^
+                nsChangeHint_Hints_AlwaysHandledForDescendants ^
+                nsChangeHint_Hints_NeverHandledForDescendants ^
+                nsChangeHint_Hints_SometimesHandledForDescendants),
+              "change hints must be present in exactly one of "
+              "nsChangeHint_Hints_{Always,Never,Sometimes}"
+              "HandledForDescendants");
+
 // The most hints that NS_HintsNotHandledForDescendantsIn could possibly return:
-#define nsChangeHint_Hints_NotHandledForDescendants nsChangeHint( \
-          nsChangeHint_UpdateTransformLayer | \
-          nsChangeHint_UpdateEffects | \
-          nsChangeHint_InvalidateRenderingObservers | \
-          nsChangeHint_UpdateOpacityLayer | \
-          nsChangeHint_UpdateOverflow | \
-          nsChangeHint_UpdatePostTransformOverflow | \
-          nsChangeHint_UpdateParentOverflow | \
-          nsChangeHint_ChildrenOnlyTransform | \
-          nsChangeHint_RecomputePosition | \
-          nsChangeHint_UpdateContainingBlock | \
-          nsChangeHint_AddOrRemoveTransform | \
-          nsChangeHint_BorderStyleNoneChange | \
-          nsChangeHint_NeedReflow | \
-          nsChangeHint_ReflowChangesSizeOrPosition | \
-          nsChangeHint_ClearAncestorIntrinsics | \
-          nsChangeHint_UpdateComputedBSize | \
-          nsChangeHint_UpdateUsesOpacity | \
-          nsChangeHint_UpdateBackgroundPosition)
+#define nsChangeHint_Hints_NotHandledForDescendants (      \
+  nsChangeHint_Hints_NeverHandledForDescendants |          \
+  nsChangeHint_Hints_SometimesHandledForDescendants        \
+)
 
 // NB: Once we drop support for the old style system, this logic should be
 // inlined in the Servo style system to eliminate the FFI call.
 inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) {
-  nsChangeHint result = nsChangeHint(aChangeHint & (
-    nsChangeHint_UpdateTransformLayer |
-    nsChangeHint_UpdateEffects |
-    nsChangeHint_InvalidateRenderingObservers |
-    nsChangeHint_UpdateOpacityLayer |
-    nsChangeHint_UpdateOverflow |
-    nsChangeHint_UpdatePostTransformOverflow |
-    nsChangeHint_UpdateParentOverflow |
-    nsChangeHint_ChildrenOnlyTransform |
-    nsChangeHint_RecomputePosition |
-    nsChangeHint_UpdateContainingBlock |
-    nsChangeHint_AddOrRemoveTransform |
-    nsChangeHint_BorderStyleNoneChange |
-    nsChangeHint_UpdateComputedBSize |
-    nsChangeHint_UpdateUsesOpacity | \
-    nsChangeHint_UpdateBackgroundPosition));
+  nsChangeHint result =
+    aChangeHint & nsChangeHint_Hints_NeverHandledForDescendants;
 
   if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aChangeHint)) {
     if (NS_IsHintSubset(nsChangeHint_NeedReflow, aChangeHint)) {
       // If NeedDirtyReflow is *not* set, then NeedReflow is a
       // non-inherited hint.
       result |= nsChangeHint_NeedReflow;
     }