Bug 1777562 [wpt PR 34663] - [FedCM] Rename FederatedCredential to IdentityCredential...
[gecko.git] / widget / gtk / WindowSurfaceProvider.cpp
blob82d6ba3caacb010f8f6e04f04ca7ed873a64bbf3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "WindowSurfaceProvider.h"
9 #include "gfxPlatformGtk.h"
10 #include "mozilla/gfx/Logging.h"
11 #include "mozilla/layers/LayersTypes.h"
12 #include "nsWindow.h"
14 #ifdef MOZ_WAYLAND
15 # include "mozilla/StaticPrefs_widget.h"
16 # include "WindowSurfaceWaylandMultiBuffer.h"
17 #endif
18 #ifdef MOZ_X11
19 # include "mozilla/X11Util.h"
20 # include "WindowSurfaceX11Image.h"
21 # include "WindowSurfaceX11SHM.h"
22 #endif
24 #undef LOG
25 #ifdef MOZ_LOGGING
26 # include "mozilla/Logging.h"
27 # include "nsTArray.h"
28 # include "Units.h"
29 extern mozilla::LazyLogModule gWidgetLog;
30 # define LOG(args) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, args)
31 #else
32 # define LOG(args)
33 #endif /* MOZ_LOGGING */
35 namespace mozilla {
36 namespace widget {
38 using namespace mozilla::layers;
40 WindowSurfaceProvider::WindowSurfaceProvider()
41 : mWindowSurface(nullptr),
42 mMutex("WindowSurfaceProvider"),
43 mWindowSurfaceValid(false)
44 #ifdef MOZ_WAYLAND
46 mWidget(nullptr)
47 #endif
48 #ifdef MOZ_X11
50 mIsShaped(false),
51 mXDepth(0),
52 mXWindow(0),
53 mXVisual(nullptr)
54 #endif
58 #ifdef MOZ_WAYLAND
59 void WindowSurfaceProvider::Initialize(RefPtr<nsWindow> aWidget) {
60 mWindowSurfaceValid = false;
61 mWidget = std::move(aWidget);
63 #endif
64 #ifdef MOZ_X11
65 void WindowSurfaceProvider::Initialize(Window aWindow, Visual* aVisual,
66 int aDepth, bool aIsShaped) {
67 mWindowSurfaceValid = false;
68 mXWindow = aWindow;
69 mXVisual = aVisual;
70 mXDepth = aDepth;
71 mIsShaped = aIsShaped;
73 #endif
75 void WindowSurfaceProvider::CleanupResources() {
76 MutexAutoLock lock(mMutex);
77 mWindowSurfaceValid = false;
78 #ifdef MOZ_WAYLAND
79 mWidget = nullptr;
80 #endif
81 #ifdef MOZ_X11
82 mXWindow = 0;
83 mXVisual = 0;
84 mXDepth = 0;
85 mIsShaped = false;
86 #endif
89 RefPtr<WindowSurface> WindowSurfaceProvider::CreateWindowSurface() {
90 #ifdef MOZ_WAYLAND
91 if (GdkIsWaylandDisplay()) {
92 // We're called too early or we're unmapped.
93 if (!mWidget) {
94 return nullptr;
96 return MakeRefPtr<WindowSurfaceWaylandMB>(mWidget);
98 #endif
99 #ifdef MOZ_X11
100 if (GdkIsX11Display()) {
101 // We're called too early or we're unmapped.
102 if (!mXWindow) {
103 return nullptr;
105 // Blit to the window with the following priority:
106 // 1. MIT-SHM
107 // 2. XPutImage
108 # ifdef MOZ_HAVE_SHMIMAGE
109 if (!mIsShaped && nsShmImage::UseShm()) {
110 LOG(("Drawing to Window 0x%lx will use MIT-SHM\n", mXWindow));
111 return MakeRefPtr<WindowSurfaceX11SHM>(DefaultXDisplay(), mXWindow,
112 mXVisual, mXDepth);
114 # endif // MOZ_HAVE_SHMIMAGE
116 LOG(("Drawing to Window 0x%lx will use XPutImage\n", mXWindow));
117 return MakeRefPtr<WindowSurfaceX11Image>(DefaultXDisplay(), mXWindow,
118 mXVisual, mXDepth, mIsShaped);
120 #endif
121 MOZ_RELEASE_ASSERT(false);
124 already_AddRefed<gfx::DrawTarget>
125 WindowSurfaceProvider::StartRemoteDrawingInRegion(
126 const LayoutDeviceIntRegion& aInvalidRegion,
127 layers::BufferMode* aBufferMode) {
128 if (aInvalidRegion.IsEmpty()) {
129 return nullptr;
132 MutexAutoLock lock(mMutex);
134 if (!mWindowSurfaceValid) {
135 mWindowSurface = nullptr;
136 mWindowSurfaceValid = true;
139 if (!mWindowSurface) {
140 mWindowSurface = CreateWindowSurface();
141 if (!mWindowSurface) {
142 return nullptr;
146 *aBufferMode = BufferMode::BUFFER_NONE;
147 RefPtr<gfx::DrawTarget> dt = mWindowSurface->Lock(aInvalidRegion);
148 #ifdef MOZ_X11
149 if (!dt && GdkIsX11Display() && !mWindowSurface->IsFallback()) {
150 // We can't use WindowSurfaceX11Image fallback on Wayland but
151 // Lock() call on WindowSurfaceWayland should never fail.
152 gfxWarningOnce()
153 << "Failed to lock WindowSurface, falling back to XPutImage backend.";
154 mWindowSurface = MakeRefPtr<WindowSurfaceX11Image>(
155 DefaultXDisplay(), mXWindow, mXVisual, mXDepth, mIsShaped);
156 dt = mWindowSurface->Lock(aInvalidRegion);
158 #endif
159 return dt.forget();
162 void WindowSurfaceProvider::EndRemoteDrawingInRegion(
163 gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
164 MutexAutoLock lock(mMutex);
165 // Commit to mWindowSurface only if we have a valid one.
166 if (!mWindowSurface || !mWindowSurfaceValid) {
167 return;
169 #if defined(MOZ_WAYLAND)
170 if (GdkIsWaylandDisplay()) {
171 // We're called too early or we're unmapped.
172 // Don't draw anything.
173 if (!mWidget) {
174 return;
176 if (moz_container_wayland_is_commiting_to_parent(
177 mWidget->GetMozContainer())) {
178 // If we're drawing directly to wl_surface owned by Gtk we need to use it
179 // in main thread to sync with Gtk access to it.
180 NS_DispatchToMainThread(NS_NewRunnableFunction(
181 "WindowSurfaceProvider::EndRemoteDrawingInRegion",
182 [RefPtr{mWidget}, this, aInvalidRegion]() {
183 MutexAutoLock lock(mMutex);
184 // Commit to mWindowSurface only when we have a valid one.
185 if (mWindowSurface && mWindowSurfaceValid) {
186 mWindowSurface->Commit(aInvalidRegion);
188 }));
189 return;
192 #endif
193 mWindowSurface->Commit(aInvalidRegion);
196 } // namespace widget
197 } // namespace mozilla