1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "base/basictypes.h"
8 
9 #include "mozilla/PresShell.h"
10 #include "mozilla/dom/ContentParent.h"
11 #include "mozilla/dom/BrowserParent.h"
12 #include "mozilla/layers/CompositorBridgeParent.h"
13 #include "mozilla/layers/CompositorTypes.h"
14 #include "mozilla/layers/LayerTransactionParent.h"
15 #include "nsFrameLoader.h"
16 #include "nsStyleStructInlines.h"
17 #include "nsSubDocumentFrame.h"
18 #include "RemoteLayerTreeOwner.h"
19 #include "mozilla/gfx/GPUProcessManager.h"
20 #include "mozilla/layers/CompositorBridgeChild.h"
21 #include "mozilla/layers/WebRenderLayerManager.h"
22 #include "mozilla/layers/WebRenderScrollData.h"
23 #include "mozilla/webrender/WebRenderAPI.h"
24 #include "mozilla/dom/EffectsInfo.h"
25 
26 using namespace mozilla::dom;
27 using namespace mozilla::gfx;
28 using namespace mozilla::layers;
29 
30 namespace mozilla {
31 namespace layout {
32 
GetLayerManager(BrowserParent * aBrowserParent)33 static already_AddRefed<LayerManager> GetLayerManager(
34     BrowserParent* aBrowserParent) {
35   if (Element* element = aBrowserParent->GetOwnerElement()) {
36     if (RefPtr<LayerManager> lm =
37             nsContentUtils::LayerManagerForContent(element)) {
38       return lm.forget();
39     }
40     return nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
41   }
42   return nullptr;
43 }
44 
RemoteLayerTreeOwner()45 RemoteLayerTreeOwner::RemoteLayerTreeOwner()
46     : mLayersId{0},
47       mBrowserParent(nullptr),
48       mLayerManager(nullptr),
49       mInitialized(false),
50       mLayersConnected(false) {}
51 
52 RemoteLayerTreeOwner::~RemoteLayerTreeOwner() = default;
53 
Initialize(BrowserParent * aBrowserParent)54 bool RemoteLayerTreeOwner::Initialize(BrowserParent* aBrowserParent) {
55   if (mInitialized || !aBrowserParent) {
56     return false;
57   }
58 
59   mBrowserParent = aBrowserParent;
60   RefPtr<LayerManager> lm = GetLayerManager(mBrowserParent);
61   PCompositorBridgeChild* compositor =
62       lm ? lm->GetCompositorBridgeChild() : nullptr;
63   mTabProcessId = mBrowserParent->Manager()->OtherPid();
64 
65   // Our remote frame will push layers updates to the compositor,
66   // and we'll keep an indirect reference to that tree.
67   GPUProcessManager* gpm = GPUProcessManager::Get();
68   mLayersConnected = gpm->AllocateAndConnectLayerTreeId(
69       compositor, mTabProcessId, &mLayersId, &mCompositorOptions);
70 
71   mInitialized = true;
72   return true;
73 }
74 
Destroy()75 void RemoteLayerTreeOwner::Destroy() {
76   if (mLayersId.IsValid()) {
77     GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, mTabProcessId);
78   }
79 
80   mBrowserParent = nullptr;
81   mLayerManager = nullptr;
82 }
83 
EnsureLayersConnected(CompositorOptions * aCompositorOptions)84 void RemoteLayerTreeOwner::EnsureLayersConnected(
85     CompositorOptions* aCompositorOptions) {
86   RefPtr<LayerManager> lm = GetLayerManager(mBrowserParent);
87   if (!lm) {
88     return;
89   }
90 
91   if (!lm->GetCompositorBridgeChild()) {
92     return;
93   }
94 
95   mLayersConnected = lm->GetCompositorBridgeChild()->SendNotifyChildRecreated(
96       mLayersId, &mCompositorOptions);
97   *aCompositorOptions = mCompositorOptions;
98 }
99 
AttachLayerManager()100 LayerManager* RemoteLayerTreeOwner::AttachLayerManager() {
101   RefPtr<LayerManager> lm;
102   if (mBrowserParent) {
103     lm = GetLayerManager(mBrowserParent);
104   }
105 
106   // Perhaps the document containing this frame currently has no presentation?
107   if (lm && lm->GetCompositorBridgeChild() && lm != mLayerManager) {
108     mLayersConnected =
109         lm->GetCompositorBridgeChild()->SendAdoptChild(mLayersId);
110     FrameLayerBuilder::InvalidateAllLayers(lm);
111   }
112 
113   mLayerManager = std::move(lm);
114   return mLayerManager;
115 }
116 
OwnerContentChanged()117 void RemoteLayerTreeOwner::OwnerContentChanged() {
118   Unused << AttachLayerManager();
119 }
120 
GetTextureFactoryIdentifier(TextureFactoryIdentifier * aTextureFactoryIdentifier) const121 void RemoteLayerTreeOwner::GetTextureFactoryIdentifier(
122     TextureFactoryIdentifier* aTextureFactoryIdentifier) const {
123   RefPtr<LayerManager> lm =
124       mBrowserParent ? GetLayerManager(mBrowserParent) : nullptr;
125   // Perhaps the document containing this frame currently has no presentation?
126   if (lm) {
127     *aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
128   } else {
129     *aTextureFactoryIdentifier = TextureFactoryIdentifier();
130   }
131 }
132 
133 }  // namespace layout
134 }  // namespace mozilla
135