Blender V4.5
draw_context.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
8
9#include <cstdio>
10
11#include "CLG_log.h"
12
13#include "BLI_listbase.h"
14#include "BLI_math_matrix.h"
15#include "BLI_math_vector.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_layer.hh"
35#include "BKE_main.hh"
36#include "BKE_mball.hh"
37#include "BKE_mesh.hh"
38#include "BKE_mesh_wrapper.hh"
39#include "BKE_modifier.hh"
40#include "BKE_object.hh"
41#include "BKE_object_types.hh"
42#include "BKE_paint.hh"
43#include "BKE_particle.h"
44#include "BKE_pointcache.h"
45#include "BKE_pointcloud.hh"
46#include "BKE_scene.hh"
47#include "BKE_screen.hh"
49#include "BKE_volume.hh"
50
51#include "DNA_camera_types.h"
52#include "DNA_mesh_types.h"
53#include "DNA_userdef_types.h"
54#include "DNA_view3d_types.h"
55#include "DNA_world_types.h"
56
57#include "ED_gpencil_legacy.hh"
58#include "ED_screen.hh"
59#include "ED_space_api.hh"
60#include "ED_view3d.hh"
61
62#include "GPU_capabilities.hh"
63#include "GPU_framebuffer.hh"
64#include "GPU_matrix.hh"
65#include "GPU_platform.hh"
66#include "GPU_shader_shared.hh"
67#include "GPU_state.hh"
68#include "GPU_uniform_buffer.hh"
69#include "GPU_viewport.hh"
70
71#include "UI_resources.hh"
72#include "UI_view2d.hh"
73
74#include "WM_api.hh"
75
76#include "draw_cache.hh"
78#include "draw_common_c.hh"
80#include "draw_manager_text.hh"
81#include "draw_shader.hh"
82#include "draw_subdivision.hh"
83#include "draw_view_c.hh"
84#include "draw_view_data.hh"
85
86/* only for callbacks */
87#include "draw_cache_impl.hh"
88
97
98#include "GPU_context.hh"
99
100#include "DEG_depsgraph.hh"
101#include "DEG_depsgraph_query.hh"
102
103#include "BLI_time.h"
104
105#include "DRW_select_buffer.hh"
106
107thread_local DRWContext *DRWContext::g_context = nullptr;
108
110{
111 return DRWContext::get_active();
112}
113
114DRWContext::DRWContext(Mode mode_,
115 Depsgraph *depsgraph,
116 const int2 size,
117 const bContext *C,
118 ARegion *region,
119 View3D *v3d)
120 : mode(mode_)
121{
122 BLI_assert(size.x > 0 && size.y > 0);
123
124 this->size = float2(size);
125 this->inv_size = 1.0f / this->size;
126
127 this->depsgraph = depsgraph;
128 this->scene = DEG_get_evaluated_scene(depsgraph);
129 this->view_layer = DEG_get_evaluated_view_layer(depsgraph);
130
131 this->evil_C = C;
132
133 this->region = (region) ? region : ((C) ? CTX_wm_region(C) : nullptr);
134 this->space_data = (C) ? CTX_wm_space_data(C) : nullptr;
135 this->v3d = (v3d) ? v3d : ((C) ? CTX_wm_view3d(C) : nullptr);
136 if (this->v3d != nullptr && this->region != nullptr) {
137 this->rv3d = static_cast<RegionView3D *>(this->region->regiondata);
138 }
139 /* Active object. Set to nullptr for render (when region is nullptr). */
140 this->obact = (this->region) ? BKE_view_layer_active_object_get(this->view_layer) : nullptr;
141 /* Object mode. */
142 this->object_mode = (this->obact) ? eObjectMode(this->obact->mode) : OB_MODE_OBJECT;
143 /* Edit object. */
144 this->object_edit = (this->object_mode & OB_MODE_EDIT) ? this->obact : nullptr;
145 /* Pose object. */
146 if (this->object_mode & OB_MODE_POSE) {
147 this->object_pose = this->obact;
148 }
149 else if (this->object_mode & OB_MODE_ALL_WEIGHT_PAINT) {
150 this->object_pose = BKE_object_pose_armature_get(this->obact);
151 }
152 else {
153 this->object_pose = nullptr;
154 }
155
156 /* TODO(fclem): This belongs to the overlay engine. */
157 if (this->v3d != nullptr && mode == DRWContext::VIEWPORT) {
158 this->options.draw_text = ((this->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
159 (this->v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0);
160 }
161
162 /* View layer can be lazily synced. */
163 BKE_view_layer_synced_ensure(this->scene, this->view_layer);
164
165 /* fclem: Is this still needed ? */
166 if (this->object_edit && rv3d) {
167 ED_view3d_init_mats_rv3d(this->object_edit, rv3d);
168 }
169
170 BLI_assert(g_context == nullptr);
171 g_context = this;
172}
173
192
194{
195 BLI_assert(g_context == this);
196 g_context = nullptr;
197}
198
200{
201 return view_data_active->dfbl.default_fb;
202}
203
208
213
215{
216 DRWContext &draw_ctx = drw_get();
217 SpaceLink *space_data = draw_ctx.space_data;
218 View3D *v3d = draw_ctx.v3d;
219
220 if (space_data != nullptr) {
221 switch (space_data->spacetype) {
222 case SPACE_IMAGE: {
223 SpaceImage *sima = (SpaceImage *)space_data;
224 return (sima->flag & SI_SHOW_GPENCIL) != 0;
225 }
226 case SPACE_NODE:
227 /* Don't draw the annotation for the node editor. Annotations are handled by space_image as
228 * the draw manager is only used to draw the background. */
229 return false;
230 default:
231 break;
232 }
233 }
234 return (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
235 ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
236}
237
238/* -------------------------------------------------------------------- */
241
243 public:
245
246 private:
247 /* WORKAROUND: BLI_gset_free is not allowing to pass a data pointer to the free function. */
248 static thread_local TaskGraph *task_graph_ptr_;
249
250 public:
252 {
253 BLI_assert_msg(graph == nullptr, "Missing call to work_and_wait");
254 }
255
256 /* `delayed_extraction` is a set of object to add to the graph before running.
257 * The non-null, the set is consumed and freed after use. */
258 void work_and_wait(GSet *&delayed_extraction)
259 {
260 BLI_assert_msg(graph, "Trying to submit more than once");
261
262 if (delayed_extraction) {
263 task_graph_ptr_ = graph;
264 BLI_gset_free(delayed_extraction, delayed_extraction_free_callback);
265 task_graph_ptr_ = nullptr;
266 delayed_extraction = nullptr;
267 }
268
271 graph = nullptr;
272 }
273
274 private:
275 static void delayed_extraction_free_callback(void *object)
276 {
278 reinterpret_cast<Object *>(object), *task_graph_ptr_);
279 }
280};
281
282thread_local TaskGraph *ExtractionGraph::task_graph_ptr_ = nullptr;
283
285
286/* -------------------------------------------------------------------- */
289
291{
293
294 if (ob->type == OB_MESH) {
295 DRWContext &draw_ctx = drw_get();
296 /* The evaluated object might be a mesh even though the original object has a different type.
297 * Also make sure the original object is a mesh (see #140762). */
298 if (draw_ctx.object_edit && draw_ctx.object_edit->type != OB_MESH) {
299 /* Noop. */
300 }
301 else if ((ob == draw_ctx.object_edit) || ob->mode == OB_MODE_EDIT) {
302 View3D *v3d = draw_ctx.v3d;
303 if (v3d && ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && RETOPOLOGY_ENABLED(v3d)) {
304 return false;
305 }
306 }
307 }
308
309 return true;
310}
311
313{
315 if (ELEM(ob->type, OB_MESH, OB_CURVES)) {
316 if ((ob->mode & OB_MODE_EDIT) == 0) {
317 return false;
318 }
319 }
320 return true;
321 }
322 return false;
323}
324
331
333{
334 if (ob->type == OB_MESH) {
335 switch (ob->mode) {
336 case OB_MODE_SCULPT:
340 return true;
341 }
342 }
343
344 return false;
345}
346
348{
349 const bool for_render = DRW_context_get()->is_image_render();
350 /* NOTE: psys_check_enabled is using object and particle system for only
351 * reading, but is using some other functions which are more generic and
352 * which are hard to make const-pointer. */
353 if (!psys_check_enabled((Object *)object, (ParticleSystem *)psys, for_render)) {
354 return false;
355 }
356 const DRWContext *draw_ctx = DRW_context_get();
357 const Scene *scene = draw_ctx->scene;
358 if (object == draw_ctx->object_edit) {
359 return false;
360 }
361 const ParticleSettings *part = psys->part;
362 const ParticleEditSettings *pset = &scene->toolsettings->particle;
363 if (object->mode == OB_MODE_PARTICLE_EDIT) {
364 if (psys_in_edit_mode(draw_ctx->depsgraph, psys)) {
365 if ((pset->flag & PE_DRAW_PART) == 0) {
366 return false;
367 }
368 if ((part->childtype == 0) &&
369 (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) == 0)
370 {
371 return false;
372 }
373 }
374 }
375 return true;
376}
377
379{
380 /* For drawing we want either the base mesh if GPU subdivision is enabled, or the
381 * tessellated mesh if GPU subdivision is disabled. */
382 BLI_assert(object.type == OB_MESH);
383 Mesh &mesh = *static_cast<Mesh *>(object.data);
385 return mesh;
386 }
388}
389
391{
392 /* Same as DRW_object_get_data_for_drawing, but for the cage mesh. */
393 BLI_assert(object.type == OB_MESH);
394 const Mesh *cage_mesh = BKE_object_get_editmesh_eval_cage(&object);
395 if (cage_mesh == nullptr) {
396 return nullptr;
397 }
398
400 return cage_mesh;
401 }
402 return BKE_mesh_wrapper_ensure_subdivision(cage_mesh);
403}
404
406
407/* -------------------------------------------------------------------- */
410
412{
413 DRWData *drw_data = MEM_callocN<DRWData>("DRWData");
414
415 drw_data->default_view = new blender::draw::View("DrawDefaultView");
416
417 for (int i = 0; i < 2; i++) {
418 drw_data->view_data[i] = new DRWViewData();
419 }
420 return drw_data;
421}
422
424{
425 using namespace blender::draw;
427 DRW_curves_init(this);
428 DRW_volume_init(this);
429}
430
432{
433 using namespace blender::draw;
436}
437
439{
440 DRW_smoke_exit(this);
441}
442
444{
445 for (int i = 0; i < 2; i++) {
446 delete drw_data->view_data[i];
447 }
451 delete drw_data->default_view;
452 MEM_freeN(drw_data);
453}
454
456{
457 DRWData **data_p = GPU_viewport_data_get(viewport);
458 DRWData *data = *data_p;
459
460 if (data == nullptr) {
461 *data_p = data = DRW_viewport_data_create();
462 }
463 return data;
464}
465
467{
469
471
472 {
473 /* Acquire DRWData. */
474 if (!this->viewport && this->data) {
475 /* Manager was init first without a viewport, created DRWData, but is being re-init.
476 * In this case, keep the old data. */
477 }
478 else if (this->viewport) {
479 /* Use viewport's persistent DRWData. */
481 }
482 else {
483 /* Create temporary DRWData. Freed in drw_manager_exit(). */
485 }
486 int view = (this->viewport) ? GPU_viewport_active_view_get(this->viewport) : 0;
487 this->view_data_active = this->data->view_data[view];
488
489 this->view_data_active->texture_list_size_validate(int2(this->size));
490
491 if (this->viewport) {
493 }
494 }
495 {
496 /* Create the default view. */
497 if (this->rv3d != nullptr) {
499 float4x4(this->rv3d->winmat));
500 }
501 else if (this->region) {
502 /* Assume that if rv3d is nullptr, we are drawing for a 2D area. */
503 View2D *v2d = &this->region->v2d;
504 rctf region_space = {0.0f, 1.0f, 0.0f, 1.0f};
505
506 float4x4 viewmat;
507 BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &region_space, viewmat.ptr());
508
509 float4x4 winmat = float4x4::identity();
510 winmat[0][0] = winmat[1][1] = 2.0f;
511 winmat[3][0] = winmat[3][1] = -1.0f;
512
513 blender::draw::View::default_set(viewmat, winmat);
514 }
515 else {
516 /* Assume that this is the render mode or custom mode and
517 * that the default view will be set appropriately or not used. */
519 }
520 }
521
522 /* Init modules ahead of time because the begin_sync happens before DRW_render_object_iter. */
523 this->data->modules_init();
524}
525
527{
529
530 this->data->modules_exit();
531
532 /* Reset drawing state to avoid to side-effects. */
534
536
537 if (this->data != nullptr && this->viewport == nullptr) {
539 }
540 this->data = nullptr;
541 this->viewport = nullptr;
542}
543
545{
547 pass_name, [&]() { return std::make_unique<blender::draw::TextureFromPool>(pass_name); });
548}
549
551{
552 if (drw_get().viewport) {
554 }
555}
556
558
559/* -------------------------------------------------------------------- */
562
563/* The Dupli systems generate a lot of transient objects that share the batch caches.
564 * So we ensure to only clear and generate the cache once per source instance type using this
565 * set. */
566/* TODO(fclem): This should be reconsidered as this has some unneeded overhead and complexity.
567 * Maybe it isn't needed at all. */
569 private:
570 /* Key identifying a single instance source. */
571 struct DupliKey {
572 Object *ob = nullptr;
573 ID *ob_data = nullptr;
574
575 bool operator==(const DupliObject *ob_dupli)
576 {
577 return this->ob == ob_dupli->ob && this->ob_data == ob_dupli->ob_data;
578 }
579
580 uint64_t hash() const
581 {
582 return blender::get_default_hash(this->ob, this->ob_data);
583 }
584
585 friend bool operator==(const DupliKey &a, const DupliKey &b)
586 {
587 return a.ob == b.ob && a.ob_data == b.ob_data;
588 }
589 };
590
591 /* Last key used. Allows to avoid the overhead of polling the `dupli_set` for each instance.
592 * This helps when a Dupli system generates a lot of similar geometry consecutively. */
593 DupliKey last_key_ = {};
594
595 /* Set containing all visited Dupli source object. */
596 blender::Set<DupliKey> *dupli_set_ = nullptr;
597
598 public:
599 void try_add(blender::draw::ObjectRef &ob_ref);
600 void extract_all(ExtractionGraph &extraction);
601};
602
604{
605 if (ob_ref.is_dupli() == false) {
606 return;
607 }
608 if (last_key_ == ob_ref.dupli_object) {
609 /* Same data as previous iteration. No need to perform the check again. */
610 return;
611 }
612
613 last_key_.ob = ob_ref.dupli_object->ob;
614 last_key_.ob_data = ob_ref.dupli_object->ob_data;
615
616 if (dupli_set_ == nullptr) {
617 dupli_set_ = MEM_new<blender::Set<DupliKey>>("DupliCacheManager::dupli_set_");
618 }
619
620 if (dupli_set_->add(last_key_)) {
621 /* Key is newly added. It is the first time we sync this object. */
622 /* TODO: Meh a bit out of place but this is nice as it is
623 * only done once per instance type. */
624 /* Note that this can happen for geometry data whose type is different from the original
625 * object (e.g. Text evaluated as Mesh, Geometry node instance etc...).
626 * In this case, key.ob is not going to have the same data type as ob_ref.object nor the same
627 * data at all. */
629 }
630}
631
633{
634 /* Reset for next iter. */
635 last_key_ = {};
636
637 if (dupli_set_ == nullptr) {
638 return;
639 }
640
641 /* Note these can referenced by the temporary object pointer `Object *ob` and needs to have at
642 * least the same lifetime. */
643 blender::bke::ObjectRuntime tmp_runtime;
644 Object tmp_object;
645
647 Iter begin = dupli_set_->begin();
648 Iter end = dupli_set_->end();
649 for (Iter iter = begin; iter != end; ++iter) {
650 const DupliKey &key = *iter;
651 Object *ob = iter->ob;
652
653 if (key.ob_data != ob->data) {
654 /* Copy both object data and runtime. */
655 tmp_runtime = *ob->runtime;
656 tmp_object = blender::dna::shallow_copy(*ob);
657 tmp_object.runtime = &tmp_runtime;
658 /* Geometry instances shouldn't be rendered with edit mode overlays. */
659 tmp_object.mode = OB_MODE_OBJECT;
660 /* Do not modify the original bound-box. */
661 BKE_object_replace_data_on_shallow_copy(&tmp_object, key.ob_data);
662
663 ob = &tmp_object;
664 }
665
667 }
668
669 /* TODO(fclem): Could eventually keep the set allocated. */
670 MEM_SAFE_DELETE(dupli_set_);
671}
672
674
675/* -------------------------------------------------------------------- */
678
679namespace blender::draw {
680
682{
683 this->dupli_parent = iter_data.dupli_parent;
684 this->dupli_object = iter_data.dupli_object_current;
685 this->object = ob;
686 /* Set by the first draw-call. */
687 this->handle = ResourceHandle(0);
688}
689
691{
692 this->dupli_parent = nullptr;
693 this->dupli_object = nullptr;
694 this->object = ob;
695 /* Set by the first draw-call. */
696 this->handle = ResourceHandle(0);
697}
698
699} // namespace blender::draw
700
702
703/* -------------------------------------------------------------------- */
706
708{
709 using namespace blender::draw;
710 Scene *scene;
711 static int lasttime = 0;
712 int ctime = int(BLI_time_now_seconds());
713
714 if (U.vbotimeout == 0 || (ctime - lasttime) < U.vbocollectrate || ctime == lasttime) {
715 return;
716 }
717
718 lasttime = ctime;
719
720 for (scene = static_cast<Scene *>(bmain->scenes.first); scene;
721 scene = static_cast<Scene *>(scene->id.next))
722 {
723 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
724 Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer);
725 if (depsgraph == nullptr) {
726 continue;
727 }
728
729 /* TODO(fclem): This is not optimal since it iter over all dupli instances.
730 * In this case only the source object should be tagged. */
731 DEGObjectIterSettings deg_iter_settings = {nullptr};
732 deg_iter_settings.depsgraph = depsgraph;
734 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
735 DRW_batch_cache_free_old(ob, ctime);
736 }
738 }
739 }
740}
741
743
744/* -------------------------------------------------------------------- */
747
749 DupliCacheManager &dupli_cache,
750 ExtractionGraph &extraction)
751{
752 if (ref.is_dupli() == false) {
754 }
755 else {
756 dupli_cache.try_add(ref);
757 }
758
759 DRWContext &ctx = drw_get();
761 [&](DrawEngine &instance) { instance.object_sync(ref, *DRW_manager_get()); });
762
763 /* TODO: in the future it would be nice to generate once for all viewports.
764 * But we need threaded DRW manager first. */
765 if (ref.is_dupli() == false) {
767 }
768 /* Batch generation for duplis happens after iter_callback. */
769}
770
772{
773 /* Enable modules and init for next sync. */
774 data->modules_begin_sync();
775
776 DupliCacheManager dupli_handler;
777 ExtractionGraph extraction;
778
779 /* Custom callback defines the set of object to sync. */
780 iter_callback(dupli_handler, extraction);
781
782 dupli_handler.extract_all(extraction);
783 extraction.work_and_wait(this->delayed_extraction);
784
786}
787
789{
790 view_data_active->foreach_enabled_engine([&](DrawEngine &instance) { instance.init(); });
791
792 view_data_active->manager->begin_sync(this->obact);
793
794 view_data_active->foreach_enabled_engine([&](DrawEngine &instance) {
795 /* TODO(fclem): Remove. Only there for overlay engine. */
796 if (instance.text_draw_cache) {
798 instance.text_draw_cache = nullptr;
799 }
800 if (text_store_p == nullptr) {
801 text_store_p = &instance.text_draw_cache;
802 }
803
804 instance.begin_sync();
805 });
806
807 sync(iter_callback);
808
809 view_data_active->foreach_enabled_engine([&](DrawEngine &instance) { instance.end_sync(); });
810
811 view_data_active->manager->end_sync();
812}
813
815{
816 /* Start Drawing */
818
819 view_data_active->foreach_enabled_engine([&](DrawEngine &instance) {
821 instance.draw(*DRW_manager_get());
823 });
824
825 /* Reset state after drawing */
827
828 /* Fix 3D view "lagging" on APPLE and WIN32+NVIDIA. (See #56996, #61474) */
830 GPU_flush();
831 }
832}
833
835{
836 DRWContext &ctx = drw_get();
838 if (instance.text_draw_cache) {
839 DRW_text_cache_draw(instance.text_draw_cache, ctx.region, ctx.v3d);
840 }
841 });
842}
843
844void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height)
845{
846 DRWContext &ctx = drw_get();
848 if (instance.info[0] != '\0') {
849 const char *buf_step = IFACE_(instance.info);
850 do {
851 const char *buf = buf_step;
852 buf_step = BLI_strchr_or_end(buf, '\n');
853 const int buf_len = buf_step - buf;
854 *yoffset -= line_height;
855 BLF_draw_default(xoffset, *yoffset, 0.0f, buf, buf_len);
856 } while (*buf_step ? ((void)buf_step++, true) : false);
857 }
858 });
859}
860
861void DRWContext::enable_engines(bool gpencil_engine_needed, RenderEngineType *render_engine_type)
862{
863 DRWViewData &view_data = *this->view_data_active;
864
865 SpaceLink *space_data = this->space_data;
866 if (space_data && space_data->spacetype == SPACE_IMAGE) {
868 view_data.external.set_used(true);
869 }
870 else {
871 view_data.image.set_used(true);
872 }
873 view_data.overlay.set_used(true);
874 return;
875 }
876
877 if (space_data && space_data->spacetype == SPACE_NODE) {
878 /* Only enable when drawing the space image backdrop. */
879 SpaceNode *snode = (SpaceNode *)space_data;
880 if ((snode->flag & SNODE_BACKDRAW) != 0) {
881 view_data.image.set_used(true);
882 view_data.overlay.set_used(true);
883 }
884 return;
885 }
886
888 view_data.grease_pencil.set_used(gpencil_engine_needed);
889 view_data.object_select.set_used(true);
890 return;
891 }
892
894 view_data.edit_select.set_used(true);
895 return;
896 }
897
899 view_data.grease_pencil.set_used(gpencil_engine_needed);
900 view_data.overlay.set_used(true);
901 return;
902 }
903
904 /* Regular V3D drawing. */
905 {
906 const eDrawType drawtype = eDrawType(this->v3d->shading.type);
907 const bool use_xray = XRAY_ENABLED(this->v3d);
908
909 /* Base engine. */
910 switch (drawtype) {
911 case OB_WIRE:
912 case OB_SOLID:
913 view_data.workbench.set_used(true);
914 break;
915 case OB_MATERIAL:
916 case OB_RENDER:
917 default:
918 if (render_engine_type == &DRW_engine_viewport_eevee_type) {
919 view_data.eevee.set_used(true);
920 }
921 else if (render_engine_type == &DRW_engine_viewport_workbench_type) {
922 view_data.workbench.set_used(true);
923 }
924 else if ((render_engine_type->flag & RE_INTERNAL) == 0) {
925 view_data.external.set_used(true);
926 }
927 else {
929 }
930 break;
931 }
932
933 if ((drawtype >= OB_SOLID) || !use_xray) {
934 view_data.grease_pencil.set_used(gpencil_engine_needed);
935 }
936
938
939 view_data.overlay.set_used(true);
940
941#ifdef WITH_DRAW_DEBUG
942 if (G.debug_value == 31) {
943 view_data.edit_select_debug.set_used(true);
944 }
945#endif
946 }
947}
948
953
955{
956 if (v3d) {
957 return ((v3d->object_type_exclude_viewport & (1 << OB_GREASE_PENCIL)) != 0);
958 }
959 return false;
960}
961
967
969{
971 return false;
972 }
974}
975
976/* -------------------------------------------------------------------- */
979
981{
982 RegionView3D *rv3d = draw_ctx.rv3d;
983
985 GPU_matrix_set(rv3d->viewmat);
986
987 if (draw_ctx.evil_C) {
992 }
993
994 /* State is reset later at the beginning of `draw_ctx.engines_draw_scene()`. */
995}
996
998{
999 RegionView3D *rv3d = draw_ctx.rv3d;
1000 ARegion *region = draw_ctx.region;
1001 View3D *v3d = draw_ctx.v3d;
1002 Depsgraph *depsgraph = draw_ctx.depsgraph;
1003
1004 const bool do_annotations = draw_show_annotation();
1005
1006 /* State has been reset at the end `draw_ctx.engines_draw_scene()`. */
1007
1009 if (draw_ctx.evil_C) {
1011
1013
1015 GPU_matrix_set(rv3d->viewmat);
1016
1017 /* annotations - temporary drawing buffer (3d space) */
1018 /* XXX: Or should we use a proper draw/overlay engine for this case? */
1019 if (do_annotations) {
1021 /* XXX: as `scene->gpd` is not copied for copy-on-eval yet. */
1024 }
1025
1027 /* Apply state for callbacks. */
1029
1031
1032#ifdef WITH_XR_OPENXR
1033 /* XR callbacks (controllers, custom draw functions) for session mirror. */
1034 if ((v3d->flag & V3D_XR_SESSION_MIRROR) != 0) {
1035 if ((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) {
1037 if (art) {
1039 }
1040 }
1041 if ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0) {
1043 if (st) {
1045 if (art) {
1047 }
1048 }
1049 }
1050 }
1051#endif
1052
1053 /* Callback can be nasty and do whatever they want with the state.
1054 * Don't trust them! */
1056
1057 /* Needed so gizmo isn't occluded. */
1058 if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
1060 DRW_draw_gizmo_3d(draw_ctx.evil_C, region);
1061 }
1062
1065
1066 DRW_draw_region_info(draw_ctx.evil_C, region);
1067
1068 /* Annotations - temporary drawing buffer (screen-space). */
1069 /* XXX: Or should we use a proper draw/overlay engine for this case? */
1070 if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
1072 /* XXX: as `scene->gpd` is not copied for copy-on-eval yet */
1074 }
1075
1076 if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
1077 /* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
1078 * 'DRW_draw_region_info' sets the projection in pixel-space. */
1080 DRW_draw_gizmo_2d(draw_ctx.evil_C, region);
1081 }
1082
1084 }
1085 else {
1086 if (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0)) {
1088 /* XXX: as `scene->gpd` is not copied for copy-on-eval yet */
1091 }
1092
1093#ifdef WITH_XR_OPENXR
1094 if ((v3d->flag & V3D_XR_SESSION_SURFACE) != 0) {
1096
1098
1100
1102 GPU_matrix_set(rv3d->viewmat);
1103
1104 /* XR callbacks (controllers, custom draw functions) for session surface. */
1105 if (((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) ||
1106 ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0))
1107 {
1110
1111 if ((v3d->flag2 & V3D_XR_SHOW_CONTROLLERS) != 0) {
1113 if (art) {
1115 }
1116 }
1117 if ((v3d->flag2 & V3D_XR_SHOW_CUSTOM_OVERLAYS) != 0) {
1119 if (st) {
1121 if (art) {
1123 }
1124 }
1125 }
1126
1128 }
1129
1131 }
1132#endif
1133 }
1135
1137}
1138
1140{
1141 if (draw_ctx.evil_C) {
1146 }
1147
1148 /* State is reset later at the beginning of `draw_ctx.engines_draw_scene()`. */
1149}
1150
1152{
1153 const bool do_annotations = draw_show_annotation();
1154 const bool do_draw_gizmos = (draw_ctx.space_data->spacetype != SPACE_IMAGE);
1155
1156 /* State has been reset at the end `draw_ctx.engines_draw_scene()`. */
1157
1159 if (draw_ctx.evil_C) {
1161
1163
1166
1167 wmOrtho2(v2d.cur.xmin, v2d.cur.xmax, v2d.cur.ymin, v2d.cur.ymax);
1168
1169 if (do_annotations) {
1170 ED_annotation_draw_view2d(draw_ctx.evil_C, true);
1171 }
1172
1174
1176
1178 /* Callback can be nasty and do whatever they want with the state.
1179 * Don't trust them! */
1181
1184
1185 if (do_annotations) {
1187 ED_annotation_draw_view2d(draw_ctx.evil_C, false);
1188 }
1189 }
1190
1191 ED_region_pixelspace(draw_ctx.region);
1192
1193 if (do_draw_gizmos) {
1195 DRW_draw_gizmo_2d(draw_ctx.evil_C, draw_ctx.region);
1196 }
1197
1199
1201}
1202
1204{
1205 DRWContext &draw_ctx = drw_get();
1206 BLI_assert(draw_ctx.text_store_p);
1207 if (*draw_ctx.text_store_p == nullptr) {
1208 *draw_ctx.text_store_p = DRW_text_cache_create();
1209 }
1210 return *draw_ctx.text_store_p;
1211}
1212
1214
1215/* -------------------------------------------------------------------- */
1218
1223static void drw_draw_render_loop_3d(DRWContext &draw_ctx, RenderEngineType *engine_type)
1224{
1225 using namespace blender::draw;
1226 Depsgraph *depsgraph = draw_ctx.depsgraph;
1227 View3D *v3d = draw_ctx.v3d;
1228
1229 const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
1230 /* Check if scene needs to perform the populate loop */
1231 const bool internal_engine = (engine_type->flag & RE_INTERNAL) != 0;
1232 const bool draw_type_render = v3d->shading.type == OB_RENDER;
1233 const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
1234 const bool gpencil_engine_needed = DRW_gpencil_engine_needed_viewport(depsgraph, v3d);
1235 const bool do_populate_loop = internal_engine || overlays_on || !draw_type_render ||
1236 gpencil_engine_needed;
1237
1238 draw_ctx.enable_engines(gpencil_engine_needed, engine_type);
1239 draw_ctx.engines_data_validate();
1240 draw_ctx.engines_init_and_sync([&](DupliCacheManager &duplis, ExtractionGraph &extraction) {
1241 /* Only iterate over objects for internal engines or when overlays are enabled */
1242 if (do_populate_loop) {
1243 DEGObjectIterSettings deg_iter_settings = {nullptr};
1244 deg_iter_settings.depsgraph = depsgraph;
1246 if (v3d->flag2 & V3D_SHOW_VIEWER) {
1247 deg_iter_settings.viewer_path = &v3d->viewer_path;
1248 }
1249 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1250 if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
1251 continue;
1252 }
1253 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
1254 continue;
1255 }
1256 blender::draw::ObjectRef ob_ref(data_, ob);
1257 drw_engines_cache_populate(ob_ref, duplis, extraction);
1258 }
1260 }
1261 });
1262
1263 /* No frame-buffer allowed before drawing. */
1267
1268 drw_callbacks_pre_scene(draw_ctx);
1269 draw_ctx.engines_draw_scene();
1270 drw_callbacks_post_scene(draw_ctx);
1271
1273 /* Don't unbind the frame-buffer yet in this case and let
1274 * GPU_viewport_unbind do it, so that we can still do further
1275 * drawing of action zones on top. */
1276 }
1277 else {
1279 }
1280}
1281
1283{
1284 Depsgraph *depsgraph = draw_ctx.depsgraph;
1285 ARegion *region = draw_ctx.region;
1286
1287 /* TODO(jbakker): Only populate when editor needs to draw object.
1288 * for the image editor this is when showing UVs. */
1289 const bool do_populate_loop = (draw_ctx.space_data->spacetype == SPACE_IMAGE);
1290
1291 draw_ctx.enable_engines();
1292 draw_ctx.engines_data_validate();
1293 draw_ctx.engines_init_and_sync([&](DupliCacheManager &duplis, ExtractionGraph &extraction) {
1294 /* Only iterate over objects when overlay uses object data. */
1295 if (do_populate_loop) {
1296 DEGObjectIterSettings deg_iter_settings = {nullptr};
1297 deg_iter_settings.depsgraph = depsgraph;
1299 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1300 blender::draw::ObjectRef ob_ref(ob);
1301 drw_engines_cache_populate(ob_ref, duplis, extraction);
1302 }
1304 }
1305 });
1306
1307 /* No frame-buffer allowed before drawing. */
1311
1313 draw_ctx.engines_draw_scene();
1314 drw_callbacks_post_scene_2D(draw_ctx, region->v2d);
1315
1317 /* Don't unbind the frame-buffer yet in this case and let
1318 * GPU_viewport_unbind do it, so that we can still do further
1319 * drawing of action zones on top. */
1320 }
1321 else {
1323 }
1324}
1325
1327{
1329 ARegion *region = CTX_wm_region(C);
1331
1332 DRWContext draw_ctx(DRWContext::VIEWPORT, depsgraph, viewport, C);
1333 draw_ctx.acquire_data();
1334
1335 if (draw_ctx.v3d) {
1337 RenderEngineType *engine_type = ED_view3d_engine_type(scene, draw_ctx.v3d->shading.type);
1338
1339 draw_ctx.options.draw_background = (scene->r.alphamode == R_ADDSKY) ||
1340 (draw_ctx.v3d->shading.type != OB_RENDER);
1341
1342 drw_draw_render_loop_3d(draw_ctx, engine_type);
1343 }
1344 else {
1345 drw_draw_render_loop_2d(draw_ctx);
1346 }
1347
1348 draw_ctx.release_data();
1349}
1350
1352 RenderEngineType *engine_type,
1353 ARegion *region,
1354 View3D *v3d,
1355 const bool is_image_render,
1356 const bool draw_background,
1357 const bool do_color_management,
1358 GPUOffScreen *ofs,
1359 GPUViewport *viewport)
1360{
1361 const bool is_xr_surface = ((v3d->flag & V3D_XR_SESSION_SURFACE) != 0);
1362
1363 /* Create temporary viewport if needed or update the existing viewport. */
1364 GPUViewport *render_viewport = viewport;
1365 if (viewport == nullptr) {
1366 render_viewport = GPU_viewport_create();
1367 }
1368
1369 GPU_viewport_bind_from_offscreen(render_viewport, ofs, is_xr_surface);
1370
1371 /* Just here to avoid an assert but shouldn't be required in practice. */
1373
1374 /* TODO(fclem): We might want to differentiate between render preview and offscreen render in the
1375 * future. The later can do progressive rendering. */
1376 BLI_assert(is_xr_surface == !is_image_render);
1377 UNUSED_VARS_NDEBUG(is_image_render);
1379
1380 DRWContext draw_ctx(mode, depsgraph, render_viewport, nullptr, region, v3d);
1381 draw_ctx.acquire_data();
1383
1384 drw_draw_render_loop_3d(draw_ctx, engine_type);
1385
1386 draw_ctx.release_data();
1387
1388 if (draw_background) {
1389 /* HACK(@fclem): In this case we need to make sure the final alpha is 1.
1390 * We use the blend mode to ensure that. A better way to fix that would
1391 * be to do that in the color-management shader. */
1392 GPU_offscreen_bind(ofs, false);
1393 GPU_clear_color(0.0f, 0.0f, 0.0f, 1.0f);
1394 /* Pre-multiply alpha over black background. */
1396 }
1397
1400 const bool do_overlays = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 ||
1401 ELEM(v3d->shading.type, OB_WIRE, OB_SOLID) ||
1402 (ELEM(v3d->shading.type, OB_MATERIAL) &&
1403 (v3d->shading.flag & V3D_SHADING_SCENE_WORLD) == 0) ||
1404 (ELEM(v3d->shading.type, OB_RENDER) &&
1406 GPU_viewport_unbind_from_offscreen(render_viewport, ofs, do_color_management, do_overlays);
1407
1408 if (draw_background) {
1409 /* Reset default. */
1411 }
1412
1413 /* Free temporary viewport. */
1414 if (viewport == nullptr) {
1415 GPU_viewport_free(render_viewport);
1416 }
1417}
1418
1420{
1422 return true;
1423 }
1424
1425 DEGObjectIterSettings deg_iter_settings = {nullptr};
1426 deg_iter_settings.depsgraph = depsgraph;
1428 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1429 if (ob->type == OB_GREASE_PENCIL) {
1431 return true;
1432 }
1433 }
1434 }
1436
1437 return false;
1438}
1439
1441{
1442 using namespace blender::draw;
1443 /* This function should only be called if there are grease pencil objects,
1444 * especially important to avoid failing in background renders without GPU context. */
1446
1449 RenderResult *render_result = RE_engine_get_result(engine);
1450 RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name);
1451 if (render_layer == nullptr) {
1452 return;
1453 }
1454
1455 Render *render = engine->re;
1456
1458
1459 DRWContext draw_ctx(DRWContext::RENDER, depsgraph, {engine->resolution_x, engine->resolution_y});
1460 draw_ctx.acquire_data();
1461 draw_ctx.options.draw_background = scene->r.alphamode == R_ADDSKY;
1462
1463 /* Main rendering. */
1464 rctf view_rect;
1465 rcti render_rect;
1466 RE_GetViewPlane(render, &view_rect, &render_rect);
1467 if (BLI_rcti_is_empty(&render_rect)) {
1468 BLI_rcti_init(&render_rect, 0, draw_ctx.size[0], 0, draw_ctx.size[1]);
1469 }
1470
1471 for (RenderView *render_view = static_cast<RenderView *>(render_result->views.first);
1472 render_view != nullptr;
1473 render_view = render_view->next)
1474 {
1475 RE_SetActiveRenderView(render, render_view->name);
1476 gpencil::Engine::render_to_image(engine, render_layer, render_rect);
1477 }
1478
1480
1482
1484
1485 draw_ctx.release_data();
1486
1487 /* Restore Drawing area. */
1489
1491}
1492
1494 RenderEngine *engine,
1495 Depsgraph *depsgraph,
1496 std::function<void(RenderEngine *, RenderLayer *, const rcti)> render_view_cb,
1497 std::function<void(RenderResult *)> store_metadata_cb)
1498{
1499 using namespace blender::draw;
1502 Render *render = engine->re;
1503
1504 /* IMPORTANT: We don't support immediate mode in render mode!
1505 * This shall remain in effect until immediate mode supports
1506 * multiple threads. */
1507
1508 /* Begin GPU workload Boundary */
1510
1511 DRWContext draw_ctx(DRWContext::RENDER, depsgraph, {engine->resolution_x, engine->resolution_y});
1512 draw_ctx.acquire_data();
1513 draw_ctx.options.draw_background = scene->r.alphamode == R_ADDSKY;
1514
1515 /* Main rendering. */
1516 rctf view_rect;
1517 rcti render_rect;
1518 RE_GetViewPlane(render, &view_rect, &render_rect);
1519 if (BLI_rcti_is_empty(&render_rect)) {
1520 BLI_rcti_init(&render_rect, 0, draw_ctx.size[0], 0, draw_ctx.size[1]);
1521 }
1522
1523 /* Reset state before drawing */
1525
1526 /* set default viewport */
1527 GPU_viewport(0, 0, draw_ctx.size[0], draw_ctx.size[1]);
1528
1529 /* Init render result. */
1530 RenderResult *render_result = RE_engine_begin_result(engine,
1531 0,
1532 0,
1533 draw_ctx.size[0],
1534 draw_ctx.size[1],
1535 view_layer->name,
1536 /*RR_ALL_VIEWS*/ nullptr);
1537 RenderLayer *render_layer = static_cast<RenderLayer *>(render_result->layers.first);
1538 for (RenderView *render_view = static_cast<RenderView *>(render_result->views.first);
1539 render_view != nullptr;
1540 render_view = render_view->next)
1541 {
1542 RE_SetActiveRenderView(render, render_view->name);
1543 render_view_cb(engine, render_layer, render_rect);
1544 }
1545
1546 RE_engine_end_result(engine, render_result, false, false, false);
1547
1548 store_metadata_cb(RE_engine_get_result(engine));
1549
1551
1553
1554 draw_ctx.release_data();
1556
1557 /* End GPU workload Boundary */
1559}
1560
1562 RenderEngine *engine,
1563 Depsgraph *depsgraph,
1564 std::function<void(blender::draw::ObjectRef &, RenderEngine *, Depsgraph *)> callback)
1565{
1566 DRWContext &draw_ctx = drw_get();
1567
1568 const int object_type_exclude_viewport = draw_ctx.v3d ?
1570 0;
1571
1572 draw_ctx.sync([&](DupliCacheManager &duplis, ExtractionGraph &extraction) {
1573 DEGObjectIterSettings deg_iter_settings = {nullptr};
1574 deg_iter_settings.depsgraph = depsgraph;
1576 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1577 if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
1578 blender::draw::ObjectRef ob_ref(data_, ob);
1579 if (ob_ref.is_dupli() == false) {
1581 }
1582 else {
1583 duplis.try_add(ob_ref);
1584 }
1585 callback(ob_ref, engine, depsgraph);
1586 if (ob_ref.is_dupli() == false) {
1588 }
1589 /* Batch generation for duplis happens after iter_callback. */
1590 }
1591 }
1593 });
1594}
1595
1596void DRW_custom_pipeline_begin(DRWContext &draw_ctx, Depsgraph * /*depsgraph*/)
1597{
1598 draw_ctx.acquire_data();
1599 draw_ctx.data->modules_begin_sync();
1600}
1601
1603{
1605
1606 /* The use of custom pipeline in other thread using the same
1607 * resources as the main thread (viewport) may lead to data
1608 * races and undefined behavior on certain drivers. Using
1609 * GPU_finish to sync seems to fix the issue. (see #62997) */
1611 if (type == GPU_BACKEND_OPENGL) {
1612 GPU_finish();
1613 }
1614
1616 draw_ctx.release_data();
1617}
1618
1620{
1621 using namespace blender::draw;
1622 DRWContext &draw_ctx = drw_get();
1623 draw_ctx.data->modules_exit();
1624 draw_ctx.acquire_data();
1625 draw_ctx.data->modules_begin_sync();
1626}
1627
1628void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
1629{
1630 DRWContext &draw_ctx = drw_get();
1631 RE_engine_frame_set(engine, frame, subframe);
1634}
1635
1636static struct DRWSelectBuffer {
1637 GPUFrameBuffer *framebuffer_depth_only;
1638 GPUTexture *texture_depth;
1639} g_select_buffer = {nullptr};
1640
1642{
1643 if (g_select_buffer.framebuffer_depth_only == nullptr) {
1644 g_select_buffer.framebuffer_depth_only = GPU_framebuffer_create("framebuffer_depth_only");
1645 }
1646
1647 if ((g_select_buffer.texture_depth != nullptr) &&
1648 ((GPU_texture_width(g_select_buffer.texture_depth) != size[0]) ||
1649 (GPU_texture_height(g_select_buffer.texture_depth) != size[1])))
1650 {
1651 GPU_texture_free(g_select_buffer.texture_depth);
1652 g_select_buffer.texture_depth = nullptr;
1653 }
1654
1655 if (g_select_buffer.texture_depth == nullptr) {
1657 g_select_buffer.texture_depth = GPU_texture_create_2d(
1658 "select_depth", size[0], size[1], 1, GPU_DEPTH_COMPONENT24, usage, nullptr);
1659
1661 g_select_buffer.framebuffer_depth_only, g_select_buffer.texture_depth, 0, 0);
1662
1663 GPU_framebuffer_check_valid(g_select_buffer.framebuffer_depth_only, nullptr);
1664 }
1665}
1666
1668 ARegion *region,
1669 View3D *v3d,
1670 bool use_obedit_skip,
1671 bool draw_surface,
1672 bool /*use_nearest*/,
1673 const bool do_material_sub_selection,
1674 const rcti *rect,
1675 DRW_SelectPassFn select_pass_fn,
1676 void *select_pass_user_data,
1677 DRW_ObjectFilterFn object_filter_fn,
1678 void *object_filter_user_data)
1679{
1680 using namespace blender::draw;
1683 const int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
1684
1685 Object *obact = BKE_view_layer_active_object_get(view_layer);
1686 Object *obedit = use_obedit_skip ? nullptr : OBEDIT_FROM_OBACT(obact);
1687
1688 bool use_obedit = false;
1689 /* obedit_ctx_mode is used for selecting the right draw engines */
1690 // eContextObjectMode obedit_ctx_mode;
1691 /* object_mode is used for filtering objects in the depsgraph */
1692 eObjectMode object_mode = eObjectMode::OB_MODE_EDIT;
1693 int object_type = 0;
1694 if (obedit != nullptr) {
1695 object_type = obedit->type;
1696 object_mode = eObjectMode(obedit->mode);
1697 if (obedit->type == OB_MBALL) {
1698 use_obedit = true;
1699 // obedit_ctx_mode = CTX_MODE_EDIT_METABALL;
1700 }
1701 else if (obedit->type == OB_ARMATURE) {
1702 use_obedit = true;
1703 // obedit_ctx_mode = CTX_MODE_EDIT_ARMATURE;
1704 }
1705 }
1707 if (!(v3d->flag2 & V3D_HIDE_OVERLAYS)) {
1708 /* NOTE: don't use "BKE_object_pose_armature_get" here, it breaks selection. */
1709 Object *obpose = OBPOSE_FROM_OBACT(obact);
1710 if (obpose == nullptr) {
1711 Object *obweight = OBWEIGHTPAINT_FROM_OBACT(obact);
1712 if (obweight) {
1713 /* Only use Armature pose selection, when connected armature is in pose mode. */
1714 Object *ob_armature = BKE_modifiers_is_deformed_by_armature(obweight);
1715 if (ob_armature && ob_armature->mode == OB_MODE_POSE) {
1716 obpose = ob_armature;
1717 }
1718 }
1719 }
1720
1721 if (obpose) {
1722 use_obedit = true;
1723 object_type = obpose->type;
1724 object_mode = eObjectMode(obpose->mode);
1725 // obedit_ctx_mode = CTX_MODE_POSE;
1726 }
1727 }
1728 }
1729
1730 bool use_gpencil = !use_obedit && !draw_surface &&
1732
1733 DRWContext::Mode mode = do_material_sub_selection ? DRWContext::SELECT_OBJECT_MATERIAL :
1735
1736 DRWContext draw_ctx(mode, depsgraph, viewport_size, nullptr, region, v3d);
1737 draw_ctx.acquire_data();
1738 draw_ctx.enable_engines(use_gpencil);
1739 draw_ctx.engines_data_validate();
1740 draw_ctx.engines_init_and_sync([&](DupliCacheManager &duplis, ExtractionGraph &extraction) {
1741 if (use_obedit) {
1742 FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, object_type, object_mode, ob_iter) {
1743 /* Depsgraph usually does this, but we use a different iterator.
1744 * So we have to do it manually. */
1745 ob_iter->runtime->select_id = DEG_get_original(ob_iter)->runtime->select_id;
1746
1747 blender::draw::ObjectRef ob_ref(ob_iter);
1748 drw_engines_cache_populate(ob_ref, duplis, extraction);
1749 }
1751 }
1752 else {
1753 /* When selecting pose-bones in pose mode, check for visibility not select-ability
1754 * as pose-bones have their own selection restriction flag. */
1755 const bool use_pose_exception = (draw_ctx.object_pose != nullptr);
1756
1757 const int object_type_exclude_select = (v3d->object_type_exclude_viewport |
1759 bool filter_exclude = false;
1760 DEGObjectIterSettings deg_iter_settings = {nullptr};
1761 deg_iter_settings.depsgraph = depsgraph;
1763 if (v3d->flag2 & V3D_SHOW_VIEWER) {
1764 deg_iter_settings.viewer_path = &v3d->viewer_path;
1765 }
1766 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1767 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
1768 continue;
1769 }
1770
1771 if (use_pose_exception && (ob->mode & OB_MODE_POSE)) {
1772 if ((ob->base_flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT) == 0) {
1773 continue;
1774 }
1775 }
1776 else {
1777 if ((ob->base_flag & BASE_SELECTABLE) == 0) {
1778 continue;
1779 }
1780 }
1781
1782 if ((object_type_exclude_select & (1 << ob->type)) == 0) {
1783 if (object_filter_fn != nullptr) {
1784 if (ob->base_flag & BASE_FROM_DUPLI) {
1785 /* pass (use previous filter_exclude value) */
1786 }
1787 else {
1788 filter_exclude = (object_filter_fn(ob, object_filter_user_data) == false);
1789 }
1790 if (filter_exclude) {
1791 continue;
1792 }
1793 }
1794
1795 blender::draw::ObjectRef ob_ref(data_, ob);
1796 drw_engines_cache_populate(ob_ref, duplis, extraction);
1797 }
1798 }
1800 }
1801 });
1802
1803 /* Setup frame-buffer. */
1805 GPU_framebuffer_bind(g_select_buffer.framebuffer_depth_only);
1806 GPU_framebuffer_clear_depth(g_select_buffer.framebuffer_depth_only, 1.0f);
1807
1808 /* WORKAROUND: Needed for Select-Next for keeping the same code-flow as Overlay-Next. */
1809 /* TODO(pragma37): Some engines retrieve the depth texture before this point (See #132922).
1810 * Check with @fclem. */
1811 BLI_assert(DRW_context_get()->viewport_texture_list_get()->depth == nullptr);
1813
1814 drw_callbacks_pre_scene(draw_ctx);
1815 /* Only 1-2 passes. */
1816 while (true) {
1817 if (!select_pass_fn(DRW_SELECT_PASS_PRE, select_pass_user_data)) {
1818 break;
1819 }
1820 draw_ctx.engines_draw_scene();
1821 if (!select_pass_fn(DRW_SELECT_PASS_POST, select_pass_user_data)) {
1822 break;
1823 }
1824 }
1825
1826 /* WORKAROUND: Do not leave ownership to the viewport list. */
1828
1829 draw_ctx.release_data();
1830
1832}
1833
1835 ARegion *region,
1836 View3D *v3d,
1837 GPUViewport *viewport,
1838 const bool use_gpencil,
1839 const bool use_only_selected,
1840 const bool use_only_active_object)
1841{
1842 using namespace blender::draw;
1843
1844 DRWContext draw_ctx(use_only_active_object ? DRWContext::DEPTH_ACTIVE_OBJECT : DRWContext::DEPTH,
1845 depsgraph,
1846 viewport,
1847 nullptr,
1848 region,
1849 v3d);
1850 draw_ctx.acquire_data();
1851 draw_ctx.enable_engines(use_gpencil);
1852 draw_ctx.engines_init_and_sync([&](DupliCacheManager &duplis, ExtractionGraph &extraction) {
1853 const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
1854 DEGObjectIterSettings deg_iter_settings = {nullptr};
1855 deg_iter_settings.depsgraph = draw_ctx.depsgraph;
1857 if (v3d->flag2 & V3D_SHOW_VIEWER) {
1858 deg_iter_settings.viewer_path = &v3d->viewer_path;
1859 }
1860 if (use_only_active_object) {
1861 blender::draw::ObjectRef ob_ref(draw_ctx.obact);
1862 drw_engines_cache_populate(ob_ref, duplis, extraction);
1863 }
1864 else {
1865 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1866 if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
1867 continue;
1868 }
1869 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
1870 continue;
1871 }
1872 if (use_only_selected && !(ob->base_flag & BASE_SELECTED)) {
1873 continue;
1874 }
1875 if ((ob->base_flag & BASE_SELECTABLE) == 0) {
1876 continue;
1877 }
1878 blender::draw::ObjectRef ob_ref(data_, ob);
1879 drw_engines_cache_populate(ob_ref, duplis, extraction);
1880 }
1882 }
1883 });
1884
1885 /* Setup frame-buffer. */
1886 GPUTexture *depth_tx = GPU_viewport_depth_texture(viewport);
1887 GPUFrameBuffer *depth_fb = nullptr;
1889 {
1890 GPU_ATTACHMENT_TEXTURE(depth_tx),
1892 });
1893 GPU_framebuffer_bind(depth_fb);
1894 GPU_framebuffer_clear_depth(depth_fb, 1.0f);
1895
1896 draw_ctx.engines_draw_scene();
1897
1898 /* TODO: Reading depth for operators should be done here. */
1899
1901 GPU_framebuffer_free(depth_fb);
1902
1903 draw_ctx.release_data();
1904}
1905
1906void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d)
1907{
1909 GPUViewport *viewport = WM_draw_region_get_viewport(region);
1910 if (!viewport) {
1911 /* Selection engine requires a viewport.
1912 * TODO(@germano): This should be done internally in the engine. */
1913 sel_ctx->max_index_drawn_len = 1;
1914 return;
1915 }
1916
1917 /* Make sure select engine gets the correct vertex size. */
1919
1920 DRWContext draw_ctx(DRWContext::SELECT_EDIT_MESH, depsgraph, viewport, nullptr, region, v3d);
1921 draw_ctx.acquire_data();
1922 draw_ctx.enable_engines();
1923 draw_ctx.engines_init_and_sync([&](DupliCacheManager &duplis, ExtractionGraph &extraction) {
1924 for (Object *obj_eval : sel_ctx->objects) {
1925 blender::draw::ObjectRef ob_ref(obj_eval);
1926 drw_engines_cache_populate(ob_ref, duplis, extraction);
1927 }
1928
1929 if (RETOPOLOGY_ENABLED(v3d) && !XRAY_ENABLED(v3d)) {
1930 DEGObjectIterSettings deg_iter_settings = {nullptr};
1931 deg_iter_settings.depsgraph = depsgraph;
1933 DEG_OBJECT_ITER_BEGIN (&deg_iter_settings, ob) {
1934 if (ob->type != OB_MESH) {
1935 /* The iterator has evaluated meshes for all solid objects.
1936 * It also has non-mesh objects however, which are not supported here. */
1937 continue;
1938 }
1940 /* Only background (non-edit) objects are used for occlusion. */
1941 continue;
1942 }
1943 if (!BKE_object_is_visible_in_viewport(v3d, ob)) {
1944 continue;
1945 }
1946 blender::draw::ObjectRef ob_ref(data_, ob);
1947 drw_engines_cache_populate(ob_ref, duplis, extraction);
1948 }
1950 }
1951 });
1952
1953 draw_ctx.engines_draw_scene();
1954
1955 draw_ctx.release_data();
1956}
1957
1959{
1960 return DRWContext::is_active();
1961}
1962
1964
1965/* -------------------------------------------------------------------- */
1968
1970{
1971 return &drw_get();
1972}
1973
1975{
1976 if (this->evil_C != nullptr) {
1978 return ED_screen_animation_playing(wm) != nullptr;
1979 }
1980 return false;
1981}
1982
1984{
1985 return (rv3d) && (rv3d->rflag & (RV3D_NAVIGATING | RV3D_PAINTING));
1986}
1987
1989{
1990 return (rv3d) && (rv3d->rflag & (RV3D_PAINTING));
1991}
1992
1994{
1995 return (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) != 0;
1996}
1997
1999{
2000 if (!this->v3d) {
2001 return false;
2002 }
2003
2005 return false;
2006 }
2007
2008 if (!(this->v3d->shading.type >= OB_MATERIAL)) {
2009 return false;
2010 }
2011
2012 if (!this->scene->use_nodes) {
2013 return false;
2014 }
2015
2016 if (!this->scene->nodetree) {
2017 return false;
2018 }
2019
2020 if (!this->rv3d) {
2021 return false;
2022 }
2023
2025 this->rv3d->persp != RV3D_CAMOB)
2026 {
2027 return false;
2028 }
2029
2030 return true;
2031}
2032
2034
2035/* -------------------------------------------------------------------- */
2038
2044
2057
2059
2060/* -------------------------------------------------------------------- */
2063
2094
2096{
2098 GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only);
2099
2101}
2102
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:5511
void(* BKE_curve_batch_cache_dirty_tag_cb)(Curve *cu, int mode)
Definition curve.cc:5510
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)
@ G_TRANSFORM_OBJ
@ G_TRANSFORM_EDIT
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:706
void(* BKE_lattice_batch_cache_free_cb)(Lattice *lt)
Definition lattice.cc:707
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)
Mesh * BKE_mesh_wrapper_ensure_subdivision(Mesh *mesh)
Object * BKE_modifiers_is_deformed_by_armature(Object *ob)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_cage(const Object *object)
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:709
void(* BKE_particle_batch_cache_dirty_tag_cb)(struct ParticleSystem *psys, int mode)
Definition particle.cc:5283
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:5284
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:3414
SpaceType * BKE_spacetype_from_id(int spaceid)
Definition screen.cc:251
ARegionType * BKE_regiontype_from_id(const SpaceType *st, int regionid)
Definition screen.cc:261
bool BKE_subsurf_modifier_has_gpu_subdiv(const Mesh *mesh)
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:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
struct GSet GSet
Definition BLI_ghash.h:337
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.cc:414
void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
Definition rct.cc:551
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
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.cc:941
void BLI_task_graph_free(struct TaskGraph *task_graph)
struct TaskGraph * BLI_task_graph_create(void)
Definition task_graph.cc:96
void BLI_task_graph_work_and_wait(struct TaskGraph *task_graph)
Platform independent time functions.
double BLI_time_now_seconds(void)
Definition time.cc:65
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
#define IFACE_(msgid)
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
T * DEG_get_original(T *id)
Scene * DEG_get_input_scene(const Depsgraph *graph)
bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type)
@ ID_GD_LEGACY
@ 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_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ 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)
@ PE_DRAW_PART
#define BASE_SELECTABLE(v3d, base)
@ R_ADDSKY
@ 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
@ RV3D_CAMOB
@ V3D_XR_SESSION_SURFACE
@ V3D_XR_SESSION_MIRROR
@ V3D_OVERLAY_HIDE_TEXT
@ V3D_OVERLAY_BONE_SELECT
@ V3D_SHOW_VIEWER
@ V3D_XR_SHOW_CUSTOM_OVERLAYS
@ V3D_HIDE_OVERLAYS
@ V3D_SHOW_ANNOTATION
@ V3D_XR_SHOW_CONTROLLERS
@ V3D_GIZMO_HIDE
@ RV3D_PAINTING
@ RV3D_NAVIGATING
@ V3D_SHADING_SCENE_WORLD_RENDER
@ V3D_SHADING_SCENE_WORLD
void DRW_submission_end()
bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
DRWData * DRW_viewport_data_create()
void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height)
bool DRW_draw_in_progress()
void DRW_draw_view(const bContext *C)
void DRW_module_exit()
bool DRW_gpencil_engine_needed_viewport(Depsgraph *depsgraph, View3D *v3d)
bool(*)(Object *ob, void *user_data) DRW_ObjectFilterFn
Definition DRW_engine.hh:47
void DRW_draw_depth_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, GPUViewport *viewport, const bool use_gpencil, const bool use_only_selected, const bool use_only_active_object)
void DRW_cache_free_old_batches(Main *bmain)
void DRW_draw_render_loop_offscreen(Depsgraph *depsgraph, RenderEngineType *engine_type, ARegion *region, View3D *v3d, bool is_image_render, bool draw_background, bool do_color_management, GPUOffScreen *ofs, GPUViewport *viewport)
void DRW_engines_free()
@ DRW_SELECT_PASS_POST
Definition DRW_engine.hh:44
@ DRW_SELECT_PASS_PRE
Definition DRW_engine.hh:43
void DRW_draw_select_loop(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bool use_obedit_skip, bool draw_surface, bool use_nearest, 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)
void DRW_render_context_disable(Render *render)
void DRW_viewport_data_free(DRWData *drw_data)
void DRW_module_init()
void DRW_submission_start()
void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d)
void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph)
void DRW_engines_register()
void DRW_render_context_enable(Render *render)
bool(*)(eDRWSelectStage stage, void *user_data) DRW_SelectPassFn
Definition DRW_engine.hh:46
void ED_region_pixelspace(const ARegion *region)
Definition area.cc:123
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)
RenderEngineType * ED_view3d_engine_type(const Scene *scene, int drawtype)
static AppView * view
void GPU_render_end()
void GPU_render_begin()
GPUContext * GPU_context_active_get()
eGPUBackendType GPU_backend_get_type()
void GPU_debug_group_end()
Definition gpu_debug.cc:33
void GPU_debug_group_begin(const char *name)
Definition gpu_debug.cc:22
GPUFrameBuffer * GPU_framebuffer_create(const char *name)
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
#define GPU_ATTACHMENT_TEXTURE(_texture)
GPUFrameBuffer * GPU_framebuffer_active_get()
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
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_framebuffer_free(GPUFrameBuffer *fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
void GPU_clear_color(float red, float green, float blue, float alpha)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_framebuffer_clear_depth(GPUFrameBuffer *fb, float clear_depth)
GPUFrameBuffer * GPU_framebuffer_back_get()
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, 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()
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
void GPU_flush()
Definition gpu_state.cc:305
@ 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:310
void GPU_viewport(int x, int y, int width, int height)
Definition gpu_state.cc:199
@ GPU_DEPTH_LESS_EQUAL
Definition GPU_state.hh:114
@ GPU_DEPTH_NONE
Definition GPU_state.hh:111
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
void GPU_apply_state()
Definition gpu_state.cc:315
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
#define GPU_TEXTURE_FREE_SAFE(texture)
@ GPU_DEPTH_COMPONENT24
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)
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)
@ RE_INTERNAL
Definition RE_engine.h:43
#define C
Definition RandGen.cpp:29
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)
bool operator==(const AssetWeakReference &a, const AssetWeakReference &b)
#define U
iter begin(iter)
BMesh const char void * data
BPy_StructRNA * depsgraph
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
Definition BLI_map.hh:620
constexpr const char * c_str() const
static void default_set(const float4x4 &view_mat, const float4x4 &win_mat)
Definition draw_view.cc:322
void reset(bool force_free=false)
static TexturePool & get()
CCL_NAMESPACE_BEGIN struct Options options
void DRW_smoke_begin_sync(DRWData *drw_data)
void DRW_smoke_exit(DRWData *drw_data)
static bool draw_show_annotation()
const DRWContext * DRW_context_get()
DRWData * DRW_viewport_data_create()
static void drw_draw_render_loop_2d(DRWContext &draw_ctx)
void DRW_custom_pipeline_begin(DRWContext &draw_ctx, Depsgraph *)
static void drw_draw_render_loop_3d(DRWContext &draw_ctx, RenderEngineType *engine_type)
static void drw_callbacks_post_scene(DRWContext &draw_ctx)
static void drw_callbacks_pre_scene(DRWContext &draw_ctx)
static void drw_callbacks_post_scene_2D(DRWContext &draw_ctx, View2D &v2d)
void DRW_cache_restart()
bool DRW_object_is_in_edit_mode(const Object *ob)
static void drw_engines_cache_populate(blender::draw::ObjectRef &ref, DupliCacheManager &dupli_cache, ExtractionGraph &extraction)
blender::draw::TextureFromPool & DRW_viewport_pass_texture_get(const char *pass_name)
void DRW_render_to_image(RenderEngine *engine, Depsgraph *depsgraph, std::function< void(RenderEngine *, RenderLayer *, const rcti)> render_view_cb, std::function< void(RenderResult *)> store_metadata_cb)
static DRWData * drw_viewport_data_ensure(GPUViewport *viewport)
bool DRW_object_use_hide_faces(const Object *ob)
void DRW_render_object_iter(RenderEngine *engine, Depsgraph *depsgraph, std::function< void(blender::draw::ObjectRef &, RenderEngine *, Depsgraph *)> callback)
bool DRW_object_is_renderable(const Object *ob)
DRWTextStore * DRW_text_cache_ensure()
static bool gpencil_object_is_excluded(View3D *v3d)
int DRW_object_visibility_in_active_context(const Object *ob)
Mesh & DRW_object_get_data_for_drawing(const Object &object)
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
void DRW_viewport_data_free(DRWData *drw_data)
const Mesh * DRW_object_get_editmesh_cage_for_drawing(const Object &object)
static struct DRWSelectBuffer g_select_buffer
void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, float subframe)
void DRW_custom_pipeline_end(DRWContext &draw_ctx)
void DRW_viewport_request_redraw()
static void draw_select_framebuffer_depth_only_setup(const int size[2])
static bool gpencil_any_exists(Depsgraph *depsgraph)
static void drw_engines_draw_text()
static void drw_callbacks_pre_scene_2D(DRWContext &draw_ctx)
DRWContext & drw_get()
blender::draw::Manager * DRW_manager_get()
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()
void DRW_draw_region_info(const bContext *C, ARegion *region)
void DRW_draw_gizmo_3d(const bContext *C, ARegion *region)
void DRW_draw_gizmo_2d(const bContext *C, ARegion *region)
void DRW_view_data_default_lists_from_viewport(DRWViewData *view_data, GPUViewport *viewport)
void DRW_view_data_reset(DRWViewData *view_data)
void DRW_view_data_free_unused(DRWViewData *view_data)
RenderEngineType DRW_engine_viewport_eevee_type
bool DRW_engine_external_acquire_for_image_editor(const DRWContext *draw_ctx)
#define this
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)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void viewport_color_management_set(GPUViewport &viewport, DRWContext &draw_ctx)
void DRW_curves_module_free(draw::CurvesModule *module)
void DRW_particle_batch_cache_free(ParticleSystem *psys)
void DRW_pointcloud_module_free(draw::PointCloudModule *module)
void DRW_lattice_batch_cache_dirty_tag(Lattice *lt, int mode)
void DRW_lattice_batch_cache_free(Lattice *lt)
void DRW_grease_pencil_batch_cache_free(GreasePencil *grease_pencil)
void drw_batch_cache_generate_requested_evaluated_mesh_or_curve(Object *ob, TaskGraph &task_graph)
void DRW_pointcloud_batch_cache_dirty_tag(PointCloud *pointcloud, int mode)
void DRW_curves_init(DRWData *drw_data=nullptr)
void drw_batch_cache_validate(Object *ob)
void DRW_subdiv_cache_free(bke::subdiv::Subdiv *subdiv)
void DRW_grease_pencil_batch_cache_dirty_tag(GreasePencil *grease_pencil, int mode)
void DRW_volume_batch_cache_free(Volume *volume)
void DRW_mesh_batch_cache_free(void *batch_cache)
void DRW_curves_update(draw::Manager &manager)
void DRW_volume_init(DRWData *drw_data=nullptr)
void DRW_volume_batch_cache_dirty_tag(Volume *volume, int mode)
void DRW_curve_batch_cache_free(Curve *cu)
void DRW_curves_begin_sync(DRWData *drw_data)
void drw_batch_cache_generate_requested(Object *ob, TaskGraph &task_graph)
void DRW_curves_batch_cache_dirty_tag(Curves *curves, int mode)
void DRW_pointcloud_init(DRWData *drw_data=nullptr)
void DRW_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
void DRW_particle_batch_cache_dirty_tag(ParticleSystem *psys, int mode)
void DRW_pointcloud_batch_cache_free(PointCloud *pointcloud)
void DRW_batch_cache_free_old(Object *ob, int ctime)
void DRW_volume_module_free(draw::VolumeModule *module)
void DRW_curves_batch_cache_free(Curves *curves)
void DRW_curve_batch_cache_dirty_tag(Curve *cu, int mode)
MatBase< float, 4, 4 > float4x4
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
#define hash
Definition noise_c.cc:154
SELECTID_Context * DRW_select_engine_context_get()
RenderLayer * RE_GetRenderLayer(RenderResult *rr, const char *name)
void RE_SetActiveRenderView(Render *re, const char *viewname)
void * regiondata
DupliObject * dupli_object_current
const ViewerPath * viewer_path
bool is_image_render() const
DRWContext(Mode mode, Depsgraph *depsgraph, GPUViewport *viewport, const bContext *C=nullptr, ARegion *region=nullptr, View3D *v3d=nullptr)
bool is_playback() const
DRWViewData * view_data_active
static bool is_active()
Object * object_edit
GSet * delayed_extraction
bool draw_background
void sync(iter_callback_t iter_callback)
DefaultFramebufferList * viewport_framebuffer_list_get() const
DRWData * data
View3D * v3d
Depsgraph * depsgraph
bool is_scene_render() const
DRWTextStore ** text_store_p
void enable_engines(bool gpencil_engine_needed=false, RenderEngineType *render_engine_type=nullptr)
RegionView3D * rv3d
struct DRWContext::@067022257143106373153342333311100057262024013260 options
@ DEPTH_ACTIVE_OBJECT
@ SELECT_OBJECT_MATERIAL
static DRWContext & get_active()
Object * obact
enum DRWContext::Mode mode
void engines_draw_scene()
Scene * scene
Object * object_pose
void acquire_data()
const bContext * evil_C
bool is_painting() const
void release_data()
ARegion * region
void engines_init_and_sync(iter_callback_t iter_callback)
SpaceLink * space_data
GPUFrameBuffer * default_framebuffer()
bool is_transforming() const
DefaultTextureList * viewport_texture_list_get() const
GPUViewport * viewport
ViewLayer * view_layer
void engines_data_validate()
std::function< void(struct DupliCacheManager &, struct ExtractionGraph &)> iter_callback_t
bool is_navigating() const
bool is_viewport_compositor_enabled() const
blender::draw::VolumeModule * volume_module
blender::draw::View * default_view
blender::draw::CurvesModule * curves_module
void modules_exit()
void modules_init()
blender::draw::PointCloudModule * pointcloud_module
DRWViewData * view_data[2]
void modules_begin_sync()
GPUTexture * texture_depth
GPUFrameBuffer * framebuffer_depth_only
blender::draw::external::Engine external
blender::draw::select::Engine object_select
blender::Map< std::string, std::unique_ptr< blender::draw::TextureFromPool > > viewport_compositor_passes
void foreach_enabled_engine(CallbackT callback)
blender::workbench::Engine workbench
blender::draw::compositor_engine::Engine compositor
blender::draw::gpencil::Engine grease_pencil
blender::image_engine::Engine image
blender::draw::overlay::Engine overlay
blender::draw::edit_select::Engine edit_select
blender::eevee::Engine eevee
GPUFrameBuffer * overlay_fb
void set_used(bool used)
virtual void begin_sync()=0
virtual void object_sync(blender::draw::ObjectRef &ob_ref, blender::draw::Manager &manager)=0
virtual void draw(blender::draw::Manager &manager)=0
virtual void init()=0
char info[GPU_INFO_SIZE]
Definition DRW_render.hh:70
virtual blender::StringRefNull name_get()=0
DRWTextStore * text_draw_cache
Definition DRW_render.hh:71
virtual void end_sync()=0
void try_add(blender::draw::ObjectRef &ob_ref)
void extract_all(ExtractionGraph &extraction)
TaskGraph * graph
void work_and_wait(GSet *&delayed_extraction)
Definition DNA_ID.h:404
void * next
Definition DNA_ID.h:407
void * first
ListBase scenes
Definition BKE_main.hh:245
short base_flag
ObjectRuntimeHandle * runtime
ParticleSettings * part
struct PointCache * pointcache
float viewmat[4][4]
float winmat[4][4]
struct Render * re
Definition RE_engine.h:138
ListBase views
ListBase layers
struct RenderView * next
Definition RE_pipeline.h:38
blender::Vector< Object * > objects
struct ToolSettings * toolsettings
struct RenderData r
ListBase view_layers
struct ParticleEditSettings particle
View3DOverlay overlay
ViewerPath viewer_path
int object_type_exclude_select
int object_type_exclude_viewport
View3DShading shading
char name[64]
const c_style_mat & ptr() const
DupliObject * dupli_object
ResourceHandleRange handle
static void set(DRWState state=DRW_STATE_DEFAULT)
static void render_to_image(RenderEngine *engine, RenderLayer *render_layer, const rcti rect)
static void free_static()
float xmax
float xmin
float ymax
float ymin
i
Definition text_draw.cc:230
static void draw_background(const rcti *rect)
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
Definition wm_draw.cc:912
GPUViewport * WM_draw_region_get_bound_viewport(ARegion *region)
Definition wm_draw.cc:922
void wmOrtho2(float x1, float x2, float y1, float y2)
ARegionType * WM_xr_surface_controller_region_type_get()
RenderEngineType DRW_engine_viewport_workbench_type