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