Cleanup: blank lines over doxy headers
[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         DRW_CALL_SINGLE,                 /* A single batch */
139         DRW_CALL_RANGE,                  /* Like single but only draw a range of vertices/indices. */
140         DRW_CALL_INSTANCES,              /* Draw instances without any instancing attribs. */
141         DRW_CALL_GENERATE,               /* Uses a callback to draw with any number of batches. */
142         DRW_CALL_PROCEDURAL,             /* Generate a drawcall without any GPUBatch. */
143 } DRWCallType;
144
145 typedef struct DRWCall {
146         struct DRWCall *next;
147         DRWCallState *state;
148
149         union {
150                 struct { /* type == DRW_CALL_SINGLE */
151                         GPUBatch *geometry;
152                         short ma_index;
153                 } single;
154                 struct { /* type == DRW_CALL_RANGE */
155                         GPUBatch *geometry;
156                         uint start, count;
157                 } range;
158                 struct { /* type == DRW_CALL_INSTANCES */
159                         GPUBatch *geometry;
160                         /* Count can be adjusted between redraw. If needed, we can add fixed count. */
161                         uint *count;
162                 } instances;
163                 struct { /* type == DRW_CALL_GENERATE */
164                         DRWCallGenerateFn *geometry_fn;
165                         void *user_data;
166                 } generate;
167                 struct { /* type == DRW_CALL_PROCEDURAL */
168                         uint vert_count;
169                         GPUPrimType prim_type;
170                 } procedural;
171         };
172
173         DRWCallType type;
174 #ifdef USE_GPU_SELECT
175         int select_id;
176 #endif
177 } DRWCall;
178
179 /* Used by DRWUniform.type */
180 typedef enum {
181         DRW_UNIFORM_BOOL,
182         DRW_UNIFORM_BOOL_COPY,
183         DRW_UNIFORM_SHORT_TO_INT,
184         DRW_UNIFORM_SHORT_TO_FLOAT,
185         DRW_UNIFORM_INT,
186         DRW_UNIFORM_INT_COPY,
187         DRW_UNIFORM_FLOAT,
188         DRW_UNIFORM_FLOAT_COPY,
189         DRW_UNIFORM_TEXTURE,
190         DRW_UNIFORM_TEXTURE_PERSIST,
191         DRW_UNIFORM_TEXTURE_REF,
192         DRW_UNIFORM_BLOCK,
193         DRW_UNIFORM_BLOCK_PERSIST
194 } DRWUniformType;
195
196 struct DRWUniform {
197         DRWUniform *next; /* single-linked list */
198         union {
199                 /* For reference or array/vector types. */
200                 const void *pvalue;
201                 /* Single values. */
202                 float fvalue;
203                 int ivalue;
204         };
205         int name_ofs; /* name offset in name buffer. */
206         int location;
207         char type; /* DRWUniformType */
208         char length; /* cannot be more than 16 */
209         char arraysize; /* cannot be more than 16 too */
210 };
211
212 typedef enum {
213         DRW_SHG_NORMAL,
214         DRW_SHG_POINT_BATCH,
215         DRW_SHG_LINE_BATCH,
216         DRW_SHG_TRIANGLE_BATCH,
217         DRW_SHG_INSTANCE,
218         DRW_SHG_INSTANCE_EXTERNAL,
219         DRW_SHG_FEEDBACK_TRANSFORM,
220 } DRWShadingGroupType;
221
222 struct DRWShadingGroup {
223         DRWShadingGroup *next;
224
225         GPUShader *shader;        /* Shader to bind */
226         DRWUniform *uniforms;          /* Uniforms pointers */
227
228         /* Watch this! Can be nasty for debugging. */
229         union {
230                 struct { /* DRW_SHG_NORMAL */
231                         DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */
232                 } calls;
233                 struct { /* DRW_SHG_FEEDBACK_TRANSFORM */
234                         DRWCall *first, *last; /* Linked list of DRWCall or DRWCallDynamic depending of type */
235                         struct GPUVertBuf *tfeedback_target; /* Transform Feedback target. */
236                 };
237                 struct { /* DRW_SHG_***_BATCH */
238                         struct GPUBatch *batch_geom;     /* Result of call batching */
239                         struct GPUVertBuf *batch_vbo;
240                         uint primitive_count;
241                 };
242                 struct { /* DRW_SHG_INSTANCE[_EXTERNAL] */
243                         struct GPUBatch *instance_geom;
244                         struct GPUVertBuf *instance_vbo;
245                         uint instance_count;
246                         float instance_orcofac[2][3]; /* TODO find a better place. */
247                 };
248         };
249
250         DRWState state_extra;            /* State changes for this batch only (or'd with the pass's state) */
251         DRWState state_extra_disable;    /* State changes for this batch only (and'd with the pass's state) */
252         uint stencil_mask;       /* Stencil mask to use for stencil test / write operations */
253         DRWShadingGroupType type;
254
255         /* Builtin matrices locations */
256         int model;
257         int modelinverse;
258         int modelview;
259         int modelviewinverse;
260         int modelviewprojection;
261         int normalview;
262         int normalworld;
263         int orcotexfac;
264         int eye;
265         int callid;
266         int objectinfo;
267         uint16_t matflag; /* Matrices needed, same as DRWCall.flag */
268
269         DRWPass *pass_parent; /* backlink to pass we're in */
270 #ifndef NDEBUG
271         char attribs_count;
272 #endif
273 #ifdef USE_GPU_SELECT
274         GPUVertBuf *inst_selectid;
275         int override_selectid; /* Override for single object instances. */
276 #endif
277 };
278
279 #define MAX_PASS_NAME 32
280
281 struct DRWPass {
282         /* Linked list */
283         struct {
284                 DRWShadingGroup *first;
285                 DRWShadingGroup *last;
286         } shgroups;
287
288         DRWState state;
289         char name[MAX_PASS_NAME];
290 };
291
292 typedef struct ViewUboStorage {
293         DRWMatrixState matstate;
294         float viewcamtexcofac[4];
295         float clipplanes[2][4];
296 } ViewUboStorage;
297
298 /* ------------- DRAW DEBUG ------------ */
299
300 typedef struct DRWDebugLine {
301         struct DRWDebugLine *next; /* linked list */
302         float pos[2][3];
303         float color[4];
304 } DRWDebugLine;
305
306 typedef struct DRWDebugSphere {
307         struct DRWDebugSphere *next; /* linked list */
308         float mat[4][4];
309         float color[4];
310 } DRWDebugSphere;
311
312 /* ------------- DRAW MANAGER ------------ */
313
314 #define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */
315 #define STENCIL_UNDEFINED 256
316 typedef struct DRWManager {
317         /* TODO clean up this struct a bit */
318         /* Cache generation */
319         ViewportMemoryPool *vmempool;
320         DRWInstanceDataList *idatalist;
321         DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE];
322         /* State of the object being evaluated if already allocated. */
323         DRWCallState *ob_state;
324         uchar state_cache_id; /* Could be larger but 254 view changes is already a lot! */
325         struct DupliObject *dupli_source;
326         struct Object *dupli_parent;
327
328         /* Rendering state */
329         GPUShader *shader;
330
331         /* Managed by `DRW_state_set`, `DRW_state_reset` */
332         DRWState state;
333         DRWState state_lock;
334         uint stencil_mask;
335
336         /* Per viewport */
337         GPUViewport *viewport;
338         struct GPUFrameBuffer *default_framebuffer;
339         float size[2];
340         float inv_size[2];
341         float screenvecs[2][3];
342         float pixsize;
343
344         GLenum backface, frontface;
345
346         struct {
347                 uint is_select : 1;
348                 uint is_depth : 1;
349                 uint is_image_render : 1;
350                 uint is_scene_render : 1;
351                 uint draw_background : 1;
352                 uint draw_text : 1;
353         } options;
354
355         /* Current rendering context */
356         DRWContextState draw_ctx;
357
358         /* Convenience pointer to text_store owned by the viewport */
359         struct DRWTextStore **text_store_p;
360
361         ListBase enabled_engines; /* RenderEngineType */
362
363         bool buffer_finish_called; /* Avoid bad usage of DRW_render_instance_buffer_finish */
364
365         /* View dependent uniforms. */
366         DRWMatrixState original_mat; /* Original rv3d matrices. */
367         int override_mat;            /* Bitflag of which matrices are overridden. */
368         int clip_planes_len;         /* Number of active clipplanes. */
369         bool dirty_mat;
370
371         /* keep in sync with viewBlock */
372         ViewUboStorage view_data;
373
374         struct {
375                 float frustum_planes[6][4];
376                 BoundBox frustum_corners;
377                 BoundSphere frustum_bsphere;
378                 bool updated;
379         } clipping;
380
381 #ifdef USE_GPU_SELECT
382         uint select_id;
383 #endif
384
385         /* ---------- Nothing after this point is cleared after use ----------- */
386
387         /* gl_context serves as the offset for clearing only
388          * the top portion of the struct so DO NOT MOVE IT! */
389         void *gl_context;                /* Unique ghost context used by the draw manager. */
390         GPUContext *gpu_context;
391         TicketMutex *gl_context_mutex;    /* Mutex to lock the drw manager and avoid concurrent context usage. */
392
393         /** GPU Resource State: Memory storage between drawing. */
394         struct {
395                 GPUTexture **bound_texs;
396                 char *bound_tex_slots;
397                 int bind_tex_inc;
398                 GPUUniformBuffer **bound_ubos;
399                 char *bound_ubo_slots;
400                 int bind_ubo_inc;
401         } RST;
402
403         struct {
404                 /* TODO(fclem) optimize: use chunks. */
405                 DRWDebugLine *lines;
406                 DRWDebugSphere *spheres;
407         } debug;
408
409         struct {
410                 char *buffer;
411                 uint buffer_len;
412                 uint buffer_ofs;
413         } uniform_names;
414 } DRWManager;
415
416 extern DRWManager DST; /* TODO : get rid of this and allow multithreaded rendering */
417
418 /* --------------- FUNCTIONS ------------- */
419
420 void drw_texture_set_parameters(GPUTexture *tex, DRWTextureFlag flags);
421
422 void *drw_viewport_engine_data_ensure(void *engine_type);
423
424 void drw_state_set(DRWState state);
425
426 void drw_debug_draw(void);
427 void drw_debug_init(void);
428
429 void drw_batch_cache_generate_requested(struct Object *ob);
430
431 #endif /* __DRAW_MANAGER_H__ */