Refactor: DRW: Replace by enabled engine list by static members
Iteration is done through templates. Removes the need for the enabled engine list/vector. Reduces API complexity.
This commit is contained in:
@@ -35,7 +35,6 @@ void DRW_engines_register();
|
||||
void DRW_engines_free();
|
||||
|
||||
bool DRW_engine_render_support(DrawEngineType *draw_engine_type);
|
||||
void DRW_engine_register(DrawEngineType *draw_engine_type);
|
||||
|
||||
void DRW_engine_external_free(RegionView3D *rv3d);
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
#include "draw_shader.hh"
|
||||
#include "draw_subdivision.hh"
|
||||
#include "draw_view_c.hh"
|
||||
#include "draw_view_data.hh"
|
||||
|
||||
/* only for callbacks */
|
||||
#include "draw_cache_impl.hh"
|
||||
@@ -171,11 +172,6 @@ void DRWContext::state_ensure_not_reused()
|
||||
g_context = nullptr;
|
||||
}
|
||||
|
||||
static struct {
|
||||
ListBase /*DRWRegisteredDrawEngine*/ engines;
|
||||
int len;
|
||||
} g_registered_engines = {{nullptr}};
|
||||
|
||||
static bool drw_draw_show_annotation()
|
||||
{
|
||||
if (drw_get().draw_ctx.space_data == nullptr) {
|
||||
@@ -363,7 +359,7 @@ DRWData *DRW_viewport_data_create()
|
||||
drw_data->default_view = new blender::draw::View("DrawDefaultView");
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
drw_data->view_data[i] = DRW_view_data_create(&g_registered_engines.engines);
|
||||
drw_data->view_data[i] = new DRWViewData();
|
||||
}
|
||||
return drw_data;
|
||||
}
|
||||
@@ -390,7 +386,7 @@ static void drw_viewport_data_reset(DRWData * /*drw_data*/)
|
||||
void DRW_viewport_data_free(DRWData *drw_data)
|
||||
{
|
||||
for (int i = 0; i < 2; i++) {
|
||||
DRW_view_data_free(drw_data->view_data[i]);
|
||||
delete drw_data->view_data[i];
|
||||
}
|
||||
DRW_volume_module_free(drw_data->volume_module);
|
||||
DRW_pointcloud_module_free(drw_data->pointcloud_module);
|
||||
@@ -472,8 +468,7 @@ static void drw_manager_init(DRWContext *dst, GPUViewport *viewport, const int s
|
||||
dst->inv_size[1] = 1.0f / dst->size[1];
|
||||
|
||||
if (do_validation) {
|
||||
DRW_view_data_texture_list_size_validate(dst->view_data_active,
|
||||
blender::int2{int(dst->size[0]), int(dst->size[1])});
|
||||
dst->view_data_active->texture_list_size_validate(int2(dst->size));
|
||||
}
|
||||
|
||||
if (viewport) {
|
||||
@@ -920,30 +915,34 @@ void DRW_cache_free_old_batches(Main *bmain)
|
||||
|
||||
static void drw_engines_init()
|
||||
{
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (engine->engine_init) {
|
||||
engine->engine_init(data);
|
||||
}
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (engine->engine_init) {
|
||||
engine->engine_init(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void drw_engines_cache_init()
|
||||
{
|
||||
DRW_manager_begin_sync();
|
||||
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (data->text_draw_cache) {
|
||||
DRW_text_cache_destroy(data->text_draw_cache);
|
||||
data->text_draw_cache = nullptr;
|
||||
}
|
||||
if (drw_get().text_store_p == nullptr) {
|
||||
drw_get().text_store_p = &data->text_draw_cache;
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (data->text_draw_cache) {
|
||||
DRW_text_cache_destroy(data->text_draw_cache);
|
||||
data->text_draw_cache = nullptr;
|
||||
}
|
||||
if (drw_get().text_store_p == nullptr) {
|
||||
drw_get().text_store_p = &data->text_draw_cache;
|
||||
}
|
||||
|
||||
if (engine->cache_init) {
|
||||
engine->cache_init(data);
|
||||
}
|
||||
}
|
||||
if (engine->cache_init) {
|
||||
engine->cache_init(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void drw_engines_world_update(Scene *scene)
|
||||
@@ -952,11 +951,13 @@ static void drw_engines_world_update(Scene *scene)
|
||||
return;
|
||||
}
|
||||
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (engine->id_update) {
|
||||
engine->id_update(data, &scene->world->id);
|
||||
}
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (engine->id_update) {
|
||||
engine->id_update(data, &scene->world->id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void drw_engines_cache_populate(blender::draw::ObjectRef &ref)
|
||||
@@ -972,11 +973,13 @@ static void drw_engines_cache_populate(blender::draw::ObjectRef &ref)
|
||||
drw_batch_cache_validate(ref.object);
|
||||
}
|
||||
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (engine->cache_populate) {
|
||||
engine->cache_populate(data, ref);
|
||||
}
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (engine->cache_populate) {
|
||||
engine->cache_populate(data, ref);
|
||||
}
|
||||
});
|
||||
|
||||
/* TODO: in the future it would be nice to generate once for all viewports.
|
||||
* But we need threaded DRW manager first. */
|
||||
@@ -991,56 +994,63 @@ static void drw_engines_cache_populate(blender::draw::ObjectRef &ref)
|
||||
|
||||
static void drw_engines_cache_finish()
|
||||
{
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (engine->cache_finish) {
|
||||
engine->cache_finish(data);
|
||||
}
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (engine->cache_finish) {
|
||||
engine->cache_finish(data);
|
||||
}
|
||||
});
|
||||
|
||||
DRW_manager_end_sync();
|
||||
}
|
||||
|
||||
static void drw_engines_draw_scene()
|
||||
{
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (engine->draw_scene) {
|
||||
GPU_debug_group_begin(engine->idname);
|
||||
engine->draw_scene(data);
|
||||
/* Restore for next engine */
|
||||
if (DRW_state_is_fbo()) {
|
||||
GPU_framebuffer_bind(drw_get().default_framebuffer());
|
||||
}
|
||||
GPU_debug_group_end();
|
||||
}
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (engine->draw_scene) {
|
||||
GPU_debug_group_begin(engine->idname);
|
||||
engine->draw_scene(data);
|
||||
/* Restore for next engine */
|
||||
if (DRW_state_is_fbo()) {
|
||||
GPU_framebuffer_bind(ctx.default_framebuffer());
|
||||
}
|
||||
GPU_debug_group_end();
|
||||
}
|
||||
});
|
||||
/* Reset state after drawing */
|
||||
blender::draw::command::StateSet::set();
|
||||
}
|
||||
|
||||
static void drw_engines_draw_text()
|
||||
{
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (data->text_draw_cache) {
|
||||
DRW_text_cache_draw(
|
||||
data->text_draw_cache, drw_get().draw_ctx.region, drw_get().draw_ctx.v3d);
|
||||
}
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType * /*engine*/) {
|
||||
if (data->text_draw_cache) {
|
||||
DRW_text_cache_draw(data->text_draw_cache, ctx.draw_ctx.region, ctx.draw_ctx.v3d);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height)
|
||||
{
|
||||
DRW_ENABLED_ENGINE_ITER (drw_get().view_data_active, engine, data) {
|
||||
if (data->info[0] != '\0') {
|
||||
const char *buf_step = IFACE_(data->info);
|
||||
do {
|
||||
const char *buf = buf_step;
|
||||
buf_step = BLI_strchr_or_end(buf, '\n');
|
||||
const int buf_len = buf_step - buf;
|
||||
*yoffset -= line_height;
|
||||
BLF_draw_default(xoffset, *yoffset, 0.0f, buf, buf_len);
|
||||
} while (*buf_step ? ((void)buf_step++, true) : false);
|
||||
}
|
||||
}
|
||||
DRWContext &ctx = drw_get();
|
||||
ctx.view_data_active->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType * /*engine*/) {
|
||||
if (data->info[0] != '\0') {
|
||||
const char *buf_step = IFACE_(data->info);
|
||||
do {
|
||||
const char *buf = buf_step;
|
||||
buf_step = BLI_strchr_or_end(buf, '\n');
|
||||
const int buf_len = buf_step - buf;
|
||||
*yoffset -= line_height;
|
||||
BLF_draw_default(xoffset, *yoffset, 0.0f, buf, buf_len);
|
||||
} while (*buf_step ? ((void)buf_step++, true) : false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void use_drw_engine(DrawEngineType *engine)
|
||||
@@ -1708,6 +1718,7 @@ static void DRW_render_gpencil_to_image(RenderEngine *engine,
|
||||
const rcti *rect)
|
||||
{
|
||||
DrawEngineType *draw_engine = &draw_engine_gpencil_type;
|
||||
|
||||
if (draw_engine->render_to_image) {
|
||||
ViewportEngineData *gpdata = DRW_view_data_engine_data_get_ensure(drw_get().view_data_active,
|
||||
draw_engine);
|
||||
@@ -2785,17 +2796,6 @@ bool DRW_engine_render_support(DrawEngineType *draw_engine_type)
|
||||
return draw_engine_type->render_to_image;
|
||||
}
|
||||
|
||||
void DRW_engine_register(DrawEngineType *draw_engine_type)
|
||||
{
|
||||
DRWRegisteredDrawEngine *draw_engine = static_cast<DRWRegisteredDrawEngine *>(
|
||||
MEM_mallocN(sizeof(DRWRegisteredDrawEngine), __func__));
|
||||
draw_engine->draw_engine = draw_engine_type;
|
||||
draw_engine->index = g_registered_engines.len;
|
||||
|
||||
BLI_addtail(&g_registered_engines.engines, draw_engine);
|
||||
g_registered_engines.len = BLI_listbase_count(&g_registered_engines.engines);
|
||||
}
|
||||
|
||||
void DRW_engines_register()
|
||||
{
|
||||
using namespace blender::draw;
|
||||
@@ -2803,19 +2803,6 @@ void DRW_engines_register()
|
||||
|
||||
RE_engines_register(&DRW_engine_viewport_workbench_type);
|
||||
|
||||
DRW_engine_register(&draw_engine_gpencil_type);
|
||||
|
||||
DRW_engine_register(&draw_engine_overlay_next_type);
|
||||
DRW_engine_register(&draw_engine_select_next_type);
|
||||
DRW_engine_register(&draw_engine_select_type);
|
||||
DRW_engine_register(&draw_engine_compositor_type);
|
||||
#ifdef WITH_DRAW_DEBUG
|
||||
DRW_engine_register(&draw_engine_debug_select_type);
|
||||
#endif
|
||||
|
||||
DRW_engine_register(&draw_engine_image_type);
|
||||
DRW_engine_register(DRW_engine_viewport_external_type.draw_engine);
|
||||
|
||||
/* setup callbacks */
|
||||
{
|
||||
BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag;
|
||||
@@ -2846,31 +2833,19 @@ void DRW_engines_register()
|
||||
}
|
||||
}
|
||||
|
||||
static void drw_registered_engines_free()
|
||||
{
|
||||
DRWRegisteredDrawEngine *next;
|
||||
for (DRWRegisteredDrawEngine *type =
|
||||
static_cast<DRWRegisteredDrawEngine *>(g_registered_engines.engines.first);
|
||||
type;
|
||||
type = next)
|
||||
{
|
||||
next = static_cast<DRWRegisteredDrawEngine *>(type->next);
|
||||
BLI_remlink(&R_engines, type);
|
||||
|
||||
if (type->draw_engine->engine_free) {
|
||||
type->draw_engine->engine_free();
|
||||
}
|
||||
MEM_freeN(type);
|
||||
}
|
||||
|
||||
BLI_listbase_clear(&g_registered_engines.engines);
|
||||
g_registered_engines.len = 0;
|
||||
}
|
||||
|
||||
void DRW_engines_free()
|
||||
{
|
||||
using namespace blender::draw;
|
||||
drw_registered_engines_free();
|
||||
|
||||
DRW_engine_viewport_eevee_next_type.draw_engine->engine_free();
|
||||
DRW_engine_viewport_workbench_type.draw_engine->engine_free();
|
||||
draw_engine_gpencil_type.engine_free();
|
||||
draw_engine_image_type.engine_free();
|
||||
draw_engine_overlay_next_type.engine_free();
|
||||
#ifdef WITH_DRAW_DEBUG
|
||||
draw_engine_debug_select_type.engine_free();
|
||||
#endif
|
||||
draw_engine_select_type.engine_free();
|
||||
|
||||
if (system_gpu_context == nullptr) {
|
||||
/* Nothing has been setup. Nothing to clear.
|
||||
|
||||
@@ -40,22 +40,6 @@ class View;
|
||||
struct GPUMaterial;
|
||||
struct GSet;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Data Structure
|
||||
*
|
||||
* Data structure to for registered draw engines that can store draw manager
|
||||
* specific data.
|
||||
* \{ */
|
||||
|
||||
typedef struct DRWRegisteredDrawEngine {
|
||||
void /*DRWRegisteredDrawEngine*/ *next, *prev;
|
||||
DrawEngineType *draw_engine;
|
||||
/** Index of the type in the lists. Index is used for dupli data. */
|
||||
int index;
|
||||
} DRWRegisteredDrawEngine;
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Memory Pools
|
||||
* \{ */
|
||||
|
||||
@@ -23,55 +23,39 @@
|
||||
#include "draw_manager_c.hh"
|
||||
#include "draw_view_data.hh"
|
||||
|
||||
#include "engines/compositor/compositor_engine.h"
|
||||
#include "engines/eevee_next/eevee_engine.h"
|
||||
#include "engines/external/external_engine.h"
|
||||
#include "engines/gpencil/gpencil_engine.h"
|
||||
#include "engines/image/image_engine.h"
|
||||
#include "engines/overlay/overlay_engine.h"
|
||||
#include "engines/select/select_engine.hh"
|
||||
#include "engines/workbench/workbench_engine.h"
|
||||
|
||||
using namespace blender;
|
||||
|
||||
struct DRWViewData {
|
||||
DefaultFramebufferList dfbl = {};
|
||||
DefaultTextureList dtxl = {};
|
||||
/** True indicates the textures inside dtxl are from the viewport and should not be freed. */
|
||||
bool from_viewport = false;
|
||||
/** Common size for texture in the engines texture list.
|
||||
* We free all texture lists if it changes. */
|
||||
int2 texture_list_size = {0, 0};
|
||||
|
||||
double cache_time = 0.0;
|
||||
|
||||
Vector<ViewportEngineData> engines;
|
||||
Vector<ViewportEngineData *> enabled_engines;
|
||||
|
||||
/* Stores passes needed by the viewport compositor. Engines are expected to populate those in
|
||||
* every redraw using calls to the DRW_viewport_pass_texture_get function. The compositor can
|
||||
* then call the same function to retrieve the passes it needs, which are expected to be
|
||||
* initialized. Those textures are release when view data is reset. */
|
||||
Map<std::string, std::unique_ptr<draw::TextureFromPool>> viewport_compositor_passes;
|
||||
|
||||
/** New per view/viewport manager. Null if not supported by current hardware. */
|
||||
draw::Manager *manager = nullptr;
|
||||
|
||||
DRWViewData()
|
||||
{
|
||||
manager = new draw::Manager();
|
||||
};
|
||||
|
||||
~DRWViewData()
|
||||
{
|
||||
delete manager;
|
||||
};
|
||||
DRWViewData::DRWViewData()
|
||||
: eevee(DRW_engine_viewport_eevee_next_type.draw_engine),
|
||||
workbench(DRW_engine_viewport_workbench_type.draw_engine),
|
||||
external(&draw_engine_external_type),
|
||||
image(&draw_engine_image_type),
|
||||
grease_pencil(&draw_engine_gpencil_type),
|
||||
overlay(&draw_engine_overlay_next_type),
|
||||
object_select(&draw_engine_select_next_type),
|
||||
edit_select(&draw_engine_select_type),
|
||||
#ifdef WITH_DRAW_DEBUG
|
||||
edit_select_debug(DRW_engine_viewport_select_type.draw_engine),
|
||||
#endif
|
||||
compositor(&draw_engine_compositor_type)
|
||||
{
|
||||
manager = new draw::Manager();
|
||||
};
|
||||
|
||||
DRWViewData *DRW_view_data_create(ListBase *engine_types)
|
||||
DRWViewData::~DRWViewData()
|
||||
{
|
||||
const int engine_types_len = BLI_listbase_count(engine_types);
|
||||
|
||||
DRWViewData *view_data = new DRWViewData();
|
||||
view_data->engines.reserve(engine_types_len);
|
||||
LISTBASE_FOREACH (DRWRegisteredDrawEngine *, type, engine_types) {
|
||||
ViewportEngineData engine = {};
|
||||
engine.engine_type = type;
|
||||
view_data->engines.append(engine);
|
||||
}
|
||||
return view_data;
|
||||
}
|
||||
this->clear(true);
|
||||
delete manager;
|
||||
};
|
||||
|
||||
draw::TextureFromPool &DRW_view_data_pass_texture_get(DRWViewData *view_data,
|
||||
const char *pass_name)
|
||||
@@ -121,7 +105,7 @@ void DRW_view_data_default_lists_from_viewport(DRWViewData *view_data, GPUViewpo
|
||||
|
||||
static void draw_viewport_engines_data_clear(ViewportEngineData *data, bool clear_instance_data)
|
||||
{
|
||||
DrawEngineType *engine_type = data->engine_type->draw_engine;
|
||||
DrawEngineType *engine_type = data->draw_engine;
|
||||
|
||||
if (clear_instance_data && data->instance_data) {
|
||||
BLI_assert(engine_type->instance_free != nullptr);
|
||||
@@ -135,61 +119,57 @@ static void draw_viewport_engines_data_clear(ViewportEngineData *data, bool clea
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_view_data_clear(DRWViewData *view_data, bool free_instance_data)
|
||||
void DRWViewData::clear(bool free_instance_data)
|
||||
{
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(view_data->dfbl.default_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(view_data->dfbl.overlay_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(view_data->dfbl.in_front_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(view_data->dfbl.color_only_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(view_data->dfbl.depth_only_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(view_data->dfbl.overlay_only_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(this->dfbl.default_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(this->dfbl.overlay_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(this->dfbl.in_front_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(this->dfbl.color_only_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(this->dfbl.depth_only_fb);
|
||||
GPU_FRAMEBUFFER_FREE_SAFE(this->dfbl.overlay_only_fb);
|
||||
|
||||
if (!view_data->from_viewport) {
|
||||
GPU_TEXTURE_FREE_SAFE(view_data->dtxl.color);
|
||||
GPU_TEXTURE_FREE_SAFE(view_data->dtxl.color_overlay);
|
||||
GPU_TEXTURE_FREE_SAFE(view_data->dtxl.depth);
|
||||
if (!this->from_viewport) {
|
||||
GPU_TEXTURE_FREE_SAFE(this->dtxl.color);
|
||||
GPU_TEXTURE_FREE_SAFE(this->dtxl.color_overlay);
|
||||
GPU_TEXTURE_FREE_SAFE(this->dtxl.depth);
|
||||
}
|
||||
GPU_TEXTURE_FREE_SAFE(view_data->dtxl.depth_in_front);
|
||||
GPU_TEXTURE_FREE_SAFE(this->dtxl.depth_in_front);
|
||||
|
||||
for (ViewportEngineData &engine : view_data->engines) {
|
||||
draw_viewport_engines_data_clear(&engine, free_instance_data);
|
||||
}
|
||||
foreach_engine([&](ViewportEngineData *data, DrawEngineType * /*engine*/) {
|
||||
draw_viewport_engines_data_clear(data, free_instance_data);
|
||||
});
|
||||
}
|
||||
|
||||
void DRW_view_data_free(DRWViewData *view_data)
|
||||
void DRWViewData::texture_list_size_validate(const blender::int2 &size)
|
||||
{
|
||||
draw_view_data_clear(view_data, true);
|
||||
delete view_data;
|
||||
}
|
||||
|
||||
void DRW_view_data_texture_list_size_validate(DRWViewData *view_data, const int size[2])
|
||||
{
|
||||
if (view_data->texture_list_size != int2(size)) {
|
||||
draw_view_data_clear(view_data, false);
|
||||
copy_v2_v2_int(view_data->texture_list_size, size);
|
||||
if (this->texture_list_size != size) {
|
||||
this->clear(false);
|
||||
copy_v2_v2_int(this->texture_list_size, size);
|
||||
}
|
||||
}
|
||||
|
||||
ViewportEngineData *DRW_view_data_engine_data_get_ensure(DRWViewData *view_data,
|
||||
DrawEngineType *engine_type)
|
||||
{
|
||||
for (ViewportEngineData &engine : view_data->engines) {
|
||||
if (engine.engine_type->draw_engine == engine_type) {
|
||||
return &engine;
|
||||
ViewportEngineData *result = nullptr;
|
||||
view_data->foreach_engine([&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (engine_type == engine) {
|
||||
result = data;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void DRW_view_data_use_engine(DRWViewData *view_data, DrawEngineType *engine_type)
|
||||
{
|
||||
ViewportEngineData *engine = DRW_view_data_engine_data_get_ensure(view_data, engine_type);
|
||||
view_data->enabled_engines.append(engine);
|
||||
engine->used = true;
|
||||
}
|
||||
|
||||
void DRW_view_data_reset(DRWViewData *view_data)
|
||||
{
|
||||
view_data->enabled_engines.clear();
|
||||
view_data->foreach_enabled_engine(
|
||||
[&](ViewportEngineData *data, DrawEngineType * /*engine*/) { data->used = false; });
|
||||
|
||||
for (std::unique_ptr<draw::TextureFromPool> &texture :
|
||||
view_data->viewport_compositor_passes.values())
|
||||
@@ -201,26 +181,20 @@ void DRW_view_data_reset(DRWViewData *view_data)
|
||||
|
||||
void DRW_view_data_free_unused(DRWViewData *view_data)
|
||||
{
|
||||
for (ViewportEngineData &engine : view_data->engines) {
|
||||
if (view_data->enabled_engines.first_index_of_try(&engine) == -1) {
|
||||
draw_viewport_engines_data_clear(&engine, false);
|
||||
view_data->foreach_engine([&](ViewportEngineData *data, DrawEngineType * /*engine*/) {
|
||||
if (data->used == false) {
|
||||
draw_viewport_engines_data_clear(data, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DRW_view_data_engines_view_update(DRWViewData *view_data)
|
||||
{
|
||||
for (ViewportEngineData &engine_data : view_data->engines) {
|
||||
DrawEngineType *draw_engine = engine_data.engine_type->draw_engine;
|
||||
if (draw_engine->view_update) {
|
||||
draw_engine->view_update(&engine_data);
|
||||
view_data->foreach_enabled_engine([&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (engine->view_update) {
|
||||
engine->view_update(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double *DRW_view_data_cache_time_get(DRWViewData *view_data)
|
||||
{
|
||||
return &view_data->cache_time;
|
||||
});
|
||||
}
|
||||
|
||||
DefaultFramebufferList *DRW_view_data_default_framebuffer_list_get(DRWViewData *view_data)
|
||||
@@ -233,22 +207,6 @@ DefaultTextureList *DRW_view_data_default_texture_list_get(DRWViewData *view_dat
|
||||
return &view_data->dtxl;
|
||||
}
|
||||
|
||||
void DRW_view_data_enabled_engine_iter_begin(DRWEngineIterator *iterator, DRWViewData *view_data)
|
||||
{
|
||||
iterator->id = 0;
|
||||
iterator->end = view_data->enabled_engines.size();
|
||||
iterator->engines = view_data->enabled_engines.data();
|
||||
}
|
||||
|
||||
ViewportEngineData *DRW_view_data_enabled_engine_iter_step(DRWEngineIterator *iterator)
|
||||
{
|
||||
if (iterator->id >= iterator->end) {
|
||||
return nullptr;
|
||||
}
|
||||
ViewportEngineData *engine = iterator->engines[iterator->id++];
|
||||
return engine;
|
||||
}
|
||||
|
||||
draw::Manager *DRW_manager_get()
|
||||
{
|
||||
BLI_assert(drw_get().view_data_active->manager);
|
||||
|
||||
@@ -11,15 +11,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "DRW_render.hh"
|
||||
#include "draw_manager_c.hh"
|
||||
|
||||
#define GPU_INFO_SIZE 512 /* IMA_MAX_RENDER_TEXT_SIZE */
|
||||
|
||||
namespace blender::draw {
|
||||
class TextureFromPool;
|
||||
class Manager;
|
||||
} // namespace blender::draw
|
||||
|
||||
struct DRWRegisteredDrawEngine;
|
||||
struct DRWTextStore;
|
||||
struct DrawEngineType;
|
||||
struct DRWTextStore;
|
||||
struct GPUFrameBuffer;
|
||||
struct GPUTexture;
|
||||
struct GPUViewport;
|
||||
@@ -27,18 +33,22 @@ struct ListBase;
|
||||
|
||||
struct ViewportEngineData {
|
||||
/* Not owning pointer to the draw engine. */
|
||||
DRWRegisteredDrawEngine *engine_type;
|
||||
DrawEngineType *draw_engine;
|
||||
|
||||
/**
|
||||
* \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;
|
||||
void *instance_data = nullptr;
|
||||
|
||||
char info[GPU_INFO_SIZE];
|
||||
char info[GPU_INFO_SIZE] = {'\0'};
|
||||
|
||||
/* we may want to put this elsewhere */
|
||||
DRWTextStore *text_draw_cache;
|
||||
DRWTextStore *text_draw_cache = nullptr;
|
||||
|
||||
bool used = false;
|
||||
|
||||
ViewportEngineData(DrawEngineType *engine_type) : draw_engine(engine_type) {}
|
||||
};
|
||||
|
||||
struct ViewportEngineData_Info {
|
||||
@@ -65,15 +75,84 @@ struct DefaultTextureList {
|
||||
GPUTexture *depth_in_front;
|
||||
};
|
||||
|
||||
struct DRWViewData;
|
||||
struct DRWViewData {
|
||||
public:
|
||||
DefaultFramebufferList dfbl = {};
|
||||
DefaultTextureList dtxl = {};
|
||||
/** True indicates the textures inside dtxl are from the viewport and should not be freed. */
|
||||
bool from_viewport = false;
|
||||
/** Common size for texture in the engines texture list.
|
||||
* We free all texture lists if it changes. */
|
||||
blender::int2 texture_list_size = {0, 0};
|
||||
|
||||
/**
|
||||
* Creates a view data with all possible engines type for this view.
|
||||
*
|
||||
* `engine_types` contains #DRWRegisteredDrawEngine.
|
||||
*/
|
||||
DRWViewData *DRW_view_data_create(ListBase *engine_types);
|
||||
void DRW_view_data_free(DRWViewData *view_data);
|
||||
/* Engines running for this viewport. nullptr if not enabled. */
|
||||
/* TODO(fclem): Directly use each engine class. */
|
||||
ViewportEngineData eevee;
|
||||
ViewportEngineData workbench;
|
||||
ViewportEngineData external;
|
||||
ViewportEngineData image;
|
||||
ViewportEngineData grease_pencil;
|
||||
ViewportEngineData overlay;
|
||||
ViewportEngineData object_select;
|
||||
ViewportEngineData edit_select;
|
||||
#ifdef WITH_DRAW_DEBUG
|
||||
ViewportEngineData edit_select_debug;
|
||||
#endif
|
||||
ViewportEngineData compositor;
|
||||
|
||||
/* Stores passes needed by the viewport compositor. Engines are expected to populate those in
|
||||
* every redraw using calls to the DRW_viewport_pass_texture_get function. The compositor can
|
||||
* then call the same function to retrieve the passes it needs, which are expected to be
|
||||
* initialized. Those textures are release when view data is reset. */
|
||||
blender::Map<std::string, std::unique_ptr<blender::draw::TextureFromPool>>
|
||||
viewport_compositor_passes;
|
||||
|
||||
/** New per view/viewport manager. Null if not supported by current hardware. */
|
||||
blender::draw::Manager *manager = nullptr;
|
||||
|
||||
public:
|
||||
DRWViewData();
|
||||
~DRWViewData();
|
||||
|
||||
void texture_list_size_validate(const blender::int2 &size);
|
||||
|
||||
template<typename CallbackT> void foreach_engine(CallbackT callback)
|
||||
{
|
||||
/* IMPORTANT: Order here defines the draw order. */
|
||||
|
||||
/* Render engines. Output to the render result framebuffer. Mutually exclusive. */
|
||||
callback(&eevee, eevee.draw_engine);
|
||||
callback(&workbench, workbench.draw_engine);
|
||||
callback(&external, external.draw_engine);
|
||||
callback(&image, image.draw_engine);
|
||||
#ifdef WITH_DRAW_DEBUG
|
||||
callback(&edit_select_debug, edit_select_debug.draw_engine);
|
||||
#endif
|
||||
/* Grease pencil. Merge its output to the render result framebuffer. */
|
||||
callback(&grease_pencil, grease_pencil.draw_engine);
|
||||
/* GPU compositor. Processes render result and output to the render result framebuffer. */
|
||||
callback(&compositor, compositor.draw_engine);
|
||||
/* Overlays. Draw on a separate overlay framebuffer. Can read render result. */
|
||||
callback(&overlay, overlay.draw_engine);
|
||||
|
||||
/* Selection. Are always enabled alone and have no interaction with other engines. */
|
||||
callback(&object_select, object_select.draw_engine);
|
||||
callback(&edit_select, edit_select.draw_engine);
|
||||
}
|
||||
|
||||
template<typename CallbackT> void foreach_enabled_engine(CallbackT callback)
|
||||
{
|
||||
foreach_engine([&](ViewportEngineData *data, DrawEngineType *engine) {
|
||||
if (!data->used) {
|
||||
return;
|
||||
}
|
||||
callback(data, engine);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
void clear(bool free_instance_data);
|
||||
};
|
||||
|
||||
/* Returns a TextureFromPool stored in the given view data for the pass identified by the given
|
||||
* pass name. Engines should call this function for each of the passes needed by the viewport
|
||||
@@ -83,32 +162,11 @@ blender::draw::TextureFromPool &DRW_view_data_pass_texture_get(DRWViewData *view
|
||||
const char *pass_name);
|
||||
|
||||
void DRW_view_data_default_lists_from_viewport(DRWViewData *view_data, GPUViewport *viewport);
|
||||
void DRW_view_data_texture_list_size_validate(DRWViewData *view_data, const int size[2]);
|
||||
ViewportEngineData *DRW_view_data_engine_data_get_ensure(DRWViewData *view_data,
|
||||
DrawEngineType *engine_type);
|
||||
void DRW_view_data_use_engine(DRWViewData *view_data, DrawEngineType *engine_type);
|
||||
void DRW_view_data_reset(DRWViewData *view_data);
|
||||
void DRW_view_data_free_unused(DRWViewData *view_data);
|
||||
void DRW_view_data_engines_view_update(DRWViewData *view_data);
|
||||
double *DRW_view_data_cache_time_get(DRWViewData *view_data);
|
||||
DefaultFramebufferList *DRW_view_data_default_framebuffer_list_get(DRWViewData *view_data);
|
||||
DefaultTextureList *DRW_view_data_default_texture_list_get(DRWViewData *view_data);
|
||||
|
||||
struct DRWEngineIterator {
|
||||
int id, end;
|
||||
ViewportEngineData **engines;
|
||||
};
|
||||
|
||||
/* Iterate over used engines of this view_data. */
|
||||
void DRW_view_data_enabled_engine_iter_begin(DRWEngineIterator *iterator, DRWViewData *view_data);
|
||||
ViewportEngineData *DRW_view_data_enabled_engine_iter_step(DRWEngineIterator *iterator);
|
||||
|
||||
#define DRW_ENABLED_ENGINE_ITER(view_data_, engine_, data_) \
|
||||
DRWEngineIterator iterator; \
|
||||
ViewportEngineData *data_; \
|
||||
DrawEngineType *engine_; \
|
||||
DRW_view_data_enabled_engine_iter_begin(&iterator, view_data_); \
|
||||
/* WATCH Comma operator trickery ahead! This tests engine_ == nullptr. */ \
|
||||
while ((data_ = DRW_view_data_enabled_engine_iter_step(&iterator), \
|
||||
engine_ = (data_ != nullptr) ? (DrawEngineType *)data_->engine_type->draw_engine : \
|
||||
nullptr))
|
||||
|
||||
@@ -81,9 +81,6 @@ void RE_engines_exit()
|
||||
|
||||
void RE_engines_register(RenderEngineType *render_type)
|
||||
{
|
||||
if (render_type->draw_engine) {
|
||||
DRW_engine_register(render_type->draw_engine);
|
||||
}
|
||||
BLI_addtail(&R_engines, render_type);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user