comp: Delay swapchain destruction until a safe time, like end frame.

This commit is contained in:
Jakob Bornecrantz 2020-04-15 17:37:34 +01:00
parent 061dbefbd0
commit c8b4a00482
4 changed files with 73 additions and 8 deletions

View file

@ -0,0 +1 @@
main: Delay the destruction of swapchains until a time where it is safe, this allows swapchains to be destroyed from other threads.

View file

@ -73,6 +73,9 @@ compositor_destroy(struct xrt_compositor *xc)
COMP_DEBUG(c, "DESTROY");
// Make sure we don't have anything to destroy.
comp_compositor_garbage_collect(c);
if (c->r) {
comp_renderer_destroy(c->r);
c->r = NULL;
@ -105,6 +108,8 @@ compositor_destroy(struct xrt_compositor *xc)
free(c->compositor_frame_times.debug_var);
}
u_threading_stack_fini(&c->threading.destroy_swapchains);
free(c);
}
@ -305,6 +310,9 @@ compositor_end_frame(struct xrt_compositor *xc,
//! @todo do a time-weighted average or something.
c->expected_app_duration_ns =
c->app_profiling.last_end - c->app_profiling.last_begin;
// Now is a good point to garbage collect.
comp_compositor_garbage_collect(c);
}
@ -806,6 +814,8 @@ xrt_gfx_provider_create_fd(struct xrt_device *xdev, bool flip_y)
c->base.base.destroy = compositor_destroy;
c->xdev = xdev;
u_threading_stack_init(&c->threading.destroy_swapchains);
COMP_DEBUG(c, "Doing init %p", (void *)c);
// Init the settings to default.
@ -868,3 +878,13 @@ xrt_gfx_provider_create_fd(struct xrt_device *xdev, bool flip_y)
return &c->base;
}
void
comp_compositor_garbage_collect(struct comp_compositor *c)
{
struct comp_swapchain *sc;
while ((sc = u_threading_stack_pop(&c->threading.destroy_swapchains))) {
comp_swapchain_really_destroy(sc);
}
}

View file

@ -10,11 +10,14 @@
#pragma once
#include "xrt/xrt_gfx_vk.h"
#include "util/u_threading.h"
#include "main/comp_settings.h"
#include "main/comp_window.h"
#include "main/comp_renderer.h"
#include "xrt/xrt_gfx_vk.h"
#ifdef __cplusplus
extern "C" {
@ -143,6 +146,12 @@ struct comp_compositor
uint32_t width;
uint32_t height;
} current;
struct
{
//! Thread object for safely destroying swapchain.
struct u_threading_stack destroy_swapchains;
} threading;
};
@ -174,6 +183,15 @@ comp_compositor(struct xrt_compositor *xc)
return (struct comp_compositor *)xc;
}
/*!
* Do garbage collection, destroying any resources that has been scheduled for
* destruction from other threads.
*
* @ingroup comp_main
*/
void
comp_compositor_garbage_collect(struct comp_compositor *c);
/*!
* A compositor function that is implemented in the swapchain code.
*
@ -191,6 +209,16 @@ comp_swapchain_create(struct xrt_compositor *xc,
uint32_t array_size,
uint32_t mip_count);
/*!
* Swapchain destruct is delayed until it is safe to destroy them, this function
* does the actual destruction and is called from @ref
* comp_compositor_garbage_collect.
*
* @ingroup comp_main
*/
void
comp_swapchain_really_destroy(struct comp_swapchain *sc);
/*!
* Free and destroy any initialized fields on the given image, safe to pass in
* images that has one or all fields set to NULL.

View file

@ -19,16 +19,10 @@ static void
swapchain_destroy(struct xrt_swapchain *xsc)
{
struct comp_swapchain *sc = comp_swapchain(xsc);
struct vk_bundle *vk = &sc->c->vk;
COMP_SPEW(sc->c, "DESTROY");
for (uint32_t i = 0; i < sc->base.base.num_images; i++) {
comp_swapchain_image_cleanup(vk, sc->base.base.array_size,
&sc->images[i]);
}
free(sc);
u_threading_stack_push(&sc->c->threading.destroy_swapchains, sc);
}
static bool
@ -205,6 +199,13 @@ err_image:
return ret;
}
/*
*
* Exported functions.
*
*/
struct xrt_swapchain *
comp_swapchain_create(struct xrt_compositor *xc,
enum xrt_swapchain_create_flags create,
@ -334,3 +335,18 @@ comp_swapchain_image_cleanup(struct vk_bundle *vk,
image->memory = VK_NULL_HANDLE;
}
}
void
comp_swapchain_really_destroy(struct comp_swapchain *sc)
{
struct vk_bundle *vk = &sc->c->vk;
COMP_SPEW(sc->c, "REALLY DESTROY");
for (uint32_t i = 0; i < sc->base.base.num_images; i++) {
comp_swapchain_image_cleanup(vk, sc->base.base.array_size,
&sc->images[i]);
}
free(sc);
}