summaryrefslogtreecommitdiffstats
path: root/widget/windows/WinCompositorWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/windows/WinCompositorWidget.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/widget/windows/WinCompositorWidget.cpp b/widget/windows/WinCompositorWidget.cpp
new file mode 100644
index 0000000000..15957a1c3f
--- /dev/null
+++ b/widget/windows/WinCompositorWidget.cpp
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "WinCompositorWidget.h"
+
+#include "mozilla/StaticPrefs_layers.h"
+#include "mozilla/gfx/DeviceManagerDx.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/layers/Compositor.h"
+#include "mozilla/layers/CompositorThread.h"
+#include "mozilla/webrender/RenderThread.h"
+#include "mozilla/widget/PlatformWidgetTypes.h"
+#include "nsWindow.h"
+#include "VsyncDispatcher.h"
+#include "WinCompositorWindowThread.h"
+#include "VRShMem.h"
+
+#include <ddraw.h>
+
+namespace mozilla {
+namespace widget {
+
+using namespace mozilla::gfx;
+using namespace mozilla;
+
+WinCompositorWidget::WinCompositorWidget(
+ const WinCompositorWidgetInitData& aInitData,
+ const layers::CompositorOptions& aOptions)
+ : CompositorWidget(aOptions),
+ mSetParentCompleted(false),
+ mWidgetKey(aInitData.widgetKey()),
+ mWnd(reinterpret_cast<HWND>(aInitData.hWnd())),
+ mCompositorWnds(nullptr, nullptr) {
+ MOZ_ASSERT(mWnd && ::IsWindow(mWnd));
+}
+
+WinCompositorWidget::~WinCompositorWidget() { DestroyCompositorWindow(); }
+
+uintptr_t WinCompositorWidget::GetWidgetKey() { return mWidgetKey; }
+
+void WinCompositorWidget::EnsureCompositorWindow() {
+ if (mCompositorWnds.mCompositorWnd || mCompositorWnds.mInitialParentWnd) {
+ return;
+ }
+
+ mCompositorWnds = WinCompositorWindowThread::CreateCompositorWindow();
+ UpdateCompositorWnd(mCompositorWnds.mCompositorWnd, mWnd);
+
+ MOZ_ASSERT(mCompositorWnds.mCompositorWnd);
+ MOZ_ASSERT(mCompositorWnds.mInitialParentWnd);
+}
+
+void WinCompositorWidget::DestroyCompositorWindow() {
+ if (!mCompositorWnds.mCompositorWnd && !mCompositorWnds.mInitialParentWnd) {
+ return;
+ }
+ WinCompositorWindowThread::DestroyCompositorWindow(mCompositorWnds);
+ mCompositorWnds = WinCompositorWnds(nullptr, nullptr);
+}
+
+void WinCompositorWidget::UpdateCompositorWndSizeIfNecessary() {
+ if (!mCompositorWnds.mCompositorWnd) {
+ return;
+ }
+
+ LayoutDeviceIntSize size = GetClientSize();
+ if (mLastCompositorWndSize == size) {
+ return;
+ }
+
+ // This code is racing with the compositor, which needs to reparent the
+ // compositor surface to the actual window (mWnd). To avoid racing mutations,
+ // we refuse to proceed until ::SetParent() is called in the parent process.
+ // After the ::SetParent() call, composition is scheduled in
+ // CompositorWidgetParent::UpdateCompositorWnd().
+ if (!mSetParentCompleted) {
+ // ::SetParent() is not completed yet.
+ return;
+ }
+
+ MOZ_ASSERT(mWnd == ::GetParent(mCompositorWnds.mCompositorWnd));
+
+ // Force a resize and redraw (but not a move, activate, etc.).
+ if (!::SetWindowPos(
+ mCompositorWnds.mCompositorWnd, nullptr, 0, 0, size.width,
+ size.height,
+ SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOZORDER)) {
+ return;
+ }
+
+ mLastCompositorWndSize = size;
+}
+
+// Creates a new instance of FxROutputHandler so that this compositor widget
+// can send its output to Firefox Reality for Desktop.
+void WinCompositorWidget::RequestFxrOutput() {
+ MOZ_ASSERT(mFxrHandler == nullptr);
+
+ mFxrHandler.reset(new FxROutputHandler());
+}
+
+} // namespace widget
+} // namespace mozilla