/* -*- 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/. */
#ifdef MOZ_WAYLAND # include "mozilla/StaticPrefs_widget.h" # include "WindowSurfaceWaylandMultiBuffer.h" #endif #ifdef MOZ_X11 # include "mozilla/X11Util.h" # include "WindowSurfaceX11Image.h" # include "WindowSurfaceX11SHM.h" #endif
#undef LOG #ifdef MOZ_LOGGING # include "mozilla/Logging.h" # include "nsTArray.h" # include "Units.h" extern mozilla::LazyLogModule gWidgetLog; # define LOG(args) MOZ_LOG(gWidgetLog, mozilla::LogLevel::Debug, args) #else # define LOG(args) #endif/* MOZ_LOGGING */
WindowSurfaceProvider::~WindowSurfaceProvider() { #ifdef MOZ_WAYLAND
MOZ_DIAGNOSTIC_ASSERT(!mWidget, "nsWindow reference is still live, we're leaking it!"); #endif #ifdef MOZ_X11
MOZ_DIAGNOSTIC_ASSERT(!mXWindow, "mXWindow should be released on quit!"); #endif
}
RefPtr<WindowSurface> WindowSurfaceProvider::CreateWindowSurface() { #ifdef MOZ_WAYLAND if (GdkIsWaylandDisplay()) { // We're called too early or we're unmapped. if (!mWidget) { return nullptr;
} return MakeRefPtr<WindowSurfaceWaylandMB>(mWidget, mCompositorWidget);
} #endif #ifdef MOZ_X11 if (GdkIsX11Display()) { // We're called too early or we're unmapped. if (!mXWindow) { return nullptr;
} // Blit to the window with the following priority: // 1. MIT-SHM // 2. XPutImage # ifdef MOZ_HAVE_SHMIMAGE if (nsShmImage::UseShm()) {
LOG(("Drawing to Window 0x%lx will use MIT-SHM\n", (Window)mXWindow)); return MakeRefPtr<WindowSurfaceX11SHM>(DefaultXDisplay(), mXWindow,
mXVisual, mXDepth);
} # endif // MOZ_HAVE_SHMIMAGE
LOG(("Drawing to Window 0x%lx will use XPutImage\n", (Window)mXWindow)); return MakeRefPtr<WindowSurfaceX11Image>(DefaultXDisplay(), mXWindow,
mXVisual, mXDepth);
} #endif
MOZ_RELEASE_ASSERT(false);
}
// We need to ignore thread safety checks here. We need to hold mMutex // between StartRemoteDrawingInRegion()/EndRemoteDrawingInRegion() calls // which confuses it.
MOZ_PUSH_IGNORE_THREAD_SAFETY
// We return a reference to mWindowSurface inside draw target so we need to // hold the mutex untill EndRemoteDrawingInRegion() call where draw target // is returned. // If we return null dt, EndRemoteDrawingInRegion() won't be called to // release mutex.
mMutex.Lock(); auto unlockMutex = MakeScopeExit([&] { mMutex.Unlock(); });
if (!mWindowSurfaceValid) {
mWindowSurface = nullptr;
mWindowSurfaceValid = true;
}
if (!mWindowSurface) {
mWindowSurface = CreateWindowSurface(); if (!mWindowSurface) { return nullptr;
}
}
*aBufferMode = BufferMode::BUFFER_NONE;
RefPtr<gfx::DrawTarget> dt = mWindowSurface->Lock(aInvalidRegion); #ifdef MOZ_X11 if (!dt && GdkIsX11Display() && !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 = MakeRefPtr<WindowSurfaceX11Image>(
DefaultXDisplay(), mXWindow, mXVisual, mXDepth);
dt = mWindowSurface->Lock(aInvalidRegion);
} #endif if (dt) { // We have valid dt, mutex will be released in EndRemoteDrawingInRegion().
unlockMutex.release();
}
// Commit to mWindowSurface only if we have a valid one. if (!mWindowSurface || !mWindowSurfaceValid) { return;
} #ifdefined(MOZ_WAYLAND) if (GdkIsWaylandDisplay()) { // We're called too early or we're unmapped. // Don't draw anything. if (!mWidget || !mWidget->IsMapped()) { return;
} if (moz_container_wayland_is_commiting_to_parent(
mWidget->GetMozContainer())) { // If we're drawing directly to wl_surface owned by Gtk we need to use it // in main thread to sync with Gtk access to it.
NS_DispatchToMainThread(NS_NewRunnableFunction( "WindowSurfaceProvider::EndRemoteDrawingInRegion",
[widget = RefPtr{mWidget}, this, aInvalidRegion]() { if (!widget->IsMapped()) { return;
}
MutexAutoLock lock(mMutex); // Commit to mWindowSurface only when we have a valid one. if (mWindowSurface && mWindowSurfaceValid) {
mWindowSurface->Commit(aInvalidRegion);
}
})); return;
}
} #endif
mWindowSurface->Commit(aInvalidRegion);
}
MOZ_POP_THREAD_SAFETY
} // namespace widget
} // namespace mozilla
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.