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 
6 #include "GtkCompositorWidget.h"
7 
8 #include "mozilla/layers/CompositorThread.h"
9 #include "mozilla/widget/InProcessCompositorWidget.h"
10 #include "mozilla/widget/PlatformWidgetTypes.h"
11 #include "nsWindow.h"
12 
13 #ifdef MOZ_X11
14 #  include "mozilla/X11Util.h"
15 #endif
16 
17 #ifdef MOZ_WAYLAND
18 #  include "mozilla/layers/NativeLayerWayland.h"
19 #endif
20 
21 namespace mozilla {
22 namespace widget {
23 
GtkCompositorWidget(const GtkCompositorWidgetInitData & aInitData,const layers::CompositorOptions & aOptions,nsWindow * aWindow)24 GtkCompositorWidget::GtkCompositorWidget(
25     const GtkCompositorWidgetInitData& aInitData,
26     const layers::CompositorOptions& aOptions, nsWindow* aWindow)
27     : CompositorWidget(aOptions),
28       mWidget(aWindow),
29       mClientSize("GtkCompositorWidget::mClientSize") {
30 #if defined(MOZ_WAYLAND)
31   if (GdkIsWaylandDisplay()) {
32     if (!aWindow) {
33       NS_WARNING("GtkCompositorWidget: We're missing nsWindow!");
34     }
35     mProvider.Initialize(aWindow);
36   }
37 #endif
38 #if defined(MOZ_X11)
39   if (GdkIsX11Display()) {
40     mXWindow = (Window)aInitData.XWindow();
41 
42     // Grab the window's visual and depth
43     XWindowAttributes windowAttrs;
44     if (!XGetWindowAttributes(DefaultXDisplay(), mXWindow, &windowAttrs)) {
45       NS_WARNING("GtkCompositorWidget(): XGetWindowAttributes() failed!");
46     }
47 
48     Visual* visual = windowAttrs.visual;
49     int depth = windowAttrs.depth;
50 
51     // Initialize the window surface provider
52     mProvider.Initialize(mXWindow, visual, depth, aInitData.Shaped());
53   }
54 #endif
55   auto size = mClientSize.Lock();
56   *size = aInitData.InitialClientSize();
57 }
58 
~GtkCompositorWidget()59 GtkCompositorWidget::~GtkCompositorWidget() { mProvider.CleanupResources(); }
60 
StartRemoteDrawing()61 already_AddRefed<gfx::DrawTarget> GtkCompositorWidget::StartRemoteDrawing() {
62   return nullptr;
63 }
EndRemoteDrawing()64 void GtkCompositorWidget::EndRemoteDrawing() {}
65 
66 already_AddRefed<gfx::DrawTarget>
StartRemoteDrawingInRegion(const LayoutDeviceIntRegion & aInvalidRegion,layers::BufferMode * aBufferMode)67 GtkCompositorWidget::StartRemoteDrawingInRegion(
68     const LayoutDeviceIntRegion& aInvalidRegion,
69     layers::BufferMode* aBufferMode) {
70   return mProvider.StartRemoteDrawingInRegion(aInvalidRegion, aBufferMode);
71 }
72 
EndRemoteDrawingInRegion(gfx::DrawTarget * aDrawTarget,const LayoutDeviceIntRegion & aInvalidRegion)73 void GtkCompositorWidget::EndRemoteDrawingInRegion(
74     gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
75   mProvider.EndRemoteDrawingInRegion(aDrawTarget, aInvalidRegion);
76 }
77 
RealWidget()78 nsIWidget* GtkCompositorWidget::RealWidget() { return mWidget; }
79 
NotifyClientSizeChanged(const LayoutDeviceIntSize & aClientSize)80 void GtkCompositorWidget::NotifyClientSizeChanged(
81     const LayoutDeviceIntSize& aClientSize) {
82   auto size = mClientSize.Lock();
83   *size = aClientSize;
84 }
85 
GetClientSize()86 LayoutDeviceIntSize GtkCompositorWidget::GetClientSize() {
87   auto size = mClientSize.Lock();
88   return *size;
89 }
90 
GetWidgetKey()91 uintptr_t GtkCompositorWidget::GetWidgetKey() {
92   return reinterpret_cast<uintptr_t>(mWidget);
93 }
94 
GetEGLNativeWindow()95 EGLNativeWindowType GtkCompositorWidget::GetEGLNativeWindow() {
96   if (mWidget) {
97     return (EGLNativeWindowType)mWidget->GetNativeData(NS_NATIVE_EGL_WINDOW);
98   }
99 #if defined(MOZ_X11)
100   if (mXWindow) {
101     return (EGLNativeWindowType)mXWindow;
102   }
103 #endif
104   return nullptr;
105 }
106 
107 #if defined(MOZ_WAYLAND)
SetEGLNativeWindowSize(const LayoutDeviceIntSize & aEGLWindowSize)108 void GtkCompositorWidget::SetEGLNativeWindowSize(
109     const LayoutDeviceIntSize& aEGLWindowSize) {
110   if (mWidget) {
111     mWidget->SetEGLNativeWindowSize(aEGLWindowSize);
112   }
113 }
114 #endif
115 
GetTransparentRegion()116 LayoutDeviceIntRegion GtkCompositorWidget::GetTransparentRegion() {
117   // We need to clear target buffer alpha values of popup windows as
118   // SW-WR paints with alpha blending (see Bug 1674473).
119   if (!mWidget || mWidget->IsPopup()) {
120     return LayoutDeviceIntRect(LayoutDeviceIntPoint(0, 0), GetClientSize());
121   }
122 
123   // Clear background of titlebar area to render titlebar
124   // transparent corners correctly.
125   return mWidget->GetTitlebarRect();
126 }
127 
128 #ifdef MOZ_WAYLAND
129 RefPtr<mozilla::layers::NativeLayerRoot>
GetNativeLayerRoot()130 GtkCompositorWidget::GetNativeLayerRoot() {
131   if (gfx::gfxVars::UseWebRenderCompositor()) {
132     if (!mNativeLayerRoot) {
133       MOZ_ASSERT(mWidget && mWidget->GetMozContainer());
134       mNativeLayerRoot = NativeLayerRootWayland::CreateForMozContainer(
135           mWidget->GetMozContainer());
136     }
137     return mNativeLayerRoot;
138   }
139   return nullptr;
140 }
141 #endif
142 
143 }  // namespace widget
144 }  // namespace mozilla
145