Merge branch 'blender2.8' into blender2.8-workbench
[blender.git] / source / blender / draw / intern / draw_manager.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file blender/draw/intern/draw_manager.c
23  *  \ingroup draw
24  */
25
26 #include <stdio.h>
27
28 #include "BLI_listbase.h"
29 #include "BLI_mempool.h"
30 #include "BLI_rect.h"
31 #include "BLI_string.h"
32 #include "BLI_threads.h"
33
34 #include "BLF_api.h"
35
36 #include "BKE_global.h"
37 #include "BKE_mesh.h"
38 #include "BKE_object.h"
39 #include "BKE_workspace.h"
40
41 #include "draw_manager.h"
42 #include "DNA_camera_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45
46 #include "ED_space_api.h"
47 #include "ED_screen.h"
48 #include "ED_view3d.h"
49
50 #include "GPU_draw.h"
51 #include "GPU_extensions.h"
52 #include "GPU_framebuffer.h"
53 #include "GPU_immediate.h"
54 #include "GPU_uniformbuffer.h"
55 #include "GPU_viewport.h"
56 #include "GPU_matrix.h"
57
58 #include "IMB_colormanagement.h"
59
60 #include "RE_engine.h"
61 #include "RE_pipeline.h"
62
63 #include "UI_interface.h"
64 #include "UI_resources.h"
65
66 #include "WM_api.h"
67 #include "wm_window.h"
68
69 #include "draw_manager_text.h"
70 #include "draw_manager_profiling.h"
71
72 /* only for callbacks */
73 #include "draw_cache_impl.h"
74
75 #include "draw_mode_engines.h"
76 #include "engines/clay/clay_engine.h"
77 #include "engines/eevee/eevee_engine.h"
78 #include "engines/basic/basic_engine.h"
79 #include "engines/workbench/workbench_engine.h"
80 #include "engines/external/external_engine.h"
81
82 #include "../../../intern/gawain/gawain/gwn_context.h"
83
84 #include "DEG_depsgraph.h"
85 #include "DEG_depsgraph_query.h"
86
87 #ifdef USE_GPU_SELECT
88 #  include "GPU_select.h"
89 #endif
90
91 /** Render State: No persistent data between draw calls. */
92 DRWManager DST = {NULL};
93
94 ListBase DRW_engines = {NULL, NULL};
95
96 extern struct GPUUniformBuffer *view_ubo; /* draw_manager_exec.c */
97
98 static void drw_state_prepare_clean_for_draw(DRWManager *dst)
99 {
100         memset(dst, 0x0, offsetof(DRWManager, ogl_context));
101 }
102
103 /* This function is used to reset draw manager to a state
104  * where we don't re-use data by accident across different
105  * draw calls.
106  */
107 #ifdef DEBUG
108 static void drw_state_ensure_not_reused(DRWManager *dst)
109 {
110         memset(dst, 0xff, offsetof(DRWManager, ogl_context));
111 }
112 #endif
113
114 /* -------------------------------------------------------------------- */
115
116 void DRW_draw_callbacks_pre_scene(void)
117 {
118         RegionView3D *rv3d = DST.draw_ctx.rv3d;
119
120         gpuLoadProjectionMatrix(rv3d->winmat);
121         gpuLoadMatrix(rv3d->viewmat);
122 }
123
124 void DRW_draw_callbacks_post_scene(void)
125 {
126         RegionView3D *rv3d = DST.draw_ctx.rv3d;
127
128         gpuLoadProjectionMatrix(rv3d->winmat);
129         gpuLoadMatrix(rv3d->viewmat);
130 }
131
132 struct DRWTextStore *DRW_text_cache_ensure(void)
133 {
134         BLI_assert(DST.text_store_p);
135         if (*DST.text_store_p == NULL) {
136                 *DST.text_store_p = DRW_text_cache_create();
137         }
138         return *DST.text_store_p;
139 }
140
141
142 /* -------------------------------------------------------------------- */
143
144 /** \name Settings
145  * \{ */
146
147 bool DRW_object_is_renderable(Object *ob)
148 {
149         BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE));
150
151         if (ob->type == OB_MESH) {
152                 if (ob == DST.draw_ctx.object_edit) {
153                         IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
154                         bool do_show_occlude_wire = BKE_collection_engine_property_value_get_bool(props, "show_occlude_wire");
155                         if (do_show_occlude_wire) {
156                                 return false;
157                         }
158                         bool do_show_weight = BKE_collection_engine_property_value_get_bool(props, "show_weight");
159                         if (do_show_weight) {
160                                 return false;
161                         }
162                 }
163         }
164
165         return true;
166 }
167
168 /**
169  * Return whether this object is visible depending if
170  * we are rendering or drawing in the viewport.
171  */
172 bool DRW_check_object_visible_within_active_context(Object *ob)
173 {
174         const eObjectVisibilityCheck mode = DRW_state_is_scene_render() ?
175                                              OB_VISIBILITY_CHECK_FOR_RENDER :
176                                              OB_VISIBILITY_CHECK_FOR_VIEWPORT;
177         return BKE_object_is_visible(ob, mode);
178 }
179
180 bool DRW_object_is_flat_normal(const Object *ob)
181 {
182         if (ob->type == OB_MESH) {
183                 const Mesh *me = ob->data;
184                 if (me->mpoly && me->mpoly[0].flag & ME_SMOOTH) {
185                         return false;
186                 }
187         }
188         return true;
189 }
190
191 /**
192  * Return true if the object has its own draw mode.
193  * Caller must check this is active */
194 int DRW_object_is_mode_shade(const Object *ob)
195 {
196         BLI_assert(ob == DST.draw_ctx.obact);
197         UNUSED_VARS_NDEBUG(ob);
198         if ((DST.draw_ctx.object_mode & OB_MODE_EDIT) == 0) {
199                 if (DST.draw_ctx.object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
200                         if ((DST.draw_ctx.v3d->flag2 & V3D_SHOW_MODE_SHADE_OVERRIDE) == 0) {
201                                 return true;
202                         }
203                         else {
204                                 return false;
205                         }
206                 }
207         }
208         return -1;
209 }
210
211 /** \} */
212
213
214 /* -------------------------------------------------------------------- */
215
216 /** \name Color Management
217  * \{ */
218
219 /* Use color management profile to draw texture to framebuffer */
220 void DRW_transform_to_display(GPUTexture *tex)
221 {
222         drw_state_set(DRW_STATE_WRITE_COLOR);
223
224         Gwn_VertFormat *vert_format = immVertexFormat();
225         unsigned int pos = GWN_vertformat_attr_add(vert_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
226         unsigned int texco = GWN_vertformat_attr_add(vert_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
227
228         const float dither = 1.0f;
229
230         bool use_ocio = false;
231
232         /* View transform is already applied for offscreen, don't apply again, see: T52046 */
233         if (!(DST.options.is_image_render && !DST.options.is_scene_render)) {
234                 Scene *scene = DST.draw_ctx.scene;
235                 use_ocio = IMB_colormanagement_setup_glsl_draw_from_space(
236                         &scene->view_settings, &scene->display_settings, NULL, dither, false);
237         }
238
239         if (!use_ocio) {
240                 /* View transform is already applied for offscreen, don't apply again, see: T52046 */
241                 if (DST.options.is_image_render && !DST.options.is_scene_render) {
242                         immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
243                         immUniformColor4f(1.0f, 1.0f, 1.0f, 1.0f);
244                 }
245                 else {
246                         immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB);
247                 }
248                 immUniform1i("image", 0);
249         }
250
251         GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */
252
253         float mat[4][4];
254         unit_m4(mat);
255         immUniformMatrix4fv("ModelViewProjectionMatrix", mat);
256
257         /* Full screen triangle */
258         immBegin(GWN_PRIM_TRIS, 3);
259         immAttrib2f(texco, 0.0f, 0.0f);
260         immVertex2f(pos, -1.0f, -1.0f);
261
262         immAttrib2f(texco, 2.0f, 0.0f);
263         immVertex2f(pos, 3.0f, -1.0f);
264
265         immAttrib2f(texco, 0.0f, 2.0f);
266         immVertex2f(pos, -1.0f, 3.0f);
267         immEnd();
268
269         GPU_texture_unbind(tex);
270
271         if (use_ocio) {
272                 IMB_colormanagement_finish_glsl_draw();
273         }
274         else {
275                 immUnbindProgram();
276         }
277 }
278
279 /** \} */
280
281
282 /* -------------------------------------------------------------------- */
283
284 /** \name Viewport (DRW_viewport)
285  * \{ */
286
287 void *drw_viewport_engine_data_ensure(void *engine_type)
288 {
289         void *data = GPU_viewport_engine_data_get(DST.viewport, engine_type);
290
291         if (data == NULL) {
292                 data = GPU_viewport_engine_data_create(DST.viewport, engine_type);
293         }
294         return data;
295 }
296
297 void DRW_engine_viewport_data_size_get(
298         const void *engine_type_v,
299         int *r_fbl_len, int *r_txl_len, int *r_psl_len, int *r_stl_len)
300 {
301         const DrawEngineType *engine_type = engine_type_v;
302
303         if (r_fbl_len) {
304                 *r_fbl_len = engine_type->vedata_size->fbl_len;
305         }
306         if (r_txl_len) {
307                 *r_txl_len = engine_type->vedata_size->txl_len;
308         }
309         if (r_psl_len) {
310                 *r_psl_len = engine_type->vedata_size->psl_len;
311         }
312         if (r_stl_len) {
313                 *r_stl_len = engine_type->vedata_size->stl_len;
314         }
315 }
316
317 const float *DRW_viewport_size_get(void)
318 {
319         return DST.size;
320 }
321
322 const float *DRW_viewport_invert_size_get(void)
323 {
324         return DST.inv_size;
325 }
326
327 const float *DRW_viewport_screenvecs_get(void)
328 {
329         return &DST.screenvecs[0][0];
330 }
331
332 const float *DRW_viewport_pixelsize_get(void)
333 {
334         return &DST.pixsize;
335 }
336
337 static void drw_viewport_cache_resize(void)
338 {
339         /* Release the memiter before clearing the mempools that references them */
340         GPU_viewport_cache_release(DST.viewport);
341
342         if (DST.vmempool != NULL) {
343                 BLI_mempool_clear_ex(DST.vmempool->calls, BLI_mempool_len(DST.vmempool->calls));
344                 BLI_mempool_clear_ex(DST.vmempool->states, BLI_mempool_len(DST.vmempool->states));
345                 BLI_mempool_clear_ex(DST.vmempool->shgroups, BLI_mempool_len(DST.vmempool->shgroups));
346                 BLI_mempool_clear_ex(DST.vmempool->uniforms, BLI_mempool_len(DST.vmempool->uniforms));
347                 BLI_mempool_clear_ex(DST.vmempool->passes, BLI_mempool_len(DST.vmempool->passes));
348         }
349
350         DRW_instance_data_list_free_unused(DST.idatalist);
351         DRW_instance_data_list_resize(DST.idatalist);
352 }
353
354 static void drw_state_eval_ctx_init(DRWManager *dst)
355 {
356         DRWContextState *draw_ctx = &dst->draw_ctx;
357         DEG_evaluation_context_init_from_scene(
358                 &draw_ctx->eval_ctx,
359                 draw_ctx->scene,
360                 draw_ctx->view_layer,
361                 DST.options.is_scene_render ? DAG_EVAL_RENDER : DAG_EVAL_VIEWPORT);
362 }
363
364 /* Not a viewport variable, we could split this out. */
365 static void drw_context_state_init(void)
366 {
367         if (DST.draw_ctx.obact) {
368                 DST.draw_ctx.object_mode = DST.draw_ctx.obact->mode;
369         }
370         else {
371                 DST.draw_ctx.object_mode = OB_MODE_OBJECT;
372         }
373
374         /* Edit object. */
375         if (DST.draw_ctx.object_mode & OB_MODE_EDIT) {
376                 DST.draw_ctx.object_edit = DST.draw_ctx.obact;
377         }
378         else {
379                 DST.draw_ctx.object_edit = NULL;
380         }
381
382         /* Pose object. */
383         if (DST.draw_ctx.object_mode & OB_MODE_POSE) {
384                 DST.draw_ctx.object_pose = DST.draw_ctx.obact;
385         }
386         else if (DST.draw_ctx.object_mode & OB_MODE_WEIGHT_PAINT) {
387                 DST.draw_ctx.object_pose = BKE_object_pose_armature_get(DST.draw_ctx.obact);
388         }
389         else {
390                 DST.draw_ctx.object_pose = NULL;
391         }
392
393         drw_state_eval_ctx_init(&DST);
394 }
395
396 /* It also stores viewport variable to an immutable place: DST
397  * This is because a cache uniform only store reference
398  * to its value. And we don't want to invalidate the cache
399  * if this value change per viewport */
400 static void drw_viewport_var_init(void)
401 {
402         RegionView3D *rv3d = DST.draw_ctx.rv3d;
403         /* Refresh DST.size */
404         if (DST.viewport) {
405                 int size[2];
406                 GPU_viewport_size_get(DST.viewport, size);
407                 DST.size[0] = size[0];
408                 DST.size[1] = size[1];
409                 DST.inv_size[0] = 1.0f / size[0];
410                 DST.inv_size[1] = 1.0f / size[1];
411
412                 DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport);
413                 DST.default_framebuffer = fbl->default_fb;
414
415                 DST.vmempool = GPU_viewport_mempool_get(DST.viewport);
416
417                 if (DST.vmempool->calls == NULL) {
418                         DST.vmempool->calls = BLI_mempool_create(sizeof(DRWCall), 0, 512, 0);
419                 }
420                 if (DST.vmempool->states == NULL) {
421                         DST.vmempool->states = BLI_mempool_create(sizeof(DRWCallState), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
422                 }
423                 if (DST.vmempool->shgroups == NULL) {
424                         DST.vmempool->shgroups = BLI_mempool_create(sizeof(DRWShadingGroup), 0, 256, 0);
425                 }
426                 if (DST.vmempool->uniforms == NULL) {
427                         DST.vmempool->uniforms = BLI_mempool_create(sizeof(DRWUniform), 0, 512, 0);
428                 }
429                 if (DST.vmempool->passes == NULL) {
430                         DST.vmempool->passes = BLI_mempool_create(sizeof(DRWPass), 0, 64, 0);
431                 }
432
433                 DST.idatalist = GPU_viewport_instance_data_list_get(DST.viewport);
434                 DRW_instance_data_list_reset(DST.idatalist);
435         }
436         else {
437                 DST.size[0] = 0;
438                 DST.size[1] = 0;
439
440                 DST.inv_size[0] = 0;
441                 DST.inv_size[1] = 0;
442
443                 DST.default_framebuffer = NULL;
444                 DST.vmempool = NULL;
445         }
446
447         if (rv3d != NULL) {
448                 /* Refresh DST.screenvecs */
449                 copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
450                 copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
451                 normalize_v3(DST.screenvecs[0]);
452                 normalize_v3(DST.screenvecs[1]);
453
454                 /* Refresh DST.pixelsize */
455                 DST.pixsize = rv3d->pixsize;
456
457                 copy_m4_m4(DST.original_mat.mat[DRW_MAT_PERS], rv3d->persmat);
458                 copy_m4_m4(DST.original_mat.mat[DRW_MAT_PERSINV], rv3d->persinv);
459                 copy_m4_m4(DST.original_mat.mat[DRW_MAT_VIEW], rv3d->viewmat);
460                 copy_m4_m4(DST.original_mat.mat[DRW_MAT_VIEWINV], rv3d->viewinv);
461                 copy_m4_m4(DST.original_mat.mat[DRW_MAT_WIN], rv3d->winmat);
462                 invert_m4_m4(DST.original_mat.mat[DRW_MAT_WININV], rv3d->winmat);
463
464                 memcpy(DST.view_data.matstate.mat, DST.original_mat.mat, sizeof(DST.original_mat.mat));
465
466                 copy_v4_v4(DST.view_data.viewcamtexcofac, rv3d->viewcamtexcofac);
467         }
468         else {
469                 copy_v4_fl4(DST.view_data.viewcamtexcofac, 1.0f, 1.0f, 0.0f, 0.0f);
470         }
471
472         /* Reset facing */
473         DST.frontface = GL_CCW;
474         DST.backface = GL_CW;
475         glFrontFace(DST.frontface);
476
477         if (DST.draw_ctx.object_edit) {
478                 ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
479         }
480
481         /* Alloc array of texture reference. */
482         if (DST.RST.bound_texs == NULL) {
483                 DST.RST.bound_texs = MEM_callocN(sizeof(GPUTexture *) * GPU_max_textures(), "Bound GPUTexture refs");
484         }
485         if (DST.RST.bound_tex_slots == NULL) {
486                 DST.RST.bound_tex_slots = MEM_callocN(sizeof(char) * GPU_max_textures(), "Bound Texture Slots");
487         }
488         if (DST.RST.bound_ubos == NULL) {
489                 DST.RST.bound_ubos = MEM_callocN(sizeof(GPUUniformBuffer *) * GPU_max_ubo_binds(), "Bound GPUUniformBuffer refs");
490         }
491         if (DST.RST.bound_ubo_slots == NULL) {
492                 DST.RST.bound_ubo_slots = MEM_callocN(sizeof(char) * GPU_max_ubo_binds(), "Bound Ubo Slots");
493         }
494
495         if (view_ubo == NULL) {
496                 view_ubo = DRW_uniformbuffer_create(sizeof(ViewUboStorage), NULL);
497         }
498
499         DST.override_mat = 0;
500         DST.dirty_mat = true;
501         DST.state_cache_id = 1;
502
503         DST.clipping.updated = false;
504
505         memset(DST.common_instance_data, 0x0, sizeof(DST.common_instance_data));
506 }
507
508 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
509 {
510         BLI_assert(type >= 0 && type < DRW_MAT_COUNT);
511         BLI_assert(((DST.override_mat & (1 << type)) != 0)|| DST.draw_ctx.rv3d != NULL); /* Can't use this in render mode. */
512
513         copy_m4_m4(mat, DST.view_data.matstate.mat[type]);
514 }
515
516 void DRW_viewport_matrix_get_all(DRWMatrixState *state)
517 {
518         memcpy(state, DST.view_data.matstate.mat, sizeof(DRWMatrixState));
519 }
520
521 void DRW_viewport_matrix_override_set(const float mat[4][4], DRWViewportMatrixType type)
522 {
523         BLI_assert(type < DRW_MAT_COUNT);
524         copy_m4_m4(DST.view_data.matstate.mat[type], mat);
525         DST.override_mat |= (1 << type);
526         DST.dirty_mat = true;
527         DST.clipping.updated = false;
528 }
529
530 void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type)
531 {
532         BLI_assert(type < DRW_MAT_COUNT);
533         copy_m4_m4(DST.view_data.matstate.mat[type], DST.original_mat.mat[type]);
534         DST.override_mat &= ~(1 << type);
535         DST.dirty_mat = true;
536         DST.clipping.updated = false;
537 }
538
539 void DRW_viewport_matrix_override_set_all(DRWMatrixState *state)
540 {
541         memcpy(DST.view_data.matstate.mat, state, sizeof(DRWMatrixState));
542         DST.override_mat = 0xFFFFFF;
543         DST.dirty_mat = true;
544         DST.clipping.updated = false;
545 }
546
547 void DRW_viewport_matrix_override_unset_all(void)
548 {
549         memcpy(DST.view_data.matstate.mat, DST.original_mat.mat, sizeof(DRWMatrixState));
550         DST.override_mat = 0;
551         DST.dirty_mat = true;
552         DST.clipping.updated = false;
553 }
554
555 bool DRW_viewport_is_persp_get(void)
556 {
557         RegionView3D *rv3d = DST.draw_ctx.rv3d;
558         if (rv3d) {
559                 return rv3d->is_persp;
560         }
561         else {
562                 return DST.view_data.matstate.mat[DRW_MAT_WIN][3][3] == 0.0f;
563         }
564         BLI_assert(0);
565         return false;
566 }
567
568 DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void)
569 {
570         return GPU_viewport_framebuffer_list_get(DST.viewport);
571 }
572
573 DefaultTextureList *DRW_viewport_texture_list_get(void)
574 {
575         return GPU_viewport_texture_list_get(DST.viewport);
576 }
577
578 void DRW_viewport_request_redraw(void)
579 {
580         GPU_viewport_tag_update(DST.viewport);
581 }
582
583 /** \} */
584
585
586 /* -------------------------------------------------------------------- */
587 /** \name ViewLayers (DRW_scenelayer)
588  * \{ */
589
590 void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type)
591 {
592         for (ViewLayerEngineData *sled = DST.draw_ctx.view_layer->drawdata.first; sled; sled = sled->next) {
593                 if (sled->engine_type == engine_type) {
594                         return sled->storage;
595                 }
596         }
597         return NULL;
598 }
599
600 void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*callback)(void *storage))
601 {
602         ViewLayerEngineData *sled;
603
604         for (sled = DST.draw_ctx.view_layer->drawdata.first; sled; sled = sled->next) {
605                 if (sled->engine_type == engine_type) {
606                         return &sled->storage;
607                 }
608         }
609
610         sled = MEM_callocN(sizeof(ViewLayerEngineData), "ViewLayerEngineData");
611         sled->engine_type = engine_type;
612         sled->free = callback;
613         BLI_addtail(&DST.draw_ctx.view_layer->drawdata, sled);
614
615         return &sled->storage;
616 }
617
618 /** \} */
619
620
621 /* -------------------------------------------------------------------- */
622
623 /** \name Objects (DRW_object)
624  * \{ */
625
626 ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type)
627 {
628         for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
629                 if (oed->engine_type == engine_type) {
630                         return oed;
631                 }
632         }
633         return NULL;
634 }
635
636 ObjectEngineData *DRW_object_engine_data_ensure(
637         Object *ob,
638         DrawEngineType *engine_type,
639         size_t size,
640         ObjectEngineDataInitCb init_cb,
641         ObjectEngineDataFreeCb free_cb)
642 {
643         BLI_assert(size >= sizeof(ObjectEngineData));
644         /* Try to re-use existing data. */
645         ObjectEngineData *oed = DRW_object_engine_data_get(ob, engine_type);
646         if (oed != NULL) {
647                 return oed;
648         }
649         /* Allocate new data. */
650         if ((ob->base_flag & BASE_FROMDUPLI) != 0) {
651                 /* NOTE: data is not persistent in this case. It is reset each redraw. */
652                 BLI_assert(free_cb == NULL); /* No callback allowed. */
653                 /* Round to sizeof(float) for DRW_instance_data_request(). */
654                 const size_t t = sizeof(float) - 1;
655                 size = (size + t) & ~t;
656                 size_t fsize = size / sizeof(float);
657                 if (DST.common_instance_data[fsize] == NULL) {
658                         DST.common_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize, 16);
659                 }
660                 oed = (ObjectEngineData *)DRW_instance_data_next(DST.common_instance_data[fsize]);
661                 memset(oed, 0, size);
662         }
663         else {
664                 oed = MEM_callocN(size, "ObjectEngineData");
665         }
666         oed->engine_type = engine_type;
667         oed->free = free_cb;
668         /* Perform user-side initialization, if needed. */
669         if (init_cb != NULL) {
670                 init_cb(oed);
671         }
672         /* Register in the list. */
673         BLI_addtail(&ob->drawdata, oed);
674         return oed;
675 }
676
677 /** \} */
678
679
680 /* -------------------------------------------------------------------- */
681
682 /** \name Rendering (DRW_engines)
683  * \{ */
684
685 static void drw_engines_init(void)
686 {
687         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
688                 DrawEngineType *engine = link->data;
689                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
690                 PROFILE_START(stime);
691
692                 if (engine->engine_init) {
693                         engine->engine_init(data);
694                 }
695
696                 PROFILE_END_UPDATE(data->init_time, stime);
697         }
698 }
699
700 static void drw_engines_cache_init(void)
701 {
702         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
703                 DrawEngineType *engine = link->data;
704                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
705
706                 if (data->text_draw_cache) {
707                         DRW_text_cache_destroy(data->text_draw_cache);
708                         data->text_draw_cache = NULL;
709                 }
710                 if (DST.text_store_p == NULL) {
711                         DST.text_store_p = &data->text_draw_cache;
712                 }
713
714                 if (engine->cache_init) {
715                         engine->cache_init(data);
716                 }
717         }
718 }
719
720 static void drw_engines_cache_populate(Object *ob)
721 {
722         DST.ob_state = NULL;
723
724         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
725                 DrawEngineType *engine = link->data;
726                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
727
728                 if (engine->id_update) {
729                         engine->id_update(data, &ob->id);
730                 }
731
732                 if (engine->cache_populate) {
733                         engine->cache_populate(data, ob);
734                 }
735         }
736 }
737
738 static void drw_engines_cache_finish(void)
739 {
740         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
741                 DrawEngineType *engine = link->data;
742                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
743
744                 if (engine->cache_finish) {
745                         engine->cache_finish(data);
746                 }
747         }
748 }
749
750 static void drw_engines_draw_background(void)
751 {
752         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
753                 DrawEngineType *engine = link->data;
754                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
755
756                 if (engine->draw_background) {
757                         PROFILE_START(stime);
758
759                         DRW_stats_group_start(engine->idname);
760                         engine->draw_background(data);
761                         DRW_stats_group_end();
762
763                         PROFILE_END_UPDATE(data->background_time, stime);
764                         return;
765                 }
766         }
767
768         /* No draw_background found, doing default background */
769         if (DRW_state_draw_background()) {
770                 DRW_draw_background();
771         }
772 }
773
774 static void drw_engines_draw_scene(void)
775 {
776         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
777                 DrawEngineType *engine = link->data;
778                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
779                 PROFILE_START(stime);
780
781                 if (engine->draw_scene) {
782                         DRW_stats_group_start(engine->idname);
783                         engine->draw_scene(data);
784                         /* Restore for next engine */
785                         if (DRW_state_is_fbo()) {
786                                 GPU_framebuffer_bind(DST.default_framebuffer);
787                         }
788                         DRW_stats_group_end();
789                 }
790
791                 PROFILE_END_UPDATE(data->render_time, stime);
792         }
793 }
794
795 static void drw_engines_draw_text(void)
796 {
797         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
798                 DrawEngineType *engine = link->data;
799                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
800                 PROFILE_START(stime);
801
802                 if (data->text_draw_cache) {
803                         DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.v3d, DST.draw_ctx.ar, false);
804                 }
805
806                 PROFILE_END_UPDATE(data->render_time, stime);
807         }
808 }
809
810 #define MAX_INFO_LINES 10
811
812 /**
813  * Returns the offset required for the drawing of engines info.
814  */
815 int DRW_draw_region_engine_info_offset(void)
816 {
817         int lines = 0;
818         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
819                 DrawEngineType *engine = link->data;
820                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
821
822                 /* Count the number of lines. */
823                 if (data->info[0] != '\0') {
824                         lines++;
825                         char *c = data->info;
826                         while (*c++ != '\0') {
827                                 if (*c == '\n') {
828                                         lines++;
829                                 }
830                         }
831                 }
832         }
833         return MIN2(MAX_INFO_LINES, lines) * UI_UNIT_Y;
834 }
835
836 /**
837  * Actual drawing;
838  */
839 void DRW_draw_region_engine_info(void)
840 {
841         const char *info_array_final[MAX_INFO_LINES + 1];
842         /* This should be maxium number of engines running at the same time. */
843         char info_array[MAX_INFO_LINES][GPU_INFO_SIZE];
844         int i = 0;
845
846         const DRWContextState *draw_ctx = DRW_context_state_get();
847         ARegion *ar = draw_ctx->ar;
848         float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
849
850         UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
851         mul_v3_fl(fill_color, fill_color[3]);
852
853         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
854                 DrawEngineType *engine = link->data;
855                 ViewportEngineData *data = drw_viewport_engine_data_ensure(engine);
856
857                 if (data->info[0] != '\0') {
858                         char *chr_current = data->info;
859                         char *chr_start = chr_current;
860                         int line_len = 0;
861
862                         while (*chr_current++ != '\0') {
863                                 line_len++;
864                                 if (*chr_current == '\n') {
865                                         BLI_strncpy(info_array[i++], chr_start, line_len + 1);
866                                         /* Re-start counting. */
867                                         chr_start = chr_current + 1;
868                                         line_len = -1;
869                                 }
870                         }
871
872                         BLI_strncpy(info_array[i++], chr_start, line_len + 1);
873
874                         if (i >= MAX_INFO_LINES) {
875                                 break;
876                         }
877                 }
878         }
879
880         for (int j = 0; j < i; j++) {
881                 info_array_final[j] = info_array[j];
882         }
883         info_array_final[i] = NULL;
884
885         if (info_array[0] != NULL) {
886                 ED_region_info_draw_multiline(ar, info_array_final, fill_color, true);
887         }
888 }
889
890 #undef MAX_INFO_LINES
891
892 static void use_drw_engine(DrawEngineType *engine)
893 {
894         LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
895         ld->data = engine;
896         BLI_addtail(&DST.enabled_engines, ld);
897 }
898
899 /**
900  * Use for external render engines.
901  */
902 static void drw_engines_enable_external(void)
903 {
904         use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
905 }
906
907 /* TODO revisit this when proper layering is implemented */
908 /* Gather all draw engines needed and store them in DST.enabled_engines
909  * That also define the rendering order of engines */
910 static void drw_engines_enable_from_engine(RenderEngineType *engine_type)
911 {
912         /* TODO layers */
913         if (engine_type->draw_engine != NULL) {
914                 use_drw_engine(engine_type->draw_engine);
915         }
916
917         if ((engine_type->flag & RE_INTERNAL) == 0) {
918                 drw_engines_enable_external();
919         }
920 }
921
922 static void drw_engines_enable_from_object_mode(void)
923 {
924         use_drw_engine(&draw_engine_object_type);
925 }
926
927 static void drw_engines_enable_from_mode(int mode)
928 {
929         switch (mode) {
930                 case CTX_MODE_EDIT_MESH:
931                         use_drw_engine(&draw_engine_edit_mesh_type);
932                         break;
933                 case CTX_MODE_EDIT_CURVE:
934                         use_drw_engine(&draw_engine_edit_curve_type);
935                         break;
936                 case CTX_MODE_EDIT_SURFACE:
937                         use_drw_engine(&draw_engine_edit_surface_type);
938                         break;
939                 case CTX_MODE_EDIT_TEXT:
940                         use_drw_engine(&draw_engine_edit_text_type);
941                         break;
942                 case CTX_MODE_EDIT_ARMATURE:
943                         use_drw_engine(&draw_engine_edit_armature_type);
944                         break;
945                 case CTX_MODE_EDIT_METABALL:
946                         use_drw_engine(&draw_engine_edit_metaball_type);
947                         break;
948                 case CTX_MODE_EDIT_LATTICE:
949                         use_drw_engine(&draw_engine_edit_lattice_type);
950                         break;
951                 case CTX_MODE_POSE:
952                         use_drw_engine(&draw_engine_pose_type);
953                         break;
954                 case CTX_MODE_SCULPT:
955                         use_drw_engine(&draw_engine_sculpt_type);
956                         break;
957                 case CTX_MODE_PAINT_WEIGHT:
958                         use_drw_engine(&draw_engine_pose_type);
959                         use_drw_engine(&draw_engine_paint_weight_type);
960                         break;
961                 case CTX_MODE_PAINT_VERTEX:
962                         use_drw_engine(&draw_engine_paint_vertex_type);
963                         break;
964                 case CTX_MODE_PAINT_TEXTURE:
965                         use_drw_engine(&draw_engine_paint_texture_type);
966                         break;
967                 case CTX_MODE_PARTICLE:
968                         use_drw_engine(&draw_engine_particle_type);
969                         break;
970                 case CTX_MODE_OBJECT:
971                         break;
972                 default:
973                         BLI_assert(!"Draw mode invalid");
974                         break;
975         }
976 }
977
978 /**
979  * Use for select and depth-drawing.
980  */
981 static void drw_engines_enable_basic(void)
982 {
983         use_drw_engine(DRW_engine_viewport_basic_type.draw_engine);
984 }
985
986 static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_type)
987 {
988         Object *obact = OBACT(view_layer);
989         const int mode = CTX_data_mode_enum_ex(DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode);
990
991         drw_engines_enable_from_engine(engine_type);
992
993         if (DRW_state_draw_support()) {
994                 drw_engines_enable_from_object_mode();
995                 drw_engines_enable_from_mode(mode);
996         }
997 }
998
999 static void drw_engines_disable(void)
1000 {
1001         BLI_freelistN(&DST.enabled_engines);
1002 }
1003
1004 static unsigned int DRW_engines_get_hash(void)
1005 {
1006         unsigned int hash = 0;
1007         /* The cache depends on enabled engines */
1008         /* FIXME : if collision occurs ... segfault */
1009         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1010                 DrawEngineType *engine = link->data;
1011                 hash += BLI_ghashutil_strhash_p(engine->idname);
1012         }
1013
1014         return hash;
1015 }
1016
1017 /* -------------------------------------------------------------------- */
1018
1019 /** \name View Update
1020  * \{ */
1021
1022 void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
1023 {
1024         RenderEngineType *engine_type = update_ctx->engine_type;
1025         ARegion *ar = update_ctx->ar;
1026         View3D *v3d = update_ctx->v3d;
1027         RegionView3D *rv3d = ar->regiondata;
1028         Depsgraph *depsgraph = update_ctx->depsgraph;
1029         Scene *scene = update_ctx->scene;
1030         ViewLayer *view_layer = update_ctx->view_layer;
1031
1032         if (rv3d->viewport == NULL) {
1033                 return;
1034         }
1035
1036         /* XXX Really nasty locking. But else this could
1037          * be executed by the material previews thread
1038          * while rendering a viewport. */
1039         BLI_mutex_lock(&DST.ogl_context_mutex);
1040
1041         /* Reset before using it. */
1042         drw_state_prepare_clean_for_draw(&DST);
1043
1044         DST.viewport = rv3d->viewport;
1045         DST.draw_ctx = (DRWContextState){
1046                 .ar = ar, .rv3d = rv3d, .v3d = v3d,
1047                 .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
1048                 .engine_type = engine_type,
1049                 .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
1050         };
1051
1052         drw_engines_enable(view_layer, engine_type);
1053
1054         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1055                 DrawEngineType *draw_engine = link->data;
1056                 ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
1057
1058                 if (draw_engine->view_update) {
1059                         draw_engine->view_update(data);
1060                 }
1061         }
1062
1063         DST.viewport = NULL;
1064
1065         drw_engines_disable();
1066
1067         BLI_mutex_unlock(&DST.ogl_context_mutex);
1068 }
1069
1070 /** \} */
1071
1072 /** \name ID Update
1073  * \{ */
1074
1075 /* TODO(sergey): This code is run for each changed ID (including the ones which
1076  * are changed indirectly via update flush. Need to find a way to make this to
1077  * run really fast, hopefully without any memory allocations on a heap
1078  * Idea here could be to run every known engine's id_update() and make them
1079  * do nothing if there is no engine-specific data yet.
1080  */
1081 void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id)
1082 {
1083         RenderEngineType *engine_type = update_ctx->engine_type;
1084         ARegion *ar = update_ctx->ar;
1085         View3D *v3d = update_ctx->v3d;
1086         RegionView3D *rv3d = ar->regiondata;
1087         Depsgraph *depsgraph = update_ctx->depsgraph;
1088         Scene *scene = update_ctx->scene;
1089         ViewLayer *view_layer = update_ctx->view_layer;
1090         if (rv3d->viewport == NULL) {
1091                 return;
1092         }
1093         /* Reset before using it. */
1094         drw_state_prepare_clean_for_draw(&DST);
1095         DST.viewport = rv3d->viewport;
1096         DST.draw_ctx = (DRWContextState){
1097                 .ar = ar, .rv3d = rv3d, .v3d = v3d,
1098                 .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
1099                 .engine_type = engine_type,
1100                 .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
1101         };
1102         drw_engines_enable(view_layer, engine_type);
1103         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1104                 DrawEngineType *draw_engine = link->data;
1105                 ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine);
1106                 if (draw_engine->id_update) {
1107                         draw_engine->id_update(data, id);
1108                 }
1109         }
1110         DST.viewport = NULL;
1111         drw_engines_disable();
1112 }
1113
1114 /** \} */
1115
1116 /* -------------------------------------------------------------------- */
1117
1118 /** \name Main Draw Loops (DRW_draw)
1119  * \{ */
1120
1121 /* Everything starts here.
1122  * This function takes care of calling all cache and rendering functions
1123  * for each relevant engine / mode engine. */
1124 void DRW_draw_view(const bContext *C)
1125 {
1126         EvaluationContext eval_ctx;
1127         CTX_data_eval_ctx(C, &eval_ctx);
1128         RenderEngineType *engine_type = CTX_data_engine_type(C);
1129         ARegion *ar = CTX_wm_region(C);
1130         View3D *v3d = CTX_wm_view3d(C);
1131
1132         /* Reset before using it. */
1133         drw_state_prepare_clean_for_draw(&DST);
1134         DRW_draw_render_loop_ex(eval_ctx.depsgraph, engine_type, ar, v3d, C);
1135 }
1136
1137 /**
1138  * Used for both regular and off-screen drawing.
1139  * Need to reset DST before calling this function
1140  */
1141 void DRW_draw_render_loop_ex(
1142         struct Depsgraph *depsgraph,
1143         RenderEngineType *engine_type,
1144         ARegion *ar, View3D *v3d,
1145         const bContext *evil_C)
1146 {
1147
1148         Scene *scene = DEG_get_evaluated_scene(depsgraph);
1149         ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1150         RegionView3D *rv3d = ar->regiondata;
1151
1152         DST.draw_ctx.evil_C = evil_C;
1153
1154         DST.viewport = rv3d->viewport;
1155         v3d->zbuf = true;
1156
1157         /* Setup viewport */
1158         GPU_viewport_engines_data_validate(DST.viewport, DRW_engines_get_hash());
1159
1160         DST.draw_ctx = (DRWContextState){
1161             .ar = ar, .rv3d = rv3d, .v3d = v3d,
1162             .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
1163             .engine_type = engine_type,
1164             .depsgraph = depsgraph,
1165
1166             /* reuse if caller sets */
1167             .evil_C = DST.draw_ctx.evil_C,
1168         };
1169         drw_context_state_init();
1170         drw_viewport_var_init();
1171
1172         /* Get list of enabled engines */
1173         drw_engines_enable(view_layer, engine_type);
1174
1175         /* Update ubos */
1176         DRW_globals_update();
1177
1178         /* No framebuffer allowed before drawing. */
1179         BLI_assert(GPU_framebuffer_current_get() == 0);
1180
1181         /* Init engines */
1182         drw_engines_init();
1183
1184         /* Cache filling */
1185         {
1186                 PROFILE_START(stime);
1187                 drw_engines_cache_init();
1188
1189                 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob, DRW_iterator_mode_get())
1190                 {
1191                         drw_engines_cache_populate(ob);
1192                 }
1193                 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
1194
1195                 drw_engines_cache_finish();
1196
1197                 DRW_render_instance_buffer_finish();
1198
1199 #ifdef USE_PROFILE
1200                 double *cache_time = GPU_viewport_cache_time_get(DST.viewport);
1201                 PROFILE_END_UPDATE(*cache_time, stime);
1202 #endif
1203         }
1204
1205         DRW_stats_begin();
1206
1207         GPU_framebuffer_bind(DST.default_framebuffer);
1208
1209         /* Start Drawing */
1210         DRW_state_reset();
1211
1212         drw_engines_draw_background();
1213
1214         /* WIP, single image drawn over the camera view (replace) */
1215         bool do_bg_image = false;
1216         if (rv3d->persp == RV3D_CAMOB) {
1217                 Object *cam_ob = v3d->camera;
1218                 if (cam_ob && cam_ob->type == OB_CAMERA) {
1219                         Camera *cam = cam_ob->data;
1220                         if (!BLI_listbase_is_empty(&cam->bg_images)) {
1221                                 do_bg_image = true;
1222                         }
1223                 }
1224         }
1225
1226         if (do_bg_image) {
1227                 ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, false, true);
1228         }
1229
1230
1231         DRW_draw_callbacks_pre_scene();
1232         if (DST.draw_ctx.evil_C) {
1233                 ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
1234         }
1235
1236         drw_engines_draw_scene();
1237
1238         DRW_draw_callbacks_post_scene();
1239         if (DST.draw_ctx.evil_C) {
1240                 ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
1241         }
1242
1243         DRW_state_reset();
1244
1245         drw_engines_draw_text();
1246
1247         if (DST.draw_ctx.evil_C) {
1248                 /* needed so manipulator isn't obscured */
1249                 glDisable(GL_DEPTH_TEST);
1250                 DRW_draw_manipulator_3d();
1251
1252                 DRW_draw_region_info();
1253
1254                 /* Draw 2D after region info so we can draw on top of the camera passepartout overlay.
1255                  * 'DRW_draw_region_info' sets the projection in pixel-space. */
1256                 DRW_draw_manipulator_2d();
1257                 glEnable(GL_DEPTH_TEST);
1258         }
1259
1260         DRW_stats_reset();
1261
1262         if (do_bg_image) {
1263                 ED_view3d_draw_bgpic_test(scene, depsgraph, ar, v3d, true, true);
1264         }
1265
1266         if (G.debug_value > 20) {
1267                 glDisable(GL_DEPTH_TEST);
1268                 rcti rect; /* local coordinate visible rect inside region, to accomodate overlapping ui */
1269                 ED_region_visible_rect(DST.draw_ctx.ar, &rect);
1270                 DRW_stats_draw(&rect);
1271                 glEnable(GL_DEPTH_TEST);
1272         }
1273
1274         GPU_framebuffer_restore();
1275
1276         DRW_state_reset();
1277         drw_engines_disable();
1278
1279         drw_viewport_cache_resize();
1280
1281 #ifdef DEBUG
1282         /* Avoid accidental reuse. */
1283         drw_state_ensure_not_reused(&DST);
1284 #endif
1285 }
1286
1287 void DRW_draw_render_loop(
1288         struct Depsgraph *depsgraph,
1289         ARegion *ar, View3D *v3d)
1290 {
1291         /* Reset before using it. */
1292         drw_state_prepare_clean_for_draw(&DST);
1293
1294         Scene *scene = DEG_get_evaluated_scene(depsgraph);
1295         RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id);
1296
1297         DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL);
1298 }
1299
1300 /* @viewport CAN be NULL, in this case we create one. */
1301 void DRW_draw_render_loop_offscreen(
1302         struct Depsgraph *depsgraph, RenderEngineType *engine_type,
1303         ARegion *ar, View3D *v3d,
1304         const bool draw_background, GPUOffScreen *ofs,
1305         GPUViewport *viewport)
1306 {
1307         RegionView3D *rv3d = ar->regiondata;
1308
1309         /* backup */
1310         void *backup_viewport = rv3d->viewport;
1311         {
1312                 /* backup (_never_ use rv3d->viewport) */
1313                 if (viewport == NULL) {
1314                         rv3d->viewport = GPU_viewport_create_from_offscreen(ofs);
1315                 }
1316                 else {
1317                         rv3d->viewport = viewport;
1318                 }
1319         }
1320
1321         GPU_framebuffer_restore();
1322
1323         /* Reset before using it. */
1324         drw_state_prepare_clean_for_draw(&DST);
1325         DST.options.is_image_render = true;
1326         DST.options.draw_background = draw_background;
1327         DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, NULL);
1328
1329         /* restore */
1330         {
1331                 if (viewport == NULL) {
1332                         /* don't free data owned by 'ofs' */
1333                         GPU_viewport_clear_from_offscreen(rv3d->viewport);
1334                         GPU_viewport_free(rv3d->viewport);
1335                 }
1336
1337                 rv3d->viewport = backup_viewport;
1338         }
1339
1340         /* we need to re-bind (annoying!) */
1341         GPU_offscreen_bind(ofs, false);
1342 }
1343
1344 void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
1345 {
1346         Scene *scene = DEG_get_evaluated_scene(depsgraph);
1347         ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1348         RenderEngineType *engine_type = engine->type;
1349         DrawEngineType *draw_engine_type = engine_type->draw_engine;
1350         RenderData *r = &scene->r;
1351         Render *render = engine->re;
1352         /* Changing Context */
1353         DRW_opengl_context_enable();
1354         /* IMPORTANT: We dont support immediate mode in render mode!
1355          * This shall remain in effect until immediate mode supports
1356          * multiple threads. */
1357
1358         /* Reset before using it. */
1359         drw_state_prepare_clean_for_draw(&DST);
1360         DST.options.is_image_render = true;
1361         DST.options.is_scene_render = true;
1362         DST.options.draw_background = scene->r.alphamode == R_ADDSKY;
1363
1364         DST.draw_ctx = (DRWContextState){
1365             .scene = scene, .view_layer = view_layer,
1366             .engine_type = engine_type,
1367             .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT,
1368         };
1369         drw_context_state_init();
1370
1371         DST.viewport = GPU_viewport_create();
1372         const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100};
1373         GPU_viewport_size_set(DST.viewport, size);
1374
1375         drw_viewport_var_init();
1376
1377         ViewportEngineData *data = drw_viewport_engine_data_ensure(draw_engine_type);
1378
1379         /* set default viewport */
1380         glViewport(0, 0, size[0], size[1]);
1381
1382         /* Main rendering. */
1383         rctf view_rect;
1384         rcti render_rect;
1385         RE_GetViewPlane(render, &view_rect, &render_rect);
1386         if (BLI_rcti_is_empty(&render_rect)) {
1387                 BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
1388         }
1389
1390         /* Init render result. */
1391         RenderResult *render_result = RE_engine_begin_result(
1392                 engine,
1393                 0,
1394                 0,
1395                 (int)size[0],
1396                 (int)size[1],
1397                 view_layer->name,
1398                 /* RR_ALL_VIEWS */ NULL);
1399
1400         RenderLayer *render_layer = render_result->layers.first;
1401         for (RenderView *render_view = render_result->views.first;
1402              render_view != NULL;
1403              render_view = render_view->next)
1404         {
1405                 RE_SetActiveRenderView(render, render_view->name);
1406                 engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect);
1407                 DST.buffer_finish_called = false;
1408         }
1409
1410         RE_engine_end_result(engine, render_result, false, false, false);
1411
1412         /* Force cache to reset. */
1413         drw_viewport_cache_resize();
1414
1415         /* TODO grease pencil */
1416
1417         GPU_viewport_free(DST.viewport);
1418         GPU_framebuffer_restore();
1419
1420         /* Changing Context */
1421         DRW_opengl_context_disable();
1422
1423 #ifdef DEBUG
1424         /* Avoid accidental reuse. */
1425         drw_state_ensure_not_reused(&DST);
1426 #endif
1427 }
1428
1429 void DRW_render_object_iter(
1430         void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph,
1431         void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
1432 {
1433         DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob, DRW_iterator_mode_get())
1434         {
1435                 DST.ob_state = NULL;
1436                 callback(vedata, ob, engine, depsgraph);
1437         }
1438         DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
1439 }
1440
1441 static struct DRWSelectBuffer {
1442         struct GPUFrameBuffer *framebuffer;
1443         struct GPUTexture *texture_depth;
1444 } g_select_buffer = {NULL};
1445
1446 static void draw_select_framebuffer_setup(const rcti *rect)
1447 {
1448         if (g_select_buffer.framebuffer == NULL) {
1449                 g_select_buffer.framebuffer = GPU_framebuffer_create();
1450         }
1451
1452         /* If size mismatch recreate the texture. */
1453         if ((g_select_buffer.texture_depth != NULL) &&
1454                 ((GPU_texture_width(g_select_buffer.texture_depth) != BLI_rcti_size_x(rect)) ||
1455                 (GPU_texture_height(g_select_buffer.texture_depth) != BLI_rcti_size_y(rect))))
1456         {
1457                 GPU_texture_free(g_select_buffer.texture_depth);
1458                 g_select_buffer.texture_depth = NULL;
1459         }
1460
1461         if (g_select_buffer.texture_depth == NULL) {
1462                 g_select_buffer.texture_depth = GPU_texture_create_depth(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), NULL);
1463
1464                 GPU_framebuffer_texture_attach(g_select_buffer.framebuffer, g_select_buffer.texture_depth, 0, 0);
1465
1466                 if (!GPU_framebuffer_check_valid(g_select_buffer.framebuffer, NULL)) {
1467                         printf("Error invalid selection framebuffer\n");
1468                 }
1469         }
1470 }
1471
1472 /* Must run after all instance datas have been added. */
1473 void DRW_render_instance_buffer_finish(void)
1474 {
1475         BLI_assert(!DST.buffer_finish_called && "DRW_render_instance_buffer_finish called twice!");
1476         DST.buffer_finish_called = true;
1477         DRW_instance_buffer_finish(DST.idatalist);
1478 }
1479
1480 /**
1481  * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
1482  */
1483 void DRW_draw_select_loop(
1484         struct Depsgraph *depsgraph,
1485         ARegion *ar, View3D *v3d,
1486         bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect,
1487         DRW_SelectPassFn select_pass_fn, void *select_pass_user_data)
1488 {
1489         Scene *scene = DEG_get_evaluated_scene(depsgraph);
1490         RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id);
1491         ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1492         Object *obact = OBACT(view_layer);
1493         Object *obedit = OBEDIT_FROM_OBACT(obact);
1494 #ifndef USE_GPU_SELECT
1495         UNUSED_VARS(vc, scene, view_layer, v3d, ar, rect);
1496 #else
1497         RegionView3D *rv3d = ar->regiondata;
1498
1499         /* Reset before using it. */
1500         drw_state_prepare_clean_for_draw(&DST);
1501
1502         /* backup (_never_ use rv3d->viewport) */
1503         void *backup_viewport = rv3d->viewport;
1504         rv3d->viewport = NULL;
1505
1506         bool use_obedit = false;
1507         int obedit_mode = 0;
1508         if (obedit != NULL) {
1509                 if (obedit->type == OB_MBALL) {
1510                         use_obedit = true;
1511                         obedit_mode = CTX_MODE_EDIT_METABALL;
1512                 }
1513                 else if (obedit->type == OB_ARMATURE) {
1514                         use_obedit = true;
1515                         obedit_mode = CTX_MODE_EDIT_ARMATURE;
1516                 }
1517         }
1518
1519         struct GPUViewport *viewport = GPU_viewport_create();
1520         GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)});
1521
1522         DST.viewport = viewport;
1523         v3d->zbuf = true;
1524
1525         DST.options.is_select = true;
1526
1527         /* Get list of enabled engines */
1528         if (use_obedit) {
1529                 drw_engines_enable_from_mode(obedit_mode);
1530         }
1531         else {
1532                 drw_engines_enable_basic();
1533                 drw_engines_enable_from_object_mode();
1534         }
1535
1536         /* Setup viewport */
1537
1538         /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
1539         DST.draw_ctx = (DRWContextState){
1540                 .ar = ar, .rv3d = rv3d, .v3d = v3d,
1541                 .scene = scene, .view_layer = view_layer, .obact = obact,
1542                 .engine_type = engine_type,
1543                 .depsgraph = depsgraph,
1544         };
1545         drw_context_state_init();
1546         drw_viewport_var_init();
1547
1548         /* Update ubos */
1549         DRW_globals_update();
1550
1551         /* Init engines */
1552         drw_engines_init();
1553
1554         {
1555                 drw_engines_cache_init();
1556
1557                 if (use_obedit) {
1558                         drw_engines_cache_populate(obact);
1559                 }
1560                 else {
1561                         DEG_OBJECT_ITER_BEGIN(
1562                                 depsgraph, ob, DRW_iterator_mode_get(),
1563                                 DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
1564                                 DEG_ITER_OBJECT_FLAG_VISIBLE |
1565                                 DEG_ITER_OBJECT_FLAG_DUPLI)
1566                         {
1567                                 if ((ob->base_flag & BASE_SELECTABLED) != 0) {
1568                                         DRW_select_load_id(ob->select_color);
1569                                         drw_engines_cache_populate(ob);
1570                                 }
1571                         }
1572                         DEG_OBJECT_ITER_END;
1573                 }
1574
1575                 drw_engines_cache_finish();
1576
1577                 DRW_render_instance_buffer_finish();
1578         }
1579
1580         /* Setup framebuffer */
1581         draw_select_framebuffer_setup(rect);
1582         GPU_framebuffer_bind(g_select_buffer.framebuffer);
1583         GPU_framebuffer_clear_depth(g_select_buffer.framebuffer, 1.0f);
1584
1585         /* Start Drawing */
1586         DRW_state_reset();
1587         DRW_draw_callbacks_pre_scene();
1588
1589         DRW_state_lock(
1590                 DRW_STATE_WRITE_DEPTH |
1591                 DRW_STATE_DEPTH_ALWAYS |
1592                 DRW_STATE_DEPTH_LESS |
1593                 DRW_STATE_DEPTH_EQUAL |
1594                 DRW_STATE_DEPTH_GREATER |
1595                 DRW_STATE_DEPTH_ALWAYS);
1596
1597         /* Only 1-2 passes. */
1598         while (true) {
1599                 if (!select_pass_fn(DRW_SELECT_PASS_PRE, select_pass_user_data)) {
1600                         break;
1601                 }
1602
1603                 drw_engines_draw_scene();
1604
1605                 if (!select_pass_fn(DRW_SELECT_PASS_POST, select_pass_user_data)) {
1606                         break;
1607                 }
1608         }
1609
1610         DRW_state_lock(0);
1611
1612         DRW_draw_callbacks_post_scene();
1613
1614         DRW_state_reset();
1615         drw_engines_disable();
1616
1617 #ifdef DEBUG
1618         /* Avoid accidental reuse. */
1619         drw_state_ensure_not_reused(&DST);
1620 #endif
1621         GPU_framebuffer_restore();
1622
1623         /* Cleanup for selection state */
1624         GPU_viewport_free(viewport);
1625
1626         /* restore */
1627         rv3d->viewport = backup_viewport;
1628 #endif  /* USE_GPU_SELECT */
1629 }
1630
1631 static void draw_depth_texture_to_screen(GPUTexture *texture)
1632 {
1633         const float w = (float)GPU_texture_width(texture);
1634         const float h = (float)GPU_texture_height(texture);
1635
1636         Gwn_VertFormat *format = immVertexFormat();
1637         unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1638         unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1639
1640         immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_DEPTH_COPY);
1641
1642         GPU_texture_bind(texture, 0);
1643
1644         immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
1645
1646         immBegin(GWN_PRIM_TRI_STRIP, 4);
1647
1648         immAttrib2f(texcoord, 0.0f, 0.0f);
1649         immVertex2f(pos, 0.0f, 0.0f);
1650
1651         immAttrib2f(texcoord, 1.0f, 0.0f);
1652         immVertex2f(pos, w, 0.0f);
1653
1654         immAttrib2f(texcoord, 0.0f, 1.0f);
1655         immVertex2f(pos, 0.0f, h);
1656
1657         immAttrib2f(texcoord, 1.0f, 1.0f);
1658         immVertex2f(pos, w, h);
1659
1660         immEnd();
1661
1662         GPU_texture_unbind(texture);
1663
1664         immUnbindProgram();
1665 }
1666
1667 /**
1668  * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
1669  */
1670 void DRW_draw_depth_loop(
1671         Depsgraph *depsgraph,
1672         ARegion *ar, View3D *v3d)
1673 {
1674         Scene *scene = DEG_get_evaluated_scene(depsgraph);
1675         RenderEngineType *engine_type = RE_engines_find(scene->view_render.engine_id);
1676         ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
1677         RegionView3D *rv3d = ar->regiondata;
1678
1679         DRW_opengl_context_enable();
1680
1681         /* backup (_never_ use rv3d->viewport) */
1682         void *backup_viewport = rv3d->viewport;
1683         rv3d->viewport = NULL;
1684
1685         /* Reset before using it. */
1686         drw_state_prepare_clean_for_draw(&DST);
1687
1688         struct GPUViewport *viewport = GPU_viewport_create();
1689         GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy});
1690
1691         /* Setup framebuffer */
1692         draw_select_framebuffer_setup(&ar->winrct);
1693         GPU_framebuffer_bind(g_select_buffer.framebuffer);
1694         GPU_framebuffer_clear_depth(g_select_buffer.framebuffer, 1.0f);
1695
1696         bool cache_is_dirty;
1697         DST.viewport = viewport;
1698         v3d->zbuf = true;
1699
1700         DST.options.is_depth = true;
1701
1702         /* Get list of enabled engines */
1703         {
1704                 drw_engines_enable_basic();
1705                 drw_engines_enable_from_object_mode();
1706         }
1707
1708         /* Setup viewport */
1709         cache_is_dirty = true;
1710
1711         /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
1712         DST.draw_ctx = (DRWContextState){
1713                 .ar = ar, .rv3d = rv3d, .v3d = v3d,
1714                 .scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
1715                 .engine_type = engine_type,
1716                 .depsgraph = depsgraph,
1717         };
1718         drw_context_state_init();
1719         drw_viewport_var_init();
1720
1721         /* Update ubos */
1722         DRW_globals_update();
1723
1724         /* Init engines */
1725         drw_engines_init();
1726
1727         /* TODO : tag to refresh by the dependency graph */
1728         /* ideally only refresh when objects are added/removed */
1729         /* or render properties / materials change */
1730         if (cache_is_dirty) {
1731                 drw_engines_cache_init();
1732
1733                 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob, DRW_iterator_mode_get())
1734                 {
1735                         drw_engines_cache_populate(ob);
1736                 }
1737                 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
1738
1739                 drw_engines_cache_finish();
1740
1741                 DRW_render_instance_buffer_finish();
1742         }
1743
1744         /* Start Drawing */
1745         DRW_state_reset();
1746         DRW_draw_callbacks_pre_scene();
1747         drw_engines_draw_scene();
1748         DRW_draw_callbacks_post_scene();
1749
1750         DRW_state_reset();
1751         drw_engines_disable();
1752
1753 #ifdef DEBUG
1754         /* Avoid accidental reuse. */
1755         drw_state_ensure_not_reused(&DST);
1756 #endif
1757
1758         /* TODO: Reading depth for operators should be done here. */
1759
1760         GPU_framebuffer_restore();
1761
1762         /* Cleanup for selection state */
1763         GPU_viewport_free(viewport);
1764
1765         /* Changin context */
1766         DRW_opengl_context_disable();
1767
1768         /* XXX Drawing the resulting buffer to the BACK_BUFFER */
1769         gpuPushMatrix();
1770         gpuPushProjectionMatrix();
1771         wmOrtho2_region_pixelspace(ar);
1772         gpuLoadIdentity();
1773
1774         glEnable(GL_DEPTH_TEST); /* Cannot write to depth buffer without testing */
1775         glDepthFunc(GL_ALWAYS);
1776         draw_depth_texture_to_screen(g_select_buffer.texture_depth);
1777         glDepthFunc(GL_LEQUAL);
1778
1779         gpuPopMatrix();
1780         gpuPopProjectionMatrix();
1781
1782         /* restore */
1783         rv3d->viewport = backup_viewport;
1784 }
1785
1786 /** \} */
1787
1788
1789 /* -------------------------------------------------------------------- */
1790
1791 /** \name Draw Manager State (DRW_state)
1792  * \{ */
1793
1794 void DRW_state_dfdy_factors_get(float dfdyfac[2])
1795 {
1796         GPU_get_dfdy_factors(dfdyfac);
1797 }
1798
1799 /**
1800  * When false, drawing doesn't output to a pixel buffer
1801  * eg: Occlusion queries, or when we have setup a context to draw in already.
1802  */
1803 bool DRW_state_is_fbo(void)
1804 {
1805         return ((DST.default_framebuffer != NULL) || DST.options.is_image_render);
1806 }
1807
1808 /**
1809  * For when engines need to know if this is drawing for selection or not.
1810  */
1811 bool DRW_state_is_select(void)
1812 {
1813         return DST.options.is_select;
1814 }
1815
1816 bool DRW_state_is_depth(void)
1817 {
1818         return DST.options.is_depth;
1819 }
1820
1821 /**
1822  * Whether we are rendering for an image
1823  */
1824 bool DRW_state_is_image_render(void)
1825 {
1826         return DST.options.is_image_render;
1827 }
1828
1829 /**
1830  * Whether we are rendering only the render engine,
1831  * or if we should also render the mode engines.
1832  */
1833 bool DRW_state_is_scene_render(void)
1834 {
1835         BLI_assert(DST.options.is_scene_render ?
1836                    DST.options.is_image_render : true);
1837         return DST.options.is_scene_render;
1838 }
1839
1840 /**
1841 * Whether we are rendering simple opengl render
1842 */
1843 bool DRW_state_is_opengl_render(void)
1844 {
1845         return DST.options.is_image_render && !DST.options.is_scene_render;
1846 }
1847
1848 /**
1849  * Gives you the iterator mode to use for depsgraph.
1850  */
1851 eDepsObjectIteratorMode DRW_iterator_mode_get(void)
1852 {
1853         return DRW_state_is_scene_render() ? DEG_ITER_OBJECT_MODE_RENDER :
1854                                              DEG_ITER_OBJECT_MODE_VIEWPORT;
1855 }
1856
1857 /**
1858  * Should text draw in this mode?
1859  */
1860 bool DRW_state_show_text(void)
1861 {
1862         return (DST.options.is_select) == 0 &&
1863                (DST.options.is_depth) == 0 &&
1864                (DST.options.is_scene_render) == 0;
1865 }
1866
1867 /**
1868  * Should draw support elements
1869  * Objects center, selection outline, probe data, ...
1870  */
1871 bool DRW_state_draw_support(void)
1872 {
1873         View3D *v3d = DST.draw_ctx.v3d;
1874         return (DRW_state_is_scene_render() == false) &&
1875                 (v3d != NULL) &&
1876                 ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0);
1877 }
1878
1879 /**
1880  * Whether we should render the background
1881  */
1882 bool DRW_state_draw_background(void)
1883 {
1884         if (DRW_state_is_image_render() == false) {
1885                 return true;
1886         }
1887         return DST.options.draw_background;
1888 }
1889
1890 /** \} */
1891
1892
1893 /* -------------------------------------------------------------------- */
1894
1895 /** \name Context State (DRW_context_state)
1896  * \{ */
1897
1898 const DRWContextState *DRW_context_state_get(void)
1899 {
1900         return &DST.draw_ctx;
1901 }
1902
1903 /** \} */
1904
1905
1906 /* -------------------------------------------------------------------- */
1907
1908 /** \name Init/Exit (DRW_engines)
1909  * \{ */
1910
1911 bool DRW_engine_render_support(DrawEngineType *draw_engine_type)
1912 {
1913         return draw_engine_type->render_to_image;
1914 }
1915
1916 void DRW_engine_register(DrawEngineType *draw_engine_type)
1917 {
1918         BLI_addtail(&DRW_engines, draw_engine_type);
1919 }
1920
1921 void DRW_engines_register(void)
1922 {
1923 #ifdef WITH_CLAY_ENGINE
1924         RE_engines_register(NULL, &DRW_engine_viewport_clay_type);
1925 #endif
1926         RE_engines_register(NULL, &DRW_engine_viewport_eevee_type);
1927         RE_engines_register(NULL, &DRW_engine_viewport_workbench_type);
1928
1929         DRW_engine_register(&draw_engine_object_type);
1930         DRW_engine_register(&draw_engine_edit_armature_type);
1931         DRW_engine_register(&draw_engine_edit_curve_type);
1932         DRW_engine_register(&draw_engine_edit_lattice_type);
1933         DRW_engine_register(&draw_engine_edit_mesh_type);
1934         DRW_engine_register(&draw_engine_edit_metaball_type);
1935         DRW_engine_register(&draw_engine_edit_surface_type);
1936         DRW_engine_register(&draw_engine_edit_text_type);
1937         DRW_engine_register(&draw_engine_paint_texture_type);
1938         DRW_engine_register(&draw_engine_paint_vertex_type);
1939         DRW_engine_register(&draw_engine_paint_weight_type);
1940         DRW_engine_register(&draw_engine_particle_type);
1941         DRW_engine_register(&draw_engine_pose_type);
1942         DRW_engine_register(&draw_engine_sculpt_type);
1943
1944         /* setup callbacks */
1945         {
1946                 /* BKE: mball.c */
1947                 extern void *BKE_mball_batch_cache_dirty_cb;
1948                 extern void *BKE_mball_batch_cache_free_cb;
1949                 /* BKE: curve.c */
1950                 extern void *BKE_curve_batch_cache_dirty_cb;
1951                 extern void *BKE_curve_batch_cache_free_cb;
1952                 /* BKE: mesh.c */
1953                 extern void *BKE_mesh_batch_cache_dirty_cb;
1954                 extern void *BKE_mesh_batch_cache_free_cb;
1955                 /* BKE: lattice.c */
1956                 extern void *BKE_lattice_batch_cache_dirty_cb;
1957                 extern void *BKE_lattice_batch_cache_free_cb;
1958                 /* BKE: particle.c */
1959                 extern void *BKE_particle_batch_cache_dirty_cb;
1960                 extern void *BKE_particle_batch_cache_free_cb;
1961
1962                 BKE_mball_batch_cache_dirty_cb = DRW_mball_batch_cache_dirty;
1963                 BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free;
1964
1965                 BKE_curve_batch_cache_dirty_cb = DRW_curve_batch_cache_dirty;
1966                 BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free;
1967
1968                 BKE_mesh_batch_cache_dirty_cb = DRW_mesh_batch_cache_dirty;
1969                 BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free;
1970
1971                 BKE_lattice_batch_cache_dirty_cb = DRW_lattice_batch_cache_dirty;
1972                 BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free;
1973
1974                 BKE_particle_batch_cache_dirty_cb = DRW_particle_batch_cache_dirty;
1975                 BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free;
1976         }
1977 }
1978
1979 extern struct Gwn_VertFormat *g_pos_format; /* draw_shgroup.c */
1980 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
1981 extern struct GPUTexture *globals_ramp; /* draw_common.c */
1982 void DRW_engines_free(void)
1983 {
1984         DRW_opengl_context_enable();
1985
1986         DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth);
1987         GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer);
1988
1989         DRW_shape_cache_free();
1990         DRW_stats_free();
1991         DRW_globals_free();
1992
1993         DrawEngineType *next;
1994         for (DrawEngineType *type = DRW_engines.first; type; type = next) {
1995                 next = type->next;
1996                 BLI_remlink(&R_engines, type);
1997
1998                 if (type->engine_free) {
1999                         type->engine_free();
2000                 }
2001         }
2002
2003         DRW_UBO_FREE_SAFE(globals_ubo);
2004         DRW_UBO_FREE_SAFE(view_ubo);
2005         DRW_TEXTURE_FREE_SAFE(globals_ramp);
2006         MEM_SAFE_FREE(g_pos_format);
2007
2008         MEM_SAFE_FREE(DST.RST.bound_texs);
2009         MEM_SAFE_FREE(DST.RST.bound_tex_slots);
2010         MEM_SAFE_FREE(DST.RST.bound_ubos);
2011         MEM_SAFE_FREE(DST.RST.bound_ubo_slots);
2012
2013         DRW_opengl_context_disable();
2014
2015 #ifdef WITH_CLAY_ENGINE
2016         BLI_remlink(&R_engines, &DRW_engine_viewport_clay_type);
2017 #endif
2018 }
2019
2020 /** \} */
2021
2022 /** \name Init/Exit (DRW_opengl_ctx)
2023  * \{ */
2024
2025 void DRW_opengl_context_create(void)
2026 {
2027         BLI_assert(DST.ogl_context == NULL); /* Ensure it's called once */
2028
2029         BLI_mutex_init(&DST.ogl_context_mutex);
2030
2031         immDeactivate();
2032         /* This changes the active context. */
2033         DST.ogl_context = WM_opengl_context_create();
2034         /* Be sure to create gawain.context too. */
2035         DST.gwn_context = GWN_context_create();
2036         immActivate();
2037         /* Set default Blender OpenGL state */
2038         GPU_state_init();
2039         /* So we activate the window's one afterwards. */
2040         wm_window_reset_drawable();
2041 }
2042
2043 void DRW_opengl_context_destroy(void)
2044 {
2045         BLI_assert(BLI_thread_is_main());
2046         if (DST.ogl_context != NULL) {
2047                 WM_opengl_context_activate(DST.ogl_context);
2048                 GWN_context_active_set(DST.gwn_context);
2049                 GWN_context_discard(DST.gwn_context);
2050                 WM_opengl_context_dispose(DST.ogl_context);
2051                 BLI_mutex_end(&DST.ogl_context_mutex);
2052         }
2053 }
2054
2055 void DRW_opengl_context_enable(void)
2056 {
2057         if (DST.ogl_context != NULL) {
2058                 /* IMPORTANT: We dont support immediate mode in render mode!
2059                  * This shall remain in effect until immediate mode supports
2060                  * multiple threads. */
2061                 BLI_mutex_lock(&DST.ogl_context_mutex);
2062                 if (BLI_thread_is_main()) {
2063                         immDeactivate();
2064                 }
2065                 WM_opengl_context_activate(DST.ogl_context);
2066                 GWN_context_active_set(DST.gwn_context);
2067                 if (BLI_thread_is_main()) {
2068                         immActivate();
2069                         BLF_batch_reset();
2070                 }
2071         }
2072 }
2073
2074 void DRW_opengl_context_disable(void)
2075 {
2076         if (DST.ogl_context != NULL) {
2077 #ifdef __APPLE__
2078                 /* Need to flush before disabling draw context, otherwise it does not
2079                  * always finish drawing and viewport can be empty or partially drawn */
2080                 glFlush();
2081 #endif
2082
2083                 if (BLI_thread_is_main()) {
2084                         wm_window_reset_drawable();
2085                 }
2086                 else {
2087                         WM_opengl_context_release(DST.ogl_context);
2088                         GWN_context_active_set(NULL);
2089                 }
2090
2091                 BLI_mutex_unlock(&DST.ogl_context_mutex);
2092         }
2093 }
2094
2095 /** \} */