mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-14 23:34:08 +00:00
libobs: Defer update of scene item texture
If the scene item crop/filtering is updated, instead of creating/destroying the item texture on the spot, update it in the graphics thread to prevent potential race conditions (especially when the crop function for example could be called from within obs_scene_enum_items in some situations, which would lock the graphics and scene mutexes in the wrong order).
This commit is contained in:
parent
01ac60c760
commit
d11b05a83d
|
@ -30,6 +30,8 @@ static void get_ungrouped_transform(obs_sceneitem_t *group,
|
|||
struct vec2 *pos,
|
||||
struct vec2 *scale,
|
||||
float *rot);
|
||||
static inline bool crop_enabled(const struct obs_sceneitem_crop *crop);
|
||||
static inline bool item_texture_enabled(const struct obs_scene_item *item);
|
||||
|
||||
/* NOTE: For proper mutex lock order (preventing mutual cross-locks), never
|
||||
* lock the graphics mutex inside either of the scene mutexes.
|
||||
|
@ -404,6 +406,18 @@ static void update_item_transform(struct obs_scene_item *item)
|
|||
calldata_set_ptr(¶ms, "item", item);
|
||||
signal_parent(item->parent, "item_transform", ¶ms);
|
||||
|
||||
if (item->item_render && !item_texture_enabled(item)) {
|
||||
obs_enter_graphics();
|
||||
gs_texrender_destroy(item->item_render);
|
||||
item->item_render = NULL;
|
||||
obs_leave_graphics();
|
||||
|
||||
} else if (!item->item_render && item_texture_enabled(item)) {
|
||||
obs_enter_graphics();
|
||||
item->item_render = gs_texrender_create(GS_RGBA, GS_ZS_NONE);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
os_atomic_set_bool(&item->update_transform, false);
|
||||
}
|
||||
|
||||
|
@ -2135,8 +2149,6 @@ static inline bool crop_equal(const struct obs_sceneitem_crop *crop1,
|
|||
void obs_sceneitem_set_crop(obs_sceneitem_t *item,
|
||||
const struct obs_sceneitem_crop *crop)
|
||||
{
|
||||
bool item_tex_now_enabled;
|
||||
|
||||
if (!obs_ptr_valid(item, "obs_sceneitem_set_crop"))
|
||||
return;
|
||||
if (!obs_ptr_valid(crop, "obs_sceneitem_set_crop"))
|
||||
|
@ -2144,26 +2156,12 @@ void obs_sceneitem_set_crop(obs_sceneitem_t *item,
|
|||
if (crop_equal(crop, &item->crop))
|
||||
return;
|
||||
|
||||
item_tex_now_enabled = crop_enabled(crop) ||
|
||||
scale_filter_enabled(item) || item_is_scene(item);
|
||||
|
||||
obs_enter_graphics();
|
||||
|
||||
if (!item_tex_now_enabled) {
|
||||
gs_texrender_destroy(item->item_render);
|
||||
item->item_render = NULL;
|
||||
|
||||
} else if (!item->item_render) {
|
||||
item->item_render = gs_texrender_create(GS_RGBA, GS_ZS_NONE);
|
||||
}
|
||||
|
||||
memcpy(&item->crop, crop, sizeof(*crop));
|
||||
|
||||
if (item->crop.left < 0) item->crop.left = 0;
|
||||
if (item->crop.right < 0) item->crop.right = 0;
|
||||
if (item->crop.top < 0) item->crop.top = 0;
|
||||
if (item->crop.bottom < 0) item->crop.bottom = 0;
|
||||
obs_leave_graphics();
|
||||
|
||||
os_atomic_set_bool(&item->update_transform, true);
|
||||
}
|
||||
|
@ -2187,18 +2185,6 @@ void obs_sceneitem_set_scale_filter(obs_sceneitem_t *item,
|
|||
|
||||
item->scale_filter = filter;
|
||||
|
||||
obs_enter_graphics();
|
||||
|
||||
if (!item_texture_enabled(item)) {
|
||||
gs_texrender_destroy(item->item_render);
|
||||
item->item_render = NULL;
|
||||
|
||||
} else if (!item->item_render) {
|
||||
item->item_render = gs_texrender_create(GS_RGBA, GS_ZS_NONE);
|
||||
}
|
||||
|
||||
obs_leave_graphics();
|
||||
|
||||
os_atomic_set_bool(&item->update_transform, true);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue