Blender V4.3
draw_manager_c.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cstdio>
10
11#include "CLG_log.h"
12
13#include "BLI_alloca.h"
14#include "BLI_listbase.h"
15#include "BLI_memblock.h"
16#include "BLI_rect.h"
17#include "BLI_string.h"
18#include "BLI_task.h"
19#include "BLI_threads.h"
20
21#include "BLF_api.hh"
22
23#include "BLT_translation.hh"
24
25#include "BKE_context.hh"
26#include "BKE_curve.hh"
27#include "BKE_curves.h"
28#include "BKE_duplilist.hh"
29#include "BKE_editmesh.hh"
30#include "BKE_global.hh"
31#include "BKE_gpencil_legacy.h"
32#include "BKE_grease_pencil.h"
33#include "BKE_lattice.hh"
34#include "BKE_main.hh"
35#include "BKE_mball.hh"
36#include "BKE_mesh.hh"
37#include "BKE_modifier.hh"
38#include "BKE_object.hh"
39#include "BKE_object_types.hh"
40#include "BKE_paint.hh"
41#include "BKE_particle.h"
42#include "BKE_pointcache.h"
43#include "BKE_pointcloud.hh"
44#include "BKE_screen.hh"
46#include "BKE_viewer_path.hh"
47#include "BKE_volume.hh"
48
49#include "DNA_camera_types.h"
50#include "DNA_mesh_types.h"
51#include "DNA_userdef_types.h"
52#include "DNA_view3d_types.h"
53#include "DNA_world_types.h"
54
55#include "ED_gpencil_legacy.hh"
56#include "ED_screen.hh"
57#include "ED_space_api.hh"
58#include "ED_view3d.hh"
59
60#include "GPU_capabilities.hh"
61#include "GPU_framebuffer.hh"
62#include "GPU_immediate.hh"
63#include "GPU_matrix.hh"
64#include "GPU_platform.hh"
65#include "GPU_shader_shared.hh"
66#include "GPU_state.hh"
67#include "GPU_uniform_buffer.hh"
68#include "GPU_viewport.hh"
69
70#include "RE_engine.h"
71#include "RE_pipeline.h"
72
73#include "UI_resources.hh"
74#include "UI_view2d.hh"
75
76#include "WM_api.hh"
77#include "wm_window.hh"
78
80#include "draw_manager_c.hh"
83#include "draw_manager_text.hh"
84#include "draw_shader.hh"
85#include "draw_subdivision.hh"
86#include "draw_texture_pool.hh"
87
88/* only for callbacks */
89#include "draw_cache_impl.hh"
90
100
101#include "GPU_context.hh"
102
103#include "DEG_depsgraph.hh"
104#include "DEG_depsgraph_query.hh"
105
106#include "DRW_select_buffer.hh"
107
108static CLG_LogRef LOG = {"draw.manager"};
109
111DRWManager DST = {nullptr};
112
113static struct {
114 ListBase /*DRWRegisteredDrawEngine*/ engines;
115 int len;
116} g_registered_engines = {{nullptr}};
117
119{
120 memset(dst, 0x0, offsetof(DRWManager, system_gpu_context));
121}
122
123/* This function is used to reset draw manager to a state
124 * where we don't re-use data by accident across different
125 * draw calls.
126 */
127#ifndef NDEBUG
129{
130 memset(dst, 0xff, offsetof(DRWManager, system_gpu_context));
131}
132#endif /* !NDEBUG */
133
135{
136 if (DST.draw_ctx.space_data == nullptr) {
137 View3D *v3d = DST.draw_ctx.v3d;
138 return (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
139 ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
140 }
141
142 switch (DST.draw_ctx.space_data->spacetype) {
143 case SPACE_IMAGE: {
145 return (sima->flag & SI_SHOW_GPENCIL) != 0;
146 }
147 case SPACE_NODE:
148 /* Don't draw the annotation for the node editor. Annotations are handled by space_image as
149 * the draw manager is only used to draw the background. */
150 return false;
151 default:
152 BLI_assert(0);
153 return false;
154 }
155}
156
157/* -------------------------------------------------------------------- */
167
180
183/* -------------------------------------------------------------------- */
188{
190
191 if (ob->type == OB_MESH) {
193 View3D *v3d = DST.draw_ctx.v3d;
194 if (v3d && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && RETOPOLOGY_ENABLED(v3d)) {
195 return false;
196 }
197 }
198 }
199
200 return true;
201}
202
204{
206 if (ELEM(ob->type, OB_MESH, OB_CURVES)) {
207 if ((ob->mode & OB_MODE_EDIT) == 0) {
208 return false;
209 }
210 }
211 return true;
212 }
213 return false;
214}
215
221
223{
224 if (ob->type == OB_MESH) {
225 switch (ob->mode) {
226 case OB_MODE_SCULPT:
230 return true;
231 }
232 }
233
234 return false;
235}
236
238{
239 const bool for_render = DRW_state_is_image_render();
240 /* NOTE: psys_check_enabled is using object and particle system for only
241 * reading, but is using some other functions which are more generic and
242 * which are hard to make const-pointer. */
243 if (!psys_check_enabled((Object *)object, (ParticleSystem *)psys, for_render)) {
244 return false;
245 }
246 const DRWContextState *draw_ctx = DRW_context_state_get();
247 const Scene *scene = draw_ctx->scene;
248 if (object == draw_ctx->object_edit) {
249 return false;
250 }
251 const ParticleSettings *part = psys->part;
252 const ParticleEditSettings *pset = &scene->toolsettings->particle;
253 if (object->mode == OB_MODE_PARTICLE_EDIT) {
254 if (psys_in_edit_mode(draw_ctx->depsgraph, psys)) {
255 if ((pset->flag & PE_DRAW_PART) == 0) {
256 return false;
257 }
258 if ((part->childtype == 0) &&
259 (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) == 0)
260 {
261 return false;
262 }
263 }
264 }
265 return true;
266}
267
269{
270 return DST.dupli_parent;
271}
272
274{
275 return DST.dupli_source;
276}
277
280/* -------------------------------------------------------------------- */
284void DRW_render_viewport_size_set(const int size[2])
285{
286 DST.size[0] = size[0];
287 DST.size[1] = size[1];
288 DST.inv_size[0] = 1.0f / size[0];
289 DST.inv_size[1] = 1.0f / size[1];
290}
291
293{
294 return DST.size;
295}
296
298{
299 return DST.inv_size;
300}
301
303{
304 return &DST.pixsize;
305}
306
307/* Not a viewport variable, we could split this out. */
309{
310 if (DST.draw_ctx.obact) {
312 }
313 else {
315 }
316
317 /* Edit object. */
320 }
321 else {
322 DST.draw_ctx.object_edit = nullptr;
323 }
324
325 /* Pose object. */
328 }
331 }
332 else {
333 DST.draw_ctx.object_pose = nullptr;
334 }
335
339 }
340}
341
343{
346 DRWCullingState *culling = static_cast<DRWCullingState *>(
348
349 unit_m4(mats->model);
350 unit_m4(mats->modelinverse);
351
352 copy_v3_fl(infos->orcotexfac[0], 0.0f);
353 copy_v3_fl(infos->orcotexfac[1], 1.0f);
354
355 infos->ob_index = 0;
356 infos->ob_random = 0.0f;
357 infos->ob_flag = 1.0f;
358 copy_v3_fl(infos->ob_color, 1.0f);
359
360 /* TODO(fclem): get rid of this. */
361 culling->bsphere.radius = -1.0f;
362 culling->user_data = nullptr;
363
365}
366
368{
369 DRWData *drw_data = static_cast<DRWData *>(MEM_callocN(sizeof(DRWData), "DRWData"));
370
372
374
375 drw_data->commands = BLI_memblock_create(sizeof(DRWCommandChunk));
377 drw_data->callbuffers = BLI_memblock_create(sizeof(DRWCallBuffer));
378 drw_data->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup));
379 drw_data->uniforms = BLI_memblock_create(sizeof(DRWUniformChunk));
380 drw_data->views = BLI_memblock_create(sizeof(DRWView));
381 drw_data->images = BLI_memblock_create(sizeof(GPUTexture *));
384 BLI_ghashutil_inthash_p_simple, BLI_ghashutil_intcmp, "View Layer Attribute names");
385 {
386 uint chunk_len = sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN;
387 drw_data->obmats = BLI_memblock_create_ex(sizeof(DRWObjectMatrix), chunk_len);
388 }
389 {
390 uint chunk_len = sizeof(DRWObjectInfos) * DRW_RESOURCE_CHUNK_LEN;
391 drw_data->obinfos = BLI_memblock_create_ex(sizeof(DRWObjectInfos), chunk_len);
392 }
393 {
394 uint chunk_len = sizeof(DRWCullingState) * DRW_RESOURCE_CHUNK_LEN;
395 drw_data->cullstates = BLI_memblock_create_ex(sizeof(DRWCullingState), chunk_len);
396 }
397 {
398 uint chunk_len = sizeof(DRWPass) * DRW_RESOURCE_CHUNK_LEN;
399 drw_data->passes = BLI_memblock_create_ex(sizeof(DRWPass), chunk_len);
400 }
401
402 for (int i = 0; i < 2; i++) {
403 drw_data->view_data[i] = DRW_view_data_create(&g_registered_engines.engines);
404 }
405 return drw_data;
406}
407
408/* Reduce ref count of the textures used by a viewport. */
409static void draw_texture_release(DRWData *drw_data)
410{
411 /* Release Image textures. */
413 GPUTexture **tex;
414 BLI_memblock_iternew(drw_data->images, &iter);
415 while ((tex = static_cast<GPUTexture **>(BLI_memblock_iterstep(&iter)))) {
417 }
418}
419
420static void draw_prune_vlattrs(DRWData *drw_data)
421{
422 drw_data->vlattrs_ubo_ready = false;
423
424 /* Forget known attributes after they are unused for a few frames. */
426 if (++attr->users > 10) {
428 drw_data->vlattrs_name_cache, POINTER_FROM_UINT(attr->hash_code), nullptr, nullptr);
429 BLI_freelinkN(&drw_data->vlattrs_name_list, attr);
430 }
431 }
432}
433
434static void drw_viewport_data_reset(DRWData *drw_data)
435{
436 draw_texture_release(drw_data);
437 draw_prune_vlattrs(drw_data);
438
439 BLI_memblock_clear(drw_data->commands, nullptr);
440 BLI_memblock_clear(drw_data->commands_small, nullptr);
441 BLI_memblock_clear(drw_data->callbuffers, nullptr);
442 BLI_memblock_clear(drw_data->obmats, nullptr);
443 BLI_memblock_clear(drw_data->obinfos, nullptr);
444 BLI_memblock_clear(drw_data->cullstates, nullptr);
445 BLI_memblock_clear(drw_data->shgroups, nullptr);
446 BLI_memblock_clear(drw_data->uniforms, nullptr);
447 BLI_memblock_clear(drw_data->passes, nullptr);
448 BLI_memblock_clear(drw_data->views, nullptr);
449 BLI_memblock_clear(drw_data->images, nullptr);
455}
456
458{
459 draw_texture_release(drw_data);
460
461 BLI_memblock_destroy(drw_data->commands, nullptr);
462 BLI_memblock_destroy(drw_data->commands_small, nullptr);
463 BLI_memblock_destroy(drw_data->callbuffers, nullptr);
464 BLI_memblock_destroy(drw_data->obmats, nullptr);
465 BLI_memblock_destroy(drw_data->obinfos, nullptr);
466 BLI_memblock_destroy(drw_data->cullstates, nullptr);
467 BLI_memblock_destroy(drw_data->shgroups, nullptr);
468 BLI_memblock_destroy(drw_data->uniforms, nullptr);
469 BLI_memblock_destroy(drw_data->views, nullptr);
470 BLI_memblock_destroy(drw_data->passes, nullptr);
471 BLI_memblock_destroy(drw_data->images, nullptr);
473 BLI_ghash_free(drw_data->vlattrs_name_cache, nullptr, nullptr);
475 if (drw_data->vlattrs_ubo) {
477 MEM_freeN(drw_data->vlattrs_buf);
478 }
481 for (int i = 0; i < 2; i++) {
482 DRW_view_data_free(drw_data->view_data[i]);
483 }
484 if (drw_data->matrices_ubo != nullptr) {
485 for (int i = 0; i < drw_data->ubo_len; i++) {
486 GPU_uniformbuf_free(drw_data->matrices_ubo[i]);
487 GPU_uniformbuf_free(drw_data->obinfos_ubo[i]);
488 }
489 MEM_freeN(drw_data->matrices_ubo);
490 MEM_freeN(drw_data->obinfos_ubo);
491 }
493 DRW_curves_ubos_pool_free(drw_data->curves_ubos);
494 MEM_freeN(drw_data);
495}
496
498{
499 DRWData **vmempool_p = GPU_viewport_data_get(viewport);
500 DRWData *vmempool = *vmempool_p;
501
502 if (vmempool == nullptr) {
503 *vmempool_p = vmempool = DRW_viewport_data_create();
504 }
505 return vmempool;
506}
507
518static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int size[2])
519{
520 RegionView3D *rv3d = dst->draw_ctx.rv3d;
521 ARegion *region = dst->draw_ctx.region;
522
523 dst->in_progress = true;
524
525 int view = (viewport) ? GPU_viewport_active_view_get(viewport) : 0;
526
527 if (!dst->viewport && dst->vmempool) {
528 /* Manager was init first without a viewport, created DRWData, but is being re-init.
529 * In this case, keep the old data. */
530 /* If it is being re-init with a valid viewport, it means there is something wrong. */
531 BLI_assert(viewport == nullptr);
532 }
533 else if (viewport) {
534 /* Use viewport's persistent DRWData. */
535 dst->vmempool = drw_viewport_data_ensure(viewport);
536 }
537 else {
538 /* Create temporary DRWData. Freed in drw_manager_exit(). */
540 }
541
542 dst->viewport = viewport;
544 dst->resource_handle = 0;
545 dst->pass_handle = 0;
546 dst->primary_view_num = 0;
547
549
550 bool do_validation = true;
551 if (size == nullptr && viewport == nullptr) {
552 /* Avoid division by 0. Engines will either override this or not use it. */
553 dst->size[0] = 1.0f;
554 dst->size[1] = 1.0f;
555 }
556 else if (size == nullptr) {
557 BLI_assert(viewport);
558 GPUTexture *tex = GPU_viewport_color_texture(viewport, 0);
559 dst->size[0] = GPU_texture_width(tex);
560 dst->size[1] = GPU_texture_height(tex);
561 }
562 else {
563 BLI_assert(size);
564 dst->size[0] = size[0];
565 dst->size[1] = size[1];
566 /* Fix case when used in DRW_cache_restart(). */
567 do_validation = false;
568 }
569 dst->inv_size[0] = 1.0f / dst->size[0];
570 dst->inv_size[1] = 1.0f / dst->size[1];
571
572 if (do_validation) {
574 blender::int2{int(dst->size[0]), int(dst->size[1])});
575 }
576
577 if (viewport) {
579 }
580
582 dst->default_framebuffer = dfbl->default_fb;
583
585
586 if (rv3d != nullptr) {
587 dst->pixsize = rv3d->pixsize;
588 dst->view_default = DRW_view_create(rv3d->viewmat, rv3d->winmat, nullptr, nullptr, nullptr);
589
591 int plane_len = (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) ? 4 : 6;
592 DRW_view_clip_planes_set(dst->view_default, rv3d->clip, plane_len);
593 }
594
595 dst->view_active = dst->view_default;
596 dst->view_previous = nullptr;
597 }
598 else if (region) {
599 View2D *v2d = &region->v2d;
600 float viewmat[4][4];
601 float winmat[4][4];
602
603 rctf region_space = {0.0f, 1.0f, 0.0f, 1.0f};
604 BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &region_space, viewmat);
605
606 unit_m4(winmat);
607 winmat[0][0] = 2.0f;
608 winmat[1][1] = 2.0f;
609 winmat[3][0] = -1.0f;
610 winmat[3][1] = -1.0f;
611
612 dst->view_default = DRW_view_create(viewmat, winmat, nullptr, nullptr, nullptr);
613 dst->view_active = dst->view_default;
614 dst->view_previous = nullptr;
615 }
616 else {
617 dst->pixsize = 1.0f;
618 dst->view_default = nullptr;
619 dst->view_active = nullptr;
620 dst->view_previous = nullptr;
621 }
622
623 /* fclem: Is this still needed ? */
624 if (dst->draw_ctx.object_edit && rv3d) {
626 }
627
628 if (G_draw.view_ubo == nullptr) {
629 G_draw.view_ubo = GPU_uniformbuf_create_ex(sizeof(ViewMatrices), nullptr, "G_draw.view_ubo");
630 }
631
632 if (G_draw.clipping_ubo == nullptr) {
634 sizeof(float4) * 6, nullptr, "G_draw.clipping_ubo");
635 }
636
637 if (dst->draw_list == nullptr) {
639 }
640
641 memset(dst->object_instance_data, 0x0, sizeof(dst->object_instance_data));
642}
643
645{
646 if (dst->vmempool != nullptr && dst->viewport == nullptr) {
648 }
649 dst->vmempool = nullptr;
650 dst->viewport = nullptr;
651#ifndef NDEBUG
652 /* Avoid accidental reuse. */
654#endif
655 dst->in_progress = false;
656}
657
662
667
672
679
682/* -------------------------------------------------------------------- */
686static uint dupli_key_hash(const void *key)
687{
688 const DupliKey *dupli_key = (const DupliKey *)key;
689 return BLI_ghashutil_ptrhash(dupli_key->ob) ^ BLI_ghashutil_ptrhash(dupli_key->ob_data);
690}
691
692static bool dupli_key_cmp(const void *key1, const void *key2)
693{
694 const DupliKey *dupli_key1 = (const DupliKey *)key1;
695 const DupliKey *dupli_key2 = (const DupliKey *)key2;
696 return dupli_key1->ob != dupli_key2->ob || dupli_key1->ob_data != dupli_key2->ob_data;
697}
698
700{
702 if (dupli == nullptr) {
703 return;
704 }
705
706 if (DST.dupli_origin != dupli->ob || (DST.dupli_origin_data != dupli->ob_data)) {
707 DST.dupli_origin = dupli->ob;
709 }
710 else {
711 /* Same data as previous iter. No need to poll ghash for this. */
712 return;
713 }
714
715 if (DST.dupli_ghash == nullptr) {
717 }
718
719 DupliKey *key = static_cast<DupliKey *>(MEM_callocN(sizeof(DupliKey), __func__));
720 key->ob = dupli->ob;
721 key->ob_data = dupli->ob_data;
722
723 void **value;
724 if (!BLI_ghash_ensure_p(DST.dupli_ghash, key, &value)) {
725 *value = MEM_callocN(sizeof(void *) * g_registered_engines.len, __func__);
726
727 /* TODO: Meh a bit out of place but this is nice as it is
728 * only done once per instance type. */
730 }
731 else {
732 MEM_freeN(key);
733 }
734 DST.dupli_datas = *(void ***)value;
735}
736
737static void duplidata_value_free(void *val)
738{
739 void **dupli_datas = static_cast<void **>(val);
740 for (int i = 0; i < g_registered_engines.len; i++) {
741 MEM_SAFE_FREE(dupli_datas[i]);
742 }
743 MEM_freeN(val);
744}
745
746static void duplidata_key_free(void *key)
747{
748 DupliKey *dupli_key = (DupliKey *)key;
749 if (dupli_key->ob_data == dupli_key->ob->data) {
751 }
752 else {
753 Object temp_object = blender::dna::shallow_copy(*dupli_key->ob);
754 blender::bke::ObjectRuntime runtime = *dupli_key->ob->runtime;
755 temp_object.runtime = &runtime;
756
757 /* Do not modify the original bound-box. */
758 BKE_object_replace_data_on_shallow_copy(&temp_object, dupli_key->ob_data);
760 }
761 MEM_freeN(key);
762}
763
765{
766 if (DST.dupli_ghash != nullptr) {
768 DST.dupli_ghash = nullptr;
769 }
770}
771
772void **DRW_duplidata_get(void *vedata)
773{
774 if (DST.dupli_source == nullptr) {
775 return nullptr;
776 }
777 ViewportEngineData *ved = (ViewportEngineData *)vedata;
779 return &DST.dupli_datas[engine_type->index];
780}
781
784/* -------------------------------------------------------------------- */
789{
791 if (sled->engine_type == engine_type) {
792 return sled->storage;
793 }
794 }
795 return nullptr;
796}
797
799 DrawEngineType *engine_type,
800 void (*callback)(void *storage))
801{
803
804 LISTBASE_FOREACH (ViewLayerEngineData *, sled, &view_layer->drawdata) {
805 if (sled->engine_type == engine_type) {
806 return &sled->storage;
807 }
808 }
809
810 sled = static_cast<ViewLayerEngineData *>(
811 MEM_callocN(sizeof(ViewLayerEngineData), "ViewLayerEngineData"));
812 sled->engine_type = engine_type;
813 sled->free = callback;
814 BLI_addtail(&view_layer->drawdata, sled);
815
816 return &sled->storage;
817}
818
820 void (*callback)(void *storage))
821{
823}
824
827/* -------------------------------------------------------------------- */
831/* Used for DRW_drawdata_from_id()
832 * All ID-data-blocks which have their own 'local' DrawData
833 * should have the same arrangement in their structs.
834 */
840
841/* Check if ID can have AnimData */
842static bool id_type_can_have_drawdata(const short id_type)
843{
844 /* Only some ID-blocks have this info for now */
845 /* TODO: finish adding this for the other block-types. */
846 switch (id_type) {
847 /* has DrawData */
848 case ID_OB:
849 case ID_WO:
850 case ID_SCE:
851 case ID_TE:
852 case ID_MSK:
853 case ID_MC:
854 case ID_IM:
855 return true;
856
857 /* no DrawData */
858 default:
859 return false;
860 }
861}
862
863static bool id_can_have_drawdata(const ID *id)
864{
865 /* sanity check */
866 if (id == nullptr) {
867 return false;
868 }
869
870 return id_type_can_have_drawdata(GS(id->name));
871}
872
874{
875 /* only some ID-blocks have this info for now, so we cast the
876 * types that do to be of type IdDdtTemplate, and extract the
877 * DrawData that way
878 */
879 if (id_can_have_drawdata(id)) {
880 IdDdtTemplate *idt = (IdDdtTemplate *)id;
881 return &idt->drawdata;
882 }
883
884 return nullptr;
885}
886
888{
890
891 if (drawdata == nullptr) {
892 return nullptr;
893 }
894
895 LISTBASE_FOREACH (DrawData *, dd, drawdata) {
896 if (dd->engine_type == engine_type) {
897 return dd;
898 }
899 }
900 return nullptr;
901}
902
904 DrawEngineType *engine_type,
905 size_t size,
906 DrawDataInitCb init_cb,
907 DrawDataFreeCb free_cb)
908{
909 BLI_assert(size >= sizeof(DrawData));
911 /* Try to re-use existing data. */
912 DrawData *dd = DRW_drawdata_get(id, engine_type);
913 if (dd != nullptr) {
914 return dd;
915 }
916
918
919 /* Allocate new data. */
920 if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROM_DUPLI) != 0) {
921 /* NOTE: data is not persistent in this case. It is reset each redraw. */
922 BLI_assert(free_cb == nullptr); /* No callback allowed. */
923 /* Round to sizeof(float) for DRW_instance_data_request(). */
924 const size_t t = sizeof(float) - 1;
925 size = (size + t) & ~t;
926 size_t fsize = size / sizeof(float);
928 if (DST.object_instance_data[fsize] == nullptr) {
930 }
932 memset(dd, 0, size);
933 }
934 else {
935 dd = static_cast<DrawData *>(MEM_callocN(size, "DrawData"));
936 }
937 dd->engine_type = engine_type;
938 dd->free = free_cb;
939 /* Perform user-side initialization, if needed. */
940 if (init_cb != nullptr) {
941 init_cb(dd);
942 }
943 /* Register in the list. */
944 BLI_addtail((ListBase *)drawdata, dd);
945 return dd;
946}
947
949{
951
952 if (drawdata == nullptr) {
953 return;
954 }
955
956 LISTBASE_FOREACH (DrawData *, dd, drawdata) {
957 if (dd->free != nullptr) {
958 dd->free(dd);
959 }
960 }
961
962 BLI_freelistN((ListBase *)drawdata);
963}
964
965/* Unlink (but don't free) the drawdata from the DrawDataList if the ID is an OB from dupli. */
967{
968 if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROM_DUPLI) != 0) {
970
971 if (drawdata == nullptr) {
972 return;
973 }
974
975 BLI_listbase_clear((ListBase *)drawdata);
976 }
977}
978
981/* -------------------------------------------------------------------- */
986{
987 using namespace blender::draw;
988 Scene *scene;
989 static int lasttime = 0;
990 int ctime = int(BLI_time_now_seconds());
991
992 if (U.vbotimeout == 0 || (ctime - lasttime) < U.vbocollectrate || ctime == lasttime) {
993 return;
994 }
995
996 lasttime = ctime;
997
998 for (scene = static_cast<Scene *>(bmain->scenes.first); scene;
999 scene = static_cast<Scene *>(scene->id.next))
1000 {
1001 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1002 Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer);
1003 if (depsgraph == nullptr) {
1004 continue;
1005 }
1006
1007 /* TODO(fclem): This is not optimal since it iter over all dupli instances.
1008 * In this case only the source object should be tagged. */
1009 DEGObjectIterSettings deg_iter_settings = {nullptr};
1010 deg_iter_settings.depsgraph = depsgraph;
1012 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1013 DRW_batch_cache_free_old(ob, ctime);
1014 }
1016 }
1017 }
1018}
1019
1022/* -------------------------------------------------------------------- */
1026static void drw_engines_init()
1027{
1029 PROFILE_START(stime);
1030
1031 const DrawEngineDataSize *data_size = engine->vedata_size;
1032 memset(data->psl->passes, 0, sizeof(*data->psl->passes) * data_size->psl_len);
1033
1034 if (engine->engine_init) {
1035 engine->engine_init(data);
1036 }
1037
1038 PROFILE_END_UPDATE(data->init_time, stime);
1039 }
1040}
1041
1043{
1045
1047 if (data->text_draw_cache) {
1048 DRW_text_cache_destroy(data->text_draw_cache);
1049 data->text_draw_cache = nullptr;
1050 }
1051 if (DST.text_store_p == nullptr) {
1052 DST.text_store_p = &data->text_draw_cache;
1053 }
1054
1055 if (engine->cache_init) {
1056 engine->cache_init(data);
1057 }
1058 }
1059}
1060
1062{
1063 if (scene->world == nullptr) {
1064 return;
1065 }
1066
1068 if (engine->id_update) {
1069 engine->id_update(data, &scene->world->id);
1070 }
1071 }
1072}
1073
1075{
1076 DST.ob_handle = 0;
1077
1078 /* HACK: DrawData is copied by copy-on-eval from the duplicated object.
1079 * This is valid for IDs that cannot be instantiated but this
1080 * is not what we want in this case so we clear the pointer
1081 * ourselves here. */
1083
1084 /* Validation for dupli objects happen elsewhere. */
1085 if (!DST.dupli_source) {
1087 }
1088
1090 if (engine->id_update) {
1091 engine->id_update(data, &ob->id);
1092 }
1093
1094 if (engine->cache_populate) {
1095 engine->cache_populate(data, ob);
1096 }
1097 }
1098
1099 /* TODO: in the future it would be nice to generate once for all viewports.
1100 * But we need threaded DRW manager first. */
1101 if (!DST.dupli_source) {
1103 }
1104
1105 /* ... and clearing it here too because this draw data is
1106 * from a mempool and must not be free individually by depsgraph. */
1108}
1109
1111{
1113 if (engine->cache_finish) {
1114 engine->cache_finish(data);
1115 }
1116 }
1117
1119}
1120
1122{
1124 PROFILE_START(stime);
1125 if (engine->draw_scene) {
1126 DRW_stats_group_start(engine->idname);
1127 engine->draw_scene(data);
1128 /* Restore for next engine */
1129 if (DRW_state_is_fbo()) {
1131 }
1133 }
1134 PROFILE_END_UPDATE(data->render_time, stime);
1135 }
1136 /* Reset state after drawing */
1138}
1139
1141{
1143 PROFILE_START(stime);
1144
1145 if (data->text_draw_cache) {
1146 DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.region, DST.draw_ctx.v3d);
1147 }
1148
1149 PROFILE_END_UPDATE(data->render_time, stime);
1150 }
1151}
1152
1153void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height)
1154{
1156 if (data->info[0] != '\0') {
1157 const char *buf_step = IFACE_(data->info);
1158 do {
1159 const char *buf = buf_step;
1160 buf_step = BLI_strchr_or_end(buf, '\n');
1161 const int buf_len = buf_step - buf;
1162 *yoffset -= line_height;
1163 BLF_draw_default(xoffset, *yoffset, 0.0f, buf, buf_len);
1164 } while (*buf_step ? ((void)buf_step++, true) : false);
1165 }
1166 }
1167}
1168
1169static void use_drw_engine(DrawEngineType *engine)
1170{
1172}
1173
1174/* Gather all draw engines needed and store them in DST.view_data_active
1175 * That also define the rendering order of engines */
1176static void drw_engines_enable_from_engine(const RenderEngineType *engine_type, eDrawType drawtype)
1177{
1178 switch (drawtype) {
1179 case OB_WIRE:
1180 case OB_SOLID:
1182 break;
1183 case OB_MATERIAL:
1184 case OB_RENDER:
1185 default:
1186 if (engine_type->draw_engine != nullptr) {
1187 use_drw_engine(engine_type->draw_engine);
1188 }
1189 else if ((engine_type->flag & RE_INTERNAL) == 0) {
1191 }
1192 break;
1193 }
1194}
1195
1197{
1198 use_drw_engine((U.experimental.enable_overlay_next) ? &draw_engine_overlay_next_type :
1200}
1208
1210{
1213 }
1214 else {
1216 }
1217
1218 use_drw_engine((U.experimental.enable_overlay_next) ? &draw_engine_overlay_next_type :
1220}
1221
1223{
1224 SpaceLink *space_data = DST.draw_ctx.space_data;
1225 if (!space_data) {
1226 return;
1227 }
1228
1229 if (space_data->spacetype == SPACE_IMAGE) {
1231 }
1232 else if (space_data->spacetype == SPACE_NODE) {
1233 /* Only enable when drawing the space image backdrop. */
1234 SpaceNode *snode = (SpaceNode *)space_data;
1235 if ((snode->flag & SNODE_BACKDRAW) != 0) {
1237 use_drw_engine((U.experimental.enable_overlay_next) ? &draw_engine_overlay_next_type :
1239 }
1240 }
1241}
1242
1244{
1245 if (!DST.draw_ctx.v3d) {
1246 return false;
1247 }
1248
1250 return false;
1251 }
1252
1253 if (!(DST.draw_ctx.v3d->shading.type >= OB_MATERIAL)) {
1254 return false;
1255 }
1256
1257 if (!DST.draw_ctx.scene->use_nodes) {
1258 return false;
1259 }
1260
1261 if (!DST.draw_ctx.scene->nodetree) {
1262 return false;
1263 }
1264
1265 if (!DST.draw_ctx.rv3d) {
1266 return false;
1267 }
1268
1271 {
1272 return false;
1273 }
1274
1275 return true;
1276}
1277
1278static void drw_engines_enable(ViewLayer * /*view_layer*/,
1279 RenderEngineType *engine_type,
1280 bool gpencil_engine_needed)
1281{
1282 View3D *v3d = DST.draw_ctx.v3d;
1283 const eDrawType drawtype = eDrawType(v3d->shading.type);
1284 const bool use_xray = XRAY_ENABLED(v3d);
1285
1286 drw_engines_enable_from_engine(engine_type, drawtype);
1287 if (gpencil_engine_needed && ((drawtype >= OB_SOLID) || !use_xray)) {
1289 }
1290
1293 }
1294
1296
1297#ifdef WITH_DRAW_DEBUG
1298 if (G.debug_value == 31) {
1300 }
1301#endif
1302}
1303
1308
1313
1314/* Fast check to see if gpencil drawing engine is needed.
1315 * For slow exact check use `DRW_render_check_grease_pencil` */
1316static bool drw_gpencil_engine_needed(Depsgraph *depsgraph, View3D *v3d)
1317{
1318 const bool exclude_gpencil_rendering =
1319 v3d ? ((v3d->object_type_exclude_viewport & (1 << OB_GPENCIL_LEGACY)) != 0) ||
1320 ((v3d->object_type_exclude_viewport & (1 << OB_GREASE_PENCIL)) != 0) :
1321 false;
1322 return (!exclude_gpencil_rendering) && (DEG_id_type_any_exists(depsgraph, ID_GD_LEGACY) ||
1324}
1325
1326/* -------------------------------------------------------------------- */
1331{
1332 RenderEngineType *engine_type = update_ctx->engine_type;
1333 ARegion *region = update_ctx->region;
1334 View3D *v3d = update_ctx->v3d;
1335 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1336 Depsgraph *depsgraph = update_ctx->depsgraph;
1337 Scene *scene = update_ctx->scene;
1338 ViewLayer *view_layer = update_ctx->view_layer;
1339
1340 GPUViewport *viewport = WM_draw_region_get_viewport(region);
1341 if (!viewport) {
1342 return;
1343 }
1344
1345 const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d);
1346
1347 /* XXX Really nasty locking. But else this could be executed by the
1348 * material previews thread while rendering a viewport.
1349 *
1350 * Check for recursive lock which can deadlock. This should not
1351 * happen, but in case there is a bug where depsgraph update is called
1352 * during drawing we try not to hang Blender. */
1354 CLOG_ERROR(&LOG, "GPU context already bound");
1356 return;
1357 }
1358
1359 /* Reset before using it. */
1361
1362 BKE_view_layer_synced_ensure(scene, view_layer);
1363 DST.draw_ctx = {};
1364 DST.draw_ctx.region = region;
1365 DST.draw_ctx.rv3d = rv3d;
1366 DST.draw_ctx.v3d = v3d;
1368 DST.draw_ctx.view_layer = view_layer;
1370 DST.draw_ctx.engine_type = engine_type;
1373
1374 /* Custom lightweight initialize to avoid resetting the memory-pools. */
1375 DST.viewport = viewport;
1377
1378 /* Separate update for each stereo view. */
1379 int view_count = GPU_viewport_is_stereo_get(viewport) ? 2 : 1;
1380 for (int view = 0; view < view_count; view++) {
1382
1383 drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
1385
1387
1389 }
1390
1392
1394}
1395
1396/* update a viewport which belongs to a GPUOffscreen */
1398 RenderEngineType *engine_type,
1399 ARegion *region,
1400 View3D *v3d,
1401 GPUViewport *viewport)
1402{
1403
1404 if (viewport && GPU_viewport_do_update(viewport)) {
1405
1408 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1409
1410 const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d);
1411
1412 /* Reset before using it. */
1414
1415 BKE_view_layer_synced_ensure(scene, view_layer);
1416 DST.draw_ctx = {};
1417 DST.draw_ctx.region = region;
1418 DST.draw_ctx.rv3d = rv3d;
1419 DST.draw_ctx.v3d = v3d;
1421 DST.draw_ctx.view_layer = view_layer;
1423 DST.draw_ctx.engine_type = engine_type;
1425
1426 /* Custom lightweight initialize to avoid resetting the memory-pools. */
1427 DST.viewport = viewport;
1429
1430 /* Separate update for each stereo view. */
1431 int view_count = GPU_viewport_is_stereo_get(viewport) ? 2 : 1;
1432 for (int view = 0; view < view_count; view++) {
1434
1435 drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
1437
1439
1441 }
1442
1444 }
1445}
1446
1449/* -------------------------------------------------------------------- */
1454{
1455 RegionView3D *rv3d = DST.draw_ctx.rv3d;
1456
1458 GPU_matrix_set(rv3d->viewmat);
1459
1460 if (DST.draw_ctx.evil_C) {
1462 /* Callback can be nasty and do whatever they want with the state.
1463 * Don't trust them! */
1465 }
1466}
1467
1469{
1470 RegionView3D *rv3d = DST.draw_ctx.rv3d;
1471 ARegion *region = DST.draw_ctx.region;
1472 View3D *v3d = DST.draw_ctx.v3d;
1473 Depsgraph *depsgraph = DST.draw_ctx.depsgraph;
1474
1475 const bool do_annotations = drw_draw_show_annotation();
1476
1477 if (DST.draw_ctx.evil_C) {
1479
1481
1483
1485 GPU_matrix_set(rv3d->viewmat);
1486
1487 /* annotations - temporary drawing buffer (3d space) */
1488 /* XXX: Or should we use a proper draw/overlay engine for this case? */
1489 if (do_annotations) {
1491 /* XXX: as `scene->gpd` is not copied for copy-on-eval yet. */
1494 }
1495
1497
1499 /* Apply state for callbacks. */
1501
1503
1504#ifdef WITH_XR_OPENXR
1505 /* XR callbacks (controllers, custom draw functions) for session mirror. */
1506 if ((v3d->flag & V3D_XR_SESSION_MIRROR) != 0) {
1507 if ((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) {
1509 if (art) {
1511 }
1512 }
1513 if ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0) {
1515 if (st) {
1517 if (art) {
1519 }
1520 }
1521 }
1522 }
1523#endif
1524
1525 /* Callback can be nasty and do whatever they want with the state.
1526 * Don't trust them! */
1528
1529 /* Needed so gizmo isn't occluded. */
1530 if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
1533 }
1534
1537
1539
1540 /* Annotations - temporary drawing buffer (screen-space). */
1541 /* XXX: Or should we use a proper draw/overlay engine for this case? */
1542 if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
1544 /* XXX: as `scene->gpd` is not copied for copy-on-eval yet */
1546 }
1547
1548 if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
1549 /* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
1550 * 'DRW_draw_region_info' sets the projection in pixel-space. */
1553 }
1554
1555 if (G.debug_value > 20 && G.debug_value < 30) {
1557 /* local coordinate visible rect inside region, to accommodate overlapping ui */
1559 DRW_stats_draw(rect);
1560 }
1561
1563 }
1564 else {
1565 if (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0)) {
1567 /* XXX: as `scene->gpd` is not copied for copy-on-eval yet */
1570 }
1571
1572#ifdef WITH_XR_OPENXR
1573 if ((v3d->flag & V3D_XR_SESSION_SURFACE) != 0) {
1575
1577
1579
1581 GPU_matrix_set(rv3d->viewmat);
1582
1583 /* XR callbacks (controllers, custom draw functions) for session surface. */
1584 if (((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) ||
1585 ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0))
1586 {
1589
1590 if ((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) {
1592 if (art) {
1594 }
1595 }
1596 if ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0) {
1598 if (st) {
1600 if (art) {
1602 }
1603 }
1604 }
1605
1607 }
1608
1610 }
1611#endif
1612 }
1613}
1614
1616{
1618 if (*DST.text_store_p == nullptr) {
1620 }
1621 return *DST.text_store_p;
1622}
1623
1626/* -------------------------------------------------------------------- */
1631{
1632 View3D *v3d = CTX_wm_view3d(C);
1633 if (v3d) {
1635 ARegion *region = CTX_wm_region(C);
1637 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
1639
1640 /* Reset before using it. */
1642 DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
1643 (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
1644 DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) ||
1645 (v3d->shading.type != OB_RENDER);
1646 DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, C);
1647 }
1648 else {
1650 ARegion *region = CTX_wm_region(C);
1653 DRW_draw_render_loop_2d_ex(depsgraph, region, viewport, C);
1654 }
1655}
1656
1658 RenderEngineType *engine_type,
1659 ARegion *region,
1660 View3D *v3d,
1661 GPUViewport *viewport,
1662 const bContext *evil_C)
1663{
1664 using namespace blender::draw;
1667 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
1668
1669 BKE_view_layer_synced_ensure(scene, view_layer);
1670 DST.draw_ctx = {};
1671 DST.draw_ctx.region = region;
1672 DST.draw_ctx.rv3d = rv3d;
1673 DST.draw_ctx.v3d = v3d;
1675 DST.draw_ctx.view_layer = view_layer;
1677 DST.draw_ctx.engine_type = engine_type;
1679
1680 /* reuse if caller sets */
1681 DST.draw_ctx.evil_C = evil_C;
1682
1685
1686 drw_manager_init(&DST, viewport, nullptr);
1688
1689 const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
1690 /* Check if scene needs to perform the populate loop */
1691 const bool internal_engine = (engine_type->flag & RE_INTERNAL) != 0;
1692 const bool draw_type_render = v3d->shading.type == OB_RENDER;
1693 const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
1694 const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d);
1695 const bool do_populate_loop = internal_engine || overlays_on || !draw_type_render ||
1696 gpencil_engine_needed;
1697
1698 /* Get list of enabled engines */
1699 drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
1701
1702 /* Update UBO's */
1704
1706 DRW_pointcloud_init();
1707 DRW_curves_init(DST.vmempool);
1710
1711 /* No frame-buffer allowed before drawing. */
1713
1714 /* Init engines */
1716
1717 /* Cache filling */
1718 {
1719 PROFILE_START(stime);
1722
1723 /* Only iterate over objects for internal engines or when overlays are enabled */
1724 if (do_populate_loop) {
1725 DST.dupli_origin = nullptr;
1726 DST.dupli_origin_data = nullptr;
1727 DEGObjectIterSettings deg_iter_settings = {nullptr};
1728 deg_iter_settings.depsgraph = depsgraph;
1730 if (v3d->flag2 & V3D_SHOW_VIEWER) {
1731 deg_iter_settings.viewer_path = &v3d->viewer_path;
1732 }
1733 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1734 if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
1735 continue;
1736 }
1737 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
1738 continue;
1739 }
1740 DST.dupli_parent = data_.dupli_parent;
1741 DST.dupli_source = data_.dupli_object_current;
1744 }
1746 }
1747
1750
1753
1754#ifdef USE_PROFILE
1756 PROFILE_END_UPDATE(*cache_time, stime);
1757#endif
1758 }
1759
1761
1763
1764 /* Start Drawing */
1766
1769
1770 DRW_curves_update();
1771
1773
1775
1776 /* Fix 3D view "lagging" on APPLE and WIN32+NVIDIA. (See #56996, #61474) */
1778 GPU_flush();
1779 }
1780
1782
1784
1786
1788 /* Don't unbind the frame-buffer yet in this case and let
1789 * GPU_viewport_unbind do it, so that we can still do further
1790 * drawing of action zones on top. */
1791 }
1792 else {
1794 }
1795
1798
1800}
1801
1803 ARegion *region,
1804 View3D *v3d,
1805 GPUViewport *viewport)
1806{
1807 /* Reset before using it. */
1809
1811 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
1812
1813 DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, nullptr);
1814}
1815
1817 RenderEngineType *engine_type,
1818 ARegion *region,
1819 View3D *v3d,
1820 const bool is_image_render,
1821 const bool draw_background,
1822 const bool do_color_management,
1823 GPUOffScreen *ofs,
1824 GPUViewport *viewport)
1825{
1826 const bool is_xr_surface = ((v3d->flag & V3D_XR_SESSION_SURFACE) != 0);
1827
1828 /* Create temporary viewport if needed or update the existing viewport. */
1829 GPUViewport *render_viewport = viewport;
1830 if (viewport == nullptr) {
1831 render_viewport = GPU_viewport_create();
1832 }
1833 else {
1834 drw_notify_view_update_offscreen(depsgraph, engine_type, region, v3d, render_viewport);
1835 }
1836
1837 GPU_viewport_bind_from_offscreen(render_viewport, ofs, is_xr_surface);
1838
1839 /* Just here to avoid an assert but shouldn't be required in practice. */
1841
1842 /* Reset before using it. */
1844 DST.options.is_image_render = is_image_render;
1846 DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, render_viewport, nullptr);
1847
1848 if (draw_background) {
1849 /* HACK(@fclem): In this case we need to make sure the final alpha is 1.
1850 * We use the blend mode to ensure that. A better way to fix that would
1851 * be to do that in the color-management shader. */
1852 GPU_offscreen_bind(ofs, false);
1853 GPU_clear_color(0.0f, 0.0f, 0.0f, 1.0f);
1854 /* Pre-multiply alpha over black background. */
1856 }
1857
1860 const bool do_overlays = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 ||
1861 ELEM(v3d->shading.type, OB_WIRE, OB_SOLID) ||
1862 (ELEM(v3d->shading.type, OB_MATERIAL) &&
1863 (v3d->shading.flag & V3D_SHADING_SCENE_WORLD) == 0) ||
1864 (ELEM(v3d->shading.type, OB_RENDER) &&
1866 GPU_viewport_unbind_from_offscreen(render_viewport, ofs, do_color_management, do_overlays);
1867
1868 if (draw_background) {
1869 /* Reset default. */
1871 }
1872
1873 /* Free temporary viewport. */
1874 if (viewport == nullptr) {
1875 GPU_viewport_free(render_viewport);
1876 }
1877}
1878
1880{
1881 if (!drw_gpencil_engine_needed(depsgraph, nullptr)) {
1882 return false;
1883 }
1884
1885 DEGObjectIterSettings deg_iter_settings = {nullptr};
1886 deg_iter_settings.depsgraph = depsgraph;
1888 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1889 if (ELEM(ob->type, OB_GPENCIL_LEGACY, OB_GREASE_PENCIL)) {
1891 return true;
1892 }
1893 }
1894 }
1896
1897 return false;
1898}
1899
1901 RenderLayer *render_layer,
1902 const rcti *rect)
1903{
1905 if (draw_engine->render_to_image) {
1907 draw_engine);
1908 draw_engine->render_to_image(gpdata, engine, render_layer, rect);
1909 }
1910}
1911
1913{
1914 /* This function should only be called if there are grease pencil objects,
1915 * especially important to avoid failing in background renders without GPU context. */
1917
1920 RenderResult *render_result = RE_engine_get_result(engine);
1921 RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name);
1922 if (render_layer == nullptr) {
1923 return;
1924 }
1925
1926 RenderEngineType *engine_type = engine->type;
1927 Render *render = engine->re;
1928
1930
1931 /* Reset before using it. */
1935 DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
1937
1938 DST.draw_ctx = {};
1940 DST.draw_ctx.view_layer = view_layer;
1941 DST.draw_ctx.engine_type = engine_type;
1944
1946
1947 const int size[2] = {engine->resolution_x, engine->resolution_y};
1948
1949 drw_manager_init(&DST, nullptr, size);
1950
1951 /* Main rendering. */
1952 rctf view_rect;
1953 rcti render_rect;
1954 RE_GetViewPlane(render, &view_rect, &render_rect);
1955 if (BLI_rcti_is_empty(&render_rect)) {
1956 BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
1957 }
1958
1959 for (RenderView *render_view = static_cast<RenderView *>(render_result->views.first);
1960 render_view != nullptr;
1961 render_view = render_view->next)
1962 {
1963 RE_SetActiveRenderView(render, render_view->name);
1965 DST.buffer_finish_called = false;
1966 DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
1967 }
1968
1970
1972
1974
1975 /* Restore Drawing area. */
1977
1979
1980 DST.buffer_finish_called = false;
1981}
1982
1984{
1985 using namespace blender::draw;
1988 RenderEngineType *engine_type = engine->type;
1989 DrawEngineType *draw_engine_type = engine_type->draw_engine;
1990 Render *render = engine->re;
1991
1992 /* IMPORTANT: We don't support immediate mode in render mode!
1993 * This shall remain in effect until immediate mode supports
1994 * multiple threads. */
1995
1996 /* Reset before using it. */
2000 DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
2001 DST.draw_ctx = {};
2003 DST.draw_ctx.view_layer = view_layer;
2004 DST.draw_ctx.engine_type = engine_type;
2007
2009
2010 /* Begin GPU workload Boundary */
2012
2013 const int size[2] = {engine->resolution_x, engine->resolution_y};
2014
2015 drw_manager_init(&DST, nullptr, size);
2016
2018 draw_engine_type);
2019
2020 /* Main rendering. */
2021 rctf view_rect;
2022 rcti render_rect;
2023 RE_GetViewPlane(render, &view_rect, &render_rect);
2024 if (BLI_rcti_is_empty(&render_rect)) {
2025 BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
2026 }
2027
2028 /* Reset state before drawing */
2030
2031 /* set default viewport */
2032 GPU_viewport(0, 0, size[0], size[1]);
2033
2034 /* Init render result. */
2035 RenderResult *render_result = RE_engine_begin_result(engine,
2036 0,
2037 0,
2038 size[0],
2039 size[1],
2040 view_layer->name,
2041 /*RR_ALL_VIEWS*/ nullptr);
2042 RenderLayer *render_layer = static_cast<RenderLayer *>(render_result->layers.first);
2043 for (RenderView *render_view = static_cast<RenderView *>(render_result->views.first);
2044 render_view != nullptr;
2045 render_view = render_view->next)
2046 {
2047 RE_SetActiveRenderView(render, render_view->name);
2049 engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect);
2050 DST.buffer_finish_called = false;
2051 }
2052
2053 RE_engine_end_result(engine, render_result, false, false, false);
2054
2055 if (engine_type->draw_engine->store_metadata) {
2056 RenderResult *final_render_result = RE_engine_get_result(engine);
2057 engine_type->draw_engine->store_metadata(data, final_render_result);
2058 }
2059
2061
2063
2065 DRW_cache_free_old_subdiv();
2066
2067 /* Reset state after drawing */
2069
2070 /* End GPU workload Boundary */
2072}
2073
2075 void *vedata,
2076 RenderEngine *engine,
2077 Depsgraph *depsgraph,
2078 void (*callback)(void *vedata, Object *ob, RenderEngine *engine, Depsgraph *depsgraph))
2079{
2080 using namespace blender::draw;
2081 const DRWContextState *draw_ctx = DRW_context_state_get();
2082 DRW_pointcloud_init();
2083 DRW_curves_init(DST.vmempool);
2086
2088 const int object_type_exclude_viewport = draw_ctx->v3d ?
2090 0;
2091 DST.dupli_origin = nullptr;
2092 DST.dupli_origin_data = nullptr;
2093 DEGObjectIterSettings deg_iter_settings = {nullptr};
2094 deg_iter_settings.depsgraph = depsgraph;
2096 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
2097 if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
2098 DST.dupli_parent = data_.dupli_parent;
2099 DST.dupli_source = data_.dupli_object_current;
2100 DST.ob_handle = 0;
2102
2103 if (!DST.dupli_source) {
2105 }
2106 callback(vedata, ob, engine, depsgraph);
2107 if (!DST.dupli_source) {
2109 }
2110 }
2111 }
2113
2116}
2117
2118void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, Depsgraph *depsgraph)
2119{
2120 using namespace blender::draw;
2123
2124 /* Reset before using it. */
2128 DST.options.draw_background = false;
2129
2130 DST.draw_ctx = {};
2132 DST.draw_ctx.view_layer = view_layer;
2133 DST.draw_ctx.engine_type = nullptr;
2136
2138
2139 drw_manager_init(&DST, nullptr, nullptr);
2140
2141 DRW_pointcloud_init();
2142 DRW_curves_init(DST.vmempool);
2145
2147}
2148
2150{
2151 DST.buffer_finish_called = false;
2152
2154
2156
2157 /* The use of custom pipeline in other thread using the same
2158 * resources as the main thread (viewport) may lead to data
2159 * races and undefined behavior on certain drivers. Using
2160 * GPU_finish to sync seems to fix the issue. (see #62997) */
2162 if (type == GPU_BACKEND_OPENGL) {
2163 GPU_finish();
2164 }
2165
2167}
2168
2170 Depsgraph *depsgraph,
2171 void (*callback)(void *vedata, void *user_data),
2172 void *user_data)
2173{
2174 DRW_custom_pipeline_begin(draw_engine_type, depsgraph);
2175
2177 draw_engine_type);
2178 /* Execute the callback. */
2179 callback(data, user_data);
2180
2182}
2183
2185{
2186 using namespace blender::draw;
2188
2189 drw_manager_init(&DST, DST.viewport, blender::int2{int(DST.size[0]), int(DST.size[1])});
2190
2191 DST.buffer_finish_called = false;
2192
2193 DRW_pointcloud_init();
2194 DRW_curves_init(DST.vmempool);
2197}
2198
2200 ARegion *region,
2201 GPUViewport *viewport,
2202 const bContext *evil_C)
2203{
2206
2207 BKE_view_layer_synced_ensure(scene, view_layer);
2208 DST.draw_ctx = {};
2209 DST.draw_ctx.region = region;
2211 DST.draw_ctx.view_layer = view_layer;
2215
2216 /* reuse if caller sets */
2217 DST.draw_ctx.evil_C = evil_C;
2218
2220 drw_manager_init(&DST, viewport, nullptr);
2222
2223 /* TODO(jbakker): Only populate when editor needs to draw object.
2224 * for the image editor this is when showing UVs. */
2225 const bool do_populate_loop = (DST.draw_ctx.space_data->spacetype == SPACE_IMAGE);
2226 const bool do_annotations = drw_draw_show_annotation();
2227 const bool do_draw_gizmos = (DST.draw_ctx.space_data->spacetype != SPACE_IMAGE);
2228
2229 /* Get list of enabled engines */
2232
2233 /* Update UBO's */
2235
2237
2238 /* No frame-buffer allowed before drawing. */
2242
2243 /* Init engines */
2246
2247 /* Cache filling */
2248 {
2249 PROFILE_START(stime);
2251
2252 /* Only iterate over objects when overlay uses object data. */
2253 if (do_populate_loop) {
2254 DEGObjectIterSettings deg_iter_settings = {nullptr};
2255 deg_iter_settings.depsgraph = depsgraph;
2257 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
2259 }
2261 }
2262
2264
2266
2267#ifdef USE_PROFILE
2269 PROFILE_END_UPDATE(*cache_time, stime);
2270#endif
2271 }
2273
2275
2277
2278 /* Start Drawing */
2280
2281 if (DST.draw_ctx.evil_C) {
2283 }
2284
2286
2287 /* Fix 3D view being "laggy" on MACOS and MS-Windows+NVIDIA. (See #56996, #61474) */
2289 GPU_flush();
2290 }
2291
2292 if (DST.draw_ctx.evil_C) {
2295
2297
2300 wmOrtho2(
2301 region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin, region->v2d.cur.ymax);
2302 if (do_annotations) {
2304 }
2308 /* Callback can be nasty and do whatever they want with the state.
2309 * Don't trust them! */
2311
2314
2315 if (do_annotations) {
2318 }
2319 }
2320
2323
2324 if (do_draw_gizmos) {
2327 }
2328
2330
2331 if (G.debug_value > 20 && G.debug_value < 30) {
2333 /* local coordinate visible rect inside region, to accommodate overlapping ui */
2335 DRW_stats_draw(rect);
2336 }
2337
2339
2341 /* Don't unbind the frame-buffer yet in this case and let
2342 * GPU_viewport_unbind do it, so that we can still do further
2343 * drawing of action zones on top. */
2344 }
2345 else {
2347 }
2348
2351
2353}
2354
2355static struct DRWSelectBuffer {
2356 GPUFrameBuffer *framebuffer_depth_only;
2357 GPUTexture *texture_depth;
2358} g_select_buffer = {nullptr};
2359
2385
2393
2394void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
2395{
2396 RE_engine_frame_set(engine, frame, subframe);
2399}
2400
2402 ARegion *region,
2403 View3D *v3d,
2404 bool use_obedit_skip,
2405 bool draw_surface,
2406 bool /*use_nearest*/,
2407 const bool do_material_sub_selection,
2408 const rcti *rect,
2409 DRW_SelectPassFn select_pass_fn,
2410 void *select_pass_user_data,
2411 DRW_ObjectFilterFn object_filter_fn,
2412 void *object_filter_user_data)
2413{
2414 using namespace blender::draw;
2416 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
2418
2419 BKE_view_layer_synced_ensure(scene, view_layer);
2420 Object *obact = BKE_view_layer_active_object_get(view_layer);
2421 Object *obedit = use_obedit_skip ? nullptr : OBEDIT_FROM_OBACT(obact);
2422#ifndef USE_GPU_SELECT
2423 UNUSED_VARS(scene, view_layer, v3d, region, rect);
2424#else
2425 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2426
2427 /* Reset before using it. */
2429
2430 bool use_obedit = false;
2431 /* obedit_ctx_mode is used for selecting the right draw engines */
2432 // eContextObjectMode obedit_ctx_mode;
2433 /* object_mode is used for filtering objects in the depsgraph */
2434 eObjectMode object_mode;
2435 int object_type = 0;
2436 if (obedit != nullptr) {
2437 object_type = obedit->type;
2438 object_mode = eObjectMode(obedit->mode);
2439 if (obedit->type == OB_MBALL) {
2440 use_obedit = true;
2441 // obedit_ctx_mode = CTX_MODE_EDIT_METABALL;
2442 }
2443 else if (obedit->type == OB_ARMATURE) {
2444 use_obedit = true;
2445 // obedit_ctx_mode = CTX_MODE_EDIT_ARMATURE;
2446 }
2447 }
2449 if (!(v3d->flag2 & V3D_HIDE_OVERLAYS)) {
2450 /* NOTE: don't use "BKE_object_pose_armature_get" here, it breaks selection. */
2451 Object *obpose = OBPOSE_FROM_OBACT(obact);
2452 if (obpose == nullptr) {
2453 Object *obweight = OBWEIGHTPAINT_FROM_OBACT(obact);
2454 if (obweight) {
2455 /* Only use Armature pose selection, when connected armature is in pose mode. */
2456 Object *ob_armature = BKE_modifiers_is_deformed_by_armature(obweight);
2457 if (ob_armature && ob_armature->mode == OB_MODE_POSE) {
2458 obpose = ob_armature;
2459 }
2460 }
2461 }
2462
2463 if (obpose) {
2464 use_obedit = true;
2465 object_type = obpose->type;
2466 object_mode = eObjectMode(obpose->mode);
2467 // obedit_ctx_mode = CTX_MODE_POSE;
2468 }
2469 }
2470 }
2471
2472 /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2473 DST.draw_ctx = {};
2474 DST.draw_ctx.region = region;
2475 DST.draw_ctx.rv3d = rv3d;
2476 DST.draw_ctx.v3d = v3d;
2478 DST.draw_ctx.view_layer = view_layer;
2479 DST.draw_ctx.obact = obact;
2480 DST.draw_ctx.engine_type = engine_type;
2482
2484
2485 const int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
2486 drw_manager_init(&DST, nullptr, viewport_size);
2487
2488 DST.options.is_select = true;
2489 DST.options.is_material_select = do_material_sub_selection;
2491 /* Get list of enabled engines */
2492 if (U.experimental.enable_overlay_next) {
2494 }
2495 else if (use_obedit) {
2497 }
2498 else if (!draw_surface) {
2499 /* grease pencil selection */
2502 }
2503
2505 }
2506 else {
2507 /* Draw surface for occlusion. */
2509 /* grease pencil selection */
2512 }
2513
2515 }
2517
2518 /* Update UBO's */
2520
2521 /* Init engines */
2523 DRW_pointcloud_init();
2524 DRW_curves_init(DST.vmempool);
2527
2528 {
2531
2532 if (use_obedit) {
2533 FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, object_type, object_mode, ob_iter) {
2535 }
2537 }
2538 else {
2539 /* When selecting pose-bones in pose mode, check for visibility not select-ability
2540 * as pose-bones have their own selection restriction flag. */
2541 const bool use_pose_exception = (DST.draw_ctx.object_pose != nullptr);
2542
2543 const int object_type_exclude_select = (v3d->object_type_exclude_viewport |
2545 bool filter_exclude = false;
2546 DST.dupli_origin = nullptr;
2547 DST.dupli_origin_data = nullptr;
2548 DEGObjectIterSettings deg_iter_settings = {nullptr};
2549 deg_iter_settings.depsgraph = depsgraph;
2551 if (v3d->flag2 & V3D_SHOW_VIEWER) {
2552 deg_iter_settings.viewer_path = &v3d->viewer_path;
2553 }
2554 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
2555 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
2556 continue;
2557 }
2558
2559 if (use_pose_exception && (ob->mode & OB_MODE_POSE)) {
2560 if ((ob->base_flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT) == 0) {
2561 continue;
2562 }
2563 }
2564 else {
2565 if ((ob->base_flag & BASE_SELECTABLE) == 0) {
2566 continue;
2567 }
2568 }
2569
2570 if ((object_type_exclude_select & (1 << ob->type)) == 0) {
2571 if (object_filter_fn != nullptr) {
2572 if (ob->base_flag & BASE_FROM_DUPLI) {
2573 /* pass (use previous filter_exclude value) */
2574 }
2575 else {
2576 filter_exclude = (object_filter_fn(ob, object_filter_user_data) == false);
2577 }
2578 if (filter_exclude) {
2579 continue;
2580 }
2581 }
2582
2583 DRW_select_load_id(ob->runtime->select_id);
2584 DST.dupli_parent = data_.dupli_parent;
2585 DST.dupli_source = data_.dupli_object_current;
2588 }
2589 }
2591 }
2592
2596
2598 }
2599
2600 /* Setup frame-buffer. */
2604 /* WORKAROUND: Needed for Select-Next for keeping the same code-flow as Overlay-Next. */
2605 BLI_assert(DRW_viewport_texture_list_get()->depth == nullptr);
2607
2608 /* Start Drawing */
2611
2612 DRW_curves_update();
2613
2614 /* Only 1-2 passes. */
2615 while (true) {
2616 if (!select_pass_fn(DRW_SELECT_PASS_PRE, select_pass_user_data)) {
2617 break;
2618 }
2619 if (!U.experimental.enable_overlay_next) {
2621 }
2622
2624
2625 if (!U.experimental.enable_overlay_next) {
2627 }
2628
2629 if (!select_pass_fn(DRW_SELECT_PASS_POST, select_pass_user_data)) {
2630 break;
2631 }
2632 }
2633
2635
2636 /* WORKAROUND: Do not leave ownership to the viewport list. */
2638
2641
2643
2645
2646#endif /* USE_GPU_SELECT */
2647}
2648
2650 ARegion *region,
2651 View3D *v3d,
2652 GPUViewport *viewport,
2653 const bool use_gpencil,
2654 const bool use_basic,
2655 const bool use_overlay,
2656 const bool use_only_selected)
2657{
2658 using namespace blender::draw;
2660 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
2662 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2663
2664 /* Reset before using it. */
2666
2667 DST.options.is_depth = true;
2668
2669 /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2670 BKE_view_layer_synced_ensure(scene, view_layer);
2671 DST.draw_ctx = {};
2672 DST.draw_ctx.region = region;
2673 DST.draw_ctx.rv3d = rv3d;
2674 DST.draw_ctx.v3d = v3d;
2676 DST.draw_ctx.view_layer = view_layer;
2678 DST.draw_ctx.engine_type = engine_type;
2680
2682 drw_manager_init(&DST, viewport, nullptr);
2683
2684 if (use_gpencil) {
2686 }
2687 if (use_basic) {
2689 }
2690 if (use_overlay) {
2692 }
2693
2695
2696 /* Setup frame-buffer. */
2697 GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
2698
2699 GPUFrameBuffer *depth_fb = nullptr;
2701 {
2702 GPU_ATTACHMENT_TEXTURE(depth_tx),
2704 });
2705
2706 GPU_framebuffer_bind(depth_fb);
2707 GPU_framebuffer_clear_depth(depth_fb, 1.0f);
2708
2709 /* Update UBO's */
2711
2712 /* Init engines */
2714 DRW_pointcloud_init();
2715 DRW_curves_init(DST.vmempool);
2718
2719 {
2722
2723 const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
2724 DST.dupli_origin = nullptr;
2725 DST.dupli_origin_data = nullptr;
2726 DEGObjectIterSettings deg_iter_settings = {nullptr};
2727 deg_iter_settings.depsgraph = DST.draw_ctx.depsgraph;
2729 if (v3d->flag2 & V3D_SHOW_VIEWER) {
2730 deg_iter_settings.viewer_path = &v3d->viewer_path;
2731 }
2732 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
2733 if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
2734 continue;
2735 }
2736 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
2737 continue;
2738 }
2739 if (use_only_selected && !(ob->base_flag & BASE_SELECTED)) {
2740 continue;
2741 }
2742 DST.dupli_parent = data_.dupli_parent;
2743 DST.dupli_source = data_.dupli_object_current;
2746 }
2748
2751
2754 }
2755
2756 /* Start Drawing */
2758
2759 DRW_curves_update();
2760
2762
2764
2766
2767 /* TODO: Reading depth for operators should be done here. */
2768
2770 GPU_framebuffer_free(depth_fb);
2771
2773
2775}
2776
2777void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d)
2778{
2780 GPUViewport *viewport = WM_draw_region_get_viewport(region);
2781 if (!viewport) {
2782 /* Selection engine requires a viewport.
2783 * TODO(@germano): This should be done internally in the engine. */
2784 sel_ctx->index_drawn_len = 1;
2785 return;
2786 }
2787
2790 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2791
2792 /* Reset before using it. */
2794
2795 /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2796 BKE_view_layer_synced_ensure(scene, view_layer);
2797 DST.draw_ctx = {};
2798 DST.draw_ctx.region = region;
2799 DST.draw_ctx.rv3d = rv3d;
2800 DST.draw_ctx.v3d = v3d;
2802 DST.draw_ctx.view_layer = view_layer;
2805
2808
2809 drw_manager_init(&DST, viewport, nullptr);
2810
2811 /* Update UBO's */
2814
2815 /* Select Engine */
2818 {
2820
2821 for (Object *obj_eval : sel_ctx->objects) {
2823 }
2824
2825 if (RETOPOLOGY_ENABLED(v3d) && !XRAY_ENABLED(v3d)) {
2826 DEGObjectIterSettings deg_iter_settings = {nullptr};
2827 deg_iter_settings.depsgraph = depsgraph;
2829 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
2830 if (ob->type != OB_MESH) {
2831 /* The iterator has evaluated meshes for all solid objects.
2832 * It also has non-mesh objects however, which are not supported here. */
2833 continue;
2834 }
2836 /* Only background (non-edit) objects are used for occlusion. */
2837 continue;
2838 }
2839 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
2840 continue;
2841 }
2843 }
2845 }
2846
2848
2850#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug (see #69377). */
2852#else
2854 // DRW_instance_buffer_finish(DST.vmempool->idatalist);
2856#endif
2857 }
2858
2859 /* Start Drawing */
2863
2865
2867}
2868
2870 Scene *scene, ARegion *region, View3D *v3d, GPUViewport *viewport, Object *object)
2871{
2872 using namespace blender::draw;
2873 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
2874
2876 GPU_matrix_set(rv3d->viewmat);
2877 GPU_matrix_mul(object->object_to_world().ptr());
2878
2879 /* Setup frame-buffer. */
2880 GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
2881
2882 GPUFrameBuffer *depth_fb = nullptr;
2884 {
2885 GPU_ATTACHMENT_TEXTURE(depth_tx),
2887 });
2888
2889 GPU_framebuffer_bind(depth_fb);
2890 GPU_framebuffer_clear_depth(depth_fb, 1.0f);
2892
2893 GPUClipPlanes planes;
2894 const bool use_clipping_planes = RV3D_CLIPPING_ENABLED(v3d, rv3d);
2895 if (use_clipping_planes) {
2897 ED_view3d_clipping_local(rv3d, object->object_to_world().ptr());
2898 for (int i = 0; i < 6; i++) {
2899 copy_v4_v4(planes.world[i], rv3d->clip_local[i]);
2900 }
2901 copy_m4_m4(planes.ClipModelMatrix.ptr(), object->object_to_world().ptr());
2902 }
2903
2905
2906 switch (object->type) {
2907 case OB_MESH: {
2908 blender::gpu::Batch *batch;
2909
2910 Mesh &mesh = *static_cast<Mesh *>(object->data);
2911
2912 if (object->mode & OB_MODE_EDIT) {
2913 batch = DRW_mesh_batch_cache_get_edit_triangles(mesh);
2914 }
2915 else {
2916 batch = DRW_mesh_batch_cache_get_surface(mesh);
2917 }
2918 TaskGraph *task_graph = BLI_task_graph_create();
2919 DRW_mesh_batch_cache_create_requested(*task_graph, *object, mesh, *scene, false, true);
2920 BLI_task_graph_work_and_wait(task_graph);
2921 BLI_task_graph_free(task_graph);
2922
2923 const eGPUShaderConfig sh_cfg = use_clipping_planes ? GPU_SHADER_CFG_CLIPPED :
2926
2927 GPUUniformBuf *ubo = nullptr;
2928 if (use_clipping_planes) {
2929 ubo = GPU_uniformbuf_create_ex(sizeof(GPUClipPlanes), &planes, __func__);
2930 GPU_batch_uniformbuf_bind(batch, "clipPlanes", ubo);
2931 }
2932
2935 break;
2936 }
2937 case OB_CURVES_LEGACY:
2938 case OB_SURF:
2939 break;
2940 }
2941
2942 if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
2944 }
2945
2946 GPU_matrix_set(rv3d->viewmat);
2949
2950 GPU_framebuffer_free(depth_fb);
2951}
2952
2954{
2955 return DST.in_progress;
2956}
2957
2960/* -------------------------------------------------------------------- */
2965{
2966 return ((DST.default_framebuffer != nullptr) || DST.options.is_image_render) &&
2968}
2969
2971{
2972 return DST.options.is_select;
2973}
2974
2979
2981{
2982 return DST.options.is_depth;
2983}
2984
2989
2995
3000
3002{
3003 if (DST.draw_ctx.evil_C != nullptr) {
3005 return ED_screen_animation_playing(wm) != nullptr;
3006 }
3007 return false;
3008}
3009
3011{
3012 const RegionView3D *rv3d = DST.draw_ctx.rv3d;
3013 return (rv3d) && (rv3d->rflag & (RV3D_NAVIGATING | RV3D_PAINTING));
3014}
3015
3017{
3018 const RegionView3D *rv3d = DST.draw_ctx.rv3d;
3019 return (rv3d) && (rv3d->rflag & (RV3D_PAINTING));
3020}
3021
3023{
3024 return (DST.options.is_select) == 0 && (DST.options.is_depth) == 0 &&
3026}
3027
3029{
3030 View3D *v3d = DST.draw_ctx.v3d;
3031 return (DRW_state_is_scene_render() == false) && (v3d != nullptr) &&
3032 ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0);
3033}
3034
3039
3042/* -------------------------------------------------------------------- */
3047{
3048 return &DST.draw_ctx;
3049}
3050
3053/* -------------------------------------------------------------------- */
3058{
3059 return draw_engine_type->render_to_image;
3060}
3061
3063{
3064 DRWRegisteredDrawEngine *draw_engine = static_cast<DRWRegisteredDrawEngine *>(
3065 MEM_mallocN(sizeof(DRWRegisteredDrawEngine), __func__));
3066 draw_engine->draw_engine = draw_engine_type;
3067 draw_engine->index = g_registered_engines.len;
3068
3069 BLI_addtail(&g_registered_engines.engines, draw_engine);
3071}
3072
3074{
3075 using namespace blender::draw;
3077
3079
3081
3088#ifdef WITH_DRAW_DEBUG
3090#endif
3091
3094
3095 /* setup callbacks */
3096 {
3097 BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag;
3098 BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free;
3099
3100 BKE_mesh_batch_cache_dirty_tag_cb = DRW_mesh_batch_cache_dirty_tag;
3101 BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free;
3102
3103 BKE_lattice_batch_cache_dirty_tag_cb = DRW_lattice_batch_cache_dirty_tag;
3104 BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free;
3105
3106 BKE_particle_batch_cache_dirty_tag_cb = DRW_particle_batch_cache_dirty_tag;
3107 BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free;
3108
3109 BKE_gpencil_batch_cache_dirty_tag_cb = DRW_gpencil_batch_cache_dirty_tag;
3110 BKE_gpencil_batch_cache_free_cb = DRW_gpencil_batch_cache_free;
3111
3112 BKE_curves_batch_cache_dirty_tag_cb = DRW_curves_batch_cache_dirty_tag;
3113 BKE_curves_batch_cache_free_cb = DRW_curves_batch_cache_free;
3114
3115 BKE_pointcloud_batch_cache_dirty_tag_cb = DRW_pointcloud_batch_cache_dirty_tag;
3116 BKE_pointcloud_batch_cache_free_cb = DRW_pointcloud_batch_cache_free;
3117
3118 BKE_volume_batch_cache_dirty_tag_cb = DRW_volume_batch_cache_dirty_tag;
3119 BKE_volume_batch_cache_free_cb = DRW_volume_batch_cache_free;
3120
3121 BKE_grease_pencil_batch_cache_dirty_tag_cb = DRW_grease_pencil_batch_cache_dirty_tag;
3122 BKE_grease_pencil_batch_cache_free_cb = DRW_grease_pencil_batch_cache_free;
3123
3124 BKE_subsurf_modifier_free_gpu_cache_cb = DRW_subdiv_cache_free;
3125 }
3126}
3127
3129{
3131 for (DRWRegisteredDrawEngine *type =
3132 static_cast<DRWRegisteredDrawEngine *>(g_registered_engines.engines.first);
3133 type;
3134 type = next)
3135 {
3136 next = static_cast<DRWRegisteredDrawEngine *>(type->next);
3137 BLI_remlink(&R_engines, type);
3138
3139 if (type->draw_engine->engine_free) {
3140 type->draw_engine->engine_free();
3141 }
3142 MEM_freeN(type);
3143 }
3144
3146 g_registered_engines.len = 0;
3147}
3148
3150{
3151 using namespace blender::draw;
3153
3154 if (DST.system_gpu_context == nullptr) {
3155 /* Nothing has been setup. Nothing to clear.
3156 * Otherwise, DRW_gpu_context_enable can
3157 * create a context in background mode. (see #62355) */
3158 return;
3159 }
3160
3162
3165
3167 DRW_pointcloud_free();
3168 DRW_curves_free();
3173
3175 DST.debug = nullptr;
3176
3182
3183 if (DST.draw_list) {
3185 }
3186
3188}
3189
3191{
3192 if (G.background && DST.system_gpu_context == nullptr) {
3193 WM_init_gpu();
3194 }
3195
3197
3201 return;
3202 }
3203
3204 void *re_system_gpu_context = RE_system_gpu_context_get(render);
3205
3206 /* Changing Context */
3207 if (re_system_gpu_context != nullptr) {
3208 DRW_system_gpu_render_context_enable(re_system_gpu_context);
3209 /* We need to query gpu context after a gl context has been bound. */
3210 void *re_blender_gpu_context = RE_blender_gpu_context_ensure(render);
3211 DRW_blender_gpu_render_context_enable(re_blender_gpu_context);
3212 }
3213 else {
3215 }
3216}
3217
3219{
3224 return;
3225 }
3226
3227 void *re_system_gpu_context = RE_system_gpu_context_get(render);
3228
3229 if (re_system_gpu_context != nullptr) {
3230 void *re_blender_gpu_context = RE_blender_gpu_context_ensure(render);
3231 /* GPU rendering may occur during context disable. */
3232 DRW_blender_gpu_render_context_disable(re_blender_gpu_context);
3234 DRW_system_gpu_render_context_disable(re_system_gpu_context);
3235 }
3236 else {
3239 }
3240}
3241
3244/* -------------------------------------------------------------------- */
3249{
3250 BLI_assert(DST.system_gpu_context == nullptr); /* Ensure it's called once */
3251
3253 /* This changes the active context. */
3256 /* Be sure to create blender_gpu_context too. */
3258 /* Setup compilation context. */
3260 /* Activate the window's context afterwards. */
3262}
3263
3276
3277void DRW_gpu_context_enable_ex(bool /*restore*/)
3278{
3279 if (DST.system_gpu_context != nullptr) {
3280 /* IMPORTANT: We don't support immediate mode in render mode!
3281 * This shall remain in effect until immediate mode supports
3282 * multiple threads. */
3287 }
3288}
3289
3291{
3292 if (DST.system_gpu_context != nullptr) {
3293 if (BLI_thread_is_main() && restore) {
3295 }
3296 else {
3298 GPU_context_active_set(nullptr);
3299 }
3300
3301 /* Render boundaries are opened and closed here as this may be
3302 * called outside of an existing render loop. */
3304
3306 }
3307}
3308
3310{
3311 /* TODO: should be replace by a more elegant alternative. */
3312
3313 if (G.background && DST.system_gpu_context == nullptr) {
3314 WM_init_gpu();
3315 }
3317}
3318
3323
3324void DRW_system_gpu_render_context_enable(void *re_system_gpu_context)
3325{
3326 /* If thread is main you should use DRW_gpu_context_enable(). */
3328
3329 /* TODO: get rid of the blocking. Only here because of the static global DST. */
3331 WM_system_gpu_context_activate(re_system_gpu_context);
3332}
3333
3334void DRW_system_gpu_render_context_disable(void *re_system_gpu_context)
3335{
3336 WM_system_gpu_context_release(re_system_gpu_context);
3337 /* TODO: get rid of the blocking. */
3339}
3340
3342{
3343 /* If thread is main you should use DRW_gpu_context_enable(). */
3345
3346 GPU_context_active_set(static_cast<GPUContext *>(re_gpu_context));
3347}
3348
3349void DRW_blender_gpu_render_context_disable(void * /*re_gpu_context*/)
3350{
3351 GPU_flush();
3352 GPU_context_active_set(nullptr);
3353}
3354
3357#ifdef WITH_XR_OPENXR
3358
3359void *DRW_system_gpu_context_get()
3360{
3361 /* XXX: There should really be no such getter, but for VR we currently can't easily avoid it.
3362 * OpenXR needs some low level info for the GPU context that will be used for submitting the
3363 * final frame-buffer. VR could in theory create its own context, but that would mean we have to
3364 * switch to it just to submit the final frame, which has notable performance impact.
3365 *
3366 * We could "inject" a context through DRW_system_gpu_render_context_enable(), but that would
3367 * have to work from the main thread, which is tricky to get working too. The preferable solution
3368 * would be using a separate thread for VR drawing where a single context can stay active. */
3369
3370 return DST.system_gpu_context;
3371}
3372
3373void *DRW_xr_blender_gpu_context_get()
3374{
3375 /* XXX: See comment on #DRW_system_gpu_context_get(). */
3376
3377 return DST.blender_gpu_context;
3378}
3379
3380void DRW_xr_drawing_begin()
3381{
3382 /* XXX: See comment on #DRW_system_gpu_context_get(). */
3383
3385}
3386
3387void DRW_xr_drawing_end()
3388{
3389 /* XXX: See comment on #DRW_system_gpu_context_get(). */
3390
3392}
3393
3394#endif
3395
3398/* -------------------------------------------------------------------- */
3402#ifdef WITH_GPU_DRAW_TESTS
3403
3404void DRW_draw_state_init_gtests(eGPUShaderConfig sh_cfg)
3405{
3406 DST.draw_ctx.sh_cfg = sh_cfg;
3407}
3408
3409#endif
3410
3413/* -------------------------------------------------------------------- */
3442{
3443 if (!BLI_thread_is_main()) {
3444 return false;
3445 }
3446
3448 /* Context release is requested from the outside of the draw manager main draw loop, indicate
3449 * this to the `DRW_gpu_context_activate()` so that it restores drawable of the window.
3450 */
3451 return false;
3452 }
3453
3454 GPU_context_active_set(nullptr);
3456
3457 return true;
3458}
3459
3460void DRW_gpu_context_activate(bool drw_state)
3461{
3462 if (!BLI_thread_is_main()) {
3463 return;
3464 }
3465
3466 if (drw_state) {
3469 }
3470 else {
3472 }
3473}
3474
Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
SpaceLink * CTX_wm_space_data(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
void(* BKE_curve_batch_cache_free_cb)(Curve *cu)
Definition curve.cc:5509
void(* BKE_curve_batch_cache_dirty_tag_cb)(Curve *cu, int mode)
Definition curve.cc:5508
Low-level operations for curves that cannot be defined in the C++ header yet.
void(* BKE_curves_batch_cache_dirty_tag_cb)(struct Curves *curves, int mode)
void(* BKE_curves_batch_cache_free_cb)(struct Curves *curves)
void(* BKE_gpencil_batch_cache_dirty_tag_cb)(struct bGPdata *gpd)
void(* BKE_gpencil_batch_cache_free_cb)(struct bGPdata *gpd)
Low-level operations for grease pencil that cannot be defined in the C++ header yet.
void(* BKE_grease_pencil_batch_cache_dirty_tag_cb)(GreasePencil *grease_pencil, int mode)
void(* BKE_grease_pencil_batch_cache_free_cb)(GreasePencil *grease_pencil)
void(* BKE_lattice_batch_cache_dirty_tag_cb)(Lattice *lt, int mode)
Definition lattice.cc:707
void(* BKE_lattice_batch_cache_free_cb)(Lattice *lt)
Definition lattice.cc:708
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
#define FOREACH_OBJECT_IN_MODE_END
Definition BKE_layer.hh:382
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
bool BKE_object_is_visible_in_viewport(const View3D *v3d, const Object *ob)
#define FOREACH_OBJECT_IN_MODE_BEGIN(_scene, _view_layer, _v3d, _object_type, _object_mode, _instance)
Definition BKE_layer.hh:377
void(* BKE_mesh_batch_cache_free_cb)(void *batch_cache)
void(* BKE_mesh_batch_cache_dirty_tag_cb)(Mesh *mesh, eMeshBatchDirtyMode mode)
Object * BKE_modifiers_is_deformed_by_armature(Object *ob)
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const Object *ob)
void BKE_object_replace_data_on_shallow_copy(Object *ob, ID *new_data)
@ OB_VISIBLE_SELF
Object * BKE_object_pose_armature_get(Object *ob)
int BKE_object_visibility(const Object *ob, int dag_eval_mode)
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, bool use_render_params)
Definition particle.cc:706
void(* BKE_particle_batch_cache_dirty_tag_cb)(struct ParticleSystem *psys, int mode)
Definition particle.cc:5292
bool psys_in_edit_mode(struct Depsgraph *depsgraph, const struct ParticleSystem *psys)
void(* BKE_particle_batch_cache_free_cb)(struct ParticleSystem *psys)
Definition particle.cc:5293
General operations for point clouds.
void(* BKE_pointcloud_batch_cache_free_cb)(PointCloud *pointcloud)
void(* BKE_pointcloud_batch_cache_dirty_tag_cb)(PointCloud *pointcloud, int mode)
Depsgraph * BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
Definition scene.cc:3364
SpaceType * BKE_spacetype_from_id(int spaceid)
Definition screen.cc:243
ARegionType * BKE_regiontype_from_id(const SpaceType *st, int regionid)
Definition screen.cc:253
void(* BKE_subsurf_modifier_free_gpu_cache_cb)(blender::bke::subdiv::Subdiv *subdiv)
Volume data-block.
void(* BKE_volume_batch_cache_dirty_tag_cb)(Volume *volume, int mode)
void(* BKE_volume_batch_cache_free_cb)(Volume *volume)
void BLF_draw_default(float x, float y, float z, const char *str, size_t str_len) ATTR_NONNULL()
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
GSet * BLI_gset_ptr_new(const char *info)
unsigned int BLI_ghashutil_ptrhash(const void *key)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:686
unsigned int BLI_ghashutil_inthash_p_simple(const void *ptr)
bool BLI_ghashutil_intcmp(const void *a, const void *b)
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:787
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition BLI_ghash.c:1034
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:752
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:269
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void unit_m4(float m[4][4])
Definition rct.c:1127
void copy_m4_m4(float m1[4][4], const float m2[4][4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_fl(float r[3], float f)
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
void * BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define BLI_memblock_create(elem_size)
BLI_memblock * BLI_memblock_create_ex(uint elem_size, uint chunk_size) ATTR_WARN_UNUSED_RESULT
void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter) ATTR_NONNULL()
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
void * BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.c:418
void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
Definition rct.c:555
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
bool BLI_rcti_is_empty(const struct rcti *rect)
char char size_t char const char * BLI_strchr_or_end(const char *str, char ch) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
Definition string.c:927
unsigned int uint
void BLI_task_graph_free(struct TaskGraph *task_graph)
struct TaskGraph * BLI_task_graph_create(void)
void BLI_task_graph_work_and_wait(struct TaskGraph *task_graph)
TicketMutex * BLI_ticket_mutex_alloc(void)
Definition threads.cc:511
void BLI_ticket_mutex_unlock(TicketMutex *ticket)
Definition threads.cc:564
bool BLI_ticket_mutex_lock_check_recursive(TicketMutex *ticket)
Definition threads.cc:559
void BLI_ticket_mutex_lock(TicketMutex *ticket)
Definition threads.cc:554
void BLI_ticket_mutex_free(TicketMutex *ticket)
Definition threads.cc:522
int BLI_thread_is_main(void)
Definition threads.cc:179
double BLI_time_now_seconds(void)
Definition time.c:65
#define UNUSED_VARS(...)
#define ELEM(...)
#define POINTER_FROM_UINT(i)
#define IFACE_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
eEvaluationMode
@ DAG_EVAL_RENDER
@ DAG_EVAL_VIEWPORT
#define DEG_OBJECT_ITER_BEGIN(settings_, instance_)
#define DEG_OBJECT_ITER_END
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS
Scene * DEG_get_input_scene(const Depsgraph *graph)
bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type)
void(* DrawDataFreeCb)(struct DrawData *engine_data)
Definition DNA_ID.h:40
void(* DrawDataInitCb)(struct DrawData *engine_data)
Definition DNA_ID.h:39
@ ID_MC
@ ID_TE
@ ID_IM
@ ID_SCE
@ ID_MSK
@ ID_WO
@ ID_GD_LEGACY
@ ID_OB
@ ID_GP
@ BASE_FROM_DUPLI
@ BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT
@ BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT
eDrawType
@ OB_WIRE
@ OB_SOLID
@ OB_RENDER
@ OB_MATERIAL
#define OB_MODE_ALL_WEIGHT_PAINT
eObjectMode
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT
@ OB_MODE_POSE
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_OBJECT
@ OB_MODE_VERTEX_PAINT
@ OB_MBALL
@ OB_SURF
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVES_LEGACY
@ OB_GPENCIL_LEGACY
@ OB_CURVES
@ PSYS_HAIR_DYNAMICS
@ PTCACHE_BAKED
#define OBPOSE_FROM_OBACT(ob)
#define BASE_SELECTED(v3d, base)
#define OBEDIT_FROM_OBACT(ob)
#define OBWEIGHTPAINT_FROM_OBACT(ob)
@ R_ADDSKY
@ PE_DRAW_PART
#define BASE_SELECTABLE(v3d, base)
@ RGN_TYPE_WINDOW
@ RGN_TYPE_XR
@ SI_SHOW_GPENCIL
@ SNODE_BACKDRAW
@ SPACE_NODE
@ SPACE_IMAGE
@ SPACE_VIEW3D
@ V3D_SHADING_USE_COMPOSITOR_CAMERA
@ V3D_SHADING_USE_COMPOSITOR_DISABLED
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_PAINTING
@ RV3D_NAVIGATING
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
@ V3D_OVERLAY_HIDE_TEXT
@ V3D_OVERLAY_BONE_SELECT
@ V3D_SHADING_SCENE_WORLD_RENDER
@ V3D_SHADING_SCENE_WORLD
@ V3D_GIZMO_HIDE
@ RV3D_CAMOB
@ RV3D_BOXCLIP
@ V3D_SHOW_VIEWER
@ V3D_XR_SHOW_CUSTOM_OVERLAYS
@ V3D_HIDE_OVERLAYS
@ V3D_SHOW_ANNOTATION
@ V3D_XR_SHOW_CONTROLLERS
@ V3D_XR_SESSION_SURFACE
@ V3D_XR_SESSION_MIRROR
void DRW_instance_data_list_free(DRWInstanceDataList *idatalist)
DRWInstanceDataList * DRW_instance_data_list_create()
bool(*)(Object *ob, void *user_data) DRW_ObjectFilterFn
Definition DRW_engine.hh:63
@ DRW_SELECT_PASS_POST
Definition DRW_engine.hh:60
@ DRW_SELECT_PASS_PRE
Definition DRW_engine.hh:59
bool(*)(eDRWSelectStage stage, void *user_data) DRW_SelectPassFn
Definition DRW_engine.hh:62
void DRW_uniform_attrs_pool_free(GHash *table)
#define DRW_UBO_FREE_SAFE(ubo)
struct DRWPass DRWPass
Definition DRW_render.hh:85
#define DRW_TEXTURE_FREE_SAFE(tex)
const rcti * ED_region_visible_rect(ARegion *region)
Definition area.cc:4010
void ED_region_pixelspace(const ARegion *region)
Definition area.cc:121
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
#define REGION_DRAW_POST_VIEW
void ED_region_surface_draw_cb_draw(ARegionType *art, int type)
#define REGION_DRAW_PRE_VIEW
#define XRAY_ENABLED(v3d)
#define RETOPOLOGY_ENABLED(v3d)
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
void ED_view3d_clipping_local(RegionView3D *rv3d, const float mat[4][4])
RenderEngineType * ED_view3d_engine_type(const Scene *scene, int drawtype)
static AppView * view
#define GPU_batch_uniformbuf_bind(batch, name, ubo)
Definition GPU_batch.hh:314
void GPU_batch_draw(blender::gpu::Batch *batch)
void GPU_batch_program_set_builtin_with_config(blender::gpu::Batch *batch, eGPUBuiltinShader shader_id, eGPUShaderConfig sh_cfg)
bool GPU_use_main_context_workaround()
void GPU_render_end()
GPUContext * GPU_context_create(void *ghost_window, void *ghost_context)
void GPU_context_main_lock()
void GPU_render_begin()
GPUContext * GPU_context_active_get()
void GPU_context_main_unlock()
void GPU_context_discard(GPUContext *)
void GPU_context_active_set(GPUContext *)
eGPUBackendType GPU_backend_get_type()
GPUDrawList * GPU_draw_list_create(int list_length)
void GPU_draw_list_discard(GPUDrawList *list)
bool GPU_framebuffer_check_valid(GPUFrameBuffer *framebuffer, char err_out[256])
GPUFrameBuffer * GPU_framebuffer_create(const char *name)
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
#define GPU_ATTACHMENT_TEXTURE(_texture)
GPUFrameBuffer * GPU_framebuffer_active_get()
void GPU_offscreen_bind(GPUOffScreen *offscreen, bool save)
void GPU_framebuffer_restore()
void GPU_framebuffer_clear_depth_stencil(GPUFrameBuffer *fb, float clear_depth, uint clear_stencil)
#define GPU_ATTACHMENT_NONE
void GPU_clear_color(float red, float green, float blue, float alpha)
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_framebuffer_clear_depth(GPUFrameBuffer *fb, float clear_depth)
void GPU_framebuffer_free(GPUFrameBuffer *framebuffer)
GPUFrameBuffer * GPU_framebuffer_back_get()
void GPU_framebuffer_texture_attach(GPUFrameBuffer *framebuffer, GPUTexture *texture, int slot, int mip)
void GPU_matrix_identity_projection_set()
void GPU_matrix_identity_set()
#define GPU_matrix_set(x)
void GPU_matrix_push_projection()
#define GPU_matrix_mul(x)
void GPU_matrix_pop_projection()
#define GPU_matrix_projection_set(x)
@ GPU_DRIVER_ANY
bool GPU_type_matches_ex(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver, eGPUBackendType backend)
@ GPU_OS_ANY
@ GPU_DEVICE_ANY
@ GPU_SHADER_CFG_DEFAULT
@ GPU_SHADER_CFG_CLIPPED
@ GPU_SHADER_3D_DEPTH_ONLY
void GPU_flush()
Definition gpu_state.cc:294
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA_PREMULT
Definition GPU_state.hh:88
void GPU_blend(eGPUBlend blend)
Definition gpu_state.cc:42
void GPU_finish()
Definition gpu_state.cc:299
void GPU_viewport(int x, int y, int width, int height)
Definition gpu_state.cc:194
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:111
@ GPU_DEPTH_NONE
Definition GPU_state.hh:108
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
void GPU_apply_state()
Definition gpu_state.cc:304
void GPU_clip_distances(int distances_enabled)
Definition gpu_state.cc:124
int GPU_texture_height(const GPUTexture *texture)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
int GPU_texture_width(const GPUTexture *texture)
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_DEPTH_COMPONENT24
GPUUniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
void GPU_uniformbuf_free(GPUUniformBuf *ubo)
GPUTexture * GPU_viewport_color_texture(GPUViewport *viewport, int view)
void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport, GPUOffScreen *ofs, bool display_colorspace, bool do_overlay_merge)
GPUViewport * GPU_viewport_create()
void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, GPUOffScreen *ofs, bool is_xr_surface)
bool GPU_viewport_is_stereo_get(GPUViewport *viewport)
bool GPU_viewport_do_update(GPUViewport *viewport)
int GPU_viewport_active_view_get(GPUViewport *viewport)
void GPU_viewport_free(GPUViewport *viewport)
GPUTexture * GPU_viewport_depth_texture(GPUViewport *viewport)
void GPU_viewport_tag_update(GPUViewport *viewport)
DRWData ** GPU_viewport_data_get(GPUViewport *viewport)
#define MEM_SAFE_FREE(v)
@ RE_INTERNAL
Definition RE_engine.h:47
void UI_SetTheme(int spacetype, int regionid)
void ED_annotation_draw_view3d(Scene *scene, Depsgraph *depsgraph, View3D *v3d, ARegion *region, bool only3d)
void ED_annotation_draw_view2d(const bContext *C, bool onlyv2d)
DrawEngineType draw_engine_basic_type
struct GPUContext GPUContext
unsigned int U
Definition btGjkEpa3.h:78
DrawEngineType draw_engine_compositor_type
const Depsgraph * depsgraph
DEGForeachIDComponentCallback callback
#define offsetof(t, d)
void drw_batch_cache_generate_requested_evaluated_mesh_or_curve(Object *ob)
void DRW_shape_cache_free()
void drw_batch_cache_generate_requested(Object *ob)
void drw_batch_cache_validate(Object *ob)
void DRW_viewport_colormanagement_set(GPUViewport *viewport)
void DRW_globals_free()
void DRW_globals_update()
DRW_Global G_draw
void DRW_volume_ubos_pool_free(void *pool)
void DRW_volume_free()
void DRW_volume_init(DRWData *drw_data)
void DRW_smoke_exit(DRWData *drw_data)
void DRW_smoke_init(DRWData *drw_data)
void drw_debug_init()
void drw_debug_module_free(DRWDebugModule *module)
void drw_debug_draw()
void DRW_instance_data_list_free_unused(DRWInstanceDataList *idatalist)
void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist)
void DRW_uniform_attrs_pool_clear_all(GHash *table)
void * DRW_instance_data_next(DRWInstanceData *idata)
GHash * DRW_uniform_attrs_pool_new()
void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist)
DRWInstanceData * DRW_instance_data_request(DRWInstanceDataList *idatalist, uint attr_size)
void DRW_instance_data_list_resize(DRWInstanceDataList *idatalist)
#define MAX_INSTANCE_DATA_SIZE
Object * DRW_object_get_dupli_parent(const Object *)
void DRW_drawdata_free(ID *id)
void DRW_gpu_context_destroy()
DrawData * DRW_drawdata_get(ID *id, DrawEngineType *engine_type)
static void drw_notify_view_update_offscreen(Depsgraph *depsgraph, RenderEngineType *engine_type, ARegion *region, View3D *v3d, GPUViewport *viewport)
static void drw_engines_cache_finish()
const float * DRW_viewport_invert_size_get()
static void drw_duplidata_load(Object *ob)
void DRW_draw_render_loop_ex(Depsgraph *depsgraph, RenderEngineType *engine_type, ARegion *region, View3D *v3d, GPUViewport *viewport, const bContext *evil_C)
const float * DRW_viewport_pixelsize_get()
bool DRW_state_show_text()
bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
DRWData * DRW_viewport_data_create()
static void drw_engines_world_update(Scene *scene)
static bool drw_draw_show_annotation()
void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height)
bool DRW_draw_in_progress()
bool DRW_state_draw_background()
void DRW_draw_view(const bContext *C)
static void draw_unit_state_create()
void * DRW_view_layer_engine_data_get(DrawEngineType *engine_type)
static void drw_manager_exit(DRWManager *dst)
void DRW_draw_render_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, GPUViewport *viewport)
bool DRW_state_is_viewport_image_render()
bool DRW_engine_render_support(DrawEngineType *draw_engine_type)
static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int size[2])
DefaultFramebufferList * DRW_viewport_framebuffer_list_get()
void DRW_cache_restart()
void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
static void drw_engines_init()
bool DRW_object_is_in_edit_mode(const Object *ob)
bool DRW_state_is_material_select()
blender::draw::TextureFromPool & DRW_viewport_pass_texture_get(const char *pass_name)
void DRW_render_viewport_size_set(const int size[2])
void ** DRW_view_layer_engine_data_ensure_ex(ViewLayer *view_layer, DrawEngineType *engine_type, void(*callback)(void *storage))
void DRW_gpu_context_disable()
static void duplidata_value_free(void *val)
const float * DRW_viewport_size_get()
static DRWData * drw_viewport_data_ensure(GPUViewport *viewport)
static void use_drw_engine(DrawEngineType *engine)
void DRW_gpu_context_disable_ex(bool restore)
bool DRW_object_use_hide_faces(const Object *ob)
static void drw_state_prepare_clean_for_draw(DRWManager *dst)
void DRW_draw_callbacks_pre_scene()
static void draw_prune_vlattrs(DRWData *drw_data)
static void drw_context_state_init()
bool DRW_object_is_renderable(const Object *ob)
DRWTextStore * DRW_text_cache_ensure()
static void drw_engines_enable_editors()
DrawData * DRW_drawdata_ensure(ID *id, DrawEngineType *engine_type, size_t size, DrawDataInitCb init_cb, DrawDataFreeCb free_cb)
void DRW_cache_free_old_batches(Main *bmain)
void DRW_gpu_context_enable_ex(bool)
void DRW_draw_depth_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, GPUViewport *viewport, const bool use_gpencil, const bool use_basic, const bool use_overlay, const bool use_only_selected)
void DRW_system_gpu_render_context_enable(void *re_system_gpu_context)
void DRW_gpu_context_enable()
void DRW_engines_free()
void DRW_render_instance_buffer_finish()
void DRW_gpu_context_create()
DRWManager DST
void DRW_draw_depth_object(Scene *scene, ARegion *region, View3D *v3d, GPUViewport *viewport, Object *object)
static void drw_task_graph_deinit()
void DRW_custom_pipeline(DrawEngineType *draw_engine_type, Depsgraph *depsgraph, void(*callback)(void *vedata, void *user_data), void *user_data)
int DRW_object_visibility_in_active_context(const Object *ob)
static uint dupli_key_hash(const void *key)
void DRW_gpu_context_activate(bool drw_state)
bool DRW_state_is_image_render()
bool DRW_state_is_painting()
void DRW_render_context_disable(Render *render)
static void drw_engines_cache_init()
void DRW_blender_gpu_render_context_disable(void *)
bool DRW_state_is_scene_render()
static void drw_engines_data_validate()
static void drw_engines_cache_populate(Object *ob)
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
void DRW_draw_select_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bool use_obedit_skip, bool draw_surface, bool, const bool do_material_sub_selection, const rcti *rect, DRW_SelectPassFn select_pass_fn, void *select_pass_user_data, DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data)
ListBase engines
void DRW_viewport_data_free(DRWData *drw_data)
void DRW_draw_render_loop_offscreen(Depsgraph *depsgraph, RenderEngineType *engine_type, ARegion *region, View3D *v3d, const bool is_image_render, const bool draw_background, const bool do_color_management, GPUOffScreen *ofs, GPUViewport *viewport)
DefaultTextureList * DRW_viewport_texture_list_get()
static void drw_engines_enable_from_engine(const RenderEngineType *engine_type, eDrawType drawtype)
void DRW_render_to_image(RenderEngine *engine, Depsgraph *depsgraph)
static void drw_registered_engines_free()
static void drw_engines_enable_overlays()
void ** DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void(*callback)(void *storage))
void DRW_system_gpu_render_context_disable(void *re_system_gpu_context)
static void duplidata_key_free(void *key)
DrawDataList * DRW_drawdatalist_from_id(ID *id)
static bool drw_gpencil_engine_needed(Depsgraph *depsgraph, View3D *v3d)
void DRW_engine_register(DrawEngineType *draw_engine_type)
void ** DRW_duplidata_get(void *vedata)
static void drw_task_graph_init()
void DRW_draw_render_loop_2d_ex(Depsgraph *depsgraph, ARegion *region, GPUViewport *viewport, const bContext *evil_C)
static struct DRWSelectBuffer g_select_buffer
void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d)
void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
static CLG_LogRef LOG
const DRWContextState * DRW_context_state_get()
bool DRW_state_draw_support()
void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph)
void DRW_draw_callbacks_post_scene()
static void DRW_render_gpencil_to_image(RenderEngine *engine, RenderLayer *render_layer, const rcti *rect)
bool DRW_gpu_context_release()
void DRW_engines_register()
DupliObject * DRW_object_get_dupli(const Object *)
bool DRW_is_viewport_compositor_enabled()
bool DRW_state_is_fbo()
void DRW_viewport_request_redraw()
void DRW_custom_pipeline_end()
static bool id_can_have_drawdata(const ID *id)
void DRW_render_object_iter(void *vedata, RenderEngine *engine, Depsgraph *depsgraph, void(*callback)(void *vedata, Object *ob, RenderEngine *engine, Depsgraph *depsgraph))
static bool dupli_key_cmp(const void *key1, const void *key2)
void DRW_render_context_enable(Render *render)
bool DRW_state_is_select()
static void drw_duplidata_free()
static void drw_engines_disable()
static void draw_select_framebuffer_depth_only_setup(const int size[2])
static void drw_engines_draw_text()
static void drw_state_ensure_not_reused(DRWManager *dst)
static void drw_viewport_data_reset(DRWData *drw_data)
static void draw_texture_release(DRWData *drw_data)
bool DRW_state_is_navigating()
static void drw_engines_enable_basic()
bool DRW_state_is_playback()
static void drw_engines_draw_scene()
void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, Depsgraph *depsgraph)
bool DRW_state_is_depth()
static void drw_engines_enable(ViewLayer *, RenderEngineType *engine_type, bool gpencil_engine_needed)
static void drw_drawdata_unlink_dupli(ID *id)
void DRW_blender_gpu_render_context_enable(void *re_gpu_context)
static void drw_engine_enable_image_editor()
static struct @275 g_registered_engines
static bool id_type_can_have_drawdata(const short id_type)
int len
void drw_resource_buffer_finish(DRWData *vmempool)
void DRW_manager_end_sync()
#define PROFILE_END_UPDATE(time_update, time_start)
#define PROFILE_START(time_start)
#define DRW_DRAWLIST_LEN
#define DRW_RESOURCE_CHUNK_LEN
BLI_INLINE void DRW_handle_increment(DRWResourceHandle *handle)
void DRW_manager_begin_sync()
void DRW_view_clip_planes_set(DRWView *view, float(*planes)[4], int plane_len)
void DRW_view_reset()
DRWView * DRW_view_create(const float viewmat[4][4], const float winmat[4][4], const float(*culling_viewmat)[4], const float(*culling_winmat)[4], DRWCallVisibilityFn *visibility_fn)
void DRW_state_reset()
void DRW_state_lock(DRWState state)
void DRW_select_load_id(uint id)
void DRW_stats_free()
void DRW_stats_group_start(const char *name)
void DRW_stats_reset()
void DRW_stats_group_end()
void DRW_stats_begin()
void DRW_stats_draw(const rcti *rect)
void DRW_shader_exit()
void DRW_shader_init()
DRWTextStore * DRW_text_cache_create()
void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, View3D *v3d)
void DRW_text_cache_destroy(DRWTextStore *dt)
void DRW_shaders_free()
DRWState
Definition draw_state.hh:25
@ DRW_STATE_WRITE_DEPTH
Definition draw_state.hh:29
#define DRW_STATE_DEPTH_TEST_ENABLED
Definition draw_state.hh:86
void DRW_texture_pool_free(DRWTexturePool *pool)
DRWTexturePool * DRW_texture_pool_create()
void DRW_texture_pool_reset(DRWTexturePool *pool)
void DRW_draw_gizmo_2d()
void DRW_draw_region_info()
void DRW_draw_cursor_2d()
void DRW_draw_gizmo_3d()
void DRW_view_data_use_engine(DRWViewData *view_data, DrawEngineType *engine_type)
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_engines_view_update(DRWViewData *view_data)
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)
DRWViewData * DRW_view_data_create(ListBase *engine_types)
void DRW_view_data_texture_list_size_validate(DRWViewData *view_data, const int size[2])
void DRW_view_data_reset(DRWViewData *view_data)
ViewportEngineData * DRW_view_data_engine_data_get_ensure(DRWViewData *view_data, DrawEngineType *engine_type)
void DRW_view_data_free_unused(DRWViewData *view_data)
#define DRW_ENABLED_ENGINE_ITER(view_data_, engine_, data_)
RenderEngineType DRW_engine_viewport_eevee_next_type
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
RenderEngineType DRW_engine_viewport_external_type
bool DRW_engine_external_acquire_for_image_editor()
DrawEngineType draw_engine_external_type
DrawEngineType draw_engine_gpencil_type
struct @620::@622 batch
DrawEngineType draw_engine_image_type
void RE_GetViewPlane(Render *re, rctf *r_viewplane, rcti *r_disprect)
void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
RenderResult * RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
RenderResult * RE_engine_get_result(RenderEngine *engine)
void RE_engines_register(RenderEngineType *render_type)
void RE_engine_end_result(RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results)
ListBase R_engines
#define GS(x)
Definition iris.cc:202
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
static ulong * next
#define G(x, y, z)
DrawEngineType draw_engine_overlay_type
DrawEngineType draw_engine_overlay_next_type
DrawEngineType draw_engine_debug_select_type
DrawEngineType draw_engine_select_type
SELECTID_Context * DRW_select_engine_context_get()
DrawEngineType draw_engine_select_next_type
static void draw_background()
void * RE_blender_gpu_context_ensure(Render *re)
void * RE_system_gpu_context_get(Render *re)
RenderLayer * RE_GetRenderLayer(RenderResult *rr, const char *name)
void RE_SetActiveRenderView(Render *re, const char *viewname)
const ViewerPath * viewer_path
Object * object_pose
ViewLayer * view_layer
Depsgraph * depsgraph
eGPUShaderConfig sh_cfg
eObjectMode object_mode
ARegion * region
const bContext * evil_C
RenderEngineType * engine_type
Object * object_edit
RegionView3D * rv3d
SpaceLink * space_data
BoundSphere bsphere
BLI_memblock * views
BLI_memblock * uniforms
void * volume_grids_ubos
GPUUniformBuf ** obinfos_ubo
BLI_memblock * cullstates
BLI_memblock * passes
GHash * vlattrs_name_cache
DRWInstanceDataList * idatalist
ListBase vlattrs_name_list
BLI_memblock * commands
GPUUniformBuf * vlattrs_ubo
GHash * obattrs_ubo_pool
BLI_memblock * images
BLI_memblock * callbuffers
BLI_memblock * obmats
DRWTexturePool * texture_pool
BLI_memblock * commands_small
LayerAttribute * vlattrs_buf
bool vlattrs_ubo_ready
blender::draw::CurvesUniformBufPool * curves_ubos
GPUUniformBuf ** matrices_ubo
DRWViewData * view_data[2]
BLI_memblock * obinfos
BLI_memblock * shgroups
DRWResourceHandle ob_handle
TaskGraph * task_graph
DRWResourceHandle pass_handle
DRWView * view_active
GSet * delayed_extraction
DRWContextState draw_ctx
DRWView * view_previous
bool buffer_finish_called
DRWResourceHandle resource_handle
DRWTextStore ** text_store_p
float inv_size[2]
DRWDebugModule * debug
void ** dupli_datas
GPUViewport * viewport
Object * dupli_origin
GPUContext * blender_gpu_context
DupliObject * dupli_source
DRWInstanceData * object_instance_data[MAX_INSTANCE_DATA_SIZE]
GPUFrameBuffer * default_framebuffer
uint is_material_select
struct DRWManager::@295 options
GPUDrawList * draw_list
TicketMutex * system_gpu_context_mutex
DRWData * vmempool
GHash * dupli_ghash
DRWView * view_default
Object * dupli_parent
void * system_gpu_context
DRWViewData * view_data_active
float orcotexfac[2][4]
float modelinverse[4][4]
DrawEngineType * draw_engine
GPUTexture * texture_depth
GPUFrameBuffer * framebuffer_depth_only
Depsgraph * depsgraph
Definition DRW_engine.hh:49
ViewLayer * view_layer
Definition DRW_engine.hh:51
ARegion * region
Definition DRW_engine.hh:52
RenderEngineType * engine_type
Definition DRW_engine.hh:54
GPUTexture * weight_ramp
GPUUniformBuf * view_ubo
GPUUniformBuf * clipping_ubo
GPUUniformBuf * block_ubo
GPUTexture * ramp
GPUFrameBuffer * overlay_fb
GPUFrameBuffer * default_fb
struct DrawEngineType * engine_type
Definition DNA_ID.h:46
DrawDataFreeCb free
Definition DNA_ID.h:48
void(* render_to_image)(void *vedata, RenderEngine *engine, RenderLayer *layer, const rcti *rect)
void(* store_metadata)(void *vedata, RenderResult *render_result)
Object * ob
Definition DNA_ID.h:413
DrawDataList drawdata
void * first
ListBase scenes
Definition BKE_main.hh:210
short base_flag
ObjectRuntimeHandle * runtime
ParticleSettings * part
struct PointCache * pointcache
float clip[6][4]
float viewmat[4][4]
float clip_local[6][4]
float winmat[4][4]
struct DrawEngineType * draw_engine
Definition RE_engine.h:119
RenderEngineType * type
Definition RE_engine.h:134
struct Render * re
Definition RE_engine.h:141
ListBase views
ListBase layers
struct RenderView * next
Definition RE_pipeline.h:46
blender::Array< Object * > objects
struct bNodeTree * nodetree
View3DOverlay overlay
ViewerPath viewer_path
int object_type_exclude_select
int object_type_exclude_viewport
View3DShading shading
struct DrawEngineType * engine_type
void(* free)(void *storage)
ListBase drawdata
char name[64]
DRWRegisteredDrawEngine * engine_type
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
Definition wm_draw.cc:905
GPUViewport * WM_draw_region_get_bound_viewport(ARegion *region)
Definition wm_draw.cc:915
void WM_init_gpu()
void wmOrtho2(float x1, float x2, float y1, float y2)
void * WM_system_gpu_context_create()
void wm_window_reset_drawable()
void WM_system_gpu_context_dispose(void *context)
void WM_system_gpu_context_activate(void *context)
void WM_system_gpu_context_release(void *context)
ARegionType * WM_xr_surface_controller_region_type_get()
RenderEngineType DRW_engine_viewport_workbench_type