Cleanup: replace attrib w/ attr
[blender.git] / source / blender / draw / intern / draw_manager.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Copyright 2016, Blender Foundation.
19  * Contributor(s): Blender Institute
20  *
21  * ***** END GPL LICENSE BLOCK *****
22  *
23  */
24
25 /** \file draw_manager.h
26  *  \ingroup draw
27  */
28
29 /* Private functions / structs of the draw manager */
30
31 #ifndef __DRAW_MANAGER_H__
32 #define __DRAW_MANAGER_H__
33
34 #include "DRW_engine.h"
35 #include "DRW_render.h"
36
37 #include "BLI_linklist.h"
38 #include "BLI_threads.h"
39
40 #include "GPU_batch.h"
41 #include "GPU_context.h"
42 #include "GPU_framebuffer.h"
43 #include "GPU_shader.h"
44 #include "GPU_uniformbuffer.h"
45 #include "GPU_viewport.h"
46
47 #include "draw_instance_data.h"
48
49 /* Use draw manager to call GPU_select, see: DRW_draw_select_loop */
50 #define USE_GPU_SELECT
51
52 #define DRW_DEBUG_USE_UNIFORM_NAME 0
53 #define DRW_UNIFORM_BUFFER_NAME 64
54 #define DRW_UNIFORM_BUFFER_NAME_INC 1024
55
56 /* ------------ Profiling --------------- */
57
58 #define USE_PROFILE
59
60 #ifdef USE_PROFILE
61 #  include "PIL_time.h"
62
63 #  define PROFILE_TIMER_FALLOFF 0.04
64
65 #  define PROFILE_START(time_start) \
66         double time_start = PIL_check_seconds_timer();
67
68 #  define PROFILE_END_ACCUM(time_accum, time_start) { \
69         time_accum += (PIL_check_seconds_timer() - time_start) * 1e3; \
70 } ((void)0)
71
72 /* exp average */
73 #  define PROFILE_END_UPDATE(time_update, time_start) { \
74         double _time_delta = (PIL_check_seconds_timer() - time_start) * 1e3; \
75         time_update = (time_update * (1.0 - PROFILE_TIMER_FALLOFF)) + \
76                       (_time_delta * PROFILE_TIMER_FALLOFF); \
77 } ((void)0)
78
79 #else  /* USE_PROFILE */
80
81 #  define PROFILE_START(time_start) ((void)0)
82 #  define PROFILE_END_ACCUM(time_accum, time_start) ((void)0)
83 #  define PROFILE_END_UPDATE(time_update, time_start) ((void)0)
84
85 #endif  /* USE_PROFILE */
86
87 /* ------------ Data Structure --------------- */
88 /**
89  * Data structure containing all drawcalls organized by passes and materials.
90  * DRWPass > DRWShadingGroup > DRWCall > DRWCallState
91  *                           > DRWUniform
92  **/
93
94 /* Used by DRWCallState.flag */
95 enum {
96         DRW_CALL_CULLED                 = (1 << 0),
97         DRW_CALL_NEGSCALE               = (1 << 1),
98         DRW_CALL_BYPASS_CULLING         = (1 << 2),
99 };
100
101 /* Used by DRWCallState.matflag */
102 enum {
103         DRW_CALL_MODELINVERSE           = (1 << 0),
104         DRW_CALL_MODELVIEW              = (1 << 1),
105         DRW_CALL_MODELVIEWINVERSE       = (1 << 2),
106         DRW_CALL_MODELVIEWPROJECTION    = (1 << 3),
107         DRW_CALL_NORMALVIEW             = (1 << 4),
108         DRW_CALL_NORMALWORLD            = (1 << 5),
109         DRW_CALL_ORCOTEXFAC             = (1 << 6),
110         DRW_CALL_EYEVEC                 = (1 << 7),
111         DRW_CALL_OBJECTINFO             = (1 << 8),
112 };
113
114 typedef struct DRWCallState {
115         DRWCallVisibilityFn *visibility_cb;
116         void *user_data;
117
118         uchar flag;
119         uchar cache_id;   /* Compared with DST.state_cache_id to see if matrices are still valid. */
120         uint16_t matflag;         /* Which matrices to compute. */
121         /* Culling: Using Bounding Sphere for now for faster culling.
122          * Not ideal for planes. */
123         BoundSphere bsphere;
124         /* Matrices */
125         float model[4][4];
126         float modelinverse[4][4];
127         float modelview[4][4];
128         float modelviewinverse[4][4];
129         float modelviewprojection[4][4];
130         float normalview[3][3];
131         float normalworld[3][3]; /* Not view dependent */
132         float orcotexfac[2][3]; /* Not view dependent */
133         float objectinfo[2];
134         float eyevec[3];
135 } DRWCallState;
136
137 typedef enum {
138         /** A single batch. */
139         DRW_CALL_SINGLE,
140         /** Like single but only draw a range of vertices/indices. */
141         DRW_CALL_RANGE,
142         /** Draw instances without any instancing attributes. */
143         DRW_CALL_INSTANCES,
144         /** Uses a callback to draw with any number of batches. */
145         DRW_CALL_GENERATE,
146         /** Generate a drawcall without any #GPUBatch. */
147         DRW_CALL_PROCEDURAL,
148 } DRWCallType;
149
150 typedef struct DRWCall {
151         struct DRWCall *next;
152         DRWCallState *state;
153
154         union {
155                 struct { /* type == DRW_CALL_SINGLE */
156                         GPUBatch *geometry;
157                         short ma_index;
158                 } single;
159                 struct { /* type == DRW_CALL_RANGE */
160                         GPUBatch *geometry;
161                         uint start, count;
162                 } range;
163                 struct { /* type == DRW_CALL_INSTANCES */
164                         GPUBatch *geometry;
165                         /* Count can be adjusted between redraw. If needed, we can add fixed count. */
166                         uint *count;
167                 } instances;
168                 struct { /* type == DRW_CALL_GENERATE */
169                         DRWCallGenerateFn *geometry_fn;
170                         void *user_data;
171                 } generate;
172                 struct { /* type == DRW_CALL_PROCEDURAL */
173                         uint vert_count;
174                         GPUPrimType prim_type;
175                 } procedural;
176         };
177
178         DRWCallType type;
179 #ifdef USE_GPU_SELECT
180         int select_id;
181 #endif
182 } DRWCall;
183
184 /* Used by DRWUniform.type */
185 typedef enum {
186         DRW_UNIFORM_BOOL,
187         DRW_UNIFORM_BOOL_COPY,
188         DRW_UNIFORM_SHORT_TO_INT,
189         DRW_UNIFORM_SHORT_TO_FLOAT,
190         DRW_UNIFORM_INT,
191         DRW_UNIFORM_INT_COPY,
192         DRW_UNIFORM_FLOAT,
193         DRW_UNIFORM_FLOAT_COPY,
194         DRW_UNIFORM_TEXTURE,
195         DRW_UNIFORM_TEXTURE_PERSIST,
196         DRW_UNIFORM_TEXTURE_REF,
197         DRW_UNIFORM_BLOCK,
198         DRW_UNIFORM_BLOCK_PERSIST
199 } DRWUniformType;
200
201 struct DRWUniform {
202         DRWUniform *next; /* single-linked list */
203         union {
204                 /* For reference or array/vector types. */
205                 const void *pvalue;
206                 /* Single values. */
207                 float fvalue;
208                 int ivalue;
209         };
210         int name_ofs; /* name offset in name buffer. */
211         int location;
212         char type; /* DRWUniformType */
213         char length; /* cannot be more than 16 */
214         char arraysize; /* cannot be more than 16 too */
215 };
216
217 typedef enum {
218         DRW_SHG_NORMAL,
219         DRW_SHG_POINT_BATCH,
220         DRW_SHG_LINE_BATCH,
221         DRW_SHG_TRIANGLE_BATCH,
222         DRW_SHG_INSTANCE,
223         DRW_SHG_INSTANCE_EXTERNAL,
224         DRW_SHG_FEEDBACK_TRANSFORM,
225 } DRWShadingGroupType;
226
227 struct DRWShadingGroup {
228         DRWShadingGroup *next;
229
230         GPUShader *shader;        /* Shader to bind */
231         DRWUniform *uniforms;          /* Uniforms pointers */
232
233         /* Watch this! Can be nasty for debugging. */
234         union {
235                 struct { /* DRW_SHG_NORMAL */
236                         DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */
237                 } calls;
238                 struct { /* DRW_SHG_FEEDBACK_TRANSFORM */
239                         DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */
240                         struct GPUVertBuf *tfeedback_target; /* Transform Feedback target. */
241                 };
242                 struct { /* DRW_SHG_***_BATCH */
243                         struct GPUBatch *batch_geom;     /* Result of call batching */
244                         struct GPUVertBuf *batch_vbo;
245                         uint primitive_count;
246                 };
247                 struct { /* DRW_SHG_INSTANCE[_EXTERNAL] */
248                         struct GPUBatch *instance_geom;
249                         struct GPUVertBuf *instance_vbo;
250                         uint instance_count;
251                         float instance_orcofac[2][3]; /* TODO find a better place. */
252                 };
253         };
254
255         DRWState state_extra;            /* State changes for this batch only (or'd with the pass's state) */
256         DRWState state_extra_disable;    /* State changes for this batch only (and'd with the pass's state) */
257         uint stencil_mask;       /* Stencil mask to use for stencil test / write operations */
258         DRWShadingGroupType type;
259
260         /* Builtin matrices locations */
261         int model;
262         int modelinverse;
263         int modelview;
264         int modelviewinverse;
265         int modelviewprojection;
266         int normalview;
267         int normalworld;
268         int orcotexfac;
269         int eye;
270         int callid;
271         int objectinfo;
272         uint16_t matflag; /* Matrices needed, same as DRWCall.flag */
273
274         DRWPass *pass_parent; /* backlink to pass we're in */
275 #ifndef NDEBUG
276         char attrs_count;
277 #endif
278 #ifdef USE_GPU_SELECT
279         GPUVertBuf *inst_selectid;
280         int override_selectid; /* Override for single object instances. */
281 #endif
282 };
283
284 #define MAX_PASS_NAME 32
285
286 struct DRWPass {
287         /* Linked list */
288         struct {
289                 DRWShadingGroup *first;
290                 DRWShadingGroup *last;
291         } shgroups;
292
293         DRWState state;
294         char name[MAX_PASS_NAME];
295 };
296
297 typedef struct ViewUboStorage {
298         DRWMatrixState matstate;
299         float viewcamtexcofac[4];
300         float clipplanes[2][4];
301 } ViewUboStorage;
302
303 /* ------------- DRAW DEBUG ------------ */
304
305 typedef struct DRWDebugLine {
306         struct DRWDebugLine *next; /* linked list */
307         float pos[2][3];
308         float color[4];
309 } DRWDebugLine;
310
311 typedef struct DRWDebugSphere {
312         struct DRWDebugSphere *next; /* linked list */
313         float mat[4][4];
314         float color[4];
315 } DRWDebugSphere;
316
317 /* ------------- DRAW MANAGER ------------ */
318
319 #define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */
320 #define STENCIL_UNDEFINED 256
321 typedef struct DRWManager {
322         /* TODO clean up this struct a bit */
323         /* Cache generation */
324         ViewportMemoryPool *vmempool;
325         DRWInstanceDataList *idatalist;
326         DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE];
327         /* State of the object being evaluated if already allocated. */
328         DRWCallState *ob_state;
329         uchar state_cache_id; /* Could be larger but 254 view changes is already a lot! */
330         struct DupliObject *dupli_source;
331         struct Object *dupli_parent;
332
333         /* Rendering state */
334         GPUShader *shader;
335
336         /* Managed by `DRW_state_set`, `DRW_state_reset` */
337         DRWState state;
338         DRWState state_lock;
339         uint stencil_mask;
340
341         /* Per viewport */
342         GPUViewport *viewport;
343         struct GPUFrameBuffer *default_framebuffer;
344         float size[2];
345         float inv_size[2];
346         float screenvecs[2][3];
347         float pixsize;
348
349         GLenum backface, frontface;
350
351         struct {
352                 uint is_select : 1;
353                 uint is_depth : 1;
354                 uint is_image_render : 1;
355                 uint is_scene_render : 1;
356                 uint draw_background : 1;
357                 uint draw_text : 1;
358         } options;
359
360         /* Current rendering context */
361         DRWContextState draw_ctx;
362
363         /* Convenience pointer to text_store owned by the viewport */
364         struct DRWTextStore **text_store_p;
365
366         ListBase enabled_engines; /* RenderEngineType */
367
368         bool buffer_finish_called; /* Avoid bad usage of DRW_render_instance_buffer_finish */
369
370         /* View dependent uniforms. */
371         DRWMatrixState original_mat; /* Original rv3d matrices. */
372         int override_mat;            /* Bitflag of which matrices are overridden. */
373         int clip_planes_len;         /* Number of active clipplanes. */
374         bool dirty_mat;
375
376         /* keep in sync with viewBlock */
377         ViewUboStorage view_data;
378
379         struct {
380                 float frustum_planes[6][4];
381                 BoundBox frustum_corners;
382                 BoundSphere frustum_bsphere;
383                 bool updated;
384         } clipping;
385
386 #ifdef USE_GPU_SELECT
387         uint select_id;
388 #endif
389
390         /* ---------- Nothing after this point is cleared after use ----------- */
391
392         /* gl_context serves as the offset for clearing only
393          * the top portion of the struct so DO NOT MOVE IT! */
394         void *gl_context;                /* Unique ghost context used by the draw manager. */
395         GPUContext *gpu_context;
396         TicketMutex *gl_context_mutex;    /* Mutex to lock the drw manager and avoid concurrent context usage. */
397
398         /** GPU Resource State: Memory storage between drawing. */
399         struct {
400                 GPUTexture **bound_texs;
401                 char *bound_tex_slots;
402                 int bind_tex_inc;
403                 GPUUniformBuffer **bound_ubos;
404                 char *bound_ubo_slots;
405                 int bind_ubo_inc;
406         } RST;
407
408         struct {
409                 /* TODO(fclem) optimize: use chunks. */
410                 DRWDebugLine *lines;
411                 DRWDebugSphere *spheres;
412         } debug;
413
414         struct {
415                 char *buffer;
416                 uint buffer_len;
417                 uint buffer_ofs;
418         } uniform_names;
419 } DRWManager;
420
421 extern DRWManager DST; /* TODO : get rid of this and allow multithreaded rendering */
422
423 /* --------------- FUNCTIONS ------------- */
424
425 void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags);
426
427 void *drw_viewport_engine_data_ensure(void *engine_type);
428
429 void drw_state_set(DRWState state);
430
431 void drw_debug_draw(void);
432 void drw_debug_init(void);
433
434 void drw_batch_cache_generate_requested(struct Object *ob);
435
436 #endif /* __DRAW_MANAGER_H__ */