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