Bug 1433850 - layout.display-list.retain.verify.order to also check RDL ordering - r?mattwoodrow draft
authorGerald Squelart <gsquelart@mozilla.com>
Mon, 29 Jan 2018 18:23:14 +1100
changeset 748213 2a186c8c7911700f0562c588f9a3a0e7f91739d1
parent 748205 a6c753e77345e968954e8d61e3871c5883015ede
push id97090
push usergsquelart@mozilla.com
push dateMon, 29 Jan 2018 07:25:44 +0000
reviewersmattwoodrow
bugs1433850
milestone60.0a1
Bug 1433850 - layout.display-list.retain.verify.order to also check RDL ordering - r?mattwoodrow MozReview-Commit-ID: 2foGnuSCwUX
gfx/thebes/gfxPrefs.h
layout/painting/DisplayListChecker.cpp
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -659,16 +659,17 @@ private:
   DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-sensitivity", ScrollSnapPredictionSensitivity, float, 0.750f);
   DECL_GFX_PREF(Live, "layout.css.scroll-snap.proximity-threshold", ScrollSnapProximityThreshold, int32_t, 200);
   DECL_GFX_PREF(Live, "layout.css.touch_action.enabled",       TouchActionEnabled, bool, false);
 
   DECL_GFX_PREF(Live, "layout.display-list.build-twice",       LayoutDisplayListBuildTwice, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.retain",            LayoutRetainDisplayList, bool, true);
   DECL_GFX_PREF(Live, "layout.display-list.retain.chrome",     LayoutRetainDisplayListChrome, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.retain.verify",     LayoutVerifyRetainDisplayList, bool, false);
+  DECL_GFX_PREF(Live, "layout.display-list.retain.verify.order", LayoutVerifyRetainDisplayListOrder, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.rebuild-frame-limit", LayoutRebuildFrameLimit, uint32_t, 500);
   DECL_GFX_PREF(Live, "layout.display-list.dump",              LayoutDumpDisplayList, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.dump-content",      LayoutDumpDisplayListContent, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.dump-parent",       LayoutDumpDisplayListParent, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.show-rebuild-area", LayoutDisplayListShowArea, bool, false);
 
   DECL_GFX_PREF(Live, "layout.event-regions.enabled",          LayoutEventRegionsEnabledDoNotUseDirectly, bool, false);
   DECL_GFX_PREF(Once, "layout.frame_rate",                     LayoutFrameRate, int32_t, -1);
--- a/layout/painting/DisplayListChecker.cpp
+++ b/layout/painting/DisplayListChecker.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DisplayListChecker.h"
 
+#include "gfxPrefs.h"
 #include "nsDisplayList.h"
 
 namespace mozilla {
 
 class DisplayItemBlueprint;
 
 // Stack node used during tree visits, to store the path to a display item.
 struct DisplayItemBlueprintStack
@@ -88,16 +89,17 @@ private:
   {
   }
 
   void processChildren(nsDisplayList* aList,
                        const char* aName,
                        unsigned& aIndex);
 
   std::vector<DisplayItemBlueprint> mItems;
+  const bool mVerifyOrder = gfxPrefs::LayoutVerifyRetainDisplayListOrder();
 };
 
 // Object representing one display item, with just enough information to
 // compare with another item and output useful debugging information.
 class DisplayItemBlueprint
 {
 public:
   DisplayItemBlueprint(nsDisplayItem& aItem,
@@ -259,35 +261,71 @@ DisplayListBlueprint::CompareList(
   const DisplayListBlueprint& aRoot,
   const DisplayListBlueprint& aOther,
   const DisplayListBlueprint& aOtherRoot,
   std::stringstream& aDiff,
   const DisplayItemBlueprintStack& aStack,
   const DisplayItemBlueprintStack& aStackOther) const
 {
   bool same = true;
+  unsigned previousFoundIndex = 0;
+  const DisplayItemBlueprint* previousFoundItemBefore = nullptr;
+  const DisplayItemBlueprint* previousFoundItemAfter = nullptr;
   for (const DisplayItemBlueprint& itemBefore : mItems) {
     bool found = false;
+    unsigned foundIndex = 0;
     for (const DisplayItemBlueprint& itemAfter : aOther.mItems) {
       if (itemBefore.CompareItem(itemAfter, aDiff)) {
         found = true;
 
+        if (mVerifyOrder) {
+          if (foundIndex < previousFoundIndex) {
+            same = false;
+            aDiff << "\n";
+            if (aStack.Output(aDiff)) {
+              aDiff << " > ";
+            }
+            aDiff << itemBefore.mDescription;
+            aDiff << "\n * Corresponding item in unexpected order: ";
+            if (aStackOther.Output(aDiff)) {
+              aDiff << " > ";
+            }
+            aDiff << itemAfter.mDescription;
+            aDiff << "\n * Was expected after: ";
+            if (aStackOther.Output(aDiff)) {
+              aDiff << " > ";
+            }
+            MOZ_ASSERT(previousFoundItemAfter);
+            aDiff << previousFoundItemAfter->mDescription;
+            aDiff << "\n   which corresponds to: ";
+            if (aStack.Output(aDiff)) {
+              aDiff << " > ";
+            }
+            MOZ_ASSERT(previousFoundItemBefore);
+            aDiff << previousFoundItemBefore->mDescription;
+          }
+          previousFoundIndex = foundIndex;
+          previousFoundItemBefore = &itemBefore;
+          previousFoundItemAfter = &itemAfter;
+        }
+
         const DisplayItemBlueprintStack stack = { &aStack, &itemBefore };
         const DisplayItemBlueprintStack stackOther = { &aStackOther,
                                                        &itemAfter };
         if (!itemBefore.mChildren.CompareList(aRoot,
                                               itemAfter.mChildren,
                                               aOtherRoot,
                                               aDiff,
                                               stack,
                                               stackOther)) {
           same = false;
         }
         break;
       }
+      ++foundIndex;
     }
     if (!found) {
       same = false;
       aDiff << "\n";
       if (aStack.Output(aDiff)) {
         aDiff << " > ";
       }
       aDiff << itemBefore.mDescription;