2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * Copyright 2016, Blender Foundation.
19 /** \file blender/draw/intern/draw_manager.c
25 #include "BLI_listbase.h"
26 #include "BLI_mempool.h"
28 #include "BLI_string.h"
29 #include "BLI_threads.h"
33 #include "BKE_colortools.h"
34 #include "BKE_global.h"
35 #include "BKE_object.h"
36 #include "BKE_particle.h"
37 #include "BKE_pointcache.h"
39 #include "draw_manager.h"
40 #include "DNA_camera_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_world_types.h"
45 #include "ED_space_api.h"
46 #include "ED_screen.h"
47 #include "ED_gpencil.h"
48 #include "ED_view3d.h"
51 #include "GPU_extensions.h"
52 #include "GPU_framebuffer.h"
53 #include "GPU_immediate.h"
54 #include "GPU_uniformbuffer.h"
55 #include "GPU_viewport.h"
56 #include "GPU_matrix.h"
58 #include "IMB_colormanagement.h"
60 #include "RE_engine.h"
61 #include "RE_pipeline.h"
63 #include "UI_resources.h"
66 #include "wm_window.h"
68 #include "draw_manager_text.h"
69 #include "draw_manager_profiling.h"
71 /* only for callbacks */
72 #include "draw_cache_impl.h"
74 #include "draw_mode_engines.h"
75 #include "engines/eevee/eevee_engine.h"
76 #include "engines/basic/basic_engine.h"
77 #include "engines/workbench/workbench_engine.h"
78 #include "engines/external/external_engine.h"
80 #include "GPU_context.h"
82 #include "DEG_depsgraph.h"
83 #include "DEG_depsgraph_query.h"
86 # include "GPU_select.h"
89 /** Render State: No persistent data between draw calls. */
90 DRWManager DST = {NULL};
92 static ListBase DRW_engines = {NULL, NULL};
94 extern struct GPUUniformBuffer *view_ubo; /* draw_manager_exec.c */
96 static void drw_state_prepare_clean_for_draw(DRWManager *dst)
98 memset(dst, 0x0, offsetof(DRWManager, gl_context));
100 /* Maybe not the best place for this. */
101 if (!DST.uniform_names.buffer) {
102 DST.uniform_names.buffer = MEM_callocN(DRW_UNIFORM_BUFFER_NAME, "Name Buffer");
103 DST.uniform_names.buffer_len = DRW_UNIFORM_BUFFER_NAME;
105 else if (DST.uniform_names.buffer_len > DRW_UNIFORM_BUFFER_NAME) {
106 DST.uniform_names.buffer = MEM_reallocN(DST.uniform_names.buffer, DRW_UNIFORM_BUFFER_NAME);
107 DST.uniform_names.buffer_len = DRW_UNIFORM_BUFFER_NAME;
109 DST.uniform_names.buffer_ofs = 0;
112 /* This function is used to reset draw manager to a state
113 * where we don't re-use data by accident across different
117 static void drw_state_ensure_not_reused(DRWManager *dst)
119 memset(dst, 0xff, offsetof(DRWManager, gl_context));
123 /* -------------------------------------------------------------------- */
125 void DRW_draw_callbacks_pre_scene(void)
127 RegionView3D *rv3d = DST.draw_ctx.rv3d;
129 GPU_matrix_projection_set(rv3d->winmat);
130 GPU_matrix_set(rv3d->viewmat);
133 void DRW_draw_callbacks_post_scene(void)
135 RegionView3D *rv3d = DST.draw_ctx.rv3d;
137 GPU_matrix_projection_set(rv3d->winmat);
138 GPU_matrix_set(rv3d->viewmat);
141 struct DRWTextStore *DRW_text_cache_ensure(void)
143 BLI_assert(DST.text_store_p);
144 if (*DST.text_store_p == NULL) {
145 *DST.text_store_p = DRW_text_cache_create();
147 return *DST.text_store_p;
151 /* -------------------------------------------------------------------- */
155 bool DRW_object_is_renderable(const Object *ob)
157 BLI_assert((ob->base_flag & BASE_VISIBLE) != 0);
159 if (ob->type == OB_MESH) {
160 if ((ob == DST.draw_ctx.object_edit) || BKE_object_is_in_editmode(ob)) {
161 View3D *v3d = DST.draw_ctx.v3d;
162 const int mask = (V3D_OVERLAY_EDIT_OCCLUDE_WIRE | V3D_OVERLAY_EDIT_WEIGHT);
164 if (v3d && v3d->overlay.edit_flag & mask) {
174 * Return whether this object is visible depending if
175 * we are rendering or drawing in the viewport.
177 int DRW_object_visibility_in_active_context(const Object *ob)
179 const eEvaluationMode mode = DRW_state_is_scene_render() ?
182 return BKE_object_visibility(ob, mode);
185 bool DRW_object_is_flat_normal(const Object *ob)
187 if (ob->type == OB_MESH) {
188 const Mesh *me = ob->data;
189 if (me->mpoly && me->mpoly[0].flag & ME_SMOOTH) {
196 bool DRW_object_use_hide_faces(const struct Object *ob)
198 if (ob->type == OB_MESH) {
199 const Mesh *me = DEG_get_original_object((Object *)ob)->data;
202 case OB_MODE_TEXTURE_PAINT:
203 return (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
204 case OB_MODE_VERTEX_PAINT:
205 case OB_MODE_WEIGHT_PAINT:
206 return (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
213 bool DRW_object_is_visible_psys_in_active_context(
214 const Object *object,
215 const ParticleSystem *psys)
217 const DRWContextState *draw_ctx = DRW_context_state_get();
218 const Scene *scene = draw_ctx->scene;
219 if (object == draw_ctx->object_edit) {
222 const ParticleSettings *part = psys->part;
223 const ParticleEditSettings *pset = &scene->toolsettings->particle;
224 if (object->mode == OB_MODE_PARTICLE_EDIT) {
225 if (psys_in_edit_mode(draw_ctx->depsgraph, psys)) {
226 if ((pset->flag & PE_DRAW_PART) == 0) {
229 if ((part->childtype == 0) &&
230 (psys->flag & PSYS_HAIR_DYNAMICS &&
231 psys->pointcache->flag & PTCACHE_BAKED) == 0)
240 struct Object *DRW_object_get_dupli_parent(const Object *UNUSED(ob))
242 return DST.dupli_parent;
245 struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob))
247 return DST.dupli_source;
253 /* -------------------------------------------------------------------- */
254 /** \name Color Management
257 /* Use color management profile to draw texture to framebuffer */
258 void DRW_transform_to_display(GPUTexture *tex, bool use_view_transform, bool use_render_settings)
260 drw_state_set(DRW_STATE_WRITE_COLOR);
262 GPUVertFormat *vert_format = immVertexFormat();
263 uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
264 uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
266 const float dither = 1.0f;
268 bool use_ocio = false;
270 /* View transform is already applied for offscreen, don't apply again, see: T52046 */
271 if (!(DST.options.is_image_render && !DST.options.is_scene_render)) {
272 Scene *scene = DST.draw_ctx.scene;
273 ColorManagedDisplaySettings *display_settings = &scene->display_settings;
274 ColorManagedViewSettings view_settings;
275 if (use_render_settings) {
276 /* Use full render settings, for renders with scene lighting. */
277 view_settings = scene->view_settings;
279 else if (use_view_transform) {
280 /* Use only view transform + look and nothing else for lookdev without
281 * scene lighting, as exposure depends on scene light intensity. */
282 BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
283 STRNCPY(view_settings.view_transform, scene->view_settings.view_transform);
284 STRNCPY(view_settings.look, scene->view_settings.look);
287 /* For workbench use only default view transform in configuration,
288 * using no scene settings. */
289 BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
292 use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(
293 &view_settings, display_settings, NULL, dither, false);
297 /* View transform is already applied for offscreen, don't apply again, see: T52046 */
298 if (DST.options.is_image_render && !DST.options.is_scene_render) {
299 immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
300 immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
303 immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB);
305 immUniform1i("image", 0);
308 GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */
312 immUniformMatrix4fv("ModelViewProjectionMatrix", mat);
314 /* Full screen triangle */
315 immBegin(GPU_PRIM_TRIS, 3);
316 immAttr2f(texco, 0.0f, 0.0f);
317 immVertex2f(pos, -1.0f, -1.0f);
319 immAttr2f(texco, 2.0f, 0.0f);
320 immVertex2f(pos, 3.0f, -1.0f);
322 immAttr2f(texco, 0.0f, 2.0f);
323 immVertex2f(pos, -1.0f, 3.0f);
326 GPU_texture_unbind(tex);
329 IMB_colormanagement_finish_glsl_draw();
336 /* Draw texture to framebuffer without any color transforms */
337 void DRW_transform_none(GPUTexture *tex)
339 /* Draw as texture for final render (without immediate mode). */
340 GPUBatch *geom = DRW_cache_fullscreen_quad_get();
341 GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR);
343 GPU_texture_bind(tex, 0);
345 const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
346 GPU_batch_uniform_4fv(geom, "color", white);
350 GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
352 GPU_batch_program_use_begin(geom);
353 GPU_batch_draw_range_ex(geom, 0, 0, false);
354 GPU_batch_program_use_end(geom);
356 GPU_texture_unbind(tex);
362 /* -------------------------------------------------------------------- */
363 /** \name Multisample Resolve
366 /* Use manual multisample resolve pass.
367 * Much quicker than blitting back and forth.
368 * Assume destination fb is bound*/
369 void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool use_depth)
371 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_PREMUL;
374 state |= DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
376 drw_state_set(state);
378 int samples = GPU_texture_samples(src_depth);
380 BLI_assert(samples > 0);
381 BLI_assert(GPU_texture_samples(src_color) == samples);
383 GPUBatch *geom = DRW_cache_fullscreen_quad_get();
388 case 2: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST; break;
389 case 4: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST; break;
390 case 8: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST; break;
391 case 16: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST; break;
393 BLI_assert("Mulisample count unsupported by blit shader.");
394 builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
400 case 2: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2; break;
401 case 4: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4; break;
402 case 8: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8; break;
403 case 16: builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16; break;
405 BLI_assert("Mulisample count unsupported by blit shader.");
406 builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
411 GPU_batch_program_set_builtin(geom, builtin);
414 GPU_texture_bind(src_depth, 0);
415 GPU_batch_uniform_1i(geom, "depthMulti", 0);
418 GPU_texture_bind(src_color, 1);
419 GPU_batch_uniform_1i(geom, "colorMulti", 1);
423 GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
425 /* avoid gpuMatrix calls */
426 GPU_batch_program_use_begin(geom);
427 GPU_batch_draw_range_ex(geom, 0, 0, false);
428 GPU_batch_program_use_end(geom);
433 /* -------------------------------------------------------------------- */
434 /** \name Viewport (DRW_viewport)
437 void *drw_viewport_engine_data_ensure(void *engine_type)
439 void *data = GPU_viewport_engine_data_get(DST.viewport, engine_type);
442 data = GPU_viewport_engine_data_create(DST.viewport, engine_type);
447 void DRW_engine_viewport_data_size_get(
448 const void *engine_type_v,
449 int *r_fbl_len, int *r_txl_len, int *r_psl_len, int *r_stl_len)
451 const DrawEngineType *engine_type = engine_type_v;
454 *r_fbl_len = engine_type->vedata_size->fbl_len;
457 *r_txl_len = engine_type->vedata_size->txl_len;
460 *r_psl_len = engine_type->vedata_size->psl_len;
463 *r_stl_len = engine_type->vedata_size->stl_len;
467 /* WARNING: only use for custom pipeline. 99% of the time, you don't want to use this. */
468 void DRW_render_viewport_size_set(int size[2])
470 DST.size[0] = size[0];
471 DST.size[1] = size[1];
474 const float *DRW_viewport_size_get(void)
479 const float *DRW_viewport_invert_size_get(void)
484 const float *DRW_viewport_screenvecs_get(void)
486 return &DST.screenvecs[0][0];
489 const float *DRW_viewport_pixelsize_get(void)
494 static void drw_viewport_cache_resize(void)
496 /* Release the memiter before clearing the mempools that references them */
497 GPU_viewport_cache_release(DST.viewport);
499 if (DST.vmempool != NULL) {
500 BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_len(DST.vmempool->calls));
501 BLI_mempool_clear_ex(DST.vmempool->states, BLI_mempool_len(DST.vmempool->states));
502 BLI_mempool_clear_ex(DST.vmempool->shgroups, BLI_mempool_len(DST.vmempool->shgroups));
503 BLI_mempool_clear_ex(DST.vmempool->uniforms, BLI_mempool_len(DST.vmempool->uniforms));
504 BLI_mempool_clear_ex(DST.vmempool->passes, BLI_mempool_len(DST.vmempool->passes));
507 DRW_instance_data_list_free_unused(DST.idatalist);
508 DRW_instance_data_list_resize(DST.idatalist);
511 /* Not a viewport variable, we could split this out. */
512 static void drw_context_state_init(void)
514 if (DST.draw_ctx.obact) {
515 DST.draw_ctx.object_mode = DST.draw_ctx.obact->mode;
518 DST.draw_ctx.object_mode = OB_MODE_OBJECT;
522 if (DST.draw_ctx.object_mode & OB_MODE_EDIT) {
523 DST.draw_ctx.object_edit = DST.draw_ctx.obact;
526 DST.draw_ctx.object_edit = NULL;
530 if (DST.draw_ctx.object_mode & OB_MODE_POSE) {
531 DST.draw_ctx.object_pose = DST.draw_ctx.obact;
533 else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) {
534 DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact);
537 DST.draw_ctx.object_pose = NULL;
540 DST.draw_ctx.shader_cfg = GPU_SHADER_CFG_DEFAULT;
541 if (DST.draw_ctx.rv3d && DST.draw_ctx.rv3d->rflag & RV3D_CLIPPING) {
542 DST.draw_ctx.shader_cfg = GPU_SHADER_CFG_CLIPPED;
546 /* It also stores viewport variable to an immutable place: DST
547 * This is because a cache uniform only store reference
548 * to its value. And we don't want to invalidate the cache
549 * if this value change per viewport */
550 static void drw_viewport_var_init(void)
552 RegionView3D *rv3d = DST.draw_ctx.rv3d;
553 /* Refresh DST.size */
556 GPU_viewport_size_get(DST.viewport, size);
557 DST.size[0] = size[0];
558 DST.size[1] = size[1];
559 DST.inv_size[0] = 1.0f / size[0];
560 DST.inv_size[1] = 1.0f / size[1];
562 DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport);
563 DST.default_framebuffer = fbl->default_fb;
565 DST.vmempool = GPU_viewport_mempool_get(DST.viewport);
567 if (DST.vmempool->calls == NULL) {
568 DST.vmempool->calls = BLI_mempool_create(sizeof(DRWCall), 0, 512, 0);
570 if (DST.vmempool->states == NULL) {
571 DST.vmempool->states = BLI_mempool_create(sizeof(DRWCallState), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
573 if (DST.vmempool->shgroups == NULL) {
574 DST.vmempool->shgroups = BLI_mempool_create(sizeof(DRWShadingGroup), 0, 256, 0);
576 if (DST.vmempool->uniforms == NULL) {
577 DST.vmempool->uniforms = BLI_mempool_create(sizeof(DRWUniform), 0, 512, 0);
579 if (DST.vmempool->passes == NULL) {
580 DST.vmempool->passes = BLI_mempool_create(sizeof(DRWPass), 0, 64, 0);
583 DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
584 DRW_instance_data_list_reset(DST.idatalist);
593 DST.default_framebuffer = NULL;
598 /* Refresh DST.screenvecs */
599 copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
600 copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
601 normalize_v3(DST.screenvecs[0]);
602 normalize_v3(DST.screenvecs[1]);
604 /* Refresh DST.pixelsize */
605 DST.pixsize = rv3d->pixsize;
607 copy_m4_m4(DST.original_mat.mat[DRW_MAT_PERS], rv3d->persmat);
608 copy_m4_m4(DST.original_mat.mat[DRW_MAT_PERSINV], rv3d->persinv);
609 copy_m4_m4(DST.original_mat.mat[DRW_MAT_VIEW], rv3d->viewmat);
610 copy_m4_m4(DST.original_mat.mat[DRW_MAT_VIEWINV], rv3d->viewinv);
611 copy_m4_m4(DST.original_mat.mat[DRW_MAT_WIN], rv3d->winmat);
612 invert_m4_m4(DST.original_mat.mat[DRW_MAT_WININV], rv3d->winmat);
614 memcpy(DST.view_data.matstate.mat, DST.original_mat.mat, sizeof(DST.original_mat.mat));
616 copy_v4_v4(DST.view_data.viewcamtexcofac, rv3d->viewcamtexcofac);
619 copy_v4_fl4(DST.view_data.viewcamtexcofac, 1.0f, 1.0f, 0.0f, 0.0f);
623 DST.frontface = GL_CCW;
624 DST.backface = GL_CW;
625 glFrontFace(DST.frontface);
627 if (DST.draw_ctx.object_edit) {
628 ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
631 /* Alloc array of texture reference. */
632 if (DST.RST.bound_texs == NULL) {
633 DST.RST.bound_texs = MEM_callocN(sizeof(GPUTexture *) * GPU_max_textures(), "Bound GPUTexture refs");
635 if (DST.RST.bound_tex_slots == NULL) {
636 DST.RST.bound_tex_slots = MEM_callocN(sizeof(char) * GPU_max_textures(), "Bound Texture Slots");
638 if (DST.RST.bound_ubos == NULL) {
639 DST.RST.bound_ubos = MEM_callocN(sizeof(GPUUniformBuffer *) * GPU_max_ubo_binds(), "Bound GPUUniformBuffer refs");
641 if (DST.RST.bound_ubo_slots == NULL) {
642 DST.RST.bound_ubo_slots = MEM_callocN(sizeof(char) * GPU_max_ubo_binds(), "Bound Ubo Slots");
645 if (view_ubo == NULL) {
646 view_ubo = DRW_uniformbuffer_create(sizeof(ViewUboStorage), NULL);
649 DST.override_mat = 0;
650 DST.dirty_mat = true;
651 DST.state_cache_id = 1;
653 DST.clipping.updated = false;
655 memset(DST.object_instance_data, 0x0, sizeof(DST.object_instance_data));
658 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
660 BLI_assert(type >= 0 && type < DRW_MAT_COUNT);
661 /* Can't use this in render mode. */
662 BLI_assert(((DST.override_mat & (1 << type)) != 0) || DST.draw_ctx.rv3d != NULL);
664 copy_m4_m4(mat, DST.view_data.matstate.mat[type]);
667 void DRW_viewport_matrix_get_all(DRWMatrixState *state)
669 memcpy(state, DST.view_data.matstate.mat, sizeof(DRWMatrixState));
672 void DRW_viewport_matrix_override_set(const float mat[4][4], DRWViewportMatrixType type)
674 BLI_assert(type < DRW_MAT_COUNT);
675 copy_m4_m4(DST.view_data.matstate.mat[type], mat);
676 DST.override_mat |= (1 << type);
677 DST.dirty_mat = true;
678 DST.clipping.updated = false;
681 void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type)
683 BLI_assert(type < DRW_MAT_COUNT);
684 copy_m4_m4(DST.view_data.matstate.mat[type], DST.original_mat.mat[type]);
685 DST.override_mat &= ~(1 << type);
686 DST.dirty_mat = true;
687 DST.clipping.updated = false;
690 void DRW_viewport_matrix_override_set_all(DRWMatrixState *state)
692 memcpy(DST.view_data.matstate.mat, state, sizeof(DRWMatrixState));
693 DST.override_mat = 0xFFFFFF;
694 DST.dirty_mat = true;
695 DST.clipping.updated = false;
698 void DRW_viewport_matrix_override_unset_all(void)
700 memcpy(DST.view_data.matstate.mat, DST.original_mat.mat, sizeof(DRWMatrixState));
701 DST.override_mat = 0;
702 DST.dirty_mat = true;
703 DST.clipping.updated = false;
706 bool DRW_viewport_is_persp_get(void)
708 RegionView3D *rv3d = DST.draw_ctx.rv3d;
710 return rv3d->is_persp;
713 return DST.view_data.matstate.mat[DRW_MAT_WIN][3][3] == 0.0f;
717 float DRW_viewport_near_distance_get(void)
720 DRW_viewport_matrix_get(projmat, DRW_MAT_WIN);
722 if (DRW_viewport_is_persp_get()) {
723 return -projmat[3][2] / (projmat[2][2] - 1.0f);
726 return -(projmat[3][2] + 1.0f) / projmat[2][2];
730 float DRW_viewport_far_distance_get(void)
733 DRW_viewport_matrix_get(projmat, DRW_MAT_WIN);
735 if (DRW_viewport_is_persp_get()) {
736 return -projmat[3][2] / (projmat[2][2] + 1.0f);
739 return -(projmat[3][2] - 1.0f) / projmat[2][2];
743 DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void)
745 return GPU_viewport_framebuffer_list_get(DST.viewport);
748 DefaultTextureList *DRW_viewport_texture_list_get(void)
750 return GPU_viewport_texture_list_get(DST.viewport);
753 void DRW_viewport_request_redraw(void)
755 GPU_viewport_tag_update(DST.viewport);
761 /* -------------------------------------------------------------------- */
762 /** \name ViewLayers (DRW_scenelayer)
765 void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type)
767 for (ViewLayerEngineData *sled = DST.draw_ctx.view_layer->drawdata.first; sled; sled = sled->next) {
768 if (sled->engine_type == engine_type) {
769 return sled->storage;
775 void **DRW_view_layer_engine_data_ensure_ex(
776 ViewLayer *view_layer, DrawEngineType *engine_type, void (*callback)(void *storage))
778 ViewLayerEngineData *sled;
780 for (sled = view_layer->drawdata.first; sled; sled = sled->next) {
781 if (sled->engine_type == engine_type) {
782 return &sled->storage;
786 sled = MEM_callocN(sizeof(ViewLayerEngineData), "ViewLayerEngineData");
787 sled->engine_type = engine_type;
788 sled->free = callback;
789 BLI_addtail(&view_layer->drawdata, sled);
791 return &sled->storage;
794 void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*callback)(void *storage))
796 return DRW_view_layer_engine_data_ensure_ex(DST.draw_ctx.view_layer, engine_type, callback);
802 /* -------------------------------------------------------------------- */
803 /** \name Draw Data (DRW_drawdata)
806 /* Used for DRW_drawdata_from_id()
807 * All ID-datablocks which have their own 'local' DrawData
808 * should have the same arrangement in their structs.
810 typedef struct IdDdtTemplate {
812 struct AnimData *adt;
813 DrawDataList drawdata;
816 /* Check if ID can have AnimData */
817 static bool id_type_can_have_drawdata(const short id_type)
819 /* Only some ID-blocks have this info for now */
820 /* TODO: finish adding this for the other blocktypes */
833 static bool id_can_have_drawdata(const ID *id)
840 return id_type_can_have_drawdata(GS(id->name));
843 /* Get DrawData from the given ID-block. In order for this to work, we assume that
844 * the DrawData pointer is stored in the struct in the same fashion as in IdDdtTemplate.
846 DrawDataList *DRW_drawdatalist_from_id(ID *id)
848 /* only some ID-blocks have this info for now, so we cast the
849 * types that do to be of type IdDdtTemplate, and extract the
852 if (id_can_have_drawdata(id)) {
853 IdDdtTemplate *idt = (IdDdtTemplate *)id;
854 return &idt->drawdata;
861 DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type)
863 DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
865 if (drawdata == NULL) {
869 LISTBASE_FOREACH(DrawData *, dd, drawdata) {
870 if (dd->engine_type == engine_type) {
877 DrawData *DRW_drawdata_ensure(
879 DrawEngineType *engine_type,
881 DrawDataInitCb init_cb,
882 DrawDataFreeCb free_cb)
884 BLI_assert(size >= sizeof(DrawData));
885 BLI_assert(id_can_have_drawdata(id));
886 /* Try to re-use existing data. */
887 DrawData *dd = DRW_drawdata_get(id, engine_type);
892 DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
894 /* Allocate new data. */
895 if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROM_DUPLI) != 0) {
896 /* NOTE: data is not persistent in this case. It is reset each redraw. */
897 BLI_assert(free_cb == NULL); /* No callback allowed. */
898 /* Round to sizeof(float) for DRW_instance_data_request(). */
899 const size_t t = sizeof(float) - 1;
900 size = (size + t) & ~t;
901 size_t fsize = size / sizeof(float);
902 BLI_assert(fsize < MAX_INSTANCE_DATA_SIZE);
903 if (DST.object_instance_data[fsize] == NULL) {
904 DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize);
906 dd = (DrawData *)DRW_instance_data_next(DST.object_instance_data[fsize]);
910 dd = MEM_callocN(size, "DrawData");
912 dd->engine_type = engine_type;
914 /* Perform user-side initialization, if needed. */
915 if (init_cb != NULL) {
918 /* Register in the list. */
919 BLI_addtail((ListBase *)drawdata, dd);
923 void DRW_drawdata_free(ID *id)
925 DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
927 if (drawdata == NULL) {
931 LISTBASE_FOREACH(DrawData *, dd, drawdata) {
932 if (dd->free != NULL) {
937 BLI_freelistN((ListBase *)drawdata);
940 /* Unlink (but don't free) the drawdata from the DrawDataList if the ID is an OB from dupli. */
941 static void drw_drawdata_unlink_dupli(ID *id)
943 if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROM_DUPLI) != 0) {
944 DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
946 if (drawdata == NULL) {
950 BLI_listbase_clear((ListBase *)drawdata);
957 /* -------------------------------------------------------------------- */
958 /** \name Rendering (DRW_engines)
961 static void drw_engines_init(void)
963 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
964 DrawEngineType *engine = link->data;
965 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
966 PROFILE_START(stime);
968 if (engine->engine_init) {
969 engine->engine_init(data);
972 PROFILE_END_UPDATE(data->init_time, stime);
976 static void drw_engines_cache_init(void)
978 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
979 DrawEngineType *engine = link->data;
980 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
982 if (data->text_draw_cache) {
983 DRW_text_cache_destroy(data->text_draw_cache);
984 data->text_draw_cache = NULL;
986 if (DST.text_store_p == NULL) {
987 DST.text_store_p = &data->text_draw_cache;
990 if (engine->cache_init) {
991 engine->cache_init(data);
996 static void drw_engines_world_update(Scene *scene)
998 if (scene->world == NULL) {
1002 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1003 DrawEngineType *engine = link->data;
1004 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1006 if (engine->id_update) {
1007 engine->id_update(data, &scene->world->id);
1012 static void drw_engines_cache_populate(Object *ob)
1014 DST.ob_state = NULL;
1016 /* HACK: DrawData is copied by COW from the duplicated object.
1017 * This is valid for IDs that cannot be instantiated but this
1018 * is not what we want in this case so we clear the pointer
1019 * ourselves here. */
1020 drw_drawdata_unlink_dupli((ID *)ob);
1022 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1023 DrawEngineType *engine = link->data;
1024 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1026 if (engine->id_update) {
1027 engine->id_update(data, &ob->id);
1030 if (engine->cache_populate) {
1031 engine->cache_populate(data, ob);
1035 /* TODO: in the future it would be nice to generate once for all viewports.
1036 * But we need threaded DRW manager first. */
1037 drw_batch_cache_generate_requested(ob);
1039 /* ... and clearing it here too because theses draw data are
1040 * from a mempool and must not be free individually by depsgraph. */
1041 drw_drawdata_unlink_dupli((ID *)ob);
1044 static void drw_engines_cache_finish(void)
1046 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1047 DrawEngineType *engine = link->data;
1048 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1050 if (engine->cache_finish) {
1051 engine->cache_finish(data);
1056 static void drw_engines_draw_background(void)
1058 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1059 DrawEngineType *engine = link->data;
1060 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1062 if (engine->draw_background) {
1063 PROFILE_START(stime);
1065 DRW_stats_group_start(engine->idname);
1066 engine->draw_background(data);
1067 DRW_stats_group_end();
1069 PROFILE_END_UPDATE(data->background_time, stime);
1074 /* No draw_background found, doing default background */
1075 if (DRW_state_draw_background()) {
1076 DRW_draw_background();
1080 static void drw_engines_draw_scene(void)
1082 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1083 DrawEngineType *engine = link->data;
1084 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1085 PROFILE_START(stime);
1087 if (engine->draw_scene) {
1088 DRW_stats_group_start(engine->idname);
1089 engine->draw_scene(data);
1090 /* Restore for next engine */
1091 if (DRW_state_is_fbo()) {
1092 GPU_framebuffer_bind(DST.default_framebuffer);
1094 DRW_stats_group_end();
1097 PROFILE_END_UPDATE(data->render_time, stime);
1101 static void drw_engines_draw_text(void)
1103 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1104 DrawEngineType *engine = link->data;
1105 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1106 PROFILE_START(stime);
1108 if (data->text_draw_cache) {
1109 DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.ar);
1112 PROFILE_END_UPDATE(data->render_time, stime);
1116 /* Draw render engine info. */
1117 void DRW_draw_region_engine_info(int xoffset, int yoffset)
1119 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1120 DrawEngineType *engine = link->data;
1121 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1123 if (data->info[0] != '\0') {
1124 char *chr_current = data->info;
1125 char *chr_start = chr_current;
1128 const int font_id = BLF_default();
1129 UI_FontThemeColor(font_id, TH_TEXT_HI);
1131 BLF_enable(font_id, BLF_SHADOW);
1132 BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
1133 BLF_shadow_offset(font_id, 1, -1);
1135 while (*chr_current++ != '\0') {
1137 if (*chr_current == '\n') {
1138 char info[GPU_INFO_SIZE];
1139 BLI_strncpy(info, chr_start, line_len + 1);
1140 yoffset -= U.widget_unit;
1141 BLF_draw_default(xoffset, yoffset, 0.0f, info, sizeof(info));
1143 /* Re-start counting. */
1144 chr_start = chr_current + 1;
1149 char info[GPU_INFO_SIZE];
1150 BLI_strncpy(info, chr_start, line_len + 1);
1151 yoffset -= U.widget_unit;
1152 BLF_draw_default(xoffset, yoffset, 0.0f, info, sizeof(info));
1154 BLF_disable(font_id, BLF_SHADOW);
1159 static void use_drw_engine(DrawEngineType *engine)
1161 LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
1163 BLI_addtail(&DST.enabled_engines, ld);
1167 * Use for external render engines.
1169 static void drw_engines_enable_external(void)
1171 use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
1174 /* TODO revisit this when proper layering is implemented */
1175 /* Gather all draw engines needed and store them in DST.enabled_engines
1176 * That also define the rendering order of engines */
1177 static void drw_engines_enable_from_engine(RenderEngineType *engine_type, int drawtype, bool use_xray)
1181 use_drw_engine(&draw_engine_workbench_transparent);
1186 use_drw_engine(&draw_engine_workbench_transparent);
1189 use_drw_engine(&draw_engine_workbench_solid);
1197 if (engine_type->draw_engine != NULL) {
1198 use_drw_engine(engine_type->draw_engine);
1201 if ((engine_type->flag & RE_INTERNAL) == 0) {
1202 drw_engines_enable_external();
1208 static void drw_engines_enable_from_object_mode(void)
1210 use_drw_engine(&draw_engine_object_type);
1211 /* TODO(fclem) remove this, it does not belong to it's own engine. */
1212 use_drw_engine(&draw_engine_motion_path_type);
1215 static void drw_engines_enable_from_paint_mode(int mode)
1218 case CTX_MODE_SCULPT:
1219 use_drw_engine(&draw_engine_sculpt_type);
1221 case CTX_MODE_PAINT_WEIGHT:
1222 use_drw_engine(&draw_engine_paint_weight_type);
1224 case CTX_MODE_PAINT_VERTEX:
1225 use_drw_engine(&draw_engine_paint_vertex_type);
1227 case CTX_MODE_PAINT_TEXTURE:
1228 use_drw_engine(&draw_engine_paint_texture_type);
1235 static void drw_engines_enable_from_mode(int mode)
1238 case CTX_MODE_EDIT_MESH:
1239 use_drw_engine(&draw_engine_edit_mesh_type);
1241 case CTX_MODE_EDIT_SURFACE:
1242 case CTX_MODE_EDIT_CURVE:
1243 use_drw_engine(&draw_engine_edit_curve_type);
1245 case CTX_MODE_EDIT_TEXT:
1246 use_drw_engine(&draw_engine_edit_text_type);
1248 case CTX_MODE_EDIT_ARMATURE:
1249 use_drw_engine(&draw_engine_edit_armature_type);
1251 case CTX_MODE_EDIT_METABALL:
1252 use_drw_engine(&draw_engine_edit_metaball_type);
1254 case CTX_MODE_EDIT_LATTICE:
1255 use_drw_engine(&draw_engine_edit_lattice_type);
1257 case CTX_MODE_PARTICLE:
1258 use_drw_engine(&draw_engine_particle_type);
1261 case CTX_MODE_PAINT_WEIGHT:
1262 /* The pose engine clears the depth of the default framebuffer
1263 * to draw an object with `OB_DRAWXRAY`.
1264 * (different of workbench that has its own framebuffer).
1265 * So make sure you call its `draw_scene` after all the other engines. */
1266 use_drw_engine(&draw_engine_pose_type);
1268 case CTX_MODE_SCULPT:
1269 case CTX_MODE_PAINT_VERTEX:
1270 case CTX_MODE_PAINT_TEXTURE:
1271 case CTX_MODE_OBJECT:
1272 case CTX_MODE_PAINT_GPENCIL:
1273 case CTX_MODE_EDIT_GPENCIL:
1274 case CTX_MODE_SCULPT_GPENCIL:
1275 case CTX_MODE_WEIGHT_GPENCIL:
1278 BLI_assert(!"Draw mode invalid");
1282 use_drw_engine(&draw_engine_gpencil_type);
1285 static void drw_engines_enable_from_overlays(int UNUSED(overlay_flag))
1287 use_drw_engine(&draw_engine_overlay_type);
1290 * Use for select and depth-drawing.
1292 static void drw_engines_enable_basic(void)
1294 use_drw_engine(DRW_engine_viewport_basic_type.draw_engine);
1297 static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_type)
1299 Object *obact = OBACT(view_layer);
1300 const int mode = CTX_data_mode_enum_ex(DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode);
1301 View3D *v3d = DST.draw_ctx.v3d;
1302 const int drawtype = v3d->shading.type;
1303 const bool use_xray = XRAY_ENABLED(v3d);
1305 drw_engines_enable_from_engine(engine_type, drawtype, use_xray);
1307 if (DRW_state_draw_support()) {
1308 /* Draw paint modes first so that they are drawn below the wireframes. */
1309 drw_engines_enable_from_paint_mode(mode);
1310 drw_engines_enable_from_overlays(v3d->overlay.flag);
1311 drw_engines_enable_from_object_mode();
1312 drw_engines_enable_from_mode(mode);
1315 /* Force enable overlays engine for wireframe mode */
1316 if (v3d->shading.type == OB_WIRE) {
1317 drw_engines_enable_from_overlays(v3d->overlay.flag);
1319 /* if gpencil must draw the strokes, but not the object */
1320 drw_engines_enable_from_mode(mode);
1324 static void drw_engines_disable(void)
1326 BLI_freelistN(&DST.enabled_engines);
1329 static uint DRW_engines_get_hash(void)
1332 /* The cache depends on enabled engines */
1333 /* FIXME : if collision occurs ... segfault */
1334 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1335 DrawEngineType *engine = link->data;
1336 hash += BLI_ghashutil_strhash_p(engine->idname);
1342 /* -------------------------------------------------------------------- */
1343 /** \name View Update
1346 void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
1348 RenderEngineType *engine_type = update_ctx->engine_type;
1349 ARegion *ar = update_ctx->ar;
1350 View3D *v3d = update_ctx->v3d;
1351 RegionView3D *rv3d = ar->regiondata;
1352 Depsgraph *depsgraph = update_ctx->depsgraph;
1353 Scene *scene = update_ctx->scene;
1354 ViewLayer *view_layer = update_ctx->view_layer;
1356 /* Separate update for each stereo view. */
1357 for (int view = 0; view < 2; view++) {
1358 GPUViewport *viewport = WM_draw_region_get_viewport(ar, view);
1363 /* XXX Really nasty locking. But else this could
1364 * be executed by the material previews thread
1365 * while rendering a viewport. */
1366 BLI_ticket_mutex_lock(DST.gl_context_mutex);
1368 /* Reset before using it. */
1369 drw_state_prepare_clean_for_draw(&DST);
1371 DST.viewport = viewport;
1372 DST.draw_ctx = (DRWContextState){
1373 .ar = ar, .rv3d = rv3d, .v3d = v3d,
1374 .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
1375 .engine_type = engine_type,
1376 .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
1379 drw_engines_enable(view_layer, engine_type);
1381 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1382 DrawEngineType *draw_engine = link->data;
1383 ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
1385 if (draw_engine->view_update) {
1386 draw_engine->view_update(data);
1390 DST.viewport = NULL;
1392 drw_engines_disable();
1394 BLI_ticket_mutex_unlock(DST.gl_context_mutex);
1400 /* -------------------------------------------------------------------- */
1401 /** \name Main Draw Loops (DRW_draw)
1404 /* Everything starts here.
1405 * This function takes care of calling all cache and rendering functions
1406 * for each relevant engine / mode engine. */
1407 void DRW_draw_view(const bContext *C)
1409 Depsgraph *depsgraph = CTX_data_depsgraph(C);
1410 ARegion *ar = CTX_wm_region(C);
1411 View3D *v3d = CTX_wm_view3d(C);
1412 Scene *scene = DEG_get_evaluated_scene(depsgraph);
1413 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
1414 GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar);
1416 /* Reset before using it. */
1417 drw_state_prepare_clean_for_draw(&DST);
1418 DST.options.draw_text = (
1419 (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0 &&
1420 (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
1421 DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
1425 * Used for both regular and off-screen drawing.
1426 * Need to reset DST before calling this function
1428 void DRW_draw_render_loop_ex(
1429 struct Depsgraph *depsgraph,
1430 RenderEngineType *engine_type,
1431 ARegion *ar, View3D *v3d,
1432 GPUViewport *viewport,
1433 const bContext *evil_C)
1436 Scene *scene = DEG_get_evaluated_scene(depsgraph);
1437 ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1438 RegionView3D *rv3d = ar->regiondata;
1439 bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0));
1441 DST.draw_ctx.evil_C = evil_C;
1442 DST.viewport = viewport;
1444 /* Setup viewport */
1445 GPU_viewport_engines_data_validate(DST.viewport, DRW_engines_get_hash());
1447 DST.draw_ctx = (DRWContextState){
1448 .ar = ar, .rv3d = rv3d, .v3d = v3d,
1449 .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
1450 .engine_type = engine_type,
1451 .depsgraph = depsgraph,
1453 /* reuse if caller sets */
1454 .evil_C = DST.draw_ctx.evil_C,
1456 drw_context_state_init();
1457 drw_viewport_var_init();
1459 /* Get list of enabled engines */
1460 drw_engines_enable(view_layer, engine_type);
1463 DRW_globals_update();
1468 /* No framebuffer allowed before drawing. */
1469 BLI_assert(GPU_framebuffer_active_get() == NULL);
1476 PROFILE_START(stime);
1477 drw_engines_cache_init();
1478 drw_engines_world_update(scene);
1480 const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
1481 DEG_OBJECT_ITER_BEGIN(depsgraph, ob,
1482 DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
1483 DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
1484 DEG_ITER_OBJECT_FLAG_VISIBLE |
1485 DEG_ITER_OBJECT_FLAG_DUPLI)
1487 if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
1490 if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
1493 DST.dupli_parent = data_.dupli_parent;
1494 DST.dupli_source = data_.dupli_object_current;
1495 drw_engines_cache_populate(ob);
1497 DEG_OBJECT_ITER_END;
1499 drw_engines_cache_finish();
1501 DRW_render_instance_buffer_finish();
1504 double *cache_time = GPU_viewport_cache_time_get(DST.viewport);
1505 PROFILE_END_UPDATE(*cache_time, stime);
1511 GPU_framebuffer_bind(DST.default_framebuffer);
1518 drw_engines_draw_background();
1520 /* WIP, single image drawn over the camera view (replace) */
1521 bool do_bg_image = false;
1522 if (rv3d->persp == RV3D_CAMOB) {
1523 Object *cam_ob = v3d->camera;
1524 if (cam_ob && cam_ob->type == OB_CAMERA) {
1525 Camera *cam = cam_ob->data;
1526 if (!BLI_listbase_is_empty(&cam->bg_images)) {
1532 GPU_framebuffer_bind(DST.default_framebuffer);
1535 ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, true);
1538 DRW_draw_callbacks_pre_scene();
1539 if (DST.draw_ctx.evil_C) {
1540 ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
1543 drw_engines_draw_scene();
1546 /* Fix 3D view being "laggy" on macos. (See T56996) */
1550 /* annotations - temporary drawing buffer (3d space) */
1551 /* XXX: Or should we use a proper draw/overlay engine for this case? */
1552 if (do_annotations) {
1553 glDisable(GL_DEPTH_TEST);
1554 /* XXX: as scene->gpd is not copied for COW yet */
1555 ED_gpencil_draw_view3d_annotations(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true);
1556 glEnable(GL_DEPTH_TEST);
1559 DRW_draw_callbacks_post_scene();
1560 if (DST.draw_ctx.evil_C) {
1561 ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
1568 glDisable(GL_DEPTH_TEST);
1569 drw_engines_draw_text();
1570 glEnable(GL_DEPTH_TEST);
1572 if (DST.draw_ctx.evil_C) {
1573 /* needed so gizmo isn't obscured */
1574 if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
1575 ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0))
1577 glDisable(GL_DEPTH_TEST);
1578 DRW_draw_gizmo_3d();
1581 DRW_draw_region_info();
1583 /* annotations - temporary drawing buffer (screenspace) */
1584 /* XXX: Or should we use a proper draw/overlay engine for this case? */
1585 if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
1588 glDisable(GL_DEPTH_TEST);
1589 /* XXX: as scene->gpd is not copied for COW yet */
1590 ED_gpencil_draw_view3d_annotations(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false);
1591 glEnable(GL_DEPTH_TEST);
1594 if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
1595 /* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
1596 * 'DRW_draw_region_info' sets the projection in pixel-space. */
1597 glDisable(GL_DEPTH_TEST);
1598 DRW_draw_gizmo_2d();
1599 glEnable(GL_DEPTH_TEST);
1606 ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, true);
1609 if (G.debug_value > 20 && G.debug_value < 30) {
1610 glDisable(GL_DEPTH_TEST);
1611 rcti rect; /* local coordinate visible rect inside region, to accommodate overlapping ui */
1612 ED_region_visible_rect(DST.draw_ctx.ar, &rect);
1613 DRW_stats_draw(&rect);
1614 glEnable(GL_DEPTH_TEST);
1617 if (WM_draw_region_get_bound_viewport(ar)) {
1618 /* Don't unbind the framebuffer yet in this case and let
1619 * GPU_viewport_unbind do it, so that we can still do further
1620 * drawing of action zones on top. */
1623 GPU_framebuffer_restore();
1627 drw_engines_disable();
1629 drw_viewport_cache_resize();
1632 /* Avoid accidental reuse. */
1633 drw_state_ensure_not_reused(&DST);
1637 void DRW_draw_render_loop(
1638 struct Depsgraph *depsgraph,
1639 ARegion *ar, View3D *v3d,
1640 GPUViewport *viewport)
1642 /* Reset before using it. */
1643 drw_state_prepare_clean_for_draw(&DST);
1645 Scene *scene = DEG_get_evaluated_scene(depsgraph);
1646 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
1648 DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, NULL);
1651 /* @viewport CAN be NULL, in this case we create one. */
1652 void DRW_draw_render_loop_offscreen(
1653 struct Depsgraph *depsgraph, RenderEngineType *engine_type,
1654 ARegion *ar, View3D *v3d,
1655 const bool draw_background, GPUOffScreen *ofs,
1656 GPUViewport *viewport)
1658 /* Create temporary viewport if needed. */
1659 GPUViewport *render_viewport = viewport;
1660 if (viewport == NULL) {
1661 render_viewport = GPU_viewport_create_from_offscreen(ofs);
1664 GPU_framebuffer_restore();
1666 /* Reset before using it. */
1667 drw_state_prepare_clean_for_draw(&DST);
1668 DST.options.is_image_render = true;
1669 DST.options.draw_background = draw_background;
1670 DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, render_viewport, NULL);
1672 /* Free temporary viewport. */
1673 if (viewport == NULL) {
1674 /* don't free data owned by 'ofs' */
1675 GPU_viewport_clear_from_offscreen(render_viewport);
1676 GPU_viewport_free(render_viewport);
1679 /* we need to re-bind (annoying!) */
1680 GPU_offscreen_bind(ofs, false);
1683 /* Helper to check if exit object type to render. */
1684 bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
1686 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
1688 if (ob->type == OB_GPENCIL) {
1689 if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
1694 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
1699 static void DRW_render_gpencil_to_image(RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect)
1701 if (draw_engine_gpencil_type.render_to_image) {
1702 ViewportEngineData *gpdata = drw_viewport_engine_data_ensure(&draw_engine_gpencil_type);
1703 draw_engine_gpencil_type.render_to_image(gpdata, engine, render_layer, rect);
1707 void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph)
1709 /* This function is only valid for Cycles
1710 * Eevee done all work in the Eevee render directly.
1711 * Maybe it can be done equal for both engines?
1713 if (STREQ(engine->type->name, "Eevee")) {
1717 /* Early out if there are no grease pencil objects, especially important
1718 * to avoid failing in in background renders without OpenGL context. */
1719 if (!DRW_render_check_grease_pencil(depsgraph)) {
1723 Scene *scene = DEG_get_evaluated_scene(depsgraph);
1724 ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1725 RenderEngineType *engine_type = engine->type;
1726 RenderData *r = &scene->r;
1727 Render *render = engine->re;
1728 /* Changing Context */
1729 if (G.background && DST.gl_context == NULL) {
1730 WM_init_opengl(G_MAIN);
1733 void *re_gl_context = RE_gl_context_get(render);
1734 void *re_gpu_context = NULL;
1736 /* Changing Context */
1737 if (re_gl_context != NULL) {
1738 DRW_opengl_render_context_enable(re_gl_context);
1739 /* We need to query gpu context after a gl context has been bound. */
1740 re_gpu_context = RE_gpu_context_get(render);
1741 DRW_gawain_render_context_enable(re_gpu_context);
1744 DRW_opengl_context_enable();
1747 /* Reset before using it. */
1748 drw_state_prepare_clean_for_draw(&DST);
1749 DST.options.is_image_render = true;
1750 DST.options.is_scene_render = true;
1751 DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
1752 DST.buffer_finish_called = true;
1754 DST.draw_ctx = (DRWContextState) {
1755 .scene = scene, .view_layer = view_layer,
1756 .engine_type = engine_type,
1757 .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
1759 drw_context_state_init();
1761 DST.viewport = GPU_viewport_create();
1762 const int size[2] = { (r->size * r->xsch) / 100, (r->size * r->ysch) / 100 };
1763 GPU_viewport_size_set(DST.viewport, size);
1765 drw_viewport_var_init();
1767 /* set default viewport */
1768 gpuPushAttr(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT);
1769 glDisable(GL_SCISSOR_TEST);
1770 glViewport(0, 0, size[0], size[1]);
1772 /* Main rendering. */
1775 RE_GetViewPlane(render, &view_rect, &render_rect);
1776 if (BLI_rcti_is_empty(&render_rect)) {
1777 BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
1780 RenderResult *render_result = RE_engine_get_result(engine);
1781 RenderLayer *render_layer = render_result->layers.first;
1783 DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
1785 /* Force cache to reset. */
1786 drw_viewport_cache_resize();
1787 GPU_viewport_free(DST.viewport);
1790 glDisable(GL_DEPTH_TEST);
1792 /* Restore Drawing area. */
1794 glEnable(GL_SCISSOR_TEST);
1795 GPU_framebuffer_restore();
1797 /* Changing Context */
1798 /* GPXX Review this context */
1799 DRW_opengl_context_disable();
1801 DST.buffer_finish_called = false;
1804 void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
1806 Scene *scene = DEG_get_evaluated_scene(depsgraph);
1807 ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1808 RenderEngineType *engine_type = engine->type;
1809 DrawEngineType *draw_engine_type = engine_type->draw_engine;
1810 RenderData *r = &scene->r;
1811 Render *render = engine->re;
1813 if (G.background && DST.gl_context == NULL) {
1814 WM_init_opengl(G_MAIN);
1817 void *re_gl_context = RE_gl_context_get(render);
1818 void *re_gpu_context = NULL;
1820 /* Changing Context */
1821 if (re_gl_context != NULL) {
1822 DRW_opengl_render_context_enable(re_gl_context);
1823 /* We need to query gpu context after a gl context has been bound. */
1824 re_gpu_context = RE_gpu_context_get(render);
1825 DRW_gawain_render_context_enable(re_gpu_context);
1828 DRW_opengl_context_enable();
1831 /* IMPORTANT: We dont support immediate mode in render mode!
1832 * This shall remain in effect until immediate mode supports
1833 * multiple threads. */
1835 /* Reset before using it. */
1836 drw_state_prepare_clean_for_draw(&DST);
1837 DST.options.is_image_render = true;
1838 DST.options.is_scene_render = true;
1839 DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
1841 DST.draw_ctx = (DRWContextState){
1842 .scene = scene, .view_layer = view_layer,
1843 .engine_type = engine_type,
1844 .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
1846 drw_context_state_init();
1848 DST.viewport = GPU_viewport_create();
1849 const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100};
1850 GPU_viewport_size_set(DST.viewport, size);
1852 drw_viewport_var_init();
1854 ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
1856 /* set default viewport */
1857 glViewport(0, 0, size[0], size[1]);
1859 /* Main rendering. */
1862 RE_GetViewPlane(render, &view_rect, &render_rect);
1863 if (BLI_rcti_is_empty(&render_rect)) {
1864 BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
1867 /* Init render result. */
1868 RenderResult *render_result = RE_engine_begin_result(
1875 /* RR_ALL_VIEWS */ NULL);
1877 RenderLayer *render_layer = render_result->layers.first;
1878 for (RenderView *render_view = render_result->views.first;
1879 render_view != NULL;
1880 render_view = render_view->next)
1882 RE_SetActiveRenderView(render, render_view->name);
1883 engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect);
1884 /* grease pencil: render result is merged in the previous render result. */
1885 if (DRW_render_check_grease_pencil(depsgraph)) {
1886 DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
1888 DST.buffer_finish_called = false;
1891 RE_engine_end_result(engine, render_result, false, false, false);
1893 /* Force cache to reset. */
1894 drw_viewport_cache_resize();
1896 GPU_viewport_free(DST.viewport);
1897 GPU_framebuffer_restore();
1900 /* Avoid accidental reuse. */
1901 drw_state_ensure_not_reused(&DST);
1904 /* Changing Context */
1905 if (re_gl_context != NULL) {
1906 DRW_gawain_render_context_disable(re_gpu_context);
1907 DRW_opengl_render_context_disable(re_gl_context);
1910 DRW_opengl_context_disable();
1914 void DRW_render_object_iter(
1915 void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph,
1916 void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
1918 const DRWContextState *draw_ctx = DRW_context_state_get();
1922 const int object_type_exclude_viewport = draw_ctx->v3d ? draw_ctx->v3d->object_type_exclude_viewport : 0;
1923 DEG_OBJECT_ITER_BEGIN(depsgraph, ob,
1924 DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
1925 DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
1926 DEG_ITER_OBJECT_FLAG_VISIBLE |
1927 DEG_ITER_OBJECT_FLAG_DUPLI)
1929 if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
1930 DST.dupli_parent = data_.dupli_parent;
1931 DST.dupli_source = data_.dupli_object_current;
1932 DST.ob_state = NULL;
1933 callback(vedata, ob, engine, depsgraph);
1935 drw_batch_cache_generate_requested(ob);
1941 /* Assume a valid gl context is bound (and that the gl_context_mutex has been acquired).
1942 * This function only setup DST and execute the given function.
1943 * Warning: similar to DRW_render_to_image you cannot use default lists (dfbl & dtxl). */
1944 void DRW_custom_pipeline(
1945 DrawEngineType *draw_engine_type,
1946 struct Depsgraph *depsgraph,
1947 void (*callback)(void *vedata, void *user_data),
1950 Scene *scene = DEG_get_evaluated_scene(depsgraph);
1951 ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1953 /* Reset before using it. */
1954 drw_state_prepare_clean_for_draw(&DST);
1955 DST.options.is_image_render = true;
1956 DST.options.is_scene_render = true;
1957 DST.options.draw_background = false;
1959 DST.draw_ctx = (DRWContextState){
1961 .view_layer = view_layer,
1962 .engine_type = NULL,
1963 .depsgraph = depsgraph,
1964 .object_mode = OB_MODE_OBJECT,
1966 drw_context_state_init();
1968 DST.viewport = GPU_viewport_create();
1969 const int size[2] = {1, 1};
1970 GPU_viewport_size_set(DST.viewport, size);
1972 drw_viewport_var_init();
1976 ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
1978 /* Execute the callback */
1979 callback(data, user_data);
1980 DST.buffer_finish_called = false;
1982 GPU_viewport_free(DST.viewport);
1983 GPU_framebuffer_restore();
1986 /* Avoid accidental reuse. */
1987 drw_state_ensure_not_reused(&DST);
1991 static struct DRWSelectBuffer {
1992 struct GPUFrameBuffer *framebuffer;
1993 struct GPUTexture *texture_depth;
1994 } g_select_buffer = {NULL};
1996 static void draw_select_framebuffer_setup(const rcti *rect)
1998 if (g_select_buffer.framebuffer == NULL) {
1999 g_select_buffer.framebuffer = GPU_framebuffer_create();
2002 /* If size mismatch recreate the texture. */
2003 if ((g_select_buffer.texture_depth != NULL) &&
2004 ((GPU_texture_width(g_select_buffer.texture_depth) != BLI_rcti_size_x(rect)) ||
2005 (GPU_texture_height(g_select_buffer.texture_depth) != BLI_rcti_size_y(rect))))
2007 GPU_texture_free(g_select_buffer.texture_depth);
2008 g_select_buffer.texture_depth = NULL;
2011 if (g_select_buffer.texture_depth == NULL) {
2012 g_select_buffer.texture_depth = GPU_texture_create_2D(
2013 BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), GPU_DEPTH_COMPONENT24, NULL, NULL);
2015 GPU_framebuffer_texture_attach(g_select_buffer.framebuffer, g_select_buffer.texture_depth, 0, 0);
2017 if (!GPU_framebuffer_check_valid(g_select_buffer.framebuffer, NULL)) {
2018 printf("Error invalid selection framebuffer\n");
2023 /* Must run after all instance datas have been added. */
2024 void DRW_render_instance_buffer_finish(void)
2026 BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
2027 DST.buffer_finish_called = true;
2028 DRW_instance_buffer_finish(DST.idatalist);
2032 * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
2034 void DRW_draw_select_loop(
2035 struct Depsgraph *depsgraph,
2036 ARegion *ar, View3D *v3d,
2037 bool UNUSED(use_obedit_skip), bool draw_surface, bool UNUSED(use_nearest), const rcti *rect,
2038 DRW_SelectPassFn select_pass_fn, void *select_pass_user_data,
2039 DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data)
2041 Scene *scene = DEG_get_evaluated_scene(depsgraph);
2042 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
2043 ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
2044 Object *obact = OBACT(view_layer);
2045 Object *obedit = OBEDIT_FROM_OBACT(obact);
2046 #ifndef USE_GPU_SELECT
2047 UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
2049 RegionView3D *rv3d = ar->regiondata;
2051 /* Reset before using it. */
2052 drw_state_prepare_clean_for_draw(&DST);
2054 bool use_obedit = false;
2055 int obedit_mode = 0;
2056 if (obedit != NULL) {
2057 if (obedit->type == OB_MBALL) {
2059 obedit_mode = CTX_MODE_EDIT_METABALL;
2061 else if (obedit->type == OB_ARMATURE) {
2063 obedit_mode = CTX_MODE_EDIT_ARMATURE;
2066 if (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT) {
2067 if (!(v3d->flag2 & V3D_RENDER_OVERRIDE)) {
2068 /* Note: don't use "BKE_object_pose_armature_get" here, it breaks selection. */
2069 Object *obpose = OBPOSE_FROM_OBACT(obact);
2072 obedit_mode = CTX_MODE_POSE;
2077 struct GPUViewport *viewport = GPU_viewport_create();
2078 GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)});
2080 DST.viewport = viewport;
2081 DST.options.is_select = true;
2083 /* Get list of enabled engines */
2085 drw_engines_enable_from_paint_mode(obedit_mode);
2086 drw_engines_enable_from_mode(obedit_mode);
2088 else if (!draw_surface) {
2089 drw_engines_enable_from_overlays(v3d->overlay.flag);
2090 drw_engines_enable_from_object_mode();
2093 drw_engines_enable_basic();
2094 drw_engines_enable_from_overlays(v3d->overlay.flag);
2095 drw_engines_enable_from_object_mode();
2098 /* Setup viewport */
2100 /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2101 DST.draw_ctx = (DRWContextState){
2102 .ar = ar, .rv3d = rv3d, .v3d = v3d,
2103 .scene = scene, .view_layer = view_layer, .obact = obact,
2104 .engine_type = engine_type,
2105 .depsgraph = depsgraph,
2107 drw_context_state_init();
2108 drw_viewport_var_init();
2111 DRW_globals_update();
2118 drw_engines_cache_init();
2119 drw_engines_world_update(scene);
2123 drw_engines_cache_populate(obact);
2125 FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
2126 drw_engines_cache_populate(ob_iter);
2128 FOREACH_OBJECT_IN_MODE_END;
2132 const int object_type_exclude_select = (
2133 v3d->object_type_exclude_viewport | v3d->object_type_exclude_select
2135 bool filter_exclude = false;
2136 DEG_OBJECT_ITER_BEGIN(depsgraph, ob,
2137 DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
2138 DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
2139 DEG_ITER_OBJECT_FLAG_VISIBLE |
2140 DEG_ITER_OBJECT_FLAG_DUPLI)
2142 if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
2146 if ((ob->base_flag & BASE_SELECTABLE) &&
2147 (object_type_exclude_select & (1 << ob->type)) == 0)
2149 if (object_filter_fn != NULL) {
2150 if (ob->base_flag & BASE_FROM_DUPLI) {
2151 /* pass (use previous filter_exclude value) */
2154 filter_exclude = (object_filter_fn(ob, object_filter_user_data) == false);
2156 if (filter_exclude) {
2161 /* This relies on dupli instances being after their instancing object. */
2162 if ((ob->base_flag & BASE_FROM_DUPLI) == 0) {
2163 Object *ob_orig = DEG_get_original_object(ob);
2164 DRW_select_load_id(ob_orig->select_color);
2166 DST.dupli_parent = data_.dupli_parent;
2167 DST.dupli_source = data_.dupli_object_current;
2168 drw_engines_cache_populate(ob);
2171 DEG_OBJECT_ITER_END;
2174 drw_engines_cache_finish();
2176 DRW_render_instance_buffer_finish();
2179 /* Setup framebuffer */
2180 draw_select_framebuffer_setup(rect);
2181 GPU_framebuffer_bind(g_select_buffer.framebuffer);
2182 GPU_framebuffer_clear_depth(g_select_buffer.framebuffer, 1.0f);
2186 DRW_draw_callbacks_pre_scene();
2191 DRW_STATE_WRITE_DEPTH |
2192 DRW_STATE_DEPTH_ALWAYS |
2193 DRW_STATE_DEPTH_LESS_EQUAL |
2194 DRW_STATE_DEPTH_EQUAL |
2195 DRW_STATE_DEPTH_GREATER |
2196 DRW_STATE_DEPTH_ALWAYS);
2198 /* Only 1-2 passes. */
2200 if (!select_pass_fn(DRW_SELECT_PASS_PRE, select_pass_user_data)) {
2204 drw_engines_draw_scene();
2206 if (!select_pass_fn(DRW_SELECT_PASS_POST, select_pass_user_data)) {
2213 DRW_draw_callbacks_post_scene();
2216 drw_engines_disable();
2219 /* Avoid accidental reuse. */
2220 drw_state_ensure_not_reused(&DST);
2222 GPU_framebuffer_restore();
2224 /* Cleanup for selection state */
2225 GPU_viewport_free(viewport);
2226 #endif /* USE_GPU_SELECT */
2229 static void draw_depth_texture_to_screen(GPUTexture *texture)
2231 const float w = (float)GPU_texture_width(texture);
2232 const float h = (float)GPU_texture_height(texture);
2234 GPUVertFormat *format = immVertexFormat();
2235 uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
2236 uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
2238 immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_DEPTH_COPY);
2240 GPU_texture_bind(texture, 0);
2242 immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
2244 immBegin(GPU_PRIM_TRI_STRIP, 4);
2246 immAttr2f(texcoord, 0.0f, 0.0f);
2247 immVertex2f(pos, 0.0f, 0.0f);
2249 immAttr2f(texcoord, 1.0f, 0.0f);
2250 immVertex2f(pos, w, 0.0f);
2252 immAttr2f(texcoord, 0.0f, 1.0f);
2253 immVertex2f(pos, 0.0f, h);
2255 immAttr2f(texcoord, 1.0f, 1.0f);
2256 immVertex2f(pos, w, h);
2260 GPU_texture_unbind(texture);
2266 * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
2268 void DRW_draw_depth_loop(
2269 Depsgraph *depsgraph,
2270 ARegion *ar, View3D *v3d)
2272 Scene *scene = DEG_get_evaluated_scene(depsgraph);
2273 RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
2274 ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
2275 RegionView3D *rv3d = ar->regiondata;
2277 DRW_opengl_context_enable();
2279 /* Reset before using it. */
2280 drw_state_prepare_clean_for_draw(&DST);
2282 struct GPUViewport *viewport = GPU_viewport_create();
2283 GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy});
2285 /* Setup framebuffer */
2286 draw_select_framebuffer_setup(&ar->winrct);
2287 GPU_framebuffer_bind(g_select_buffer.framebuffer);
2288 GPU_framebuffer_clear_depth(g_select_buffer.framebuffer, 1.0f);
2290 DST.viewport = viewport;
2291 DST.options.is_depth = true;
2293 /* Get list of enabled engines */
2295 drw_engines_enable_basic();
2296 if (DRW_state_draw_support()) {
2297 drw_engines_enable_from_object_mode();
2301 /* Setup viewport */
2303 /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2304 DST.draw_ctx = (DRWContextState){
2305 .ar = ar, .rv3d = rv3d, .v3d = v3d,
2306 .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
2307 .engine_type = engine_type,
2308 .depsgraph = depsgraph,
2310 drw_context_state_init();
2311 drw_viewport_var_init();
2314 DRW_globals_update();
2321 drw_engines_cache_init();
2322 drw_engines_world_update(scene);
2324 const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
2325 DEG_OBJECT_ITER_BEGIN(depsgraph, ob,
2326 DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
2327 DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
2328 DEG_ITER_OBJECT_FLAG_VISIBLE |
2329 DEG_ITER_OBJECT_FLAG_DUPLI)
2331 if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
2335 if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
2339 DST.dupli_parent = data_.dupli_parent;
2340 DST.dupli_source = data_.dupli_object_current;
2341 drw_engines_cache_populate(ob);
2343 DEG_OBJECT_ITER_END;
2345 drw_engines_cache_finish();
2347 DRW_render_instance_buffer_finish();
2355 DRW_draw_callbacks_pre_scene();
2356 drw_engines_draw_scene();
2357 DRW_draw_callbacks_post_scene();
2360 drw_engines_disable();
2363 /* Avoid accidental reuse. */
2364 drw_state_ensure_not_reused(&DST);
2367 /* TODO: Reading depth for operators should be done here. */
2369 GPU_framebuffer_restore();
2371 /* Cleanup for selection state */
2372 GPU_viewport_free(viewport);
2374 /* Changin context */
2375 DRW_opengl_context_disable();
2377 /* XXX Drawing the resulting buffer to the BACK_BUFFER */
2379 GPU_matrix_push_projection();
2380 wmOrtho2_region_pixelspace(ar);
2381 GPU_matrix_identity_set();
2383 glEnable(GL_DEPTH_TEST); /* Cannot write to depth buffer without testing */
2384 glDepthFunc(GL_ALWAYS);
2385 draw_depth_texture_to_screen(g_select_buffer.texture_depth);
2386 glDepthFunc(GL_LEQUAL);
2389 GPU_matrix_pop_projection();
2395 /* -------------------------------------------------------------------- */
2396 /** \name Draw Manager State (DRW_state)
2399 void DRW_state_dfdy_factors_get(float dfdyfac[2])
2401 GPU_get_dfdy_factors(dfdyfac);
2405 * When false, drawing doesn't output to a pixel buffer
2406 * eg: Occlusion queries, or when we have setup a context to draw in already.
2408 bool DRW_state_is_fbo(void)
2410 return ((DST.default_framebuffer != NULL) || DST.options.is_image_render);
2414 * For when engines need to know if this is drawing for selection or not.
2416 bool DRW_state_is_select(void)
2418 return DST.options.is_select;
2421 bool DRW_state_is_depth(void)
2423 return DST.options.is_depth;
2427 * Whether we are rendering for an image
2429 bool DRW_state_is_image_render(void)
2431 return DST.options.is_image_render;
2435 * Whether we are rendering only the render engine,
2436 * or if we should also render the mode engines.
2438 bool DRW_state_is_scene_render(void)
2440 BLI_assert(DST.options.is_scene_render ?
2441 DST.options.is_image_render : true);
2442 return DST.options.is_scene_render;
2446 * Whether we are rendering simple opengl render
2448 bool DRW_state_is_opengl_render(void)
2450 return DST.options.is_image_render && !DST.options.is_scene_render;
2453 bool DRW_state_is_playback(void)
2455 if (DST.draw_ctx.evil_C != NULL) {
2456 struct wmWindowManager *wm = CTX_wm_manager(DST.draw_ctx.evil_C);
2457 return ED_screen_animation_playing(wm) != NULL;
2464 * Should text draw in this mode?
2466 bool DRW_state_show_text(void)
2468 return (DST.options.is_select) == 0 &&
2469 (DST.options.is_depth) == 0 &&
2470 (DST.options.is_scene_render) == 0 &&
2471 (DST.options.draw_text) == 0;
2475 * Should draw support elements
2476 * Objects center, selection outline, probe data, ...
2478 bool DRW_state_draw_support(void)
2480 View3D *v3d = DST.draw_ctx.v3d;
2481 return (DRW_state_is_scene_render() == false) &&
2483 ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0);
2487 * Whether we should render the background
2489 bool DRW_state_draw_background(void)
2491 if (DRW_state_is_image_render() == false) {
2494 return DST.options.draw_background;
2500 /* -------------------------------------------------------------------- */
2501 /** \name Context State (DRW_context_state)
2504 const DRWContextState *DRW_context_state_get(void)
2506 return &DST.draw_ctx;
2512 /* -------------------------------------------------------------------- */
2513 /** \name Init/Exit (DRW_engines)
2516 bool DRW_engine_render_support(DrawEngineType *draw_engine_type)
2518 return draw_engine_type->render_to_image;
2521 void DRW_engine_register(DrawEngineType *draw_engine_type)
2523 BLI_addtail(&DRW_engines, draw_engine_type);
2526 void DRW_engines_register(void)
2528 RE_engines_register(&DRW_engine_viewport_eevee_type);
2529 RE_engines_register(&DRW_engine_viewport_workbench_type);
2531 DRW_engine_register(&draw_engine_workbench_solid);
2532 DRW_engine_register(&draw_engine_workbench_transparent);
2534 DRW_engine_register(&draw_engine_object_type);
2535 DRW_engine_register(&draw_engine_edit_armature_type);
2536 DRW_engine_register(&draw_engine_edit_curve_type);
2537 DRW_engine_register(&draw_engine_edit_lattice_type);
2538 DRW_engine_register(&draw_engine_edit_mesh_type);
2539 DRW_engine_register(&draw_engine_edit_metaball_type);
2540 DRW_engine_register(&draw_engine_edit_text_type);
2541 DRW_engine_register(&draw_engine_motion_path_type);
2542 DRW_engine_register(&draw_engine_overlay_type);
2543 DRW_engine_register(&draw_engine_paint_texture_type);
2544 DRW_engine_register(&draw_engine_paint_vertex_type);
2545 DRW_engine_register(&draw_engine_paint_weight_type);
2546 DRW_engine_register(&draw_engine_particle_type);
2547 DRW_engine_register(&draw_engine_pose_type);
2548 DRW_engine_register(&draw_engine_sculpt_type);
2549 DRW_engine_register(&draw_engine_gpencil_type);
2551 /* setup callbacks */
2554 extern void *BKE_mball_batch_cache_dirty_tag_cb;
2555 extern void *BKE_mball_batch_cache_free_cb;
2557 extern void *BKE_curve_batch_cache_dirty_tag_cb;
2558 extern void *BKE_curve_batch_cache_free_cb;
2560 extern void *BKE_mesh_batch_cache_dirty_tag_cb;
2561 extern void *BKE_mesh_batch_cache_free_cb;
2562 /* BKE: lattice.c */
2563 extern void *BKE_lattice_batch_cache_dirty_tag_cb;
2564 extern void *BKE_lattice_batch_cache_free_cb;
2565 /* BKE: particle.c */
2566 extern void *BKE_particle_batch_cache_dirty_tag_cb;
2567 extern void *BKE_particle_batch_cache_free_cb;
2568 /* BKE: gpencil.c */
2569 extern void *BKE_gpencil_batch_cache_dirty_tag_cb;
2570 extern void *BKE_gpencil_batch_cache_free_cb;
2572 BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag;
2573 BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free;
2575 BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag;
2576 BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free;
2578 BKE_mesh_batch_cache_dirty_tag_cb = DRW_mesh_batch_cache_dirty_tag;
2579 BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free;
2581 BKE_lattice_batch_cache_dirty_tag_cb = DRW_lattice_batch_cache_dirty_tag;
2582 BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free;
2584 BKE_particle_batch_cache_dirty_tag_cb = DRW_particle_batch_cache_dirty_tag;
2585 BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free;
2587 BKE_gpencil_batch_cache_dirty_tag_cb = DRW_gpencil_batch_cache_dirty_tag;
2588 BKE_gpencil_batch_cache_free_cb = DRW_gpencil_batch_cache_free;
2592 extern struct GPUVertFormat *g_pos_format; /* draw_shgroup.c */
2593 void DRW_engines_free(void)
2595 DRW_opengl_context_enable();
2597 DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth);
2598 GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer);
2601 DRW_shape_cache_free();
2605 DrawEngineType *next;
2606 for (DrawEngineType *type = DRW_engines.first; type; type = next) {
2608 BLI_remlink(&R_engines, type);
2610 if (type->engine_free) {
2611 type->engine_free();
2615 DRW_UBO_FREE_SAFE(G_draw.block_ubo);
2616 DRW_UBO_FREE_SAFE(view_ubo);
2617 DRW_TEXTURE_FREE_SAFE(G_draw.ramp);
2618 DRW_TEXTURE_FREE_SAFE(G_draw.weight_ramp);
2619 MEM_SAFE_FREE(g_pos_format);
2621 MEM_SAFE_FREE(DST.RST.bound_texs);
2622 MEM_SAFE_FREE(DST.RST.bound_tex_slots);
2623 MEM_SAFE_FREE(DST.RST.bound_ubos);
2624 MEM_SAFE_FREE(DST.RST.bound_ubo_slots);
2626 MEM_SAFE_FREE(DST.uniform_names.buffer);
2628 DRW_opengl_context_disable();
2633 /** \name Init/Exit (DRW_opengl_ctx)
2636 void DRW_opengl_context_create(void)
2638 BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */
2640 DST.gl_context_mutex = BLI_ticket_mutex_alloc();
2641 if (!G.background) {
2644 /* This changes the active context. */
2645 DST.gl_context = WM_opengl_context_create();
2646 WM_opengl_context_activate(DST.gl_context);
2647 /* Be sure to create gawain.context too. */
2648 DST.gpu_context = GPU_context_create();
2649 if (!G.background) {
2652 /* Set default Blender OpenGL state */
2654 /* So we activate the window's one afterwards. */
2655 wm_window_reset_drawable();
2658 void DRW_opengl_context_destroy(void)
2660 BLI_assert(BLI_thread_is_main());
2661 if (DST.gl_context != NULL) {
2662 WM_opengl_context_activate(DST.gl_context);
2663 GPU_context_active_set(DST.gpu_context);
2664 GPU_context_discard(DST.gpu_context);
2665 WM_opengl_context_dispose(DST.gl_context);
2666 BLI_ticket_mutex_free(DST.gl_context_mutex);
2670 void DRW_opengl_context_enable_ex(bool restore)
2672 if (DST.gl_context != NULL) {
2673 /* IMPORTANT: We dont support immediate mode in render mode!
2674 * This shall remain in effect until immediate mode supports
2675 * multiple threads. */
2676 BLI_ticket_mutex_lock(DST.gl_context_mutex);
2677 if (BLI_thread_is_main() && restore) {
2678 if (!G.background) {
2682 WM_opengl_context_activate(DST.gl_context);
2683 GPU_context_active_set(DST.gpu_context);
2684 if (BLI_thread_is_main() && restore) {
2685 if (!G.background) {
2693 void DRW_opengl_context_disable_ex(bool restore)
2695 if (DST.gl_context != NULL) {
2697 /* Need to flush before disabling draw context, otherwise it does not
2698 * always finish drawing and viewport can be empty or partially drawn */
2702 if (BLI_thread_is_main() && restore) {
2703 wm_window_reset_drawable();
2706 WM_opengl_context_release(DST.gl_context);
2707 GPU_context_active_set(NULL);
2710 BLI_ticket_mutex_unlock(DST.gl_context_mutex);
2714 void DRW_opengl_context_enable(void)
2716 DRW_opengl_context_enable_ex(true);
2719 void DRW_opengl_context_disable(void)
2721 DRW_opengl_context_disable_ex(true);
2724 void DRW_opengl_render_context_enable(void *re_gl_context)
2726 /* If thread is main you should use DRW_opengl_context_enable(). */
2727 BLI_assert(!BLI_thread_is_main());
2729 /* TODO get rid of the blocking. Only here because of the static global DST. */
2730 BLI_ticket_mutex_lock(DST.gl_context_mutex);
2731 WM_opengl_context_activate(re_gl_context);
2734 void DRW_opengl_render_context_disable(void *re_gl_context)
2737 WM_opengl_context_release(re_gl_context);
2738 /* TODO get rid of the blocking. */
2739 BLI_ticket_mutex_unlock(DST.gl_context_mutex);
2742 /* Needs to be called AFTER DRW_opengl_render_context_enable() */
2743 void DRW_gawain_render_context_enable(void *re_gpu_context)
2745 /* If thread is main you should use DRW_opengl_context_enable(). */
2746 BLI_assert(!BLI_thread_is_main());
2748 GPU_context_active_set(re_gpu_context);
2749 DRW_shape_cache_reset(); /* XXX fix that too. */
2752 /* Needs to be called BEFORE DRW_opengl_render_context_disable() */
2753 void DRW_gawain_render_context_disable(void *UNUSED(re_gpu_context))
2755 DRW_shape_cache_reset(); /* XXX fix that too. */
2756 GPU_context_active_set(NULL);