Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_cryptomatte.h27
-rw-r--r--source/blender/blenkernel/intern/cryptomatte.cc186
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c1
-rw-r--r--source/blender/draw/engines/eevee/eevee_cryptomatte.c52
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c13
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h3
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c1
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c4
-rw-r--r--source/blender/draw/engines/external/external_engine.c1
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c1
-rw-r--r--source/blender/draw/engines/image/image_engine.c1
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c1
-rw-r--r--source/blender/draw/engines/select/select_engine.c1
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c1
-rw-r--r--source/blender/draw/intern/DRW_render.h1
-rw-r--r--source/blender/draw/intern/draw_manager.c5
16 files changed, 272 insertions, 27 deletions
diff --git a/source/blender/blenkernel/BKE_cryptomatte.h b/source/blender/blenkernel/BKE_cryptomatte.h
index 433c25084ad..3abaf5256df 100644
--- a/source/blender/blenkernel/BKE_cryptomatte.h
+++ b/source/blender/blenkernel/BKE_cryptomatte.h
@@ -24,19 +24,30 @@
#pragma once
#include "BLI_sys_types.h"
+#include "DNA_layer_types.h"
#ifdef __cplusplus
extern "C" {
#endif
-struct Main;
+struct CryptomatteSession;
struct Material;
+struct ID;
+struct Main;
struct Object;
+struct RenderResult;
+
+struct CryptomatteSession *BKE_cryptomatte_init(void);
+void BKE_cryptomatte_finish(struct CryptomatteSession *session);
+void BKE_cryptomatte_free(struct CryptomatteSession *session);
uint32_t BKE_cryptomatte_hash(const char *name, int name_len);
-uint32_t BKE_cryptomatte_object_hash(const struct Object *object);
-uint32_t BKE_cryptomatte_material_hash(const struct Material *material);
-uint32_t BKE_cryptomatte_asset_hash(const struct Object *object);
+uint32_t BKE_cryptomatte_object_hash(struct CryptomatteSession *session,
+ const struct Object *object);
+uint32_t BKE_cryptomatte_material_hash(struct CryptomatteSession *session,
+ const struct Material *material);
+uint32_t BKE_cryptomatte_asset_hash(struct CryptomatteSession *session,
+ const struct Object *object);
float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash);
char *BKE_cryptomatte_entries_to_matte_id(struct NodeCryptomatte *node_storage);
@@ -44,6 +55,12 @@ void BKE_cryptomatte_matte_id_to_entries(const struct Main *bmain,
struct NodeCryptomatte *node_storage,
const char *matte_id);
+void BKE_cryptomatte_store_metadata(struct CryptomatteSession *session,
+ struct RenderResult *render_result,
+ const ViewLayer *view_layer,
+ eViewLayerCryptomatteFlags cryptomatte_layer,
+ const char *cryptomatte_layer_name);
+
#ifdef __cplusplus
}
-#endif
+#endif \ No newline at end of file
diff --git a/source/blender/blenkernel/intern/cryptomatte.cc b/source/blender/blenkernel/intern/cryptomatte.cc
index 4bbeb088628..3ed66960162 100644
--- a/source/blender/blenkernel/intern/cryptomatte.cc
+++ b/source/blender/blenkernel/intern/cryptomatte.cc
@@ -22,8 +22,10 @@
*/
#include "BKE_cryptomatte.h"
+#include "BKE_image.h"
#include "BKE_main.h"
+#include "DNA_layer_types.h"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
@@ -32,48 +34,142 @@
#include "BLI_dynstr.h"
#include "BLI_hash_mm3.h"
#include "BLI_listbase.h"
+#include "BLI_set.hh"
#include "BLI_string.h"
#include "MEM_guardedalloc.h"
#include <cstring>
+#include <iomanip>
#include <sstream>
#include <string>
-static uint32_t cryptomatte_hash(const ID *id)
+enum CryptomatteLayerState {
+ EMPTY,
+ FILLED,
+ CLOSED,
+};
+
+struct CryptomatteLayer {
+ CryptomatteLayerState state = CryptomatteLayerState::EMPTY;
+ blender::Set<std::string> names;
+ std::stringstream manifest;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("cryptomatte:CryptomatteLayer")
+#endif
+
+ void add_hash(std::string name, uint32_t cryptomatte_hash)
+ {
+ BLI_assert(state != CryptomatteLayerState::CLOSED);
+ const bool first_item = names.is_empty();
+ if (!names.add(name)) {
+ return;
+ }
+
+ if (first_item) {
+ state = CryptomatteLayerState::FILLED;
+ manifest << "{";
+ }
+ else {
+ manifest << ",";
+ }
+ manifest << quoted(name) << ":\"";
+ manifest << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex
+ << cryptomatte_hash;
+ manifest << "\"";
+ }
+
+ void close_manifest()
+ {
+ BLI_assert(state != CryptomatteLayerState::CLOSED);
+ if (state == CryptomatteLayerState::FILLED) {
+ manifest << "}";
+ }
+ state = CryptomatteLayerState::CLOSED;
+ }
+
+ std::string manifest_get_string()
+ {
+ BLI_assert(state == CryptomatteLayerState::CLOSED);
+ return manifest.str();
+ }
+};
+
+struct CryptomatteSession {
+ CryptomatteLayer objects;
+ CryptomatteLayer assets;
+ CryptomatteLayer materials;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("cryptomatte:CryptomatteSession")
+#endif
+
+ void finish()
+ {
+ objects.close_manifest();
+ materials.close_manifest();
+ assets.close_manifest();
+ }
+};
+
+CryptomatteSession *BKE_cryptomatte_init(void)
{
- const char *name = &id->name[2];
- const int name_len = BLI_strnlen(name, MAX_NAME);
- uint32_t cryptohash_int = BKE_cryptomatte_hash(name, name_len);
- return cryptohash_int;
+ CryptomatteSession *session = new CryptomatteSession();
+ return session;
+}
+
+void BKE_cryptomatte_finish(CryptomatteSession *session)
+{
+ BLI_assert(session != NULL);
+ session->finish();
}
-uint32_t BKE_cryptomatte_hash(const char *name, int name_len)
+void BKE_cryptomatte_free(CryptomatteSession *session)
+{
+ BLI_assert(session != NULL);
+ delete session;
+}
+
+uint32_t BKE_cryptomatte_hash(const char *name, const int name_len)
{
uint32_t cryptohash_int = BLI_hash_mm3((const unsigned char *)name, name_len, 0);
return cryptohash_int;
}
-uint32_t BKE_cryptomatte_object_hash(const Object *object)
+static uint32_t cryptomatte_hash(CryptomatteLayer *layer, const ID *id)
{
- return cryptomatte_hash(&object->id);
+ const char *name = &id->name[2];
+ const int name_len = BLI_strnlen(name, MAX_NAME - 2);
+ uint32_t cryptohash_int = BKE_cryptomatte_hash(name, name_len);
+
+ if (layer != nullptr) {
+ layer->add_hash(std::string(name, name_len), cryptohash_int);
+ }
+
+ return cryptohash_int;
}
-uint32_t BKE_cryptomatte_material_hash(const Material *material)
+uint32_t BKE_cryptomatte_object_hash(CryptomatteSession *session, const Object *object)
{
- if (material == nullptr) {
+ return cryptomatte_hash(&session->objects, &object->id);
+}
+
+uint32_t BKE_cryptomatte_material_hash(CryptomatteSession *session, const Material *material)
+{
+ if (material == NULL) {
return 0.0f;
}
- return cryptomatte_hash(&material->id);
+ return cryptomatte_hash(&session->materials, &material->id);
}
-uint32_t BKE_cryptomatte_asset_hash(const Object *object)
+uint32_t BKE_cryptomatte_asset_hash(CryptomatteSession *session, const Object *object)
{
const Object *asset_object = object;
- while (asset_object->parent != nullptr) {
+ while (asset_object->parent != NULL) {
asset_object = asset_object->parent;
}
- return cryptomatte_hash(&asset_object->id);
+ return cryptomatte_hash(&session->assets, &asset_object->id);
}
/* Convert a cryptomatte hash to a float.
@@ -187,4 +283,64 @@ void BKE_cryptomatte_matte_id_to_entries(const Main *bmain,
BLI_addtail(&node_storage->entries, entry);
}
}
-} \ No newline at end of file
+}
+
+static std::string cryptomatte_determine_name(const ViewLayer *view_layer,
+ const std::string cryptomatte_layer_name)
+{
+ std::stringstream stream;
+ const size_t view_layer_name_len = BLI_strnlen(view_layer->name, sizeof(view_layer->name));
+ stream << std::string(view_layer->name, view_layer_name_len) << "." << cryptomatte_layer_name;
+ return stream.str();
+}
+
+static uint32_t cryptomatte_determine_identifier(const std::string name)
+{
+ return BLI_hash_mm3(reinterpret_cast<const unsigned char *>(name.c_str()), name.length(), 0);
+}
+
+static std::string cryptomatte_determine_prefix(const std::string name)
+{
+ std::stringstream stream;
+ const uint32_t render_pass_identifier = cryptomatte_determine_identifier(name);
+ stream << "cryptomatte/";
+ stream << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex
+ << render_pass_identifier;
+ stream << "/";
+ return stream.str();
+}
+
+void BKE_cryptomatte_store_metadata(struct CryptomatteSession *session,
+ RenderResult *render_result,
+ const ViewLayer *view_layer,
+ eViewLayerCryptomatteFlags cryptomatte_layer,
+ const char *cryptomatte_layer_name)
+{
+ /* Create Manifest. */
+ CryptomatteLayer *layer = nullptr;
+ switch (cryptomatte_layer) {
+ case VIEW_LAYER_CRYPTOMATTE_OBJECT:
+ layer = &session->objects;
+ break;
+ case VIEW_LAYER_CRYPTOMATTE_MATERIAL:
+ layer = &session->materials;
+ break;
+ case VIEW_LAYER_CRYPTOMATTE_ASSET:
+ layer = &session->assets;
+ break;
+ default:
+ BLI_assert(!"Incorrect cryptomatte layer");
+ break;
+ }
+
+ const std::string manifest = layer->manifest_get_string();
+ const std::string name = cryptomatte_determine_name(view_layer, cryptomatte_layer_name);
+ const std::string prefix = cryptomatte_determine_prefix(name);
+
+ /* Store the meta data into the render result. */
+ BKE_render_result_stamp_data(render_result, (prefix + "name").c_str(), name.c_str());
+ BKE_render_result_stamp_data(render_result, (prefix + "hash").c_str(), "MurmurHash3_32");
+ BKE_render_result_stamp_data(
+ render_result, (prefix + "conversion").c_str(), "uint32_to_float32");
+ BKE_render_result_stamp_data(render_result, (prefix + "manifest").c_str(), manifest.c_str());
+}
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index a152f90e2c5..c120df7e897 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -260,6 +260,7 @@ DrawEngineType draw_engine_basic_type = {
NULL,
NULL,
NULL,
+ NULL,
};
#undef BASIC_ENGINE
diff --git a/source/blender/draw/engines/eevee/eevee_cryptomatte.c b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
index 9150de7184a..ce714715c6c 100644
--- a/source/blender/draw/engines/eevee/eevee_cryptomatte.c
+++ b/source/blender/draw/engines/eevee/eevee_cryptomatte.c
@@ -125,6 +125,7 @@ void EEVEE_cryptomatte_renderpasses_init(EEVEE_Data *vedata)
return;
}
if (eevee_cryptomatte_active_layers(view_layer) != 0) {
+ g_data->cryptomatte_session = BKE_cryptomatte_init();
g_data->render_passes |= EEVEE_RENDER_PASS_CRYPTOMATTE | EEVEE_RENDER_PASS_VOLUME_LIGHT;
g_data->cryptomatte_accurate_mode = (view_layer->cryptomatte_flag &
VIEW_LAYER_CRYPTOMATTE_ACCURATE) != 0;
@@ -193,24 +194,26 @@ static DRWShadingGroup *eevee_cryptomatte_shading_group_create(EEVEE_Data *vedat
const ViewLayer *view_layer = draw_ctx->view_layer;
const eViewLayerCryptomatteFlags cryptomatte_layers = eevee_cryptomatte_active_layers(
view_layer);
+ EEVEE_PrivateData *g_data = vedata->stl->g_data;
float cryptohash[4] = {0.0f};
EEVEE_PassList *psl = vedata->psl;
int layer_offset = 0;
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
- uint32_t cryptomatte_hash = BKE_cryptomatte_object_hash(ob);
+ uint32_t cryptomatte_hash = BKE_cryptomatte_object_hash(g_data->cryptomatte_session, ob);
float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
cryptohash[layer_offset] = cryptomatte_color_value;
layer_offset++;
}
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
- uint32_t cryptomatte_hash = BKE_cryptomatte_material_hash(material);
+ uint32_t cryptomatte_hash = BKE_cryptomatte_material_hash(g_data->cryptomatte_session,
+ material);
float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
cryptohash[layer_offset] = cryptomatte_color_value;
layer_offset++;
}
if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
- uint32_t cryptomatte_hash = BKE_cryptomatte_asset_hash(ob);
+ uint32_t cryptomatte_hash = BKE_cryptomatte_asset_hash(g_data->cryptomatte_session, ob);
float cryptomatte_color_value = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
cryptohash[layer_offset] = cryptomatte_color_value;
layer_offset++;
@@ -310,6 +313,12 @@ void EEVEE_cryptomatte_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *s
}
}
+void EEVEE_cryptomatte_cache_finish(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_PrivateData *g_data = vedata->stl->g_data;
+ BKE_cryptomatte_finish(g_data->cryptomatte_session);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -677,6 +686,37 @@ void EEVEE_cryptomatte_render_result(RenderLayer *rl,
}
}
+void EEVEE_cryptomatte_store_metadata(EEVEE_Data *vedata, RenderResult *render_result)
+{
+ EEVEE_PrivateData *g_data = vedata->stl->g_data;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const ViewLayer *view_layer = draw_ctx->view_layer;
+ const eViewLayerCryptomatteFlags cryptomatte_layers = view_layer->cryptomatte_flag &
+ VIEW_LAYER_CRYPTOMATTE_ALL;
+ BLI_assert(g_data->cryptomatte_session);
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_OBJECT) != 0) {
+ BKE_cryptomatte_store_metadata(g_data->cryptomatte_session,
+ render_result,
+ view_layer,
+ VIEW_LAYER_CRYPTOMATTE_OBJECT,
+ "CryptoObject");
+ }
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_MATERIAL) != 0) {
+ BKE_cryptomatte_store_metadata(g_data->cryptomatte_session,
+ render_result,
+ view_layer,
+ VIEW_LAYER_CRYPTOMATTE_MATERIAL,
+ "CryptoMaterial");
+ }
+ if ((cryptomatte_layers & VIEW_LAYER_CRYPTOMATTE_ASSET) != 0) {
+ BKE_cryptomatte_store_metadata(g_data->cryptomatte_session,
+ render_result,
+ view_layer,
+ VIEW_LAYER_CRYPTOMATTE_ASSET,
+ "CryptoAsset");
+ }
+}
+
/** \} */
void EEVEE_cryptomatte_free(EEVEE_Data *vedata)
@@ -684,4 +724,8 @@ void EEVEE_cryptomatte_free(EEVEE_Data *vedata)
EEVEE_PrivateData *g_data = vedata->stl->g_data;
MEM_SAFE_FREE(g_data->cryptomatte_accum_buffer);
MEM_SAFE_FREE(g_data->cryptomatte_download_buffer);
-}
+ if (g_data->cryptomatte_session) {
+ BKE_cryptomatte_free(g_data->cryptomatte_session);
+ g_data->cryptomatte_session = NULL;
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index f233b0fda96..c6760de5cfa 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -570,8 +570,6 @@ static void eevee_render_to_image(void *vedata,
EEVEE_motion_blur_data_free(&ved->stl->effects->motion_blur);
if (RE_engine_test_break(engine)) {
- /* Cryptomatte buffers are freed during render_read_result */
- EEVEE_cryptomatte_free(vedata);
return;
}
@@ -586,6 +584,16 @@ static void eevee_render_to_image(void *vedata,
}
}
+static void eevee_store_metadata(void *vedata, struct RenderResult *render_result)
+{
+ EEVEE_Data *ved = (EEVEE_Data *)vedata;
+ EEVEE_PrivateData *g_data = ved->stl->g_data;
+ if (g_data->render_passes & EEVEE_RENDER_PASS_CRYPTOMATTE) {
+ EEVEE_cryptomatte_store_metadata(ved, render_result);
+ EEVEE_cryptomatte_free(ved);
+ }
+}
+
static void eevee_engine_free(void)
{
EEVEE_shaders_free();
@@ -611,6 +619,7 @@ DrawEngineType draw_engine_eevee_type = {
&eevee_view_update,
&eevee_id_update,
&eevee_render_to_image,
+ &eevee_store_metadata,
};
RenderEngineType DRW_engine_viewport_eevee_type = {
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 5bf8cab1b22..9702db5fecc 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -977,6 +977,7 @@ typedef struct EEVEE_PrivateData {
eViewLayerEEVEEPassType render_passes;
int aov_hash;
int num_aovs_used;
+ struct CryptomatteSession *cryptomatte_session;
bool cryptomatte_accurate_mode;
EEVEE_CryptomatteSample *cryptomatte_accum_buffer;
float *cryptomatte_download_buffer;
@@ -1246,6 +1247,7 @@ void EEVEE_cryptomatte_output_init(EEVEE_ViewLayerData *sldata,
int tot_samples);
void EEVEE_cryptomatte_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_cryptomatte_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob);
+void EEVEE_cryptomatte_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_cryptomatte_particle_hair_cache_populate(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
Object *ob);
@@ -1261,6 +1263,7 @@ void EEVEE_cryptomatte_render_result(struct RenderLayer *rl,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata);
+void EEVEE_cryptomatte_store_metadata(EEVEE_Data *vedata, struct RenderResult *render_result);
void EEVEE_cryptomatte_free(EEVEE_Data *vedata);
/* eevee_occlusion.c */
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 2a01aeefce8..bb974688404 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -510,7 +510,6 @@ static void eevee_render_result_cryptomatte(RenderLayer *rl,
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_CRYPTOMATTE) != 0) {
EEVEE_cryptomatte_render_result(rl, viewname, rect, vedata, sldata);
}
- EEVEE_cryptomatte_free(vedata);
}
static void eevee_render_draw_background(EEVEE_Data *vedata)
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index dff3b437953..ce5292fbbb0 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -255,6 +255,10 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
else {
psl->renderpass_pass = NULL;
}
+
+ if ((g_data->render_passes & (EEVEE_RENDER_PASS_CRYPTOMATTE)) != 0) {
+ EEVEE_cryptomatte_cache_finish(sldata, vedata);
+ }
}
/* Post-process data to construct a specific render-pass
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index bd97fd8a413..1b331052a06 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -311,6 +311,7 @@ static DrawEngineType draw_engine_external_type = {
NULL,
NULL,
NULL,
+ NULL,
};
/* Note: currently unused,
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 519b015a6ad..20044fbe3ce 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -977,4 +977,5 @@ DrawEngineType draw_engine_gpencil_type = {
NULL,
NULL,
&GPENCIL_render_to_image,
+ NULL,
};
diff --git a/source/blender/draw/engines/image/image_engine.c b/source/blender/draw/engines/image/image_engine.c
index 0c602ba77c8..5445685b5ba 100644
--- a/source/blender/draw/engines/image/image_engine.c
+++ b/source/blender/draw/engines/image/image_engine.c
@@ -413,4 +413,5 @@ DrawEngineType draw_engine_image_type = {
NULL, /* view_update */
NULL, /* id_update */
NULL, /* render_to_image */
+ NULL, /* store_metadata */
};
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index 0fa3b17e7a5..f87f781b6ce 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -695,6 +695,7 @@ DrawEngineType draw_engine_overlay_type = {
NULL,
NULL,
NULL,
+ NULL,
};
/** \} */
diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c
index ec6e4c73043..c9c4a2076ef 100644
--- a/source/blender/draw/engines/select/select_engine.c
+++ b/source/blender/draw/engines/select/select_engine.c
@@ -370,6 +370,7 @@ DrawEngineType draw_engine_select_type = {
NULL,
NULL,
NULL,
+ NULL,
};
/* Note: currently unused, we may want to register so we can see this when debugging the view. */
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 92ce5dddbc6..37dbfe4d2a6 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -641,6 +641,7 @@ DrawEngineType draw_engine_workbench = {
&workbench_view_update,
&workbench_id_update,
&workbench_render,
+ NULL,
};
RenderEngineType DRW_engine_viewport_workbench_type = {
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index f133f3bc6d7..4a43107c612 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -131,6 +131,7 @@ typedef struct DrawEngineType {
struct RenderEngine *engine,
struct RenderLayer *layer,
const struct rcti *rect);
+ void (*store_metadata)(void *vedata, struct RenderResult *render_result);
} DrawEngineType;
/* Textures */
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index db701c384bd..1115d819659 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1911,6 +1911,11 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
RE_engine_end_result(engine, render_result, false, false, false);
+ if (engine_type->draw_engine->store_metadata) {
+ RenderResult *final_render_result = RE_engine_get_result(engine);
+ engine_type->draw_engine->store_metadata(data, final_render_result);
+ }
+
/* Force cache to reset. */
drw_viewport_cache_resize();