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)
57 void WindowSurfaceProvider::Initialize(RefPtr
<nsWindow
> aWidget
) {
58 mWidget
= std::move(aWidget
);
62 void WindowSurfaceProvider::Initialize(Window aWindow
, Visual
* aVisual
,
63 int aDepth
, bool aIsShaped
) {
67 mIsShaped
= aIsShaped
;
71 void WindowSurfaceProvider::CleanupResources() { mWindowSurface
= nullptr; }
73 RefPtr
<WindowSurface
> WindowSurfaceProvider::CreateWindowSurface() {
75 if (GdkIsWaylandDisplay()) {
76 return MakeRefPtr
<WindowSurfaceWaylandMB
>(mWidget
);
80 if (GdkIsX11Display()) {
81 // Blit to the window with the following priority:
84 # ifdef MOZ_HAVE_SHMIMAGE
85 if (!mIsShaped
&& nsShmImage::UseShm()) {
86 LOG(("Drawing to Window 0x%lx will use MIT-SHM\n", mXWindow
));
87 return MakeRefPtr
<WindowSurfaceX11SHM
>(DefaultXDisplay(), mXWindow
,
90 # endif // MOZ_HAVE_SHMIMAGE
92 LOG(("Drawing to Window 0x%lx will use XPutImage\n", mXWindow
));
93 return MakeRefPtr
<WindowSurfaceX11Image
>(DefaultXDisplay(), mXWindow
,
94 mXVisual
, mXDepth
, mIsShaped
);
97 MOZ_RELEASE_ASSERT(false);
100 already_AddRefed
<gfx::DrawTarget
>
101 WindowSurfaceProvider::StartRemoteDrawingInRegion(
102 const LayoutDeviceIntRegion
& aInvalidRegion
,
103 layers::BufferMode
* aBufferMode
) {
104 if (aInvalidRegion
.IsEmpty()) return nullptr;
106 if (!mWindowSurface
) {
107 mWindowSurface
= CreateWindowSurface();
108 if (!mWindowSurface
) return nullptr;
111 *aBufferMode
= BufferMode::BUFFER_NONE
;
112 RefPtr
<gfx::DrawTarget
> dt
= mWindowSurface
->Lock(aInvalidRegion
);
114 if (!dt
&& GdkIsX11Display() && !mWindowSurface
->IsFallback()) {
115 // We can't use WindowSurfaceX11Image fallback on Wayland but
116 // Lock() call on WindowSurfaceWayland should never fail.
118 << "Failed to lock WindowSurface, falling back to XPutImage backend.";
119 mWindowSurface
= MakeRefPtr
<WindowSurfaceX11Image
>(
120 DefaultXDisplay(), mXWindow
, mXVisual
, mXDepth
, mIsShaped
);
121 dt
= mWindowSurface
->Lock(aInvalidRegion
);
127 void WindowSurfaceProvider::EndRemoteDrawingInRegion(
128 gfx::DrawTarget
* aDrawTarget
, const LayoutDeviceIntRegion
& aInvalidRegion
) {
129 if (mWindowSurface
) mWindowSurface
->Commit(aInvalidRegion
);
132 } // namespace widget
133 } // namespace mozilla