Blender V4.3
draw_view_data.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <memory>
10
11#include "BLI_vector.hh"
12
13#include "GPU_capabilities.hh"
14#include "GPU_viewport.hh"
15
16#include "DRW_gpu_wrapper.hh"
17#include "DRW_render.hh"
18
19#include "draw_instance_data.hh"
20
21#include "draw_manager_text.hh"
22
23#include "draw_manager.hh"
24#include "draw_manager_c.hh"
25#include "draw_view_data.hh"
26
27using namespace blender;
28
33 bool from_viewport = false;
36 int texture_list_size[2] = {0, 0};
37
38 double cache_time = 0.0;
39
42
43 /* Stores passes needed by the viewport compositor. Engines are expected to populate those in
44 * every redraw using calls to the DRW_viewport_pass_texture_get function. The compositor can
45 * then call the same function to retrieve the passes it needs, which are expected to be
46 * initialized. Those textures are release when view data is reset. */
48
51
53 {
54 manager = new draw::Manager();
55 };
56
58 {
59 delete manager;
60 };
61};
62
64{
65 const int engine_types_len = BLI_listbase_count(engine_types);
66
67 DRWViewData *view_data = new DRWViewData();
68 view_data->engines.reserve(engine_types_len);
69 LISTBASE_FOREACH (DRWRegisteredDrawEngine *, type, engine_types) {
70 ViewportEngineData engine = {};
71 engine.engine_type = type;
72 view_data->engines.append(engine);
73 }
74 return view_data;
75}
76
78 const char *pass_name)
79{
81 pass_name, [&]() { return std::make_unique<draw::TextureFromPool>(pass_name); });
82}
83
85{
86 int active_view = GPU_viewport_active_view_get(viewport);
87 view_data->from_viewport = true;
88
89 DefaultFramebufferList *dfbl = &view_data->dfbl;
90 DefaultTextureList *dtxl = &view_data->dtxl;
91 /* Depth texture is shared between both stereo views. */
92 dtxl->depth = GPU_viewport_depth_texture(viewport);
93 dtxl->color = GPU_viewport_color_texture(viewport, active_view);
94 dtxl->color_overlay = GPU_viewport_overlay_texture(viewport, active_view);
95
97 {
98 GPU_ATTACHMENT_TEXTURE(dtxl->depth),
99 GPU_ATTACHMENT_TEXTURE(dtxl->color),
100 });
102 {
103 GPU_ATTACHMENT_TEXTURE(dtxl->depth),
104 GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
105 });
107 {
108 GPU_ATTACHMENT_TEXTURE(dtxl->depth),
109 GPU_ATTACHMENT_NONE,
110 });
112 {
113 GPU_ATTACHMENT_NONE,
114 GPU_ATTACHMENT_TEXTURE(dtxl->color),
115 });
117 {
118 GPU_ATTACHMENT_NONE,
119 GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay),
120 });
121}
122
123static void draw_viewport_engines_data_clear(ViewportEngineData *data, bool clear_instance_data)
124{
125 DrawEngineType *engine_type = data->engine_type->draw_engine;
126 const DrawEngineDataSize *data_size = engine_type->vedata_size;
127
128 for (int i = 0; data->fbl && i < data_size->fbl_len; i++) {
129 GPU_FRAMEBUFFER_FREE_SAFE(data->fbl->framebuffers[i]);
130 }
131 for (int i = 0; data->txl && i < data_size->txl_len; i++) {
132 GPU_TEXTURE_FREE_SAFE(data->txl->textures[i]);
133 }
134 for (int i = 0; data->stl && i < data_size->stl_len; i++) {
135 MEM_SAFE_FREE(data->stl->storage[i]);
136 }
137
138 if (clear_instance_data && data->instance_data) {
139 BLI_assert(engine_type->instance_free != nullptr);
140 engine_type->instance_free(data->instance_data);
141 data->instance_data = nullptr;
142 }
143
144 MEM_SAFE_FREE(data->fbl);
145 MEM_SAFE_FREE(data->txl);
146 MEM_SAFE_FREE(data->psl);
147 MEM_SAFE_FREE(data->stl);
148
149 if (data->text_draw_cache) {
150 DRW_text_cache_destroy(data->text_draw_cache);
151 data->text_draw_cache = nullptr;
152 }
153}
154
155static void draw_view_data_clear(DRWViewData *view_data, bool free_instance_data)
156{
163
164 if (!view_data->from_viewport) {
165 GPU_TEXTURE_FREE_SAFE(view_data->dtxl.color);
167 GPU_TEXTURE_FREE_SAFE(view_data->dtxl.depth);
168 }
170
171 for (ViewportEngineData &engine : view_data->engines) {
172 draw_viewport_engines_data_clear(&engine, free_instance_data);
173 }
174}
175
177{
178 draw_view_data_clear(view_data, true);
179 delete view_data;
180}
181
182void DRW_view_data_texture_list_size_validate(DRWViewData *view_data, const int size[2])
183{
184 if (!equals_v2v2_int(view_data->texture_list_size, size)) {
185 draw_view_data_clear(view_data, false);
186 copy_v2_v2_int(view_data->texture_list_size, size);
187 }
188}
189
191 DrawEngineType *engine_type)
192{
193 for (ViewportEngineData &engine : view_data->engines) {
194 if (engine.engine_type->draw_engine == engine_type) {
195 if (engine.fbl == nullptr) {
196 const DrawEngineDataSize *data_size = engine_type->vedata_size;
197 engine.fbl = (FramebufferList *)MEM_calloc_arrayN(
198 data_size->fbl_len, sizeof(GPUFrameBuffer *), "FramebufferList");
199 engine.txl = (TextureList *)MEM_calloc_arrayN(
200 data_size->txl_len, sizeof(GPUTexture *), "TextureList");
201 engine.psl = (PassList *)MEM_calloc_arrayN(
202 data_size->psl_len, sizeof(DRWPass *), "PassList");
203 engine.stl = (StorageList *)MEM_calloc_arrayN(
204 data_size->stl_len, sizeof(void *), "StorageList");
205 }
206 return &engine;
207 }
208 }
209 return nullptr;
210}
211
213{
214 ViewportEngineData *engine = DRW_view_data_engine_data_get_ensure(view_data, engine_type);
215 view_data->enabled_engines.append(engine);
216}
217
219{
220 view_data->enabled_engines.clear();
221
222 for (std::unique_ptr<draw::TextureFromPool> &texture :
224 {
225 texture->release();
226 }
228}
229
231{
232 for (ViewportEngineData &engine : view_data->engines) {
233 if (view_data->enabled_engines.first_index_of_try(&engine) == -1) {
234 draw_viewport_engines_data_clear(&engine, false);
235 }
236 }
237}
238
240{
241 for (ViewportEngineData &engine_data : view_data->engines) {
242 DrawEngineType *draw_engine = engine_data.engine_type->draw_engine;
243 if (draw_engine->view_update) {
244 draw_engine->view_update(&engine_data);
245 }
246 }
247}
248
250{
251 return &view_data->cache_time;
252}
253
258
260{
261 return &view_data->dtxl;
262}
263
265{
266 iterator->id = 0;
267 iterator->end = view_data->enabled_engines.size();
268 iterator->engines = view_data->enabled_engines.data();
269}
270
272{
273 if (iterator->id >= iterator->end) {
274 return nullptr;
275 }
276 ViewportEngineData *engine = iterator->engines[iterator->id++];
277 return engine;
278}
279
285
291
293{
294 if (DST.view_data_active->manager == nullptr) {
295 return;
296 }
297 reinterpret_cast<draw::Manager *>(DST.view_data_active->manager)->begin_sync();
298}
299
301{
302 if (DST.view_data_active->manager == nullptr) {
303 return;
304 }
305 reinterpret_cast<draw::Manager *>(DST.view_data_active->manager)->end_sync();
306}
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE bool equals_v2v2_int(const int v1[2], const int v2[2]) ATTR_WARN_UNUSED_RESULT
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
#define GPU_framebuffer_ensure_config(_fb,...)
#define GPU_TEXTURE_FREE_SAFE(texture)
GPUTexture * GPU_viewport_color_texture(GPUViewport *viewport, int view)
int GPU_viewport_active_view_get(GPUViewport *viewport)
GPUTexture * GPU_viewport_depth_texture(GPUViewport *viewport)
GPUTexture * GPU_viewport_overlay_texture(GPUViewport *viewport, int view)
#define MEM_SAFE_FREE(v)
void clear()
Definition BLI_map.hh:989
ValueIterator values() const
Definition BLI_map.hh:846
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
Definition BLI_map.hh:582
int64_t size() const
void append(const T &value)
void reserve(const int64_t min_capacity)
int64_t first_index_of_try(const T &value) const
DRWManager DST
void DRW_text_cache_destroy(DRWTextStore *dt)
void DRW_manager_end_sync()
void DRW_view_data_use_engine(DRWViewData *view_data, DrawEngineType *engine_type)
static void draw_view_data_clear(DRWViewData *view_data, bool free_instance_data)
void DRW_view_data_free(DRWViewData *view_data)
void DRW_view_data_default_lists_from_viewport(DRWViewData *view_data, GPUViewport *viewport)
DefaultFramebufferList * DRW_view_data_default_framebuffer_list_get(DRWViewData *view_data)
DefaultTextureList * DRW_view_data_default_texture_list_get(DRWViewData *view_data)
void DRW_view_data_enabled_engine_iter_begin(DRWEngineIterator *iterator, DRWViewData *view_data)
void DRW_view_data_engines_view_update(DRWViewData *view_data)
ViewportEngineData * DRW_view_data_enabled_engine_iter_step(DRWEngineIterator *iterator)
draw::TextureFromPool & DRW_view_data_pass_texture_get(DRWViewData *view_data, const char *pass_name)
double * DRW_view_data_cache_time_get(DRWViewData *view_data)
static void draw_viewport_engines_data_clear(ViewportEngineData *data, bool clear_instance_data)
DRWViewData * DRW_view_data_create(ListBase *engine_types)
draw::ObjectRef DRW_object_ref_get(Object *object)
void DRW_view_data_texture_list_size_validate(DRWViewData *view_data, const int size[2])
draw::Manager * DRW_manager_get()
void DRW_view_data_reset(DRWViewData *view_data)
void DRW_manager_begin_sync()
ViewportEngineData * DRW_view_data_engine_data_get_ensure(DRWViewData *view_data, DrawEngineType *engine_type)
void DRW_view_data_free_unused(DRWViewData *view_data)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:43
ViewportEngineData ** engines
DupliObject * dupli_source
Object * dupli_parent
DRWViewData * view_data_active
int texture_list_size[2]
draw::Manager * manager
Vector< ViewportEngineData * > enabled_engines
DefaultTextureList dtxl
DefaultFramebufferList dfbl
Vector< ViewportEngineData > engines
Map< std::string, std::unique_ptr< draw::TextureFromPool > > viewport_compositor_passes
GPUFrameBuffer * depth_only_fb
GPUFrameBuffer * overlay_fb
GPUFrameBuffer * color_only_fb
GPUFrameBuffer * in_front_fb
GPUFrameBuffer * overlay_only_fb
GPUFrameBuffer * default_fb
GPUTexture * depth_in_front
GPUTexture * color_overlay
void(* instance_free)(void *instance_data)
const DrawEngineDataSize * vedata_size
void(* view_update)(void *vedata)
DRWRegisteredDrawEngine * engine_type