RemoteLayerTreeOwner.cpp (4358B)
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 "RemoteLayerTreeOwner.h" 8 9 #include "base/basictypes.h" 10 #include "mozilla/PresShell.h" 11 #include "mozilla/dom/BrowserParent.h" 12 #include "mozilla/dom/ContentParent.h" 13 #include "mozilla/dom/EffectsInfo.h" 14 #include "mozilla/gfx/GPUProcessManager.h" 15 #include "mozilla/layers/CompositorBridgeChild.h" 16 #include "mozilla/layers/CompositorBridgeParent.h" 17 #include "mozilla/layers/CompositorTypes.h" 18 #include "mozilla/layers/WebRenderLayerManager.h" 19 #include "mozilla/layers/WebRenderScrollData.h" 20 #include "mozilla/webrender/WebRenderAPI.h" 21 #include "nsFrameLoader.h" 22 #include "nsStyleStructInlines.h" 23 #include "nsSubDocumentFrame.h" 24 25 using namespace mozilla::dom; 26 using namespace mozilla::gfx; 27 using namespace mozilla::layers; 28 29 namespace mozilla { 30 namespace layout { 31 32 static already_AddRefed<WindowRenderer> GetWindowRenderer( 33 BrowserParent* aBrowserParent) { 34 RefPtr<WindowRenderer> renderer; 35 if (Element* element = aBrowserParent->GetOwnerElement()) { 36 renderer = nsContentUtils::WindowRendererForContent(element); 37 if (renderer) { 38 return renderer.forget(); 39 } 40 renderer = nsContentUtils::WindowRendererForDocument(element->OwnerDoc()); 41 if (renderer) { 42 return renderer.forget(); 43 } 44 } 45 return nullptr; 46 } 47 48 RemoteLayerTreeOwner::RemoteLayerTreeOwner() 49 : mLayersId{0}, 50 mBrowserParent(nullptr), 51 mInitialized(false), 52 mLayersConnected(false) {} 53 54 RemoteLayerTreeOwner::~RemoteLayerTreeOwner() = default; 55 56 bool RemoteLayerTreeOwner::Initialize(BrowserParent* aBrowserParent) { 57 if (mInitialized || !aBrowserParent) { 58 return false; 59 } 60 61 mBrowserParent = aBrowserParent; 62 RefPtr<WindowRenderer> renderer = GetWindowRenderer(mBrowserParent); 63 PCompositorBridgeChild* compositor = 64 renderer ? renderer->GetCompositorBridgeChild() : nullptr; 65 mTabProcessId = mBrowserParent->Manager()->OtherPid(); 66 67 // Our remote frame will push layers updates to the compositor, 68 // and we'll keep an indirect reference to that tree. 69 GPUProcessManager* gpm = GPUProcessManager::Get(); 70 mLayersConnected = gpm->AllocateAndConnectLayerTreeId( 71 compositor, mTabProcessId, &mLayersId, &mCompositorOptions); 72 73 mInitialized = true; 74 return true; 75 } 76 77 void RemoteLayerTreeOwner::Destroy() { 78 if (mLayersId.IsValid()) { 79 GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, mTabProcessId); 80 } 81 82 mBrowserParent = nullptr; 83 mWindowRenderer = nullptr; 84 } 85 86 void RemoteLayerTreeOwner::EnsureLayersConnected( 87 CompositorOptions* aCompositorOptions) { 88 RefPtr<WindowRenderer> renderer = GetWindowRenderer(mBrowserParent); 89 if (!renderer) { 90 return; 91 } 92 93 if (!renderer->GetCompositorBridgeChild()) { 94 return; 95 } 96 97 mLayersConnected = 98 renderer->GetCompositorBridgeChild()->SendNotifyChildRecreated( 99 mLayersId, &mCompositorOptions); 100 *aCompositorOptions = mCompositorOptions; 101 } 102 103 bool RemoteLayerTreeOwner::AttachWindowRenderer() { 104 RefPtr<WindowRenderer> renderer; 105 if (mBrowserParent) { 106 renderer = GetWindowRenderer(mBrowserParent); 107 } 108 109 // Perhaps the document containing this frame currently has no presentation? 110 if (renderer && renderer->GetCompositorBridgeChild() && 111 renderer != mWindowRenderer) { 112 mLayersConnected = 113 renderer->GetCompositorBridgeChild()->SendAdoptChild(mLayersId); 114 } 115 116 mWindowRenderer = std::move(renderer); 117 return !!mWindowRenderer; 118 } 119 120 void RemoteLayerTreeOwner::OwnerContentChanged() { 121 (void)AttachWindowRenderer(); 122 } 123 124 void RemoteLayerTreeOwner::GetTextureFactoryIdentifier( 125 TextureFactoryIdentifier* aTextureFactoryIdentifier) const { 126 RefPtr<WindowRenderer> renderer = 127 mBrowserParent ? GetWindowRenderer(mBrowserParent) : nullptr; 128 // Perhaps the document containing this frame currently has no presentation? 129 if (renderer && renderer->AsWebRender()) { 130 *aTextureFactoryIdentifier = 131 renderer->AsWebRender()->GetTextureFactoryIdentifier(); 132 } else { 133 *aTextureFactoryIdentifier = TextureFactoryIdentifier(); 134 } 135 } 136 137 } // namespace layout 138 } // namespace mozilla