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