-- v3: winewayland: Avoid recreating window surface buffer queues. winewayland: Create the window surface buffer queue unconditionally. winewayland: Set the window viewport source rectangle.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_surface.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index a2699d66e51..bf65edd77fb 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -351,6 +351,24 @@ void wayland_surface_attach_shm(struct wayland_surface *surface,
surface->buffer_width = shm_buffer->width; surface->buffer_height = shm_buffer->height; + + if (surface->wp_viewport) + { + int win_width, win_height, width, height; + + win_width = surface->window.rect.right - surface->window.rect.left; + win_height = surface->window.rect.bottom - surface->window.rect.top; + + /* It is an error to specify a wp_viewporter source rectangle that + * is partially or completely outside of the wl_buffer. */ + width = min(win_width, surface->buffer_width); + height = min(win_height, surface->buffer_height); + + if (width != 0 && height != 0) + wp_viewport_set_source(surface->wp_viewport, 0, 0, width << 8, height << 8); + else + wp_viewport_set_source(surface->wp_viewport, -1, -1, -1, -1); + } }
/**********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/window_surface.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 570c186861b..ddd4fb45976 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -329,10 +329,9 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, HRGN surface_damage_region = NULL; HRGN copy_from_window_region;
- if (!wws->wayland_surface || !wws->wayland_buffer_queue) + if (!wws->wayland_surface) { - ERR("missing wayland surface=%p or buffer_queue=%p, returning\n", - wws->wayland_surface, wws->wayland_buffer_queue); + ERR("missing wayland surface=%p, returning\n", wws->wayland_surface); goto done; }
@@ -423,8 +422,7 @@ static void wayland_window_surface_destroy(struct window_surface *window_surface
TRACE("surface=%p\n", wws);
- if (wws->wayland_buffer_queue) - wayland_buffer_queue_destroy(wws->wayland_buffer_queue); + wayland_buffer_queue_destroy(wws->wayland_buffer_queue); }
static const struct window_surface_funcs wayland_window_surface_funcs = @@ -444,6 +442,7 @@ static struct window_surface *wayland_window_surface_create(HWND hwnd, const REC struct wayland_window_surface *wws; int width = rect->right - rect->left; int height = rect->bottom - rect->top; + struct window_surface *window_surface;
TRACE("hwnd %p rect %s\n", hwnd, wine_dbgstr_rect(rect));
@@ -456,7 +455,13 @@ static struct window_surface *wayland_window_surface_create(HWND hwnd, const REC info->bmiHeader.biSizeImage = width * height * 4; info->bmiHeader.biCompression = BI_RGB;
- return window_surface_create(sizeof(*wws), &wayland_window_surface_funcs, hwnd, rect, info, 0); + if ((window_surface = window_surface_create(sizeof(*wws), &wayland_window_surface_funcs, hwnd, rect, info, 0))) + { + struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); + wws->wayland_buffer_queue = wayland_buffer_queue_create(width, height); + } + + return window_surface; }
/***********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/window_surface.c | 15 --------------- 1 file changed, 15 deletions(-)
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index ddd4fb45976..7e4ea202e89 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -482,21 +482,6 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window wine_dbgstr_rect(visible_rect), wayland_surface);
wws->wayland_surface = wayland_surface; - - if (wws->wayland_buffer_queue) - { - wayland_buffer_queue_destroy(wws->wayland_buffer_queue); - wws->wayland_buffer_queue = NULL; - } - - /* We only need a buffer queue if we have a surface to commit to. */ - if (wws->wayland_surface) - { - wws->wayland_buffer_queue = - wayland_buffer_queue_create(visible_rect->right - visible_rect->left, - visible_rect->bottom - visible_rect->top); - } - window_surface_unlock(window_surface); }
v3: Avoid converting coordinates to surface coordinates, the wp_viewporter_set_source are supposed to be in buffer coordinates instead, which should match the window rect (it actually should be the visible rect, but the surface window config doesn't carry it for the moment).
Alexandros Frantzis (@afrantzis) commented about dlls/winewayland.drv/wayland_surface.c:
surface->buffer_height = shm_buffer->height;
- if (surface->wp_viewport)
- {
int win_width, win_height, width, height;
win_width = surface->window.rect.right - surface->window.rect.left;
win_height = surface->window.rect.bottom - surface->window.rect.top;
/* It is an error to specify a wp_viewporter source rectangle that
* is partially or completely outside of the wl_buffer. */
width = min(win_width, surface->buffer_width);
height = min(win_height, surface->buffer_height);
if (width != 0 && height != 0)
wp_viewport_set_source(surface->wp_viewport, 0, 0, width << 8, height << 8);
`wl_fixed_from_int()`?
Thanks, I have some more proposed changes/fixes at https://gitlab.winehq.org/afrantzis/wine/-/commits/wip/wayland-buffer-queue .
This MR effectively makes `wp_viewport` a requirement for the Wayland driver, even for non-scaled scenarios, so I would say let's check for it at startup like we do with other protocols and remove further runtime checks (can be done in a follow-up MR).