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"
15 # include "mozilla/StaticPrefs_widget.h"
16 # include "WindowSurfaceWaylandMultiBuffer.h"
19 # include "mozilla/X11Util.h"
20 # include "WindowSurfaceX11Image.h"
21 # include "WindowSurfaceX11SHM.h"
26 # include "mozilla/Logging.h"
27 # include "nsTArray.h"
29 extern mozilla::LazyLogModule gWidgetLog
;
30 # define LOG(args) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, args)
33 #endif /* MOZ_LOGGING */
38 using namespace mozilla::layers
;
40 WindowSurfaceProvider::WindowSurfaceProvider()
41 : mWindowSurface(nullptr),
42 mMutex("WindowSurfaceProvider"),
43 mWindowSurfaceValid(false)
59 void WindowSurfaceProvider::Initialize(RefPtr
<nsWindow
> aWidget
) {
60 mWindowSurfaceValid
= false;
61 mWidget
= std::move(aWidget
);
65 void WindowSurfaceProvider::Initialize(Window aWindow
, Visual
* aVisual
,
66 int aDepth
, bool aIsShaped
) {
67 mWindowSurfaceValid
= false;
71 mIsShaped
= aIsShaped
;
75 void WindowSurfaceProvider::CleanupResources() {
76 MutexAutoLock
lock(mMutex
);
77 mWindowSurfaceValid
= false;
89 RefPtr
<WindowSurface
> WindowSurfaceProvider::CreateWindowSurface() {
91 if (GdkIsWaylandDisplay()) {
92 // We're called too early or we're unmapped.
96 return MakeRefPtr
<WindowSurfaceWaylandMB
>(mWidget
);
100 if (GdkIsX11Display()) {
101 // We're called too early or we're unmapped.
105 // Blit to the window with the following priority:
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
,
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
);
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()) {
132 MutexAutoLock
lock(mMutex
);
134 if (!mWindowSurfaceValid
) {
135 mWindowSurface
= nullptr;
136 mWindowSurfaceValid
= true;
139 if (!mWindowSurface
) {
140 mWindowSurface
= CreateWindowSurface();
141 if (!mWindowSurface
) {
146 *aBufferMode
= BufferMode::BUFFER_NONE
;
147 RefPtr
<gfx::DrawTarget
> dt
= mWindowSurface
->Lock(aInvalidRegion
);
149 if (!dt
&& GdkIsX11Display() && !mWindowSurface
->IsFallback()) {
150 // We can't use WindowSurfaceX11Image fallback on Wayland but
151 // Lock() call on WindowSurfaceWayland should never fail.
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
);
162 void WindowSurfaceProvider::EndRemoteDrawingInRegion(
163 gfx::DrawTarget
* aDrawTarget
, const LayoutDeviceIntRegion
& aInvalidRegion
) {
164 MutexAutoLock
lock(mMutex
);
165 // Commit to mWindowSurface only when we have a valid one.
166 if (mWindowSurface
&& mWindowSurfaceValid
) {
167 mWindowSurface
->Commit(aInvalidRegion
);
171 } // namespace widget
172 } // namespace mozilla