Bug 1475139 part 9 - Use DrawDependentSurface in nsDisplayRemote when painting to a temp layer manager with a recording. r=mattwoodrow
authorRyan Hunt <rhunt@eqrion.net>
Mon, 24 Sep 2018 21:45:54 -0500
changeset 495735 12814192462281b2ca942b957c1bb3c016b46f2e
parent 495734 0bad6cdec7dad7df2f91427b9e36d56585ff1883
child 495736 3942a3b983a65155b928456d9cf4ed4aca447857
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1475139
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1475139 part 9 - Use DrawDependentSurface in nsDisplayRemote when painting to a temp layer manager with a recording. r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D6788
layout/generic/nsSubDocumentFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -362,17 +362,26 @@ nsSubDocumentFrame::BuildDisplayList(nsD
   // subdocuments no matter what, to determine which parts are transparent for
   // hit-testing or event regions.
   bool needToDescend = aBuilder->GetDescendIntoSubdocuments();
   if (!mInnerView || !needToDescend) {
     return;
   }
 
   if (rfp) {
-    rfp->BuildDisplayList(aBuilder, this, aLists);
+    // We're the subdoc for <browser remote="true"> and it has
+    // painted content.  Display its shadow layer tree.
+    DisplayListClipState::AutoSaveRestore clipState(aBuilder);
+
+    nsPoint offset = aBuilder->ToReferenceFrame(this);
+    nsRect bounds = this->EnsureInnerView()->GetBounds() + offset;
+    clipState.ClipContentDescendants(bounds);
+
+    aLists.Content()->AppendToTop(
+      MakeDisplayItem<nsDisplayRemote>(aBuilder, this));
     return;
   }
 
   nsCOMPtr<nsIPresShell> presShell =
     GetSubdocumentPresShellForPainting(
       aBuilder->IsIgnoringPaintSuppression() ? IGNORE_PAINT_SUPPRESSION : 0);
 
   if (!presShell) {
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -270,33 +270,16 @@ RenderFrameParent::TriggerRepaint()
     // to /dev/null.
     return;
   }
 
   docFrame->InvalidateLayer(DisplayItemType::TYPE_REMOTE);
 }
 
 void
-RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
-                                    nsSubDocumentFrame* aFrame,
-                                    const nsDisplayListSet& aLists)
-{
-  // We're the subdoc for <browser remote="true"> and it has
-  // painted content.  Display its shadow layer tree.
-  DisplayListClipState::AutoSaveRestore clipState(aBuilder);
-
-  nsPoint offset = aBuilder->ToReferenceFrame(aFrame);
-  nsRect bounds = aFrame->EnsureInnerView()->GetBounds() + offset;
-  clipState.ClipContentDescendants(bounds);
-
-  aLists.Content()->AppendToTop(
-    MakeDisplayItem<nsDisplayRemote>(aBuilder, aFrame));
-}
-
-void
 RenderFrameParent::GetTextureFactoryIdentifier(TextureFactoryIdentifier* aTextureFactoryIdentifier)
 {
   RefPtr<LayerManager> lm = mFrameLoader ? GetLayerManager(mFrameLoader) : nullptr;
   // Perhaps the document containing this frame currently has no presentation?
   if (lm) {
     *aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
   } else {
     *aTextureFactoryIdentifier = TextureFactoryIdentifier();
@@ -336,27 +319,47 @@ RenderFrameParent::EnsureLayersConnected
 }
 
 } // namespace layout
 } // namespace mozilla
 
 nsDisplayRemote::nsDisplayRemote(nsDisplayListBuilder* aBuilder,
                                  nsSubDocumentFrame* aFrame)
   : nsDisplayItem(aBuilder, aFrame)
+  , mTabId{0}
   , mEventRegionsOverride(EventRegionsOverride::NoOverride)
 {
   bool frameIsPointerEventsNone =
     aFrame->StyleUI()->GetEffectivePointerEvents(aFrame) ==
       NS_STYLE_POINTER_EVENTS_NONE;
   if (aBuilder->IsInsidePointerEventsNoneDoc() || frameIsPointerEventsNone) {
     mEventRegionsOverride |= EventRegionsOverride::ForceEmptyHitRegion;
   }
   if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresShell())) {
     mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
   }
+
+  nsFrameLoader* frameLoader = GetRenderFrameParent()->FrameLoader();
+  if (frameLoader) {
+    TabParent* browser = TabParent::GetFrom(frameLoader);
+    if (browser) {
+      mTabId = browser->GetTabId();
+    }
+  }
+}
+
+mozilla::LayerState
+nsDisplayRemote::GetLayerState(nsDisplayListBuilder* aBuilder,
+                               LayerManager* aManager,
+                               const ContainerLayerParameters& aParameters)
+{
+  if (mozilla::layout::IsTempLayerManager(aManager)) {
+    return mozilla::LAYER_NONE;
+  }
+  return mozilla::LAYER_ACTIVE_FORCE;
 }
 
 bool
 nsDisplayRemote::HasDeletedFrame() const
 {
   // RenderFrameParent might change without invalidating nsSubDocumentFrame.
   return !GetRenderFrameParent() || nsDisplayItem::HasDeletedFrame();
 }
