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 "GtkCompositorWidget.h"
8 #include "mozilla/gfx/gfxVars.h"
9 #include "mozilla/layers/CompositorThread.h"
10 #include "mozilla/widget/InProcessCompositorWidget.h"
11 #include "mozilla/widget/PlatformWidgetTypes.h"
15 # include "mozilla/X11Util.h"
19 # include "mozilla/layers/NativeLayerWayland.h"
24 # define LOG(str, ...) \
25 MOZ_LOG(IsPopup() ? gWidgetPopupLog : gWidgetLog, \
26 mozilla::LogLevel::Debug, \
27 ("[%p]: " str, mWidget.get(), ##__VA_ARGS__))
28 #endif /* MOZ_LOGGING */
33 GtkCompositorWidget::GtkCompositorWidget(
34 const GtkCompositorWidgetInitData
& aInitData
,
35 const layers::CompositorOptions
& aOptions
, RefPtr
<nsWindow
> aWindow
)
36 : CompositorWidget(aOptions
),
37 mWidget(std::move(aWindow
)),
38 mClientSize(LayoutDeviceIntSize(aInitData
.InitialClientSize()),
39 "GtkCompositorWidget::mClientSize") {
41 if (GdkIsX11Display()) {
42 mXWindow
= (Window
)aInitData
.XWindow();
43 ConfigureX11Backend(mXWindow
, aInitData
.Shaped());
44 LOG("GtkCompositorWidget::GtkCompositorWidget() [%p] mXWindow %p "
45 "mIsRenderingSuspended %d\n",
46 (void*)mWidget
.get(), (void*)mXWindow
, !!mIsRenderingSuspended
);
49 #if defined(MOZ_WAYLAND)
50 if (GdkIsWaylandDisplay()) {
51 ConfigureWaylandBackend();
52 LOG("GtkCompositorWidget::GtkCompositorWidget() [%p] mWidget %p "
53 "mIsRenderingSuspended %d\n",
54 (void*)mWidget
.get(), (void*)mWidget
, !!mIsRenderingSuspended
);
59 GtkCompositorWidget::~GtkCompositorWidget() {
60 LOG("GtkCompositorWidget::~GtkCompositorWidget [%p]\n", (void*)mWidget
.get());
62 RefPtr
<nsIWidget
> widget
= mWidget
.forget();
63 NS_ReleaseOnMainThread("GtkCompositorWidget::mWidget", widget
.forget());
66 already_AddRefed
<gfx::DrawTarget
> GtkCompositorWidget::StartRemoteDrawing() {
69 void GtkCompositorWidget::EndRemoteDrawing() {}
71 already_AddRefed
<gfx::DrawTarget
>
72 GtkCompositorWidget::StartRemoteDrawingInRegion(
73 const LayoutDeviceIntRegion
& aInvalidRegion
,
74 layers::BufferMode
* aBufferMode
) {
75 return mProvider
.StartRemoteDrawingInRegion(aInvalidRegion
, aBufferMode
);
78 void GtkCompositorWidget::EndRemoteDrawingInRegion(
79 gfx::DrawTarget
* aDrawTarget
, const LayoutDeviceIntRegion
& aInvalidRegion
) {
80 mProvider
.EndRemoteDrawingInRegion(aDrawTarget
, aInvalidRegion
);
83 nsIWidget
* GtkCompositorWidget::RealWidget() { return mWidget
; }
85 void GtkCompositorWidget::NotifyClientSizeChanged(
86 const LayoutDeviceIntSize
& aClientSize
) {
87 LOG("GtkCompositorWidget::NotifyClientSizeChanged() to %d x %d",
88 aClientSize
.width
, aClientSize
.height
);
90 auto size
= mClientSize
.Lock();
94 LayoutDeviceIntSize
GtkCompositorWidget::GetClientSize() {
95 auto size
= mClientSize
.Lock();
99 void GtkCompositorWidget::RemoteLayoutSizeUpdated(
100 const LayoutDeviceRect
& aSize
) {
101 if (!mWidget
|| !mWidget
->IsWaitingForCompositorResume()) {
105 LOG("GtkCompositorWidget::RemoteLayoutSizeUpdated() %d x %d",
106 (int)aSize
.width
, (int)aSize
.height
);
108 // We're waiting for layout to match widget size.
109 auto clientSize
= mClientSize
.Lock();
110 if (clientSize
->width
!= (int)aSize
.width
||
111 clientSize
->height
!= (int)aSize
.height
) {
112 LOG("quit, client size doesn't match (%d x %d)", clientSize
->width
,
117 mWidget
->ResumeCompositorFromCompositorThread();
120 EGLNativeWindowType
GtkCompositorWidget::GetEGLNativeWindow() {
121 EGLNativeWindowType window
= nullptr;
123 window
= (EGLNativeWindowType
)mWidget
->GetNativeData(NS_NATIVE_EGL_WINDOW
);
127 window
= (EGLNativeWindowType
)mXWindow
;
130 LOG("GtkCompositorWidget::GetEGLNativeWindow [%p] window %p\n", mWidget
.get(),
135 bool GtkCompositorWidget::SetEGLNativeWindowSize(
136 const LayoutDeviceIntSize
& aEGLWindowSize
) {
137 #if defined(MOZ_WAYLAND)
139 return mWidget
->SetEGLNativeWindowSize(aEGLWindowSize
);
145 LayoutDeviceIntRegion
GtkCompositorWidget::GetTransparentRegion() {
146 // We need to clear target buffer alpha values of popup windows as
147 // SW-WR paints with alpha blending (see Bug 1674473).
148 if (!mWidget
|| mWidget
->IsPopup()) {
149 return LayoutDeviceIntRect(LayoutDeviceIntPoint(0, 0), GetClientSize());
152 // Clear background of titlebar area to render titlebar
153 // transparent corners correctly.
154 return mWidget
->GetTitlebarRect();
158 RefPtr
<mozilla::layers::NativeLayerRoot
>
159 GtkCompositorWidget::GetNativeLayerRoot() {
160 if (gfx::gfxVars::UseWebRenderCompositor()) {
161 if (!mNativeLayerRoot
) {
162 MOZ_ASSERT(mWidget
&& mWidget
->GetMozContainer());
163 mNativeLayerRoot
= NativeLayerRootWayland::CreateForMozContainer(
164 mWidget
->GetMozContainer());
166 return mNativeLayerRoot
;
172 void GtkCompositorWidget::DisableRendering() {
173 LOG("GtkCompositorWidget::DisableRendering [%p]\n", (void*)mWidget
.get());
174 mIsRenderingSuspended
= true;
175 mProvider
.CleanupResources();
181 #if defined(MOZ_WAYLAND)
182 bool GtkCompositorWidget::ConfigureWaylandBackend() {
183 mProvider
.Initialize(this);
189 bool GtkCompositorWidget::ConfigureX11Backend(Window aXWindow
, bool aShaped
) {
192 // We don't have X window yet.
194 mIsRenderingSuspended
= true;
198 // Grab the window's visual and depth
199 XWindowAttributes windowAttrs
;
200 if (!XGetWindowAttributes(DefaultXDisplay(), mXWindow
, &windowAttrs
)) {
201 NS_WARNING("GtkCompositorWidget(): XGetWindowAttributes() failed!");
205 Visual
* visual
= windowAttrs
.visual
;
206 int depth
= windowAttrs
.depth
;
208 // Initialize the window surface provider
209 mProvider
.Initialize(mXWindow
, visual
, depth
, aShaped
);
214 void GtkCompositorWidget::EnableRendering(const uintptr_t aXWindow
,
215 const bool aShaped
) {
216 LOG("GtkCompositorWidget::EnableRendering() [%p]\n", mWidget
.get());
218 if (!mIsRenderingSuspended
) {
219 LOG(" quit, mIsRenderingSuspended = false\n");
222 #if defined(MOZ_WAYLAND)
223 if (GdkIsWaylandDisplay()) {
224 LOG(" configure widget %p\n", mWidget
.get());
225 if (!ConfigureWaylandBackend()) {
231 if (GdkIsX11Display()) {
232 LOG(" configure XWindow %p shaped %d\n", (void*)aXWindow
, aShaped
);
233 if (!ConfigureX11Backend((Window
)aXWindow
, aShaped
)) {
238 mIsRenderingSuspended
= false;
241 bool GtkCompositorWidget::IsPopup() {
242 return mWidget
? mWidget
->IsPopup() : false;
246 } // namespace widget
247 } // namespace mozilla