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