Bug 1475637 - Add a mechanism for dumping an interleaved display list. r?jrmuizel draft
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 19 Jul 2018 15:30:30 -0400
changeset 820517 d1c60d4ee8722fe5c72e334fdb1e8710096cb9a8
parent 820484 d94abfaa59928d8fd87f74dbde2ae82d9b7ba667
push id116858
push userkgupta@mozilla.com
push dateThu, 19 Jul 2018 19:31:29 +0000
reviewersjrmuizel
bugs1475637
milestone63.0a1
Bug 1475637 - Add a mechanism for dumping an interleaved display list. r?jrmuizel The prefs, when enabled, will dump the gecko DL items followed by the WR DL items that were generated from that gecko item. This allows us to easily go from a DOM element with known id/class attributes to e.g. an ImageKey of an image that was generated for that element. Also, this logging can be enabled in CI builds just like gecko display-list dumping, instead of the ifdef that we previously had in WebRenderLayerManager. MozReview-Commit-ID: Eeo4iO62YY1
gfx/layers/wr/WebRenderCommandBuilder.cpp
gfx/layers/wr/WebRenderCommandBuilder.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/thebes/gfxPrefs.h
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/WebRenderTypes.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
layout/base/nsLayoutDebugger.cpp
layout/generic/nsFrame.h
modules/libpref/init/all.js
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -1185,20 +1185,25 @@ WebRenderCommandBuilder::BuildWebRenderC
                                                 wr::LayoutSize& aContentSize,
                                                 const nsTArray<wr::WrFilterOp>& aFilters)
 {
   StackingContextHelper sc;
   aScrollData = WebRenderScrollData(mManager);
   MOZ_ASSERT(mLayerScrollData.empty());
   mLastCanvasDatas.Clear();
   mLastAsr = nullptr;
+  mBuilderDumpIndex = 0;
+  MOZ_ASSERT(mDumpIndent == 0);
   mClipManager.BeginBuild(mManager, aBuilder);
 
   {
     StackingContextHelper pageRootSc(sc, aBuilder, aFilters);
+    if (ShouldDumpDisplayList()) {
+      mBuilderDumpIndex = aBuilder.Dump(mDumpIndent + 1, Some(mBuilderDumpIndex), Nothing());
+    }
     CreateWebRenderCommandsFromDisplayList(aDisplayList, nullptr, aDisplayListBuilder,
                                            pageRootSc, aBuilder, aResourceUpdates);
   }
 
   // Make a "root" layer data that has everything else as descendants
   mLayerScrollData.emplace_back();
   mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
   auto callback = [&aScrollData](FrameMetrics::ViewID aScrollId) -> bool {
@@ -1217,31 +1222,46 @@ WebRenderCommandBuilder::BuildWebRenderC
   mLayerScrollData.clear();
   mClipManager.EndBuild();
 
   // Remove the user data those are not displayed on the screen and
   // also reset the data to unused for next transaction.
   RemoveUnusedAndResetWebRenderUserData();
 }
 
+bool
+WebRenderCommandBuilder::ShouldDumpDisplayList()
+{
+  return (XRE_IsParentProcess() && gfxPrefs::WebRenderDLDumpParent()) ||
+         (XRE_IsContentProcess() && gfxPrefs::WebRenderDLDumpContent());
+}
+
 void
 WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
                                                                 nsDisplayItem* aWrappingItem,
                                                                 nsDisplayListBuilder* aDisplayListBuilder,
                                                                 const StackingContextHelper& aSc,
                                                                 wr::DisplayListBuilder& aBuilder,
                                                                 wr::IpcResourceUpdateQueue& aResources)
 {
   if (mDoGrouping) {
     MOZ_RELEASE_ASSERT(aWrappingItem, "Only the root list should have a null wrapping item, and mDoGrouping should never be true for the root list.");
     GP("actually entering the grouping code\n");
     DoGroupingForDisplayList(aDisplayList, aWrappingItem, aDisplayListBuilder, aSc, aBuilder, aResources);
     return;
   }
 
+  bool dumpEnabled = ShouldDumpDisplayList();
+  if (dumpEnabled) {
+    // If we're inside a nested display list, print the WR DL items from the
+    // wrapper item before we start processing the nested items.
+    mBuilderDumpIndex = aBuilder.Dump(mDumpIndent + 1, Some(mBuilderDumpIndex), Nothing());
+  }
+
+  mDumpIndent++;
   mClipManager.BeginList(aSc);
 
   bool apzEnabled = mManager->AsyncPanZoomEnabled();
 
   FlattenedDisplayItemIterator iter(aDisplayListBuilder, aDisplayList);
   while (nsDisplayItem* i = iter.GetNext()) {
     nsDisplayItem* item = i;
     DisplayItemType itemType = item->GetType();
@@ -1304,25 +1324,35 @@ WebRenderCommandBuilder::CreateWebRender
         mDoGrouping = true;
         GP("attempting to enter the grouping code\n");
       }/* else if (itemType == DisplayItemType::TYPE_FOREIGN_OBJECT) {
         // We do not want to apply grouping inside <foreignObject>.
         // TODO: TYPE_FOREIGN_OBJECT does not exist yet, make it exist
         mDoGrouping = false;
       }*/
 
+      if (dumpEnabled) {
+        std::stringstream ss;
+        nsFrame::PrintDisplayItem(aDisplayListBuilder, item, ss, static_cast<uint32_t>(mDumpIndent));
+        printf_stderr("%s", ss.str().c_str());
+      }
+
       // Note: this call to CreateWebRenderCommands can recurse back into
       // this function if the |item| is a wrapper for a sublist.
       item->SetPaintRect(item->GetBuildingRect());
       bool createdWRCommands =
         item->CreateWebRenderCommands(aBuilder, aResources, aSc, mManager,
                                       aDisplayListBuilder);
       if (!createdWRCommands) {
         PushItemAsImage(item, aBuilder, aResources, aSc, aDisplayListBuilder);
       }
+
+      if (dumpEnabled) {
+        mBuilderDumpIndex = aBuilder.Dump(mDumpIndent + 1, Some(mBuilderDumpIndex), Nothing());
+      }
     }
 
     if (apzEnabled) {
       if (forceNewLayerData) {
         // Pop the thing we pushed before the recursion, so the topmost item on
         // the stack is enclosing display item's ASR (or the stack is empty)
         mAsrStack.pop_back();
         const ActiveScrolledRoot* stopAtAsr =
@@ -1375,16 +1405,17 @@ WebRenderCommandBuilder::CreateWebRender
           mLayerScrollData.emplace_back();
           mLayerScrollData.back().Initialize(mManager->GetScrollData(), item,
               descendants, stopAtAsr, deferred ? Some((*deferred)->GetTransform().GetMatrix()) : Nothing());
         }
       }
     }
   }
 
