1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-08 20:06:18 +00:00

winewayland.drv: Ensure Vulkan parent surface is mapped with proper size.

The client area subsurface (the target of Vulkan rendering) is not going
to be presented properly (or at all) by the compositor if its parent
surface is not mapped or doesn't have the right size, even though the
window may be visible from Wine's perspective. To avoid this issue,
ensure that the parent surface has up-to-date contents in terms of size,
in case these haven't been provided yet, or will never be provided
(e.g., when the Vulkan rendering is fullscreen).
This commit is contained in:
Alexandros Frantzis 2023-11-07 08:15:36 +02:00 committed by Alexandre Julliard
parent d0fb8f637c
commit dc35c8a7b9
4 changed files with 74 additions and 0 deletions

View File

@ -266,6 +266,8 @@ static VkResult check_queue_present(const VkPresentInfoKHR *present_info,
int client_height = wayland_surface->window.client_rect.bottom -
wayland_surface->window.client_rect.top;
wayland_surface_ensure_contents(wayland_surface);
pthread_mutex_unlock(&wayland_surface->mutex);
if (client_width == wine_vk_swapchain->extent.width &&

View File

@ -293,6 +293,9 @@ void wayland_surface_clear_role(struct wayland_surface *surface)
wl_surface_attach(surface->wl_surface, NULL, 0, 0);
wl_surface_commit(surface->wl_surface);
surface->buffer_width = 0;
surface->buffer_height = 0;
wl_display_flush(process_wayland.wl_display);
}
@ -336,6 +339,9 @@ void wayland_surface_attach_shm(struct wayland_surface *surface,
}
free(surface_damage);
}
surface->buffer_width = shm_buffer->width;
surface->buffer_height = shm_buffer->height;
}
/**********************************************************************
@ -825,3 +831,65 @@ err:
}
return NULL;
}
static void dummy_buffer_release(void *data, struct wl_buffer *buffer)
{
struct wayland_shm_buffer *shm_buffer = data;
TRACE("shm_buffer=%p\n", shm_buffer);
wayland_shm_buffer_unref(shm_buffer);
}
static const struct wl_buffer_listener dummy_buffer_listener =
{
dummy_buffer_release
};
/**********************************************************************
* wayland_surface_ensure_contents
*
* Ensure that the wayland surface has up-to-date contents, by committing
* a dummy buffer if necessary.
*/
void wayland_surface_ensure_contents(struct wayland_surface *surface)
{
struct wayland_shm_buffer *dummy_shm_buffer;
HRGN damage;
int width, height;
BOOL needs_contents;
width = surface->window.rect.right - surface->window.rect.left;
height = surface->window.rect.bottom - surface->window.rect.top;
needs_contents = surface->window.visible &&
(surface->buffer_width != width ||
surface->buffer_height != height);
TRACE("surface=%p hwnd=%p needs_contents=%d\n",
surface, surface->hwnd, needs_contents);
if (!needs_contents) return;
/* Create a transparent dummy buffer. */
dummy_shm_buffer = wayland_shm_buffer_create(width, height, WL_SHM_FORMAT_ARGB8888);
if (!dummy_shm_buffer)
{
ERR("Failed to create dummy buffer\n");
return;
}
wl_buffer_add_listener(dummy_shm_buffer->wl_buffer, &dummy_buffer_listener,
dummy_shm_buffer);
if (!(damage = NtGdiCreateRectRgn(0, 0, width, height)))
WARN("Failed to create damage region for dummy buffer\n");
if (wayland_surface_reconfigure(surface))
{
wayland_surface_attach_shm(surface, dummy_shm_buffer, damage);
wl_surface_commit(surface->wl_surface);
}
else
{
wayland_shm_buffer_unref(dummy_shm_buffer);
}
if (damage) NtGdiDeleteObjectApp(damage);
}

View File

@ -164,6 +164,7 @@ struct wayland_window_config
enum wayland_surface_config_state state;
/* The scale (i.e., normalized dpi) the window is rendering at. */
double scale;
BOOL visible;
};
struct wayland_client_surface
@ -187,6 +188,7 @@ struct wayland_surface
BOOL resizing;
struct wayland_window_config window;
struct wayland_client_surface *client;
int buffer_width, buffer_height;
};
struct wayland_shm_buffer
@ -240,6 +242,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface,
int *window_x, int *window_y) DECLSPEC_HIDDEN;
struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) DECLSPEC_HIDDEN;
BOOL wayland_client_surface_release(struct wayland_client_surface *client) DECLSPEC_HIDDEN;
void wayland_surface_ensure_contents(struct wayland_surface *surface) DECLSPEC_HIDDEN;
/**********************************************************************
* Wayland SHM buffer

View File

@ -181,6 +181,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data,
conf->state = window_state;
conf->scale = NtUserGetDpiForWindow(data->hwnd) / 96.0;
conf->visible = (style & WS_VISIBLE) == WS_VISIBLE;
}
static void wayland_win_data_update_wayland_surface(struct wayland_win_data *data)