Files
test2/source/blender/draw/intern/draw_view_data.cc
Brecht Van Lommel c7a33a62a2 Cleanup: Directly include DNA_userdef_types.h and BLI_listbase.h
Instead of relying on them being included indirectly.

Pull Request: https://projects.blender.org/blender/blender/pulls/134406
2025-02-12 23:01:08 +01:00

278 lines
8.5 KiB
C++

/* SPDX-FileCopyrightText: 2021 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup draw
*/
#include <memory>
#include "BLI_listbase.h"
#include "BLI_vector.hh"
#include "GPU_viewport.hh"
#include "DRW_gpu_wrapper.hh"
#include "DRW_render.hh"
#include "draw_manager_text.hh"
#include "draw_manager.hh"
#include "draw_manager_c.hh"
#include "draw_view_data.hh"
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 *DRW_view_data_create(ListBase *engine_types)
{
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;
}
draw::TextureFromPool &DRW_view_data_pass_texture_get(DRWViewData *view_data,
const char *pass_name)
{
return *view_data->viewport_compositor_passes.lookup_or_add_cb(
pass_name, [&]() { return std::make_unique<draw::TextureFromPool>(pass_name); });
}
void DRW_view_data_default_lists_from_viewport(DRWViewData *view_data, GPUViewport *viewport)
{
int active_view = GPU_viewport_active_view_get(viewport);
view_data->from_viewport = true;
DefaultFramebufferList *dfbl = &view_data->dfbl;
DefaultTextureList *dtxl = &view_data->dtxl;
/* Depth texture is shared between both stereo views. */
dtxl->depth = GPU_viewport_depth_texture(viewport);
dtxl->color = GPU_viewport_color_texture(viewport, active_view);
dtxl->color_overlay = GPU_viewport_overlay_texture(viewport, active_view);
GPU_framebuffer_ensure_config(&dfbl->default_fb,
{
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(dtxl->color),
});
GPU_framebuffer_ensure_config(&dfbl->overlay_fb,
{
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
});
GPU_framebuffer_ensure_config(&dfbl->depth_only_fb,
{
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_NONE,
});
GPU_framebuffer_ensure_config(&dfbl->color_only_fb,
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(dtxl->color),
});
GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb,
{
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
});
}
static void draw_viewport_engines_data_clear(ViewportEngineData *data, bool clear_instance_data)
{
DrawEngineType *engine_type = data->engine_type->draw_engine;
if (clear_instance_data && data->instance_data) {
BLI_assert(engine_type->instance_free != nullptr);
engine_type->instance_free(data->instance_data);
data->instance_data = nullptr;
}
if (data->text_draw_cache) {
DRW_text_cache_destroy(data->text_draw_cache);
data->text_draw_cache = nullptr;
}
}
static void draw_view_data_clear(DRWViewData *view_data, 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);
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);
}
GPU_TEXTURE_FREE_SAFE(view_data->dtxl.depth_in_front);
for (ViewportEngineData &engine : view_data->engines) {
draw_viewport_engines_data_clear(&engine, free_instance_data);
}
}
void DRW_view_data_free(DRWViewData *view_data)
{
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);
}
}
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;
}
}
return nullptr;
}
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);
}
void DRW_view_data_reset(DRWViewData *view_data)
{
view_data->enabled_engines.clear();
for (std::unique_ptr<draw::TextureFromPool> &texture :
view_data->viewport_compositor_passes.values())
{
texture->release();
}
view_data->viewport_compositor_passes.clear();
}
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);
}
}
}
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);
}
}
}
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)
{
return &view_data->dfbl;
}
DefaultTextureList *DRW_view_data_default_texture_list_get(DRWViewData *view_data)
{
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(DST.view_data_active->manager);
return DST.view_data_active->manager;
}
draw::ObjectRef DRW_object_ref_get(Object *object)
{
BLI_assert(DST.view_data_active->manager);
return {object, DST.dupli_source, DST.dupli_parent, draw::ResourceHandle(0)};
}
void DRW_manager_begin_sync()
{
if (DST.view_data_active->manager == nullptr) {
return;
}
DST.view_data_active->manager->begin_sync();
}
void DRW_manager_end_sync()
{
if (DST.view_data_active->manager == nullptr) {
return;
}
DST.view_data_active->manager->end_sync();
}