Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / widget / windows / CompositorWidgetParent.cpp
blobd38125f4caffb4b4f8a9bc99db7cb6dc087e2333
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::IsHidden() const { return ::IsIconic(mWnd); }
123 mozilla::ipc::IPCResult CompositorWidgetParent::RecvInitialize(
124 const RemoteBackbufferHandles& aRemoteHandles) {
125 Unused << Initialize(aRemoteHandles);
126 return IPC_OK();
129 mozilla::ipc::IPCResult CompositorWidgetParent::RecvEnterPresentLock() {
130 mPresentLock.Enter();
131 return IPC_OK();
134 mozilla::ipc::IPCResult CompositorWidgetParent::RecvLeavePresentLock() {
135 mPresentLock.Leave();
136 return IPC_OK();
139 mozilla::ipc::IPCResult CompositorWidgetParent::RecvUpdateTransparency(
140 const TransparencyMode& aMode) {
141 mTransparencyMode = uint32_t(aMode);
142 return IPC_OK();
145 mozilla::ipc::IPCResult CompositorWidgetParent::RecvNotifyVisibilityUpdated(
146 const nsSizeMode& aSizeMode, const bool& aIsFullyOccluded) {
147 mSizeMode = aSizeMode;
148 mIsFullyOccluded = aIsFullyOccluded;
149 return IPC_OK();
152 nsSizeMode CompositorWidgetParent::GetWindowSizeMode() const {
153 return mSizeMode;
156 bool CompositorWidgetParent::GetWindowIsFullyOccluded() const {
157 return mIsFullyOccluded;
160 mozilla::ipc::IPCResult CompositorWidgetParent::RecvClearTransparentWindow() {
161 gfx::CriticalSectionAutoEnter lock(&mPresentLock);
163 RefPtr<DrawTarget> drawTarget = mRemoteBackbufferClient->BorrowDrawTarget();
164 if (!drawTarget) {
165 return IPC_OK();
168 IntSize size = drawTarget->GetSize();
169 if (size.IsEmpty()) {
170 return IPC_OK();
173 drawTarget->ClearRect(Rect(0, 0, size.width, size.height));
175 Unused << mRemoteBackbufferClient->PresentDrawTarget(
176 IntRect(0, 0, size.width, size.height));
178 return IPC_OK();
181 nsIWidget* CompositorWidgetParent::RealWidget() { return nullptr; }
183 void CompositorWidgetParent::ObserveVsync(VsyncObserver* aObserver) {
184 if (aObserver) {
185 Unused << SendObserveVsync();
186 } else {
187 Unused << SendUnobserveVsync();
189 mVsyncObserver = aObserver;
192 RefPtr<VsyncObserver> CompositorWidgetParent::GetVsyncObserver() const {
193 MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
194 return mVsyncObserver;
197 void CompositorWidgetParent::UpdateCompositorWnd(const HWND aCompositorWnd,
198 const HWND aParentWnd) {
199 MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread());
200 MOZ_ASSERT(mRootLayerTreeID.isSome());
202 RefPtr<CompositorWidgetParent> self = this;
203 SendUpdateCompositorWnd(reinterpret_cast<WindowsHandle>(aCompositorWnd),
204 reinterpret_cast<WindowsHandle>(aParentWnd))
205 ->Then(
206 layers::CompositorThread(), __func__,
207 [self](const bool& aSuccess) {
208 if (aSuccess && self->mRootLayerTreeID.isSome() &&
209 layers::CompositorThreadHolder::IsActive()) {
210 self->mSetParentCompleted = true;
211 // Schedule composition after ::SetParent() call in parent
212 // process.
213 layers::CompositorBridgeParent::ScheduleForcedComposition(
214 self->mRootLayerTreeID.ref(), wr::RenderReasons::WIDGET);
217 [self](const mozilla::ipc::ResponseRejectReason&) {});
220 void CompositorWidgetParent::SetRootLayerTreeID(
221 const layers::LayersId& aRootLayerTreeId) {
222 mRootLayerTreeID = Some(aRootLayerTreeId);
225 void CompositorWidgetParent::ActorDestroy(ActorDestroyReason aWhy) {}
227 } // namespace widget
228 } // namespace mozilla