e561acca021a56d110276e859919a0a3443f292a
[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_dynstr.h"
29 #include "BLI_listbase.h"
30 #include "BLI_rect.h"
31 #include "BLI_string.h"
32
33 #include "BIF_glutil.h"
34
35 #include "BKE_depsgraph.h"
36 #include "BKE_global.h"
37 #include "BKE_object.h"
38 #include "BKE_pbvh.h"
39 #include "BKE_paint.h"
40
41 #include "BLT_translation.h"
42 #include "BLF_api.h"
43
44 #include "DRW_engine.h"
45 #include "DRW_render.h"
46
47 #include "DNA_camera_types.h"
48 #include "DNA_view3d_types.h"
49 #include "DNA_screen_types.h"
50 #include "DNA_mesh_types.h"
51 #include "DNA_meshdata_types.h"
52
53 #include "ED_space_api.h"
54 #include "ED_screen.h"
55
56 #include "intern/gpu_codegen.h"
57 #include "GPU_batch.h"
58 #include "GPU_draw.h"
59 #include "GPU_extensions.h"
60 #include "GPU_framebuffer.h"
61 #include "GPU_immediate.h"
62 #include "GPU_lamp.h"
63 #include "GPU_material.h"
64 #include "GPU_shader.h"
65 #include "GPU_texture.h"
66 #include "GPU_uniformbuffer.h"
67 #include "GPU_viewport.h"
68 #include "GPU_matrix.h"
69
70 #include "IMB_colormanagement.h"
71
72 #include "PIL_time.h"
73
74 #include "RE_engine.h"
75
76 #include "UI_interface.h"
77 #include "UI_resources.h"
78
79 #include "draw_manager_text.h"
80
81 /* only for callbacks */
82 #include "draw_cache_impl.h"
83
84 #include "draw_mode_engines.h"
85
86 #include "engines/clay/clay_engine.h"
87 #include "engines/eevee/eevee_engine.h"
88 #include "engines/basic/basic_engine.h"
89 #include "engines/external/external_engine.h"
90
91 #include "DEG_depsgraph.h"
92 #include "DEG_depsgraph_query.h"
93
94 #define MAX_ATTRIB_NAME 32
95 #define MAX_PASS_NAME 32
96
97 /* Use draw manager to call GPU_select, see: DRW_draw_select_loop */
98 #define USE_GPU_SELECT
99
100 #ifdef USE_GPU_SELECT
101 #  include "ED_view3d.h"
102 #  include "ED_armature.h"
103 #  include "GPU_select.h"
104 #endif
105
106 extern char datatoc_gpu_shader_2D_vert_glsl[];
107 extern char datatoc_gpu_shader_3D_vert_glsl[];
108 extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
109
110 /* Prototypes. */
111 static void DRW_engines_enable_external(void);
112
113 /* Structures */
114 typedef enum {
115         DRW_UNIFORM_BOOL,
116         DRW_UNIFORM_SHORT_TO_INT,
117         DRW_UNIFORM_SHORT_TO_FLOAT,
118         DRW_UNIFORM_INT,
119         DRW_UNIFORM_FLOAT,
120         DRW_UNIFORM_TEXTURE,
121         DRW_UNIFORM_BUFFER,
122         DRW_UNIFORM_MAT3,
123         DRW_UNIFORM_MAT4,
124         DRW_UNIFORM_BLOCK
125 } DRWUniformType;
126
127 typedef enum {
128         DRW_ATTRIB_INT,
129         DRW_ATTRIB_FLOAT,
130 } DRWAttribType;
131
132 struct DRWUniform {
133         struct DRWUniform *next, *prev;
134         DRWUniformType type;
135         int location;
136         int length;
137         int arraysize;
138         int bindloc;
139         const void *value;
140 };
141
142 typedef struct DRWAttrib {
143         struct DRWAttrib *next, *prev;
144         char name[MAX_ATTRIB_NAME];
145         int location;
146         int format_id;
147         int size; /* number of component */
148         int type;
149 } DRWAttrib;
150
151 struct DRWInterface {
152         ListBase uniforms;   /* DRWUniform */
153         ListBase attribs;    /* DRWAttrib */
154         int attribs_count;
155         int attribs_stride;
156         int attribs_size[16];
157         int attribs_loc[16];
158         /* matrices locations */
159         int model;
160         int modelinverse;
161         int modelview;
162         int modelviewinverse;
163         int projection;
164         int projectioninverse;
165         int view;
166         int viewinverse;
167         int modelviewprojection;
168         int viewprojection;
169         int viewprojectioninverse;
170         int normal;
171         int worldnormal;
172         int camtexfac;
173         int orcotexfac;
174         int eye;
175         /* Textures */
176         int tex_bind; /* next texture binding point */
177         /* UBO */
178         int ubo_bind; /* next ubo binding point */
179         /* Dynamic batch */
180         Batch *instance_batch; /* contains instances attributes */
181         GLuint instance_vbo; /* same as instance_batch but generated from DRWCalls */
182         int instance_count;
183         VertexFormat vbo_format;
184 };
185
186 struct DRWPass {
187         ListBase shgroups; /* DRWShadingGroup */
188         DRWState state;
189         char name[MAX_PASS_NAME];
190         /* use two query to not stall the cpu waiting for queries to complete */
191         unsigned int timer_queries[2];
192         /* alternate between front and back query */
193         unsigned int front_idx;
194         unsigned int back_idx;
195         bool wasdrawn; /* if it was drawn during this frame */
196 };
197
198 typedef struct DRWCallHeader {
199         void *next, *prev;
200 #ifdef USE_GPU_SELECT
201         int select_id;
202 #endif
203         uchar type;
204 } DRWCallHeader;
205
206 typedef struct DRWCall {
207         DRWCallHeader head;
208
209         float (*obmat)[4];
210         Batch *geometry;
211
212         Object *ob; /* Optionnal */
213 } DRWCall;
214
215 typedef struct DRWCallGenerate {
216         DRWCallHeader head;
217
218         float (*obmat)[4];
219
220         DRWCallGenerateFn *geometry_fn;
221         void *user_data;
222 } DRWCallGenerate;
223
224 typedef struct DRWCallDynamic {
225         DRWCallHeader head;
226
227         const void *data[];
228 } DRWCallDynamic;
229
230 struct DRWShadingGroup {
231         struct DRWShadingGroup *next, *prev;
232
233         GPUShader *shader;               /* Shader to bind */
234         DRWInterface *interface;         /* Uniforms pointers */
235         ListBase calls;                  /* DRWCall or DRWCallDynamic depending of type */
236         DRWState state_extra;            /* State changes for this batch only (or'd with the pass's state) */
237         int type;
238
239         Batch *instance_geom;  /* Geometry to instance */
240         Batch *batch_geom;     /* Result of call batching */
241
242 #ifdef USE_GPU_SELECT
243         /* backlink to pass we're in */
244         DRWPass *pass_parent;
245 #endif
246 };
247
248 /* Used by DRWShadingGroup.type */
249 enum {
250         DRW_SHG_NORMAL,
251         DRW_SHG_POINT_BATCH,
252         DRW_SHG_LINE_BATCH,
253         DRW_SHG_TRIANGLE_BATCH,
254         DRW_SHG_INSTANCE,
255 };
256
257 /* Used by DRWCall.type */
258 enum {
259         /* A single batch */
260         DRW_CALL_SINGLE,
261         /* Uses a callback to draw with any number of batches. */
262         DRW_CALL_GENERATE,
263         /* Arbitrary number of multiple args. */
264         DRW_CALL_DYNAMIC,
265 };
266
267 /* only 16 bits long */
268 enum {
269         STENCIL_SELECT          = (1 << 0),
270         STENCIL_ACTIVE          = (1 << 1),
271 };
272
273 /* Render State */
274 static struct DRWGlobalState {
275         /* Rendering state */
276         GPUShader *shader;
277         ListBase bound_texs;
278         int tex_bind_id;
279
280         /* Managed by `DRW_state_set`, `DRW_state_reset` */
281         DRWState state;
282
283         /* Per viewport */
284         GPUViewport *viewport;
285         struct GPUFrameBuffer *default_framebuffer;
286         float size[2];
287         float screenvecs[2][3];
288         float pixsize;
289
290         struct {
291                 unsigned int is_select : 1;
292                 unsigned int is_depth : 1;
293         } options;
294
295         /* Current rendering context */
296         DRWContextState draw_ctx;
297
298         /* Convenience pointer to text_store owned by the viewport */
299         struct DRWTextStore **text_store_p;
300
301         ListBase enabled_engines; /* RenderEngineType */
302 } DST = {NULL};
303
304 ListBase DRW_engines = {NULL, NULL};
305
306 #ifdef USE_GPU_SELECT
307 static unsigned int g_DRW_select_id = (unsigned int)-1;
308
309 void DRW_select_load_id(unsigned int id)
310 {
311         BLI_assert(G.f & G_PICKSEL);
312         g_DRW_select_id = id;
313 }
314 #endif
315
316
317 /* -------------------------------------------------------------------- */
318
319 /** \name Textures (DRW_texture)
320  * \{ */
321
322 static void drw_texture_get_format(DRWTextureFormat format, GPUTextureFormat *data_type, int *channels)
323 {
324         switch (format) {
325                 case DRW_TEX_RGBA_8: *data_type = GPU_RGBA8; break;
326                 case DRW_TEX_RGBA_16: *data_type = GPU_RGBA16F; break;
327                 case DRW_TEX_RGB_16: *data_type = GPU_RGB16F; break;
328                 case DRW_TEX_RGB_11_11_10: *data_type = GPU_R11F_G11F_B10F; break;
329                 case DRW_TEX_RG_16: *data_type = GPU_RG16F; break;
330                 case DRW_TEX_RG_32: *data_type = GPU_RG32F; break;
331                 case DRW_TEX_R_8: *data_type = GPU_R8; break;
332                 case DRW_TEX_R_16: *data_type = GPU_R16F; break;
333                 case DRW_TEX_R_32: *data_type = GPU_R32F; break;
334 #if 0
335                 case DRW_TEX_RGBA_32: *data_type = GPU_RGBA32F; break;
336                 case DRW_TEX_RGB_8: *data_type = GPU_RGB8; break;
337                 case DRW_TEX_RGB_32: *data_type = GPU_RGB32F; break;
338                 case DRW_TEX_RG_8: *data_type = GPU_RG8; break;
339 #endif
340                 case DRW_TEX_DEPTH_16: *data_type = GPU_DEPTH_COMPONENT16; break;
341                 case DRW_TEX_DEPTH_24: *data_type = GPU_DEPTH_COMPONENT24; break;
342                 case DRW_TEX_DEPTH_32: *data_type = GPU_DEPTH_COMPONENT32F; break;
343                 default :
344                         /* file type not supported you must uncomment it from above */
345                         BLI_assert(false);
346                         break;
347         }
348
349         switch (format) {
350                 case DRW_TEX_RGBA_8:
351                 case DRW_TEX_RGBA_16:
352                 case DRW_TEX_RGBA_32:
353                         *channels = 4;
354                         break;
355                 case DRW_TEX_RGB_8:
356                 case DRW_TEX_RGB_16:
357                 case DRW_TEX_RGB_32:
358                 case DRW_TEX_RGB_11_11_10:
359                         *channels = 3;
360                         break;
361                 case DRW_TEX_RG_8:
362                 case DRW_TEX_RG_16:
363                 case DRW_TEX_RG_32:
364                         *channels = 2;
365                         break;
366                 default:
367                         *channels = 1;
368                         break;
369         }
370 }
371
372 static void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags)
373 {
374         GPU_texture_bind(tex, 0);
375         GPU_texture_filter_mode(tex, flags & DRW_TEX_FILTER);
376         if (flags & DRW_TEX_MIPMAP) {
377                 GPU_texture_mipmap_mode(tex, true);
378                 DRW_texture_generate_mipmaps(tex);
379         }
380         GPU_texture_wrap_mode(tex, flags & DRW_TEX_WRAP);
381         GPU_texture_compare_mode(tex, flags & DRW_TEX_COMPARE);
382         GPU_texture_unbind(tex);
383 }
384
385 GPUTexture *DRW_texture_create_1D(int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
386 {
387         GPUTexture *tex;
388         GPUTextureFormat data_type;
389         int channels;
390
391         drw_texture_get_format(format, &data_type, &channels);
392         tex = GPU_texture_create_1D_custom(w, channels, data_type, fpixels, NULL);
393         drw_texture_set_parameters(tex, flags);
394
395         return tex;
396 }
397
398 GPUTexture *DRW_texture_create_2D(int w, int h, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
399 {
400         GPUTexture *tex;
401         GPUTextureFormat data_type;
402         int channels;
403
404         drw_texture_get_format(format, &data_type, &channels);
405         tex = GPU_texture_create_2D_custom(w, h, channels, data_type, fpixels, NULL);
406         drw_texture_set_parameters(tex, flags);
407
408         return tex;
409 }
410
411 GPUTexture *DRW_texture_create_2D_array(
412         int w, int h, int d, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
413 {
414         GPUTexture *tex;
415         GPUTextureFormat data_type;
416         int channels;
417
418         drw_texture_get_format(format, &data_type, &channels);
419         tex = GPU_texture_create_2D_array_custom(w, h, d, channels, data_type, fpixels, NULL);
420         drw_texture_set_parameters(tex, flags);
421
422         return tex;
423 }
424
425 GPUTexture *DRW_texture_create_cube(int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
426 {
427         GPUTexture *tex;
428         GPUTextureFormat data_type;
429         int channels;
430
431         drw_texture_get_format(format, &data_type, &channels);
432         tex = GPU_texture_create_cube_custom(w, channels, data_type, fpixels, NULL);
433         drw_texture_set_parameters(tex, flags);
434
435         return tex;
436 }
437
438 void DRW_texture_generate_mipmaps(GPUTexture *tex)
439 {
440         GPU_texture_bind(tex, 0);
441         GPU_texture_generate_mipmap(tex);
442         GPU_texture_unbind(tex);
443 }
444
445 void DRW_texture_free(GPUTexture *tex)
446 {
447         GPU_texture_free(tex);
448 }
449
450 /** \} */
451
452
453 /* -------------------------------------------------------------------- */
454
455 /** \name Uniform Buffer Object (DRW_uniformbuffer)
456  * \{ */
457
458 GPUUniformBuffer *DRW_uniformbuffer_create(int size, const void *data)
459 {
460         return GPU_uniformbuffer_create(size, data, NULL);
461 }
462
463 void DRW_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
464 {
465         GPU_uniformbuffer_update(ubo, data);
466 }
467
468 void DRW_uniformbuffer_free(GPUUniformBuffer *ubo)
469 {
470         GPU_uniformbuffer_free(ubo);
471 }
472
473 /** \} */
474
475
476 /* -------------------------------------------------------------------- */
477
478 /** \name Shaders (DRW_shader)
479  * \{ */
480
481 GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, const char *defines)
482 {
483         return GPU_shader_create(vert, frag, geom, NULL, defines);
484 }
485
486 GPUShader *DRW_shader_create_with_lib(
487         const char *vert, const char *geom, const char *frag, const char *lib, const char *defines)
488 {
489         GPUShader *sh;
490         char *vert_with_lib = NULL;
491         char *frag_with_lib = NULL;
492         char *geom_with_lib = NULL;
493
494         DynStr *ds_vert = BLI_dynstr_new();
495         BLI_dynstr_append(ds_vert, lib);
496         BLI_dynstr_append(ds_vert, vert);
497         vert_with_lib = BLI_dynstr_get_cstring(ds_vert);
498         BLI_dynstr_free(ds_vert);
499
500         DynStr *ds_frag = BLI_dynstr_new();
501         BLI_dynstr_append(ds_frag, lib);
502         BLI_dynstr_append(ds_frag, frag);
503         frag_with_lib = BLI_dynstr_get_cstring(ds_frag);
504         BLI_dynstr_free(ds_frag);
505
506         if (geom) {
507                 DynStr *ds_geom = BLI_dynstr_new();
508                 BLI_dynstr_append(ds_geom, lib);
509                 BLI_dynstr_append(ds_geom, geom);
510                 geom_with_lib = BLI_dynstr_get_cstring(ds_geom);
511                 BLI_dynstr_free(ds_geom);
512         }
513
514         sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines);
515
516         MEM_freeN(vert_with_lib);
517         MEM_freeN(frag_with_lib);
518         if (geom) {
519                 MEM_freeN(geom_with_lib);
520         }
521
522         return sh;
523 }
524
525 GPUShader *DRW_shader_create_2D(const char *frag, const char *defines)
526 {
527         return GPU_shader_create(datatoc_gpu_shader_2D_vert_glsl, frag, NULL, NULL, defines);
528 }
529
530 GPUShader *DRW_shader_create_3D(const char *frag, const char *defines)
531 {
532         return GPU_shader_create(datatoc_gpu_shader_3D_vert_glsl, frag, NULL, NULL, defines);
533 }
534
535 GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines)
536 {
537         return GPU_shader_create(datatoc_gpu_shader_fullscreen_vert_glsl, frag, NULL, NULL, defines);
538 }
539
540 GPUShader *DRW_shader_create_3D_depth_only(void)
541 {
542         return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
543 }
544
545 void DRW_shader_free(GPUShader *shader)
546 {
547         GPU_shader_free(shader);
548 }
549
550 /** \} */
551
552
553 /* -------------------------------------------------------------------- */
554
555 /** \name Interface (DRW_interface)
556  * \{ */
557
558 static DRWInterface *DRW_interface_create(GPUShader *shader)
559 {
560         DRWInterface *interface = MEM_mallocN(sizeof(DRWInterface), "DRWInterface");
561
562         interface->model = GPU_shader_get_uniform(shader, "ModelMatrix");
563         interface->modelinverse = GPU_shader_get_uniform(shader, "ModelMatrixInverse");
564         interface->modelview = GPU_shader_get_uniform(shader, "ModelViewMatrix");
565         interface->modelviewinverse = GPU_shader_get_uniform(shader, "ModelViewMatrixInverse");
566         interface->projection = GPU_shader_get_uniform(shader, "ProjectionMatrix");
567         interface->projectioninverse = GPU_shader_get_uniform(shader, "ProjectionMatrixInverse");
568         interface->view = GPU_shader_get_uniform(shader, "ViewMatrix");
569         interface->viewinverse = GPU_shader_get_uniform(shader, "ViewMatrixInverse");
570         interface->viewprojection = GPU_shader_get_uniform(shader, "ViewProjectionMatrix");
571         interface->viewprojectioninverse = GPU_shader_get_uniform(shader, "ViewProjectionMatrixInverse");
572         interface->modelviewprojection = GPU_shader_get_uniform(shader, "ModelViewProjectionMatrix");
573         interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix");
574         interface->worldnormal = GPU_shader_get_uniform(shader, "WorldNormalMatrix");
575         interface->camtexfac = GPU_shader_get_uniform(shader, "CameraTexCoFactors");
576         interface->orcotexfac = GPU_shader_get_uniform(shader, "OrcoTexCoFactors[0]");
577         interface->eye = GPU_shader_get_uniform(shader, "eye");
578         interface->instance_count = 0;
579         interface->attribs_count = 0;
580         interface->attribs_stride = 0;
581         interface->instance_vbo = 0;
582         interface->instance_batch = NULL;
583         interface->tex_bind = GPU_max_textures() - 1;
584         interface->ubo_bind = GPU_max_ubo_binds() - 1;
585
586         memset(&interface->vbo_format, 0, sizeof(VertexFormat));
587
588         BLI_listbase_clear(&interface->uniforms);
589         BLI_listbase_clear(&interface->attribs);
590
591         return interface;
592 }
593
594 #ifdef USE_GPU_SELECT
595 static DRWInterface *DRW_interface_duplicate(DRWInterface *interface_src)
596 {
597         DRWInterface *interface_dst = MEM_dupallocN(interface_src);
598         BLI_duplicatelist(&interface_dst->uniforms, &interface_src->uniforms);
599         BLI_duplicatelist(&interface_dst->attribs, &interface_src->attribs);
600         return interface_dst;
601 }
602 #endif
603
604 static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name,
605                                   DRWUniformType type, const void *value, int length, int arraysize, int bindloc)
606 {
607         DRWUniform *uni = MEM_mallocN(sizeof(DRWUniform), "DRWUniform");
608
609         if (type == DRW_UNIFORM_BLOCK) {
610                 uni->location = GPU_shader_get_uniform_block(shgroup->shader, name);
611         }
612         else {
613                 uni->location = GPU_shader_get_uniform(shgroup->shader, name);
614         }
615
616         BLI_assert(arraysize > 0);
617
618         uni->type = type;
619         uni->value = value;
620         uni->length = length;
621         uni->arraysize = arraysize;
622         uni->bindloc = bindloc; /* for textures */
623
624         if (uni->location == -1) {
625                 if (G.debug & G_DEBUG)
626                         fprintf(stderr, "Uniform '%s' not found!\n", name);
627                 /* Nice to enable eventually, for now eevee uses uniforms that might not exist. */
628                 // BLI_assert(0);
629                 MEM_freeN(uni);
630                 return;
631         }
632
633         BLI_addtail(&shgroup->interface->uniforms, uni);
634 }
635
636 static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType type, int size, bool dummy)
637 {
638         DRWAttrib *attrib = MEM_mallocN(sizeof(DRWAttrib), "DRWAttrib");
639         GLuint program = GPU_shader_get_program(shgroup->shader);
640
641         attrib->location = glGetAttribLocation(program, name);
642         attrib->type = type;
643         attrib->size = size;
644
645         if (attrib->location == -1 && !dummy) {
646                 if (G.debug & G_DEBUG)
647                         fprintf(stderr, "Attribute '%s' not found!\n", name);
648                 BLI_assert(0);
649                 MEM_freeN(attrib);
650                 return;
651         }
652
653         BLI_assert(BLI_strnlen(name, 32) < 32);
654         BLI_strncpy(attrib->name, name, 32);
655
656         shgroup->interface->attribs_count += 1;
657
658         BLI_addtail(&shgroup->interface->attribs, attrib);
659 }
660
661 /** \} */
662
663
664 /* -------------------------------------------------------------------- */
665
666 /** \name Shading Group (DRW_shgroup)
667  * \{ */
668
669 DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
670 {
671         DRWShadingGroup *shgroup = MEM_mallocN(sizeof(DRWShadingGroup), "DRWShadingGroup");
672
673         shgroup->type = DRW_SHG_NORMAL;
674         shgroup->shader = shader;
675         shgroup->interface = DRW_interface_create(shader);
676         shgroup->state_extra = 0;
677         shgroup->batch_geom = NULL;
678         shgroup->instance_geom = NULL;
679
680         BLI_addtail(&pass->shgroups, shgroup);
681         BLI_listbase_clear(&shgroup->calls);
682
683 #ifdef USE_GPU_SELECT
684         shgroup->pass_parent = pass;
685 #endif
686
687         return shgroup;
688 }
689
690 DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
691 {
692         double time = 0.0; /* TODO make time variable */
693
694         /* TODO : Ideally we should not convert. But since the whole codegen
695          * is relying on GPUPass we keep it as is for now. */
696         GPUPass *gpupass = GPU_material_get_pass(material);
697
698         if (!gpupass) {
699                 /* Shader compilation error */
700                 return NULL;
701         }
702
703         struct GPUShader *shader = GPU_pass_shader(gpupass);
704
705         DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
706
707         /* Converting dynamic GPUInput to DRWUniform */
708         ListBase *inputs = &gpupass->inputs;
709
710         for (GPUInput *input = inputs->first; input; input = input->next) {
711                 /* Textures */
712                 if (input->ima) {
713                         GPUTexture *tex = GPU_texture_from_blender(input->ima, input->iuser, input->textarget, input->image_isdata, time, 1);
714
715                         if (input->bindtex) {
716                                 DRW_shgroup_uniform_texture(grp, input->shadername, tex);
717                         }
718                 }
719                 /* Color Ramps */
720                 else if (input->tex) {
721                         DRW_shgroup_uniform_texture(grp, input->shadername, input->tex);
722                 }
723                 /* Floats */
724                 else {
725                         switch (input->type) {
726                                 case 1:
727                                         DRW_shgroup_uniform_float(grp, input->shadername, (float *)input->dynamicvec, 1);
728                                         break;
729                                 case 2:
730                                         DRW_shgroup_uniform_vec2(grp, input->shadername, (float *)input->dynamicvec, 1);
731                                         break;
732                                 case 3:
733                                         DRW_shgroup_uniform_vec3(grp, input->shadername, (float *)input->dynamicvec, 1);
734                                         break;
735                                 case 4:
736                                         DRW_shgroup_uniform_vec4(grp, input->shadername, (float *)input->dynamicvec, 1);
737                                         break;
738                                 case 9:
739                                         DRW_shgroup_uniform_mat3(grp, input->shadername, (float *)input->dynamicvec);
740                                         break;
741                                 case 16:
742                                         DRW_shgroup_uniform_mat4(grp, input->shadername, (float *)input->dynamicvec);
743                                         break;
744                                 default:
745                                         break;
746                         }
747                 }
748         }
749
750         return grp;
751 }
752
753 DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material, DRWPass *pass, Batch *geom)
754 {
755         DRWShadingGroup *shgroup = DRW_shgroup_material_create(material, pass);
756
757         if (shgroup) {
758                 shgroup->type = DRW_SHG_INSTANCE;
759                 shgroup->instance_geom = geom;
760         }
761
762         return shgroup;
763 }
764
765 DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, Batch *geom)
766 {
767         DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
768
769         shgroup->type = DRW_SHG_INSTANCE;
770         shgroup->instance_geom = geom;
771
772         return shgroup;
773 }
774
775 DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass)
776 {
777         DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
778
779         shgroup->type = DRW_SHG_POINT_BATCH;
780         DRW_shgroup_attrib_float(shgroup, "pos", 3);
781
782         return shgroup;
783 }
784
785 DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass)
786 {
787         DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
788
789         shgroup->type = DRW_SHG_LINE_BATCH;
790         DRW_shgroup_attrib_float(shgroup, "pos", 3);
791
792         return shgroup;
793 }
794
795 /* Very special batch. Use this if you position
796  * your vertices with the vertex shader
797  * and dont need any VBO attrib */
798 DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size)
799 {
800         DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
801
802         shgroup->type = DRW_SHG_TRIANGLE_BATCH;
803         shgroup->interface->instance_count = size * 3;
804         DRW_interface_attrib(shgroup, "dummy", DRW_ATTRIB_FLOAT, 1, true);
805
806         return shgroup;
807 }
808
809 void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
810 {
811         BLI_freelistN(&shgroup->calls);
812         BLI_freelistN(&shgroup->interface->uniforms);
813         BLI_freelistN(&shgroup->interface->attribs);
814
815         if (shgroup->interface->instance_vbo &&
816                 (shgroup->interface->instance_batch == 0))
817         {
818                 glDeleteBuffers(1, &shgroup->interface->instance_vbo);
819         }
820
821         MEM_freeN(shgroup->interface);
822
823         BATCH_DISCARD_ALL_SAFE(shgroup->batch_geom);
824 }
825
826 void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Batch *instances)
827 {
828         BLI_assert(shgroup->type == DRW_SHG_INSTANCE);
829         BLI_assert(shgroup->interface->instance_batch == NULL);
830
831         shgroup->interface->instance_batch = instances;
832 }
833
834 void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[4])
835 {
836         BLI_assert(geom != NULL);
837
838         DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
839
840         call->head.type = DRW_CALL_SINGLE;
841 #ifdef USE_GPU_SELECT
842         call->head.select_id = g_DRW_select_id;
843 #endif
844
845         call->obmat = obmat;
846         call->geometry = geom;
847
848         BLI_addtail(&shgroup->calls, call);
849 }
850
851 void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Batch *geom, Object *ob)
852 {
853         BLI_assert(geom != NULL);
854
855         DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
856
857         call->head.type = DRW_CALL_SINGLE;
858 #ifdef USE_GPU_SELECT
859         call->head.select_id = g_DRW_select_id;
860 #endif
861
862         call->obmat = ob->obmat;
863         call->geometry = geom;
864         call->ob = ob;
865
866         BLI_addtail(&shgroup->calls, call);
867 }
868
869 void DRW_shgroup_call_generate_add(
870         DRWShadingGroup *shgroup,
871         DRWCallGenerateFn *geometry_fn, void *user_data,
872         float (*obmat)[4])
873 {
874         BLI_assert(geometry_fn != NULL);
875
876         DRWCallGenerate *call = MEM_callocN(sizeof(DRWCallGenerate), "DRWCallGenerate");
877
878         call->head.type = DRW_CALL_GENERATE;
879 #ifdef USE_GPU_SELECT
880         call->head.select_id = g_DRW_select_id;
881 #endif
882
883         call->obmat = obmat;
884
885         call->geometry_fn = geometry_fn;
886         call->user_data = user_data;
887
888         BLI_addtail(&shgroup->calls, call);
889 }
890
891 static void sculpt_draw_cb(
892         DRWShadingGroup *shgroup,
893         void (*draw_fn)(DRWShadingGroup *shgroup, Batch *geom),
894         void *user_data)
895 {
896         Object *ob = user_data;
897         PBVH *pbvh = ob->sculpt->pbvh;
898
899         if (pbvh) {
900                 BKE_pbvh_draw_cb(
901                         pbvh, NULL, NULL, false,
902                         (void (*)(void *, Batch *))draw_fn, shgroup);
903         }
904 }
905
906 void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, Object *ob, float (*obmat)[4])
907 {
908         DRW_shgroup_call_generate_add(shgroup, sculpt_draw_cb, ob, obmat);
909 }
910
911 void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *attr[], unsigned int attr_len)
912 {
913         DRWInterface *interface = shgroup->interface;
914
915 #ifdef USE_GPU_SELECT
916         if ((G.f & G_PICKSEL) && (interface->instance_count > 0)) {
917                 shgroup = MEM_dupallocN(shgroup);
918                 BLI_listbase_clear(&shgroup->calls);
919
920                 shgroup->interface = interface = DRW_interface_duplicate(interface);
921                 interface->instance_count = 0;
922
923                 BLI_addtail(&shgroup->pass_parent->shgroups, shgroup);
924         }
925 #endif
926
927         unsigned int data_size = sizeof(void *) * interface->attribs_count;
928         int size = sizeof(DRWCallDynamic) + data_size;
929
930         DRWCallDynamic *call = MEM_callocN(size, "DRWCallDynamic");
931
932         BLI_assert(attr_len == interface->attribs_count);
933         UNUSED_VARS_NDEBUG(attr_len);
934
935         call->head.type = DRW_CALL_DYNAMIC;
936 #ifdef USE_GPU_SELECT
937         call->head.select_id = g_DRW_select_id;
938 #endif
939
940         if (data_size != 0) {
941                 memcpy((void *)call->data, attr, data_size);
942         }
943
944         interface->instance_count += 1;
945
946         BLI_addtail(&shgroup->calls, call);
947 }
948
949 /* Used for instancing with no attributes */
950 void DRW_shgroup_set_instance_count(DRWShadingGroup *shgroup, int count)
951 {
952         DRWInterface *interface = shgroup->interface;
953
954         BLI_assert(interface->attribs_count == 0);
955
956         interface->instance_count = count;
957 }
958
959 /**
960  * State is added to #Pass.state while drawing.
961  * Use to temporarily enable draw options.
962  *
963  * Currently there is no way to disable (could add if needed).
964  */
965 void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state)
966 {
967         shgroup->state_extra |= state;
968 }
969
970 void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size)
971 {
972         DRW_interface_attrib(shgroup, name, DRW_ATTRIB_FLOAT, size, false);
973 }
974
975 void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
976 {
977         DRWInterface *interface = shgroup->interface;
978
979         if (interface->tex_bind < 0) {
980                 /* TODO alert user */
981                 printf("Not enough texture slot for %s\n", name);
982                 return;
983         }
984
985         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 1, interface->tex_bind--);
986 }
987
988 void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuffer *ubo)
989 {
990         DRWInterface *interface = shgroup->interface;
991
992         /* Be carefull: there is also a limit per shader stage. Usually 1/3 of normal limit. */
993         if (interface->ubo_bind < 0) {
994                 /* TODO alert user */
995                 printf("Not enough ubo slots for %s\n", name);
996                 return;
997         }
998
999         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 1, interface->ubo_bind--);
1000 }
1001
1002 void DRW_shgroup_uniform_buffer(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
1003 {
1004         DRWInterface *interface = shgroup->interface;
1005
1006         if (interface->tex_bind < 0) {
1007                 /* TODO alert user */
1008                 printf("Not enough texture slot for %s\n", name);
1009                 return;
1010         }
1011
1012         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BUFFER, tex, 0, 1, interface->tex_bind--);
1013 }
1014
1015 void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const bool *value, int arraysize)
1016 {
1017         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BOOL, value, 1, arraysize, 0);
1018 }
1019
1020 void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
1021 {
1022         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 1, arraysize, 0);
1023 }
1024
1025 void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
1026 {
1027         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 2, arraysize, 0);
1028 }
1029
1030 void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
1031 {
1032         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 3, arraysize, 0);
1033 }
1034
1035 void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
1036 {
1037         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 4, arraysize, 0);
1038 }
1039
1040 void DRW_shgroup_uniform_short_to_int(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize)
1041 {
1042         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_INT, value, 1, arraysize, 0);
1043 }
1044
1045 void DRW_shgroup_uniform_short_to_float(DRWShadingGroup *shgroup, const char *name, const short *value, int arraysize)
1046 {
1047         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_SHORT_TO_FLOAT, value, 1, arraysize, 0);
1048 }
1049
1050 void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
1051 {
1052         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 1, arraysize, 0);
1053 }
1054
1055 void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
1056 {
1057         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 2, arraysize, 0);
1058 }
1059
1060 void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
1061 {
1062         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 3, arraysize, 0);
1063 }
1064
1065 void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float *value)
1066 {
1067         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT3, value, 9, 1, 0);
1068 }
1069
1070 void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float *value)
1071 {
1072         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1, 0);
1073 }
1074
1075 /* Creates a VBO containing OGL primitives for all DRWCallDynamic */
1076 static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
1077 {
1078         DRWInterface *interface = shgroup->interface;
1079         int nbr = interface->instance_count;
1080
1081         PrimitiveType type = (shgroup->type == DRW_SHG_POINT_BATCH) ? PRIM_POINTS :
1082                              (shgroup->type == DRW_SHG_TRIANGLE_BATCH) ? PRIM_TRIANGLES : PRIM_LINES;
1083
1084         if (nbr == 0)
1085                 return;
1086
1087         /* Upload Data */
1088         if (interface->vbo_format.attrib_ct == 0) {
1089                 for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next) {
1090                         BLI_assert(attrib->size <= 4); /* matrices have no place here for now */
1091                         if (attrib->type == DRW_ATTRIB_FLOAT) {
1092                                 attrib->format_id = VertexFormat_add_attrib(
1093                                         &interface->vbo_format, attrib->name, COMP_F32, attrib->size, KEEP_FLOAT);
1094                         }
1095                         else if (attrib->type == DRW_ATTRIB_INT) {
1096                                 attrib->format_id = VertexFormat_add_attrib(
1097                                         &interface->vbo_format, attrib->name, COMP_I8, attrib->size, KEEP_INT);
1098                         }
1099                         else {
1100                                 BLI_assert(false);
1101                         }
1102                 }
1103         }
1104
1105         VertexBuffer *vbo = VertexBuffer_create_with_format(&interface->vbo_format);
1106         VertexBuffer_allocate_data(vbo, nbr);
1107
1108         int j = 0;
1109         for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next, j++) {
1110                 int i = 0;
1111                 for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
1112                         VertexBuffer_set_attrib(vbo, attrib->format_id, j, call->data[i]);
1113                 }
1114         }
1115
1116         /* TODO make the batch dynamic instead of freeing it every times */
1117         if (shgroup->batch_geom)
1118                 Batch_discard_all(shgroup->batch_geom);
1119
1120         shgroup->batch_geom = Batch_create(type, vbo, NULL);
1121 }
1122
1123 static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
1124 {
1125         int i = 0;
1126         int offset = 0;
1127         DRWInterface *interface = shgroup->interface;
1128         int buffer_size = 0;
1129
1130         /* XXX All of this is pretty garbage. Better revisit it later. */
1131         if (interface->instance_batch != NULL) {
1132                 VertexBuffer *vert = interface->instance_batch->verts[0];
1133                 /* This is double check but we don't want
1134                  * VertexBuffer_use() to bind the buffer if it exists. */
1135                 if (vert->vbo_id == 0) {
1136                         VertexBuffer_use(vert);
1137                 }
1138                 interface->instance_vbo = vert->vbo_id;
1139                 interface->instance_count = vert->vertex_ct;
1140         }
1141
1142         if (interface->instance_count == 0) {
1143                 if (interface->instance_vbo) {
1144                         glDeleteBuffers(1, &interface->instance_vbo);
1145                         interface->instance_vbo = 0;
1146                 }
1147                 return;
1148         }
1149
1150         /* only once */
1151         if (interface->attribs_stride == 0) {
1152                 for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
1153                         BLI_assert(attrib->type == DRW_ATTRIB_FLOAT); /* Only float for now */
1154                         interface->attribs_stride += attrib->size;
1155                         interface->attribs_size[i] = attrib->size;
1156                         interface->attribs_loc[i] = attrib->location;
1157                 }
1158         }
1159
1160         if (interface->instance_batch != NULL) {
1161                 /* Quit just after attribs where specified */
1162                 return;
1163         }
1164
1165         /* Gather Data */
1166         buffer_size = sizeof(float) * interface->attribs_stride * interface->instance_count;
1167         float *data = MEM_mallocN(buffer_size, "Instance VBO data");
1168
1169         for (DRWCallDynamic *call = shgroup->calls.first; call; call = call->head.next) {
1170                 for (int j = 0; j < interface->attribs_count; ++j) {
1171                         memcpy(data + offset, call->data[j], sizeof(float) * interface->attribs_size[j]);
1172                         offset += interface->attribs_size[j];
1173                 }
1174         }
1175
1176         /* TODO poke mike to add this to gawain */
1177         if (interface->instance_vbo) {
1178                 glDeleteBuffers(1, &interface->instance_vbo);
1179                 interface->instance_vbo = 0;
1180         }
1181
1182         glGenBuffers(1, &interface->instance_vbo);
1183         glBindBuffer(GL_ARRAY_BUFFER, interface->instance_vbo);
1184         glBufferData(GL_ARRAY_BUFFER, buffer_size, data, GL_STATIC_DRAW);
1185
1186         MEM_freeN(data);
1187 }
1188
1189 static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup)
1190 {
1191         if ((shgroup->interface->instance_vbo || shgroup->batch_geom) &&
1192             (G.debug_value == 667))
1193         {
1194                 return;
1195         }
1196
1197         if (shgroup->type == DRW_SHG_INSTANCE) {
1198                 shgroup_dynamic_instance(shgroup);
1199         }
1200         else {
1201                 shgroup_dynamic_batch(shgroup);
1202         }
1203 }
1204
1205 /** \} */
1206
1207
1208 /* -------------------------------------------------------------------- */
1209
1210 /** \name Passes (DRW_pass)
1211  * \{ */
1212
1213 DRWPass *DRW_pass_create(const char *name, DRWState state)
1214 {
1215         DRWPass *pass = MEM_callocN(sizeof(DRWPass), name);
1216         pass->state = state;
1217         BLI_strncpy(pass->name, name, MAX_PASS_NAME);
1218
1219         BLI_listbase_clear(&pass->shgroups);
1220
1221         return pass;
1222 }
1223
1224 void DRW_pass_free(DRWPass *pass)
1225 {
1226         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
1227                 DRW_shgroup_free(shgroup);
1228         }
1229
1230         glDeleteQueries(2, pass->timer_queries);
1231         BLI_freelistN(&pass->shgroups);
1232 }
1233
1234 void DRW_pass_foreach_shgroup(DRWPass *pass, void (*callback)(void *userData, DRWShadingGroup *shgrp), void *userData)
1235 {
1236         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
1237                 callback(userData, shgroup);
1238         }
1239 }
1240
1241 /** \} */
1242
1243
1244 /* -------------------------------------------------------------------- */
1245
1246 /** \name Draw (DRW_draw)
1247  * \{ */
1248
1249 static void DRW_state_set(DRWState state)
1250 {
1251         if (DST.state == state) {
1252                 return;
1253         }
1254
1255
1256 #define CHANGED_TO(f) \
1257         ((DST.state & (f)) ? \
1258                 ((state & (f)) ?  0 : -1) : \
1259                 ((state & (f)) ?  1 :  0))
1260
1261 #define CHANGED_ANY(f) \
1262         ((DST.state & (f)) != (state & (f)))
1263
1264 #define CHANGED_ANY_STORE_VAR(f, enabled) \
1265         ((DST.state & (f)) != (enabled = (state & (f))))
1266
1267         /* Depth Write */
1268         {
1269                 int test;
1270                 if ((test = CHANGED_TO(DRW_STATE_WRITE_DEPTH))) {
1271                         if (test == 1) {
1272                                 glDepthMask(GL_TRUE);
1273                         }
1274                         else {
1275                                 glDepthMask(GL_FALSE);
1276                         }
1277                 }
1278         }
1279
1280         /* Color Write */
1281         {
1282                 int test;
1283                 if ((test = CHANGED_TO(DRW_STATE_WRITE_COLOR))) {
1284                         if (test == 1) {
1285                                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1286                         }
1287                         else {
1288                                 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1289                         }
1290                 }
1291         }
1292
1293         /* Cull */
1294         {
1295                 DRWState test;
1296                 if (CHANGED_ANY_STORE_VAR(
1297                         DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT,
1298                         test))
1299                 {
1300                         if (test) {
1301                                 glEnable(GL_CULL_FACE);
1302
1303                                 if ((state & DRW_STATE_CULL_BACK) != 0) {
1304                                         glCullFace(GL_BACK);
1305                                 }
1306                                 else if ((state & DRW_STATE_CULL_FRONT) != 0) {
1307                                         glCullFace(GL_FRONT);
1308                                 }
1309                                 else {
1310                                         BLI_assert(0);
1311                                 }
1312                         }
1313                         else {
1314                                 glDisable(GL_CULL_FACE);
1315                         }
1316                 }
1317         }
1318
1319         /* Depth Test */
1320         {
1321                 DRWState test;
1322                 if (CHANGED_ANY_STORE_VAR(
1323                         DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER,
1324                         test))
1325                 {
1326                         if (test) {
1327                                 glEnable(GL_DEPTH_TEST);
1328
1329                                 if (state & DRW_STATE_DEPTH_LESS) {
1330                                         glDepthFunc(GL_LEQUAL);
1331                                 }
1332                                 else if (state & DRW_STATE_DEPTH_EQUAL) {
1333                                         glDepthFunc(GL_EQUAL);
1334                                 }
1335                                 else if (state & DRW_STATE_DEPTH_GREATER) {
1336                                         glDepthFunc(GL_GREATER);
1337                                 }
1338                                 else {
1339                                         BLI_assert(0);
1340                                 }
1341                         }
1342                         else {
1343                                 glDisable(GL_DEPTH_TEST);
1344                         }
1345                 }
1346         }
1347
1348         /* Wire Width */
1349         {
1350                 if (CHANGED_ANY(DRW_STATE_WIRE | DRW_STATE_WIRE_LARGE)) {
1351                         if ((state & DRW_STATE_WIRE) != 0) {
1352                                 glLineWidth(1.0f);
1353                         }
1354                         else if ((state & DRW_STATE_WIRE_LARGE) != 0) {
1355                                 glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
1356                         }
1357                         else {
1358                                 /* do nothing */
1359                         }
1360                 }
1361         }
1362
1363         /* Points Size */
1364         {
1365                 int test;
1366                 if ((test = CHANGED_TO(DRW_STATE_POINT))) {
1367                         if (test == 1) {
1368                                 GPU_enable_program_point_size();
1369                                 glPointSize(5.0f);
1370                         }
1371                         else {
1372                                 GPU_disable_program_point_size();
1373                         }
1374                 }
1375         }
1376
1377         /* Blending (all buffer) */
1378         {
1379                 int test;
1380                 if (CHANGED_ANY_STORE_VAR(
1381                         DRW_STATE_BLEND | DRW_STATE_ADDITIVE | DRW_STATE_MULTIPLY,
1382                         test))
1383                 {
1384                         if (test) {
1385                                 glEnable(GL_BLEND);
1386
1387                                 if ((state & DRW_STATE_BLEND) != 0) {
1388                                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1389                                 }
1390                                 else if ((state & DRW_STATE_MULTIPLY) != 0) {
1391                                         glBlendFunc(GL_DST_COLOR, GL_ZERO);
1392                                 }
1393                                 else if ((state & DRW_STATE_ADDITIVE) != 0) {
1394                                         glBlendFunc(GL_ONE, GL_ONE);
1395                                 }
1396                                 else {
1397                                         BLI_assert(0);
1398                                 }
1399                         }
1400                         else {
1401                                 glDisable(GL_BLEND);
1402                         }
1403                 }
1404         }
1405
1406         /* Line Stipple */
1407         {
1408                 int test;
1409                 if (CHANGED_ANY_STORE_VAR(
1410                         DRW_STATE_STIPPLE_2 | DRW_STATE_STIPPLE_3 | DRW_STATE_STIPPLE_4,
1411                         test))
1412                 {
1413                         if (test) {
1414                                 if ((state & DRW_STATE_STIPPLE_2) != 0) {
1415                                         setlinestyle(2);
1416                                 }
1417                                 else if ((state & DRW_STATE_STIPPLE_3) != 0) {
1418                                         setlinestyle(3);
1419                                 }
1420                                 else if ((state & DRW_STATE_STIPPLE_4) != 0) {
1421                                         setlinestyle(4);
1422                                 }
1423                                 else {
1424                                         BLI_assert(0);
1425                                 }
1426                         }
1427                         else {
1428                                 setlinestyle(0);
1429                         }
1430                 }
1431         }
1432
1433         /* Stencil */
1434         {
1435                 DRWState test;
1436                 if (CHANGED_ANY_STORE_VAR(
1437                         DRW_STATE_WRITE_STENCIL_SELECT |
1438                         DRW_STATE_WRITE_STENCIL_ACTIVE |
1439                         DRW_STATE_TEST_STENCIL_SELECT |
1440                         DRW_STATE_TEST_STENCIL_ACTIVE,
1441                         test))
1442                 {
1443                         if (test) {
1444                                 glEnable(GL_STENCIL_TEST);
1445
1446                                 /* Stencil Write */
1447                                 if ((state & DRW_STATE_WRITE_STENCIL_SELECT) != 0) {
1448                                         glStencilMask(STENCIL_SELECT);
1449                                         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1450                                         glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_SELECT);
1451                                 }
1452                                 else if ((state & DRW_STATE_WRITE_STENCIL_ACTIVE) != 0) {
1453                                         glStencilMask(STENCIL_ACTIVE);
1454                                         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1455                                         glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_ACTIVE);
1456                                 }
1457                                 /* Stencil Test */
1458                                 else if ((state & DRW_STATE_TEST_STENCIL_SELECT) != 0) {
1459                                         glStencilMask(0x00); /* disable write */
1460                                         glStencilFunc(GL_NOTEQUAL, 0xFF, STENCIL_SELECT);
1461                                 }
1462                                 else if ((state & DRW_STATE_TEST_STENCIL_ACTIVE) != 0) {
1463                                         glStencilMask(0x00); /* disable write */
1464                                         glStencilFunc(GL_NOTEQUAL, 0xFF, STENCIL_ACTIVE);
1465                                 }
1466                                 else {
1467                                         BLI_assert(0);
1468                                 }
1469                         }
1470                         else {
1471                                 /* disable write & test */
1472                                 glStencilMask(0x00);
1473                                 glStencilFunc(GL_ALWAYS, 1, 0xFF);
1474                                 glDisable(GL_STENCIL_TEST);
1475                         }
1476                 }
1477         }
1478
1479 #undef CHANGED_TO
1480 #undef CHANGED_ANY
1481 #undef CHANGED_ANY_STORE_VAR
1482
1483         DST.state = state;
1484 }
1485
1486 typedef struct DRWBoundTexture {
1487         struct DRWBoundTexture *next, *prev;
1488         GPUTexture *tex;
1489 } DRWBoundTexture;
1490
1491 static void draw_geometry_prepare(
1492         DRWShadingGroup *shgroup, const float (*obmat)[4], const float *texcoloc, const float *texcosize)
1493 {
1494         RegionView3D *rv3d = DST.draw_ctx.rv3d;
1495         DRWInterface *interface = shgroup->interface;
1496
1497         float mvp[4][4], mv[4][4], mi[4][4], mvi[4][4], pi[4][4], n[3][3], wn[3][3];
1498         float orcofacs[2][3] = {{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}};
1499         float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
1500
1501         bool do_pi = (interface->projectioninverse != -1);
1502         bool do_mvp = (interface->modelviewprojection != -1);
1503         bool do_mi = (interface->modelinverse != -1);
1504         bool do_mv = (interface->modelview != -1);
1505         bool do_mvi = (interface->modelviewinverse != -1);
1506         bool do_n = (interface->normal != -1);
1507         bool do_wn = (interface->worldnormal != -1);
1508         bool do_eye = (interface->eye != -1);
1509         bool do_orco = (interface->orcotexfac != -1) && (texcoloc != NULL) && (texcosize != NULL);
1510
1511         if (do_pi) {
1512                 invert_m4_m4(pi, rv3d->winmat);
1513         }
1514         if (do_mi) {
1515                 invert_m4_m4(mi, obmat);
1516         }
1517         if (do_mvp) {
1518                 mul_m4_m4m4(mvp, rv3d->persmat, obmat);
1519         }
1520         if (do_mv || do_mvi || do_n || do_eye) {
1521                 mul_m4_m4m4(mv, rv3d->viewmat, obmat);
1522         }
1523         if (do_mvi) {
1524                 invert_m4_m4(mvi, mv);
1525         }
1526         if (do_n || do_eye) {
1527                 copy_m3_m4(n, mv);
1528                 invert_m3(n);
1529                 transpose_m3(n);
1530         }
1531         if (do_wn) {
1532                 copy_m3_m4(wn, obmat);
1533                 invert_m3(wn);
1534                 transpose_m3(wn);
1535         }
1536         if (do_eye) {
1537                 /* Used by orthographic wires */
1538                 float tmp[3][3];
1539                 invert_m3_m3(tmp, n);
1540                 /* set eye vector, transformed to object coords */
1541                 mul_m3_v3(tmp, eye);
1542         }
1543         if (do_orco) {
1544                 mul_v3_v3fl(orcofacs[1], texcosize, 2.0f);
1545                 invert_v3(orcofacs[1]);
1546                 sub_v3_v3v3(orcofacs[0], texcoloc, texcosize);
1547                 negate_v3(orcofacs[0]);
1548                 mul_v3_v3(orcofacs[0], orcofacs[1]); /* result in a nice MADD in the shader */
1549         }
1550
1551         /* Should be really simple */
1552         /* step 1 : bind object dependent matrices */
1553         if (interface->model != -1) {
1554                 GPU_shader_uniform_vector(shgroup->shader, interface->model, 16, 1, (float *)obmat);
1555         }
1556         if (interface->modelinverse != -1) {
1557                 GPU_shader_uniform_vector(shgroup->shader, interface->modelinverse, 16, 1, (float *)mi);
1558         }
1559         if (interface->modelviewprojection != -1) {
1560                 GPU_shader_uniform_vector(shgroup->shader, interface->modelviewprojection, 16, 1, (float *)mvp);
1561         }
1562         if (interface->viewinverse != -1) {
1563                 GPU_shader_uniform_vector(shgroup->shader, interface->viewinverse, 16, 1, (float *)rv3d->viewinv);
1564         }
1565         if (interface->viewprojection != -1) {
1566                 GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)rv3d->persmat);
1567         }
1568         if (interface->viewprojectioninverse != -1) {
1569                 GPU_shader_uniform_vector(shgroup->shader, interface->viewprojectioninverse, 16, 1, (float *)rv3d->persinv);
1570         }
1571         if (interface->projection != -1) {
1572                 GPU_shader_uniform_vector(shgroup->shader, interface->projection, 16, 1, (float *)rv3d->winmat);
1573         }
1574         if (interface->projectioninverse != -1) {
1575                 GPU_shader_uniform_vector(shgroup->shader, interface->projectioninverse, 16, 1, (float *)pi);
1576         }
1577         if (interface->view != -1) {
1578                 GPU_shader_uniform_vector(shgroup->shader, interface->view, 16, 1, (float *)rv3d->viewmat);
1579         }
1580         if (interface->modelview != -1) {
1581                 GPU_shader_uniform_vector(shgroup->shader, interface->modelview, 16, 1, (float *)mv);
1582         }
1583         if (interface->modelviewinverse != -1) {
1584                 GPU_shader_uniform_vector(shgroup->shader, interface->modelviewinverse, 16, 1, (float *)mvi);
1585         }
1586         if (interface->normal != -1) {
1587                 GPU_shader_uniform_vector(shgroup->shader, interface->normal, 9, 1, (float *)n);
1588         }
1589         if (interface->worldnormal != -1) {
1590                 GPU_shader_uniform_vector(shgroup->shader, interface->worldnormal, 9, 1, (float *)wn);
1591         }
1592         if (interface->camtexfac != -1) {
1593                 GPU_shader_uniform_vector(shgroup->shader, interface->camtexfac, 4, 1, (float *)rv3d->viewcamtexcofac);
1594         }
1595         if (interface->orcotexfac != -1) {
1596                 GPU_shader_uniform_vector(shgroup->shader, interface->orcotexfac, 3, 2, (float *)orcofacs);
1597         }
1598         if (interface->eye != -1) {
1599                 GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye);
1600         }
1601 }
1602
1603 static void draw_geometry_execute(DRWShadingGroup *shgroup, Batch *geom)
1604 {
1605         DRWInterface *interface = shgroup->interface;
1606         /* step 2 : bind vertex array & draw */
1607         Batch_set_program(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
1608         if (interface->instance_vbo) {
1609                 Batch_draw_stupid_instanced(geom, interface->instance_vbo, interface->instance_count, interface->attribs_count,
1610                                             interface->attribs_stride, interface->attribs_size, interface->attribs_loc);
1611         }
1612         else {
1613                 Batch_draw_stupid(geom);
1614         }
1615 }
1616
1617 static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*obmat)[4], Object *ob)
1618 {
1619         float *texcoloc = NULL;
1620         float *texcosize = NULL;
1621
1622         if (ob != NULL) {
1623                 BKE_object_obdata_texspace_get(ob, NULL, &texcoloc, &texcosize, NULL);
1624         }
1625
1626         draw_geometry_prepare(shgroup, obmat, texcoloc, texcosize);
1627
1628         draw_geometry_execute(shgroup, geom);
1629 }
1630
1631 static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
1632 {
1633         BLI_assert(shgroup->shader);
1634         BLI_assert(shgroup->interface);
1635
1636         DRWInterface *interface = shgroup->interface;
1637         GPUTexture *tex;
1638         int val;
1639         float fval;
1640
1641         if (DST.shader != shgroup->shader) {
1642                 if (DST.shader) GPU_shader_unbind();
1643                 GPU_shader_bind(shgroup->shader);
1644                 DST.shader = shgroup->shader;
1645         }
1646
1647         const bool is_normal = ELEM(shgroup->type, DRW_SHG_NORMAL);
1648
1649         if (!is_normal) {
1650                 shgroup_dynamic_batch_from_calls(shgroup);
1651         }
1652
1653         DRW_state_set(pass_state | shgroup->state_extra);
1654
1655         /* Binding Uniform */
1656         /* Don't check anything, Interface should already contain the least uniform as possible */
1657         for (DRWUniform *uni = interface->uniforms.first; uni; uni = uni->next) {
1658                 DRWBoundTexture *bound_tex;
1659
1660                 switch (uni->type) {
1661                         case DRW_UNIFORM_SHORT_TO_INT:
1662                                 val = (int)*((short *)uni->value);
1663                                 GPU_shader_uniform_vector_int(
1664                                         shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)&val);
1665                                 break;
1666                         case DRW_UNIFORM_SHORT_TO_FLOAT:
1667                                 fval = (float)*((short *)uni->value);
1668                                 GPU_shader_uniform_vector(
1669                                         shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)&fval);
1670                                 break;
1671                         case DRW_UNIFORM_BOOL:
1672                         case DRW_UNIFORM_INT:
1673                                 GPU_shader_uniform_vector_int(
1674                                         shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)uni->value);
1675                                 break;
1676                         case DRW_UNIFORM_FLOAT:
1677                         case DRW_UNIFORM_MAT3:
1678                         case DRW_UNIFORM_MAT4:
1679                                 GPU_shader_uniform_vector(
1680                                         shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)uni->value);
1681                                 break;
1682                         case DRW_UNIFORM_TEXTURE:
1683                                 tex = (GPUTexture *)uni->value;
1684                                 GPU_texture_bind(tex, uni->bindloc);
1685
1686                                 bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
1687                                 bound_tex->tex = tex;
1688                                 BLI_addtail(&DST.bound_texs, bound_tex);
1689
1690                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
1691                                 break;
1692                         case DRW_UNIFORM_BUFFER:
1693                                 if (!DRW_state_is_fbo()) {
1694                                         break;
1695                                 }
1696                                 tex = *((GPUTexture **)uni->value);
1697                                 GPU_texture_bind(tex, uni->bindloc);
1698
1699                                 bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
1700                                 bound_tex->tex = tex;
1701                                 BLI_addtail(&DST.bound_texs, bound_tex);
1702
1703                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
1704                                 break;
1705                         case DRW_UNIFORM_BLOCK:
1706                                 GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
1707                                 GPU_shader_uniform_buffer(shgroup->shader, uni->location, (GPUUniformBuffer *)uni->value);
1708                                 break;
1709                 }
1710         }
1711
1712 #ifdef USE_GPU_SELECT
1713         /* use the first item because of selection we only ever add one */
1714 #  define GPU_SELECT_LOAD_IF_PICKSEL(_call) \
1715         if ((G.f & G_PICKSEL) && (_call)) { \
1716                 GPU_select_load_id((_call)->head.select_id); \
1717         } ((void)0)
1718 #  define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_call_ls) \
1719         if ((G.f & G_PICKSEL) && (_call_ls)->first) { \
1720                 BLI_assert(BLI_listbase_is_single(_call_ls)); \
1721                 GPU_select_load_id(((DRWCall *)(_call_ls)->first)->head.select_id); \
1722         } ((void)0)
1723 #else
1724 #  define GPU_SELECT_LOAD_IF_PICKSEL(call)
1725 #  define GPU_SELECT_LOAD_IF_PICKSEL_LIST(call)
1726 #endif
1727
1728         /* Rendering Calls */
1729         if (!is_normal) {
1730                 /* Replacing multiple calls with only one */
1731                 float obmat[4][4];
1732                 unit_m4(obmat);
1733
1734                 if (shgroup->type == DRW_SHG_INSTANCE && interface->instance_count > 0) {
1735                         GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls);
1736                         draw_geometry(shgroup, shgroup->instance_geom, obmat, NULL);
1737                 }
1738                 else {
1739                         /* Some dynamic batch can have no geom (no call to aggregate) */
1740                         if (shgroup->batch_geom) {
1741                                 GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls);
1742                                 draw_geometry(shgroup, shgroup->batch_geom, obmat, NULL);
1743                         }
1744                 }
1745         }
1746         else {
1747                 for (DRWCall *call = shgroup->calls.first; call; call = call->head.next) {
1748                         bool neg_scale = call->obmat && is_negative_m4(call->obmat);
1749
1750                         /* Negative scale objects */
1751                         if (neg_scale) {
1752                                 glFrontFace(GL_CW);
1753                         }
1754
1755                         GPU_SELECT_LOAD_IF_PICKSEL(call);
1756
1757                         if (call->head.type == DRW_CALL_SINGLE) {
1758                                 draw_geometry(shgroup, call->geometry, call->obmat, call->ob);
1759                         }
1760                         else {
1761                                 BLI_assert(call->head.type == DRW_CALL_GENERATE);
1762                                 DRWCallGenerate *callgen = ((DRWCallGenerate *)call);
1763                                 draw_geometry_prepare(shgroup, callgen->obmat, NULL, NULL);
1764                                 callgen->geometry_fn(shgroup, draw_geometry_execute, callgen->user_data);
1765                         }
1766
1767                         /* Reset state */
1768                         if (neg_scale) {
1769                                 glFrontFace(GL_CCW);
1770                         }
1771                 }
1772         }
1773
1774         /* TODO: remove, (currently causes alpha issue with sculpt, need to investigate) */
1775         DRW_state_reset();
1776 }
1777
1778 void DRW_draw_pass(DRWPass *pass)
1779 {
1780         /* Start fresh */
1781         DST.shader = NULL;
1782         DST.tex_bind_id = 0;
1783
1784         DRW_state_set(pass->state);
1785         BLI_listbase_clear(&DST.bound_texs);
1786
1787         /* Init Timer queries */
1788         if (pass->timer_queries[0] == 0) {
1789                 pass->front_idx = 0;
1790                 pass->back_idx = 1;
1791
1792                 glGenQueries(2, pass->timer_queries);
1793
1794                 /* dummy query, avoid gl error */
1795                 glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->front_idx]);
1796                 glEndQuery(GL_TIME_ELAPSED);
1797         }
1798         else {
1799                 /* swap indices */
1800                 unsigned int tmp = pass->back_idx;
1801                 pass->back_idx = pass->front_idx;
1802                 pass->front_idx = tmp;
1803         }
1804
1805         if (!pass->wasdrawn) {
1806                 /* issue query for the next frame */
1807                 glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->back_idx]);
1808         }
1809
1810         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
1811                 draw_shgroup(shgroup, pass->state);
1812         }
1813
1814         /* Clear Bound textures */
1815         for (DRWBoundTexture *bound_tex = DST.bound_texs.first; bound_tex; bound_tex = bound_tex->next) {
1816                 GPU_texture_unbind(bound_tex->tex);
1817         }
1818         DST.tex_bind_id = 0;
1819         BLI_freelistN(&DST.bound_texs);
1820
1821         if (DST.shader) {
1822                 GPU_shader_unbind();
1823                 DST.shader = NULL;
1824         }
1825
1826         if (!pass->wasdrawn) {
1827                 glEndQuery(GL_TIME_ELAPSED);
1828         }
1829
1830         pass->wasdrawn = true;
1831 }
1832
1833 void DRW_draw_callbacks_pre_scene(void)
1834 {
1835         RegionView3D *rv3d = DST.draw_ctx.rv3d;
1836
1837         gpuLoadProjectionMatrix(rv3d->winmat);
1838         gpuLoadMatrix(rv3d->viewmat);
1839 }
1840
1841 void DRW_draw_callbacks_post_scene(void)
1842 {
1843         RegionView3D *rv3d = DST.draw_ctx.rv3d;
1844
1845         gpuLoadProjectionMatrix(rv3d->winmat);
1846         gpuLoadMatrix(rv3d->viewmat);
1847 }
1848
1849 /* Reset state to not interfer with other UI drawcall */
1850 void DRW_state_reset_ex(DRWState state)
1851 {
1852         DST.state = ~state;
1853         DRW_state_set(state);
1854 }
1855
1856 void DRW_state_reset(void)
1857 {
1858         DRW_state_reset_ex(DRW_STATE_DEFAULT);
1859 }
1860
1861 /** \} */
1862
1863
1864 struct DRWTextStore *DRW_text_cache_ensure(void)
1865 {
1866         BLI_assert(DST.text_store_p);
1867         if (*DST.text_store_p == NULL) {
1868                 *DST.text_store_p = DRW_text_cache_create();
1869         }
1870         return *DST.text_store_p;
1871 }
1872
1873
1874 /* -------------------------------------------------------------------- */
1875
1876 /** \name Settings
1877  * \{ */
1878
1879 bool DRW_object_is_renderable(Object *ob)
1880 {
1881         Scene *scene = DST.draw_ctx.scene;
1882         Object *obedit = scene->obedit;
1883
1884         if (ob->type == OB_MESH) {
1885                 if (ob == obedit) {
1886                         IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_EDIT, "");
1887                         bool do_show_occlude_wire = BKE_collection_engine_property_value_get_bool(props, "show_occlude_wire");
1888                         if (do_show_occlude_wire) {
1889                                 return false;
1890                         }
1891                         bool do_show_weight = BKE_collection_engine_property_value_get_bool(props, "show_weight");
1892                         if (do_show_weight) {
1893                                 return false;
1894                         }
1895                 }
1896         }
1897
1898         return true;
1899 }
1900
1901
1902 bool DRW_object_is_flat_normal(Object *ob)
1903 {
1904         if (ob->type == OB_MESH) {
1905                 Mesh *me = ob->data;
1906                 if (me->mpoly && me->mpoly[0].flag & ME_SMOOTH) {
1907                         return false;
1908                 }
1909         }
1910         return true;
1911 }
1912
1913 /** \} */
1914
1915
1916 /* -------------------------------------------------------------------- */
1917
1918 /** \name Framebuffers (DRW_framebuffer)
1919  * \{ */
1920
1921 static GPUTextureFormat convert_tex_format(int fbo_format, int *channels, bool *is_depth)
1922 {
1923         *is_depth = ELEM(fbo_format, DRW_TEX_DEPTH_16, DRW_TEX_DEPTH_24);
1924
1925         switch (fbo_format) {
1926                 case DRW_TEX_R_16:     *channels = 1; return GPU_R16F;
1927                 case DRW_TEX_R_32:     *channels = 1; return GPU_R32F;
1928                 case DRW_TEX_RG_16:    *channels = 2; return GPU_RG16F;
1929                 case DRW_TEX_RGBA_8:   *channels = 4; return GPU_RGBA8;
1930                 case DRW_TEX_RGBA_16:  *channels = 4; return GPU_RGBA16F;
1931                 case DRW_TEX_RGBA_32:  *channels = 4; return GPU_RGBA32F;
1932                 case DRW_TEX_DEPTH_24: *channels = 1; return GPU_DEPTH_COMPONENT24;
1933                 case DRW_TEX_RGB_11_11_10: *channels = 3; return GPU_R11F_G11F_B10F;
1934                 default:
1935                         BLI_assert(false && "Texture format unsupported as render target!");
1936                         *channels = 4; return GPU_RGBA8;
1937         }
1938 }
1939
1940 void DRW_framebuffer_init(
1941         struct GPUFrameBuffer **fb, void *engine_type, int width, int height,
1942         DRWFboTexture textures[MAX_FBO_TEX], int textures_len)
1943 {
1944         BLI_assert(textures_len <= MAX_FBO_TEX);
1945
1946         bool create_fb = false;
1947         int color_attachment = -1;
1948
1949         if (!*fb) {
1950                 *fb = GPU_framebuffer_create();
1951                 create_fb = true;
1952         }
1953
1954         for (int i = 0; i < textures_len; ++i) {
1955                 int channels;
1956                 bool is_depth;
1957
1958                 DRWFboTexture fbotex = textures[i];
1959                 bool is_temp = (fbotex.flag & DRW_TEX_TEMP) != 0;
1960
1961                 GPUTextureFormat gpu_format = convert_tex_format(fbotex.format, &channels, &is_depth);
1962
1963                 if (!*fbotex.tex || is_temp) {
1964                         /* Temp textures need to be queried each frame, others not. */
1965                         if (is_temp) {
1966                                 *fbotex.tex = GPU_viewport_texture_pool_query(DST.viewport, engine_type, width, height, channels, gpu_format);
1967                         }
1968                         else if (create_fb) {
1969                                 *fbotex.tex = GPU_texture_create_2D_custom(width, height, channels, gpu_format, NULL, NULL);
1970                         }
1971                 }
1972
1973                 if (create_fb) {
1974                         if (!is_depth) {
1975                                 ++color_attachment;
1976                         }
1977                         drw_texture_set_parameters(*fbotex.tex, fbotex.flag);
1978                         GPU_framebuffer_texture_attach(*fb, *fbotex.tex, color_attachment, 0);
1979                 }
1980         }
1981
1982         if (create_fb) {
1983                 if (!GPU_framebuffer_check_valid(*fb, NULL)) {
1984                         printf("Error invalid framebuffer\n");
1985                 }
1986
1987                 /* Detach temp textures */
1988                 for (int i = 0; i < textures_len; ++i) {
1989                         DRWFboTexture fbotex = textures[i];
1990
1991                         if ((fbotex.flag & DRW_TEX_TEMP) != 0) {
1992                                 GPU_framebuffer_texture_detach(*fbotex.tex);
1993                         }
1994                 }
1995
1996                 GPU_framebuffer_bind(DST.default_framebuffer);
1997         }
1998 }
1999
2000 void DRW_framebuffer_free(struct GPUFrameBuffer *fb)
2001 {
2002         GPU_framebuffer_free(fb);
2003 }
2004
2005 void DRW_framebuffer_bind(struct GPUFrameBuffer *fb)
2006 {
2007         GPU_framebuffer_bind(fb);
2008 }
2009
2010 void DRW_framebuffer_clear(bool color, bool depth, bool stencil, float clear_col[4], float clear_depth)
2011 {
2012         if (color) {
2013                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2014                 glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]);
2015         }
2016         if (depth) {
2017                 glDepthMask(GL_TRUE);
2018                 glClearDepth(clear_depth);
2019         }
2020         if (stencil) {
2021                 glStencilMask(0xFF);
2022         }
2023         glClear(((color) ? GL_COLOR_BUFFER_BIT : 0) |
2024                 ((depth) ? GL_DEPTH_BUFFER_BIT : 0) |
2025                 ((stencil) ? GL_STENCIL_BUFFER_BIT : 0));
2026 }
2027
2028 void DRW_framebuffer_read_data(int x, int y, int w, int h, int channels, int slot, float *data)
2029 {
2030         GLenum type;
2031         switch (channels) {
2032                 case 1: type = GL_RED; break;
2033                 case 2: type = GL_RG; break;
2034                 case 3: type = GL_RGB; break;
2035                 case 4: type = GL_RGBA; break;
2036                 default:
2037                         BLI_assert(false && "wrong number of read channels");
2038                         return;
2039         }
2040         glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
2041         glReadPixels(x, y, w, h, type, GL_FLOAT, data);
2042 }
2043
2044 void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
2045 {
2046         GPU_framebuffer_texture_attach(fb, tex, slot, mip);
2047 }
2048
2049 void DRW_framebuffer_texture_detach(GPUTexture *tex)
2050 {
2051         GPU_framebuffer_texture_detach(tex);
2052 }
2053
2054 void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer *fb_write, bool depth)
2055 {
2056         GPU_framebuffer_blit(fb_read, 0, fb_write, 0, depth);
2057 }
2058
2059 void DRW_framebuffer_viewport_size(struct GPUFrameBuffer *UNUSED(fb_read), int w, int h)
2060 {
2061         glViewport(0, 0, w, h);
2062 }
2063
2064 /* Use color management profile to draw texture to framebuffer */
2065 void DRW_transform_to_display(GPUTexture *tex)
2066 {
2067         DRW_state_set(DRW_STATE_WRITE_COLOR);
2068
2069         VertexFormat *vert_format = immVertexFormat();
2070         unsigned int pos = VertexFormat_add_attrib(vert_format, "pos", COMP_F32, 2, KEEP_FLOAT);
2071         unsigned int texco = VertexFormat_add_attrib(vert_format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
2072
2073         const float dither = 1.0f;
2074
2075         bool use_ocio = false;
2076
2077         if (DST.draw_ctx.evil_C != NULL) {
2078                 use_ocio = IMB_colormanagement_setup_glsl_draw_from_space_ctx(DST.draw_ctx.evil_C, NULL, dither, false);
2079         }
2080
2081         if (!use_ocio) {
2082                 immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_LINEAR_TO_SRGB);
2083                 immUniform1i("image", 0);
2084         }
2085
2086         GPU_texture_bind(tex, 0); /* OCIO texture bind point is 0 */
2087
2088         float mat[4][4];
2089         unit_m4(mat);
2090         immUniformMatrix4fv("ModelViewProjectionMatrix", mat);
2091
2092         /* Full screen triangle */
2093         immBegin(PRIM_TRIANGLES, 3);
2094         immAttrib2f(texco, 0.0f, 0.0f);
2095         immVertex2f(pos, -1.0f, -1.0f);
2096
2097         immAttrib2f(texco, 2.0f, 0.0f);
2098         immVertex2f(pos, 3.0f, -1.0f);
2099
2100         immAttrib2f(texco, 0.0f, 2.0f);
2101         immVertex2f(pos, -1.0f, 3.0f);
2102         immEnd();
2103
2104         GPU_texture_unbind(tex);
2105
2106         if (use_ocio) {
2107                 IMB_colormanagement_finish_glsl_draw();
2108         }
2109         else {
2110                 immUnbindProgram();
2111         }
2112 }
2113
2114 /** \} */
2115
2116
2117 /* -------------------------------------------------------------------- */
2118
2119 /** \name Viewport (DRW_viewport)
2120  * \{ */
2121
2122 static void *DRW_viewport_engine_data_get(void *engine_type)
2123 {
2124         void *data = GPU_viewport_engine_data_get(DST.viewport, engine_type);
2125
2126         if (data == NULL) {
2127                 data = GPU_viewport_engine_data_create(DST.viewport, engine_type);
2128         }
2129         return data;
2130 }
2131
2132 void DRW_engine_viewport_data_size_get(
2133         const void *engine_type_v,
2134         int *r_fbl_len, int *r_txl_len, int *r_psl_len, int *r_stl_len)
2135 {
2136         const DrawEngineType *engine_type = engine_type_v;
2137
2138         if (r_fbl_len) {
2139                 *r_fbl_len = engine_type->vedata_size->fbl_len;
2140         }
2141         if (r_txl_len) {
2142                 *r_txl_len = engine_type->vedata_size->txl_len;
2143         }
2144         if (r_psl_len) {
2145                 *r_psl_len = engine_type->vedata_size->psl_len;
2146         }
2147         if (r_stl_len) {
2148                 *r_stl_len = engine_type->vedata_size->stl_len;
2149         }
2150 }
2151
2152 const float *DRW_viewport_size_get(void)
2153 {
2154         return &DST.size[0];
2155 }
2156
2157 const float *DRW_viewport_screenvecs_get(void)
2158 {
2159         return &DST.screenvecs[0][0];
2160 }
2161
2162 const float *DRW_viewport_pixelsize_get(void)
2163 {
2164         return &DST.pixsize;
2165 }
2166
2167 /* It also stores viewport variable to an immutable place: DST
2168  * This is because a cache uniform only store reference
2169  * to its value. And we don't want to invalidate the cache
2170  * if this value change per viewport */
2171 static void DRW_viewport_var_init(void)
2172 {
2173         RegionView3D *rv3d = DST.draw_ctx.rv3d;
2174
2175         /* Refresh DST.size */
2176         if (DST.viewport) {
2177                 int size[2];
2178                 GPU_viewport_size_get(DST.viewport, size);
2179                 DST.size[0] = size[0];
2180                 DST.size[1] = size[1];
2181
2182                 DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport);
2183                 DST.default_framebuffer = fbl->default_fb;
2184         }
2185         else {
2186                 DST.size[0] = 0;
2187                 DST.size[1] = 0;
2188
2189                 DST.default_framebuffer = NULL;
2190         }
2191         /* Refresh DST.screenvecs */
2192         copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
2193         copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
2194         normalize_v3(DST.screenvecs[0]);
2195         normalize_v3(DST.screenvecs[1]);
2196
2197         /* Refresh DST.pixelsize */
2198         DST.pixsize = rv3d->pixsize;
2199 }
2200
2201 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
2202 {
2203         RegionView3D *rv3d = DST.draw_ctx.rv3d;
2204
2205         switch (type) {
2206                 case DRW_MAT_PERS:
2207                         copy_m4_m4(mat, rv3d->persmat);
2208                         break;
2209                 case DRW_MAT_PERSINV:
2210                         copy_m4_m4(mat, rv3d->persinv);
2211                         break;
2212                 case DRW_MAT_VIEW:
2213                         copy_m4_m4(mat, rv3d->viewmat);
2214                         break;
2215                 case DRW_MAT_VIEWINV:
2216                         copy_m4_m4(mat, rv3d->viewinv);
2217                         break;
2218                 case DRW_MAT_WIN:
2219                         copy_m4_m4(mat, rv3d->winmat);
2220                         break;
2221                 default:
2222                         BLI_assert(!"Matrix type invalid");
2223                         break;
2224         }
2225 }
2226
2227 bool DRW_viewport_is_persp_get(void)
2228 {
2229         RegionView3D *rv3d = DST.draw_ctx.rv3d;
2230         return rv3d->is_persp;
2231 }
2232
2233 DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void)
2234 {
2235         return GPU_viewport_framebuffer_list_get(DST.viewport);
2236 }
2237
2238 DefaultTextureList *DRW_viewport_texture_list_get(void)
2239 {
2240         return GPU_viewport_texture_list_get(DST.viewport);
2241 }
2242
2243 /** \} */
2244
2245
2246 /* -------------------------------------------------------------------- */
2247
2248 /** \name Objects (DRW_object)
2249  * \{ */
2250
2251 typedef struct ObjectEngineData {
2252         struct ObjectEngineData *next, *prev;
2253         DrawEngineType *engine_type;
2254         void *storage;
2255 } ObjectEngineData;
2256
2257 void **DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type)
2258 {
2259         ObjectEngineData *oed;
2260
2261         for (oed = ob->drawdata.first; oed; oed = oed->next) {
2262                 if (oed->engine_type == engine_type) {
2263                         return &oed->storage;
2264                 }
2265         }
2266
2267         oed = MEM_callocN(sizeof(ObjectEngineData), "ObjectEngineData");
2268         oed->engine_type = engine_type;
2269         BLI_addtail(&ob->drawdata, oed);
2270
2271         return &oed->storage;
2272 }
2273
2274 void DRW_object_engine_data_free(Object *ob)
2275 {
2276         for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
2277                 if (oed->storage) {
2278                         MEM_freeN(oed->storage);
2279                 }
2280         }
2281
2282         BLI_freelistN(&ob->drawdata);
2283 }
2284
2285 LampEngineData *DRW_lamp_engine_data_get(Object *ob, RenderEngineType *engine_type)
2286 {
2287         BLI_assert(ob->type == OB_LAMP);
2288
2289         Scene *scene = DST.draw_ctx.scene;
2290
2291         /* TODO Dupliobjects */
2292         return GPU_lamp_engine_data_get(scene, ob, NULL, engine_type);
2293 }
2294
2295 void DRW_lamp_engine_data_free(LampEngineData *led)
2296 {
2297         GPU_lamp_engine_data_free(led);
2298 }
2299
2300 /** \} */
2301
2302
2303 /* -------------------------------------------------------------------- */
2304
2305 /** \name Rendering (DRW_engines)
2306  * \{ */
2307
2308 #define TIMER_FALLOFF 0.1f
2309
2310 static void DRW_engines_init(void)
2311 {
2312         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2313                 DrawEngineType *engine = link->data;
2314                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2315                 double stime = PIL_check_seconds_timer();
2316
2317                 if (engine->engine_init) {
2318                         engine->engine_init(data);
2319                 }
2320
2321                 double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
2322                 data->init_time = data->init_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
2323         }
2324 }
2325
2326 static void DRW_engines_cache_init(void)
2327 {
2328         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2329                 DrawEngineType *engine = link->data;
2330                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2331
2332                 if (data->text_draw_cache) {
2333                         DRW_text_cache_destroy(data->text_draw_cache);
2334                         data->text_draw_cache = NULL;
2335                 }
2336                 if (DST.text_store_p == NULL) {
2337                         DST.text_store_p = &data->text_draw_cache;
2338                 }
2339
2340                 double stime = PIL_check_seconds_timer();
2341                 data->cache_time = 0.0;
2342
2343                 if (engine->cache_init) {
2344                         engine->cache_init(data);
2345                 }
2346
2347                 data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
2348         }
2349 }
2350
2351 static void DRW_engines_cache_populate(Object *ob)
2352 {
2353         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2354                 DrawEngineType *engine = link->data;
2355                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2356                 double stime = PIL_check_seconds_timer();
2357
2358                 if (engine->cache_populate) {
2359                         engine->cache_populate(data, ob);
2360                 }
2361
2362                 data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
2363         }
2364 }
2365
2366 static void DRW_engines_cache_finish(void)
2367 {
2368         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2369                 DrawEngineType *engine = link->data;
2370                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2371                 double stime = PIL_check_seconds_timer();
2372
2373                 if (engine->cache_finish) {
2374                         engine->cache_finish(data);
2375                 }
2376
2377                 data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
2378         }
2379 }
2380
2381 static void DRW_engines_draw_background(void)
2382 {
2383         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2384                 DrawEngineType *engine = link->data;
2385                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2386                 double stime = PIL_check_seconds_timer();
2387
2388                 if (engine->draw_background) {
2389                         engine->draw_background(data);
2390                         return;
2391                 }
2392
2393                 double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
2394                 data->background_time = data->background_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
2395         }
2396
2397         /* No draw_background found, doing default background */
2398         DRW_draw_background();
2399 }
2400
2401 static void DRW_engines_draw_scene(void)
2402 {
2403         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2404                 DrawEngineType *engine = link->data;
2405                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2406                 double stime = PIL_check_seconds_timer();
2407
2408                 if (engine->draw_scene) {
2409                         engine->draw_scene(data);
2410                 }
2411
2412                 double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
2413                 data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
2414         }
2415 }
2416
2417 static void DRW_engines_draw_text(void)
2418 {
2419         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2420                 DrawEngineType *engine = link->data;
2421                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2422                 double stime = PIL_check_seconds_timer();
2423
2424                 if (data->text_draw_cache) {
2425                         DRW_text_cache_draw(data->text_draw_cache, DST.draw_ctx.v3d, DST.draw_ctx.ar, false);
2426                 }
2427
2428                 double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
2429                 data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
2430         }
2431 }
2432
2433 #define MAX_INFO_LINES 10
2434
2435 /**
2436  * Returns the offset required for the drawing of engines info.
2437  */
2438 int DRW_draw_region_engine_info_offset(void)
2439 {
2440         int lines = 0;
2441         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2442                 DrawEngineType *engine = link->data;
2443                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2444
2445                 /* Count the number of lines. */
2446                 if (data->info[0] != '\0') {
2447                         lines++;
2448                         char *c = data->info;
2449                         while (*c++ != '\0') {
2450                                 if (*c == '\n') {
2451                                         lines++;
2452                                 }
2453                         }
2454                 }
2455         }
2456         return MIN2(MAX_INFO_LINES, lines) * UI_UNIT_Y;
2457 }
2458
2459 /**
2460  * Actual drawing;
2461  */
2462 void DRW_draw_region_engine_info(void)
2463 {
2464         const char *info_array_final[MAX_INFO_LINES + 1];
2465         char info_array[MAX_INFO_LINES][GPU_INFO_SIZE]; /* This should be maxium number of engines running at the same time. */
2466         int i = 0;
2467
2468         const DRWContextState *draw_ctx = DRW_context_state_get();
2469         ARegion *ar = draw_ctx->ar;
2470         float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
2471
2472         UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
2473         mul_v3_fl(fill_color, fill_color[3]);
2474
2475         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2476                 DrawEngineType *engine = link->data;
2477                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2478
2479                 if (data->info[0] != '\0') {
2480                         char *chr_current = data->info;
2481                         char *chr_start = chr_current;
2482                         int line_len = 0;
2483
2484                         while (*chr_current++ != '\0') {
2485                                 line_len++;
2486                                 if (*chr_current == '\n') {
2487                                         BLI_strncpy(info_array[i++], chr_start, line_len + 1);
2488                                         /* Re-start counting. */
2489                                         chr_start = chr_current + 1;
2490                                         line_len = -1;
2491                                 }
2492                         }
2493
2494                         BLI_strncpy(info_array[i++], chr_start, line_len + 1);
2495
2496                         if (i >= MAX_INFO_LINES) {
2497                                 break;
2498                         }
2499                 }
2500         }
2501
2502         for (int j = 0; j < i; j++) {
2503                 info_array_final[j] = info_array[j];
2504         }
2505         info_array_final[i] = NULL;
2506
2507         if (info_array[0] != NULL) {
2508                 ED_region_info_draw_multiline(ar, info_array_final, fill_color, true);
2509         }
2510 }
2511
2512 #undef MAX_INFO_LINES
2513
2514 static void use_drw_engine(DrawEngineType *engine)
2515 {
2516         LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
2517         ld->data = engine;
2518         BLI_addtail(&DST.enabled_engines, ld);
2519 }
2520
2521 /* TODO revisit this when proper layering is implemented */
2522 /* Gather all draw engines needed and store them in DST.enabled_engines
2523  * That also define the rendering order of engines */
2524 static void DRW_engines_enable_from_engine(const Scene *scene)
2525 {
2526         /* TODO layers */
2527         RenderEngineType *type = RE_engines_find(scene->r.engine);
2528         if (type->draw_engine != NULL) {
2529                 use_drw_engine(type->draw_engine);
2530         }
2531
2532         if ((type->flag & RE_INTERNAL) == 0) {
2533                 DRW_engines_enable_external();
2534         }
2535 }
2536
2537 static void DRW_engines_enable_from_object_mode(void)
2538 {
2539         use_drw_engine(&draw_engine_object_type);
2540 }
2541
2542 static void DRW_engines_enable_from_mode(int mode)
2543 {
2544         switch (mode) {
2545                 case CTX_MODE_EDIT_MESH:
2546                         use_drw_engine(&draw_engine_edit_mesh_type);
2547                         break;
2548                 case CTX_MODE_EDIT_CURVE:
2549                         use_drw_engine(&draw_engine_edit_curve_type);
2550                         break;
2551                 case CTX_MODE_EDIT_SURFACE:
2552                         use_drw_engine(&draw_engine_edit_surface_type);
2553                         break;
2554                 case CTX_MODE_EDIT_TEXT:
2555                         use_drw_engine(&draw_engine_edit_text_type);
2556                         break;
2557                 case CTX_MODE_EDIT_ARMATURE:
2558                         use_drw_engine(&draw_engine_edit_armature_type);
2559                         break;
2560                 case CTX_MODE_EDIT_METABALL:
2561                         use_drw_engine(&draw_engine_edit_metaball_type);
2562                         break;
2563                 case CTX_MODE_EDIT_LATTICE:
2564                         use_drw_engine(&draw_engine_edit_lattice_type);
2565                         break;
2566                 case CTX_MODE_POSE:
2567                         use_drw_engine(&draw_engine_pose_type);
2568                         break;
2569                 case CTX_MODE_SCULPT:
2570                         use_drw_engine(&draw_engine_sculpt_type);
2571                         break;
2572                 case CTX_MODE_PAINT_WEIGHT:
2573                         use_drw_engine(&draw_engine_pose_type);
2574                         use_drw_engine(&draw_engine_paint_weight_type);
2575                         break;
2576                 case CTX_MODE_PAINT_VERTEX:
2577                         use_drw_engine(&draw_engine_paint_vertex_type);
2578                         break;
2579                 case CTX_MODE_PAINT_TEXTURE:
2580                         use_drw_engine(&draw_engine_paint_texture_type);
2581                         break;
2582                 case CTX_MODE_PARTICLE:
2583                         use_drw_engine(&draw_engine_particle_type);
2584                         break;
2585                 case CTX_MODE_OBJECT:
2586                         break;
2587                 default:
2588                         BLI_assert(!"Draw mode invalid");
2589                         break;
2590         }
2591 }
2592
2593 /**
2594  * Use for select and depth-drawing.
2595  */
2596 static void DRW_engines_enable_basic(void)
2597 {
2598         use_drw_engine(DRW_engine_viewport_basic_type.draw_engine);
2599 }
2600
2601 /**
2602  * Use for external render engines.
2603  */
2604 static void DRW_engines_enable_external(void)
2605 {
2606         use_drw_engine(DRW_engine_viewport_external_type.draw_engine);
2607 }
2608
2609 static void DRW_engines_enable(const Scene *scene, SceneLayer *sl, const View3D *v3d)
2610 {
2611         const int mode = CTX_data_mode_enum_ex(scene->obedit, OBACT_NEW);
2612         DRW_engines_enable_from_engine(scene);
2613         if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) {
2614                 DRW_engines_enable_from_object_mode();
2615                 DRW_engines_enable_from_mode(mode);
2616         }
2617 }
2618
2619 static void DRW_engines_disable(void)
2620 {
2621         BLI_freelistN(&DST.enabled_engines);
2622 }
2623
2624 static unsigned int DRW_engines_get_hash(void)
2625 {
2626         unsigned int hash = 0;
2627         /* The cache depends on enabled engines */
2628         /* FIXME : if collision occurs ... segfault */
2629         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2630                 DrawEngineType *engine = link->data;
2631                 hash += BLI_ghashutil_strhash_p(engine->idname);
2632         }
2633
2634         return hash;
2635 }
2636
2637 static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size)
2638 {
2639         BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit,
2640                                rect->ymax - (3 + v++) * U.widget_unit, 0.0f,
2641                                txt, size);
2642 }
2643
2644 /* CPU stats */
2645 static void DRW_debug_cpu_stats(void)
2646 {
2647         int u, v;
2648         double cache_tot_time = 0.0, init_tot_time = 0.0, background_tot_time = 0.0, render_tot_time = 0.0, tot_time = 0.0;
2649         /* local coordinate visible rect inside region, to accomodate overlapping ui */
2650         rcti rect;
2651         struct ARegion *ar = DST.draw_ctx.ar;
2652         ED_region_visible_rect(ar, &rect);
2653
2654         UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
2655
2656         /* row by row */
2657         v = 0; u = 0;
2658         /* Label row */
2659         char col_label[32];
2660         sprintf(col_label, "Engine");
2661         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
2662         sprintf(col_label, "Cache");
2663         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
2664         sprintf(col_label, "Init");
2665         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
2666         sprintf(col_label, "Background");
2667         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
2668         sprintf(col_label, "Render");
2669         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
2670         sprintf(col_label, "Total (w/o cache)");
2671         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
2672         v++;
2673
2674         /* Engines rows */
2675         char time_to_txt[16];
2676         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2677                 u = 0;
2678                 DrawEngineType *engine = link->data;
2679                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2680
2681                 draw_stat(&rect, u++, v, engine->idname, sizeof(engine->idname));
2682
2683                 cache_tot_time += data->cache_time;
2684                 sprintf(time_to_txt, "%.2fms", data->cache_time);
2685                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2686
2687                 init_tot_time += data->init_time;
2688                 sprintf(time_to_txt, "%.2fms", data->init_time);
2689                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2690
2691                 background_tot_time += data->background_time;
2692                 sprintf(time_to_txt, "%.2fms", data->background_time);
2693                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2694
2695                 render_tot_time += data->render_time;
2696                 sprintf(time_to_txt, "%.2fms", data->render_time);
2697                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2698
2699                 tot_time += data->init_time + data->background_time + data->render_time;
2700                 sprintf(time_to_txt, "%.2fms", data->init_time + data->background_time + data->render_time);
2701                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2702                 v++;
2703         }
2704
2705         /* Totals row */
2706         u = 0;
2707         sprintf(col_label, "Sub Total");
2708         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
2709         sprintf(time_to_txt, "%.2fms", cache_tot_time);
2710         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2711         sprintf(time_to_txt, "%.2fms", init_tot_time);
2712         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2713         sprintf(time_to_txt, "%.2fms", background_tot_time);
2714         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2715         sprintf(time_to_txt, "%.2fms", render_tot_time);
2716         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2717         sprintf(time_to_txt, "%.2fms", tot_time);
2718         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
2719 }
2720
2721 /* Display GPU time for each passes */
2722 static void DRW_debug_gpu_stats(void)
2723 {
2724         /* local coordinate visible rect inside region, to accomodate overlapping ui */
2725         rcti rect;
2726         struct ARegion *ar = DST.draw_ctx.ar;
2727         ED_region_visible_rect(ar, &rect);
2728
2729         UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
2730
2731         char time_to_txt[16];
2732         char pass_name[MAX_PASS_NAME + 16];
2733         int v = BLI_listbase_count(&DST.enabled_engines) + 3;
2734         GLuint64 tot_time = 0;
2735
2736         if (G.debug_value > 666) {
2737                 for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
2738                         GLuint64 engine_time = 0;
2739                         DrawEngineType *engine = link->data;
2740                         ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
2741                         int vsta = v;
2742
2743                         draw_stat(&rect, 0, v, engine->idname, sizeof(engine->idname));
2744                         v++;
2745
2746                         for (int i = 0; i < engine->vedata_size->psl_len; ++i) {
2747                                 DRWPass *pass = data->psl->passes[i];
2748                                 if (pass != NULL && pass->wasdrawn) {
2749                                         GLuint64 time;
2750                                         glGetQueryObjectui64v(pass->timer_queries[pass->front_idx], GL_QUERY_RESULT, &time);
2751
2752                                         sprintf(pass_name, "   |--> %s", pass->name);
2753                                         draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
2754
2755                                         sprintf(time_to_txt, "%.2fms", time / 1000000.0);
2756                                         engine_time += time;
2757                                         tot_time += time;
2758
2759                                         draw_stat(&rect, 2, v++, time_to_txt, sizeof(time_to_txt));
2760
2761                                         pass->wasdrawn = false;
2762                                 }
2763                         }
2764                         /* engine total time */
2765                         sprintf(time_to_txt, "%.2fms", engine_time / 1000000.0);
2766                         draw_stat(&rect, 2, vsta, time_to_txt, sizeof(time_to_txt));
2767                         v++;
2768                 }
2769
2770                 sprintf(pass_name, "Total GPU time %.2fms (%.1f fps)", tot_time / 1000000.0, 1000000000.0 / tot_time);
2771                 draw_stat(&rect, 0, v++, pass_name, sizeof(pass_name));
2772                 v++;
2773         }
2774
2775         /* Memory Stats */
2776         unsigned int tex_mem = GPU_texture_memory_usage_get();
2777         unsigned int vbo_mem = VertexBuffer_get_memory_usage();
2778
2779         sprintf(pass_name, "GPU Memory");
2780         draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
2781         sprintf(pass_name, "%.2fMB", (float)(tex_mem + vbo_mem) / 1000000.0);
2782         draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name));
2783         sprintf(pass_name, "   |--> Textures");
2784         draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
2785         sprintf(pass_name, "%.2fMB", (float)tex_mem / 1000000.0);
2786         draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name));
2787         sprintf(pass_name, "   |--> Meshes");
2788         draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
2789         sprintf(pass_name, "%.2fMB", (float)vbo_mem / 1000000.0);
2790         draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name));
2791 }
2792
2793
2794 /* -------------------------------------------------------------------- */
2795
2796 /** \name Main Draw Loops (DRW_draw)
2797  * \{ */
2798
2799 /* Everything starts here.
2800  * This function takes care of calling all cache and rendering functions
2801  * for each relevant engine / mode engine. */
2802 void DRW_draw_view(const bContext *C)
2803 {
2804         struct Depsgraph *graph = CTX_data_depsgraph(C);
2805         ARegion *ar = CTX_wm_region(C);
2806         View3D *v3d = CTX_wm_view3d(C);
2807
2808         DST.draw_ctx.evil_C = C;
2809
2810         DRW_draw_render_loop(graph, ar, v3d);
2811 }
2812
2813 /**
2814  * Used for both regular and off-screen drawing.
2815  */
2816 void DRW_draw_render_loop(
2817         struct Depsgraph *graph,
2818         ARegion *ar, View3D *v3d)
2819 {
2820         Scene *scene = DAG_get_scene(graph);
2821         SceneLayer *sl = DAG_get_scene_layer(graph);
2822         RegionView3D *rv3d = ar->regiondata;
2823
2824         bool cache_is_dirty;
2825         DST.viewport = rv3d->viewport;
2826         v3d->zbuf = true;
2827
2828         /* Get list of enabled engines */
2829         DRW_engines_enable(scene, sl, v3d);
2830
2831         /* Setup viewport */
2832         cache_is_dirty = GPU_viewport_cache_validate(DST.viewport, DRW_engines_get_hash());
2833
2834         DST.draw_ctx = (DRWContextState){
2835                 ar, rv3d, v3d, scene, sl, OBACT_NEW,
2836                 /* reuse if caller sets */
2837                 DST.draw_ctx.evil_C,
2838         };
2839
2840         DRW_viewport_var_init();
2841
2842         /* Update ubos */
2843         DRW_globals_update();
2844
2845         /* Init engines */
2846         DRW_engines_init();
2847
2848         /* TODO : tag to refresh by the deps graph */
2849         /* ideally only refresh when objects are added/removed */
2850         /* or render properties / materials change */
2851         if (cache_is_dirty) {
2852                 DRW_engines_cache_init();
2853
2854                 DEG_OBJECT_ITER(graph, ob);
2855                 {
2856                         DRW_engines_cache_populate(ob);
2857                 }
2858                 DEG_OBJECT_ITER_END
2859
2860                 DRW_engines_cache_finish();
2861         }
2862
2863         /* Start Drawing */
2864         DRW_state_reset();
2865         DRW_engines_draw_background();
2866
2867         DRW_draw_callbacks_pre_scene();
2868         if (DST.draw_ctx.evil_C) {
2869                 ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW);
2870         }
2871
2872         DRW_engines_draw_scene();
2873
2874         DRW_draw_callbacks_post_scene();
2875         if (DST.draw_ctx.evil_C) {
2876                 ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW);
2877         }
2878
2879         DRW_state_reset();
2880
2881         DRW_engines_draw_text();
2882
2883         if (DST.draw_ctx.evil_C) {
2884                 /* needed so manipulator isn't obscured */
2885                 glDisable(GL_DEPTH_TEST);
2886                 DRW_draw_manipulator();
2887                 glEnable(GL_DEPTH_TEST);
2888
2889                 DRW_draw_region_info();
2890         }
2891
2892         if (G.debug_value > 20) {
2893                 DRW_debug_cpu_stats();
2894                 DRW_debug_gpu_stats();
2895         }
2896
2897         DRW_state_reset();
2898         DRW_engines_disable();
2899
2900         /* avoid accidental reuse */
2901         memset(&DST, 0x0, sizeof(DST));
2902 }
2903
2904 void DRW_draw_render_loop_offscreen(
2905         struct Depsgraph *graph,
2906         ARegion *ar, View3D *v3d, GPUOffScreen *ofs)
2907 {
2908         RegionView3D *rv3d = ar->regiondata;
2909
2910         /* backup */
2911         void *backup_viewport = rv3d->viewport;
2912         {
2913                 /* backup (_never_ use rv3d->viewport) */
2914                 rv3d->viewport = GPU_viewport_create_from_offscreen(ofs);
2915         }
2916
2917         DST.draw_ctx.evil_C = NULL;
2918
2919         DRW_draw_render_loop(graph, ar, v3d);
2920
2921         /* restore */
2922         {
2923                 /* don't free data owned by 'ofs' */
2924                 GPU_viewport_clear_from_offscreen(rv3d->viewport);
2925                 GPU_viewport_free(rv3d->viewport);
2926                 MEM_freeN(rv3d->viewport);
2927
2928                 rv3d->viewport = backup_viewport;
2929         }
2930
2931         /* we need to re-bind (annoying!) */
2932         GPU_offscreen_bind(ofs, false);
2933 }
2934
2935 /**
2936  * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
2937  */
2938 void DRW_draw_select_loop(
2939         struct Depsgraph *graph,
2940         ARegion *ar, View3D *v3d,
2941         bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect)
2942 {
2943         Scene *scene = DAG_get_scene(graph);
2944         SceneLayer *sl = DAG_get_scene_layer(graph);
2945 #ifndef USE_GPU_SELECT
2946         UNUSED_VARS(vc, scene, sl, v3d, ar, rect);
2947 #else
2948         RegionView3D *rv3d = ar->regiondata;
2949
2950         /* backup (_never_ use rv3d->viewport) */
2951         void *backup_viewport = rv3d->viewport;
2952         rv3d->viewport = NULL;
2953
2954         bool use_obedit = false;
2955         int obedit_mode = 0;
2956         if (scene->obedit && scene->obedit->type == OB_MBALL) {
2957                 use_obedit = true;
2958                 DRW_engines_cache_populate(scene->obedit);
2959                 obedit_mode = CTX_MODE_EDIT_METABALL;
2960         }
2961         else if ((scene->obedit && scene->obedit->type == OB_ARMATURE)) {
2962                 /* if not drawing sketch, draw bones */
2963                 // if (!BDR_drawSketchNames(vc))
2964                 {
2965                         use_obedit = true;
2966                         obedit_mode = CTX_MODE_EDIT_ARMATURE;
2967                 }
2968         }
2969
2970         struct GPUViewport *viewport = GPU_viewport_create();
2971         GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)});
2972
2973         bool cache_is_dirty;
2974         DST.viewport = viewport;
2975         v3d->zbuf = true;
2976
2977         DST.options.is_select = true;
2978
2979         /* Get list of enabled engines */
2980         if (use_obedit) {
2981                 DRW_engines_enable_from_mode(obedit_mode);
2982         }
2983         else {
2984                 DRW_engines_enable_basic();
2985                 DRW_engines_enable_from_object_mode();
2986         }
2987
2988         /* Setup viewport */
2989         cache_is_dirty = true;
2990
2991         /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
2992         DST.draw_ctx = (DRWContextState){
2993                 ar, rv3d, v3d, scene, sl, OBACT_NEW, (bContext *)NULL,
2994         };
2995
2996         DRW_viewport_var_init();
2997
2998         /* Update ubos */
2999         DRW_globals_update();
3000
3001         /* Init engines */
3002         DRW_engines_init();
3003
3004         /* TODO : tag to refresh by the deps graph */
3005         /* ideally only refresh when objects are added/removed */
3006         /* or render properties / materials change */
3007         if (cache_is_dirty) {
3008
3009                 DRW_engines_cache_init();
3010
3011                 if (use_obedit) {
3012                         DRW_engines_cache_populate(scene->obedit);
3013                 }
3014                 else {
3015                         DEG_OBJECT_ITER(graph, ob)
3016                         {
3017                                 if ((ob->base_flag & BASE_SELECTABLED) != 0) {
3018                                         DRW_select_load_id(ob->base_selection_color);
3019                                         DRW_engines_cache_populate(ob);
3020                                 }
3021                         }
3022                         DEG_OBJECT_ITER_END
3023                 }
3024
3025                 DRW_engines_cache_finish();
3026         }
3027
3028         /* Start Drawing */
3029         DRW_state_reset();
3030         DRW_draw_callbacks_pre_scene();
3031         DRW_engines_draw_scene();
3032         DRW_draw_callbacks_post_scene();
3033
3034         DRW_state_reset();
3035         DRW_engines_disable();
3036
3037         /* avoid accidental reuse */
3038         memset(&DST, 0x0, sizeof(DST));
3039
3040         /* Cleanup for selection state */
3041         GPU_viewport_free(viewport);
3042         MEM_freeN(viewport);
3043
3044         /* restore */
3045         rv3d->viewport = backup_viewport;
3046 #endif  /* USE_GPU_SELECT */
3047 }
3048
3049 /**
3050  * object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
3051  */
3052 void DRW_draw_depth_loop(
3053         Depsgraph *graph,
3054         ARegion *ar, View3D *v3d)
3055 {
3056         Scene *scene = DAG_get_scene(graph);
3057         SceneLayer *sl = DAG_get_scene_layer(graph);
3058         RegionView3D *rv3d = ar->regiondata;
3059
3060         /* backup (_never_ use rv3d->viewport) */
3061         void *backup_viewport = rv3d->viewport;
3062         rv3d->viewport = NULL;
3063
3064         struct GPUViewport *viewport = GPU_viewport_create();
3065         GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy});
3066
3067         bool cache_is_dirty;
3068         DST.viewport = viewport;
3069         v3d->zbuf = true;
3070
3071         DST.options.is_depth = true;
3072
3073         /* Get list of enabled engines */
3074         {
3075                 DRW_engines_enable_basic();
3076                 DRW_engines_enable_from_object_mode();
3077         }
3078
3079         /* Setup viewport */
3080         cache_is_dirty = true;
3081
3082         /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
3083         DST.draw_ctx = (DRWContextState){
3084                 ar, rv3d, v3d, scene, sl, OBACT_NEW, (bContext *)NULL,
3085         };
3086
3087         DRW_viewport_var_init();
3088
3089         /* Update ubos */
3090         DRW_globals_update();
3091
3092         /* Init engines */
3093         DRW_engines_init();
3094
3095         /* TODO : tag to refresh by the deps graph */
3096         /* ideally only refresh when objects are added/removed */
3097         /* or render properties / materials change */
3098         if (cache_is_dirty) {
3099
3100                 DRW_engines_cache_init();
3101
3102                 DEG_OBJECT_ITER(graph, ob)
3103                 {
3104                         DRW_engines_cache_populate(ob);
3105                 }
3106                 DEG_OBJECT_ITER_END
3107
3108                 DRW_engines_cache_finish();
3109         }
3110
3111         /* Start Drawing */
3112         DRW_state_reset();
3113         DRW_draw_callbacks_pre_scene();
3114         DRW_engines_draw_scene();
3115         DRW_draw_callbacks_post_scene();
3116
3117         DRW_state_reset();
3118         DRW_engines_disable();
3119
3120         /* avoid accidental reuse */
3121         memset(&DST, 0x0, sizeof(DST));
3122
3123         /* Cleanup for selection state */
3124         GPU_viewport_free(viewport);
3125         MEM_freeN(viewport);
3126
3127         /* restore */
3128         rv3d->viewport = backup_viewport;
3129 }
3130
3131 /** \} */
3132
3133
3134 /* -------------------------------------------------------------------- */
3135
3136 /** \name Draw Manager State (DRW_state)
3137  * \{ */
3138
3139 void DRW_state_dfdy_factors_get(float dfdyfac[2])
3140 {
3141         GPU_get_dfdy_factors(dfdyfac);
3142 }
3143
3144 /**
3145  * When false, drawing doesn't output to a pixel buffer
3146  * eg: Occlusion queries, or when we have setup a context to draw in already.
3147  */
3148 bool DRW_state_is_fbo(void)
3149 {
3150         return (DST.default_framebuffer != NULL);
3151 }
3152
3153 /**
3154  * For when engines need to know if this is drawing for selection or not.
3155  */
3156 bool DRW_state_is_select(void)
3157 {
3158         return DST.options.is_select;
3159 }
3160
3161 bool DRW_state_is_depth(void)
3162 {
3163         return DST.options.is_depth;
3164 }
3165
3166 /**
3167  * Should text draw in this mode?
3168  */
3169 bool DRW_state_show_text(void)
3170 {
3171         return (DST.options.is_select) == 0 &&
3172                (DST.options.is_depth) == 0;
3173 }
3174
3175 /** \} */
3176
3177
3178 /* -------------------------------------------------------------------- */
3179
3180 /** \name Context State (DRW_context_state)
3181  * \{ */
3182
3183 void DRW_context_state_init(const bContext *C, DRWContextState *r_draw_ctx)
3184 {
3185         r_draw_ctx->ar = CTX_wm_region(C);
3186         r_draw_ctx->rv3d = CTX_wm_region_view3d(C);
3187         r_draw_ctx->v3d = CTX_wm_view3d(C);
3188
3189         r_draw_ctx->scene = CTX_data_scene(C);
3190         r_draw_ctx->sl = CTX_data_scene_layer(C);
3191         r_draw_ctx->obact = r_draw_ctx->sl->basact ? r_draw_ctx->sl->basact->object : NULL;
3192
3193         /* grr, cant avoid! */
3194         r_draw_ctx->evil_C = C;
3195 }
3196
3197
3198 const DRWContextState *DRW_context_state_get(void)
3199 {
3200         return &DST.draw_ctx;
3201 }
3202
3203 /** \} */
3204
3205
3206 /* -------------------------------------------------------------------- */
3207
3208 /** \name Init/Exit (DRW_engines)
3209  * \{ */
3210
3211 void DRW_engine_register(DrawEngineType *draw_engine_type)
3212 {
3213         BLI_addtail(&DRW_engines, draw_engine_type);
3214 }
3215
3216 void DRW_engines_register(void)
3217 {
3218 #ifdef WITH_CLAY_ENGINE
3219         RE_engines_register(NULL, &DRW_engine_viewport_clay_type);
3220 #endif
3221         RE_engines_register(NULL, &DRW_engine_viewport_eevee_type);
3222
3223         DRW_engine_register(&draw_engine_object_type);
3224         DRW_engine_register(&draw_engine_edit_armature_type);
3225         DRW_engine_register(&draw_engine_edit_curve_type);
3226         DRW_engine_register(&draw_engine_edit_lattice_type);
3227         DRW_engine_register(&draw_engine_edit_mesh_type);
3228         DRW_engine_register(&draw_engine_edit_metaball_type);
3229         DRW_engine_register(&draw_engine_edit_surface_type);
3230         DRW_engine_register(&draw_engine_edit_text_type);
3231         DRW_engine_register(&draw_engine_paint_texture_type);
3232         DRW_engine_register(&draw_engine_paint_vertex_type);
3233         DRW_engine_register(&draw_engine_paint_weight_type);
3234         DRW_engine_register(&draw_engine_particle_type);
3235         DRW_engine_register(&draw_engine_pose_type);
3236         DRW_engine_register(&draw_engine_sculpt_type);
3237
3238         /* setup callbacks */
3239         {
3240                 /* BKE: curve.c */
3241                 extern void *BKE_curve_batch_cache_dirty_cb;
3242                 extern void *BKE_curve_batch_cache_free_cb;
3243                 /* BKE: mesh.c */
3244                 extern void *BKE_mesh_batch_cache_dirty_cb;
3245                 extern void *BKE_mesh_batch_cache_free_cb;
3246                 /* BKE: lattice.c */
3247                 extern void *BKE_lattice_batch_cache_dirty_cb;
3248                 extern void *BKE_lattice_batch_cache_free_cb;
3249                 /* BKE: particle.c */
3250                 extern void *BKE_particle_batch_cache_dirty_cb;
3251                 extern void *BKE_particle_batch_cache_free_cb;
3252
3253                 BKE_curve_batch_cache_dirty_cb = DRW_curve_batch_cache_dirty;
3254                 BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free;
3255
3256                 BKE_mesh_batch_cache_dirty_cb = DRW_mesh_batch_cache_dirty;
3257                 BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free;
3258
3259                 BKE_lattice_batch_cache_dirty_cb = DRW_lattice_batch_cache_dirty;
3260                 BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free;
3261
3262                 BKE_particle_batch_cache_dirty_cb = DRW_particle_batch_cache_dirty;
3263                 BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free;
3264         }
3265 }
3266
3267 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
3268 void DRW_engines_free(void)
3269 {
3270         DRW_shape_cache_free();
3271
3272         DrawEngineType *next;
3273         for (DrawEngineType *type = DRW_engines.first; type; type = next) {
3274                 next = type->next;
3275                 BLI_remlink(&R_engines, type);
3276
3277                 if (type->engine_free) {
3278                         type->engine_free();
3279                 }
3280         }
3281
3282         if (globals_ubo)
3283                 GPU_uniformbuffer_free(globals_ubo);
3284
3285 #ifdef WITH_CLAY_ENGINE
3286         BLI_remlink(&R_engines, &DRW_engine_viewport_clay_type);
3287 #endif
3288 }
3289
3290 /** \} */