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