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