Industry Compat Keymap: support new outliner features
[blender.git] / source / blender / draw / intern / draw_manager.c
1 /*
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.
6  *
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.
11  *
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.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup draw
21  */
22
23 #include <stdio.h>
24
25 #include "BLI_alloca.h"
26 #include "BLI_listbase.h"
27 #include "BLI_memblock.h"
28 #include "BLI_rect.h"
29 #include "BLI_string.h"
30 #include "BLI_threads.h"
31
32 #include "BLF_api.h"
33
34 #include "BKE_anim.h"
35 #include "BKE_colortools.h"
36 #include "BKE_curve.h"
37 #include "BKE_editmesh.h"
38 #include "BKE_global.h"
39 #include "BKE_gpencil.h"
40 #include "BKE_lattice.h"
41 #include "BKE_main.h"
42 #include "BKE_mball.h"
43 #include "BKE_mesh.h"
44 #include "BKE_object.h"
45 #include "BKE_particle.h"
46 #include "BKE_paint.h"
47 #include "BKE_pbvh.h"
48 #include "BKE_pointcache.h"
49
50 #include "draw_manager.h"
51 #include "DNA_camera_types.h"
52 #include "DNA_mesh_types.h"
53 #include "DNA_meshdata_types.h"
54 #include "DNA_world_types.h"
55
56 #include "ED_space_api.h"
57 #include "ED_screen.h"
58 #include "ED_gpencil.h"
59 #include "ED_view3d.h"
60
61 #include "GPU_draw.h"
62 #include "GPU_extensions.h"
63 #include "GPU_framebuffer.h"
64 #include "GPU_immediate.h"
65 #include "GPU_uniformbuffer.h"
66 #include "GPU_viewport.h"
67 #include "GPU_matrix.h"
68 #include "GPU_select.h"
69
70 #include "IMB_colormanagement.h"
71
72 #include "RE_engine.h"
73 #include "RE_pipeline.h"
74
75 #include "UI_resources.h"
76
77 #include "WM_api.h"
78 #include "wm_window.h"
79
80 #include "draw_manager_text.h"
81 #include "draw_manager_profiling.h"
82
83 /* only for callbacks */
84 #include "draw_cache_impl.h"
85
86 #include "draw_mode_engines.h"
87 #include "engines/eevee/eevee_engine.h"
88 #include "engines/basic/basic_engine.h"
89 #include "engines/workbench/workbench_engine.h"
90 #include "engines/external/external_engine.h"
91 #include "engines/gpencil/gpencil_engine.h"
92 #include "engines/select/select_engine.h"
93
94 #include "GPU_context.h"
95
96 #include "DEG_depsgraph.h"
97 #include "DEG_depsgraph_query.h"
98
99 #include "DRW_select_buffer.h"
100
101 #ifdef USE_GPU_SELECT
102 #  include "GPU_select.h"
103 #endif
104
105 /** Render State: No persistent data between draw calls. */
106 DRWManager DST = {NULL};
107
108 static ListBase DRW_engines = {NULL, NULL};
109
110 static void drw_state_prepare_clean_for_draw(DRWManager *dst)
111 {
112   memset(dst, 0x0, offsetof(DRWManager, gl_context));
113
114   /* Maybe not the best place for this. */
115   if (!DST.uniform_names.buffer) {
116     DST.uniform_names.buffer = MEM_callocN(DRW_UNIFORM_BUFFER_NAME, "Name Buffer");
117     DST.uniform_names.buffer_len = DRW_UNIFORM_BUFFER_NAME;
118   }
119   else if (DST.uniform_names.buffer_len > DRW_UNIFORM_BUFFER_NAME) {
120     DST.uniform_names.buffer = MEM_reallocN(DST.uniform_names.buffer, DRW_UNIFORM_BUFFER_NAME);
121     DST.uniform_names.buffer_len = DRW_UNIFORM_BUFFER_NAME;
122   }
123   DST.uniform_names.buffer_ofs = 0;
124 }
125
126 /* This function is used to reset draw manager to a state
127  * where we don't re-use data by accident across different
128  * draw calls.
129  */
130 #ifdef DEBUG
131 static void drw_state_ensure_not_reused(DRWManager *dst)
132 {
133   memset(dst, 0xff, offsetof(DRWManager, gl_context));
134 }
135 #endif
136
137 /* -------------------------------------------------------------------- */
138
139 void DRW_draw_callbacks_pre_scene(void)
140 {
141   RegionView3D *rv3d = DST.draw_ctx.rv3d;
142
143   GPU_matrix_projection_set(rv3d->winmat);
144   GPU_matrix_set(rv3d->viewmat);
145 }
146
147 void DRW_draw_callbacks_post_scene(void)
148 {
149   RegionView3D *rv3d = DST.draw_ctx.rv3d;
150
151   GPU_matrix_projection_set(rv3d->winmat);
152   GPU_matrix_set(rv3d->viewmat);
153 }
154
155 struct DRWTextStore *DRW_text_cache_ensure(void)
156 {
157   BLI_assert(DST.text_store_p);
158   if (*DST.text_store_p == NULL) {
159     *DST.text_store_p = DRW_text_cache_create();
160   }
161   return *DST.text_store_p;
162 }
163
164 /* -------------------------------------------------------------------- */
165 /** \name Settings
166  * \{ */
167
168 bool DRW_object_is_renderable(const Object *ob)
169 {
170   BLI_assert((ob->base_flag & BASE_VISIBLE) != 0);
171
172   if (ob->type == OB_MESH) {
173     if ((ob == DST.draw_ctx.object_edit) || BKE_object_is_in_editmode(ob)) {
174       View3D *v3d = DST.draw_ctx.v3d;
175       const int mask = (V3D_OVERLAY_EDIT_OCCLUDE_WIRE | V3D_OVERLAY_EDIT_WEIGHT);
176
177       if (v3d && v3d->overlay.edit_flag & mask) {
178         return false;
179       }
180     }
181   }
182
183   return true;
184 }
185
186 /**
187  * Return whether this object is visible depending if
188  * we are rendering or drawing in the viewport.
189  */
190 int DRW_object_visibility_in_active_context(const Object *ob)
191 {
192   const eEvaluationMode mode = DRW_state_is_scene_render() ? DAG_EVAL_RENDER : DAG_EVAL_VIEWPORT;
193   return BKE_object_visibility(ob, mode);
194 }
195
196 bool DRW_object_is_flat_normal(const Object *ob)
197 {
198   if (ob->type == OB_MESH) {
199     const Mesh *me = ob->data;
200     if (me->mpoly && me->mpoly[0].flag & ME_SMOOTH) {
201       return false;
202     }
203   }
204   return true;
205 }
206
207 bool DRW_object_use_hide_faces(const struct Object *ob)
208 {
209   if (ob->type == OB_MESH) {
210     const Mesh *me = ob->data;
211
212     switch (ob->mode) {
213       case OB_MODE_SCULPT:
214         return true;
215       case OB_MODE_TEXTURE_PAINT:
216         return (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
217       case OB_MODE_VERTEX_PAINT:
218       case OB_MODE_WEIGHT_PAINT:
219         return (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
220     }
221   }
222
223   return false;
224 }
225
226 bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
227 {
228   const bool for_render = DRW_state_is_image_render();
229   /* NOTE: psys_check_enabled is using object and particle system for only
230    * reading, but is using some other functions which are more generic and
231    * which are hard to make const-pointer. */
232   if (!psys_check_enabled((Object *)object, (ParticleSystem *)psys, for_render)) {
233     return false;
234   }
235   const DRWContextState *draw_ctx = DRW_context_state_get();
236   const Scene *scene = draw_ctx->scene;
237   if (object == draw_ctx->object_edit) {
238     return false;
239   }
240   const ParticleSettings *part = psys->part;
241   const ParticleEditSettings *pset = &scene->toolsettings->particle;
242   if (object->mode == OB_MODE_PARTICLE_EDIT) {
243     if (psys_in_edit_mode(draw_ctx->depsgraph, psys)) {
244       if ((pset->flag & PE_DRAW_PART) == 0) {
245         return false;
246       }
247       if ((part->childtype == 0) &&
248           (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) == 0) {
249         return false;
250       }
251     }
252   }
253   return true;
254 }
255
256 struct Object *DRW_object_get_dupli_parent(const Object *UNUSED(ob))
257 {
258   return DST.dupli_parent;
259 }
260
261 struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob))
262 {
263   return DST.dupli_source;
264 }
265
266 /** \} */
267
268 /* -------------------------------------------------------------------- */
269 /** \name Color Management
270  * \{ */
271
272 /* Use color management profile to draw texture to framebuffer */
273 void DRW_transform_to_display(GPUTexture *tex, bool use_view_transform, bool use_render_settings)
274 {
275   drw_state_set(DRW_STATE_WRITE_COLOR);
276
277   GPUVertFormat *vert_format = immVertexFormat();
278   uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
279   uint texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
280
281   const float dither = 1.0f;
282
283   bool use_ocio = false;
284
285   /* Should we apply the view transform */
286   if (DRW_state_do_color_management()) {
287     Scene *scene = DST.draw_ctx.scene;
288     ColorManagedDisplaySettings *display_settings = &scene->display_settings;
289     ColorManagedViewSettings view_settings;
290     if (use_render_settings) {
291       /* Use full render settings, for renders with scene lighting. */
292       view_settings = scene->view_settings;
293     }
294     else if (use_view_transform) {
295       /* Use only view transform + look and nothing else for lookdev without
296        * scene lighting, as exposure depends on scene light intensity. */
297       BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
298       STRNCPY(view_settings.view_transform, scene->view_settings.view_transform);
299       STRNCPY(view_settings.look, scene->view_settings.look);
300     }
301     else {
302       /* For workbench use only default view transform in configuration,
303        * using no scene settings. */
304       BKE_color_managed_view_settings_init_render(&view_settings, display_settings, NULL);
305     }
306
307     use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(
308         &view_settings, display_settings, NULL, dither, false);
309   }
310
311   if (!use_ocio) {
312     /* View transform is already applied for offscreen, don't apply again, see: T52046 */
313     if (DST.options.is_image_render && !DST.options.is_scene_render) {
314       immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
315       immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
316     }
317     else {
318       immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB);
319     }
320     immUniform1i("image", 0);
321   }
322
323   GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */
324
325   float mat[4][4];
326   unit_m4(mat);
327   immUniformMatrix4fv("ModelViewProjectionMatrix", mat);
328
329   /* Full screen triangle */
330   immBegin(GPU_PRIM_TRIS, 3);
331   immAttr2f(texco, 0.0f, 0.0f);
332   immVertex2f(pos, -1.0f, -1.0f);
333
334   immAttr2f(texco, 2.0f, 0.0f);
335   immVertex2f(pos, 3.0f, -1.0f);
336
337   immAttr2f(texco, 0.0f, 2.0f);
338   immVertex2f(pos, -1.0f, 3.0f);
339   immEnd();
340
341   GPU_texture_unbind(tex);
342
343   if (use_ocio) {
344     IMB_colormanagement_finish_glsl_draw();
345   }
346   else {
347     immUnbindProgram();
348   }
349 }
350
351 /* Draw texture to framebuffer without any color transforms */
352 void DRW_transform_none(GPUTexture *tex)
353 {
354   drw_state_set(DRW_STATE_WRITE_COLOR);
355
356   /* Draw as texture for final render (without immediate mode). */
357   GPUBatch *geom = DRW_cache_fullscreen_quad_get();
358   GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_IMAGE_COLOR);
359
360   GPU_texture_bind(tex, 0);
361
362   const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
363   GPU_batch_uniform_4fv(geom, "color", white);
364
365   float mat[4][4];
366   unit_m4(mat);
367   GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
368
369   GPU_batch_program_use_begin(geom);
370   GPU_batch_bind(geom);
371   GPU_batch_draw_advanced(geom, 0, 0, 0, 0);
372   GPU_batch_program_use_end(geom);
373
374   GPU_texture_unbind(tex);
375 }
376
377 /** \} */
378
379 /* -------------------------------------------------------------------- */
380 /** \name Multisample Resolve
381  * \{ */
382
383 /**
384  * Use manual multisample resolve pass.
385  * Much quicker than blitting back and forth.
386  * Assume destination fb is bound.
387  */
388 void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool use_depth)
389 {
390   DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL;
391
392   if (use_depth) {
393     state |= DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
394   }
395   drw_state_set(state);
396
397   int samples = GPU_texture_samples(src_depth);
398
399   BLI_assert(samples > 0);
400   BLI_assert(GPU_texture_samples(src_color) == samples);
401
402   GPUBatch *geom = DRW_cache_fullscreen_quad_get();
403
404   int builtin;
405   if (use_depth) {
406     switch (samples) {
407       case 2:
408         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
409         break;
410       case 4:
411         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4_DEPTH_TEST;
412         break;
413       case 8:
414         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8_DEPTH_TEST;
415         break;
416       case 16:
417         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST;
418         break;
419       default:
420         BLI_assert(!"Mulisample count unsupported by blit shader.");
421         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
422         break;
423     }
424   }
425   else {
426     switch (samples) {
427       case 2:
428         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
429         break;
430       case 4:
431         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_4;
432         break;
433       case 8:
434         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_8;
435         break;
436       case 16:
437         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16;
438         break;
439       default:
440         BLI_assert(!"Mulisample count unsupported by blit shader.");
441         builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
442         break;
443     }
444   }
445
446   GPU_batch_program_set_builtin(geom, builtin);
447
448   if (use_depth) {
449     GPU_texture_bind(src_depth, 0);
450     GPU_batch_uniform_1i(geom, "depthMulti", 0);
451   }
452
453   GPU_texture_bind(src_color, 1);
454   GPU_batch_uniform_1i(geom, "colorMulti", 1);
455
456   float mat[4][4];
457   unit_m4(mat);
458   GPU_batch_uniform_mat4(geom, "ModelViewProjectionMatrix", mat);
459
460   /* avoid gpuMatrix calls */
461   GPU_batch_program_use_begin(geom);
462   GPU_batch_bind(geom);
463   GPU_batch_draw_advanced(geom, 0, 0, 0, 0);
464   GPU_batch_program_use_end(geom);
465 }
466
467 /** \} */
468
469 /* -------------------------------------------------------------------- */
470 /** \name Viewport (DRW_viewport)
471  * \{ */
472
473 void *drw_viewport_engine_data_ensure(void *engine_type)
474 {
475   void *data = GPU_viewport_engine_data_get(DST.viewport, engine_type);
476
477   if (data == NULL) {
478     data = GPU_viewport_engine_data_create(DST.viewport, engine_type);
479   }
480   return data;
481 }
482
483 void DRW_engine_viewport_data_size_get(
484     const void *engine_type_v, int *r_fbl_len, int *r_txl_len, int *r_psl_len, int *r_stl_len)
485 {
486   const DrawEngineType *engine_type = engine_type_v;
487
488   if (r_fbl_len) {
489     *r_fbl_len = engine_type->vedata_size->fbl_len;
490   }
491   if (r_txl_len) {
492     *r_txl_len = engine_type->vedata_size->txl_len;
493   }
494   if (r_psl_len) {
495     *r_psl_len = engine_type->vedata_size->psl_len;
496   }
497   if (r_stl_len) {
498     *r_stl_len = engine_type->vedata_size->stl_len;
499   }
500 }
501
502 /* WARNING: only use for custom pipeline. 99% of the time, you don't want to use this. */
503 void DRW_render_viewport_size_set(int size[2])
504 {
505   DST.size[0] = size[0];
506   DST.size[1] = size[1];
507 }
508
509 const float *DRW_viewport_size_get(void)
510 {
511   return DST.size;
512 }
513
514 const float *DRW_viewport_invert_size_get(void)
515 {
516   return DST.inv_size;
517 }
518
519 const float *DRW_viewport_screenvecs_get(void)
520 {
521   return &DST.screenvecs[0][0];
522 }
523
524 const float *DRW_viewport_pixelsize_get(void)
525 {
526   return &DST.pixsize;
527 }
528
529 static void drw_viewport_cache_resize(void)
530 {
531   /* Release the memiter before clearing the mempools that references them */
532   GPU_viewport_cache_release(DST.viewport);
533
534   if (DST.vmempool != NULL) {
535     /* Release Image textures. */
536     BLI_memblock_iter iter;
537     GPUTexture **tex;
538     BLI_memblock_iternew(DST.vmempool->images, &iter);
539     while ((tex = BLI_memblock_iterstep(&iter))) {
540       GPU_texture_free(*tex);
541     }
542
543     BLI_memblock_clear(DST.vmempool->calls, NULL);
544     BLI_memblock_clear(DST.vmempool->states, NULL);
545     BLI_memblock_clear(DST.vmempool->cullstates, NULL);
546     BLI_memblock_clear(DST.vmempool->shgroups, NULL);
547     BLI_memblock_clear(DST.vmempool->uniforms, NULL);
548     BLI_memblock_clear(DST.vmempool->passes, NULL);
549     BLI_memblock_clear(DST.vmempool->views, NULL);
550     BLI_memblock_clear(DST.vmempool->images, NULL);
551   }
552
553   DRW_instance_data_list_free_unused(DST.idatalist);
554   DRW_instance_data_list_resize(DST.idatalist);
555 }
556
557 /* Not a viewport variable, we could split this out. */
558 static void drw_context_state_init(void)
559 {
560   if (DST.draw_ctx.obact) {
561     DST.draw_ctx.object_mode = DST.draw_ctx.obact->mode;
562   }
563   else {
564     DST.draw_ctx.object_mode = OB_MODE_OBJECT;
565   }
566
567   /* Edit object. */
568   if (DST.draw_ctx.object_mode & OB_MODE_EDIT) {
569     DST.draw_ctx.object_edit = DST.draw_ctx.obact;
570   }
571   else {
572     DST.draw_ctx.object_edit = NULL;
573   }
574
575   /* Pose object. */
576   if (DST.draw_ctx.object_mode & OB_MODE_POSE) {
577     DST.draw_ctx.object_pose = DST.draw_ctx.obact;
578   }
579   else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) {
580     DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact);
581   }
582   else {
583     DST.draw_ctx.object_pose = NULL;
584   }
585
586   DST.draw_ctx.sh_cfg = GPU_SHADER_CFG_DEFAULT;
587   if (DST.draw_ctx.rv3d && DST.draw_ctx.rv3d->rflag & RV3D_CLIPPING) {
588     DST.draw_ctx.sh_cfg = GPU_SHADER_CFG_CLIPPED;
589   }
590 }
591
592 static DRWCallState *draw_unit_state_create(void)
593 {
594   DRWCallState *state = BLI_memblock_alloc(DST.vmempool->states);
595   state->flag = 0;
596   state->matflag = 0;
597
598   unit_m4(state->model);
599   unit_m4(state->modelinverse);
600
601   copy_v3_fl(state->orcotexfac[0], 0.0f);
602   copy_v3_fl(state->orcotexfac[1], 1.0f);
603
604   state->ob_index = 0;
605   state->ob_random = 0.0f;
606
607   /* TODO(fclem) get rid of this. */
608   state->culling = BLI_memblock_alloc(DST.vmempool->cullstates);
609   state->culling->bsphere.radius = -1.0f;
610   state->culling->user_data = NULL;
611
612   return state;
613 }
614
615 /* It also stores viewport variable to an immutable place: DST
616  * This is because a cache uniform only store reference
617  * to its value. And we don't want to invalidate the cache
618  * if this value change per viewport */
619 static void drw_viewport_var_init(void)
620 {
621   RegionView3D *rv3d = DST.draw_ctx.rv3d;
622   /* Refresh DST.size */
623   if (DST.viewport) {
624     int size[2];
625     GPU_viewport_size_get(DST.viewport, size);
626     DST.size[0] = size[0];
627     DST.size[1] = size[1];
628     DST.inv_size[0] = 1.0f / size[0];
629     DST.inv_size[1] = 1.0f / size[1];
630
631     DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(
632         DST.viewport);
633     DST.default_framebuffer = fbl->default_fb;
634
635     DST.vmempool = GPU_viewport_mempool_get(DST.viewport);
636
637     if (DST.vmempool->calls == NULL) {
638       DST.vmempool->calls = BLI_memblock_create(sizeof(DRWCall));
639     }
640     if (DST.vmempool->states == NULL) {
641       DST.vmempool->states = BLI_memblock_create(sizeof(DRWCallState));
642     }
643     if (DST.vmempool->cullstates == NULL) {
644       DST.vmempool->cullstates = BLI_memblock_create(sizeof(DRWCullingState));
645     }
646     if (DST.vmempool->shgroups == NULL) {
647       DST.vmempool->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup));
648     }
649     if (DST.vmempool->uniforms == NULL) {
650       DST.vmempool->uniforms = BLI_memblock_create(sizeof(DRWUniform));
651     }
652     if (DST.vmempool->views == NULL) {
653       DST.vmempool->views = BLI_memblock_create(sizeof(DRWView));
654     }
655     if (DST.vmempool->passes == NULL) {
656       DST.vmempool->passes = BLI_memblock_create(sizeof(DRWPass));
657     }
658     if (DST.vmempool->images == NULL) {
659       DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *));
660     }
661
662     /* Alloc default unit state */
663     DST.unit_state = draw_unit_state_create();
664
665     DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
666     DRW_instance_data_list_reset(DST.idatalist);
667   }
668   else {
669     DST.size[0] = 0;
670     DST.size[1] = 0;
671
672     DST.inv_size[0] = 0;
673     DST.inv_size[1] = 0;
674
675     DST.default_framebuffer = NULL;
676     DST.vmempool = NULL;
677
678     DST.unit_state = NULL;
679   }
680
681   DST.primary_view_ct = 0;
682
683   if (rv3d != NULL) {
684     normalize_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
685     normalize_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
686
687     DST.pixsize = rv3d->pixsize;
688     DST.view_default = DRW_view_create(rv3d->viewmat, rv3d->winmat, NULL, NULL, NULL);
689     DRW_view_camtexco_set(DST.view_default, rv3d->viewcamtexcofac);
690
691     if (DST.draw_ctx.sh_cfg == GPU_SHADER_CFG_CLIPPED) {
692       int plane_len = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
693       DRW_view_clip_planes_set(DST.view_default, rv3d->clip, plane_len);
694     }
695
696     DST.view_active = DST.view_default;
697     DST.view_previous = NULL;
698   }
699   else {
700     zero_v3(DST.screenvecs[0]);
701     zero_v3(DST.screenvecs[1]);
702
703     DST.pixsize = 1.0f;
704     DST.view_default = NULL;
705     DST.view_active = NULL;
706     DST.view_previous = NULL;
707   }
708
709   /* fclem: Is this still needed ? */
710   if (DST.draw_ctx.object_edit) {
711     ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
712   }
713
714   /* Alloc array of texture reference. */
715   memset(&DST.RST, 0x0, sizeof(DST.RST));
716
717   if (G_draw.view_ubo == NULL) {
718     G_draw.view_ubo = DRW_uniformbuffer_create(sizeof(DRWViewUboStorage), NULL);
719   }
720
721   memset(DST.object_instance_data, 0x0, sizeof(DST.object_instance_data));
722 }
723
724 DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void)
725 {
726   return GPU_viewport_framebuffer_list_get(DST.viewport);
727 }
728
729 DefaultTextureList *DRW_viewport_texture_list_get(void)
730 {
731   return GPU_viewport_texture_list_get(DST.viewport);
732 }
733
734 void DRW_viewport_request_redraw(void)
735 {
736   GPU_viewport_tag_update(DST.viewport);
737 }
738
739 /** \} */
740
741 /* -------------------------------------------------------------------- */
742 /** \name Duplis
743  * \{ */
744
745 static void drw_duplidata_load(DupliObject *dupli)
746 {
747   if (dupli == NULL) {
748     return;
749   }
750
751   if (DST.dupli_origin != dupli->ob) {
752     DST.dupli_origin = dupli->ob;
753   }
754   else {
755     /* Same data as previous iter. No need to poll ghash for this. */
756     return;
757   }
758
759   if (DST.dupli_ghash == NULL) {
760     DST.dupli_ghash = BLI_ghash_ptr_new(__func__);
761   }
762
763   void **value;
764   if (!BLI_ghash_ensure_p(DST.dupli_ghash, DST.dupli_origin, &value)) {
765     *value = MEM_callocN(sizeof(void *) * DST.enabled_engine_count, __func__);
766
767     /* TODO: Meh a bit out of place but this is nice as it is
768      * only done once per "original" object. */
769     drw_batch_cache_validate(DST.dupli_origin);
770   }
771   DST.dupli_datas = *(void ***)value;
772 }
773
774 static void duplidata_value_free(void *val)
775 {
776   void **dupli_datas = val;
777   for (int i = 0; i < DST.enabled_engine_count; i++) {
778     MEM_SAFE_FREE(dupli_datas[i]);
779   }
780   MEM_freeN(val);
781 }
782
783 static void drw_duplidata_free(void)
784 {
785   if (DST.dupli_ghash != NULL) {
786     BLI_ghash_free(DST.dupli_ghash,
787                    (void (*)(void *key))drw_batch_cache_generate_requested,
788                    duplidata_value_free);
789     DST.dupli_ghash = NULL;
790   }
791 }
792
793 /* Return NULL if not a dupli or a pointer of pointer to the engine data */
794 void **DRW_duplidata_get(void *vedata)
795 {
796   if (DST.dupli_source == NULL) {
797     return NULL;
798   }
799   /* XXX Search engine index by using vedata array */
800   for (int i = 0; i < DST.enabled_engine_count; i++) {
801     if (DST.vedata_array[i] == vedata) {
802       return &DST.dupli_datas[i];
803     }
804   }
805   return NULL;
806 }
807
808 /** \} */
809
810 /* -------------------------------------------------------------------- */
811 /** \name ViewLayers (DRW_scenelayer)
812  * \{ */
813
814 void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type)
815 {
816   for (ViewLayerEngineData *sled = DST.draw_ctx.view_layer->drawdata.first; sled;
817        sled = sled->next) {
818     if (sled->engine_type == engine_type) {
819       return sled->storage;
820     }
821   }
822   return NULL;
823 }
824
825 void **DRW_view_layer_engine_data_ensure_ex(ViewLayer *view_layer,
826                                             DrawEngineType *engine_type,
827                                             void (*callback)(void *storage))
828 {
829   ViewLayerEngineData *sled;
830
831   for (sled = view_layer->drawdata.first; sled; sled = sled->next) {
832     if (sled->engine_type == engine_type) {
833       return &sled->storage;
834     }
835   }
836
837   sled = MEM_callocN(sizeof(ViewLayerEngineData), "ViewLayerEngineData");
838   sled->engine_type = engine_type;
839   sled->free = callback;
840   BLI_addtail(&view_layer->drawdata, sled);
841
842   return &sled->storage;
843 }
844
845 void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type,
846                                          void (*callback)(void *storage))
847 {
848   return DRW_view_layer_engine_data_ensure_ex(DST.draw_ctx.view_layer, engine_type, callback);
849 }
850
851 /** \} */
852
853 /* -------------------------------------------------------------------- */
854 /** \name Draw Data (DRW_drawdata)
855  * \{ */
856
857 /* Used for DRW_drawdata_from_id()
858  * All ID-data-blocks which have their own 'local' DrawData
859  * should have the same arrangement in their structs.
860  */
861 typedef struct IdDdtTemplate {
862   ID id;
863   struct AnimData *adt;
864   DrawDataList drawdata;
865 } IdDdtTemplate;
866
867 /* Check if ID can have AnimData */
868 static bool id_type_can_have_drawdata(const short id_type)
869 {
870   /* Only some ID-blocks have this info for now */
871   /* TODO: finish adding this for the other blocktypes */
872   switch (id_type) {
873     /* has DrawData */
874     case ID_OB:
875     case ID_WO:
876       return true;
877
878     /* no DrawData */
879     default:
880       return false;
881   }
882 }
883
884 static bool id_can_have_drawdata(const ID *id)
885 {
886   /* sanity check */
887   if (id == NULL) {
888     return false;
889   }
890
891   return id_type_can_have_drawdata(GS(id->name));
892 }
893
894 /* Get DrawData from the given ID-block. In order for this to work, we assume that
895  * the DrawData pointer is stored in the struct in the same fashion as in IdDdtTemplate.
896  */
897 DrawDataList *DRW_drawdatalist_from_id(ID *id)
898 {
899   /* only some ID-blocks have this info for now, so we cast the
900    * types that do to be of type IdDdtTemplate, and extract the
901    * DrawData that way
902    */
903   if (id_can_have_drawdata(id)) {
904     IdDdtTemplate *idt = (IdDdtTemplate *)id;
905     return &idt->drawdata;
906   }
907   else {
908     return NULL;
909   }
910 }
911
912 DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type)
913 {
914   DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
915
916   if (drawdata == NULL) {
917     return NULL;
918   }
919
920   LISTBASE_FOREACH (DrawData *, dd, drawdata) {
921     if (dd->engine_type == engine_type) {
922       return dd;
923     }
924   }
925   return NULL;
926 }
927
928 DrawData *DRW_drawdata_ensure(ID *id,
929                               DrawEngineType *engine_type,
930                               size_t size,
931                               DrawDataInitCb init_cb,
932                               DrawDataFreeCb free_cb)
933 {
934   BLI_assert(size >= sizeof(DrawData));
935   BLI_assert(id_can_have_drawdata(id));
936   /* Try to re-use existing data. */
937   DrawData *dd = DRW_drawdata_get(id, engine_type);
938   if (dd != NULL) {
939     return dd;
940   }
941
942   DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
943
944   /* Allocate new data. */
945   if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROM_DUPLI) != 0) {
946     /* NOTE: data is not persistent in this case. It is reset each redraw. */
947     BLI_assert(free_cb == NULL); /* No callback allowed. */
948     /* Round to sizeof(float) for DRW_instance_data_request(). */
949     const size_t t = sizeof(float) - 1;
950     size = (size + t) & ~t;
951     size_t fsize = size / sizeof(float);
952     BLI_assert(fsize < MAX_INSTANCE_DATA_SIZE);
953     if (DST.object_instance_data[fsize] == NULL) {
954       DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize);
955     }
956     dd = (DrawData *)DRW_instance_data_next(DST.object_instance_data[fsize]);
957     memset(dd, 0, size);
958   }
959   else {
960     dd = MEM_callocN(size, "DrawData");
961   }
962   dd->engine_type = engine_type;
963   dd->free = free_cb;
964   /* Perform user-side initialization, if needed. */
965   if (init_cb != NULL) {
966     init_cb(dd);
967   }
968   /* Register in the list. */
969   BLI_addtail((ListBase *)drawdata, dd);
970   return dd;
971 }
972
973 void DRW_drawdata_free(ID *id)
974 {
975   DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
976
977   if (drawdata == NULL) {
978     return;
979   }
980
981   LISTBASE_FOREACH (DrawData *, dd, drawdata) {
982     if (dd->free != NULL) {
983       dd->free(dd);
984     }
985   }
986
987   BLI_freelistN((ListBase *)drawdata);
988 }
989
990 /* Unlink (but don't free) the drawdata from the DrawDataList if the ID is an OB from dupli. */
991 static void drw_drawdata_unlink_dupli(ID *id)
992 {
993   if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROM_DUPLI) != 0) {
994     DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
995
996     if (drawdata == NULL) {
997       return;
998     }
999
1000     BLI_listbase_clear((ListBase *)drawdata);
1001   }
1002 }
1003
1004 /** \} */
1005
1006 /* -------------------------------------------------------------------- */
1007 /** \name Garbage Collection
1008  * \{ */
1009
1010 void DRW_cache_free_old_batches(Main *bmain)
1011 {
1012   Scene *scene;
1013   ViewLayer *view_layer;
1014   static int lasttime = 0;
1015   int ctime = (int)PIL_check_seconds_timer();
1016
1017   if (U.vbotimeout == 0 || (ctime - lasttime) < U.vbocollectrate || ctime == lasttime) {
1018     return;
1019   }
1020
1021   lasttime = ctime;
1022
1023   for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
1024     for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
1025       Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
1026       if (depsgraph == NULL) {
1027         continue;
1028       }
1029
1030       /* TODO(fclem): This is not optimal since it iter over all dupli instances.
1031        * In this case only the source object should be tagged. */
1032       DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
1033         DRW_batch_cache_free_old(ob, ctime);
1034       }
1035       DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
1036     }
1037   }
1038 }
1039
1040 /** \} */
1041
1042 /* -------------------------------------------------------------------- */
1043 /** \name Rendering (DRW_engines)
1044  * \{ */
1045
1046 static void drw_engines_init(void)
1047 {
1048   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1049     DrawEngineType *engine = link->data;
1050     ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1051     PROFILE_START(stime);
1052
1053     if (engine->engine_init) {
1054       engine->engine_init(data);
1055     }
1056
1057     PROFILE_END_UPDATE(data->init_time, stime);
1058   }
1059 }
1060
1061 static void drw_engines_cache_init(void)
1062 {
1063   DST.enabled_engine_count = BLI_listbase_count(&DST.enabled_engines);
1064   DST.vedata_array = MEM_mallocN(sizeof(void *) * DST.enabled_engine_count, __func__);
1065
1066   int i = 0;
1067   for (LinkData *link = DST.enabled_engines.first; link; link = link->next, i++) {
1068     DrawEngineType *engine = link->data;
1069     ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1070     DST.vedata_array[i] = data;
1071
1072     if (data->text_draw_cache) {
1073       DRW_text_cache_destroy(data->text_draw_cache);
1074       data->text_draw_cache = NULL;
1075     }
1076     if (DST.text_store_p == NULL) {
1077       DST.text_store_p = &data->text_draw_cache;
1078     }
1079
1080     if (engine->cache_init) {
1081       engine->cache_init(data);
1082     }
1083   }
1084 }
1085
1086 static void drw_engines_world_update(Scene *scene)
1087 {
1088   if (scene->world == NULL) {
1089     return;
1090   }
1091
1092   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1093     DrawEngineType *engine = link->data;
1094     ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1095
1096     if (engine->id_update) {
1097       engine->id_update(data, &scene->world->id);
1098     }
1099   }
1100 }
1101
1102 static void drw_engines_cache_populate(Object *ob)
1103 {
1104   DST.ob_state = NULL;
1105
1106   /* HACK: DrawData is copied by COW from the duplicated object.
1107    * This is valid for IDs that cannot be instantiated but this
1108    * is not what we want in this case so we clear the pointer
1109    * ourselves here. */
1110   drw_drawdata_unlink_dupli((ID *)ob);
1111
1112   /* Validation for dupli objects happen elsewhere. */
1113   if (!DST.dupli_source) {
1114     drw_batch_cache_validate(ob);
1115   }
1116
1117   int i = 0;
1118   for (LinkData *link = DST.enabled_engines.first; link; link = link->next, i++) {
1119     DrawEngineType *engine = link->data;
1120     ViewportEngineData *data = DST.vedata_array[i];
1121
1122     if (engine->id_update) {
1123       engine->id_update(data, &ob->id);
1124     }
1125
1126     if (engine->cache_populate) {
1127       engine->cache_populate(data, ob);
1128     }
1129   }
1130
1131   /* TODO: in the future it would be nice to generate once for all viewports.
1132    * But we need threaded DRW manager first. */
1133   if (!DST.dupli_source) {
1134     drw_batch_cache_generate_requested(ob);
1135   }
1136
1137   /* ... and clearing it here too because this draw data is
1138    * from a mempool and must not be free individually by depsgraph. */
1139   drw_drawdata_unlink_dupli((ID *)ob);
1140 }
1141
1142 static void drw_engines_cache_finish(void)
1143 {
1144   int i = 0;
1145   for (LinkData *link = DST.enabled_engines.first; link; link = link->next, i++) {
1146     DrawEngineType *engine = link->data;
1147     ViewportEngineData *data = DST.vedata_array[i];
1148
1149     if (engine->cache_finish) {
1150       engine->cache_finish(data);
1151     }
1152   }
1153   MEM_freeN(DST.vedata_array);
1154 }
1155
1156 static void drw_engines_draw_background(void)
1157 {
1158   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1159     DrawEngineType *engine = link->data;
1160     ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1161
1162     if (engine->draw_background) {
1163       PROFILE_START(stime);
1164
1165       DRW_stats_group_start(engine->idname);
1166       engine->draw_background(data);
1167       DRW_stats_group_end();
1168
1169       PROFILE_END_UPDATE(data->background_time, stime);
1170       return;
1171     }
1172   }
1173
1174   /* No draw_background found, doing default background */
1175   const bool do_alpha_checker = !DRW_state_draw_background();
1176   DRW_draw_background(do_alpha_checker);
1177 }
1178
1179 static void drw_engines_draw_scene(void)
1180 {
1181   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1182     DrawEngineType *engine = link->data;
1183     ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1184     PROFILE_START(stime);
1185
1186     if (engine->draw_scene) {
1187       DRW_stats_group_start(engine->idname);
1188       engine->draw_scene(data);
1189       /* Restore for next engine */
1190       if (DRW_state_is_fbo()) {
1191         GPU_framebuffer_bind(DST.default_framebuffer);
1192       }
1193       DRW_stats_group_end();
1194     }
1195
1196     PROFILE_END_UPDATE(data->render_time, stime);
1197   }
1198   /* Reset state after drawing */
1199   DRW_state_reset();
1200 }
1201
1202 static void drw_engines_draw_text(void)
1203 {
1204   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1205     DrawEngineType *engine = link->data;
1206     ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1207     PROFILE_START(stime);
1208
1209     if (data->text_draw_cache) {
1210       DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.ar);
1211     }
1212
1213     PROFILE_END_UPDATE(data->render_time, stime);
1214   }
1215 }
1216
1217 /* Draw render engine info. */
1218 void DRW_draw_region_engine_info(int xoffset, int yoffset)
1219 {
1220   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1221     DrawEngineType *engine = link->data;
1222     ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
1223
1224     if (data->info[0] != '\0') {
1225       char *chr_current = data->info;
1226       char *chr_start = chr_current;
1227       int line_len = 0;
1228
1229       const int font_id = BLF_default();
1230       UI_FontThemeColor(font_id, TH_TEXT_HI);
1231
1232       BLF_enable(font_id, BLF_SHADOW);
1233       BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f});
1234       BLF_shadow_offset(font_id, 1, -1);
1235
1236       while (*chr_current++ != '\0') {
1237         line_len++;
1238         if (*chr_current == '\n') {
1239           char info[GPU_INFO_SIZE];
1240           BLI_strncpy(info, chr_start, line_len + 1);
1241           yoffset -= U.widget_unit;
1242           BLF_draw_default(xoffset, yoffset, 0.0f, info, sizeof(info));
1243
1244           /* Re-start counting. */
1245           chr_start = chr_current + 1;
1246           line_len = -1;
1247         }
1248       }
1249
1250       char info[GPU_INFO_SIZE];
1251       BLI_strncpy(info, chr_start, line_len + 1);
1252       yoffset -= U.widget_unit;
1253       BLF_draw_default(xoffset, yoffset, 0.0f, info, sizeof(info));
1254
1255       BLF_disable(font_id, BLF_SHADOW);
1256     }
1257   }
1258 }
1259
1260 static void use_drw_engine(DrawEngineType *engine)
1261 {
1262   LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
1263   ld->data = engine;
1264   BLI_addtail(&DST.enabled_engines, ld);
1265 }
1266
1267 /**
1268  * Use for external render engines.
1269  */
1270 static void drw_engines_enable_external(void)
1271 {
1272   use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
1273 }
1274
1275 /* TODO revisit this when proper layering is implemented */
1276 /* Gather all draw engines needed and store them in DST.enabled_engines
1277  * That also define the rendering order of engines */
1278 static void drw_engines_enable_from_engine(RenderEngineType *engine_type,
1279                                            int drawtype,
1280                                            bool use_xray)
1281 {
1282   switch (drawtype) {
1283     case OB_WIRE:
1284       use_drw_engine(&draw_engine_workbench_transparent);
1285       break;
1286
1287     case OB_SOLID:
1288       if (use_xray) {
1289         use_drw_engine(&draw_engine_workbench_transparent);
1290       }
1291       else {
1292         use_drw_engine(&draw_engine_workbench_solid);
1293       }
1294       break;
1295
1296     case OB_MATERIAL:
1297     case OB_RENDER:
1298     default:
1299       /* TODO layers */
1300       if (engine_type->draw_engine != NULL) {
1301         use_drw_engine(engine_type->draw_engine);
1302       }
1303
1304       if ((engine_type->flag & RE_INTERNAL) == 0) {
1305         drw_engines_enable_external();
1306       }
1307       break;
1308   }
1309 }
1310
1311 static void drw_engines_enable_from_object_mode(void)
1312 {
1313   use_drw_engine(&draw_engine_object_type);
1314   /* TODO(fclem) remove this, it does not belong to it's own engine. */
1315   use_drw_engine(&draw_engine_motion_path_type);
1316 }
1317
1318 static void drw_engines_enable_from_paint_mode(int mode)
1319 {
1320   switch (mode) {
1321     case CTX_MODE_SCULPT:
1322       use_drw_engine(&draw_engine_sculpt_type);
1323       break;
1324     case CTX_MODE_PAINT_WEIGHT:
1325     case CTX_MODE_PAINT_VERTEX:
1326       use_drw_engine(&draw_engine_paint_vertex_type);
1327       break;
1328     case CTX_MODE_PAINT_TEXTURE:
1329       use_drw_engine(&draw_engine_paint_texture_type);
1330       break;
1331     default:
1332       break;
1333   }
1334 }
1335
1336 static void drw_engines_enable_from_mode(int mode)
1337 {
1338   switch (mode) {
1339     case CTX_MODE_EDIT_MESH:
1340       use_drw_engine(&draw_engine_edit_mesh_type);
1341       break;
1342     case CTX_MODE_EDIT_SURFACE:
1343     case CTX_MODE_EDIT_CURVE:
1344       use_drw_engine(&draw_engine_edit_curve_type);
1345       break;
1346     case CTX_MODE_EDIT_TEXT:
1347       use_drw_engine(&draw_engine_edit_text_type);
1348       break;
1349     case CTX_MODE_EDIT_ARMATURE:
1350       use_drw_engine(&draw_engine_edit_armature_type);
1351       break;
1352     case CTX_MODE_EDIT_METABALL:
1353       use_drw_engine(&draw_engine_edit_metaball_type);
1354       break;
1355     case CTX_MODE_EDIT_LATTICE:
1356       use_drw_engine(&draw_engine_edit_lattice_type);
1357       break;
1358     case CTX_MODE_PARTICLE:
1359       use_drw_engine(&draw_engine_particle_type);
1360       break;
1361     case CTX_MODE_POSE:
1362     case CTX_MODE_PAINT_WEIGHT:
1363       /* The pose engine clears the depth of the default framebuffer
1364        * to draw an object with `OB_DRAWXRAY`.
1365        * (different of workbench that has its own framebuffer).
1366        * So make sure you call its `draw_scene` after all the other engines. */
1367       use_drw_engine(&draw_engine_pose_type);
1368       break;
1369     case CTX_MODE_SCULPT:
1370     case CTX_MODE_PAINT_VERTEX:
1371     case CTX_MODE_PAINT_TEXTURE:
1372     case CTX_MODE_OBJECT:
1373     case CTX_MODE_PAINT_GPENCIL:
1374     case CTX_MODE_EDIT_GPENCIL:
1375     case CTX_MODE_SCULPT_GPENCIL:
1376     case CTX_MODE_WEIGHT_GPENCIL:
1377       break;
1378     default:
1379       BLI_assert(!"Draw mode invalid");
1380       break;
1381   }
1382 }
1383
1384 static void drw_engines_enable_from_overlays(int UNUSED(overlay_flag))
1385 {
1386   use_drw_engine(&draw_engine_overlay_type);
1387 }
1388 /**
1389  * Use for select and depth-drawing.
1390  */
1391 static void drw_engines_enable_basic(void)
1392 {
1393   use_drw_engine(DRW_engine_viewport_basic_type.draw_engine);
1394 }
1395
1396 static void drw_engines_enable(ViewLayer *view_layer,
1397                                RenderEngineType *engine_type,
1398                                bool gpencil_engine_needed)
1399 {
1400   Object *obact = OBACT(view_layer);
1401   const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
1402       DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode);
1403   View3D *v3d = DST.draw_ctx.v3d;
1404   const int drawtype = v3d->shading.type;
1405   const bool use_xray = XRAY_ENABLED(v3d);
1406
1407   drw_engines_enable_from_engine(engine_type, drawtype, use_xray);
1408   /* grease pencil */
1409   if (gpencil_engine_needed) {
1410     use_drw_engine(&draw_engine_gpencil_type);
1411   }
1412
1413   if (DRW_state_draw_support()) {
1414     /* Draw paint modes first so that they are drawn below the wireframes. */
1415     drw_engines_enable_from_paint_mode(mode);
1416     drw_engines_enable_from_overlays(v3d->overlay.flag);
1417     drw_engines_enable_from_object_mode();
1418     drw_engines_enable_from_mode(mode);
1419   }
1420   else {
1421     /* Force enable overlays engine for wireframe mode */
1422     if (v3d->shading.type == OB_WIRE) {
1423       drw_engines_enable_from_overlays(v3d->overlay.flag);
1424     }
1425   }
1426 }
1427
1428 static void drw_engines_disable(void)
1429 {
1430   BLI_freelistN(&DST.enabled_engines);
1431 }
1432
1433 static void drw_engines_data_validate(void)
1434 {
1435   int enabled_engines = BLI_listbase_count(&DST.enabled_engines);
1436   void **engine_handle_array = BLI_array_alloca(engine_handle_array, enabled_engines + 1);
1437   int i = 0;
1438
1439   for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1440     DrawEngineType *engine = link->data;
1441     engine_handle_array[i++] = engine;
1442   }
1443   engine_handle_array[i] = NULL;
1444
1445   GPU_viewport_engines_data_validate(DST.viewport, engine_handle_array);
1446 }
1447
1448 /* Fast check to see if gpencil drawing engine is needed.
1449  * For slow exact check use `DRW_render_check_grease_pencil` */
1450 static bool drw_gpencil_engine_needed(Depsgraph *depsgraph, View3D *v3d)
1451 {
1452   const bool exclude_gpencil_rendering = v3d ? (v3d->object_type_exclude_viewport &
1453                                                 (1 << OB_GPENCIL)) != 0 :
1454                                                false;
1455   return (!exclude_gpencil_rendering) || DEG_id_type_any_exists(depsgraph, ID_GD);
1456 }
1457
1458 /* -------------------------------------------------------------------- */
1459 /** \name View Update
1460  * \{ */
1461
1462 void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
1463 {
1464   RenderEngineType *engine_type = update_ctx->engine_type;
1465   ARegion *ar = update_ctx->ar;
1466   View3D *v3d = update_ctx->v3d;
1467   RegionView3D *rv3d = ar->regiondata;
1468   Depsgraph *depsgraph = update_ctx->depsgraph;
1469   Scene *scene = update_ctx->scene;
1470   ViewLayer *view_layer = update_ctx->view_layer;
1471
1472   const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d);
1473
1474   /* Separate update for each stereo view. */
1475   for (int view = 0; view < 2; view++) {
1476     GPUViewport *viewport = WM_draw_region_get_viewport(ar, view);
1477     if (!viewport) {
1478       continue;
1479     }
1480
1481     /* XXX Really nasty locking. But else this could
1482      * be executed by the material previews thread
1483      * while rendering a viewport. */
1484     BLI_ticket_mutex_lock(DST.gl_context_mutex);
1485
1486     /* Reset before using it. */
1487     drw_state_prepare_clean_for_draw(&DST);
1488
1489     DST.viewport = viewport;
1490     DST.draw_ctx = (DRWContextState){
1491         .ar = ar,
1492         .rv3d = rv3d,
1493         .v3d = v3d,
1494         .scene = scene,
1495         .view_layer = view_layer,
1496         .obact = OBACT(view_layer),
1497         .engine_type = engine_type,
1498         .depsgraph = depsgraph,
1499         .object_mode = OB_MODE_OBJECT,
1500     };
1501
1502     drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
1503     drw_engines_data_validate();
1504
1505     for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1506       DrawEngineType *draw_engine = link->data;
1507       ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
1508
1509       if (draw_engine->view_update) {
1510         draw_engine->view_update(data);
1511       }
1512     }
1513
1514     DST.viewport = NULL;
1515
1516     drw_engines_disable();
1517
1518     BLI_ticket_mutex_unlock(DST.gl_context_mutex);
1519   }
1520 }
1521
1522 /** \} */
1523
1524 /* -------------------------------------------------------------------- */
1525 /** \name Main Draw Loops (DRW_draw)
1526  * \{ */
1527
1528 /* Everything starts here.
1529  * This function takes care of calling all cache and rendering functions
1530  * for each relevant engine / mode engine. */
1531 void DRW_draw_view(const bContext *C)
1532 {
1533   Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
1534   ARegion *ar = CTX_wm_region(C);
1535   View3D *v3d = CTX_wm_view3d(C);
1536   Scene *scene = DEG_get_evaluated_scene(depsgraph);
1537   RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
1538   GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar);
1539
1540   /* Reset before using it. */
1541   drw_state_prepare_clean_for_draw(&DST);
1542   DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
1543                            (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
1544   DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) ||
1545                                 (v3d->shading.type != OB_RENDER);
1546   DST.options.do_color_management = true;
1547   DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C);
1548 }
1549
1550 /**
1551  * Used for both regular and off-screen drawing.
1552  * Need to reset DST before calling this function
1553  */
1554 void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
1555                              RenderEngineType *engine_type,
1556                              ARegion *ar,
1557                              View3D *v3d,
1558                              GPUViewport *viewport,
1559                              const bContext *evil_C)
1560 {
1561
1562   Scene *scene = DEG_get_evaluated_scene(depsgraph);
1563   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1564   RegionView3D *rv3d = ar->regiondata;
1565   const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
1566                                ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
1567
1568   DST.draw_ctx.evil_C = evil_C;
1569   DST.viewport = viewport;
1570
1571   /* Setup viewport */
1572   DST.draw_ctx = (DRWContextState){
1573       .ar = ar,
1574       .rv3d = rv3d,
1575       .v3d = v3d,
1576       .scene = scene,
1577       .view_layer = view_layer,
1578       .obact = OBACT(view_layer),
1579       .engine_type = engine_type,
1580       .depsgraph = depsgraph,
1581
1582       /* reuse if caller sets */
1583       .evil_C = DST.draw_ctx.evil_C,
1584   };
1585   drw_context_state_init();
1586   drw_viewport_var_init();
1587
1588   const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
1589   /* Check if scene needs to perform the populate loop */
1590   const bool internal_engine = (engine_type->flag & RE_INTERNAL) != 0;
1591   const bool draw_type_render = v3d->shading.type == OB_RENDER;
1592   const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0;
1593   const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d);
1594   const bool do_populate_loop = internal_engine || overlays_on || !draw_type_render ||
1595                                 gpencil_engine_needed;
1596
1597   /* Get list of enabled engines */
1598   drw_engines_enable(view_layer, engine_type, gpencil_engine_needed);
1599   drw_engines_data_validate();
1600
1601   /* Update ubos */
1602   DRW_globals_update();
1603
1604   drw_debug_init();
1605   DRW_hair_init();
1606
1607   /* No framebuffer allowed before drawing. */
1608   BLI_assert(GPU_framebuffer_active_get() == NULL);
1609
1610   /* Init engines */
1611   drw_engines_init();
1612
1613   /* Cache filling */
1614   {
1615     PROFILE_START(stime);
1616     drw_engines_cache_init();
1617     drw_engines_world_update(scene);
1618
1619     /* Only iterate over objects for internal engines or when overlays are enabled */
1620     if (do_populate_loop) {
1621       DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
1622         if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
1623           continue;
1624         }
1625         if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
1626           continue;
1627         }
1628         DST.dupli_parent = data_.dupli_parent;
1629         DST.dupli_source = data_.dupli_object_current;
1630         drw_duplidata_load(DST.dupli_source);
1631         drw_engines_cache_populate(ob);
1632       }
1633       DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
1634     }
1635
1636     drw_duplidata_free();
1637     drw_engines_cache_finish();
1638
1639     DRW_render_instance_buffer_finish();
1640
1641 #ifdef USE_PROFILE
1642     double *cache_time = GPU_viewport_cache_time_get(DST.viewport);
1643     PROFILE_END_UPDATE(*cache_time, stime);
1644 #endif
1645   }
1646
1647   DRW_stats_begin();
1648
1649   GPU_framebuffer_bind(DST.default_framebuffer);
1650
1651   /* Start Drawing */
1652   DRW_state_reset();
1653
1654   DRW_hair_update();
1655
1656   drw_engines_draw_background();
1657
1658   GPU_framebuffer_bind(DST.default_framebuffer);
1659
1660   DRW_draw_callbacks_pre_scene();
1661   if (DST.draw_ctx.evil_C) {
1662     ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
1663   }
1664
1665   drw_engines_draw_scene();
1666
1667   /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
1668   GPU_flush();
1669
1670   /* annotations - temporary drawing buffer (3d space) */
1671   /* XXX: Or should we use a proper draw/overlay engine for this case? */
1672   if (do_annotations) {
1673     GPU_depth_test(false);
1674     /* XXX: as scene->gpd is not copied for COW yet */
1675     ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true);
1676     GPU_depth_test(true);
1677   }
1678
1679   DRW_draw_callbacks_post_scene();
1680   DRW_state_reset();
1681
1682   if (DST.draw_ctx.evil_C) {
1683     GPU_depth_test(false);
1684     ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
1685     GPU_depth_test(true);
1686     /* Callback can be nasty and do whatever they want with the state.
1687      * Don't trust them! */
1688     DRW_state_reset();
1689   }
1690
1691   drw_debug_draw();
1692
1693   GPU_depth_test(false);
1694   drw_engines_draw_text();
1695   GPU_depth_test(true);
1696
1697   if (DST.draw_ctx.evil_C) {
1698     /* needed so gizmo isn't obscured */
1699     if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
1700       glDisable(GL_DEPTH_TEST);
1701       DRW_draw_gizmo_3d();
1702     }
1703
1704     DRW_draw_region_info();
1705
1706     /* annotations - temporary drawing buffer (screenspace) */
1707     /* XXX: Or should we use a proper draw/overlay engine for this case? */
1708     if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) && (do_annotations)) {
1709       GPU_depth_test(false);
1710       /* XXX: as scene->gpd is not copied for COW yet */
1711       ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false);
1712       GPU_depth_test(true);
1713     }
1714
1715     if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) {
1716       /* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
1717        * 'DRW_draw_region_info' sets the projection in pixel-space. */
1718       GPU_depth_test(false);
1719       DRW_draw_gizmo_2d();
1720       GPU_depth_test(true);
1721     }
1722   }
1723
1724   DRW_stats_reset();
1725
1726   if (G.debug_value > 20 && G.debug_value < 30) {
1727     GPU_depth_test(false);
1728     /* local coordinate visible rect inside region, to accommodate overlapping ui */
1729     const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar);
1730     DRW_stats_draw(rect);
1731     GPU_depth_test(true);
1732   }
1733
1734   if (WM_draw_region_get_bound_viewport(ar)) {
1735     /* Don't unbind the framebuffer yet in this case and let
1736      * GPU_viewport_unbind do it, so that we can still do further
1737      * drawing of action zones on top. */
1738   }
1739   else {
1740     GPU_framebuffer_restore();
1741   }
1742
1743   DRW_state_reset();
1744   drw_engines_disable();
1745
1746   drw_viewport_cache_resize();
1747
1748 #ifdef DEBUG
1749   /* Avoid accidental reuse. */
1750   drw_state_ensure_not_reused(&DST);
1751 #endif
1752 }
1753
1754 void DRW_draw_render_loop(struct Depsgraph *depsgraph,
1755                           ARegion *ar,
1756                           View3D *v3d,
1757                           GPUViewport *viewport)
1758 {
1759   /* Reset before using it. */
1760   drw_state_prepare_clean_for_draw(&DST);
1761
1762   Scene *scene = DEG_get_evaluated_scene(depsgraph);
1763   RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
1764
1765   DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, NULL);
1766 }
1767
1768 /* @viewport CAN be NULL, in this case we create one. */
1769 void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
1770                                     RenderEngineType *engine_type,
1771                                     ARegion *ar,
1772                                     View3D *v3d,
1773                                     const bool draw_background,
1774                                     const bool do_color_management,
1775                                     GPUOffScreen *ofs,
1776                                     GPUViewport *viewport)
1777 {
1778   /* Create temporary viewport if needed. */
1779   GPUViewport *render_viewport = viewport;
1780   if (viewport == NULL) {
1781     render_viewport = GPU_viewport_create_from_offscreen(ofs);
1782   }
1783
1784   GPU_framebuffer_restore();
1785
1786   /* Reset before using it. */
1787   drw_state_prepare_clean_for_draw(&DST);
1788   DST.options.is_image_render = true;
1789   DST.options.do_color_management = do_color_management;
1790   DST.options.draw_background = draw_background;
1791   DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, render_viewport, NULL);
1792
1793   /* Free temporary viewport. */
1794   if (viewport == NULL) {
1795     /* don't free data owned by 'ofs' */
1796     GPU_viewport_clear_from_offscreen(render_viewport);
1797     GPU_viewport_free(render_viewport);
1798   }
1799
1800   /* we need to re-bind (annoying!) */
1801   GPU_offscreen_bind(ofs, false);
1802 }
1803
1804 /* Helper to check if exit object type to render. */
1805 bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
1806 {
1807   if (!drw_gpencil_engine_needed(depsgraph, NULL)) {
1808     return false;
1809   }
1810
1811   DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
1812     if (ob->type == OB_GPENCIL) {
1813       if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
1814         return true;
1815       }
1816     }
1817   }
1818   DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
1819
1820   return false;
1821 }
1822
1823 static void DRW_render_gpencil_to_image(RenderEngine *engine,
1824                                         struct RenderLayer *render_layer,
1825                                         const rcti *rect)
1826 {
1827   if (draw_engine_gpencil_type.render_to_image) {
1828     ViewportEngineData *gpdata = drw_viewport_engine_data_ensure(&draw_engine_gpencil_type);
1829     draw_engine_gpencil_type.render_to_image(gpdata, engine, render_layer, rect);
1830   }
1831 }
1832
1833 void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph)
1834 {
1835   /* This function is only valid for Cycles & Workbench
1836    * Eevee does all work in the Eevee render directly.
1837    * Maybe it can be done equal for all engines?
1838    */
1839   if (STREQ(engine->type->name, "Eevee")) {
1840     return;
1841   }
1842
1843   /* Early out if there are no grease pencil objects, especially important
1844    * to avoid failing in in background renders without OpenGL context. */
1845   if (!DRW_render_check_grease_pencil(depsgraph)) {
1846     return;
1847   }
1848
1849   Scene *scene = DEG_get_evaluated_scene(depsgraph);
1850   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1851   RenderEngineType *engine_type = engine->type;
1852   RenderData *r = &scene->r;
1853   Render *render = engine->re;
1854   /* Changing Context */
1855   if (G.background && DST.gl_context == NULL) {
1856     WM_init_opengl(G_MAIN);
1857   }
1858
1859   void *re_gl_context = RE_gl_context_get(render);
1860   void *re_gpu_context = NULL;
1861
1862   /* Changing Context */
1863   if (re_gl_context != NULL) {
1864     DRW_opengl_render_context_enable(re_gl_context);
1865     /* We need to query gpu context after a gl context has been bound. */
1866     re_gpu_context = RE_gpu_context_get(render);
1867     DRW_gpu_render_context_enable(re_gpu_context);
1868   }
1869   else {
1870     DRW_opengl_context_enable();
1871   }
1872
1873   /* Reset before using it. */
1874   drw_state_prepare_clean_for_draw(&DST);
1875   DST.options.is_image_render = true;
1876   DST.options.is_scene_render = true;
1877   DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
1878   DST.buffer_finish_called = true;
1879
1880   DST.draw_ctx = (DRWContextState){
1881       .scene = scene,
1882       .view_layer = view_layer,
1883       .engine_type = engine_type,
1884       .depsgraph = depsgraph,
1885       .object_mode = OB_MODE_OBJECT,
1886   };
1887   drw_context_state_init();
1888
1889   DST.viewport = GPU_viewport_create();
1890   const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100};
1891   GPU_viewport_size_set(DST.viewport, size);
1892
1893   drw_viewport_var_init();
1894
1895   /* Main rendering. */
1896   rctf view_rect;
1897   rcti render_rect;
1898   RE_GetViewPlane(render, &view_rect, &render_rect);
1899   if (BLI_rcti_is_empty(&render_rect)) {
1900     BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
1901   }
1902
1903   RenderResult *render_result = RE_engine_get_result(engine);
1904   RenderLayer *render_layer = RE_GetRenderLayer(render_result, view_layer->name);
1905
1906   DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
1907
1908   /* Force cache to reset. */
1909   drw_viewport_cache_resize();
1910   GPU_viewport_free(DST.viewport);
1911   DRW_state_reset();
1912
1913   glDisable(GL_DEPTH_TEST);
1914
1915   /* Restore Drawing area. */
1916   GPU_framebuffer_restore();
1917
1918   /* Changing Context */
1919   /* GPXX Review this context */
1920   DRW_opengl_context_disable();
1921
1922   DST.buffer_finish_called = false;
1923 }
1924
1925 static void drw_view_reset(void)
1926 {
1927   DST.view_default = NULL;
1928   DST.view_active = NULL;
1929   DST.view_previous = NULL;
1930 }
1931
1932 void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
1933 {
1934   Scene *scene = DEG_get_evaluated_scene(depsgraph);
1935   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1936   RenderEngineType *engine_type = engine->type;
1937   DrawEngineType *draw_engine_type = engine_type->draw_engine;
1938   Render *render = engine->re;
1939
1940   if (G.background && DST.gl_context == NULL) {
1941     WM_init_opengl(G_MAIN);
1942   }
1943
1944   void *re_gl_context = RE_gl_context_get(render);
1945   void *re_gpu_context = NULL;
1946
1947   /* Changing Context */
1948   if (re_gl_context != NULL) {
1949     DRW_opengl_render_context_enable(re_gl_context);
1950     /* We need to query gpu context after a gl context has been bound. */
1951     re_gpu_context = RE_gpu_context_get(render);
1952     DRW_gpu_render_context_enable(re_gpu_context);
1953   }
1954   else {
1955     DRW_opengl_context_enable();
1956   }
1957
1958   /* IMPORTANT: We don't support immediate mode in render mode!
1959    * This shall remain in effect until immediate mode supports
1960    * multiple threads. */
1961
1962   /* Reset before using it. */
1963   drw_state_prepare_clean_for_draw(&DST);
1964   DST.options.is_image_render = true;
1965   DST.options.is_scene_render = true;
1966   DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
1967
1968   DST.draw_ctx = (DRWContextState){
1969       .scene = scene,
1970       .view_layer = view_layer,
1971       .engine_type = engine_type,
1972       .depsgraph = depsgraph,
1973       .object_mode = OB_MODE_OBJECT,
1974   };
1975   drw_context_state_init();
1976
1977   DST.viewport = GPU_viewport_create();
1978   const int size[2] = {engine->resolution_x, engine->resolution_y};
1979   GPU_viewport_size_set(DST.viewport, size);
1980
1981   drw_viewport_var_init();
1982
1983   ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
1984
1985   /* set default viewport */
1986   glViewport(0, 0, size[0], size[1]);
1987
1988   /* Main rendering. */
1989   rctf view_rect;
1990   rcti render_rect;
1991   RE_GetViewPlane(render, &view_rect, &render_rect);
1992   if (BLI_rcti_is_empty(&render_rect)) {
1993     BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
1994   }
1995
1996   /* Set the default Blender draw state */
1997   GPU_state_init();
1998   /* Reset state before drawing */
1999   DRW_state_reset();
2000
2001   /* Init render result. */
2002   RenderResult *render_result = RE_engine_begin_result(engine,
2003                                                        0,
2004                                                        0,
2005                                                        (int)size[0],
2006                                                        (int)size[1],
2007                                                        view_layer->name,
2008                                                        /* RR_ALL_VIEWS */ NULL);
2009
2010   RenderLayer *render_layer = render_result->layers.first;
2011   for (RenderView *render_view = render_result->views.first; render_view != NULL;
2012        render_view = render_view->next) {
2013     RE_SetActiveRenderView(render, render_view->name);
2014     drw_view_reset();
2015     engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect);
2016     /* grease pencil: render result is merged in the previous render result. */
2017     if (DRW_render_check_grease_pencil(depsgraph)) {
2018       DRW_state_reset();
2019       drw_view_reset();
2020       DRW_render_gpencil_to_image(engine, render_layer, &render_rect);
2021     }
2022     DST.buffer_finish_called = false;
2023   }
2024
2025   RE_engine_end_result(engine, render_result, false, false, false);
2026
2027   /* Force cache to reset. */
2028   drw_viewport_cache_resize();
2029
2030   GPU_viewport_free(DST.viewport);
2031   GPU_framebuffer_restore();
2032
2033 #ifdef DEBUG
2034   /* Avoid accidental reuse. */
2035   drw_state_ensure_not_reused(&DST);
2036 #endif
2037
2038   /* Reset state after drawing */
2039   DRW_state_reset();
2040
2041   /* Changing Context */
2042   if (re_gl_context != NULL) {
2043     DRW_gpu_render_context_disable(re_gpu_context);
2044     DRW_opengl_render_context_disable(re_gl_context);
2045   }
2046   else {
2047     DRW_opengl_context_disable();
2048   }
2049 }
2050
2051 void DRW_render_object_iter(
2052     void *vedata,
2053     RenderEngine *engine,
2054     struct Depsgraph *depsgraph,
2055     void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
2056 {
2057   const DRWContextState *draw_ctx = DRW_context_state_get();
2058
2059   DRW_hair_init();
2060
2061   const int object_type_exclude_viewport = draw_ctx->v3d ?
2062                                                draw_ctx->v3d->object_type_exclude_viewport :
2063                                                0;
2064   DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
2065     if ((object_type_exclude_viewport & (1 << ob->type)) == 0) {
2066       DST.dupli_parent = data_.dupli_parent;
2067       DST.dupli_source = data_.dupli_object_current;
2068       DST.ob_state = NULL;
2069       drw_duplidata_load(DST.dupli_source);
2070
2071       if (!DST.dupli_source) {
2072         drw_batch_cache_validate(ob);
2073       }
2074       callback(vedata, ob, engine, depsgraph);
2075       if (!DST.dupli_source) {
2076         drw_batch_cache_generate_requested(ob);
2077       }
2078     }
2079   }
2080   DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
2081
2082   drw_duplidata_free();
2083 }
2084
2085 /* Assume a valid gl context is bound (and that the gl_context_mutex has been acquired).
2086  * This function only setup DST and execute the given function.
2087  * Warning: similar to DRW_render_to_image you cannot use default lists (dfbl & dtxl). */
2088 void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
2089                          struct Depsgraph *depsgraph,
2090                          void (*callback)(void *vedata, void *user_data),
2091                          void *user_data)
2092 {
2093   Scene *scene = DEG_get_evaluated_scene(depsgraph);
2094   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
2095
2096   /* Reset before using it. */
2097   drw_state_prepare_clean_for_draw(&DST);
2098   DST.options.is_image_render = true;
2099   DST.options.is_scene_render = true;
2100   DST.options.draw_background = false;
2101
2102   DST.draw_ctx = (DRWContextState){
2103       .scene = scene,
2104       .view_layer = view_layer,
2105       .engine_type = NULL,
2106       .depsgraph = depsgraph,
2107       .object_mode = OB_MODE_OBJECT,
2108   };
2109   drw_context_state_init();
2110
2111   DST.viewport = GPU_viewport_create();
2112   const int size[2] = {1, 1};
2113   GPU_viewport_size_set(DST.viewport, size);
2114
2115   drw_viewport_var_init();
2116
2117   DRW_hair_init();
2118
2119   ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
2120
2121   /* Execute the callback */
2122   callback(data, user_data);
2123   DST.buffer_finish_called = false;
2124
2125   GPU_viewport_free(DST.viewport);
2126   GPU_framebuffer_restore();
2127
2128   /* The use of custom pipeline in other thread using the same
2129    * resources as the main thread (viewport) may lead to data
2130    * races and undefined behavior on certain drivers. Using
2131    * GPU_finish to sync seems to fix the issue. (see T62997) */
2132   GPU_finish();
2133
2134 #ifdef DEBUG
2135   /* Avoid accidental reuse. */
2136   drw_state_ensure_not_reused(&DST);
2137 #endif
2138 }
2139
2140 static struct DRWSelectBuffer {
2141   struct GPUFrameBuffer *framebuffer_depth_only;
2142   struct GPUTexture *texture_depth;
2143 } g_select_buffer = {NULL};
2144
2145 static void draw_select_framebuffer_depth_only_setup(const int size[2])
2146 {
2147   if (g_select_buffer.framebuffer_depth_only == NULL) {
2148     g_select_buffer.framebuffer_depth_only = GPU_framebuffer_create();
2149   }
2150
2151   if ((g_select_buffer.texture_depth != NULL) &&
2152       ((GPU_texture_width(g_select_buffer.texture_depth) != size[0]) ||
2153        (GPU_texture_height(g_select_buffer.texture_depth) != size[1]))) {
2154     GPU_texture_free(g_select_buffer.texture_depth);
2155     g_select_buffer.texture_depth = NULL;
2156   }
2157
2158   if (g_select_buffer.texture_depth == NULL) {
2159     g_select_buffer.texture_depth = GPU_texture_create_2d(
2160         size[0], size[1], GPU_DEPTH_COMPONENT24, NULL, NULL);
2161
2162     GPU_framebuffer_texture_attach(
2163         g_select_buffer.framebuffer_depth_only, g_select_buffer.texture_depth, 0, 0);
2164
2165     GPU_framebuffer_check_valid(g_select_buffer.framebuffer_depth_only, NULL);
2166   }
2167 }
2168
2169 /* Must run after all instance datas have been added. */
2170 void DRW_render_instance_buffer_finish(void)
2171 {
2172   BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
2173   DST.buffer_finish_called = true;
2174   DRW_instance_buffer_finish(DST.idatalist);
2175 }
2176
2177 /**
2178  * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
2179  */
2180 void DRW_draw_select_loop(struct Depsgraph *depsgraph,
2181                           ARegion *ar,
2182                           View3D *v3d,
2183                           bool UNUSED(use_obedit_skip),
2184                           bool draw_surface,
2185                           bool UNUSED(use_nearest),
2186                           const rcti *rect,
2187                           DRW_SelectPassFn select_pass_fn,
2188                           void *select_pass_user_data,
2189                           DRW_ObjectFilterFn object_filter_fn,
2190                           void *object_filter_user_data)
2191 {
2192   Scene *scene = DEG_get_evaluated_scene(depsgraph);
2193   RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
2194   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
2195   Object *obact = OBACT(view_layer);
2196   Object *obedit = OBEDIT_FROM_OBACT(obact);
2197 #ifndef USE_GPU_SELECT
2198   UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
2199 #else
2200   RegionView3D *rv3d = ar->regiondata;
2201
2202   /* Reset before using it. */
2203   drw_state_prepare_clean_for_draw(&DST);
2204
2205   bool use_obedit = false;
2206   int obedit_mode = 0;
2207   if (obedit != NULL) {
2208     if (obedit->type == OB_MBALL) {
2209       use_obedit = true;
2210       obedit_mode = CTX_MODE_EDIT_METABALL;
2211     }
2212     else if (obedit->type == OB_ARMATURE) {
2213       use_obedit = true;
2214       obedit_mode = CTX_MODE_EDIT_ARMATURE;
2215     }
2216   }
2217   if (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT) {
2218     if (!(v3d->flag2 & V3D_HIDE_OVERLAYS)) {
2219       /* Note: don't use "BKE_object_pose_armature_get" here, it breaks selection. */
2220       Object *obpose = OBPOSE_FROM_OBACT(obact);
2221       if (obpose) {
2222         use_obedit = true;
2223         obedit_mode = CTX_MODE_POSE;
2224       }
2225     }
2226   }
2227
2228   int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
2229   struct GPUViewport *viewport = GPU_viewport_create();
2230   GPU_viewport_size_set(viewport, viewport_size);
2231
2232   DST.viewport = viewport;
2233   DST.options.is_select = true;
2234
2235   /* Get list of enabled engines */
2236   if (use_obedit) {
2237     drw_engines_enable_from_paint_mode(obedit_mode);
2238     drw_engines_enable_from_mode(obedit_mode);
2239   }
2240   else if (!draw_surface) {
2241     /* grease pencil selection */
2242     use_drw_engine(&draw_engine_gpencil_type);
2243
2244     drw_engines_enable_from_overlays(v3d->overlay.flag);
2245     drw_engines_enable_from_object_mode();
2246   }
2247   else {
2248     drw_engines_enable_basic();
2249     /* grease pencil selection */
2250     use_drw_engine(&draw_engine_gpencil_type);
2251
2252     drw_engines_enable_from_overlays(v3d->overlay.flag);
2253     drw_engines_enable_from_object_mode();
2254   }
2255   drw_engines_data_validate();
2256
2257   /* Setup viewport */
2258
2259   /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2260   DST.draw_ctx = (DRWContextState){
2261       .ar = ar,
2262       .rv3d = rv3d,
2263       .v3d = v3d,
2264       .scene = scene,
2265       .view_layer = view_layer,
2266       .obact = obact,
2267       .engine_type = engine_type,
2268       .depsgraph = depsgraph,
2269   };
2270   drw_context_state_init();
2271   drw_viewport_var_init();
2272
2273   /* Update ubos */
2274   DRW_globals_update();
2275
2276   /* Init engines */
2277   drw_engines_init();
2278   DRW_hair_init();
2279
2280   {
2281     drw_engines_cache_init();
2282     drw_engines_world_update(scene);
2283
2284     if (use_obedit) {
2285       FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
2286         drw_engines_cache_populate(ob_iter);
2287       }
2288       FOREACH_OBJECT_IN_MODE_END;
2289     }
2290     else {
2291       const int object_type_exclude_select = (v3d->object_type_exclude_viewport |
2292                                               v3d->object_type_exclude_select);
2293       bool filter_exclude = false;
2294       DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
2295         if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
2296           continue;
2297         }
2298
2299         if ((ob->base_flag & BASE_SELECTABLE) &&
2300             (object_type_exclude_select & (1 << ob->type)) == 0) {
2301           if (object_filter_fn != NULL) {
2302             if (ob->base_flag & BASE_FROM_DUPLI) {
2303               /* pass (use previous filter_exclude value) */
2304             }
2305             else {
2306               filter_exclude = (object_filter_fn(ob, object_filter_user_data) == false);
2307             }
2308             if (filter_exclude) {
2309               continue;
2310             }
2311           }
2312
2313           /* This relies on dupli instances being after their instancing object. */
2314           if ((ob->base_flag & BASE_FROM_DUPLI) == 0) {
2315             Object *ob_orig = DEG_get_original_object(ob);
2316             DRW_select_load_id(ob_orig->runtime.select_id);
2317           }
2318           DST.dupli_parent = data_.dupli_parent;
2319           DST.dupli_source = data_.dupli_object_current;
2320           drw_duplidata_load(DST.dupli_source);
2321           drw_engines_cache_populate(ob);
2322         }
2323       }
2324       DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
2325     }
2326
2327     drw_duplidata_free();
2328     drw_engines_cache_finish();
2329
2330     DRW_render_instance_buffer_finish();
2331   }
2332
2333   /* Setup framebuffer */
2334   draw_select_framebuffer_depth_only_setup(viewport_size);
2335   GPU_framebuffer_bind(g_select_buffer.framebuffer_depth_only);
2336   GPU_framebuffer_clear_depth(g_select_buffer.framebuffer_depth_only, 1.0f);
2337
2338   /* Start Drawing */
2339   DRW_state_reset();
2340   DRW_draw_callbacks_pre_scene();
2341
2342   DRW_hair_update();
2343
2344   DRW_state_lock(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_DEPTH_LESS_EQUAL |
2345                  DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER | DRW_STATE_DEPTH_ALWAYS);
2346
2347   /* Only 1-2 passes. */
2348   while (true) {
2349     if (!select_pass_fn(DRW_SELECT_PASS_PRE, select_pass_user_data)) {
2350       break;
2351     }
2352
2353     drw_engines_draw_scene();
2354
2355     if (!select_pass_fn(DRW_SELECT_PASS_POST, select_pass_user_data)) {
2356       break;
2357     }
2358   }
2359
2360   /* TODO: GPXX Workaround for grease pencil selection while draw manager support a callback from
2361    * scene finish */
2362   void *data = GPU_viewport_engine_data_get(DST.viewport, &draw_engine_gpencil_type);
2363   if (data != NULL) {
2364     DRW_gpencil_free_runtime_data(data);
2365   }
2366
2367   DRW_state_lock(0);
2368
2369   DRW_draw_callbacks_post_scene();
2370
2371   DRW_state_reset();
2372   drw_engines_disable();
2373
2374 #  ifdef DEBUG
2375   /* Avoid accidental reuse. */
2376   drw_state_ensure_not_reused(&DST);
2377 #  endif
2378   GPU_framebuffer_restore();
2379
2380   /* Cleanup for selection state */
2381   GPU_viewport_free(viewport);
2382 #endif /* USE_GPU_SELECT */
2383 }
2384
2385 /**
2386  * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
2387  */
2388 static void drw_draw_depth_loop_imp(void)
2389 {
2390   /* Setup framebuffer */
2391   DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(
2392       DST.viewport);
2393   GPU_framebuffer_bind(fbl->depth_only_fb);
2394   GPU_framebuffer_clear_depth(fbl->depth_only_fb, 1.0f);
2395
2396   /* Setup viewport */
2397   drw_context_state_init();
2398   drw_viewport_var_init();
2399
2400   /* Update ubos */
2401   DRW_globals_update();
2402
2403   /* Init engines */
2404   drw_engines_init();
2405   DRW_hair_init();
2406
2407   {
2408     drw_engines_cache_init();
2409     drw_engines_world_update(DST.draw_ctx.scene);
2410
2411     View3D *v3d = DST.draw_ctx.v3d;
2412     const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
2413     DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (DST.draw_ctx.depsgraph, ob) {
2414       if ((object_type_exclude_viewport & (1 << ob->type)) != 0) {
2415         continue;
2416       }
2417
2418       if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) {
2419         continue;
2420       }
2421
2422       DST.dupli_parent = data_.dupli_parent;
2423       DST.dupli_source = data_.dupli_object_current;
2424       drw_duplidata_load(DST.dupli_source);
2425       drw_engines_cache_populate(ob);
2426     }
2427     DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
2428
2429     drw_duplidata_free();
2430     drw_engines_cache_finish();
2431
2432     DRW_render_instance_buffer_finish();
2433   }
2434
2435   /* Start Drawing */
2436   DRW_state_reset();
2437
2438   DRW_hair_update();
2439
2440   DRW_draw_callbacks_pre_scene();
2441   drw_engines_draw_scene();
2442   DRW_draw_callbacks_post_scene();
2443
2444   DRW_state_reset();
2445
2446   /* TODO: Reading depth for operators should be done here. */
2447
2448   GPU_framebuffer_restore();
2449 }
2450
2451 /**
2452  * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
2453  */
2454 void DRW_draw_depth_loop(struct Depsgraph *depsgraph,
2455                          ARegion *ar,
2456                          View3D *v3d,
2457                          GPUViewport *viewport,
2458                          bool use_opengl_context)
2459 {
2460   Scene *scene = DEG_get_evaluated_scene(depsgraph);
2461   RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
2462   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
2463   RegionView3D *rv3d = ar->regiondata;
2464
2465   if (use_opengl_context) {
2466     DRW_opengl_context_enable();
2467   }
2468
2469   /* Reset before using it. */
2470   drw_state_prepare_clean_for_draw(&DST);
2471
2472   DST.viewport = viewport;
2473   DST.options.is_depth = true;
2474
2475   /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2476   DST.draw_ctx = (DRWContextState){
2477       .ar = ar,
2478       .rv3d = rv3d,
2479       .v3d = v3d,
2480       .scene = scene,
2481       .view_layer = view_layer,
2482       .obact = OBACT(view_layer),
2483       .engine_type = engine_type,
2484       .depsgraph = depsgraph,
2485   };
2486
2487   /* Get list of enabled engines */
2488   {
2489     drw_engines_enable_basic();
2490     if (DRW_state_draw_support()) {
2491       drw_engines_enable_from_object_mode();
2492     }
2493     drw_engines_data_validate();
2494   }
2495
2496   drw_draw_depth_loop_imp();
2497
2498   drw_engines_disable();
2499
2500 #ifdef DEBUG
2501   /* Avoid accidental reuse. */
2502   drw_state_ensure_not_reused(&DST);
2503 #endif
2504
2505   /* Changin context */
2506   if (use_opengl_context) {
2507     DRW_opengl_context_disable();
2508   }
2509 }
2510
2511 /**
2512  * Converted from ED_view3d_draw_depth_gpencil (legacy drawing).
2513  */
2514 void DRW_draw_depth_loop_gpencil(struct Depsgraph *depsgraph,
2515                                  ARegion *ar,
2516                                  View3D *v3d,
2517                                  GPUViewport *viewport)
2518 {
2519   Scene *scene = DEG_get_evaluated_scene(depsgraph);
2520   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
2521   RegionView3D *rv3d = ar->regiondata;
2522
2523   DRW_opengl_context_enable();
2524
2525   /* Reset before using it. */
2526   drw_state_prepare_clean_for_draw(&DST);
2527
2528   DST.viewport = viewport;
2529   DST.options.is_depth = true;
2530
2531   /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2532   DST.draw_ctx = (DRWContextState){
2533       .ar = ar,
2534       .rv3d = rv3d,
2535       .v3d = v3d,
2536       .scene = scene,
2537       .view_layer = view_layer,
2538       .obact = OBACT(view_layer),
2539       .depsgraph = depsgraph,
2540   };
2541
2542   use_drw_engine(&draw_engine_gpencil_type);
2543   drw_engines_data_validate();
2544
2545   drw_draw_depth_loop_imp();
2546
2547   drw_engines_disable();
2548
2549 #ifdef DEBUG
2550   /* Avoid accidental reuse. */
2551   drw_state_ensure_not_reused(&DST);
2552 #endif
2553
2554   /* Changin context */
2555   DRW_opengl_context_disable();
2556 }
2557
2558 void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *ar, View3D *v3d, const rcti *rect)
2559 {
2560   Scene *scene = DEG_get_evaluated_scene(depsgraph);
2561   ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
2562
2563   /* Reset before using it. */
2564   drw_state_prepare_clean_for_draw(&DST);
2565
2566   /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2567   DST.draw_ctx = (DRWContextState){
2568       .ar = ar,
2569       .rv3d = ar->regiondata,
2570       .v3d = v3d,
2571       .scene = scene,
2572       .view_layer = view_layer,
2573       .obact = OBACT(view_layer),
2574       .depsgraph = depsgraph,
2575   };
2576
2577   drw_context_state_init();
2578
2579   /* Setup viewport */
2580   DST.viewport = WM_draw_region_get_viewport(ar, 0);
2581   drw_viewport_var_init();
2582
2583   /* Update ubos */
2584   DRW_globals_update();
2585
2586   /* Init Select Engine */
2587   struct SELECTID_Context *sel_ctx = DRW_select_engine_context_get();
2588   sel_ctx->last_rect = *rect;
2589
2590   use_drw_engine(&draw_engine_select_type);
2591   drw_engines_init();
2592   {
2593     drw_engines_cache_init();
2594
2595     Object **obj = &sel_ctx->objects[0];
2596     for (uint remaining = sel_ctx->objects_len; remaining--; obj++) {
2597       Object *obj_eval = DEG_get_evaluated_object(depsgraph, *obj);
2598       drw_engines_cache_populate(obj_eval);
2599     }
2600
2601     drw_engines_cache_finish();
2602
2603     DRW_render_instance_buffer_finish();
2604   }
2605
2606   /* Start Drawing */
2607   DRW_state_reset();
2608   drw_engines_draw_scene();
2609   DRW_state_reset();
2610
2611   drw_engines_disable();
2612
2613   drw_viewport_cache_resize();
2614
2615 #ifdef DEBUG
2616   /* Avoid accidental reuse. */
2617   drw_state_ensure_not_reused(&DST);
2618 #endif
2619 }
2620
2621 /** See #DRW_shgroup_world_clip_planes_from_rv3d. */
2622 static void draw_world_clip_planes_from_rv3d(GPUBatch *batch, const float world_clip_planes[6][4])
2623 {
2624   GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
2625 }
2626
2627 /**
2628  * Clears the Depth Buffer and draws only the specified object.
2629  */
2630 void DRW_draw_depth_object(ARegion *ar, GPUViewport *viewport, Object *object)
2631 {
2632   RegionView3D *rv3d = ar->regiondata;
2633
2634   DRW_opengl_context_enable();
2635
2636   /* Setup framebuffer */
2637   DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport);
2638
2639   GPU_framebuffer_bind(fbl->depth_only_fb);
2640   GPU_framebuffer_clear_depth(fbl->depth_only_fb, 1.0f);
2641   GPU_depth_test(true);
2642   GPU_matrix_mul(object->obmat);
2643
2644   const float(*world_clip_planes)[4] = NULL;
2645   if (rv3d->rflag & RV3D_CLIPPING) {
2646     ED_view3d_clipping_set(rv3d);
2647     ED_view3d_clipping_local(rv3d, object->obmat);
2648     world_clip_planes = rv3d->clip_local;
2649   }
2650
2651   drw_batch_cache_validate(object);
2652
2653   switch (object->type) {
2654     case OB_MESH: {
2655       GPUBatch *batch;
2656
2657       Mesh *me = object->data;
2658
2659       if (object->mode & OB_MODE_EDIT) {
2660         batch = DRW_mesh_batch_cache_get_edit_triangles(me);
2661       }
2662       else {
2663         batch = DRW_mesh_batch_cache_get_surface(me);
2664       }
2665
2666       DRW_mesh_batch_cache_create_requested(object, me, NULL, false, true);
2667
2668       const eGPUShaderConfig sh_cfg = world_clip_planes ? GPU_SHADER_CFG_CLIPPED :
2669                                                           GPU_SHADER_CFG_DEFAULT;
2670       GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
2671       if (world_clip_planes != NULL) {
2672         draw_world_clip_planes_from_rv3d(batch, world_clip_planes);
2673       }
2674
2675       GPU_batch_draw(batch);
2676     } break;
2677     case OB_CURVE:
2678     case OB_SURF:
2679       break;
2680   }
2681
2682   if (rv3d->rflag & RV3D_CLIPPING) {
2683     ED_view3d_clipping_disable();
2684   }
2685
2686   GPU_matrix_set(rv3d->viewmat);
2687   GPU_depth_test(false);
2688   GPU_framebuffer_restore();
2689   DRW_opengl_context_disable();
2690 }
2691
2692 /** \} */
2693
2694 /* -------------------------------------------------------------------- */
2695 /** \name Draw Manager State (DRW_state)
2696  * \{ */
2697
2698 void DRW_state_dfdy_factors_get(float dfdyfac[2])
2699 {
2700   GPU_get_dfdy_factors(dfdyfac);
2701 }
2702
2703 /**
2704  * When false, drawing doesn't output to a pixel buffer
2705  * eg: Occlusion queries, or when we have setup a context to draw in already.
2706  */
2707 bool DRW_state_is_fbo(void)
2708 {
2709   return ((DST.default_framebuffer != NULL) || DST.options.is_image_render) &&
2710          !DRW_state_is_depth() && !DRW_state_is_select();
2711 }
2712
2713 /**
2714  * For when engines need to know if this is drawing for selection or not.
2715  */
2716 bool DRW_state_is_select(void)
2717 {
2718   return DST.options.is_select;
2719 }
2720
2721 bool DRW_state_is_depth(void)
2722 {
2723   return DST.options.is_depth;
2724 }
2725
2726 /**
2727  * Whether we are rendering for an image
2728  */
2729 bool DRW_state_is_image_render(void)
2730 {
2731   return DST.options.is_image_render;
2732 }
2733
2734 /**
2735  * Whether the view transform should be applied.
2736  */
2737 bool DRW_state_do_color_management(void)
2738 {
2739   return DST.options.do_color_management;
2740 }
2741
2742 /**
2743  * Whether we are rendering only the render engine,
2744  * or if we should also render the mode engines.
2745  */
2746 bool DRW_state_is_scene_render(void)
2747 {
2748   BLI_assert(DST.options.is_scene_render ? DST.options.is_image_render : true);
2749   return DST.options.is_scene_render;
2750 }
2751
2752 /**
2753  * Whether we are rendering simple opengl render
2754  */
2755 bool DRW_state_is_opengl_render(void)
2756 {
2757   return DST.options.is_image_render && !DST.options.is_scene_render;
2758 }
2759
2760 bool DRW_state_is_playback(void)
2761 {
2762   if (DST.draw_ctx.evil_C != NULL) {
2763     struct wmWindowManager *wm = CTX_wm_manager(DST.draw_ctx.evil_C);
2764     return ED_screen_animation_playing(wm) != NULL;
2765   }
2766   return false;
2767 }
2768
2769 /**
2770  * Should text draw in this mode?
2771  */
2772 bool DRW_state_show_text(void)
2773 {
2774   return (DST.options.is_select) == 0 && (DST.options.is_depth) == 0 &&
2775          (DST.options.is_scene_render) == 0 && (DST.options.draw_text) == 0;
2776 }
2777
2778 /**
2779  * Should draw support elements
2780  * Objects center, selection outline, probe data, ...
2781  */
2782 bool DRW_state_draw_support(void)
2783 {
2784   View3D *v3d = DST.draw_ctx.v3d;
2785   return (DRW_state_is_scene_render() == false) && (v3d != NULL) &&
2786          ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0);
2787 }
2788
2789 /**
2790  * Whether we should render the background
2791  */
2792 bool DRW_state_draw_background(void)
2793 {
2794   return DST.options.draw_background;
2795 }
2796
2797 /** \} */
2798
2799 /* -------------------------------------------------------------------- */
2800 /** \name Context State (DRW_context_state)
2801  * \{ */
2802
2803 const DRWContextState *DRW_context_state_get(void)
2804 {
2805   return &DST.draw_ctx;
2806 }
2807
2808 /** \} */
2809
2810 /* -------------------------------------------------------------------- */
2811 /** \name Init/Exit (DRW_engines)
2812  * \{ */
2813
2814 bool DRW_engine_render_support(DrawEngineType *draw_engine_type)
2815 {
2816   return draw_engine_type->render_to_image;
2817 }
2818
2819 void DRW_engine_register(DrawEngineType *draw_engine_type)
2820 {
2821   BLI_addtail(&DRW_engines, draw_engine_type);
2822 }
2823
2824 void DRW_engines_register(void)
2825 {
2826   RE_engines_register(&DRW_engine_viewport_eevee_type);
2827   RE_engines_register(&DRW_engine_viewport_workbench_type);
2828
2829   DRW_engine_register(&draw_engine_workbench_solid);
2830   DRW_engine_register(&draw_engine_workbench_transparent);
2831
2832   DRW_engine_register(&draw_engine_object_type);
2833   DRW_engine_register(&draw_engine_edit_armature_type);
2834   DRW_engine_register(&draw_engine_edit_curve_type);
2835   DRW_engine_register(&draw_engine_edit_lattice_type);
2836   DRW_engine_register(&draw_engine_edit_mesh_type);
2837   DRW_engine_register(&draw_engine_edit_metaball_type);
2838   DRW_engine_register(&draw_engine_edit_text_type);
2839   DRW_engine_register(&draw_engine_motion_path_type);
2840   DRW_engine_register(&draw_engine_overlay_type);
2841   DRW_engine_register(&draw_engine_paint_texture_type);
2842   DRW_engine_register(&draw_engine_paint_vertex_type);
2843   DRW_engine_register(&draw_engine_particle_type);
2844   DRW_engine_register(&draw_engine_pose_type);
2845   DRW_engine_register(&draw_engine_sculpt_type);
2846   DRW_engine_register(&draw_engine_gpencil_type);
2847   DRW_engine_register(&draw_engine_select_type);
2848
2849   /* setup callbacks */
2850   {
2851     BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag;
2852     BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free;
2853
2854     BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag;
2855     BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free;
2856
2857     BKE_mesh_batch_cache_dirty_tag_cb = DRW_mesh_batch_cache_dirty_tag;
2858     BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free;
2859
2860     BKE_lattice_batch_cache_dirty_tag_cb = DRW_lattice_batch_cache_dirty_tag;
2861     BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free;
2862
2863     BKE_particle_batch_cache_dirty_tag_cb = DRW_particle_batch_cache_dirty_tag;
2864     BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free;
2865
2866     BKE_gpencil_batch_cache_dirty_tag_cb = DRW_gpencil_batch_cache_dirty_tag;
2867     BKE_gpencil_batch_cache_free_cb = DRW_gpencil_batch_cache_free;
2868   }
2869 }
2870
2871 void DRW_engines_free(void)
2872 {
2873   if (DST.gl_context == NULL) {
2874     /* Nothing has been setup. Nothing to clear.
2875      * Otherwise, DRW_opengl_context_enable can
2876      * create a context in background mode. (see T62355) */
2877     return;
2878   }
2879
2880   DRW_opengl_context_enable();
2881
2882   DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth);
2883   GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only);
2884
2885   DRW_hair_free();
2886   DRW_shape_cache_free();
2887   DRW_stats_free();
2888   DRW_globals_free();
2889
2890   DrawEngineType *next;
2891   for (DrawEngineType *type = DRW_engines.first; type; type = next) {
2892     next = type->next;
2893     BLI_remlink(&R_engines, type);
2894
2895     if (type->engine_free) {
2896       type->engine_free();
2897     }
2898   }
2899
2900   DRW_UBO_FREE_SAFE(G_draw.block_ubo);
2901   DRW_UBO_FREE_SAFE(G_draw.view_ubo);
2902   DRW_TEXTURE_FREE_SAFE(G_draw.ramp);
2903   DRW_TEXTURE_FREE_SAFE(G_draw.weight_ramp);
2904
2905   MEM_SAFE_FREE(DST.uniform_names.buffer);
2906
2907   DRW_opengl_context_disable();
2908 }
2909
2910 /** \} */
2911
2912 /** \name Init/Exit (DRW_opengl_ctx)
2913  * \{ */
2914
2915 void DRW_opengl_context_create(void)
2916 {
2917   BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */
2918
2919   DST.gl_context_mutex = BLI_ticket_mutex_alloc();
2920   if (!G.background) {
2921     immDeactivate();
2922   }
2923   /* This changes the active context. */
2924   DST.gl_context = WM_opengl_context_create();
2925   WM_opengl_context_activate(DST.gl_context);
2926   /* Be sure to create gpu_context too. */
2927   DST.gpu_context = GPU_context_create(0);
2928   if (!G.background) {
2929     immActivate();
2930   }
2931   /* Set default Blender OpenGL state */
2932   GPU_state_init();
2933   /* So we activate the window's one afterwards. */
2934   wm_window_reset_drawable();
2935 }
2936
2937 void DRW_opengl_context_destroy(void)
2938 {
2939   BLI_assert(BLI_thread_is_main());
2940   if (DST.gl_context != NULL) {
2941     WM_opengl_context_activate(DST.gl_context);
2942     GPU_context_active_set(DST.gpu_context);
2943     GPU_context_discard(DST.gpu_context);
2944     WM_opengl_context_dispose(DST.gl_context);
2945     BLI_ticket_mutex_free(DST.gl_context_mutex);
2946   }
2947 }
2948
2949 void DRW_opengl_context_enable_ex(bool restore)
2950 {
2951   if (DST.gl_context != NULL) {
2952     /* IMPORTANT: We dont support immediate mode in render mode!
2953      * This shall remain in effect until immediate mode supports
2954      * multiple threads. */
2955     BLI_ticket_mutex_lock(DST.gl_context_mutex);
2956     if (BLI_thread_is_main() && restore) {
2957       if (!G.background) {
2958         immDeactivate();
2959       }
2960     }
2961     WM_opengl_context_activate(DST.gl_context);
2962     GPU_context_active_set(DST.gpu_context);
2963     if (BLI_thread_is_main() && restore) {
2964       if (!G.background) {
2965         immActivate();
2966       }
2967       BLF_batch_reset();
2968     }
2969   }
2970 }
2971
2972 void DRW_opengl_context_disable_ex(bool restore)
2973 {
2974   if (DST.gl_context != NULL) {
2975 #ifdef __APPLE__
2976     /* Need to flush before disabling draw context, otherwise it does not
2977      * always finish drawing and viewport can be empty or partially drawn */
2978     GPU_flush();
2979 #endif
2980
2981     if (BLI_thread_is_main() && restore) {
2982       wm_window_reset_drawable();
2983     }
2984     else {
2985       WM_opengl_context_release(DST.gl_context);
2986       GPU_context_active_set(NULL);
2987     }
2988
2989     BLI_ticket_mutex_unlock(DST.gl_context_mutex);
2990   }
2991 }
2992
2993 void DRW_opengl_context_enable(void)
2994 {
2995   if (G.background && DST.gl_context == NULL) {
2996     WM_init_opengl(G_MAIN);
2997   }
2998   DRW_opengl_context_enable_ex(true);
2999 }
3000
3001 void DRW_opengl_context_disable(void)
3002 {
3003   DRW_opengl_context_disable_ex(true);
3004 }
3005
3006 void DRW_opengl_render_context_enable(void *re_gl_context)
3007 {
3008   /* If thread is main you should use DRW_opengl_context_enable(). */
3009   BLI_assert(!BLI_thread_is_main());
3010
3011   /* TODO get rid of the blocking. Only here because of the static global DST. */
3012   BLI_ticket_mutex_lock(DST.gl_context_mutex);
3013   WM_opengl_context_activate(re_gl_context);
3014 }
3015
3016 void DRW_opengl_render_context_disable(void *re_gl_context)
3017 {
3018   GPU_flush();
3019   WM_opengl_context_release(re_gl_context);
3020   /* TODO get rid of the blocking. */
3021   BLI_ticket_mutex_unlock(DST.gl_context_mutex);
3022 }
3023
3024 /* Needs to be called AFTER DRW_opengl_render_context_enable() */
3025 void DRW_gpu_render_context_enable(void *re_gpu_context)
3026 {
3027   /* If thread is main you should use DRW_opengl_context_enable(). */
3028   BLI_assert(!BLI_thread_is_main());
3029
3030   GPU_context_active_set(re_gpu_context);
3031   DRW_shape_cache_reset(); /* XXX fix that too. */
3032 }
3033
3034 /* Needs to be called BEFORE DRW_opengl_render_context_disable() */
3035 void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context))
3036 {
3037   DRW_shape_cache_reset(); /* XXX fix that too. */
3038   GPU_context_active_set(NULL);
3039 }
3040
3041 /** \} */