Bug 1261554 (Part 2) - Mark frames which are added to the display list when painting to the window as having Visibility::IN_DISPLAYPORT. r=mstange
authorSeth Fowler <mark.seth.fowler@gmail.com>
Thu, 21 Apr 2016 01:22:10 -0700
changeset 318034 82c3b4b81d82daa6cd0dcddfecdcab9e0d0d1773
parent 318033 69abdc731a9962cb1220facb41f26bef7087b486
child 318035 bb3bf463c0ec5fae4dcb8469a1cd127d40ad8f59
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1261554
milestone48.0a1
Bug 1261554 (Part 2) - Mark frames which are added to the display list when painting to the window as having Visibility::IN_DISPLAYPORT. r=mstange
layout/base/nsPresShell.cpp
layout/generic/nsFrame.cpp
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4740,16 +4740,19 @@ PresShell::RenderDocument(const nsRect& 
   // Don't let drawWindow blow away our retained layer tree
   if ((flags & nsLayoutUtils::PAINT_WIDGET_LAYERS) && wouldFlushRetainedLayers) {
     flags &= ~nsLayoutUtils::PAINT_WIDGET_LAYERS;
   }
 
   nsLayoutUtils::PaintFrame(&rc, rootFrame, nsRegion(aRect),
                             aBackgroundColor, flags);
 
+  // We don't call NotifyCompositorOfVisibleRegionsChange here because we're
+  // not painting to the window, and hence there should be no change.
+
   return NS_OK;
 }
 
 /*
  * Clip the display list aList to a range. Returns the clipped
  * rectangle surrounding the range.
  */
 nsRect
@@ -6427,18 +6430,40 @@ PresShell::Paint(nsView*        aViewToP
     flags |= nsLayoutUtils::PAINT_SYNC_DECODE_IMAGES;
   }
   if (mNextPaintCompressed) {
     flags |= nsLayoutUtils::PAINT_COMPRESSED;
     mNextPaintCompressed = false;
   }
 
   if (frame) {
+    // Remove the entries of the mInDisplayPortFrames hashtable and put them
+    // in oldInDisplayPortFrames.
+    VisibleFrames oldInDisplayPortFrames;
+    mInDisplayPortFrames.SwapElements(oldInDisplayPortFrames);
+
+    InitVisibleRegionsIfVisualizationEnabled(VisibilityCounter::IN_DISPLAYPORT);
+
     // We can paint directly into the widget using its layer manager.
     nsLayoutUtils::PaintFrame(nullptr, frame, aDirtyRegion, bgcolor, flags);
+
+    DecVisibleCount(oldInDisplayPortFrames, VisibilityCounter::IN_DISPLAYPORT);
+
+    if (mVisibleRegions &&
+        !mNotifyCompositorOfVisibleRegionsChangeEvent.IsPending()) {
+      // Asynchronously notify the compositor of the new visible regions,
+      // since this is happening during a paint and updating the visible
+      // regions triggers a recomposite.
+      RefPtr<nsRunnableMethod<PresShell>> event =
+        NS_NewRunnableMethod(this, &PresShell::NotifyCompositorOfVisibleRegionsChange);
+      if (NS_SUCCEEDED(NS_DispatchToMainThread(event))) {
+        mNotifyCompositorOfVisibleRegionsChangeEvent = event;
+      }
+    }
+
     return;
   }
 
   RefPtr<ColorLayer> root = layerManager->CreateColorLayer();
   if (root) {
     nsPresContext* pc = GetPresContext();
     nsIntRect bounds =
       pc->GetVisibleArea().ToOutsidePixels(pc->AppUnitsPerDevPixel());
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2699,16 +2699,24 @@ nsIFrame::BuildDisplayListForChild(nsDis
   
   const nsStyleDisplay* ourDisp = StyleDisplay();
   // REVIEW: Taken from nsBoxFrame::Paint
   // Don't paint our children if the theme object is a leaf.
   if (IsThemed(ourDisp) &&
       !PresContext()->GetTheme()->WidgetIsContainer(ourDisp->mAppearance))
     return;
 
+  // Since we're now sure that we're adding this frame to the display list
+  // (which means we're painting it, modulo occlusion), mark it as visible
+  // within the displayport.
+  if (aBuilder->IsPaintingToWindow() && child->TrackingVisibility()) {
+    nsIPresShell* shell = child->PresContext()->PresShell();
+    shell->MarkFrameVisibleInDisplayPort(child);
+  }
+
   // Child is composited if it's transformed, partially transparent, or has
   // SVG effects or a blend mode..
   const nsStyleDisplay* disp = child->StyleDisplay();
   const nsStyleEffects* effects = child->StyleEffects();
   const nsStylePosition* pos = child->StylePosition();
   bool isVisuallyAtomic = child->HasOpacity()
     || child->IsTransformed()
     // strictly speaking, 'perspective' doesn't require visual atomicity,