Bug 1861709 replace AudioCallbackDriver::ThreadRunning() assertions that mean to...
[gecko.git] / widget / windows / CompositorWidgetParent.cpp
blobb25d30d9d5460c8316a4f912b00adf55da0d67c1
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::CompositorWidgetParent::GetWindowSizeMode()
153 const {
154 nsSizeMode sizeMode = mSizeMode;
155 return sizeMode;
158 bool CompositorWidgetParent::CompositorWidgetParent::GetWindowIsFullyOccluded()
159 const {
160 bool isFullyOccluded = mIsFullyOccluded;
161 return isFullyOccluded;
164 mozilla::ipc::IPCResult CompositorWidgetParent::RecvClearTransparentWindow() {
165 gfx::CriticalSectionAutoEnter lock(&mPresentLock);
167 RefPtr<DrawTarget> drawTarget = mRemoteBackbufferClient->BorrowDrawTarget();
168 if (!drawTarget) {
169 return IPC_OK();
172 IntSize size = drawTarget->GetSize();
173 if (size.IsEmpty()) {
174 return IPC_OK();
177 drawTarget->ClearRect(Rect(0, 0, size.width, size.height));
179 Unused << mRemoteBackbufferClient->PresentDrawTarget(
180 IntRect(0, 0, size.width, size.height));
182 return IPC_OK();
185 nsIWidget* CompositorWidgetParent::RealWidget() { return nullptr; }
187 void CompositorWidgetParent::ObserveVsync(VsyncObserver* aObserver) {
188 if (aObserver) {
189 Unused << SendObserveVsync();
190 } else {
191 Unused << SendUnobserveVsync();
193 mVsyncObserver = aObserver;
196 RefPtr<VsyncObserver> CompositorWidgetParent::GetVsyncObserver() const {
197 MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
198 return mVsyncObserver;
201 void CompositorWidgetParent::UpdateCompositorWnd(const HWND aCompositorWnd,
202 const HWND aParentWnd) {
203 MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread());
204 MOZ_ASSERT(mRootLayerTreeID.isSome());
206 RefPtr<CompositorWidgetParent> self = this;
207 SendUpdateCompositorWnd(reinterpret_cast<WindowsHandle>(aCompositorWnd),
208 reinterpret_cast<WindowsHandle>(aParentWnd))
209 ->Then(
210 layers::CompositorThread(), __func__,
211 [self](const bool& aSuccess) {
212 if (aSuccess && self->mRootLayerTreeID.isSome() &&
213 layers::CompositorThreadHolder::IsActive()) {
214 self->mSetParentCompleted = true;
215 // Schedule composition after ::SetParent() call in parent
216 // process.
217 layers::CompositorBridgeParent::ScheduleForcedComposition(
218 self->mRootLayerTreeID.ref(), wr::RenderReasons::WIDGET);
221 [self](const mozilla::ipc::ResponseRejectReason&) {});
224 void CompositorWidgetParent::SetRootLayerTreeID(
225 const layers::LayersId& aRootLayerTreeId) {
226 mRootLayerTreeID = Some(aRootLayerTreeId);
229 void CompositorWidgetParent::ActorDestroy(ActorDestroyReason aWhy) {}
231 } // namespace widget
232 } // namespace mozilla