DrawManager: Engine Instance Data.

In the original design draw engines had to copy with a limitation that
they were not allowed to reuse complex data structures between drawing
calls. Data that could be reused were limited to:
- GPUFramebuffers
- GPUTextures
- Memory that could be removed calling MEM_freeN (storage list)
- DRWPass

This is fine when the storage list contains arrays or structs but when
more complex data types (vectors, maps) etc wasn't possible.

This patch adds instance_data that can be reused between drawing calls.
The instance_data is controlled by the draw engine and doesn't need to
be limited as described above.

When an engines stores instance_data it must implement the
`DrawEngineType.instance_free` callback to free the data.

The patch originates from eevee rewrite. But was added to master as the
image engine rewrite also has a need for it.

Reviewed By: fclem

Differential Revision: https://developer.blender.org/D13425
This commit is contained in:
Jeroen Bakker 2021-12-07 10:33:55 +01:00 committed by Jeroen Bakker
parent e2f0b4a0cb
commit b069218a55
12 changed files with 23 additions and 0 deletions

View File

@ -265,6 +265,7 @@ DrawEngineType draw_engine_basic_type = {
&basic_data_size,
NULL,
&basic_engine_free,
NULL, /* instance_free */
&basic_cache_init,
&basic_cache_populate,
&basic_cache_finish,

View File

@ -629,6 +629,7 @@ DrawEngineType draw_engine_eevee_type = {
&eevee_data_size,
&eevee_engine_init,
&eevee_engine_free,
NULL, /* instance_free */
&eevee_cache_init,
&EEVEE_cache_populate,
&eevee_cache_finish,

View File

@ -451,6 +451,7 @@ DrawEngineType draw_engine_external_type = {
&external_data_size,
&external_engine_init,
&external_engine_free,
NULL, /* instance_free */
&external_cache_init,
&external_cache_populate,
&external_cache_finish,

View File

@ -990,6 +990,7 @@ DrawEngineType draw_engine_gpencil_type = {
&GPENCIL_data_size,
&GPENCIL_engine_init,
&GPENCIL_engine_free,
NULL, /* instance_free */
&GPENCIL_cache_init,
&GPENCIL_cache_populate,
&GPENCIL_cache_finish,

View File

@ -191,6 +191,7 @@ DrawEngineType draw_engine_image_type = {
&IMAGE_data_size, /* vedata_size */
&IMAGE_engine_init, /* engine_init */
&IMAGE_engine_free, /* engine_free */
nullptr, /* instance_free */
&IMAGE_cache_init, /* cache_init */
&IMAGE_cache_populate, /* cache_populate */
nullptr, /* cache_finish */

View File

@ -703,6 +703,7 @@ DrawEngineType draw_engine_overlay_type = {
&overlay_data_size,
&OVERLAY_engine_init,
&OVERLAY_engine_free,
NULL, /* instance_free */
&OVERLAY_cache_init,
&OVERLAY_cache_populate,
&OVERLAY_cache_finish,

View File

@ -120,6 +120,7 @@ DrawEngineType draw_engine_debug_select_type = {
&select_debug_data_size,
&select_debug_engine_init,
&select_debug_engine_free,
NULL, /* instance_free */
NULL,
NULL,
NULL,

View File

@ -363,6 +363,7 @@ DrawEngineType draw_engine_select_type = {
&select_data_size,
&select_engine_init,
&select_engine_free,
NULL, /* instance_free */
&select_cache_init,
&select_cache_populate,
NULL,

View File

@ -629,6 +629,7 @@ DrawEngineType draw_engine_workbench = {
&workbench_data_size,
&workbench_engine_init,
&workbench_engine_free,
NULL, /* instance_free */
&workbench_cache_init,
&workbench_cache_populate,
&workbench_cache_finish,

View File

@ -121,6 +121,8 @@ typedef struct DrawEngineType {
void (*engine_init)(void *vedata);
void (*engine_free)(void);
void (*instance_free)(void *instance_data);
void (*cache_init)(void *vedata);
void (*cache_populate)(void *vedata, struct Object *ob);
void (*cache_finish)(void *vedata);

View File

@ -120,6 +120,12 @@ static void draw_viewport_engines_data_clear(ViewportEngineData *data)
MEM_SAFE_FREE(data->stl->storage[i]);
}
if (data->instance_data) {
BLI_assert(engine_type->instance_free != nullptr);
engine_type->instance_free(data->instance_data);
data->instance_data = nullptr;
}
MEM_SAFE_FREE(data->fbl);
MEM_SAFE_FREE(data->txl);
MEM_SAFE_FREE(data->psl);

View File

@ -63,6 +63,12 @@ typedef struct ViewportEngineData {
TextureList *txl;
PassList *psl;
StorageList *stl;
/**
* \brief Memory block that can be freely used by the draw engine.
* When used the draw engine must implement #DrawEngineType.instance_free callback.
*/
void *instance_data;
char info[GPU_INFO_SIZE];
/* we may want to put this elsewhere */