Merge branch 'master' into blender2.8
[blender.git] / source / blender / draw / engines / gpencil / gpencil_engine.c
1 /*
2  * Copyright 2017, 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): Antonio Vazquez
19  *
20  */
21
22 /** \file blender/draw/engines/gpencil/gpencil_engine.c
23  *  \ingroup draw
24  */
25 #include "DRW_engine.h"
26 #include "DRW_render.h"
27
28 #include "BKE_camera.h"
29 #include "BKE_object.h"
30 #include "BKE_paint.h"
31 #include "BKE_gpencil.h"
32 #include "BKE_shader_fx.h"
33
34 #include "DNA_gpencil_types.h"
35 #include "DNA_view3d_types.h"
36
37 #include "draw_mode_engines.h"
38
39 #include "UI_resources.h"
40
41 #include "GPU_texture.h"
42
43 #include "gpencil_engine.h"
44
45 #include "DEG_depsgraph_query.h"
46
47 #include "ED_screen.h"
48 #include "ED_gpencil.h"
49
50 #include "WM_api.h"
51
52 extern char datatoc_gpencil_fill_vert_glsl[];
53 extern char datatoc_gpencil_fill_frag_glsl[];
54 extern char datatoc_gpencil_stroke_vert_glsl[];
55 extern char datatoc_gpencil_stroke_geom_glsl[];
56 extern char datatoc_gpencil_stroke_frag_glsl[];
57 extern char datatoc_gpencil_zdepth_mix_frag_glsl[];
58 extern char datatoc_gpencil_simple_mix_frag_glsl[];
59 extern char datatoc_gpencil_point_vert_glsl[];
60 extern char datatoc_gpencil_point_geom_glsl[];
61 extern char datatoc_gpencil_point_frag_glsl[];
62 extern char datatoc_gpencil_background_frag_glsl[];
63 extern char datatoc_gpencil_paper_frag_glsl[];
64 extern char datatoc_gpencil_edit_point_vert_glsl[];
65 extern char datatoc_gpencil_edit_point_geom_glsl[];
66 extern char datatoc_gpencil_edit_point_frag_glsl[];
67
68 /* *********** STATIC *********** */
69 static GPENCIL_e_data e_data = {NULL}; /* Engine data */
70
71 /* *********** FUNCTIONS *********** */
72
73 /* create a multisample buffer if not present */
74 void DRW_gpencil_multisample_ensure(GPENCIL_Data *vedata, int rect_w, int rect_h)
75 {
76         GPENCIL_FramebufferList *fbl = vedata->fbl;
77         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
78         GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
79
80         short samples = stl->storage->multisamples;
81
82         if (samples > 0) {
83                 if (!fbl->multisample_fb) {
84                         fbl->multisample_fb = GPU_framebuffer_create();
85                         if (fbl->multisample_fb) {
86                                 if (txl->multisample_color == NULL) {
87                                         txl->multisample_color = GPU_texture_create_2D_multisample(
88                                                 rect_w, rect_h, GPU_RGBA16F, NULL, samples, NULL);
89                                 }
90                                 if (txl->multisample_depth == NULL) {
91                                         txl->multisample_depth = GPU_texture_create_2D_multisample(
92                                                 rect_w, rect_h, GPU_DEPTH24_STENCIL8, NULL, samples, NULL);
93                                 }
94                                 GPU_framebuffer_ensure_config(
95                                         &fbl->multisample_fb, {
96                                             GPU_ATTACHMENT_TEXTURE(txl->multisample_depth),
97                                             GPU_ATTACHMENT_TEXTURE(txl->multisample_color)
98                                         });
99                         }
100                 }
101         }
102 }
103
104 static void GPENCIL_create_framebuffers(void *vedata)
105 {
106         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
107         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
108
109         /* Go full 32bits for rendering */
110         GPUTextureFormat fb_format = DRW_state_is_image_render() ? GPU_RGBA32F : GPU_RGBA16F;
111
112         if (DRW_state_is_fbo()) {
113                 const float *viewport_size = DRW_viewport_size_get();
114                 const int size[2] = { (int)viewport_size[0], (int)viewport_size[1] };
115
116                 /* create multiframe framebuffer for AA */
117                 if (stl->storage->multisamples > 0) {
118                         DRW_gpencil_multisample_ensure(vedata, size[0], size[1]);
119                 }
120
121                 /* temp textures */
122                 e_data.temp_depth_tx_a = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH24_STENCIL8,
123                         &draw_engine_gpencil_type);
124                 e_data.temp_color_tx_a = DRW_texture_pool_query_2D(size[0], size[1], fb_format,
125                         &draw_engine_gpencil_type);
126                 GPU_framebuffer_ensure_config(
127                         &fbl->temp_fb_a, {
128                             GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_a),
129                             GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_a)
130                         });
131
132                 e_data.temp_depth_tx_b = DRW_texture_pool_query_2D(
133                         size[0], size[1], GPU_DEPTH24_STENCIL8,
134                         &draw_engine_gpencil_type);
135                 e_data.temp_color_tx_b = DRW_texture_pool_query_2D(
136                         size[0], size[1], fb_format,
137                         &draw_engine_gpencil_type);
138                 GPU_framebuffer_ensure_config(
139                         &fbl->temp_fb_b, {
140                             GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_b),
141                             GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b)
142                         });
143
144                 /* used for rim and shadow FX effects */
145                 e_data.temp_depth_tx_fx = DRW_texture_pool_query_2D(
146                         size[0], size[1], GPU_DEPTH24_STENCIL8,
147                         &draw_engine_gpencil_type);
148                 e_data.temp_color_tx_fx = DRW_texture_pool_query_2D(
149                         size[0], size[1], fb_format,
150                         &draw_engine_gpencil_type);
151                 GPU_framebuffer_ensure_config(
152                         &fbl->temp_fb_fx, {
153                             GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_fx),
154                             GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_fx),
155                         });
156
157                 /* background framebuffer to speed up drawing process (always 16 bits) */
158                 e_data.background_depth_tx = DRW_texture_pool_query_2D(
159                         size[0], size[1], GPU_DEPTH24_STENCIL8,
160                         &draw_engine_gpencil_type);
161                 e_data.background_color_tx = DRW_texture_pool_query_2D(
162                         size[0], size[1], GPU_RGBA32F,
163                         &draw_engine_gpencil_type);
164                 GPU_framebuffer_ensure_config(
165                         &fbl->background_fb, {
166                             GPU_ATTACHMENT_TEXTURE(e_data.background_depth_tx),
167                             GPU_ATTACHMENT_TEXTURE(e_data.background_color_tx)
168                         });
169         }
170 }
171
172 static void GPENCIL_create_shaders(void)
173 {
174         /* normal fill shader */
175         if (!e_data.gpencil_fill_sh) {
176                 e_data.gpencil_fill_sh = DRW_shader_create(
177                         datatoc_gpencil_fill_vert_glsl, NULL,
178                         datatoc_gpencil_fill_frag_glsl, NULL);
179         }
180
181         /* normal stroke shader using geometry to display lines (line mode) */
182         if (!e_data.gpencil_stroke_sh) {
183                 e_data.gpencil_stroke_sh = DRW_shader_create(
184                         datatoc_gpencil_stroke_vert_glsl,
185                         datatoc_gpencil_stroke_geom_glsl,
186                         datatoc_gpencil_stroke_frag_glsl,
187                         NULL);
188         }
189
190         /* dot/rectangle mode for normal strokes using geometry */
191         if (!e_data.gpencil_point_sh) {
192                 e_data.gpencil_point_sh = DRW_shader_create(
193                         datatoc_gpencil_point_vert_glsl,
194                         datatoc_gpencil_point_geom_glsl,
195                         datatoc_gpencil_point_frag_glsl,
196                         NULL);
197         }
198         /* used for edit points or strokes with one point only */
199         if (!e_data.gpencil_edit_point_sh) {
200                 e_data.gpencil_edit_point_sh = DRW_shader_create(
201                         datatoc_gpencil_edit_point_vert_glsl,
202                         datatoc_gpencil_edit_point_geom_glsl,
203                         datatoc_gpencil_edit_point_frag_glsl, NULL);
204         }
205
206         /* used for edit lines for edit modes */
207         if (!e_data.gpencil_line_sh) {
208                 e_data.gpencil_line_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
209         }
210
211         /* used to filling during drawing */
212         if (!e_data.gpencil_drawing_fill_sh) {
213                 e_data.gpencil_drawing_fill_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
214         }
215
216         /* full screen for mix zdepth*/
217         if (!e_data.gpencil_fullscreen_sh) {
218                 e_data.gpencil_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_zdepth_mix_frag_glsl, NULL);
219         }
220         if (!e_data.gpencil_simple_fullscreen_sh) {
221                 e_data.gpencil_simple_fullscreen_sh = DRW_shader_create_fullscreen(datatoc_gpencil_simple_mix_frag_glsl, NULL);
222         }
223
224         /* shaders for use when drawing */
225         if (!e_data.gpencil_background_sh) {
226                 e_data.gpencil_background_sh = DRW_shader_create_fullscreen(datatoc_gpencil_background_frag_glsl, NULL);
227         }
228         if (!e_data.gpencil_paper_sh) {
229                 e_data.gpencil_paper_sh = DRW_shader_create_fullscreen(datatoc_gpencil_paper_frag_glsl, NULL);
230         }
231 }
232
233 void GPENCIL_engine_init(void *vedata)
234 {
235         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
236         /* init storage */
237         if (!stl->storage) {
238                 stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), "GPENCIL_Storage");
239
240                 /* unit matrix */
241                 unit_m4(stl->storage->unit_matrix);
242         }
243
244         stl->storage->multisamples = U.gpencil_multisamples;
245
246         /* create framebuffers */
247         GPENCIL_create_framebuffers(vedata);
248
249         /* create shaders */
250         GPENCIL_create_shaders();
251         GPENCIL_create_fx_shaders(&e_data);
252
253         /* blank texture used if no texture defined for fill shader */
254         if (!e_data.gpencil_blank_texture) {
255                 float rect[16][16][4] = {{{0.0f}}};
256                 e_data.gpencil_blank_texture = DRW_texture_create_2D(16, 16, GPU_RGBA8, DRW_TEX_FILTER, (float *)rect);
257         }
258 }
259
260 static void GPENCIL_engine_free(void)
261 {
262         /* only free custom shaders, builtin shaders are freed in blender close */
263         DRW_SHADER_FREE_SAFE(e_data.gpencil_fill_sh);
264         DRW_SHADER_FREE_SAFE(e_data.gpencil_stroke_sh);
265         DRW_SHADER_FREE_SAFE(e_data.gpencil_point_sh);
266         DRW_SHADER_FREE_SAFE(e_data.gpencil_edit_point_sh);
267         DRW_SHADER_FREE_SAFE(e_data.gpencil_fullscreen_sh);
268         DRW_SHADER_FREE_SAFE(e_data.gpencil_simple_fullscreen_sh);
269         DRW_SHADER_FREE_SAFE(e_data.gpencil_background_sh);
270         DRW_SHADER_FREE_SAFE(e_data.gpencil_paper_sh);
271
272         DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture);
273
274         GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_stroke);
275         MEM_SAFE_FREE(e_data.batch_buffer_stroke);
276
277         GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill);
278         MEM_SAFE_FREE(e_data.batch_buffer_fill);
279
280         GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
281         MEM_SAFE_FREE(e_data.batch_grid);
282
283         /* effects */
284         GPENCIL_delete_fx_shaders(&e_data);
285 }
286
287 void GPENCIL_cache_init(void *vedata)
288 {
289         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
290         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
291         const DRWContextState *draw_ctx = DRW_context_state_get();
292         Scene *scene = draw_ctx->scene;
293         View3D *v3d = draw_ctx->v3d;
294
295         /* Special handling for when active object is GP object (e.g. for draw mode) */
296         Object *obact = draw_ctx->obact;
297         bGPdata *obact_gpd = NULL;
298         MaterialGPencilStyle *gp_style = NULL;
299
300         if (obact && (obact->type == OB_GPENCIL) && (obact->data)) {
301                 obact_gpd = (bGPdata *)obact->data;
302                 gp_style = BKE_material_gpencil_settings_get(obact, obact->actcol);
303         }
304
305         if (!stl->g_data) {
306                 /* Alloc transient pointers */
307                 stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
308                 stl->storage->xray = GP_XRAY_FRONT; /* used for drawing */
309                 stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID; /* used for drawing */
310         }
311         stl->storage->tonemapping = 0;
312
313         stl->g_data->shgrps_edit_line = NULL;
314         stl->g_data->shgrps_edit_point = NULL;
315
316         if (!stl->shgroups) {
317                 /* Alloc maximum size because count strokes is very slow and can be very complex due onion skinning.
318                    I tried to allocate only one block and using realloc, increasing the size when read a new strokes
319                    in cache_finish, but the realloc produce weird things on screen, so we keep as is while we found
320                    a better solution
321                  */
322                 stl->shgroups = MEM_mallocN(sizeof(GPENCIL_shgroup) * GPENCIL_MAX_SHGROUPS, "GPENCIL_shgroup");
323         }
324
325         /* init gp objects cache */
326         stl->g_data->gp_cache_used = 0;
327         stl->g_data->gp_cache_size = 0;
328         stl->g_data->gp_object_cache = NULL;
329
330         {
331                 /* Stroke pass */
332                 psl->stroke_pass = DRW_pass_create(
333                         "GPencil Stroke Pass",
334                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND);
335                 stl->storage->shgroup_id = 0;
336
337                 /* edit pass */
338                 psl->edit_pass = DRW_pass_create(
339                         "GPencil Edit Pass",
340                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
341
342                 /* detect if playing animation */
343                 if (draw_ctx->evil_C) {
344
345                         bool playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL;
346                         if (playing != stl->storage->is_playing) {
347                                 stl->storage->reset_cache = true;
348                         }
349                         stl->storage->is_playing = playing;
350                 }
351                 else {
352                         stl->storage->is_playing = false;
353                         stl->storage->reset_cache = false;
354                 }
355                 /* save render state */
356                 stl->storage->is_render = DRW_state_is_image_render();
357                 stl->storage->is_mat_preview = (bool)stl->storage->is_render && STREQ(scene->id.name + 2, "preview");
358
359                 if (obact_gpd) {
360                         /* for some reason, when press play there is a delay in the animation flag check
361                          * and this produces errors. To be sure, we set cache as dirty because the frame
362                          * is changing.
363                          */
364                         if (stl->storage->is_playing == true) {
365                                 obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
366                         }
367                         /* if render, set as dirty to update all data */
368                         else if (stl->storage->is_render == true) {
369                                 obact_gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
370                         }
371                 }
372
373                 /* save simplify flags (can change while drawing, so it's better to save) */
374                 stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing);
375                 stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing);
376                 stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->is_playing);
377
378                 /* save pixsize */
379                 stl->storage->pixsize = DRW_viewport_pixelsize_get();
380                 if ((!DRW_state_is_opengl_render()) && (stl->storage->is_render)) {
381                         stl->storage->pixsize = &stl->storage->render_pixsize;
382                 }
383
384                 /* detect if painting session */
385                 if ((obact_gpd) &&
386                     (obact_gpd->flag & GP_DATA_STROKE_PAINTMODE) &&
387                     (stl->storage->is_playing == false))
388                 {
389                         /* need the original to avoid cow overhead while drawing */
390                         bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&obact_gpd->id);
391                         if (((gpd_orig->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
392                             (gpd_orig->runtime.sbuffer_size > 0) &&
393                             ((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0))
394                         {
395                                 stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING;
396                         }
397                         else {
398                                 stl->g_data->session_flag = GP_DRW_PAINT_IDLE;
399                         }
400                 }
401                 else {
402                         /* if not drawing mode */
403                         stl->g_data->session_flag = GP_DRW_PAINT_HOLD;
404                 }
405
406                 if (gp_style) {
407                         stl->storage->stroke_style = gp_style->stroke_style;
408                         stl->storage->color_type = GPENCIL_COLOR_SOLID;
409                         if (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) {
410                                 stl->storage->color_type = GPENCIL_COLOR_TEXTURE;
411                                 if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
412                                         stl->storage->color_type = GPENCIL_COLOR_PATTERN;
413                                 }
414                         }
415                 }
416                 else {
417                         stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID;
418                         stl->storage->color_type = GPENCIL_COLOR_SOLID;
419                 }
420
421                 /* drawing buffer pass for drawing the stroke that is being drawing by the user. The data
422                  * is stored in sbuffer
423                  */
424                 psl->drawing_pass = DRW_pass_create(
425                         "GPencil Drawing Pass",
426                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
427
428                 /* full screen pass to combine the result with default framebuffer */
429                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
430                 psl->mix_pass = DRW_pass_create(
431                         "GPencil Mix Pass",
432                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
433                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass);
434                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
435                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeColor", &e_data.input_color_tx);
436                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &e_data.input_depth_tx);
437                 DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
438
439                 /* mix pass no blend used to copy between passes. A separated pass is required
440                  * because if mix_pass is used, the acumulation of blend degrade the colors.
441                  *
442                  * This pass is used too to take the snapshot used for background_pass. This image
443                  * will be used as the background while the user is drawing.
444                  */
445                 psl->mix_pass_noblend = DRW_pass_create(
446                         "GPencil Mix Pass no blend",
447                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
448                 DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass_noblend);
449                 DRW_shgroup_call_add(mix_shgrp_noblend, quad, NULL);
450                 DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeColor", &e_data.input_color_tx);
451                 DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeDepth", &e_data.input_depth_tx);
452                 DRW_shgroup_uniform_int(mix_shgrp_noblend, "tonemapping", &stl->storage->tonemapping, 1);
453
454                 /* Painting session pass (used only to speedup while the user is drawing )
455                  * This pass is used to show the snapshot of the current grease pencil strokes captured
456                  * when the user starts to draw (see comments above).
457                  * In this way, the previous strokes don't need to be redraw and the drawing process
458                  * is far to agile.
459                  */
460                 psl->background_pass = DRW_pass_create(
461                         "GPencil Background Painting Session Pass",
462                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
463                 DRWShadingGroup *background_shgrp = DRW_shgroup_create(e_data.gpencil_background_sh, psl->background_pass);
464                 DRW_shgroup_call_add(background_shgrp, quad, NULL);
465                 DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeColor", &e_data.background_color_tx);
466                 DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeDepth", &e_data.background_depth_tx);
467
468                 /* pass for drawing paper (only if viewport)
469                  * In render, the v3d is null so the paper is disabled
470                  * The paper is way to isolate the drawing in complex scene and to have a cleaner
471                  * drawing area.
472                  */
473                 if (v3d) {
474                         psl->paper_pass = DRW_pass_create(
475                                 "GPencil Paper Pass",
476                                 DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
477                         DRWShadingGroup *paper_shgrp = DRW_shgroup_create(e_data.gpencil_paper_sh, psl->paper_pass);
478                         DRW_shgroup_call_add(paper_shgrp, quad, NULL);
479                         DRW_shgroup_uniform_vec3(paper_shgrp, "color", v3d->shading.background_color, 1);
480                         DRW_shgroup_uniform_float(paper_shgrp, "opacity", &v3d->overlay.gpencil_paper_opacity, 1);
481                 }
482
483                 /* grid pass */
484                 if (v3d) {
485                         psl->grid_pass = DRW_pass_create(
486                                 "GPencil Grid Pass",
487                                 DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
488                         stl->g_data->shgrps_grid = DRW_shgroup_create(e_data.gpencil_line_sh, psl->grid_pass);
489                 }
490
491                 /* create effects passes */
492                 if (!stl->storage->simplify_fx) {
493                         GPENCIL_create_fx_passes(psl);
494                 }
495         }
496 }
497
498 static void gpencil_add_draw_data(void *vedata, Object *ob)
499 {
500         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
501         const DRWContextState *draw_ctx = DRW_context_state_get();
502         Scene *scene = draw_ctx->scene;
503         bGPdata *gpd = (bGPdata *)ob->data;
504         const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
505
506         int i = stl->g_data->gp_cache_used - 1;
507         tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
508
509         /* save init shading group */
510         cache_ob->init_grp = stl->storage->shgroup_id;
511
512         /* fill shading groups */
513         if ((!is_multiedit) || (cache_ob->is_dup_ob)) {
514                 DRW_gpencil_populate_datablock(&e_data, vedata, scene, ob, cache_ob);
515         }
516         else {
517                 DRW_gpencil_populate_multiedit(&e_data, vedata, scene, ob, cache_ob);
518         }
519
520         /* save end shading group */
521         cache_ob->end_grp = stl->storage->shgroup_id - 1;
522
523         /* FX passses */
524         cache_ob->has_fx = false;
525         if ((!stl->storage->simplify_fx) &&
526             (BKE_shaderfx_has_gpencil(ob)))
527         {
528                 cache_ob->has_fx = true;
529                 if ((!stl->storage->simplify_fx) && (!is_multiedit)) {
530                         DRW_gpencil_fx_prepare(&e_data, vedata, cache_ob);
531                 }
532         }
533
534 }
535
536 void GPENCIL_cache_populate(void *vedata, Object *ob)
537 {
538         /* object must be visible */
539         if (!DRW_object_is_visible_in_active_context(ob)) {
540                 return;
541         }
542
543         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
544         const DRWContextState *draw_ctx = DRW_context_state_get();
545         Scene *scene = draw_ctx->scene;
546         ToolSettings *ts = scene->toolsettings;
547         View3D *v3d = draw_ctx->v3d;
548
549         if (ob->type == OB_GPENCIL && ob->data) {
550                 bGPdata *gpd = (bGPdata *)ob->data;
551
552                 /* if onion, set as dirty always
553                  * This reduces performance, but avoid any crash in the multiple
554                  * overlay and multiwindow options
555                  */
556                 if (gpd->flag & GP_DATA_SHOW_ONIONSKINS) {
557                         gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
558                 }
559
560                 /* when start/stop animation the cache must be set as dirty to reset all data */
561                 if (stl->storage->reset_cache) {
562                         gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
563                         stl->storage->reset_cache = false;
564                 }
565
566                 /* is edit mode only current object, not particle instances */
567                 if ((ob->base_flag & BASE_FROMDUPLI) && GPENCIL_ANY_EDIT_MODE(gpd)) {
568                         return;
569                 }
570
571                 if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) {
572
573                         /* save gp objects for drawing later */
574                         stl->g_data->gp_object_cache = gpencil_object_cache_add(
575                                 stl->g_data->gp_object_cache, ob,
576                                 &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
577
578                         /* load drawing data */
579                         gpencil_add_draw_data(vedata, ob);
580                 }
581
582                 /* draw current painting strokes
583                 * (only if region is equal to originated paint region)
584                 */
585                 if ((draw_ctx->obact == ob) &&
586                     ((gpd->runtime.ar == NULL) || (gpd->runtime.ar == draw_ctx->ar)))
587                 {
588                         DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob);
589                 }
590
591                 /* grid */
592                 if ((v3d) &&
593                     ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
594                     (v3d->gp_flag & V3D_GP_SHOW_GRID) &&
595                     (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact))
596                 {
597                         GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
598                         MEM_SAFE_FREE(e_data.batch_grid);
599
600                         e_data.batch_grid = DRW_gpencil_get_grid(ob);
601
602                         /* define grid orientation */
603                         if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_VIEW) {
604                                 copy_m4_m4(stl->storage->grid_matrix, ob->obmat);
605                         }
606                         else {
607                                 /* align always to view */
608                                 invert_m4_m4(stl->storage->grid_matrix, draw_ctx->rv3d->viewmat);
609                                 /* copy ob location */
610                                 copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
611                         }
612
613                         DRW_shgroup_call_add(
614                                 stl->g_data->shgrps_grid,
615                                 e_data.batch_grid,
616                                 stl->storage->grid_matrix);
617                 }
618         }
619 }
620
621 void GPENCIL_cache_finish(void *UNUSED(vedata))
622 {
623         return;
624
625 }
626
627 /* helper function to sort inverse gpencil objects using qsort */
628 static int gpencil_object_cache_compare_zdepth(const void *a1, const void *a2)
629 {
630         const tGPencilObjectCache *ps1 = a1, *ps2 = a2;
631
632         if (ps1->zdepth < ps2->zdepth) return 1;
633         else if (ps1->zdepth > ps2->zdepth) return -1;
634
635         return 0;
636 }
637
638 /* prepare a texture with full viewport screenshot for fast drawing */
639 static void gpencil_prepare_fast_drawing(
640         GPENCIL_StorageList *stl, DefaultFramebufferList *dfbl,
641         GPENCIL_FramebufferList *fbl, DRWPass *pass,
642         const float clearcol[4])
643 {
644         if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
645                 GPU_framebuffer_bind(fbl->background_fb);
646                 /* clean only in first loop cycle */
647                 if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) {
648                         GPU_framebuffer_clear_color_depth(fbl->background_fb, clearcol, 1.0f);
649                         stl->g_data->session_flag = GP_DRW_PAINT_FILLING;
650                 }
651                 /* repeat pass to fill temp texture */
652                 DRW_draw_pass(pass);
653                 /* set default framebuffer again */
654                 GPU_framebuffer_bind(dfbl->default_fb);
655         }
656 }
657
658 static void gpencil_free_obj_runtime(GPENCIL_StorageList *stl)
659 {
660         /* free the cache itself */
661         MEM_SAFE_FREE(stl->g_data->gp_object_cache);
662 }
663
664 /* draw scene */
665 void GPENCIL_draw_scene(void *ved)
666 {
667         GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
668         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
669
670         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
671         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
672         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
673         GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
674
675         int init_grp, end_grp;
676         tGPencilObjectCache *cache_ob;
677         const float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
678
679         const DRWContextState *draw_ctx = DRW_context_state_get();
680         View3D *v3d = draw_ctx->v3d;
681         Object *obact = draw_ctx->obact;
682         const bool playing = stl->storage->is_playing;
683         const bool is_render = stl->storage->is_render;
684
685         /* paper pass to display a comfortable area to draw over complex scenes with geometry */
686         if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
687                 if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
688                     (v3d->gp_flag & V3D_GP_SHOW_PAPER))
689                 {
690                         DRW_draw_pass(psl->paper_pass);
691                 }
692         }
693
694         /* if we have a painting session, we use fast viewport drawing method */
695         if ((!is_render) && (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING)) {
696                 GPU_framebuffer_bind(dfbl->default_fb);
697
698                 MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
699
700                 DRW_draw_pass(psl->background_pass);
701                 DRW_draw_pass(psl->drawing_pass);
702
703                 MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, dfbl->default_fb, txl);
704
705                 /* free memory */
706                 gpencil_free_obj_runtime(stl);
707
708                 /* grid pass */
709                 if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
710                         if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
711                             (v3d->gp_flag & V3D_GP_SHOW_GRID))
712                         {
713                                 DRW_draw_pass(psl->grid_pass);
714                         }
715                 }
716
717                 return;
718         }
719
720         if (DRW_state_is_fbo()) {
721
722                 /* Draw all pending objects */
723                 if (stl->g_data->gp_cache_used > 0) {
724
725                         /* sort by zdepth */
726                         qsort(stl->g_data->gp_object_cache, stl->g_data->gp_cache_used,
727                               sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth);
728
729                         for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
730                                 cache_ob = &stl->g_data->gp_object_cache[i];
731                                 bGPdata *gpd = cache_ob->gpd;
732                                 init_grp = cache_ob->init_grp;
733                                 end_grp = cache_ob->end_grp;
734
735                                 /* Render stroke in separated framebuffer */
736                                 GPU_framebuffer_bind(fbl->temp_fb_a);
737                                 GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
738
739                                 /* Stroke Pass: DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH
740                                  * draw only a subset that usually start with a fill and end with stroke because the
741                                  * shading groups are created by pairs */
742                                 if (end_grp >= init_grp) {
743                                         /* previews don't use AA */
744                                         if (!stl->storage->is_mat_preview) {
745                                                 MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
746                                         }
747
748                                         DRW_draw_pass_subset(
749                                                 psl->stroke_pass,
750                                                 stl->shgroups[init_grp].shgrps_fill != NULL ?
751                                                 stl->shgroups[init_grp].shgrps_fill : stl->shgroups[init_grp].shgrps_stroke,
752                                                 stl->shgroups[end_grp].shgrps_stroke);
753
754                                         if (!stl->storage->is_mat_preview) {
755                                                 MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fbl->temp_fb_a, txl);
756                                         }
757                                 }
758
759                                 /* Current buffer drawing */
760                                 if ((!is_render) && (cache_ob->is_dup_ob == false)) {
761                                         DRW_draw_pass(psl->drawing_pass);
762                                 }
763                                 /* fx passes */
764                                 if (cache_ob->has_fx == true) {
765                                         stl->storage->tonemapping = 0;
766                                         DRW_gpencil_fx_draw(&e_data, vedata, cache_ob);
767                                 }
768
769                                 e_data.input_depth_tx = e_data.temp_depth_tx_a;
770                                 e_data.input_color_tx = e_data.temp_color_tx_a;
771
772                                 /* Combine with scene buffer */
773                                 if ((!is_render) || (fbl->main == NULL)) {
774                                         GPU_framebuffer_bind(dfbl->default_fb);
775                                 }
776                                 else {
777                                         GPU_framebuffer_bind(fbl->main);
778                                 }
779                                 /* tonemapping */
780                                 stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
781
782                                 DRW_draw_pass(psl->mix_pass);
783
784                                 /* prepare for fast drawing */
785                                 if (!is_render) {
786                                         if (!playing) {
787                                                 gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol);
788                                         }
789                                 }
790                                 else {
791                                         /* if render, the cache must be dirty for next loop */
792                                         gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
793                                 }
794                         }
795                         /* edit points */
796                         if ((!is_render) && (!playing)) {
797                                 DRW_draw_pass(psl->edit_pass);
798                         }
799                 }
800                 /* grid pass */
801                 if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
802                         if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) &&
803                             (v3d->gp_flag & V3D_GP_SHOW_GRID))
804                         {
805                                 DRW_draw_pass(psl->grid_pass);
806                         }
807                 }
808         }
809         /* free memory */
810         gpencil_free_obj_runtime(stl);
811
812         /* reset  */
813         if (DRW_state_is_fbo()) {
814                 /* attach again default framebuffer */
815                 if (!is_render) {
816                         GPU_framebuffer_bind(dfbl->default_fb);
817                 }
818
819                 /* the temp texture is ready. Now we can use fast screen drawing */
820                 if (stl->g_data->session_flag & GP_DRW_PAINT_FILLING) {
821                         stl->g_data->session_flag = GP_DRW_PAINT_READY;
822                 }
823         }
824 }
825
826 static const DrawEngineDataSize GPENCIL_data_size = DRW_VIEWPORT_DATA_SIZE(GPENCIL_Data);
827
828 DrawEngineType draw_engine_gpencil_type = {
829         NULL, NULL,
830         N_("GpencilMode"),
831         &GPENCIL_data_size,
832         &GPENCIL_engine_init,
833         &GPENCIL_engine_free,
834         &GPENCIL_cache_init,
835         &GPENCIL_cache_populate,
836         &GPENCIL_cache_finish,
837         NULL,
838         &GPENCIL_draw_scene,
839         NULL,
840         NULL,
841         &GPENCIL_render_to_image,
842 };