Bug 1829659 - Remove `import.py` because it's not used anymore r=glandium,bwc
[gecko.git] / widget / windows / CompositorWidgetParent.cpp
blob0196f3d6a4e34530fe3d89925b535f92ba301331
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/. */
5 #include "CompositorWidgetParent.h"
7 #include "mozilla/Unused.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/CompositorBridgeParent.h"
13 #include "mozilla/layers/CompositorThread.h"
14 #include "mozilla/webrender/RenderThread.h"
15 #include "mozilla/widget/PlatformWidgetTypes.h"
16 #include "nsWindow.h"
17 #include "VsyncDispatcher.h"
18 #include "WinCompositorWindowThread.h"
19 #include "VRShMem.h"
20 #include "RemoteBackbuffer.h"
22 #include <ddraw.h>
24 namespace mozilla {
25 namespace widget {
27 using namespace mozilla::gfx;
28 using namespace mozilla;
30 CompositorWidgetParent::CompositorWidgetParent(
31 const CompositorWidgetInitData& aInitData,
32 const layers::CompositorOptions& aOptions)
33 : WinCompositorWidget(aInitData.get_WinCompositorWidgetInitData(),
34 aOptions),
35 mWnd(reinterpret_cast<HWND>(
36 aInitData.get_WinCompositorWidgetInitData().hWnd())),
37 mTransparencyMode(uint32_t(
38 aInitData.get_WinCompositorWidgetInitData().transparencyMode())),
39 mSizeMode(nsSizeMode_Normal),
40 mIsFullyOccluded(false),
41 mRemoteBackbufferClient() {
42 MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
43 MOZ_ASSERT(mWnd && ::IsWindow(mWnd));
46 CompositorWidgetParent::~CompositorWidgetParent() {}
48 bool CompositorWidgetParent::Initialize(
49 const RemoteBackbufferHandles& aRemoteHandles) {
50 mRemoteBackbufferClient = std::make_unique<remote_backbuffer::Client>();
51 if (!mRemoteBackbufferClient->Initialize(aRemoteHandles)) {
52 return false;
55 return true;
58 bool CompositorWidgetParent::PreRender(WidgetRenderingContext* aContext) {
59 // This can block waiting for WM_SETTEXT to finish
60 // Using PreRender is unnecessarily pessimistic because
61 // we technically only need to block during the present call
62 // not all of compositor rendering
63 mPresentLock.Enter();
64 return true;
67 void CompositorWidgetParent::PostRender(WidgetRenderingContext* aContext) {
68 mPresentLock.Leave();
71 LayoutDeviceIntSize CompositorWidgetParent::GetClientSize() {
72 RECT r;
73 if (!::GetClientRect(mWnd, &r)) {
74 return LayoutDeviceIntSize();
76 return LayoutDeviceIntSize(r.right - r.left, r.bottom - r.top);
79 already_AddRefed<gfx::DrawTarget>
80 CompositorWidgetParent::StartRemoteDrawingInRegion(
81 const LayoutDeviceIntRegion& aInvalidRegion,
82 layers::BufferMode* aBufferMode) {
83 MOZ_ASSERT(mRemoteBackbufferClient);
84 MOZ_ASSERT(aBufferMode);
86 // Because we use remote backbuffering, there is no need to use a local
87 // backbuffer too.
88 (*aBufferMode) = layers::BufferMode::BUFFER_NONE;
90 return mRemoteBackbufferClient->BorrowDrawTarget();
93 void CompositorWidgetParent::EndRemoteDrawingInRegion(
94 gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
95 Unused << mRemoteBackbufferClient->PresentDrawTarget(
96 aInvalidRegion.ToUnknownRegion());
99 bool CompositorWidgetParent::NeedsToDeferEndRemoteDrawing() { return false; }
101 already_AddRefed<gfx::DrawTarget>
102 CompositorWidgetParent::GetBackBufferDrawTarget(gfx::DrawTarget* aScreenTarget,
103 const gfx::IntRect& aRect,
104 bool* aOutIsCleared) {
105 MOZ_CRASH(
106 "Unexpected call to GetBackBufferDrawTarget() with remote "
107 "backbuffering in use");
110 already_AddRefed<gfx::SourceSurface>
111 CompositorWidgetParent::EndBackBufferDrawing() {
112 MOZ_CRASH(
113 "Unexpected call to EndBackBufferDrawing() with remote "
114 "backbuffering in use");
117 bool CompositorWidgetParent::InitCompositor(layers::Compositor* aCompositor) {
118 return true;
121 bool CompositorWidgetParent::HasGlass() const {
122 MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread() ||
123 wr::RenderThread::IsInRenderThread());
125 return mTransparencyMode == uint32_t(TransparencyMode::BorderlessGlass);
128 bool CompositorWidgetParent::IsHidden() const { return ::IsIconic(mWnd); }
130 mozilla::ipc::IPCResult CompositorWidgetParent::RecvInitialize(
131 const RemoteBackbufferHandles& aRemoteHandles) {
132 Unused << Initialize(aRemoteHandles);
133 return IPC_OK();
136 mozilla::ipc::IPCResult CompositorWidgetParent::RecvEnterPresentLock() {
137 mPresentLock.Enter();
138 return IPC_OK();
141 mozilla::ipc::IPCResult CompositorWidgetParent::RecvLeavePresentLock() {
142 mPresentLock.Leave();
143 return IPC_OK();
146 mozilla::ipc::IPCResult CompositorWidgetParent::RecvUpdateTransparency(
147 const TransparencyMode& aMode) {
148 mTransparencyMode = uint32_t(aMode);
149 return IPC_OK();
152 mozilla::ipc::IPCResult CompositorWidgetParent::RecvNotifyVisibilityUpdated(
153 const nsSizeMode& aSizeMode, const bool& aIsFullyOccluded) {
154 mSizeMode = aSizeMode;
155 mIsFullyOccluded = aIsFullyOccluded;
156 return IPC_OK();
159 nsSizeMode CompositorWidgetParent::CompositorWidgetParent::GetWindowSizeMode()
160 const {
161 nsSizeMode sizeMode = mSizeMode;
162 return sizeMode;
165 bool CompositorWidgetParent::CompositorWidgetParent::GetWindowIsFullyOccluded()
166 const {
167 bool isFullyOccluded = mIsFullyOccluded;
168 return isFullyOccluded;
171 mozilla::ipc::IPCResult CompositorWidgetParent::RecvClearTransparentWindow() {
172 gfx::CriticalSectionAutoEnter lock(&mPresentLock);
174 RefPtr<DrawTarget> drawTarget = mRemoteBackbufferClient->BorrowDrawTarget();
175 if (!drawTarget) {
176 return IPC_OK();
179 IntSize size = drawTarget->GetSize();
180 if (size.IsEmpty()) {
181 return IPC_OK();
184 drawTarget->ClearRect(Rect(0, 0, size.width, size.height));
186 Unused << mRemoteBackbufferClient->PresentDrawTarget(
187 IntRect(0, 0, size.width, size.height));
189 return IPC_OK();
192 nsIWidget* CompositorWidgetParent::RealWidget() { return nullptr; }
194 void CompositorWidgetParent::ObserveVsync(VsyncObserver* aObserver) {
195 if (aObserver) {
196 Unused << SendObserveVsync();
197 } else {
198 Unused << SendUnobserveVsync();
200 mVsyncObserver = aObserver;
203 RefPtr<VsyncObserver> CompositorWidgetParent::GetVsyncObserver() const {
204 MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
205 return mVsyncObserver;
208 void CompositorWidgetParent::UpdateCompositorWnd(const HWND aCompositorWnd,
209 const HWND aParentWnd) {
210 MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread());
211 MOZ_ASSERT(mRootLayerTreeID.isSome());
213 RefPtr<CompositorWidgetParent> self = this;
214 SendUpdateCompositorWnd(reinterpret_cast<WindowsHandle>(aCompositorWnd),
215 reinterpret_cast<WindowsHandle>(aParentWnd))
216 ->Then(
217 layers::CompositorThread(), __func__,
218 [self](const bool& aSuccess) {
219 if (aSuccess && self->mRootLayerTreeID.isSome() &&
220 layers::CompositorThreadHolder::IsActive()) {
221 self->mSetParentCompleted = true;
222 // Schedule composition after ::SetParent() call in parent
223 // process.
224 layers::CompositorBridgeParent::ScheduleForcedComposition(
225 self->mRootLayerTreeID.ref(), wr::RenderReasons::WIDGET);
228 [self](const mozilla::ipc::ResponseRejectReason&) {});
231 void CompositorWidgetParent::SetRootLayerTreeID(
232 const layers::LayersId& aRootLayerTreeId) {
233 mRootLayerTreeID = Some(aRootLayerTreeId);
236 void CompositorWidgetParent::ActorDestroy(ActorDestroyReason aWhy) {}
238 } // namespace widget
239 } // namespace mozilla