Bug 1404181 - Part 27: Add some retained-dl debugging tools. r?mstange draft
authorMatt Woodrow <mwoodrow@mozilla.com>, Miko Mynttinen <mikokm@gmail.com>, Timothy Nikkel <tnikkel@gmail.com>
Sat, 21 Oct 2017 16:54:24 +1300
changeset 684538 53b44cb60ca4af13f775bf4e0b34cc3b4aa3f9bd
parent 684537 87cd435d018da188e960d88c39fc444c10e46a0d
child 736879 84e97d4db36699ea48d24b68c8499d53b36c6f95
push id85633
push usermwoodrow@mozilla.com
push dateSun, 22 Oct 2017 23:03:02 +0000
reviewersmstange
bugs1404181
milestone58.0a1
Bug 1404181 - Part 27: Add some retained-dl debugging tools. r?mstange MozReview-Commit-ID: EQO1lAbUnpY
gfx/layers/composite/Diagnostics.cpp
gfx/layers/composite/Diagnostics.h
gfx/layers/ipc/LayersMessages.ipdlh
gfx/thebes/gfxPrefs.h
layout/base/nsLayoutUtils.cpp
layout/generic/nsFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/painting/nsDisplayList.h
--- a/gfx/layers/composite/Diagnostics.cpp
+++ b/gfx/layers/composite/Diagnostics.cpp
@@ -36,16 +36,17 @@ Diagnostics::Diagnostics()
    mTransactionFps("LayerTransactions")
 {
 }
 
 void
 Diagnostics::RecordPaintTimes(const PaintTiming& aPaintTimes)
 {
   mDlbMs.Add(aPaintTimes.dlMs());
+  mDlb2Ms.Add(aPaintTimes.dl2Ms());
   mFlbMs.Add(aPaintTimes.flbMs());
   mRasterMs.Add(aPaintTimes.rasterMs());
   mSerializeMs.Add(aPaintTimes.serializeMs());
   mSendMs.Add(aPaintTimes.sendMs());
 }
 
 std::string
 Diagnostics::GetFrameOverlayString(const GPUStats& aStats)
