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