@@ -373,16 +376,31 @@ nsDisplayRemote::BuildLayer(nsDisplayLis
                                        this, aContainerParameters);
 
   if (layer && layer->AsRefLayer()) {
     layer->AsRefLayer()->SetEventRegionsOverride(mEventRegionsOverride);
   }
   return layer.forget();
 }
 
+void
+nsDisplayRemote::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx)
+{
+  DrawTarget* target = aCtx->GetDrawTarget();
+  if (!target->IsRecording() || mTabId == 0) {
+    NS_WARNING("Remote iframe not rendered");
+    return;
+  }
+
+  int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
+  Rect destRect =
+    mozilla::NSRectToSnappedRect(GetContentRect(), appUnitsPerDevPixel, *target);
+  target->DrawDependentSurface(mTabId, destRect);
+}
+
 bool
 nsDisplayRemote::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                          mozilla::wr::IpcResourceUpdateQueue& aResources,
                                          const StackingContextHelper& aSc,
                                          mozilla::layers::WebRenderLayerManager* aManager,
                                          nsDisplayListBuilder* aDisplayListBuilder)
 {
   mOffset = mozilla::layout::GetContentRectLayerOffset(mFrame, aDisplayListBuilder);
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layout_RenderFrameParent_h
 #define mozilla_layout_RenderFrameParent_h
 
 #include "mozilla/Attributes.h"
 #include <map>
 
+#include "mozilla/dom/ipc/IdType.h"
 #include "mozilla/layers/APZUtils.h"
 #include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/layers/LayersTypes.h"
 #include "mozilla/layout/PRenderFrameParent.h"
 #include "nsDisplayList.h"
 
 class nsFrameLoader;
 class nsSubDocumentFrame;
@@ -59,19 +60,16 @@ public:
    */
   explicit RenderFrameParent(nsFrameLoader* aFrameLoader);
   virtual ~RenderFrameParent();
 
   bool Init(nsFrameLoader* aFrameLoader);
   bool IsInitted();
   void Destroy();
 
-  void BuildDisplayList(nsDisplayListBuilder* aBuilder,
-                        nsSubDocumentFrame* aFrame,
-                        const nsDisplayListSet& aLists);
 
   already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                      nsIFrame* aFrame,
                                      LayerManager* aManager,
                                      nsDisplayItem* aItem,
                                      const ContainerLayerParameters& aContainerParameters);
 
   void OwnerContentChanged(nsIContent* aContent);
@@ -85,16 +83,21 @@ public:
   inline CompositorOptions GetCompositorOptions() const { return mCompositorOptions; }
 
   void TakeFocusForClickFromTap();
 
   void EnsureLayersConnected(CompositorOptions* aCompositorOptions);
 
   LayerManager* AttachLayerManager();
 
+  nsFrameLoader* FrameLoader() const
+  {
+    return mFrameLoader;
+  }
+
 protected:
   void ActorDestroy(ActorDestroyReason why) override;
 
   virtual mozilla::ipc::IPCResult RecvNotifyCompositorTransaction() override;
 
 private:
   void TriggerRepaint();
   void DispatchEventForPanZoomController(const InputEvent& aEvent);
@@ -150,37 +153,37 @@ class nsDisplayRemote final : public nsD
 public:
   nsDisplayRemote(nsDisplayListBuilder* aBuilder,
                   nsSubDocumentFrame* aFrame);
 
   bool HasDeletedFrame() const override;
 
   LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                            LayerManager* aManager,
-                           const ContainerLayerParameters& aParameters) override
-  {
-    return mozilla::LAYER_ACTIVE_FORCE;
-  }
+                           const ContainerLayerParameters& aParameters) override;
 
   already_AddRefed<Layer>
   BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager,
              const ContainerLayerParameters& aContainerParameters) override;
 
+  void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
+
   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                mozilla::wr::IpcResourceUpdateQueue& aResources,
                                const StackingContextHelper& aSc,
                                mozilla::layers::WebRenderLayerManager* aManager,
                                nsDisplayListBuilder* aDisplayListBuilder) override;
   bool UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
                         mozilla::layers::WebRenderLayerScrollData* aLayerData) override;
 
   NS_DISPLAY_DECL_NAME("Remote", TYPE_REMOTE)
 
 private:
   mozilla::layers::LayersId GetRemoteLayersId() const;
   RenderFrameParent* GetRenderFrameParent() const;
 
+  mozilla::dom::TabId mTabId;
   mozilla::LayoutDeviceIntPoint mOffset;
   mozilla::layers::EventRegionsOverride mEventRegionsOverride;
 };
 
 
 #endif  // mozilla_layout_RenderFrameParent_h