summaryrefslogtreecommitdiffstats
path: root/widget/gtk/WindowSurfaceProvider.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/gtk/WindowSurfaceProvider.cpp131
1 files changed, 131 insertions, 0 deletions
diff --git a/widget/gtk/WindowSurfaceProvider.cpp b/widget/gtk/WindowSurfaceProvider.cpp
new file mode 100644
index 0000000000..282847a512
--- /dev/null
+++ b/widget/gtk/WindowSurfaceProvider.cpp
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WindowSurfaceProvider.h"
+
+#include "gfxPlatformGtk.h"
+#include "mozilla/gfx/Logging.h"
+#include "mozilla/layers/LayersTypes.h"
+#include "nsWindow.h"
+#include "WindowSurfaceX11Image.h"
+#include "WindowSurfaceX11SHM.h"
+#include "WindowSurfaceXRender.h"
+#ifdef MOZ_WAYLAND
+# include "WindowSurfaceWayland.h"
+#endif
+
+namespace mozilla {
+namespace widget {
+
+using namespace mozilla::layers;
+
+WindowSurfaceProvider::WindowSurfaceProvider()
+ : mIsX11Display(false),
+ mXDisplay(nullptr),
+ mXWindow(0),
+ mXVisual(nullptr),
+ mXDepth(0),
+ mWindowSurface(nullptr)
+#ifdef MOZ_WAYLAND
+ ,
+ mWidget(nullptr)
+#endif
+ ,
+ mIsShaped(false) {
+}
+
+void WindowSurfaceProvider::Initialize(Display* aDisplay, Window aWindow,
+ Visual* aVisual, int aDepth,
+ bool aIsShaped) {
+ // We should not be initialized
+ MOZ_ASSERT(!mXDisplay);
+
+ // This should also be a valid initialization
+ MOZ_ASSERT(aDisplay && aWindow != X11None && aVisual);
+
+ mXDisplay = aDisplay;
+ mXWindow = aWindow;
+ mXVisual = aVisual;
+ mXDepth = aDepth;
+ mIsShaped = aIsShaped;
+ mIsX11Display = true;
+}
+
+#ifdef MOZ_WAYLAND
+void WindowSurfaceProvider::Initialize(nsWindow* aWidget) {
+ mWidget = aWidget;
+ mIsX11Display = false;
+}
+#endif
+
+void WindowSurfaceProvider::CleanupResources() { mWindowSurface = nullptr; }
+
+UniquePtr<WindowSurface> WindowSurfaceProvider::CreateWindowSurface() {
+#ifdef MOZ_WAYLAND
+ if (!mIsX11Display) {
+ LOGDRAW(("Drawing to nsWindow %p will use wl_surface\n", mWidget));
+ return MakeUnique<WindowSurfaceWayland>(mWidget);
+ }
+#endif
+
+ // We should be initialized
+ MOZ_ASSERT(mXDisplay);
+
+ // Blit to the window with the following priority:
+ // 1. XRender (iff XRender is enabled && we are in-process)
+ // 2. MIT-SHM
+ // 3. XPutImage
+ if (!mIsShaped && gfx::gfxVars::UseXRender()) {
+ LOGDRAW(("Drawing to Window 0x%lx will use XRender\n", mXWindow));
+ return MakeUnique<WindowSurfaceXRender>(mXDisplay, mXWindow, mXVisual,
+ mXDepth);
+ }
+
+#ifdef MOZ_HAVE_SHMIMAGE
+ if (!mIsShaped && nsShmImage::UseShm()) {
+ LOGDRAW(("Drawing to Window 0x%lx will use MIT-SHM\n", mXWindow));
+ return MakeUnique<WindowSurfaceX11SHM>(mXDisplay, mXWindow, mXVisual,
+ mXDepth);
+ }
+#endif // MOZ_HAVE_SHMIMAGE
+
+ LOGDRAW(("Drawing to Window 0x%lx will use XPutImage\n", mXWindow));
+ return MakeUnique<WindowSurfaceX11Image>(mXDisplay, mXWindow, mXVisual,
+ mXDepth, mIsShaped);
+}
+
+already_AddRefed<gfx::DrawTarget>
+WindowSurfaceProvider::StartRemoteDrawingInRegion(
+ LayoutDeviceIntRegion& aInvalidRegion, layers::BufferMode* aBufferMode) {
+ if (aInvalidRegion.IsEmpty()) return nullptr;
+
+ if (!mWindowSurface) {
+ mWindowSurface = CreateWindowSurface();
+ if (!mWindowSurface) return nullptr;
+ }
+
+ *aBufferMode = BufferMode::BUFFER_NONE;
+ RefPtr<gfx::DrawTarget> dt = nullptr;
+ if (!(dt = mWindowSurface->Lock(aInvalidRegion)) && mIsX11Display &&
+ !mWindowSurface->IsFallback()) {
+ // We can't use WindowSurfaceX11Image fallback on Wayland but
+ // Lock() call on WindowSurfaceWayland should never fail.
+ gfxWarningOnce()
+ << "Failed to lock WindowSurface, falling back to XPutImage backend.";
+ mWindowSurface = MakeUnique<WindowSurfaceX11Image>(
+ mXDisplay, mXWindow, mXVisual, mXDepth, mIsShaped);
+ dt = mWindowSurface->Lock(aInvalidRegion);
+ }
+ return dt.forget();
+}
+
+void WindowSurfaceProvider::EndRemoteDrawingInRegion(
+ gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
+ if (mWindowSurface) mWindowSurface->Commit(aInvalidRegion);
+}
+
+} // namespace widget
+} // namespace mozilla