@@ -82,20 +83,29 @@ Diagnostics::GetFrameOverlayString(const
   // CC_EXEC  = Container render/composite drawing
   nsPrintfCString line1("FPS: %d (TXN: %d)", fps, txnFps);
   nsPrintfCString line2("[CC] Build: %0.1fms Exec: %0.1fms GPU: %s Fill Ratio: %0.1f/%0.1f",
     mPrepareMs.Average(),
     mCompositeMs.Average(),
     gpuTimeString.c_str(),
     pixelFillRatio,
     screenFillRatio);
-  nsPrintfCString line3("[Content] DL: %0.1fms FLB: %0.1fms Raster: %0.1fms",
+  nsCString line3;
+  if (mDlb2Ms.Average() != 0.0f) {
+    line3 += nsPrintfCString("[Content] DL: %0.1f/%0.1fms FLB: %0.1fms Raster: %0.1fms",
+    mDlb2Ms.Average(),
     mDlbMs.Average(),
     mFlbMs.Average(),
     mRasterMs.Average());
+  } else {
+    line3 += nsPrintfCString("[Content] DL: %0.1fms FLB: %0.1fms Raster: %0.1fms",
+    mDlbMs.Average(),
+    mFlbMs.Average(),
+    mRasterMs.Average());
+  }
   nsPrintfCString line4("[IPDL] Build: %0.1fms Send: %0.1fms Update: %0.1fms",
     mSerializeMs.Average(),
     mSendMs.Average(),
     mUpdateMs.Average());
 
   return std::string(line1.get()) + "\n" +
          std::string(line2.get()) + "\n" +
          std::string(line3.get()) + "\n" +
--- a/gfx/layers/composite/Diagnostics.h
+++ b/gfx/layers/composite/Diagnostics.h
@@ -96,16 +96,17 @@ public:
   private:
     TimeStamp mStart;
   };
 
 private:
   FPSCounter mCompositeFps;
   FPSCounter mTransactionFps;
   TimedMetric mDlbMs;
+  TimedMetric mDlb2Ms;
   TimedMetric mFlbMs;
   TimedMetric mRasterMs;
   TimedMetric mSerializeMs;
   TimedMetric mSendMs;
   TimedMetric mUpdateMs;
   TimedMetric mPrepareMs;
   TimedMetric mCompositeMs;
   TimedMetric mGPUDrawMs;
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -550,16 +550,17 @@ struct ImageCompositeNotification {
 union AsyncParentMessageData {
   OpNotifyNotUsed;
 };
 
 struct PaintTiming {
   float serializeMs;
   float sendMs;
   float dlMs;
+  float dl2Ms;
   float flbMs;
   float rasterMs;
 };
 
 struct TransactionInfo
 {
   Edit[] cset;
   OpSetSimpleLayerAttributes[] setSimpleAttrs;
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -657,20 +657,23 @@ private:
 
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f);
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.enabled",    ScrollBehaviorEnabled, bool, true);
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.spring-constant", ScrollBehaviorSpringConstant, float, 250.0f);
   DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-max-velocity", ScrollSnapPredictionMaxVelocity, int32_t, 2000);
   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.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);
   DECL_GFX_PREF(Live, "layout.min-active-layer-size",          LayoutMinActiveLayerSize, int, 64);
   DECL_GFX_PREF(Once, "layout.paint_rects_separately",         LayoutPaintRectsSeparately, bool, true);
 
   // This and code dependent on it should be removed once containerless scrolling looks stable.
   DECL_GFX_PREF(Once, "layout.scroll.root-frame-containers",   LayoutUseContainersForRootFrames, bool, true);
   // This pref is to be set by test code only.
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3810,16 +3810,28 @@ nsLayoutUtils::PaintFrame(gfxContext* aR
       // Attempt to do a partial build and merge into the existing list.
       // This calls BuildDisplayListForStacking context on a subset of the
       // viewport.
       bool merged = false;
       if (retainedBuilder && paintedPreviously) {
         merged = retainedBuilder->AttemptPartialUpdate(aBackstop);
       }
 
+      if (merged && gfxPrefs::LayoutDisplayListBuildTwice()) {
+        merged = false;
+        if (gfxPrefs::LayersDrawFPS()) {
+          if (RefPtr<LayerManager> lm = builder.GetWidgetLayerManager()) {
+            if (PaintTiming* pt = ClientLayerManager::MaybeGetPaintTiming(lm)) {
+              pt->dl2Ms() = (TimeStamp::Now() - dlStart).ToMilliseconds();
+            }
+          }
+        }
+        dlStart = TimeStamp::Now();
+      }
+
       if (!merged) {
         list.DeleteAll(&builder);
         builder.EnterPresShell(aFrame);
         builder.SetDirtyRect(visibleRect);
         builder.ClearWindowDraggingRegion();
         aFrame->BuildDisplayListForStackingContext(&builder, &list);
         AddExtraBackgroundItems(builder, list, aFrame, canvasArea, visibleRegion, aBackstop);
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2832,16 +2832,25 @@ nsIFrame::BuildDisplayListForStackingCon
   if (aBuilder->IsBackgroundOnly()) {
     set.BlockBorderBackgrounds()->DeleteAll(aBuilder);
     set.Floats()->DeleteAll(aBuilder);
     set.Content()->DeleteAll(aBuilder);
     set.PositionedDescendants()->DeleteAll(aBuilder);
     set.Outlines()->DeleteAll(aBuilder);
   }
 
+  if (hasOverrideDirtyRect && gfxPrefs::LayoutDisplayListShowArea()) {
+    nsDisplaySolidColor* color =
+     new (aBuilder) nsDisplaySolidColor(aBuilder, this,
+                                        dirtyRect + aBuilder->GetCurrentFrameOffsetToReferenceFrame(),
+                                        NS_RGBA(255, 0, 0, 64), false);
+    color->SetOverrideZIndex(INT32_MAX);
+    set.PositionedDescendants()->AppendNewToTop(color);
+  }
+
   // Sort PositionedDescendants() in CSS 'z-order' order.  The list is already
   // in content document order and SortByZOrder is a stable sort which
   // guarantees that boxes produced by the same element are placed together
   // in the sort. Consider a position:relative inline element that breaks
   // across lines and has absolutely positioned children; all the abs-pos
   // children should be z-ordered after all the boxes for the position:relative
   // element itself.
   set.PositionedDescendants()->SortByZOrder();
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3553,16 +3553,25 @@ ScrollFrameHelper::BuildDisplayList(nsDi
       }
       scrolledRectClipState.ClipContainingBlockDescendants(
         scrolledRectClip + aBuilder->ToReferenceFrame(mOuter));
 
       nsDisplayListBuilder::AutoBuildingDisplayList
         building(aBuilder, mOuter, visibleRect, dirtyRect, aBuilder->IsAtRootOfPseudoStackingContext());
 
       mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, scrolledContent);
+
+      if (dirtyRectHasBeenOverriden && gfxPrefs::LayoutDisplayListShowArea()) {
+        nsDisplaySolidColor* color =
+          new (aBuilder) nsDisplaySolidColor(aBuilder, mOuter,
+                                             dirtyRect + aBuilder->GetCurrentFrameOffsetToReferenceFrame(),
+                                             NS_RGBA(0, 0, 255, 64), false);
+        color->SetOverrideZIndex(INT32_MAX);
+        scrolledContent.PositionedDescendants()->AppendNewToTop(color);
+      }
     }
 
     if (extraContentBoxClipForNonCaretContent) {
       // The items were built while the inflated content box clip was in
       // effect, so that the caret wasn't clipped unnecessarily. We apply
       // the non-inflated clip to the non-caret items now, by intersecting
       // it with their existing clip.
       ClipListsExceptCaret(&scrolledContent, aBuilder, mScrolledFrame,
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3479,18 +3479,19 @@ public:
 
 protected:
   nscolor mColor;
 };
 
 class nsDisplaySolidColor : public nsDisplaySolidColorBase {
 public:
   nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
-                      const nsRect& aBounds, nscolor aColor)
+                      const nsRect& aBounds, nscolor aColor, bool aCanBeReused = true)
     : nsDisplaySolidColorBase(aBuilder, aFrame, aColor), mBounds(aBounds)
+    , mCanBeReused(aCanBeReused)
   {
     NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
     MOZ_COUNT_CTOR(nsDisplaySolidColor);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplaySolidColor() {
     MOZ_COUNT_DTOR(nsDisplaySolidColor);
   }
@@ -3513,18 +3514,35 @@ public:
   virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
                                        const StackingContextHelper& aSc,
                                        mozilla::layers::WebRenderLayerManager* aManager,
                                        nsDisplayListBuilder* aDisplayListBuilder) override;
 
   NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
 
+  virtual bool CanBeReused() const override { return mCanBeReused; }
+
+  int32_t ZIndex() const override
+  {
+    if (mOverrideZIndex) {
+      return mOverrideZIndex.value();
+    }
+    return nsDisplaySolidColorBase::ZIndex();
+  }
+
+  void SetOverrideZIndex(int32_t aZIndex)
+  {
+    mOverrideZIndex = mozilla::Some(aZIndex);
+  }
+
 private:
   nsRect  mBounds;
+  bool mCanBeReused;
+  mozilla::Maybe<int32_t> mOverrideZIndex;
 };
 
 /**
  * A display item that renders a solid color over a region. This is not
  * exposed through CSS, its only purpose is efficient invalidation of
  * the find bar highlighter dimmer.
  */
 class nsDisplaySolidColorRegion : public nsDisplayItem {