summaryrefslogtreecommitdiffstats
path: root/layout/ipc/RemoteLayerTreeOwner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/ipc/RemoteLayerTreeOwner.cpp')
-rw-r--r--layout/ipc/RemoteLayerTreeOwner.cpp138
1 files changed, 138 insertions, 0 deletions
diff --git a/layout/ipc/RemoteLayerTreeOwner.cpp b/layout/ipc/RemoteLayerTreeOwner.cpp
new file mode 100644
index 0000000000..0ab05c8000
--- /dev/null
+++ b/layout/ipc/RemoteLayerTreeOwner.cpp
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "base/basictypes.h"
+
+#include "mozilla/PresShell.h"
+#include "mozilla/dom/ContentParent.h"
+#include "mozilla/dom/BrowserParent.h"
+#include "mozilla/layers/CompositorBridgeParent.h"
+#include "mozilla/layers/CompositorTypes.h"
+#include "nsFrameLoader.h"
+#include "nsStyleStructInlines.h"
+#include "nsSubDocumentFrame.h"
+#include "RemoteLayerTreeOwner.h"
+#include "mozilla/gfx/GPUProcessManager.h"
+#include "mozilla/layers/CompositorBridgeChild.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
+#include "mozilla/layers/WebRenderScrollData.h"
+#include "mozilla/webrender/WebRenderAPI.h"
+#include "mozilla/dom/EffectsInfo.h"
+
+using namespace mozilla::dom;
+using namespace mozilla::gfx;
+using namespace mozilla::layers;
+
+namespace mozilla {
+namespace layout {
+
+static already_AddRefed<WindowRenderer> GetWindowRenderer(
+ BrowserParent* aBrowserParent) {
+ RefPtr<WindowRenderer> renderer;
+ if (Element* element = aBrowserParent->GetOwnerElement()) {
+ renderer = nsContentUtils::WindowRendererForContent(element);
+ if (renderer) {
+ return renderer.forget();
+ }
+ renderer = nsContentUtils::WindowRendererForDocument(element->OwnerDoc());
+ if (renderer) {
+ return renderer.forget();
+ }
+ }
+ return nullptr;
+}
+
+RemoteLayerTreeOwner::RemoteLayerTreeOwner()
+ : mLayersId{0},
+ mBrowserParent(nullptr),
+ mInitialized(false),
+ mLayersConnected(false) {}
+
+RemoteLayerTreeOwner::~RemoteLayerTreeOwner() = default;
+
+bool RemoteLayerTreeOwner::Initialize(BrowserParent* aBrowserParent) {
+ if (mInitialized || !aBrowserParent) {
+ return false;
+ }
+
+ mBrowserParent = aBrowserParent;
+ RefPtr<WindowRenderer> renderer = GetWindowRenderer(mBrowserParent);
+ PCompositorBridgeChild* compositor =
+ renderer ? renderer->GetCompositorBridgeChild() : nullptr;
+ mTabProcessId = mBrowserParent->Manager()->OtherPid();
+
+ // Our remote frame will push layers updates to the compositor,
+ // and we'll keep an indirect reference to that tree.
+ GPUProcessManager* gpm = GPUProcessManager::Get();
+ mLayersConnected = gpm->AllocateAndConnectLayerTreeId(
+ compositor, mTabProcessId, &mLayersId, &mCompositorOptions);
+
+ mInitialized = true;
+ return true;
+}
+
+void RemoteLayerTreeOwner::Destroy() {
+ if (mLayersId.IsValid()) {
+ GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, mTabProcessId);
+ }
+
+ mBrowserParent = nullptr;
+ mWindowRenderer = nullptr;
+}
+
+void RemoteLayerTreeOwner::EnsureLayersConnected(
+ CompositorOptions* aCompositorOptions) {
+ RefPtr<WindowRenderer> renderer = GetWindowRenderer(mBrowserParent);
+ if (!renderer) {
+ return;
+ }
+
+ if (!renderer->GetCompositorBridgeChild()) {
+ return;
+ }
+
+ mLayersConnected =
+ renderer->GetCompositorBridgeChild()->SendNotifyChildRecreated(
+ mLayersId, &mCompositorOptions);
+ *aCompositorOptions = mCompositorOptions;
+}
+
+bool RemoteLayerTreeOwner::AttachWindowRenderer() {
+ RefPtr<WindowRenderer> renderer;
+ if (mBrowserParent) {
+ renderer = GetWindowRenderer(mBrowserParent);
+ }
+
+ // Perhaps the document containing this frame currently has no presentation?
+ if (renderer && renderer->GetCompositorBridgeChild() &&
+ renderer != mWindowRenderer) {
+ mLayersConnected =
+ renderer->GetCompositorBridgeChild()->SendAdoptChild(mLayersId);
+ }
+
+ mWindowRenderer = std::move(renderer);
+ return !!mWindowRenderer;
+}
+
+void RemoteLayerTreeOwner::OwnerContentChanged() {
+ Unused << AttachWindowRenderer();
+}
+
+void RemoteLayerTreeOwner::GetTextureFactoryIdentifier(
+ TextureFactoryIdentifier* aTextureFactoryIdentifier) const {
+ RefPtr<WindowRenderer> renderer =
+ mBrowserParent ? GetWindowRenderer(mBrowserParent) : nullptr;
+ // Perhaps the document containing this frame currently has no presentation?
+ if (renderer && renderer->AsWebRender()) {
+ *aTextureFactoryIdentifier =
+ renderer->AsWebRender()->GetTextureFactoryIdentifier();
+ } else {
+ *aTextureFactoryIdentifier = TextureFactoryIdentifier();
+ }
+}
+
+} // namespace layout
+} // namespace mozilla