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