1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "WinCompositorWidget.h"
8 #include "mozilla/StaticPrefs_layers.h"
9 #include "mozilla/gfx/DeviceManagerDx.h"
10 #include "mozilla/gfx/Point.h"
11 #include "mozilla/layers/Compositor.h"
12 #include "mozilla/layers/CompositorThread.h"
13 #include "mozilla/webrender/RenderThread.h"
14 #include "mozilla/widget/PlatformWidgetTypes.h"
16 #include "VsyncDispatcher.h"
17 #include "WinCompositorWindowThread.h"
25 using namespace mozilla::gfx
;
26 using namespace mozilla
;
28 WinCompositorWidget::WinCompositorWidget(
29 const WinCompositorWidgetInitData
& aInitData
,
30 const layers::CompositorOptions
& aOptions
)
31 : CompositorWidget(aOptions
),
32 mSetParentCompleted(false),
33 mWidgetKey(aInitData
.widgetKey()),
34 mWnd(reinterpret_cast<HWND
>(aInitData
.hWnd())),
35 mTransparencyMode(uint32_t(aInitData
.transparencyMode())),
36 mCompositorWnds(nullptr, nullptr) {
37 MOZ_ASSERT(mWnd
&& ::IsWindow(mWnd
));
40 WinCompositorWidget::~WinCompositorWidget() { DestroyCompositorWindow(); }
42 uintptr_t WinCompositorWidget::GetWidgetKey() { return mWidgetKey
; }
44 void WinCompositorWidget::EnsureCompositorWindow() {
45 if (mCompositorWnds
.mCompositorWnd
|| mCompositorWnds
.mInitialParentWnd
) {
49 mCompositorWnds
= WinCompositorWindowThread::CreateCompositorWindow();
50 UpdateCompositorWnd(mCompositorWnds
.mCompositorWnd
, mWnd
);
52 MOZ_ASSERT(mCompositorWnds
.mCompositorWnd
);
53 MOZ_ASSERT(mCompositorWnds
.mInitialParentWnd
);
56 void WinCompositorWidget::DestroyCompositorWindow() {
57 if (!mCompositorWnds
.mCompositorWnd
&& !mCompositorWnds
.mInitialParentWnd
) {
60 WinCompositorWindowThread::DestroyCompositorWindow(mCompositorWnds
);
61 mCompositorWnds
= WinCompositorWnds(nullptr, nullptr);
64 void WinCompositorWidget::UpdateCompositorWndSizeIfNecessary() {
65 if (!mCompositorWnds
.mCompositorWnd
) {
69 LayoutDeviceIntSize size
= GetClientSize();
70 if (mLastCompositorWndSize
== size
) {
74 // This code is racing with the compositor, which needs to reparent the
75 // compositor surface to the actual window (mWnd). To avoid racing mutations,
76 // we refuse to proceed until ::SetParent() is called in the parent process.
77 // After the ::SetParent() call, composition is scheduled in
78 // CompositorWidgetParent::UpdateCompositorWnd().
79 if (!mSetParentCompleted
) {
80 // ::SetParent() is not completed yet.
84 MOZ_ASSERT(mWnd
== ::GetParent(mCompositorWnds
.mCompositorWnd
));
86 // Force a resize and redraw (but not a move, activate, etc.).
88 mCompositorWnds
.mCompositorWnd
, nullptr, 0, 0, size
.width
,
90 SWP_NOACTIVATE
| SWP_NOCOPYBITS
| SWP_NOOWNERZORDER
| SWP_NOZORDER
)) {
94 mLastCompositorWndSize
= size
;
97 // Creates a new instance of FxROutputHandler so that this compositor widget
98 // can send its output to Firefox Reality for Desktop.
99 void WinCompositorWidget::RequestFxrOutput() {
100 MOZ_ASSERT(mFxrHandler
== nullptr);
102 mFxrHandler
.reset(new FxROutputHandler());
105 } // namespace widget
106 } // namespace mozilla