+  mDumpIndent--;
   mClipManager.EndList(aSc);
 }
 
 void
 WebRenderCommandBuilder::PushOverrideForASR(const ActiveScrolledRoot* aASR,
                                             const Maybe<wr::WrClipId>& aClipId)
 {
   mClipManager.PushOverrideForASR(aASR, aClipId);
--- a/gfx/layers/wr/WebRenderCommandBuilder.h
+++ b/gfx/layers/wr/WebRenderCommandBuilder.h
@@ -33,16 +33,18 @@ class WebRenderUserData;
 class WebRenderCommandBuilder {
   typedef nsTHashtable<nsRefPtrHashKey<WebRenderUserData>> WebRenderUserDataRefTable;
   typedef nsTHashtable<nsRefPtrHashKey<WebRenderCanvasData>> CanvasDataSet;
 
 public:
   explicit WebRenderCommandBuilder(WebRenderLayerManager* aManager)
   : mManager(aManager)
   , mLastAsr(nullptr)
+  , mBuilderDumpIndex(0)
+  , mDumpIndent(0)
   , mDoGrouping(false)
   {}
 
   void Destroy();
 
   void EmptyTransaction();
 
   bool NeedsEmptyTransaction();
@@ -109,16 +111,19 @@ public:
                                                                wr::IpcResourceUpdateQueue& aResources,
                                                                const StackingContextHelper& aSc,
                                                                nsDisplayListBuilder* aDisplayListBuilder,
                                                                LayoutDeviceRect& aImageRect);
 
   void RemoveUnusedAndResetWebRenderUserData();
   void ClearCachedResources();
 
+  bool ShouldDumpDisplayList();
+  wr::usize GetBuilderDumpIndex() { return mBuilderDumpIndex; }
+
   // Those are data that we kept between transactions. We used to cache some
   // data in the layer. But in layers free mode, we don't have layer which
   // means we need some other place to cached the data between transaction.
   // We store the data in frame's property.
   template<class T> already_AddRefed<T>
   CreateOrRecycleWebRenderUserData(nsDisplayItem* aItem,
                                    bool* aOutIsRecycled = nullptr)
   {
@@ -177,16 +182,18 @@ private:
   std::vector<const ActiveScrolledRoot*> mAsrStack;
   const ActiveScrolledRoot* mLastAsr;
 
   WebRenderUserDataRefTable mWebRenderUserDatas;
 
   // Store of WebRenderCanvasData objects for use in empty transactions
   CanvasDataSet mLastCanvasDatas;
 
+  wr::usize mBuilderDumpIndex;
+  wr::usize mDumpIndent;
   // Whether consecutive inactive display items should be grouped into one
   // blob image.
   bool mDoGrouping;
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -21,20 +21,16 @@
 #include "mozilla/layers/UpdateImageHelper.h"
 #include "nsDisplayList.h"
 #include "WebRenderCanvasRenderer.h"
 
 #ifdef XP_WIN
 #include "gfxDWriteFonts.h"
 #endif
 
-// Useful for debugging, it dumps the Gecko display list *before* we try to
-// build WR commands from it, and dumps the WR display list after building it.
-#define DUMP_LISTS 0
-
 namespace mozilla {
 
 using namespace gfx;
 
 namespace layers {
 
 WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
   : mWidget(aWidget)
@@ -244,63 +240,68 @@ WebRenderLayerManager::EndTransaction(Dr
 void
 WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
                                                   nsDisplayListBuilder* aDisplayListBuilder,
                                                   const nsTArray<wr::WrFilterOp>& aFilters,
                                                   WebRenderBackgroundData* aBackground)
 {
   AUTO_PROFILER_TRACING("Paint", "RenderLayers");
 
-#if DUMP_LISTS
-  // Useful for debugging, it dumps the display list *before* we try to build
-  // WR commands from it
-  if (XRE_IsContentProcess() && aDisplayList) nsFrame::PrintDisplayList(aDisplayListBuilder, *aDisplayList);
-#endif
-
 #ifdef XP_WIN
   gfxDWriteFont::UpdateClearTypeUsage();
 #endif
 
   // Since we don't do repeat transactions right now, just set the time
   mAnimationReadyTime = TimeStamp::Now();
 
   WrBridge()->BeginTransaction();
 
   LayoutDeviceIntSize size = mWidget->GetClientSize();
   wr::LayoutSize contentSize { (float)size.width, (float)size.height };
   wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize, mLastDisplayListSize);
   wr::IpcResourceUpdateQueue resourceUpdates(WrBridge());
+  wr::usize builderDumpIndex = 0;
+  bool dumpEnabled = mWebRenderCommandBuilder.ShouldDumpDisplayList();
+  if (dumpEnabled) {
+    printf_stderr("-- WebRender display list build --\n");
+  }
 
   if (aDisplayList) {
     MOZ_ASSERT(aDisplayListBuilder && !aBackground);
     // Record the time spent "layerizing". WR doesn't actually layerize but
     // generating the WR display list is the closest equivalent
     PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Layerization);
 
     mWebRenderCommandBuilder.BuildWebRenderCommands(builder,
                                                     resourceUpdates,
                                                     aDisplayList,
                                                     aDisplayListBuilder,
                                                     mScrollData,
                                                     contentSize,
                                                     aFilters);
+    builderDumpIndex = mWebRenderCommandBuilder.GetBuilderDumpIndex();
   } else {
     // ViewToPaint does not have frame yet, then render only background clolor.
     MOZ_ASSERT(!aDisplayListBuilder && aBackground);
     aBackground->AddWebRenderCommands(builder);
+    if (dumpEnabled) {
+      printf_stderr("(no display list; background only)\n");
+      builderDumpIndex = builder.Dump(/*indent*/ 1, Some(builderDumpIndex), Nothing());
+    }
   }
 
   DiscardCompositorAnimations();
 
   mWidget->AddWindowOverlayWebRenderCommands(WrBridge(), builder, resourceUpdates);
   mWindowOverlayChanged = false;
+  if (dumpEnabled) {
+    printf_stderr("(window overlay)\n");
+    Unused << builder.Dump(/*indent*/ 1, Some(builderDumpIndex), Nothing());
+  }
 
-#if DUMP_LISTS
-  if (XRE_IsContentProcess()) mScrollData.Dump();
-#endif
   if (AsyncPanZoomEnabled()) {
     mScrollData.SetFocusTarget(mFocusTarget);
     mFocusTarget = FocusTarget();
 
     if (mIsFirstPaint) {
       mScrollData.SetIsFirstPaint();
       mIsFirstPaint = false;
     }
@@ -325,20 +326,16 @@ WebRenderLayerManager::EndTransactionWit
   // device-reset status.
   if (!gfxPlatform::GetPlatform()->DidRenderingDeviceReset()) {
     if (WrBridge()->GetSyncObject() &&
         WrBridge()->GetSyncObject()->IsSyncObjectValid()) {
       WrBridge()->GetSyncObject()->Synchronize();
     }
   }
 
-#if DUMP_LISTS
-  if (XRE_IsContentProcess()) builder.Dump();
-#endif
-
   wr::BuiltDisplayList dl;
   builder.Finalize(contentSize, dl);
   mLastDisplayListSize = dl.dl.inner.capacity;
 
   {
     AUTO_PROFILER_TRACING("Paint", "ForwardDPTransaction");
     WrBridge()->EndTransaction(contentSize, dl, resourceUpdates, size.ToUnknownSize(),
                                mLatestTransactionId, mScrollData, refreshStart, mTransactionStart);
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -515,16 +515,18 @@ private:
 
   DECL_GFX_PREF(Live, "gfx.vsync.collect-scroll-transforms",   CollectScrollTransforms, bool, false);
   DECL_GFX_PREF(Once, "gfx.vsync.compositor.unobserve-count",  CompositorUnobserveCount, int32_t, 10);
 
   DECL_GFX_PREF(Once, "gfx.webrender.all",                     WebRenderAll, bool, false);
   DECL_GFX_PREF(Once, "gfx.webrender.all.qualified",           WebRenderAllQualified, bool, false);
   DECL_GFX_PREF(Live, "gfx.webrender.blob-images",             WebRenderBlobImages, bool, true);
   DECL_GFX_PREF(Live, "gfx.webrender.blob.invalidation",       WebRenderBlobInvalidation, bool, false);
+  DECL_GFX_PREF(Live, "gfx.webrender.dl.dump-parent",          WebRenderDLDumpParent, bool, false);
+  DECL_GFX_PREF(Live, "gfx.webrender.dl.dump-content",         WebRenderDLDumpContent, bool, false);
   DECL_GFX_PREF(Once, "gfx.webrender.enabled",                 WebRenderEnabledDoNotUseDirectly, bool, false);
   DECL_GFX_PREF(Once, "gfx.webrender.force-disabled",          WebRenderForceDisabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.webrender.highlight-painted-layers",WebRenderHighlightPaintedLayers, bool, false);
 
   // Use vsync events generated by hardware
   DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs",           WorkAroundDriverBugs, bool, true);
 
   DECL_GFX_PREF(Live, "gl.ignore-dx-interop2-blacklist",       IgnoreDXInterop2Blacklist, bool, false);
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -751,17 +751,23 @@ DisplayListBuilder::~DisplayListBuilder(
 {
   MOZ_COUNT_DTOR(DisplayListBuilder);
   wr_state_delete(mWrState);
 }
 
 void DisplayListBuilder::Save() { wr_dp_save(mWrState); }
 void DisplayListBuilder::Restore() { wr_dp_restore(mWrState); }
 void DisplayListBuilder::ClearSave() { wr_dp_clear_save(mWrState); }
-void DisplayListBuilder::Dump() { wr_dump_display_list(mWrState); }
+
+usize DisplayListBuilder::Dump(usize aIndent,
+                               const Maybe<usize>& aStart,
+                               const Maybe<usize>& aEnd)
+{
+  return wr_dump_display_list(mWrState, aIndent, aStart.ptrOr(nullptr), aEnd.ptrOr(nullptr));
+}
 
 void
 DisplayListBuilder::Finalize(wr::LayoutSize& aOutContentSize,
                              BuiltDisplayList& aOutDisplayList)
 {
   wr_api_finalize_builder(mWrState,
                           &aOutContentSize,
                           &aOutDisplayList.dl_desc,
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -277,17 +277,17 @@ public:
                               size_t aCapacity = 0);
   DisplayListBuilder(DisplayListBuilder&&) = default;
 
   ~DisplayListBuilder();
 
   void Save();
   void Restore();
   void ClearSave();
-  void Dump();
+  usize Dump(usize aIndent, const Maybe<usize>& aStart, const Maybe<usize>& aEnd);
 
   void Finalize(wr::LayoutSize& aOutContentSize,
                 wr::BuiltDisplayList& aOutDisplayList);
 
   Maybe<wr::WrClipId> PushStackingContext(
           const wr::LayoutRect& aBounds, // TODO: We should work with strongly typed rects
           const wr::WrClipId* aClipNodeId,
           const wr::WrAnimationProperty* aAnimation,
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -24,16 +24,21 @@
 namespace mozilla {
 
 namespace ipc {
 class ByteBuf;
 } // namespace ipc
 
 namespace wr {
 
+// Using uintptr_t in C++ code for "size" types seems weird, so let's use a
+// better-sounding typedef. The name comes from the fact that we generally
+// have to deal with uintptr_t because that's what rust's usize maps to.
+typedef uintptr_t usize;
+
 typedef wr::WrWindowId WindowId;
 typedef wr::WrPipelineId PipelineId;
 typedef wr::WrImageKey ImageKey;
 typedef wr::WrFontKey FontKey;
 typedef wr::WrFontInstanceKey FontInstanceKey;
 typedef wr::WrEpoch Epoch;
 typedef wr::WrExternalImageId ExternalImageId;
 typedef wr::WrDebugFlags DebugFlags;
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -2349,20 +2349,25 @@ pub extern "C" fn wr_dp_push_box_shadow(
                           color,
                           blur_radius,
                           spread_radius,
                           border_radius,
                           clip_mode);
 }
 
 #[no_mangle]
-pub extern "C" fn wr_dump_display_list(state: &mut WrState) {
+pub extern "C" fn wr_dump_display_list(state: &mut WrState,
+                                       indent: usize,
+                                       start: *const usize,
+                                       end: *const usize) -> usize {
+    let start = unsafe { start.as_ref().cloned() };
+    let end = unsafe { end.as_ref().cloned() };
     state.frame_builder
          .dl_builder
-         .print_display_list(0, None, None);
+         .print_display_list(indent, start, end)
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_finalize_builder(state: &mut WrState,
                                                  content_size: &mut LayoutSize,
                                                  dl_descriptor: &mut BuiltDisplayListDescriptor,
                                                  dl_data: &mut WrVecU8) {
     let frame_builder = mem::replace(&mut state.frame_builder,
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1415,17 +1415,20 @@ WR_INLINE
 void wr_dp_restore(WrState *aState)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_save(WrState *aState)
 WR_FUNC;
 
 WR_INLINE
-void wr_dump_display_list(WrState *aState)
+uintptr_t wr_dump_display_list(WrState *aState,
+                               uintptr_t aIndent,
+                               const uintptr_t *aStart,
+                               const uintptr_t *aEnd)
 WR_FUNC;
 
 extern bool wr_moz2d_render_cb(ByteSlice aBlob,
                                uint32_t aWidth,
                                uint32_t aHeight,
                                ImageFormat aFormat,
                                const uint16_t *aTileSize,
                                const TileOffset *aTileOffset,
--- a/layout/base/nsLayoutDebugger.cpp
+++ b/layout/base/nsLayoutDebugger.cpp
@@ -255,16 +255,27 @@ void
 nsFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder,
                           const nsDisplayList& aList,
                           std::stringstream& aStream,
                           bool aDumpHtml)
 {
   PrintDisplayListTo(aBuilder, aList, aStream, 0, aDumpHtml);
 }
 
+void
+nsFrame::PrintDisplayItem(nsDisplayListBuilder* aBuilder,
+                          nsDisplayItem* aItem,
+                          std::stringstream& aStream,
+                          uint32_t aIndent,
+                          bool aDumpSublist,
+                          bool aDumpHtml)
+{
+  PrintDisplayItemTo(aBuilder, aItem, aStream, aIndent, aDumpSublist, aDumpHtml);
+}
+
 /**
  * The two functions below are intended to be called from a debugger.
  */
 void
 PrintDisplayItemToStdout(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
 {
   std::stringstream stream;
   PrintDisplayItemTo(aBuilder, aItem, stream, 0, true, false);
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -746,16 +746,22 @@ public:
     std::stringstream ss;
     PrintDisplayList(aBuilder, aList, ss, aDumpHtml);
     fprintf_stderr(stderr, "%s", ss.str().c_str());
   }
   static void PrintDisplayList(nsDisplayListBuilder* aBuilder,
                                const nsDisplayList& aList,
                                std::stringstream& aStream,
                                bool aDumpHtml = false);
+  static void PrintDisplayItem(nsDisplayListBuilder* aBuilder,
+                               nsDisplayItem* aItem,
+                               std::stringstream& aStream,
+                               uint32_t aIndent = 0,
+                               bool aDumpSublist = false,
+                               bool aDumpHtml = false);
   static void PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
                                   const nsDisplayListSet& aList,
                                   std::stringstream& aStream,
                                   bool aDumpHtml = false);
 
 };
 
 // Start Display Reflow Debugging
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -884,16 +884,18 @@ pref("gfx.webrender.debug.profiler", fal
 pref("gfx.webrender.debug.gpu-time-queries", false);
 pref("gfx.webrender.debug.gpu-sample-queries", false);
 pref("gfx.webrender.debug.disable-batching", false);
 pref("gfx.webrender.debug.epochs", false);
 pref("gfx.webrender.debug.compact-profiler", false);
 pref("gfx.webrender.debug.echo-driver-messages", false);
 pref("gfx.webrender.debug.new-frame-indicator", false);
 pref("gfx.webrender.debug.new-scene-indicator", false);
+pref("gfx.webrender.dl.dump-parent", false);
+pref("gfx.webrender.dl.dump-content", false);
 
 pref("accessibility.browsewithcaret", false);
 pref("accessibility.warn_on_browsewithcaret", true);
 
 pref("accessibility.browsewithcaret_shortcut.enabled", true);
 
 #ifndef XP_MACOSX
 // Tab focus model bit field: