renderer: cleanup dangling resources.

if a context goes away we should cleanup any resources
left in its resource hash table.
macos/master
Dave Airlie 10 years ago
parent 4920fc6d1d
commit aef2ec2e78
  1. 19
      src/vrend_object.c
  2. 1
      src/vrend_object.h
  3. 13
      src/vrend_renderer.c
  4. 4
      src/vrend_renderer.h

@ -32,11 +32,18 @@ struct vrend_object_types {
void (*unref)(void *); void (*unref)(void *);
} obj_types[VIRGL_MAX_OBJECTS]; } obj_types[VIRGL_MAX_OBJECTS];
static void (*resource_unref)(void *);
void vrend_object_set_destroy_callback(int type, void (*cb)(void *)) void vrend_object_set_destroy_callback(int type, void (*cb)(void *))
{ {
obj_types[type].unref = cb; obj_types[type].unref = cb;
} }
void vrend_resource_set_destroy_callback(void (*cb)(void *))
{
resource_unref = cb;
}
static unsigned static unsigned
hash_func(void *key) hash_func(void *key)
{ {
@ -107,10 +114,20 @@ vrend_object_init_resource_table(void)
res_hash = util_hash_table_create(hash_func, compare); res_hash = util_hash_table_create(hash_func, compare);
} }
static enum pipe_error free_res_cb(void *key, void *value, void *data)
{
struct vrend_object *obj = value;
(*resource_unref)(obj->data);
free(obj);
return PIPE_OK;
}
void vrend_object_fini_resource_table(void) void vrend_object_fini_resource_table(void)
{ {
if (res_hash) if (res_hash) {
util_hash_table_foreach(res_hash, free_res_cb, NULL);
util_hash_table_destroy(res_hash); util_hash_table_destroy(res_hash);
}
res_hash = NULL; res_hash = NULL;
} }

@ -48,4 +48,5 @@ void vrend_resource_remove(uint32_t handle);
void *vrend_resource_lookup(uint32_t handle, uint32_t ctx_id); void *vrend_resource_lookup(uint32_t handle, uint32_t ctx_id);
void vrend_object_set_destroy_callback(int type, void (*cb)(void *)); void vrend_object_set_destroy_callback(int type, void (*cb)(void *));
void vrend_resource_set_destroy_callback(void (*cb)(void *));
#endif #endif

@ -59,6 +59,7 @@ static void vrend_finish_context_switch(struct vrend_context *ctx);
static void vrend_patch_blend_func(struct vrend_context *ctx); static void vrend_patch_blend_func(struct vrend_context *ctx);
static void vrend_update_frontface_state(struct vrend_context *ctx); static void vrend_update_frontface_state(struct vrend_context *ctx);
static void vrender_get_glsl_version(int *glsl_version); static void vrender_get_glsl_version(int *glsl_version);
static void vrend_destroy_resource_object(void *obj_ptr);
extern int vrend_shader_use_explicit; extern int vrend_shader_use_explicit;
static int have_invert_mesa = 0; static int have_invert_mesa = 0;
static int use_core_profile = 0; static int use_core_profile = 0;
@ -3150,6 +3151,7 @@ void vrend_renderer_init(struct vrend_if_cbs *cbs)
} }
/* callbacks for when we are cleaning up the object table */ /* callbacks for when we are cleaning up the object table */
vrend_resource_set_destroy_callback(vrend_destroy_resource_object);
vrend_object_set_destroy_callback(VIRGL_OBJECT_QUERY, vrend_destroy_query_object); vrend_object_set_destroy_callback(VIRGL_OBJECT_QUERY, vrend_destroy_query_object);
vrend_object_set_destroy_callback(VIRGL_OBJECT_SURFACE, vrend_destroy_surface_object); vrend_object_set_destroy_callback(VIRGL_OBJECT_SURFACE, vrend_destroy_surface_object);
vrend_object_set_destroy_callback(VIRGL_OBJECT_VS, vrend_destroy_shader_object); vrend_object_set_destroy_callback(VIRGL_OBJECT_VS, vrend_destroy_shader_object);
@ -3452,13 +3454,13 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a
ret = vrend_resource_insert(gr, sizeof(*gr), args->handle); ret = vrend_resource_insert(gr, sizeof(*gr), args->handle);
if (ret == 0) { if (ret == 0) {
vrend_renderer_resource_destroy(gr); vrend_renderer_resource_destroy(gr, true);
return ENOMEM; return ENOMEM;
} }
return 0; return 0;
} }
void vrend_renderer_resource_destroy(struct vrend_resource *res) void vrend_renderer_resource_destroy(struct vrend_resource *res, bool remove)
{ {
// if (res->scannedout) TODO // if (res->scannedout) TODO
// (*vrend_clicbs->scanout_resource_info)(0, res->id, 0, 0, 0, 0, 0); // (*vrend_clicbs->scanout_resource_info)(0, res->id, 0, 0, 0, 0, 0);
@ -3481,11 +3483,16 @@ void vrend_renderer_resource_destroy(struct vrend_resource *res)
glDeleteTextures(1, &res->id); glDeleteTextures(1, &res->id);
} }
if (res->handle) if (res->handle && remove)
vrend_resource_remove(res->handle); vrend_resource_remove(res->handle);
free(res); free(res);
} }
static void vrend_destroy_resource_object(void *obj_ptr)
{
struct vrend_resource *res = obj_ptr;
vrend_renderer_resource_destroy(res, false);
}
void vrend_renderer_resource_unref(uint32_t res_handle) void vrend_renderer_resource_unref(uint32_t res_handle)
{ {

@ -327,7 +327,7 @@ int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov,
void vrend_renderer_resource_detach_iov(int res_handle, void vrend_renderer_resource_detach_iov(int res_handle,
struct iovec **iov_p, struct iovec **iov_p,
int *num_iovs_p); int *num_iovs_p);
void vrend_renderer_resource_destroy(struct vrend_resource *res); void vrend_renderer_resource_destroy(struct vrend_resource *res, bool remove);
static INLINE void static INLINE void
vrend_resource_reference(struct vrend_resource **ptr, struct vrend_resource *tex) vrend_resource_reference(struct vrend_resource **ptr, struct vrend_resource *tex)
@ -335,7 +335,7 @@ vrend_resource_reference(struct vrend_resource **ptr, struct vrend_resource *tex
struct vrend_resource *old_tex = *ptr; struct vrend_resource *old_tex = *ptr;
if (pipe_reference(&(*ptr)->base.reference, &tex->base.reference)) if (pipe_reference(&(*ptr)->base.reference, &tex->base.reference))
vrend_renderer_resource_destroy(old_tex); vrend_renderer_resource_destroy(old_tex, true);
*ptr = tex; *ptr = tex;
} }

Loading…
Cancel
Save