Fix T91197: marking assets from Python may crash
When using `asset_mark` function from a Python script and afterwards updating the preview image, a crash might happen. The preview image is generated by the `asset_mark` function. This may happen on a background thread, introducing potential synchronization issues. This patch fixes this by separating the preview generation `ID.asset_generate_preview` from the mark as asset `ID.asset_mark`. Note: this separation of "mark as asset" and "generate preview" also applies to the `ED_asset_mark_id()` C function; if it is desired to have previews rendered after marking as asset, a call to `ED_asset_generate_preview()` is now also required. Reviewed By: sybren Maniphest Tasks: T91197 Differential Revision: https://developer.blender.org/D12922
This commit is contained in:
@@ -34,7 +34,14 @@ struct bContext;
|
||||
*
|
||||
* \return whether the datablock was marked as asset; false when it is not capable of becoming an
|
||||
* asset, or when it already was an asset. */
|
||||
bool ED_asset_mark_id(const struct bContext *C, struct ID *id);
|
||||
bool ED_asset_mark_id(struct ID *id);
|
||||
|
||||
/**
|
||||
* Generate preview image for the given datablock.
|
||||
*
|
||||
* The preview image might be generated using a background thread.
|
||||
*/
|
||||
void ED_asset_generate_preview(const struct bContext *C, struct ID *id);
|
||||
|
||||
/**
|
||||
* Remove the asset metadata, turning the ID into a "normal" ID.
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "ED_asset_list.h"
|
||||
#include "ED_asset_mark_clear.h"
|
||||
|
||||
bool ED_asset_mark_id(const bContext *C, ID *id)
|
||||
bool ED_asset_mark_id(ID *id)
|
||||
{
|
||||
if (id->asset_data) {
|
||||
return false;
|
||||
@@ -53,14 +53,17 @@ bool ED_asset_mark_id(const bContext *C, ID *id)
|
||||
|
||||
id->asset_data = BKE_asset_metadata_create();
|
||||
|
||||
UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
|
||||
|
||||
/* Important for asset storage to update properly! */
|
||||
ED_assetlist_storage_tag_main_data_dirty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ED_asset_generate_preview(const bContext *C, ID *id)
|
||||
{
|
||||
UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
|
||||
}
|
||||
|
||||
bool ED_asset_clear_id(ID *id)
|
||||
{
|
||||
if (!id->asset_data) {
|
||||
|
||||
@@ -145,7 +145,9 @@ void AssetMarkHelper::operator()(const bContext &C, PointerRNAVec &ids)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ED_asset_mark_id(&C, id)) {
|
||||
if (ED_asset_mark_id(id)) {
|
||||
ED_asset_generate_preview(&C, id);
|
||||
|
||||
stats.last_id = id;
|
||||
stats.tot_created++;
|
||||
}
|
||||
|
||||
@@ -669,14 +669,22 @@ static ID *rna_ID_copy(ID *id, Main *bmain)
|
||||
return newid;
|
||||
}
|
||||
|
||||
static void rna_ID_asset_mark(ID *id, bContext *C)
|
||||
static void rna_ID_asset_mark(ID *id)
|
||||
{
|
||||
if (ED_asset_mark_id(C, id)) {
|
||||
if (ED_asset_mark_id(id)) {
|
||||
WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
|
||||
WM_main_add_notifier(NC_ASSET | NA_ADDED, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_ID_asset_generate_preview(ID *id, bContext *C)
|
||||
{
|
||||
ED_asset_generate_preview(C, id);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
|
||||
WM_main_add_notifier(NC_ASSET | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static void rna_ID_asset_clear(ID *id)
|
||||
{
|
||||
if (ED_asset_clear_id(id)) {
|
||||
@@ -1986,13 +1994,17 @@ static void rna_def_ID(BlenderRNA *brna)
|
||||
func,
|
||||
"Enable easier reuse of the data-block through the Asset Browser, with the help of "
|
||||
"customizable metadata (like previews, descriptions and tags)");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
|
||||
func = RNA_def_function(srna, "asset_clear", "rna_ID_asset_clear");
|
||||
RNA_def_function_ui_description(
|
||||
func,
|
||||
"Delete all asset metadata and turn the asset data-block back into a normal data-block");
|
||||
|
||||
func = RNA_def_function(srna, "asset_generate_preview", "rna_ID_asset_generate_preview");
|
||||
RNA_def_function_ui_description(
|
||||
func, "Generate preview image (might be scheduled in a background thread)");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
|
||||
func = RNA_def_function(srna, "override_create", "rna_ID_override_create");
|
||||
RNA_def_function_ui_description(func,
|
||||
"Create an overridden local copy of this linked data-block (not "
|
||||
|
||||
Reference in New Issue
Block a user