commit 913045c3a687b810208fb4e1b010994eaa9d05ef
parent 39c0bbfbfb43cac6d0c017a7d63fa9383f15f1fd
Author: stransky <stransky@redhat.com>
Date: Wed, 5 Nov 2025 11:49:47 +0000
Bug 1998379 [Wayland] Use correct rounding for EGL window size r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D271378
Diffstat:
4 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/widget/gtk/MozContainerWayland.cpp b/widget/gtk/MozContainerWayland.cpp
@@ -295,9 +295,9 @@ struct wl_egl_window* moz_container_wayland_get_egl_window(
// TODO: Get size from bounds instead of GdkWindow?
// We may be in rendering/compositor thread here.
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
- nsIntSize unscaledSize(gdk_window_get_width(window),
- gdk_window_get_height(window));
- return MOZ_WL_SURFACE(container)->GetEGLWindow(unscaledSize);
+ DesktopIntSize size(gdk_window_get_width(window),
+ gdk_window_get_height(window));
+ return MOZ_WL_SURFACE(container)->GetEGLWindow(size);
}
gboolean moz_container_wayland_can_draw(MozContainer* container) {
diff --git a/widget/gtk/WaylandSurface.cpp b/widget/gtk/WaylandSurface.cpp
@@ -1049,7 +1049,7 @@ bool WaylandSurface::RemoveOpaqueSurfaceHandlerLocked(
return true;
}
-wl_egl_window* WaylandSurface::GetEGLWindow(nsIntSize aUnscaledSize) {
+wl_egl_window* WaylandSurface::GetEGLWindow(DesktopIntSize aSize) {
LOGWAYLAND("WaylandSurface::GetEGLWindow() eglwindow %p", (void*)mEGLWindow);
WaylandSurfaceLock lock(this);
@@ -1059,10 +1059,9 @@ wl_egl_window* WaylandSurface::GetEGLWindow(nsIntSize aUnscaledSize) {
return nullptr;
}
- auto scale = GetScale();
- // TODO: Correct size rounding
- nsIntSize scaledSize((int)floor(aUnscaledSize.width * scale),
- (int)floor(aUnscaledSize.height * scale));
+ auto scaledSize = LayoutDeviceIntSize::Round(
+ aSize * DesktopToLayoutDeviceScale(GetScale()));
+
if (!mEGLWindow) {
mEGLWindow =
wl_egl_window_create(mSurface, scaledSize.width, scaledSize.height);
@@ -1076,7 +1075,7 @@ wl_egl_window* WaylandSurface::GetEGLWindow(nsIntSize aUnscaledSize) {
}
if (mEGLWindow) {
- SetSizeLocked(lock, scaledSize, aUnscaledSize);
+ SetSizeLocked(lock, scaledSize.ToUnknownSize(), aSize.ToUnknownSize());
}
return mEGLWindow;
@@ -1084,7 +1083,7 @@ wl_egl_window* WaylandSurface::GetEGLWindow(nsIntSize aUnscaledSize) {
// Return false if scale factor doesn't match buffer size.
// We need to skip painting in such case do avoid Wayland compositor freaking.
-bool WaylandSurface::SetEGLWindowSize(nsIntSize aScaledSize) {
+bool WaylandSurface::SetEGLWindowSize(LayoutDeviceIntSize aSize) {
WaylandSurfaceLock lock(this);
// We may be called after unmap so we're missing egl window completelly.
@@ -1095,19 +1094,17 @@ bool WaylandSurface::SetEGLWindowSize(nsIntSize aScaledSize) {
return true;
}
- auto scale = GetScale();
- // TODO: Avoid precision lost here? Load coordinates from window?
- nsIntSize unscaledSize((int)round(aScaledSize.width / scale),
- (int)round(aScaledSize.height / scale));
+ auto unscaledSize =
+ DesktopIntSize::Round(aSize / DesktopToLayoutDeviceScale(GetScale()));
LOGVERBOSE(
"WaylandSurface::SetEGLWindowSize() scaled [%d x %d] unscaled [%d x %d] "
"scale %f",
- aScaledSize.width, aScaledSize.height, unscaledSize.width,
- unscaledSize.height, scale);
+ aSize.width, aSize.height, unscaledSize.width, unscaledSize.height,
+ GetScale());
- wl_egl_window_resize(mEGLWindow, aScaledSize.width, aScaledSize.height, 0, 0);
- SetSizeLocked(lock, aScaledSize, unscaledSize);
+ wl_egl_window_resize(mEGLWindow, aSize.width, aSize.height, 0, 0);
+ SetSizeLocked(lock, aSize.ToUnknownSize(), unscaledSize.ToUnknownSize());
return true;
}
diff --git a/widget/gtk/WaylandSurface.h b/widget/gtk/WaylandSurface.h
@@ -72,13 +72,10 @@ class WaylandSurface final {
const WaylandSurfaceLock& aProofOfLock,
const std::function<void(bool)>& aFrameCallbackStateHandler);
- // Create and resize EGL window.
- // GetEGLWindow() takes unscaled window size as we derive size from GdkWindow.
- // It's scaled internally by WaylandSurface fractional scale.
- wl_egl_window* GetEGLWindow(nsIntSize aUnscaledSize);
- // SetEGLWindowSize() takes scaled size - it's called from rendering code
- // which uses scaled sizes.
- bool SetEGLWindowSize(nsIntSize aScaledSize);
+ // Create and resize EGL window (Gdk coordinates).
+ wl_egl_window* GetEGLWindow(DesktopIntSize aSize);
+ // Resize EGL window (pixel coordinates).
+ bool SetEGLWindowSize(LayoutDeviceIntSize aSize);
bool HasEGLWindow() const { return !!mEGLWindow; }
// Read to draw means we got frame callback from parent surface
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
@@ -9978,7 +9978,7 @@ bool nsWindow::SetEGLNativeWindowSize(
}
}
# endif
- return mSurface->SetEGLWindowSize(aEGLWindowSize.ToUnknownSize());
+ return mSurface->SetEGLWindowSize(aEGLWindowSize);
}
#endif