Commit dc35c8a7 authored by Alexandros Frantzis's avatar Alexandros Frantzis Committed by Alexandre Julliard

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).
parent d0fb8f63
...@@ -266,6 +266,8 @@ static VkResult check_queue_present(const VkPresentInfoKHR *present_info, ...@@ -266,6 +266,8 @@ static VkResult check_queue_present(const VkPresentInfoKHR *present_info,
int client_height = wayland_surface->window.client_rect.bottom - int client_height = wayland_surface->window.client_rect.bottom -
wayland_surface->window.client_rect.top; wayland_surface->window.client_rect.top;
wayland_surface_ensure_contents(wayland_surface);
pthread_mutex_unlock(&wayland_surface->mutex); pthread_mutex_unlock(&wayland_surface->mutex);
if (client_width == wine_vk_swapchain->extent.width && if (client_width == wine_vk_swapchain->extent.width &&
......
...@@ -293,6 +293,9 @@ void wayland_surface_clear_role(struct wayland_surface *surface) ...@@ -293,6 +293,9 @@ void wayland_surface_clear_role(struct wayland_surface *surface)
wl_surface_attach(surface->wl_surface, NULL, 0, 0); wl_surface_attach(surface->wl_surface, NULL, 0, 0);
wl_surface_commit(surface->wl_surface); wl_surface_commit(surface->wl_surface);
surface->buffer_width = 0;
surface->buffer_height = 0;
wl_display_flush(process_wayland.wl_display); wl_display_flush(process_wayland.wl_display);
} }
...@@ -336,6 +339,9 @@ void wayland_surface_attach_shm(struct wayland_surface *surface, ...@@ -336,6 +339,9 @@ void wayland_surface_attach_shm(struct wayland_surface *surface,
} }
free(surface_damage); free(surface_damage);
} }
surface->buffer_width = shm_buffer->width;
surface->buffer_height = shm_buffer->height;
} }
/********************************************************************** /**********************************************************************
...@@ -825,3 +831,65 @@ err: ...@@ -825,3 +831,65 @@ err:
} }
return NULL; 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);
}
...@@ -164,6 +164,7 @@ struct wayland_window_config ...@@ -164,6 +164,7 @@ struct wayland_window_config
enum wayland_surface_config_state state; enum wayland_surface_config_state state;
/* The scale (i.e., normalized dpi) the window is rendering at. */ /* The scale (i.e., normalized dpi) the window is rendering at. */
double scale; double scale;
BOOL visible;
}; };
struct wayland_client_surface struct wayland_client_surface
...@@ -187,6 +188,7 @@ struct wayland_surface ...@@ -187,6 +188,7 @@ struct wayland_surface
BOOL resizing; BOOL resizing;
struct wayland_window_config window; struct wayland_window_config window;
struct wayland_client_surface *client; struct wayland_client_surface *client;
int buffer_width, buffer_height;
}; };
struct wayland_shm_buffer struct wayland_shm_buffer
...@@ -240,6 +242,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, ...@@ -240,6 +242,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface,
int *window_x, int *window_y) DECLSPEC_HIDDEN; int *window_x, int *window_y) DECLSPEC_HIDDEN;
struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) 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; 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 * Wayland SHM buffer
......
...@@ -181,6 +181,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data, ...@@ -181,6 +181,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data,
conf->state = window_state; conf->state = window_state;
conf->scale = NtUserGetDpiForWindow(data->hwnd) / 96.0; 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) static void wayland_win_data_update_wayland_surface(struct wayland_win_data *data)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment