fdf99f906c65ed29554236a959e6faf5b9a3fec7
[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_global.h"
36
37 #include "BLT_translation.h"
38 #include "BLF_api.h"
39
40 #include "DRW_engine.h"
41 #include "DRW_render.h"
42
43 #include "DNA_view3d_types.h"
44 #include "DNA_screen_types.h"
45
46 #include "ED_space_api.h"
47 #include "ED_screen.h"
48
49 #include "GPU_batch.h"
50 #include "GPU_draw.h"
51 #include "GPU_extensions.h"
52 #include "GPU_framebuffer.h"
53 #include "GPU_lamp.h"
54 #include "GPU_shader.h"
55 #include "GPU_texture.h"
56 #include "GPU_uniformbuffer.h"
57 #include "GPU_viewport.h"
58 #include "GPU_matrix.h"
59
60 #include "PIL_time.h"
61
62 #include "RE_engine.h"
63
64 #include "UI_resources.h"
65
66 #include "draw_mode_engines.h"
67 #include "clay.h"
68 #include "eevee.h"
69
70 #define MAX_ATTRIB_NAME 32
71 #define MAX_PASS_NAME 32
72
73 extern char datatoc_gpu_shader_2D_vert_glsl[];
74 extern char datatoc_gpu_shader_3D_vert_glsl[];
75 extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
76
77 /* Structures */
78 typedef enum {
79         DRW_UNIFORM_BOOL,
80         DRW_UNIFORM_INT,
81         DRW_UNIFORM_FLOAT,
82         DRW_UNIFORM_TEXTURE,
83         DRW_UNIFORM_BUFFER,
84         DRW_UNIFORM_MAT3,
85         DRW_UNIFORM_MAT4,
86         DRW_UNIFORM_BLOCK
87 } DRWUniformType;
88
89 typedef enum {
90         DRW_ATTRIB_INT,
91         DRW_ATTRIB_FLOAT,
92 } DRWAttribType;
93
94 struct DRWUniform {
95         struct DRWUniform *next, *prev;
96         DRWUniformType type;
97         int location;
98         int length;
99         int arraysize;
100         int bindloc;
101         const void *value;
102 };
103
104 typedef struct DRWAttrib {
105         struct DRWAttrib *next, *prev;
106         char name[MAX_ATTRIB_NAME];
107         int location;
108         int format_id;
109         int size; /* number of component */
110         int type;
111 } DRWAttrib;
112
113 struct DRWInterface {
114         ListBase uniforms;   /* DRWUniform */
115         ListBase attribs;    /* DRWAttrib */
116         int attribs_count;
117         int attribs_stride;
118         int attribs_size[16];
119         int attribs_loc[16];
120         /* matrices locations */
121         int model;
122         int modelview;
123         int projection;
124         int view;
125         int modelviewprojection;
126         int viewprojection;
127         int normal;
128         int worldnormal;
129         int eye;
130         /* Dynamic batch */
131         GLuint instance_vbo;
132         int instance_count;
133         VertexFormat vbo_format;
134 };
135
136 struct DRWPass {
137         ListBase shgroups; /* DRWShadingGroup */
138         DRWState state;
139         char name[MAX_PASS_NAME];
140         /* use two query to not stall the cpu waiting for queries to complete */
141         unsigned int timer_queries[2];
142         /* alternate between front and back query */
143         unsigned int front_idx;
144         unsigned int back_idx;
145         bool wasdrawn; /* if it was drawn during this frame */
146 };
147
148 typedef struct DRWCall {
149         struct DRWCall *next, *prev;
150         Batch *geometry;
151         float (*obmat)[4];
152 } DRWCall;
153
154 typedef struct DRWDynamicCall {
155         struct DRWDynamicCall *next, *prev;
156         const void *data[];
157 } DRWDynamicCall;
158
159 struct DRWShadingGroup {
160         struct DRWShadingGroup *next, *prev;
161
162         struct GPUShader *shader;        /* Shader to bind */
163         struct DRWInterface *interface;  /* Uniforms pointers */
164         ListBase calls;                  /* DRWCall or DRWDynamicCall depending of type*/
165         DRWState state;                  /* State changes for this batch only */
166         int type;
167
168         Batch *instance_geom;  /* Geometry to instance */
169         Batch *batch_geom;     /* Result of call batching */
170 };
171
172 /* Used by DRWShadingGroup.type */
173 enum {
174         DRW_SHG_NORMAL,
175         DRW_SHG_POINT_BATCH,
176         DRW_SHG_LINE_BATCH,
177         DRW_SHG_INSTANCE,
178 };
179
180 /* only 16 bits long */
181 enum {
182         STENCIL_SELECT          = (1 << 0),
183         STENCIL_ACTIVE          = (1 << 1),
184 };
185
186 /* Render State */
187 static struct DRWGlobalState {
188         /* Rendering state */
189         GPUShader *shader;
190         ListBase bound_texs;
191         int tex_bind_id;
192
193         /* Per viewport */
194         GPUViewport *viewport;
195         struct GPUFrameBuffer *default_framebuffer;
196         float size[2];
197         float screenvecs[2][3];
198         float pixsize;
199
200         /* Current rendering context */
201         const struct bContext *context;
202         ListBase enabled_engines; /* RenderEngineType */
203 } DST = {NULL};
204
205 ListBase DRW_engines = {NULL, NULL};
206
207 /* ***************************************** TEXTURES ******************************************/
208 static void drw_texture_get_format(DRWTextureFormat format, GPUTextureFormat *data_type, int *channels)
209 {
210         switch (format) {
211                 case DRW_TEX_RGBA_8: *data_type = GPU_RGBA8; break;
212                 case DRW_TEX_RGBA_16: *data_type = GPU_RGBA16F; break;
213                 case DRW_TEX_RG_16: *data_type = GPU_RG16F; break;
214                 case DRW_TEX_RG_32: *data_type = GPU_RG32F; break;
215                 case DRW_TEX_R_8: *data_type = GPU_R8; break;
216                 case DRW_TEX_R_16: *data_type = GPU_R16F; break;
217 #if 0
218                 case DRW_TEX_RGBA_32: *data_type = GPU_RGBA32F; break;
219                 case DRW_TEX_RGB_8: *data_type = GPU_RGB8; break;
220                 case DRW_TEX_RGB_16: *data_type = GPU_RGB16F; break;
221                 case DRW_TEX_RGB_32: *data_type = GPU_RGB32F; break;
222                 case DRW_TEX_RG_8: *data_type = GPU_RG8; break;
223                 case DRW_TEX_R_32: *data_type = GPU_R32F; break;
224 #endif
225                 case DRW_TEX_DEPTH_16: *data_type = GPU_DEPTH_COMPONENT16; break;
226                 case DRW_TEX_DEPTH_24: *data_type = GPU_DEPTH_COMPONENT24; break;
227                 case DRW_TEX_DEPTH_32: *data_type = GPU_DEPTH_COMPONENT32F; break;
228                 default :
229                         /* file type not supported you must uncomment it from above */
230                         BLI_assert(false);
231                         break;
232         }
233
234         switch (format) {
235                 case DRW_TEX_RGBA_8:
236                 case DRW_TEX_RGBA_16:
237                 case DRW_TEX_RGBA_32:
238                         *channels = 4;
239                         break;
240                 case DRW_TEX_RGB_8:
241                 case DRW_TEX_RGB_16:
242                 case DRW_TEX_RGB_32:
243                         *channels = 3;
244                         break;
245                 case DRW_TEX_RG_8:
246                 case DRW_TEX_RG_16:
247                 case DRW_TEX_RG_32:
248                         *channels = 2;
249                         break;
250                 default:
251                         *channels = 1;
252                         break;
253         }
254 }
255
256 static void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags)
257 {
258         GPU_texture_bind(tex, 0);
259         GPU_texture_filter_mode(tex, flags & DRW_TEX_FILTER);
260         GPU_texture_wrap_mode(tex, flags & DRW_TEX_WRAP);
261         GPU_texture_compare_mode(tex, flags & DRW_TEX_COMPARE);
262         GPU_texture_unbind(tex);
263 }
264
265 GPUTexture *DRW_texture_create_1D(int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
266 {
267         GPUTexture *tex;
268         GPUTextureFormat data_type;
269         int channels;
270
271         drw_texture_get_format(format, &data_type, &channels);
272         tex = GPU_texture_create_1D_custom(w, channels, data_type, fpixels, NULL);
273         drw_texture_set_parameters(tex, flags);
274
275         return tex;
276 }
277
278 GPUTexture *DRW_texture_create_2D(int w, int h, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
279 {
280         GPUTexture *tex;
281         GPUTextureFormat data_type;
282         int channels;
283
284         drw_texture_get_format(format, &data_type, &channels);
285         tex = GPU_texture_create_2D_custom(w, h, channels, data_type, fpixels, NULL);
286         drw_texture_set_parameters(tex, flags);
287
288         return tex;
289 }
290
291 GPUTexture *DRW_texture_create_2D_array(int w, int h, int d, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
292 {
293         GPUTexture *tex;
294         GPUTextureFormat data_type;
295         int channels;
296
297         drw_texture_get_format(format, &data_type, &channels);
298         tex = GPU_texture_create_2D_array_custom(w, h, d, channels, data_type, fpixels, NULL);
299         drw_texture_set_parameters(tex, flags);
300
301         return tex;
302 }
303
304 GPUTexture *DRW_texture_create_cube(int w, DRWTextureFormat format, DRWTextureFlag flags, const float *fpixels)
305 {
306         GPUTexture *tex;
307         GPUTextureFormat data_type;
308         int channels;
309
310         drw_texture_get_format(format, &data_type, &channels);
311         tex = GPU_texture_create_cube_custom(w, channels, data_type, fpixels, NULL);
312         drw_texture_set_parameters(tex, flags);
313
314         return tex;
315 }
316
317 void DRW_texture_free(GPUTexture *tex)
318 {
319         GPU_texture_free(tex);
320 }
321
322
323 /* ************************************ UNIFORM BUFFER OBJECT **********************************/
324
325 GPUUniformBuffer *DRW_uniformbuffer_create(int size, const void *data)
326 {
327         return GPU_uniformbuffer_create(size, data, NULL);
328 }
329
330 void DRW_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
331 {
332         GPU_uniformbuffer_update(ubo, data);
333 }
334
335 void DRW_uniformbuffer_free(GPUUniformBuffer *ubo)
336 {
337         GPU_uniformbuffer_free(ubo);
338 }
339
340 /* ****************************************** SHADERS ******************************************/
341
342 GPUShader *DRW_shader_create(const char *vert, const char *geom, const char *frag, const char *defines)
343 {
344         return GPU_shader_create(vert, frag, geom, NULL, defines);
345 }
346
347 GPUShader *DRW_shader_create_with_lib(const char *vert, const char *geom, const char *frag, const char *lib, const char *defines)
348 {
349         GPUShader *sh;
350         char *vert_with_lib = NULL;
351         char *frag_with_lib = NULL;
352         char *geom_with_lib = NULL;
353
354         DynStr *ds_vert = BLI_dynstr_new();
355         BLI_dynstr_append(ds_vert, lib);
356         BLI_dynstr_append(ds_vert, vert);
357         vert_with_lib = BLI_dynstr_get_cstring(ds_vert);
358         BLI_dynstr_free(ds_vert);
359
360         DynStr *ds_frag = BLI_dynstr_new();
361         BLI_dynstr_append(ds_frag, lib);
362         BLI_dynstr_append(ds_frag, frag);
363         frag_with_lib = BLI_dynstr_get_cstring(ds_frag);
364         BLI_dynstr_free(ds_frag);
365
366         if (geom) {
367                 DynStr *ds_geom = BLI_dynstr_new();
368                 BLI_dynstr_append(ds_geom, lib);
369                 BLI_dynstr_append(ds_geom, geom);
370                 geom_with_lib = BLI_dynstr_get_cstring(ds_geom);
371                 BLI_dynstr_free(ds_geom);
372         }
373
374         sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines);
375
376         MEM_freeN(vert_with_lib);
377         MEM_freeN(frag_with_lib);
378         if (geom) {
379                 MEM_freeN(geom_with_lib);
380         }
381
382         return sh;
383 }
384
385 GPUShader *DRW_shader_create_2D(const char *frag, const char *defines)
386 {
387         return GPU_shader_create(datatoc_gpu_shader_2D_vert_glsl, frag, NULL, NULL, defines);
388 }
389
390 GPUShader *DRW_shader_create_3D(const char *frag, const char *defines)
391 {
392         return GPU_shader_create(datatoc_gpu_shader_3D_vert_glsl, frag, NULL, NULL, defines);
393 }
394
395 GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines)
396 {
397         return GPU_shader_create(datatoc_gpu_shader_fullscreen_vert_glsl, frag, NULL, NULL, defines);
398 }
399
400 GPUShader *DRW_shader_create_3D_depth_only(void)
401 {
402         return GPU_shader_get_builtin_shader(GPU_SHADER_3D_DEPTH_ONLY);
403 }
404
405 void DRW_shader_free(GPUShader *shader)
406 {
407         GPU_shader_free(shader);
408 }
409
410 /* ***************************************** INTERFACE ******************************************/
411
412 static DRWInterface *DRW_interface_create(GPUShader *shader)
413 {
414         DRWInterface *interface = MEM_mallocN(sizeof(DRWInterface), "DRWInterface");
415
416         interface->model = GPU_shader_get_uniform(shader, "ModelMatrix");
417         interface->modelview = GPU_shader_get_uniform(shader, "ModelViewMatrix");
418         interface->projection = GPU_shader_get_uniform(shader, "ProjectionMatrix");
419         interface->view = GPU_shader_get_uniform(shader, "ViewMatrix");
420         interface->viewprojection = GPU_shader_get_uniform(shader, "ViewProjectionMatrix");
421         interface->modelviewprojection = GPU_shader_get_uniform(shader, "ModelViewProjectionMatrix");
422         interface->normal = GPU_shader_get_uniform(shader, "NormalMatrix");
423         interface->worldnormal = GPU_shader_get_uniform(shader, "WorldNormalMatrix");
424         interface->eye = GPU_shader_get_uniform(shader, "eye");
425         interface->instance_count = 0;
426         interface->attribs_count = 0;
427         interface->attribs_stride = 0;
428         interface->instance_vbo = 0;
429
430         memset(&interface->vbo_format, 0, sizeof(VertexFormat));
431
432         BLI_listbase_clear(&interface->uniforms);
433         BLI_listbase_clear(&interface->attribs);
434
435         return interface;
436 }
437
438 static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name,
439                                   DRWUniformType type, const void *value, int length, int arraysize, int bindloc)
440 {
441         DRWUniform *uni = MEM_mallocN(sizeof(DRWUniform), "DRWUniform");
442
443         if (type == DRW_UNIFORM_BLOCK) {
444                 uni->location = GPU_shader_get_uniform_block(shgroup->shader, name);
445         }
446         else {
447                 uni->location = GPU_shader_get_uniform(shgroup->shader, name);
448         }
449
450         uni->type = type;
451         uni->value = value;
452         uni->length = length;
453         uni->arraysize = arraysize;
454         uni->bindloc = bindloc; /* for textures */
455
456         if (uni->location == -1) {
457                 if (G.debug & G_DEBUG)
458                         fprintf(stderr, "Uniform '%s' not found!\n", name);
459
460                 MEM_freeN(uni);
461                 return;
462         }
463
464         BLI_addtail(&shgroup->interface->uniforms, uni);
465 }
466
467 static void DRW_interface_attrib(DRWShadingGroup *shgroup, const char *name, DRWAttribType type, int size)
468 {
469         DRWAttrib *attrib = MEM_mallocN(sizeof(DRWAttrib), "DRWAttrib");
470         GLuint program = GPU_shader_get_program(shgroup->shader);
471
472         attrib->location = glGetAttribLocation(program, name);
473         attrib->type = type;
474         attrib->size = size;
475
476         if (attrib->location == -1) {
477                 if (G.debug & G_DEBUG)
478                         fprintf(stderr, "Attribute '%s' not found!\n", name);
479
480                 MEM_freeN(attrib);
481                 return;
482         }
483
484         BLI_assert(BLI_strnlen(name, 32) < 32);
485         BLI_strncpy(attrib->name, name, 32);
486
487         shgroup->interface->attribs_count += 1;
488
489         BLI_addtail(&shgroup->interface->attribs, attrib);
490 }
491
492 void DRW_get_dfdy_factors(float dfdyfac[2])
493 {
494         GPU_get_dfdy_factors(dfdyfac);
495 }
496
497 /* ***************************************** SHADING GROUP ******************************************/
498
499 DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
500 {
501         DRWShadingGroup *shgroup = MEM_mallocN(sizeof(DRWShadingGroup), "DRWShadingGroup");
502
503         shgroup->type = DRW_SHG_NORMAL;
504         shgroup->shader = shader;
505         shgroup->interface = DRW_interface_create(shader);
506         shgroup->state = 0;
507         shgroup->batch_geom = NULL;
508         shgroup->instance_geom = NULL;
509
510         BLI_addtail(&pass->shgroups, shgroup);
511         BLI_listbase_clear(&shgroup->calls);
512
513         return shgroup;
514 }
515
516 DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, Batch *geom)
517 {
518         DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
519
520         shgroup->type = DRW_SHG_INSTANCE;
521         shgroup->instance_geom = geom;
522
523         return shgroup;
524 }
525
526 DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass)
527 {
528         DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
529
530         shgroup->type = DRW_SHG_POINT_BATCH;
531         DRW_shgroup_attrib_float(shgroup, "pos", 3);
532
533         return shgroup;
534 }
535
536 DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass)
537 {
538         DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
539
540         shgroup->type = DRW_SHG_LINE_BATCH;
541         DRW_shgroup_attrib_float(shgroup, "pos", 3);
542
543         return shgroup;
544 }
545
546 void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
547 {
548         BLI_freelistN(&shgroup->calls);
549         BLI_freelistN(&shgroup->interface->uniforms);
550         BLI_freelistN(&shgroup->interface->attribs);
551
552         if (shgroup->interface->instance_vbo) {
553                 glDeleteBuffers(1, &shgroup->interface->instance_vbo);
554         }
555
556         MEM_freeN(shgroup->interface);
557
558         if (shgroup->batch_geom) {
559                 Batch_discard_all(shgroup->batch_geom);
560         }
561 }
562
563 void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[4])
564 {
565         BLI_assert(geom != NULL);
566
567         DRWCall *call = MEM_callocN(sizeof(DRWCall), "DRWCall");
568
569         call->obmat = obmat;
570         call->geometry = geom;
571
572         BLI_addtail(&shgroup->calls, call);
573 }
574
575 void DRW_shgroup_dynamic_call_add_array(DRWShadingGroup *shgroup, const void *attr[], unsigned int attr_len)
576 {
577         DRWInterface *interface = shgroup->interface;
578         unsigned int data_size = sizeof(void *) * interface->attribs_count;
579         int size = sizeof(ListBase) + data_size;
580
581         DRWDynamicCall *call = MEM_callocN(size, "DRWDynamicCall");
582
583         BLI_assert(attr_len == interface->attribs_count);
584
585         memcpy((void *) call->data, attr, data_size);
586
587         interface->instance_count += 1;
588
589         BLI_addtail(&shgroup->calls, call);
590 }
591
592 /* Make sure you know what you do when using this,
593  * State is not revert back at the end of the shgroup */
594 void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state)
595 {
596         shgroup->state = state;
597 }
598
599 void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size)
600 {
601         DRW_interface_attrib(shgroup, name, DRW_ATTRIB_FLOAT, size);
602 }
603
604 void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex, int loc)
605 {
606         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_TEXTURE, tex, 0, 0, loc);
607 }
608
609 void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuffer *ubo, int loc)
610 {
611         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BLOCK, ubo, 0, 0, loc);
612 }
613
614 void DRW_shgroup_uniform_buffer(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex, int loc)
615 {
616         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BUFFER, tex, 0, 0, loc);
617 }
618
619 void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const bool *value, int arraysize)
620 {
621         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_BOOL, value, 1, arraysize, 0);
622 }
623
624 void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
625 {
626         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 1, arraysize, 0);
627 }
628
629 void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
630 {
631         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 2, arraysize, 0);
632 }
633
634 void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
635 {
636         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 3, arraysize, 0);
637 }
638
639 void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
640 {
641         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_FLOAT, value, 4, arraysize, 0);
642 }
643
644 void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
645 {
646         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 1, arraysize, 0);
647 }
648
649 void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
650 {
651         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 2, arraysize, 0);
652 }
653
654 void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
655 {
656         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_INT, value, 3, arraysize, 0);
657 }
658
659 void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float *value)
660 {
661         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT3, value, 9, 1, 0);
662 }
663
664 void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float *value)
665 {
666         DRW_interface_uniform(shgroup, name, DRW_UNIFORM_MAT4, value, 16, 1, 0);
667 }
668
669 #ifdef WITH_CLAY_ENGINE
670
671 /* Creates a VBO containing OGL primitives for all DRWDynamicCall */
672 static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
673 {
674         DRWInterface *interface = shgroup->interface;
675         int nbr = interface->instance_count;
676
677         PrimitiveType type = (shgroup->type == DRW_SHG_POINT_BATCH) ? PRIM_POINTS : PRIM_LINES;
678
679         if (nbr == 0)
680                 return;
681
682         /* Upload Data */
683         if (interface->vbo_format.attrib_ct == 0) {
684                 for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next) {
685                         BLI_assert(attrib->size <= 4); /* matrices have no place here for now */
686                         if (attrib->type == DRW_ATTRIB_FLOAT) {
687                                 attrib->format_id = VertexFormat_add_attrib(&interface->vbo_format, attrib->name, COMP_F32, attrib->size, KEEP_FLOAT);
688                         }
689                         else if (attrib->type == DRW_ATTRIB_INT) {
690                                 attrib->format_id = VertexFormat_add_attrib(&interface->vbo_format, attrib->name, COMP_I8, attrib->size, KEEP_INT);
691                         }
692                         else {
693                                 BLI_assert(false);
694                         }
695                 }
696         }
697
698         VertexBuffer *vbo = VertexBuffer_create_with_format(&interface->vbo_format);
699         VertexBuffer_allocate_data(vbo, nbr);
700
701         int j = 0;
702         for (DRWDynamicCall *call = shgroup->calls.first; call; call = call->next, j++) {
703                 int i = 0;
704                 for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
705                         VertexBuffer_set_attrib(vbo, attrib->format_id, j, call->data[i]);
706                 }
707         }
708
709         /* TODO make the batch dynamic instead of freeing it every times */
710         if (shgroup->batch_geom)
711                 Batch_discard_all(shgroup->batch_geom);
712
713         shgroup->batch_geom = Batch_create(type, vbo, NULL);
714 }
715
716 static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
717 {
718         int i = 0;
719         int offset = 0;
720         DRWInterface *interface = shgroup->interface;
721         int vert_nbr = interface->instance_count;
722         int buffer_size = 0;
723
724         if (vert_nbr == 0) {
725                 if (interface->instance_vbo) {
726                         glDeleteBuffers(1, &interface->instance_vbo);
727                         interface->instance_vbo = 0;
728                 }
729                 return;
730         }
731
732         /* only once */
733         if (interface->attribs_stride == 0) {
734                 for (DRWAttrib *attrib = interface->attribs.first; attrib; attrib = attrib->next, i++) {
735                         BLI_assert(attrib->type == DRW_ATTRIB_FLOAT); /* Only float for now */
736                         interface->attribs_stride += attrib->size;
737                         interface->attribs_size[i] = attrib->size;
738                         interface->attribs_loc[i] = attrib->location;
739                 }
740         }
741
742         /* Gather Data */
743         buffer_size = sizeof(float) * interface->attribs_stride * vert_nbr;
744         float *data = MEM_mallocN(buffer_size, "Instance VBO data");
745
746         for (DRWDynamicCall *call = shgroup->calls.first; call; call = call->next) {
747                 for (int j = 0; j < interface->attribs_count; ++j) {
748                         memcpy(data + offset, call->data[j], sizeof(float) * interface->attribs_size[j]);
749                         offset += interface->attribs_size[j];
750                 }
751         }
752
753         /* TODO poke mike to add this to gawain */
754         if (interface->instance_vbo) {
755                 glDeleteBuffers(1, &interface->instance_vbo);
756                 interface->instance_vbo = 0;
757         }
758
759         glGenBuffers(1, &interface->instance_vbo);
760         glBindBuffer(GL_ARRAY_BUFFER, interface->instance_vbo);
761         glBufferData(GL_ARRAY_BUFFER, buffer_size, data, GL_STATIC_DRAW);
762
763         MEM_freeN(data);
764 }
765
766 static void shgroup_dynamic_batch_from_calls(DRWShadingGroup *shgroup)
767 {
768         if ((shgroup->interface->instance_vbo || shgroup->batch_geom) &&
769             (G.debug_value == 667))
770         {
771                 return;
772         }
773
774         if (shgroup->type == DRW_SHG_INSTANCE) {
775                 shgroup_dynamic_instance(shgroup);
776         }
777         else {
778                 shgroup_dynamic_batch(shgroup);
779         }
780 }
781 #endif  /* WITH_CLAY_ENGINE */
782
783 /* ***************************************** PASSES ******************************************/
784
785 DRWPass *DRW_pass_create(const char *name, DRWState state)
786 {
787         DRWPass *pass = MEM_callocN(sizeof(DRWPass), name);
788         pass->state = state;
789         BLI_strncpy(pass->name, name, MAX_PASS_NAME);
790
791         BLI_listbase_clear(&pass->shgroups);
792
793         return pass;
794 }
795
796 void DRW_pass_free(DRWPass *pass)
797 {
798         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
799                 DRW_shgroup_free(shgroup);
800         }
801
802         glDeleteQueries(2, pass->timer_queries);
803         BLI_freelistN(&pass->shgroups);
804 }
805
806 /* ****************************************** DRAW ******************************************/
807
808 #ifdef WITH_CLAY_ENGINE
809 static void set_state(DRWState flag, const bool reset)
810 {
811         /* TODO Keep track of the state and only revert what is needed */
812
813         if (reset) {
814                 /* Depth Write */
815                 if (flag & DRW_STATE_WRITE_DEPTH)
816                         glDepthMask(GL_TRUE);
817                 else
818                         glDepthMask(GL_FALSE);
819
820                 /* Color Write */
821                 if (flag & DRW_STATE_WRITE_COLOR)
822                         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
823                 else
824                         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
825
826                 /* Backface Culling */
827                 if (flag & DRW_STATE_CULL_BACK ||
828                     flag & DRW_STATE_CULL_FRONT)
829                 {
830                         glEnable(GL_CULL_FACE);
831
832                         if (flag & DRW_STATE_CULL_BACK)
833                                 glCullFace(GL_BACK);
834                         else if (flag & DRW_STATE_CULL_FRONT)
835                                 glCullFace(GL_FRONT);
836                 }
837                 else {
838                         glDisable(GL_CULL_FACE);
839                 }
840
841                 /* Depht Test */
842                 if (flag & (DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER))
843                 {
844                         glEnable(GL_DEPTH_TEST);
845
846                         if (flag & DRW_STATE_DEPTH_LESS)
847                                 glDepthFunc(GL_LEQUAL);
848                         else if (flag & DRW_STATE_DEPTH_EQUAL)
849                                 glDepthFunc(GL_EQUAL);
850                         else if (flag & DRW_STATE_DEPTH_GREATER)
851                                 glDepthFunc(GL_GREATER);
852                 }
853                 else {
854                         glDisable(GL_DEPTH_TEST);
855                 }
856         }
857
858         /* Wire Width */
859         if (flag & DRW_STATE_WIRE) {
860                 glLineWidth(1.0f);
861         }
862         else if (flag & DRW_STATE_WIRE_LARGE) {
863                 glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
864         }
865
866         /* Points Size */
867         if (flag & DRW_STATE_POINT) {
868                 GPU_enable_program_point_size();
869                 glPointSize(5.0f);
870         }
871         else if (reset) {
872                 GPU_disable_program_point_size();
873         }
874
875         /* Blending (all buffer) */
876         if (flag & DRW_STATE_BLEND) {
877                 glEnable(GL_BLEND);
878                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
879         }
880         else if (reset) {
881                 glDisable(GL_BLEND);
882         }
883
884         /* Line Stipple */
885         if (flag & DRW_STATE_STIPPLE_2) {
886                 setlinestyle(2);
887         }
888         else if (flag & DRW_STATE_STIPPLE_3) {
889                 setlinestyle(3);
890         }
891         else if (flag & DRW_STATE_STIPPLE_4) {
892                 setlinestyle(4);
893         }
894         else if (reset) {
895                 setlinestyle(0);
896         }
897
898         /* Stencil */
899         if (flag & (DRW_STATE_WRITE_STENCIL_SELECT | DRW_STATE_WRITE_STENCIL_ACTIVE |
900                     DRW_STATE_TEST_STENCIL_SELECT | DRW_STATE_TEST_STENCIL_ACTIVE))
901         {
902                 glEnable(GL_STENCIL_TEST);
903
904                 /* Stencil Write */
905                 if (flag & DRW_STATE_WRITE_STENCIL_SELECT) {
906                         glStencilMask(STENCIL_SELECT);
907                         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
908                         glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_SELECT);
909                 }
910                 else if (flag & DRW_STATE_WRITE_STENCIL_ACTIVE) {
911                         glStencilMask(STENCIL_ACTIVE);
912                         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
913                         glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_ACTIVE);
914                 }
915                 /* Stencil Test */
916                 else if (flag & DRW_STATE_TEST_STENCIL_SELECT) {
917                         glStencilMask(0x00); /* disable write */
918                         glStencilFunc(GL_NOTEQUAL, 0xFF, STENCIL_SELECT);
919                 }
920                 else if (flag & DRW_STATE_TEST_STENCIL_ACTIVE) {
921                         glStencilMask(0x00); /* disable write */
922                         glStencilFunc(GL_NOTEQUAL, 0xFF, STENCIL_ACTIVE);
923                 }
924         }
925         else if (reset) {
926                 /* disable write & test */
927                 glStencilMask(0x00);
928                 glStencilFunc(GL_ALWAYS, 1, 0xFF);
929                 glDisable(GL_STENCIL_TEST);
930         }
931 }
932
933 typedef struct DRWBoundTexture {
934         struct DRWBoundTexture *next, *prev;
935         GPUTexture *tex;
936 } DRWBoundTexture;
937
938 static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*obmat)[4])
939 {
940         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
941         DRWInterface *interface = shgroup->interface;
942
943         float mvp[4][4], mv[4][4], n[3][3], wn[3][3];
944         float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
945
946         bool do_mvp = (interface->modelviewprojection != -1);
947         bool do_mv = (interface->modelview != -1);
948         bool do_n = (interface->normal != -1);
949         bool do_wn = (interface->worldnormal != -1);
950         bool do_eye = (interface->eye != -1);
951
952         if (do_mvp) {
953                 mul_m4_m4m4(mvp, rv3d->persmat, obmat);
954         }
955         if (do_mv || do_n || do_eye) {
956                 mul_m4_m4m4(mv, rv3d->viewmat, obmat);
957         }
958         if (do_n || do_eye) {
959                 copy_m3_m4(n, mv);
960                 invert_m3(n);
961                 transpose_m3(n);
962         }
963         if (do_wn) {
964                 copy_m3_m4(wn, obmat);
965                 invert_m3(wn);
966                 transpose_m3(wn);
967         }
968         if (do_eye) {
969                 /* Used by orthographic wires */
970                 float tmp[3][3];
971                 invert_m3_m3(tmp, n);
972                 /* set eye vector, transformed to object coords */
973                 mul_m3_v3(tmp, eye);
974         }
975
976         /* Should be really simple */
977         /* step 1 : bind object dependent matrices */
978         if (interface->model != -1) {
979                 GPU_shader_uniform_vector(shgroup->shader, interface->model, 16, 1, (float *)obmat);
980         }
981         if (interface->modelviewprojection != -1) {
982                 GPU_shader_uniform_vector(shgroup->shader, interface->modelviewprojection, 16, 1, (float *)mvp);
983         }
984         if (interface->viewprojection != -1) {
985                 GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)rv3d->persmat);
986         }
987         if (interface->projection != -1) {
988                 GPU_shader_uniform_vector(shgroup->shader, interface->projection, 16, 1, (float *)rv3d->winmat);
989         }
990         if (interface->view != -1) {
991                 GPU_shader_uniform_vector(shgroup->shader, interface->view, 16, 1, (float *)rv3d->viewmat);
992         }
993         if (interface->modelview != -1) {
994                 GPU_shader_uniform_vector(shgroup->shader, interface->modelview, 16, 1, (float *)mv);
995         }
996         if (interface->normal != -1) {
997                 GPU_shader_uniform_vector(shgroup->shader, interface->normal, 9, 1, (float *)n);
998         }
999         if (interface->worldnormal != -1) {
1000                 GPU_shader_uniform_vector(shgroup->shader, interface->worldnormal, 9, 1, (float *)wn);
1001         }
1002         if (interface->eye != -1) {
1003                 GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye);
1004         }
1005
1006         /* step 2 : bind vertex array & draw */
1007         Batch_set_program(geom, GPU_shader_get_program(shgroup->shader));
1008         if (interface->instance_vbo) {
1009                 Batch_draw_stupid_instanced(geom, interface->instance_vbo, interface->instance_count, interface->attribs_count,
1010                                             interface->attribs_stride, interface->attribs_size, interface->attribs_loc);
1011         }
1012         else {
1013                 Batch_draw_stupid(geom);
1014         }
1015 }
1016
1017 static void draw_shgroup(DRWShadingGroup *shgroup)
1018 {
1019         BLI_assert(shgroup->shader);
1020         BLI_assert(shgroup->interface);
1021
1022         DRWInterface *interface = shgroup->interface;
1023         GPUTexture *tex;
1024
1025         if (DST.shader != shgroup->shader) {
1026                 if (DST.shader) GPU_shader_unbind();
1027                 GPU_shader_bind(shgroup->shader);
1028                 DST.shader = shgroup->shader;
1029         }
1030
1031         if (shgroup->type != DRW_SHG_NORMAL) {
1032                 shgroup_dynamic_batch_from_calls(shgroup);
1033         }
1034
1035         if (shgroup->state != 0) {
1036                 set_state(shgroup->state, false);
1037         }
1038
1039         /* Binding Uniform */
1040         /* Don't check anything, Interface should already contain the least uniform as possible */
1041         for (DRWUniform *uni = interface->uniforms.first; uni; uni = uni->next) {
1042                 DRWBoundTexture *bound_tex;
1043
1044                 switch (uni->type) {
1045                         case DRW_UNIFORM_BOOL:
1046                         case DRW_UNIFORM_INT:
1047                                 GPU_shader_uniform_vector_int(shgroup->shader, uni->location, uni->length, uni->arraysize, (int *)uni->value);
1048                                 break;
1049                         case DRW_UNIFORM_FLOAT:
1050                         case DRW_UNIFORM_MAT3:
1051                         case DRW_UNIFORM_MAT4:
1052                                 GPU_shader_uniform_vector(shgroup->shader, uni->location, uni->length, uni->arraysize, (float *)uni->value);
1053                                 break;
1054                         case DRW_UNIFORM_TEXTURE:
1055                                 tex = (GPUTexture *)uni->value;
1056                                 GPU_texture_bind(tex, uni->bindloc);
1057
1058                                 bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
1059                                 bound_tex->tex = tex;
1060                                 BLI_addtail(&DST.bound_texs, bound_tex);
1061
1062                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
1063                                 break;
1064                         case DRW_UNIFORM_BUFFER:
1065                                 tex = *((GPUTexture **)uni->value);
1066                                 GPU_texture_bind(tex, uni->bindloc);
1067                                 GPU_texture_compare_mode(tex, false);
1068                                 GPU_texture_filter_mode(tex, false);
1069
1070                                 bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
1071                                 bound_tex->tex = tex;
1072                                 BLI_addtail(&DST.bound_texs, bound_tex);
1073
1074                                 GPU_shader_uniform_texture(shgroup->shader, uni->location, tex);
1075                                 break;
1076                         case DRW_UNIFORM_BLOCK:
1077                                 GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
1078                                 GPU_shader_uniform_buffer(shgroup->shader, uni->location, (GPUUniformBuffer *)uni->value);
1079                                 break;
1080                 }
1081         }
1082
1083         /* Rendering Calls */
1084         if (shgroup->type != DRW_SHG_NORMAL) {
1085                 /* Replacing multiple calls with only one */
1086                 float obmat[4][4];
1087                 unit_m4(obmat);
1088
1089                 if (shgroup->type == DRW_SHG_INSTANCE && interface->instance_count > 0) {
1090                         draw_geometry(shgroup, shgroup->instance_geom, obmat);
1091                 }
1092                 else {
1093                         /* Some dynamic batch can have no geom (no call to aggregate) */
1094                         if (shgroup->batch_geom) {
1095                                 draw_geometry(shgroup, shgroup->batch_geom, obmat);
1096                         }
1097                 }
1098         }
1099         else {
1100                 for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
1101                         draw_geometry(shgroup, call->geometry, call->obmat);
1102                 }
1103         }
1104 }
1105
1106 void DRW_draw_pass(DRWPass *pass)
1107 {
1108         /* Start fresh */
1109         DST.shader = NULL;
1110         DST.tex_bind_id = 0;
1111
1112         set_state(pass->state, true);
1113         BLI_listbase_clear(&DST.bound_texs);
1114
1115         pass->wasdrawn = true;
1116
1117         /* Init Timer queries */
1118         if (pass->timer_queries[0] == 0) {
1119                 pass->front_idx = 0;
1120                 pass->back_idx = 1;
1121
1122                 glGenQueries(2, pass->timer_queries);
1123
1124                 /* dummy query, avoid gl error */
1125                 glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->front_idx]);
1126                 glEndQuery(GL_TIME_ELAPSED);
1127         }
1128         else {
1129                 /* swap indices */
1130                 unsigned int tmp = pass->back_idx;
1131                 pass->back_idx = pass->front_idx;
1132                 pass->front_idx = tmp;
1133         }
1134
1135         /* issue query for the next frame */
1136         glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->back_idx]);
1137
1138         for (DRWShadingGroup *shgroup = pass->shgroups.first; shgroup; shgroup = shgroup->next) {
1139                 draw_shgroup(shgroup);
1140         }
1141
1142         /* Clear Bound textures */
1143         for (DRWBoundTexture *bound_tex = DST.bound_texs.first; bound_tex; bound_tex = bound_tex->next) {
1144                 GPU_texture_unbind(bound_tex->tex);
1145         }
1146         DST.tex_bind_id = 0;
1147         BLI_freelistN(&DST.bound_texs);
1148
1149         if (DST.shader) {
1150                 GPU_shader_unbind();
1151                 DST.shader = NULL;
1152         }
1153
1154         glEndQuery(GL_TIME_ELAPSED);
1155 }
1156
1157 void DRW_draw_callbacks_pre_scene(void)
1158 {
1159         struct ARegion *ar = CTX_wm_region(DST.context);
1160         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
1161
1162         gpuLoadProjectionMatrix3D(rv3d->winmat);
1163         gpuLoadMatrix3D(rv3d->viewmat);
1164
1165         ED_region_draw_cb_draw(DST.context, ar, REGION_DRAW_PRE_VIEW);
1166 }
1167
1168 void DRW_draw_callbacks_post_scene(void)
1169 {
1170         struct ARegion *ar = CTX_wm_region(DST.context);
1171         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
1172
1173         gpuLoadProjectionMatrix3D(rv3d->winmat);
1174         gpuLoadMatrix3D(rv3d->viewmat);
1175
1176         ED_region_draw_cb_draw(DST.context, ar, REGION_DRAW_POST_VIEW);
1177 }
1178
1179 /* Reset state to not interfer with other UI drawcall */
1180 void DRW_state_reset(void)
1181 {
1182         DRWState state = 0;
1183         state |= DRW_STATE_WRITE_DEPTH;
1184         state |= DRW_STATE_WRITE_COLOR;
1185         state |= DRW_STATE_DEPTH_LESS;
1186         set_state(state, true);
1187 }
1188
1189 #else  /* !WITH_CLAY_ENGINE */
1190
1191 void DRW_draw_pass(DRWPass *UNUSED(pass)) {}
1192 void DRW_draw_callbacks_pre_scene(void) {}
1193 void DRW_draw_callbacks_post_scene(void) {}
1194 void DRW_state_reset(void) {}
1195
1196 #endif  /* WITH_CLAY_ENGINE */
1197
1198
1199 /* ****************************************** Settings ******************************************/
1200
1201 bool DRW_is_object_renderable(Object *ob)
1202 {
1203         Scene *scene = CTX_data_scene(DST.context);
1204         Object *obedit = scene->obedit;
1205
1206         if (ob->type == OB_MESH) {
1207                 if (ob == obedit) {
1208                         IDProperty *props = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
1209                         bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(props, "show_occlude_wire");
1210
1211                         if (do_occlude_wire)
1212                                 return false;
1213                 }
1214         }
1215
1216         return true;
1217 }
1218
1219 /* ****************************************** Framebuffers ******************************************/
1220
1221 static GPUTextureFormat convert_tex_format(int fbo_format, int *channels, bool *is_depth)
1222 {
1223         *is_depth = ((fbo_format == DRW_BUF_DEPTH_16) ||
1224                      (fbo_format == DRW_BUF_DEPTH_24));
1225
1226         switch (fbo_format) {
1227                 case DRW_BUF_RGBA_8:   *channels = 4; return GPU_RGBA8;
1228                 case DRW_BUF_RGBA_16:  *channels = 4; return GPU_RGBA16F;
1229                 case DRW_BUF_DEPTH_24: *channels = 1; return GPU_DEPTH_COMPONENT24;
1230                 default:
1231                         BLI_assert(false);
1232                         *channels = 4; return GPU_RGBA8;
1233         }
1234 }
1235
1236 void DRW_framebuffer_init(struct GPUFrameBuffer **fb, int width, int height, DRWFboTexture textures[MAX_FBO_TEX],
1237                           int texnbr)
1238 {
1239         BLI_assert(texnbr <= MAX_FBO_TEX);
1240
1241         if (!*fb) {
1242                 int color_attachment = -1;
1243                 *fb = GPU_framebuffer_create();
1244
1245                 for (int i = 0; i < texnbr; ++i) {
1246                         DRWFboTexture fbotex = textures[i];
1247
1248                         if (!*fbotex.tex) {
1249                                 int channels;
1250                                 bool is_depth;
1251                                 GPUTextureFormat gpu_format = convert_tex_format(fbotex.format, &channels, &is_depth);
1252
1253                                 *fbotex.tex = GPU_texture_create_2D_custom(width, height, channels, gpu_format, NULL, NULL);
1254                                 drw_texture_set_parameters(*fbotex.tex, fbotex.flag);
1255
1256                                 if (!is_depth) {
1257                                         ++color_attachment;
1258                                 }
1259                         }
1260
1261                         GPU_framebuffer_texture_attach(*fb, *fbotex.tex, color_attachment);
1262                 }
1263
1264                 if (!GPU_framebuffer_check_valid(*fb, NULL)) {
1265                         printf("Error invalid framebuffer\n");
1266                 }
1267
1268                 GPU_framebuffer_bind(DST.default_framebuffer);
1269         }
1270 }
1271
1272 void DRW_framebuffer_bind(struct GPUFrameBuffer *fb)
1273 {
1274         GPU_framebuffer_bind(fb);
1275 }
1276
1277 void DRW_framebuffer_clear(bool color, bool depth, bool stencil, float clear_col[4], float clear_depth)
1278 {
1279         if (color) {
1280                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1281                 glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]);
1282         }
1283         if (depth) {
1284                 glDepthMask(GL_TRUE);
1285                 glClearDepth(clear_depth);
1286         }
1287         if (stencil) {
1288                 glStencilMask(0xFF);
1289         }
1290         glClear(((color) ? GL_COLOR_BUFFER_BIT : 0) |
1291                 ((depth) ? GL_DEPTH_BUFFER_BIT : 0) |
1292                 ((stencil) ? GL_STENCIL_BUFFER_BIT : 0));
1293 }
1294
1295 void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, GPUTexture *tex, int slot)
1296 {
1297         GPU_framebuffer_texture_attach(fb, tex, slot);
1298 }
1299
1300 void DRW_framebuffer_texture_detach(GPUTexture *tex)
1301 {
1302         GPU_framebuffer_texture_detach(tex);
1303 }
1304
1305 void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer *fb_write, bool depth)
1306 {
1307         GPU_framebuffer_blit(fb_read, 0, fb_write, 0, depth);
1308 }
1309
1310 /* ****************************************** Viewport ******************************************/
1311 static void *DRW_viewport_engine_data_get(void *engine_type)
1312 {
1313         void *data = GPU_viewport_engine_data_get(DST.viewport, engine_type);
1314
1315         if (data == NULL) {
1316                 data = GPU_viewport_engine_data_create(DST.viewport, engine_type);
1317         }
1318         return data;
1319 }
1320
1321 float *DRW_viewport_size_get(void)
1322 {
1323         return &DST.size[0];
1324 }
1325
1326 float *DRW_viewport_screenvecs_get(void)
1327 {
1328         return &DST.screenvecs[0][0];
1329 }
1330
1331 float *DRW_viewport_pixelsize_get(void)
1332 {
1333         return &DST.pixsize;
1334 }
1335
1336 /* It also stores viewport variable to an immutable place: DST
1337  * This is because a cache uniform only store reference
1338  * to its value. And we don't want to invalidate the cache
1339  * if this value change per viewport */
1340 static void DRW_viewport_var_init(const bContext *C)
1341 {
1342         RegionView3D *rv3d = CTX_wm_region_view3d(C);
1343
1344         /* Refresh DST.size */
1345         int size[2];
1346         GPU_viewport_size_get(DST.viewport, size);
1347         DST.size[0] = size[0];
1348         DST.size[1] = size[1];
1349
1350         DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport);
1351         DST.default_framebuffer = fbl->default_fb;
1352
1353         /* Refresh DST.screenvecs */
1354         copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
1355         copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
1356         normalize_v3(DST.screenvecs[0]);
1357         normalize_v3(DST.screenvecs[1]);
1358
1359         /* Refresh DST.pixelsize */
1360         DST.pixsize = rv3d->pixsize;
1361
1362         /* Save context for all later needs */
1363         DST.context = C;
1364 }
1365
1366 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
1367 {
1368         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
1369
1370         if (type == DRW_MAT_PERS)
1371                 copy_m4_m4(mat, rv3d->persmat);
1372         else if (type == DRW_MAT_VIEW)
1373                 copy_m4_m4(mat, rv3d->viewmat);
1374         else if (type == DRW_MAT_VIEWINV)
1375                 copy_m4_m4(mat, rv3d->viewinv);
1376         else if (type == DRW_MAT_WIN)
1377                 copy_m4_m4(mat, rv3d->winmat);
1378 }
1379
1380 bool DRW_viewport_is_persp_get(void)
1381 {
1382         RegionView3D *rv3d = CTX_wm_region_view3d(DST.context);
1383         return rv3d->is_persp;
1384 }
1385
1386 DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void)
1387 {
1388         return GPU_viewport_framebuffer_list_get(DST.viewport);
1389 }
1390
1391 DefaultTextureList *DRW_viewport_texture_list_get(void)
1392 {
1393         return GPU_viewport_texture_list_get(DST.viewport);
1394 }
1395
1396 /* **************************************** OBJECTS *************************************** */
1397
1398 typedef struct ObjectEngineData {
1399         struct ObjectEngineData *next, *prev;
1400         DrawEngineType *engine_type;
1401         void *storage;
1402 } ObjectEngineData;
1403
1404 void **DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type)
1405 {
1406         ObjectEngineData *oed;
1407
1408         for (oed = ob->drawdata.first; oed; oed = oed->next) {
1409                 if (oed->engine_type == engine_type) {
1410                         return &oed->storage;
1411                 }
1412         }
1413
1414         oed = MEM_callocN(sizeof(ObjectEngineData), "ObjectEngineData");
1415         oed->engine_type = engine_type;
1416         BLI_addtail(&ob->drawdata, oed);
1417
1418         return &oed->storage;
1419 }
1420
1421 void DRW_object_engine_data_free(Object *ob)
1422 {
1423         for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) {
1424                 if (oed->storage) {
1425                         MEM_freeN(oed->storage);
1426                 }
1427         }
1428
1429         BLI_freelistN(&ob->drawdata);
1430 }
1431
1432 LampEngineData *DRW_lamp_engine_data_get(Object *ob, RenderEngineType *engine_type)
1433 {
1434         BLI_assert(ob->type == OB_LAMP);
1435
1436         Scene *scene = CTX_data_scene(DST.context);
1437
1438         /* TODO Dupliobjects */
1439         return GPU_lamp_engine_data_get(scene, ob, NULL, engine_type);
1440 }
1441
1442 void DRW_lamp_engine_data_free(LampEngineData *led)
1443 {
1444         GPU_lamp_engine_data_free(led);
1445 }
1446
1447 /* **************************************** RENDERING ************************************** */
1448
1449 #define TIMER_FALLOFF 0.1f
1450
1451 static void DRW_engines_init(void)
1452 {
1453         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1454                 DrawEngineType *engine = link->data;
1455                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1456                 double stime = PIL_check_seconds_timer();
1457
1458                 if (engine->engine_init) {
1459                         engine->engine_init(data);
1460                 }
1461
1462                 double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
1463                 data->init_time = data->init_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
1464         }
1465 }
1466
1467 static void DRW_engines_cache_init(void)
1468 {
1469         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1470                 DrawEngineType *engine = link->data;
1471                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1472                 double stime = PIL_check_seconds_timer();
1473                 data->cache_time = 0.0;
1474
1475                 if (engine->cache_init) {
1476                         engine->cache_init(data);
1477                 }
1478
1479                 data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
1480         }
1481 }
1482
1483 static void DRW_engines_cache_populate(Object *ob)
1484 {
1485         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1486                 DrawEngineType *engine = link->data;
1487                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1488                 double stime = PIL_check_seconds_timer();
1489
1490                 if (engine->cache_populate) {
1491                         engine->cache_populate(data, ob);
1492                 }
1493
1494                 data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
1495         }
1496 }
1497
1498 static void DRW_engines_cache_finish(void)
1499 {
1500         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1501                 DrawEngineType *engine = link->data;
1502                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1503                 double stime = PIL_check_seconds_timer();
1504
1505                 if (engine->cache_finish) {
1506                         engine->cache_finish(data);
1507                 }
1508
1509                 data->cache_time += (PIL_check_seconds_timer() - stime) * 1e3;
1510         }
1511 }
1512
1513 static void DRW_engines_draw_background(void)
1514 {
1515         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1516                 DrawEngineType *engine = link->data;
1517                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1518                 double stime = PIL_check_seconds_timer();
1519
1520                 if (engine->draw_background) {
1521                         engine->draw_background(data);
1522                         return;
1523                 }
1524
1525                 double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
1526                 data->background_time = data->background_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
1527         }
1528
1529         /* No draw_background found, doing default background */
1530         DRW_draw_background();
1531 }
1532
1533 static void DRW_engines_draw_scene(void)
1534 {
1535         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1536                 DrawEngineType *engine = link->data;
1537                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1538                 double stime = PIL_check_seconds_timer();
1539
1540                 if (engine->draw_scene) {
1541                         engine->draw_scene(data);
1542                 }
1543
1544                 double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
1545                 data->render_time = data->render_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
1546         }
1547 }
1548
1549 static void use_drw_engine(DrawEngineType *engine)
1550 {
1551         LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
1552         ld->data = engine;
1553         BLI_addtail(&DST.enabled_engines, ld);
1554 }
1555
1556 /* TODO revisit this when proper layering is implemented */
1557 /* Gather all draw engines needed and store them in DST.enabled_engines
1558  * That also define the rendering order of engines */
1559 static void DRW_engines_enable(const bContext *C)
1560 {
1561         /* TODO layers */
1562         Scene *scene = CTX_data_scene(C);
1563         RenderEngineType *type = RE_engines_find(scene->r.engine);
1564         use_drw_engine(type->draw_engine);
1565
1566         /* TODO Refine the folowing logic based on objects states
1567          * not on global state.
1568          * Order is important */
1569         use_drw_engine(&draw_engine_object_type);
1570
1571         switch (CTX_data_mode_enum(C)) {
1572                 case CTX_MODE_EDIT_MESH:
1573                         use_drw_engine(&draw_engine_edit_mesh_type);
1574                         break;
1575                 case CTX_MODE_EDIT_CURVE:
1576                         use_drw_engine(&draw_engine_edit_curve_type);
1577                         break;
1578                 case CTX_MODE_EDIT_SURFACE:
1579                         use_drw_engine(&draw_engine_edit_surface_type);
1580                         break;
1581                 case CTX_MODE_EDIT_TEXT:
1582                         use_drw_engine(&draw_engine_edit_text_type);
1583                         break;
1584                 case CTX_MODE_EDIT_ARMATURE:
1585                         use_drw_engine(&draw_engine_edit_armature_type);
1586                         break;
1587                 case CTX_MODE_EDIT_METABALL:
1588                         use_drw_engine(&draw_engine_edit_metaball_type);
1589                         break;
1590                 case CTX_MODE_EDIT_LATTICE:
1591                         use_drw_engine(&draw_engine_edit_lattice_type);
1592                         break;
1593                 case CTX_MODE_POSE:
1594                         use_drw_engine(&draw_engine_pose_type);
1595                         break;
1596                 case CTX_MODE_SCULPT:
1597                         use_drw_engine(&draw_engine_sculpt_type);
1598                         break;
1599                 case CTX_MODE_PAINT_WEIGHT:
1600                         use_drw_engine(&draw_engine_paint_weight_type);
1601                         break;
1602                 case CTX_MODE_PAINT_VERTEX:
1603                         use_drw_engine(&draw_engine_paint_vertex_type);
1604                         break;
1605                 case CTX_MODE_PAINT_TEXTURE:
1606                         use_drw_engine(&draw_engine_paint_texture_type);
1607                         break;
1608                 case CTX_MODE_PARTICLE:
1609                         use_drw_engine(&draw_engine_particle_type);
1610                         break;
1611                 case CTX_MODE_OBJECT:
1612                         break;
1613         }
1614 }
1615
1616 static void DRW_engines_disable(void)
1617 {
1618         BLI_freelistN(&DST.enabled_engines);
1619 }
1620
1621 static unsigned int DRW_engines_get_hash(void)
1622 {
1623         unsigned int hash = 0;
1624         /* The cache depends on enabled engines */
1625         /* FIXME : if collision occurs ... segfault */
1626         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1627                 DrawEngineType *engine = link->data;
1628                 hash += BLI_ghashutil_strhash_p(engine->idname);
1629         }
1630
1631         return hash;
1632 }
1633
1634 static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size)
1635 {
1636         BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit,
1637                                rect->ymax - (3 + v++) * U.widget_unit, 0.0f,
1638                                txt, size);
1639 }
1640
1641 /* CPU stats */
1642 static void DRW_debug_cpu_stats(void)
1643 {
1644         int u, v;
1645         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;
1646         /* local coordinate visible rect inside region, to accomodate overlapping ui */
1647         rcti rect;
1648         struct ARegion *ar = CTX_wm_region(DST.context);
1649         ED_region_visible_rect(ar, &rect);
1650
1651         UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
1652
1653         /* row by row */
1654         v = 0; u = 0;
1655         /* Label row */
1656         char col_label[32];
1657         sprintf(col_label, "Engine");
1658         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
1659         sprintf(col_label, "Cache");
1660         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
1661         sprintf(col_label, "Init");
1662         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
1663         sprintf(col_label, "Background");
1664         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
1665         sprintf(col_label, "Render");
1666         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
1667         sprintf(col_label, "Total (w/o cache)");
1668         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
1669         v++;
1670
1671         /* Engines rows */
1672         char time_to_txt[16];
1673         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1674                 u = 0;
1675                 DrawEngineType *engine = link->data;
1676                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1677
1678                 draw_stat(&rect, u++, v, engine->idname, sizeof(engine->idname));
1679
1680                 cache_tot_time += data->cache_time;
1681                 sprintf(time_to_txt, "%.2fms", data->cache_time);
1682                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1683
1684                 init_tot_time += data->init_time;
1685                 sprintf(time_to_txt, "%.2fms", data->init_time);
1686                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1687
1688                 background_tot_time += data->background_time;
1689                 sprintf(time_to_txt, "%.2fms", data->background_time);
1690                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1691
1692                 render_tot_time += data->render_time;
1693                 sprintf(time_to_txt, "%.2fms", data->render_time);
1694                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1695
1696                 tot_time += data->init_time + data->background_time + data->render_time;
1697                 sprintf(time_to_txt, "%.2fms", data->init_time + data->background_time + data->render_time);
1698                 draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1699                 v++;
1700         }
1701
1702         /* Totals row */
1703         u = 0;
1704         sprintf(col_label, "Sub Total");
1705         draw_stat(&rect, u++, v, col_label, sizeof(col_label));
1706         sprintf(time_to_txt, "%.2fms", cache_tot_time);
1707         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1708         sprintf(time_to_txt, "%.2fms", init_tot_time);
1709         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1710         sprintf(time_to_txt, "%.2fms", background_tot_time);
1711         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1712         sprintf(time_to_txt, "%.2fms", render_tot_time);
1713         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1714         sprintf(time_to_txt, "%.2fms", tot_time);
1715         draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
1716 }
1717
1718 /* Display GPU time for each passes */
1719 static void DRW_debug_gpu_stats(void)
1720 {
1721         /* local coordinate visible rect inside region, to accomodate overlapping ui */
1722         rcti rect;
1723         struct ARegion *ar = CTX_wm_region(DST.context);
1724         ED_region_visible_rect(ar, &rect);
1725
1726         UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
1727
1728         char time_to_txt[16];
1729         char pass_name[MAX_PASS_NAME + 8];
1730         int v = BLI_listbase_count(&DST.enabled_engines) + 3;
1731         GLuint64 tot_time = 0;
1732
1733         for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
1734                 GLuint64 engine_time = 0;
1735                 DrawEngineType *engine = link->data;
1736                 ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
1737                 int vsta = v;
1738
1739                 draw_stat(&rect, 0, v, engine->idname, sizeof(engine->idname));
1740                 v++;
1741
1742                 for (int i = 0; i < MAX_PASSES; ++i) {
1743                         DRWPass *pass = data->psl->passes[i];
1744                         if (pass != NULL) {
1745                                 GLuint64 time;
1746                                 glGetQueryObjectui64v(pass->timer_queries[pass->front_idx], GL_QUERY_RESULT, &time);
1747                                 tot_time += time;
1748                                 engine_time += time;
1749
1750                                 sprintf(pass_name, "   |--> %s", pass->name);
1751                                 draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
1752
1753                                 if (pass->wasdrawn)
1754                                         sprintf(time_to_txt, "%.2fms", time / 1000000.0);
1755                                 else
1756                                         sprintf(time_to_txt, "Not drawn");
1757                                 draw_stat(&rect, 2, v++, time_to_txt, sizeof(time_to_txt));
1758
1759                                 pass->wasdrawn = false;
1760                         }
1761                 }
1762                 /* engine total time */
1763                 sprintf(time_to_txt, "%.2fms", engine_time / 1000000.0);
1764                 draw_stat(&rect, 2, vsta, time_to_txt, sizeof(time_to_txt));
1765                 v++;
1766         }
1767
1768         sprintf(pass_name, "Total GPU time %.2fms (%.1f fps)", tot_time / 1000000.0, 1000000000.0 / tot_time);
1769         draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
1770 }
1771
1772 /* Everything starts here.
1773  * This function takes care of calling all cache and rendering functions
1774  * for each relevant engine / mode engine. */
1775 void DRW_draw_view(const bContext *C)
1776 {
1777         bool cache_is_dirty;
1778         RegionView3D *rv3d = CTX_wm_region_view3d(C);
1779         View3D *v3d = CTX_wm_view3d(C);
1780         DST.viewport = rv3d->viewport;
1781         v3d->zbuf = true;
1782
1783         /* Get list of enabled engines */
1784         DRW_engines_enable(C);
1785
1786         /* Setup viewport */
1787         cache_is_dirty = GPU_viewport_cache_validate(DST.viewport, DRW_engines_get_hash());
1788         DRW_viewport_var_init(C);
1789
1790         /* Update ubos */
1791         DRW_globals_update();
1792
1793         /* Init engines */
1794         DRW_engines_init();
1795
1796         /* TODO : tag to refresh by the deps graph */
1797         /* ideally only refresh when objects are added/removed */
1798         /* or render properties / materials change */
1799         if (cache_is_dirty) {
1800                 SceneLayer *sl;
1801                 Scene *scene = CTX_data_scene(C);
1802
1803                 DRW_engines_cache_init();
1804
1805                 /* draw set first */
1806                 if (scene->set) {
1807                         sl = BKE_scene_layer_render_active(scene->set);
1808                         DEG_OBJECT_ITER(sl, ob);
1809                         {
1810                                 ob->base_flag &= ~BASE_SELECTED;
1811                                 DRW_engines_cache_populate(ob);
1812                         }
1813                         DEG_OBJECT_ITER_END
1814                 }
1815
1816                 sl = CTX_data_scene_layer(C);
1817                 DEG_OBJECT_ITER(sl, ob);
1818                 {
1819                         DRW_engines_cache_populate(ob);
1820                 }
1821                 DEG_OBJECT_ITER_END
1822
1823                 DRW_engines_cache_finish();
1824         }
1825
1826         /* Start Drawing */
1827         DRW_engines_draw_background();
1828
1829         DRW_draw_callbacks_pre_scene();
1830         // DRW_draw_grid();
1831         DRW_engines_draw_scene();
1832         DRW_draw_callbacks_post_scene();
1833
1834         DRW_draw_manipulator();
1835
1836         DRW_draw_region_info();
1837
1838         if (G.debug_value > 20) {
1839                 DRW_debug_cpu_stats();
1840                 DRW_debug_gpu_stats();
1841         }
1842
1843         DRW_state_reset();
1844         DRW_engines_disable();
1845 }
1846
1847 /* ****************************************** OTHER ***************************************** */
1848
1849 const bContext *DRW_get_context(void)
1850 {
1851         return DST.context;
1852 }
1853
1854 /* ****************************************** INIT ***************************************** */
1855
1856 void DRW_engine_register(DrawEngineType *draw_engine_type)
1857 {
1858         BLI_addtail(&DRW_engines, draw_engine_type);
1859 }
1860
1861 void DRW_engines_register(void)
1862 {
1863 #ifdef WITH_CLAY_ENGINE
1864         RE_engines_register(NULL, &viewport_clay_type);
1865         RE_engines_register(NULL, &viewport_eevee_type);
1866
1867         DRW_engine_register(&draw_engine_object_type);
1868         DRW_engine_register(&draw_engine_edit_armature_type);
1869         DRW_engine_register(&draw_engine_edit_curve_type);
1870         DRW_engine_register(&draw_engine_edit_lattice_type);
1871         DRW_engine_register(&draw_engine_edit_mesh_type);
1872         DRW_engine_register(&draw_engine_edit_metaball_type);
1873         DRW_engine_register(&draw_engine_edit_surface_type);
1874         DRW_engine_register(&draw_engine_edit_text_type);
1875         DRW_engine_register(&draw_engine_paint_texture_type);
1876         DRW_engine_register(&draw_engine_paint_vertex_type);
1877         DRW_engine_register(&draw_engine_paint_weight_type);
1878         DRW_engine_register(&draw_engine_particle_type);
1879         DRW_engine_register(&draw_engine_pose_type);
1880         DRW_engine_register(&draw_engine_sculpt_type);
1881 #endif
1882 }
1883
1884 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
1885 void DRW_engines_free(void)
1886 {
1887 #ifdef WITH_CLAY_ENGINE
1888         DRW_shape_cache_free();
1889
1890         DrawEngineType *next;
1891         for (DrawEngineType *type = DRW_engines.first; type; type = next) {
1892                 next = type->next;
1893                 BLI_remlink(&R_engines, type);
1894
1895                 if (type->engine_free) {
1896                         type->engine_free();
1897                 }
1898         }
1899
1900         if (globals_ubo)
1901                 GPU_uniformbuffer_free(globals_ubo);
1902
1903         BLI_remlink(&R_engines, &viewport_clay_type);
1904 #endif
1905 }