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