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