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