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