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