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