mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-07 08:28:09 +02:00
renderer-gl: recreate SHM buffers in GPU recovery
Call gl_renderer_attach_shm() to recreate all the SHM buffer states in the new EGL context. This can enable non-GL applications to continue running without crashing during GPU reset and recovery processes, as if no GPU reset had ever occurred. Signed-off-by: Trigger Huang <Trigger.Huang@amd.com>
This commit is contained in:
parent
49732c40c1
commit
9730192811
1 changed files with 78 additions and 2 deletions
|
|
@ -304,6 +304,7 @@ struct gl_buffer_state {
|
|||
struct wl_listener destroy_listener;
|
||||
|
||||
struct wl_list link; /* link to shm_bufs of gl renderer */
|
||||
void *saved_gs; /* gl_surface_state, saved for gb recreation */
|
||||
};
|
||||
|
||||
struct gl_surface_state {
|
||||
|
|
@ -3599,7 +3600,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
* than allocating a new one. */
|
||||
assert(!gs->buffer ||
|
||||
(old_buffer && old_buffer->type == WESTON_BUFFER_SHM));
|
||||
if (gs->buffer &&
|
||||
if (gs->buffer && !gr->recovering &&
|
||||
buffer->width == old_buffer->width &&
|
||||
buffer->height == old_buffer->height &&
|
||||
buffer->pixel_format == old_buffer->pixel_format) {
|
||||
|
|
@ -3614,6 +3615,7 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
|
||||
gb = xzalloc(sizeof(*gb));
|
||||
gb->gr = gr;
|
||||
gb->saved_gs = gs;
|
||||
|
||||
wl_list_init(&gb->destroy_listener.link);
|
||||
wl_list_init(&gb->link);
|
||||
|
|
@ -3641,7 +3643,9 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
false);
|
||||
}
|
||||
|
||||
wl_list_insert(&gr->shm_bufs, &gb->link);
|
||||
/* For recovery, we will manually add the new gb to shm_bufs. */
|
||||
if (!gr->recovering)
|
||||
wl_list_insert(&gr->shm_bufs, &gb->link);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -5168,6 +5172,7 @@ gl_renderer_destroy_context(struct weston_compositor *ec)
|
|||
struct gl_renderer *gr = get_renderer(ec);
|
||||
struct dmabuf_format *format, *next_format;
|
||||
struct gl_capture_task *gl_task, *tmp;
|
||||
struct gl_buffer_state *gb;
|
||||
|
||||
if (gr->display_bound) {
|
||||
gr->unbind_display(gr->egl_display, ec->wl_display);
|
||||
|
|
@ -5199,6 +5204,18 @@ gl_renderer_destroy_context(struct weston_compositor *ec)
|
|||
ec->dmabuf_feedback_format_table = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the GL textures of the SHM buffer as they are invalid in the
|
||||
* new context. gl_renderer_attach_shm() will be called after recovery
|
||||
* to recreate all the SHM buffer states.
|
||||
*/
|
||||
if (gr->recovering) {
|
||||
wl_list_for_each(gb, &gr->shm_bufs, link) {
|
||||
glDeleteTextures(gb->num_textures, gb->textures);
|
||||
gb->num_textures = 0;
|
||||
}
|
||||
}
|
||||
|
||||
wl_list_for_each_safe(format, next_format, &gr->dmabuf_formats, link)
|
||||
dmabuf_format_destroy(format);
|
||||
|
||||
|
|
@ -5279,6 +5296,62 @@ create_default_dmabuf_feedback(struct weston_compositor *ec,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gl_renderer_recover_resources(struct weston_compositor *ec)
|
||||
{
|
||||
struct gl_renderer *gr = get_renderer(ec);
|
||||
struct gl_buffer_state *gb, *tmp;
|
||||
struct wl_list tmp_gb_list;
|
||||
|
||||
wl_list_init(&tmp_gb_list);
|
||||
wl_list_for_each_safe(gb, tmp, &gr->shm_bufs, link) {
|
||||
struct gl_surface_state *gs = gb->saved_gs;
|
||||
struct weston_surface *es = gs->surface;
|
||||
struct gl_buffer_state *new_gb;
|
||||
struct weston_buffer *buffer;
|
||||
|
||||
assert(es);
|
||||
/*
|
||||
* This gb is no longer the surface's current SHM buffer state.
|
||||
* It has lost its owner link through gs->buffer, so the normal
|
||||
* surface lifecycle will not destroy it for us anymore. Treat it
|
||||
* as an orphaned stale entry and clean it up here.
|
||||
*/
|
||||
if (gs->buffer != gb) {
|
||||
destroy_buffer_state(gb);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Destroy the original gb and recreate it. */
|
||||
buffer = es->buffer_ref.buffer;
|
||||
if (!buffer || buffer->type != WESTON_BUFFER_SHM) {
|
||||
/*
|
||||
* The surface no longer points at a live SHM buffer, so
|
||||
* this gb should not participate in GPU recovery.
|
||||
* However, gs->buffer still owns it, and the normal
|
||||
* attach/surface-destroy paths will destroy it later.
|
||||
* Remove it from shm_bufs so recovery ignores it, but do
|
||||
* not change its original lifetime.
|
||||
*/
|
||||
wl_list_remove(&gb->link);
|
||||
wl_list_init(&gb->link);
|
||||
continue;
|
||||
}
|
||||
|
||||
gl_renderer_attach_shm(es, buffer);
|
||||
new_gb = gs->buffer;
|
||||
assert(new_gb);
|
||||
|
||||
wl_list_insert(&tmp_gb_list, &new_gb->link);
|
||||
}
|
||||
|
||||
assert(wl_list_empty(&gr->shm_bufs));
|
||||
/* Manually add the new gbs to shm_bufs. */
|
||||
wl_list_insert_list(&gr->shm_bufs, &tmp_gb_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gl_renderer_init_context(struct weston_compositor *ec,
|
||||
const struct gl_renderer_display_options *options)
|
||||
|
|
@ -5370,6 +5443,9 @@ gl_renderer_init_context(struct weston_compositor *ec,
|
|||
}
|
||||
wl_list_init(&gr->dmabuf_formats);
|
||||
|
||||
if (gr->recovering && gl_renderer_recover_resources(ec))
|
||||
goto fail_with_error;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_with_error:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue