From ffd80047ee4dd2d1136a0e1c5bf2b79fc4b6a410 Mon Sep 17 00:00:00 2001 From: Falk David Date: Thu, 7 Nov 2024 11:54:33 +0100 Subject: [PATCH] Fix #124725: GPv3: Masked layers not rendered correctly with onion skinning The issue was that the masks for the current frame would be rendered for a different frame. Unfortunately, we can't easily render masks for the onion skinned frames correctly at the moment. The fix makes it so that we render the mask only for the current frame. Pull Request: https://projects.blender.org/blender/blender/pulls/129878 --- .../engines/gpencil/gpencil_cache_utils.cc | 19 +++++++++++-------- .../draw/engines/gpencil/gpencil_engine.h | 6 +++++- .../draw/engines/gpencil/gpencil_engine_c.cc | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc b/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc index 375d0112c8e..9ff3576d735 100644 --- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc +++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.cc @@ -515,15 +515,17 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd, return tgp_layer; } -GPENCIL_tLayer *gpencil_layer_cache_get(GPENCIL_tObject *tgp_ob, int number) +GPENCIL_tLayer *grease_pencil_layer_cache_get(GPENCIL_tObject *tgp_ob, + int layer_id, + const bool skip_onion) { - if (number >= 0) { - GPENCIL_tLayer *layer = tgp_ob->layers.first; - while (layer != nullptr) { - if (layer->layer_id == number) { - return layer; - } - layer = layer->next; + BLI_assert(layer_id >= 0); + for (GPENCIL_tLayer *layer = tgp_ob->layers.first; layer != nullptr; layer = layer->next) { + if (skip_onion && layer->is_onion) { + continue; + } + if (layer->layer_id == layer_id) { + return layer; } } return nullptr; @@ -576,6 +578,7 @@ GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd, GPENCIL_tLayer *tgp_layer = static_cast(BLI_memblock_alloc(pd->gp_layer_pool)); BLI_LINKS_APPEND(&tgp_ob->layers, tgp_layer); tgp_layer->layer_id = *grease_pencil.get_layer_index(layer); + tgp_layer->is_onion = onion_id != 0; tgp_layer->mask_bits = nullptr; tgp_layer->mask_invert_bits = nullptr; tgp_layer->blend_ps = nullptr; diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 1ed634d6681..7d155e479e3 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -109,6 +109,8 @@ typedef struct GPENCIL_tLayer { BLI_bitmap *mask_invert_bits; /** Index in the layer list. Used as id for masking. */ int layer_id; + /** True if this pass is part of the onion skinning. */ + bool is_onion; } GPENCIL_tLayer; typedef struct GPENCIL_tObject { @@ -333,7 +335,9 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd, const bGPDlayer *gpl, const bGPDframe *gpf, GPENCIL_tObject *tgp_ob); -GPENCIL_tLayer *gpencil_layer_cache_get(GPENCIL_tObject *tgp_ob, int number); +GPENCIL_tLayer *grease_pencil_layer_cache_get(GPENCIL_tObject *tgp_ob, + int layer_id, + bool skip_onion); GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd, const Object *ob, diff --git a/source/blender/draw/engines/gpencil/gpencil_engine_c.cc b/source/blender/draw/engines/gpencil/gpencil_engine_c.cc index ad32d3f242b..37b96c5c6df 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine_c.cc +++ b/source/blender/draw/engines/gpencil/gpencil_engine_c.cc @@ -775,7 +775,7 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL GPU_framebuffer_clear_color_depth(fbl->mask_fb, clear_col, clear_depth); } - GPENCIL_tLayer *mask_layer = gpencil_layer_cache_get(ob, i); + GPENCIL_tLayer *mask_layer = grease_pencil_layer_cache_get(ob, i, true); /* When filtering by view-layer, the mask could be null and must be ignored. */ if (mask_layer == nullptr) { continue;