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