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