5f2652b0bfb55f16a82b509bd333206cc5a4c8bb
[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                         {
419                                 stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING;
420                         }
421                         else {
422                                 stl->g_data->session_flag = GP_DRW_PAINT_IDLE;
423                         }
424                 }
425                 else {
426                         /* if not drawing mode */
427                         stl->g_data->session_flag = GP_DRW_PAINT_HOLD;
428                 }
429
430                 if (gp_style) {
431                         stl->storage->stroke_style = gp_style->stroke_style;
432                         stl->storage->color_type = GPENCIL_COLOR_SOLID;
433                         if (gp_style->stroke_style == GP_STYLE_STROKE_STYLE_TEXTURE) {
434                                 stl->storage->color_type = GPENCIL_COLOR_TEXTURE;
435                                 if (gp_style->flag & GP_STYLE_STROKE_PATTERN) {
436                                         stl->storage->color_type = GPENCIL_COLOR_PATTERN;
437                                 }
438                         }
439                 }
440                 else {
441                         stl->storage->stroke_style = GP_STYLE_STROKE_STYLE_SOLID;
442                         stl->storage->color_type = GPENCIL_COLOR_SOLID;
443                 }
444
445                 /* drawing buffer pass for drawing the stroke that is being drawing by the user. The data
446                  * is stored in sbuffer
447                  */
448                 psl->drawing_pass = DRW_pass_create(
449                         "GPencil Drawing Pass",
450                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
451
452                 /* full screen pass to combine the result with default framebuffer */
453                 struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
454                 psl->mix_pass = DRW_pass_create(
455                         "GPencil Mix Pass",
456                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
457                 DRWShadingGroup *mix_shgrp = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass);
458                 DRW_shgroup_call_add(mix_shgrp, quad, NULL);
459                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeColor", &e_data.input_color_tx);
460                 DRW_shgroup_uniform_texture_ref(mix_shgrp, "strokeDepth", &e_data.input_depth_tx);
461                 DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
462                 DRW_shgroup_uniform_int(mix_shgrp, "do_select", &stl->storage->do_select_outline, 1);
463                 DRW_shgroup_uniform_vec4(mix_shgrp, "select_color", stl->storage->select_color, 1);
464
465                 /* mix pass no blend used to copy between passes. A separated pass is required
466                  * because if mix_pass is used, the acumulation of blend degrade the colors.
467                  *
468                  * This pass is used too to take the snapshot used for background_pass. This image
469                  * will be used as the background while the user is drawing.
470                  */
471                 psl->mix_pass_noblend = DRW_pass_create(
472                         "GPencil Mix Pass no blend",
473                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
474                 DRWShadingGroup *mix_shgrp_noblend = DRW_shgroup_create(e_data.gpencil_fullscreen_sh, psl->mix_pass_noblend);
475                 DRW_shgroup_call_add(mix_shgrp_noblend, quad, NULL);
476                 DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeColor", &e_data.input_color_tx);
477                 DRW_shgroup_uniform_texture_ref(mix_shgrp_noblend, "strokeDepth", &e_data.input_depth_tx);
478                 DRW_shgroup_uniform_int(mix_shgrp_noblend, "tonemapping", &stl->storage->tonemapping, 1);
479                 DRW_shgroup_uniform_int(mix_shgrp_noblend, "do_select", &stl->storage->do_select_outline, 1);
480                 DRW_shgroup_uniform_vec4(mix_shgrp_noblend, "select_color", stl->storage->select_color, 1);
481
482                 /* Painting session pass (used only to speedup while the user is drawing )
483                  * This pass is used to show the snapshot of the current grease pencil strokes captured
484                  * when the user starts to draw (see comments above).
485                  * In this way, the previous strokes don't need to be redraw and the drawing process
486                  * is far to agile.
487                  */
488                 psl->background_pass = DRW_pass_create(
489                         "GPencil Background Painting Session Pass",
490                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
491                 DRWShadingGroup *background_shgrp = DRW_shgroup_create(e_data.gpencil_background_sh, psl->background_pass);
492                 DRW_shgroup_call_add(background_shgrp, quad, NULL);
493                 DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeColor", &e_data.background_color_tx);
494                 DRW_shgroup_uniform_texture_ref(background_shgrp, "strokeDepth", &e_data.background_depth_tx);
495
496                 /* pass for drawing paper (only if viewport)
497                  * In render, the v3d is null so the paper is disabled
498                  * The paper is way to isolate the drawing in complex scene and to have a cleaner
499                  * drawing area.
500                  */
501                 if (v3d) {
502                         psl->paper_pass = DRW_pass_create(
503                                 "GPencil Paper Pass",
504                                 DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
505                         DRWShadingGroup *paper_shgrp = DRW_shgroup_create(e_data.gpencil_paper_sh, psl->paper_pass);
506                         DRW_shgroup_call_add(paper_shgrp, quad, NULL);
507                         DRW_shgroup_uniform_vec3(paper_shgrp, "color", v3d->shading.background_color, 1);
508                         DRW_shgroup_uniform_float(paper_shgrp, "opacity", &v3d->overlay.gpencil_paper_opacity, 1);
509                 }
510
511                 /* grid pass */
512                 if (v3d) {
513                         psl->grid_pass = DRW_pass_create(
514                                 "GPencil Grid Pass",
515                                 DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
516                         stl->g_data->shgrps_grid = DRW_shgroup_create(e_data.gpencil_line_sh, psl->grid_pass);
517                 }
518
519                 /* blend layers pass */
520                 psl->blend_pass = DRW_pass_create(
521                         "GPencil Blend Layers Pass",
522                         DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
523                 DRWShadingGroup *blend_shgrp = DRW_shgroup_create(e_data.gpencil_blend_fullscreen_sh, psl->blend_pass);
524                 DRW_shgroup_call_add(blend_shgrp, quad, NULL);
525                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeColor", &e_data.temp_color_tx_a);
526                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "strokeDepth", &e_data.temp_depth_tx_a);
527                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendColor", &e_data.temp_color_tx_fx);
528                 DRW_shgroup_uniform_texture_ref(blend_shgrp, "blendDepth", &e_data.temp_depth_tx_fx);
529                 DRW_shgroup_uniform_int(blend_shgrp, "mode", &stl->storage->blend_mode, 1);
530                 DRW_shgroup_uniform_int(blend_shgrp, "clamp_layer", &stl->storage->clamp_layer, 1);
531                 DRW_shgroup_uniform_float(blend_shgrp, "blend_opacity", &stl->storage->blend_opacity, 1);
532                 DRW_shgroup_uniform_int(mix_shgrp, "tonemapping", &stl->storage->tonemapping, 1);
533
534                 /* create effects passes */
535                 if (!stl->storage->simplify_fx) {
536                         GPENCIL_create_fx_passes(psl);
537                 }
538         }
539 }
540
541 static void gpencil_add_draw_data(void *vedata, Object *ob)
542 {
543         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
544         bGPdata *gpd = (bGPdata *)ob->data;
545         const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
546
547         int i = stl->g_data->gp_cache_used - 1;
548         tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
549
550         if (!cache_ob->is_dup_ob) {
551                 /* fill shading groups */
552                 if (!is_multiedit) {
553                         DRW_gpencil_populate_datablock(&e_data, vedata, ob, cache_ob);
554                 }
555                 else {
556                         DRW_gpencil_populate_multiedit(&e_data, vedata, ob, cache_ob);
557                 }
558         }
559
560         /* FX passses */
561         cache_ob->has_fx = false;
562         if ((!stl->storage->simplify_fx) &&
563             (!ELEM(cache_ob->shading_type[0], OB_WIRE, OB_SOLID)) &&
564             (BKE_shaderfx_has_gpencil(ob)))
565         {
566                 cache_ob->has_fx = true;
567                 if ((!stl->storage->simplify_fx) && (!is_multiedit)) {
568                         DRW_gpencil_fx_prepare(&e_data, vedata, cache_ob);
569                 }
570         }
571 }
572
573 void GPENCIL_cache_populate(void *vedata, Object *ob)
574 {
575         /* object must be visible */
576         if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
577                 return;
578         }
579
580         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
581         const DRWContextState *draw_ctx = DRW_context_state_get();
582         Scene *scene = draw_ctx->scene;
583         ToolSettings *ts = scene->toolsettings;
584         View3D *v3d = draw_ctx->v3d;
585
586         if (ob->type == OB_GPENCIL && ob->data) {
587                 bGPdata *gpd = (bGPdata *)ob->data;
588
589                 /* enable multisample and basic framebuffer creation */
590                 stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_MULTISAMPLE;
591                 stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_BASIC;
592
593                 /* when start/stop animation the cache must be set as dirty to reset all data */
594                 if (stl->storage->reset_cache) {
595                         gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
596                         stl->storage->reset_cache = false;
597                 }
598
599                 if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) {
600                         /* bound box object are not visible, only external box*/
601                         if (ob->dt != OB_BOUNDBOX) {
602                                 /* save gp objects for drawing later */
603                                 stl->g_data->gp_object_cache = gpencil_object_cache_add(
604                                         stl->g_data->gp_object_cache, ob,
605                                         &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
606
607                                 /* enable instance loop */
608                                 if (!stl->g_data->do_instances) {
609                                         stl->g_data->do_instances = ob->base_flag & BASE_FROM_DUPLI;
610                                 }
611
612                                 /* load drawing data */
613                                 gpencil_add_draw_data(vedata, ob);
614                         }
615                 }
616
617                 /* draw current painting strokes
618                  * (only if region is equal to originated paint region) */
619                 if ((draw_ctx->obact == ob) &&
620                     ((gpd->runtime.ar == NULL) || (gpd->runtime.ar == draw_ctx->ar)))
621                 {
622                         DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob);
623                 }
624
625                 /* grid */
626                 if ((v3d) &&
627                     ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
628                     (v3d->gp_flag & V3D_GP_SHOW_GRID) &&
629                     (ob->type == OB_GPENCIL) && (ob == draw_ctx->obact))
630                 {
631                         GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
632                         MEM_SAFE_FREE(e_data.batch_grid);
633
634                         e_data.batch_grid = DRW_gpencil_get_grid(ob);
635
636                         /* define grid orientation */
637                         if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_VIEW) {
638                                 copy_m4_m4(stl->storage->grid_matrix, ob->obmat);
639                         }
640                         else {
641                                 /* align always to view */
642                                 invert_m4_m4(stl->storage->grid_matrix, draw_ctx->rv3d->viewmat);
643                                 /* copy ob location */
644                                 copy_v3_v3(stl->storage->grid_matrix[3], ob->obmat[3]);
645                         }
646
647                         DRW_shgroup_call_add(
648                                 stl->g_data->shgrps_grid,
649                                 e_data.batch_grid,
650                                 stl->storage->grid_matrix);
651                 }
652         }
653 }
654
655 void GPENCIL_cache_finish(void *vedata)
656 {
657         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
658         tGPencilObjectCache *cache_ob = NULL;
659         Object *ob = NULL;
660
661         /* create data for instances */
662         if (stl->g_data->do_instances) {
663                 GHash *gh_objects = BLI_ghash_str_new(__func__);
664                 /* create hash of real object (non duplicated) */
665                 for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
666                         cache_ob = &stl->g_data->gp_object_cache[i];
667                         if (!cache_ob->is_dup_ob) {
668                                 ob = cache_ob->ob;
669                                 char *name = BKE_id_to_unique_string_key(&ob->id);
670                                 BLI_ghash_insert(gh_objects, name, cache_ob->ob);
671                         }
672                 }
673
674                 /* draw particles */
675                 DRW_gpencil_populate_particles(&e_data, gh_objects, vedata);
676
677                 /* free hash */
678                 BLI_ghash_free(gh_objects, MEM_freeN, NULL);
679         }
680
681         if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
682                 stl->storage->framebuffer_flag |= GP_FRAMEBUFFER_DRAW;
683         }
684
685         /* create framebuffers (only for normal drawing) */
686         if (!DRW_state_is_select()) {
687                 GPENCIL_create_framebuffers(vedata);
688         }
689 }
690
691 /* helper function to sort inverse gpencil objects using qsort */
692 static int gpencil_object_cache_compare_zdepth(const void *a1, const void *a2)
693 {
694         const tGPencilObjectCache *ps1 = a1, *ps2 = a2;
695
696         if (ps1->zdepth < ps2->zdepth) return 1;
697         else if (ps1->zdepth > ps2->zdepth) return -1;
698
699         return 0;
700 }
701
702 /* prepare a texture with full viewport screenshot for fast drawing */
703 static void gpencil_prepare_fast_drawing(
704         GPENCIL_StorageList *stl, DefaultFramebufferList *dfbl,
705         GPENCIL_FramebufferList *fbl, DRWPass *pass,
706         const float clearcol[4])
707 {
708         if (stl->g_data->session_flag & (GP_DRW_PAINT_IDLE | GP_DRW_PAINT_FILLING)) {
709                 GPU_framebuffer_bind(fbl->background_fb);
710                 /* clean only in first loop cycle */
711                 if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) {
712                         GPU_framebuffer_clear_color_depth(fbl->background_fb, clearcol, 1.0f);
713                         stl->g_data->session_flag = GP_DRW_PAINT_FILLING;
714                 }
715                 /* repeat pass to fill temp texture */
716                 DRW_draw_pass(pass);
717                 /* set default framebuffer again */
718                 GPU_framebuffer_bind(dfbl->default_fb);
719         }
720 }
721
722 static void gpencil_free_obj_runtime(GPENCIL_StorageList *stl)
723 {
724         if (stl->g_data->gp_object_cache == NULL) {
725                 return;
726         }
727
728         /* reset all cache flags */
729         for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
730                 tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
731                 if (cache_ob) {
732                         bGPdata *gpd = cache_ob->gpd;
733                         gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
734
735                         /* free shgrp array */
736                         cache_ob->tot_layers = 0;
737                         MEM_SAFE_FREE(cache_ob->name);
738                         MEM_SAFE_FREE(cache_ob->shgrp_array);
739                 }
740         }
741
742         /* free the cache itself */
743         MEM_SAFE_FREE(stl->g_data->gp_object_cache);
744 }
745
746 static void gpencil_draw_pass_range(
747         GPENCIL_FramebufferList *fbl, GPENCIL_StorageList *stl,
748         GPENCIL_PassList *psl, GPENCIL_TextureList *txl,
749         GPUFrameBuffer *fb, Object *ob, bGPdata *gpd,
750         DRWShadingGroup *init_shgrp, DRWShadingGroup *end_shgrp, bool multi)
751 {
752         if (init_shgrp == NULL) {
753                 return;
754         }
755
756         /* previews don't use AA */
757         if ((!stl->storage->is_mat_preview) && (multi)) {
758                 MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
759         }
760
761         DRW_draw_pass_subset(
762                 GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d,
763                 init_shgrp, end_shgrp);
764
765         if ((!stl->storage->is_mat_preview) && (multi)) {
766                 MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl);
767         }
768 }
769
770 /* draw strokes to use for selection */
771 static void drw_gpencil_select_render(GPENCIL_StorageList *stl, GPENCIL_PassList *psl)
772 {
773         tGPencilObjectCache *cache_ob;
774         tGPencilObjectCache_shgrp *array_elm = NULL;
775         DRWShadingGroup *init_shgrp = NULL;
776         DRWShadingGroup *end_shgrp = NULL;
777
778         /* Draw all pending objects */
779         if ((stl->g_data->gp_cache_used > 0) &&
780             (stl->g_data->gp_object_cache))
781         {
782                 /* sort by zdepth */
783                 qsort(stl->g_data->gp_object_cache, stl->g_data->gp_cache_used,
784                       sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth);
785
786                 for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
787                         cache_ob = &stl->g_data->gp_object_cache[i];
788                         if (cache_ob) {
789                                 Object *ob = cache_ob->ob;
790                                 bGPdata *gpd = cache_ob->gpd;
791                                 init_shgrp = NULL;
792                                 if (cache_ob->tot_layers > 0) {
793                                         for (int e = 0; e < cache_ob->tot_layers; e++) {
794                                                 array_elm = &cache_ob->shgrp_array[e];
795                                                 if (init_shgrp == NULL) {
796                                                         init_shgrp = array_elm->init_shgrp;
797                                                 }
798                                                 end_shgrp = array_elm->end_shgrp;
799                                         }
800                                         /* draw group */
801                                         DRW_draw_pass_subset(
802                                                 GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d,
803                                                 init_shgrp, end_shgrp);
804                                 }
805                                 /* the cache must be dirty for next loop */
806                                 gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
807                         }
808                 }
809         }
810 }
811
812 /* draw scene */
813 void GPENCIL_draw_scene(void *ved)
814 {
815         GPENCIL_Data *vedata = (GPENCIL_Data *)ved;
816         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
817
818         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
819         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
820         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
821         GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
822
823         tGPencilObjectCache *cache_ob;
824         tGPencilObjectCache_shgrp *array_elm = NULL;
825         DRWShadingGroup *init_shgrp = NULL;
826         DRWShadingGroup *end_shgrp = NULL;
827
828         const float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
829
830         const DRWContextState *draw_ctx = DRW_context_state_get();
831         View3D *v3d = draw_ctx->v3d;
832         Object *obact = draw_ctx->obact;
833         const bool playing = stl->storage->is_playing;
834         const bool is_render = stl->storage->is_render;
835         bGPdata *gpd_act = (obact) && (obact->type == OB_GPENCIL) ? (bGPdata *)obact->data : NULL;
836         const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd_act);
837         const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
838
839         /* if the draw is for select, do a basic drawing and return */
840         if (DRW_state_is_select()) {
841                 drw_gpencil_select_render(stl, psl);
842                 /* free memory */
843                 gpencil_free_obj_runtime(stl);
844                 return;
845         }
846
847         /* paper pass to display a comfortable area to draw over complex scenes with geometry */
848         if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
849                 if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
850                     (v3d->gp_flag & V3D_GP_SHOW_PAPER))
851                 {
852                         DRW_draw_pass(psl->paper_pass);
853                 }
854         }
855
856         /* if we have a painting session, we use fast viewport drawing method */
857         if ((!is_render) && (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING)) {
858                 GPU_framebuffer_bind(dfbl->default_fb);
859
860                 MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl);
861                 if (obact->dt != OB_BOUNDBOX) {
862                         DRW_draw_pass(psl->background_pass);
863                 }
864                 DRW_draw_pass(psl->drawing_pass);
865
866                 MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, dfbl->default_fb, txl);
867
868                 /* free memory */
869                 gpencil_free_obj_runtime(stl);
870
871                 /* grid pass */
872                 if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
873                         if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
874                             (v3d->gp_flag & V3D_GP_SHOW_GRID))
875                         {
876                                 DRW_draw_pass(psl->grid_pass);
877                         }
878                 }
879                 return;
880         }
881
882         if (DRW_state_is_fbo()) {
883
884                 /* Draw all pending objects */
885                 if (stl->g_data->gp_cache_used > 0) {
886                         /* sort by zdepth */
887                         qsort(stl->g_data->gp_object_cache, stl->g_data->gp_cache_used,
888                               sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth);
889
890                         for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
891                                 cache_ob = &stl->g_data->gp_object_cache[i];
892                                 Object *ob = cache_ob->ob;
893                                 bGPdata *gpd = cache_ob->gpd;
894                                 init_shgrp = NULL;
895                                 /* Render stroke in separated framebuffer */
896                                 GPU_framebuffer_bind(fbl->temp_fb_a);
897                                 GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
898
899                                 /* Stroke Pass:
900                                  * draw only a subset that usually starts with a fill and ends with stroke
901                                  */
902                                 bool use_blend = false;
903                                 if (cache_ob->tot_layers > 0) {
904                                         for (int e = 0; e < cache_ob->tot_layers; e++) {
905                                                 bool is_last = e == cache_ob->tot_layers - 1 ? true : false;
906                                                 array_elm = &cache_ob->shgrp_array[e];
907
908                                                 if (((array_elm->mode == eGplBlendMode_Normal) &&
909                                                      (!use_blend) && (!array_elm->clamp_layer)) ||
910                                                     (e == 0))
911                                                 {
912                                                         if (init_shgrp == NULL) {
913                                                                 init_shgrp = array_elm->init_shgrp;
914                                                         }
915                                                         end_shgrp = array_elm->end_shgrp;
916                                                 }
917                                                 else {
918                                                         use_blend = true;
919                                                         /* draw pending groups */
920                                                         gpencil_draw_pass_range(
921                                                                 fbl, stl, psl, txl, fbl->temp_fb_a,
922                                                                 ob, gpd, init_shgrp, end_shgrp, is_last);
923
924                                                         /* draw current group in separated texture */
925                                                         init_shgrp = array_elm->init_shgrp;
926                                                         end_shgrp = array_elm->end_shgrp;
927
928                                                         GPU_framebuffer_bind(fbl->temp_fb_fx);
929                                                         GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
930                                                         gpencil_draw_pass_range(
931                                                                 fbl, stl, psl, txl, fbl->temp_fb_fx,
932                                                                 ob, gpd, init_shgrp, end_shgrp,
933                                                                 is_last);
934
935                                                         /* Blend A texture and FX texture */
936                                                         GPU_framebuffer_bind(fbl->temp_fb_b);
937                                                         GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
938                                                         stl->storage->blend_mode = array_elm->mode;
939                                                         stl->storage->clamp_layer = (int)array_elm->clamp_layer;
940                                                         stl->storage->blend_opacity = array_elm->blend_opacity;
941                                                         stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
942                                                         DRW_draw_pass(psl->blend_pass);
943                                                         stl->storage->tonemapping = 0;
944
945                                                         /* Copy B texture to A texture to follow loop */
946                                                         e_data.input_depth_tx = e_data.temp_depth_tx_b;
947                                                         e_data.input_color_tx = e_data.temp_color_tx_b;
948
949                                                         GPU_framebuffer_bind(fbl->temp_fb_a);
950                                                         GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
951                                                         DRW_draw_pass(psl->mix_pass_noblend);
952
953                                                         /* prepare next group */
954                                                         init_shgrp = NULL;
955                                                 }
956                                         }
957                                         /* last group */
958                                         gpencil_draw_pass_range(
959                                                 fbl, stl, psl, txl, fbl->temp_fb_a,
960                                                 ob, gpd, init_shgrp, end_shgrp,
961                                                 true);
962                                 }
963
964                                 /* Current buffer drawing */
965                                 if ((!is_render) && (cache_ob->is_dup_ob == false)) {
966                                         DRW_draw_pass(psl->drawing_pass);
967                                 }
968                                 /* fx passes */
969                                 if (cache_ob->has_fx == true) {
970                                         stl->storage->tonemapping = 0;
971                                         DRW_gpencil_fx_draw(&e_data, vedata, cache_ob);
972                                 }
973
974                                 e_data.input_depth_tx = e_data.temp_depth_tx_a;
975                                 e_data.input_color_tx = e_data.temp_color_tx_a;
976
977                                 /* Combine with scene buffer */
978                                 if ((!is_render) || (fbl->main == NULL)) {
979                                         GPU_framebuffer_bind(dfbl->default_fb);
980                                 }
981                                 else {
982                                         GPU_framebuffer_bind(fbl->main);
983                                 }
984                                 /* tonemapping */
985                                 stl->storage->tonemapping = stl->storage->is_render ? 1 : 0;
986
987                                 /* active select flag and selection color */
988                                 stl->storage->do_select_outline = (
989                                         (overlay) &&
990                                         (ob->base_flag & BASE_SELECTED) &&
991                                         (ob->mode == OB_MODE_OBJECT) &&
992                                         (!is_render) && (!playing) &&
993                                         (v3d->flag & V3D_SELECT_OUTLINE));
994
995                                 /* if active object is not object mode, disable for all objects */
996                                 if ((draw_ctx->obact) && (draw_ctx->obact->mode != OB_MODE_OBJECT)) {
997                                         stl->storage->do_select_outline = 0;
998                                 }
999                                 UI_GetThemeColorShadeAlpha4fv(
1000                                         (ob == draw_ctx->obact) ? TH_ACTIVE : TH_SELECT, 0, -40,
1001                                         stl->storage->select_color);
1002
1003                                 /* draw mix pass */
1004                                 DRW_draw_pass(psl->mix_pass);
1005
1006                                 /* disable select flag */
1007                                 stl->storage->do_select_outline = 0;
1008
1009                                 /* prepare for fast drawing */
1010                                 if (!is_render) {
1011                                         if (!playing) {
1012                                                 gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol);
1013                                         }
1014                                 }
1015                                 else {
1016                                         /* if render, the cache must be dirty for next loop */
1017                                         gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
1018                                 }
1019                         }
1020                         /* edit points */
1021                         if ((!is_render) && (!playing) && (is_edit)) {
1022                                 DRW_draw_pass(psl->edit_pass);
1023                         }
1024                 }
1025                 /* grid pass */
1026                 if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
1027                         if (((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) &&
1028                             (v3d->gp_flag & V3D_GP_SHOW_GRID))
1029                         {
1030                                 DRW_draw_pass(psl->grid_pass);
1031                         }
1032                 }
1033         }
1034         /* free memory */
1035         gpencil_free_obj_runtime(stl);
1036
1037         /* reset  */
1038         if (DRW_state_is_fbo()) {
1039                 /* attach again default framebuffer */
1040                 if (!is_render) {
1041                         GPU_framebuffer_bind(dfbl->default_fb);
1042                 }
1043
1044                 /* the temp texture is ready. Now we can use fast screen drawing */
1045                 if (stl->g_data->session_flag & GP_DRW_PAINT_FILLING) {
1046                         stl->g_data->session_flag = GP_DRW_PAINT_READY;
1047                 }
1048         }
1049 }
1050
1051 static const DrawEngineDataSize GPENCIL_data_size = DRW_VIEWPORT_DATA_SIZE(GPENCIL_Data);
1052
1053 DrawEngineType draw_engine_gpencil_type = {
1054         NULL, NULL,
1055         N_("GpencilMode"),
1056         &GPENCIL_data_size,
1057         &GPENCIL_engine_init,
1058         &GPENCIL_engine_free,
1059         &GPENCIL_cache_init,
1060         &GPENCIL_cache_populate,
1061         &GPENCIL_cache_finish,
1062         NULL,
1063         &GPENCIL_draw_scene,
1064         NULL,
1065         NULL,
1066         &GPENCIL_render_to_image,
1067 };