GPencil: Fix regression with stroke buffer introduced in rB0ee9282b5c51

This commit is contained in:
Clément Foucault
2022-10-24 15:28:49 +02:00
parent a8731718a1
commit b400717326
3 changed files with 34 additions and 38 deletions

View File

@@ -342,7 +342,6 @@ typedef struct gpIterPopulateData {
int stroke_index_offset;
/* Infos for call batching. */
struct GPUBatch *geom;
bool instancing;
int vfirst, vcount;
} gpIterPopulateData;
@@ -352,12 +351,7 @@ static void gpencil_drawcall_flush(gpIterPopulateData *iter)
{
#if !DISABLE_BATCHING
if (iter->geom != NULL) {
if (iter->instancing) {
DRW_shgroup_call_instance_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
}
else {
DRW_shgroup_call_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
}
DRW_shgroup_call_range(iter->grp, iter->ob, iter->geom, iter->vfirst, iter->vcount);
}
#endif
@@ -367,16 +361,13 @@ static void gpencil_drawcall_flush(gpIterPopulateData *iter)
}
/* Group draw-calls that are consecutive and with the same type. Reduces GPU driver overhead. */
static void gpencil_drawcall_add(
gpIterPopulateData *iter, struct GPUBatch *geom, bool instancing, int v_first, int v_count)
static void gpencil_drawcall_add(gpIterPopulateData *iter,
struct GPUBatch *geom,
int v_first,
int v_count)
{
#if DISABLE_BATCHING
if (instancing) {
DRW_shgroup_call_instance_range(iter->grp, iter->ob, geom, v_first, v_count);
}
else {
DRW_shgroup_call_range(iter->grp, iter->ob, geom, v_first, v_count);
}
DRW_shgroup_call_range(iter->grp, iter->ob, geom, v_first, v_count);
return;
#endif
@@ -386,7 +377,6 @@ static void gpencil_drawcall_add(
gpencil_drawcall_flush(iter);
}
iter->geom = geom;
iter->instancing = instancing;
if (iter->vfirst == -1) {
iter->vfirst = v_first;
}
@@ -517,16 +507,17 @@ static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
bool do_sbuffer = (iter->do_sbuffer_call == DRAW_NOW);
GPUBatch *geom = do_sbuffer ? DRW_cache_gpencil_sbuffer_get(iter->ob) :
GPUBatch *geom = do_sbuffer ? DRW_cache_gpencil_sbuffer_get(iter->ob, show_fill) :
DRW_cache_gpencil_get(iter->ob, iter->pd->cfra);
if (geom != iter->geom) {
gpencil_drawcall_flush(iter);
GPUVertBuf *position_tx = do_sbuffer ?
DRW_cache_gpencil_sbuffer_position_buffer_get(iter->ob) :
DRW_cache_gpencil_sbuffer_position_buffer_get(iter->ob,
show_fill) :
DRW_cache_gpencil_position_buffer_get(iter->ob, iter->pd->cfra);
GPUVertBuf *color_tx = do_sbuffer ?
DRW_cache_gpencil_sbuffer_color_buffer_get(iter->ob) :
DRW_cache_gpencil_sbuffer_color_buffer_get(iter->ob, show_fill) :
DRW_cache_gpencil_color_buffer_get(iter->ob, iter->pd->cfra);
DRW_shgroup_buffer_texture(iter->grp, "gp_pos_tx", position_tx);
DRW_shgroup_buffer_texture(iter->grp, "gp_col_tx", color_tx);
@@ -535,14 +526,17 @@ static void gpencil_stroke_cache_populate(bGPDlayer *gpl,
if (show_fill) {
int vfirst = gps->runtime.fill_start * 3;
int vcount = gps->tot_triangles * 3;
gpencil_drawcall_add(iter, geom, false, vfirst, vcount);
if (do_sbuffer) {
printf("draw_fill vfirst %d vcount %d\n", vfirst, vcount);
}
gpencil_drawcall_add(iter, geom, vfirst, vcount);
}
if (show_stroke) {
int vfirst = gps->runtime.stroke_start * 3;
bool is_cyclic = ((gps->flag & GP_STROKE_CYCLIC) != 0) && (gps->totpoints > 2);
int vcount = (gps->totpoints + (int)is_cyclic) * 2 * 3;
gpencil_drawcall_add(iter, geom, false, vfirst, vcount);
gpencil_drawcall_add(iter, geom, vfirst, vcount);
}
iter->stroke_index_last = gps->runtime.stroke_start + gps->totpoints + 1;

View File

@@ -265,9 +265,10 @@ struct GPUBatch *DRW_cache_gpencil_edit_lines_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_edit_points_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_edit_curve_handles_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_edit_curve_points_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_gpencil_sbuffer_get(struct Object *ob);
struct GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(struct Object *ob);
struct GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(struct Object *ob);
struct GPUBatch *DRW_cache_gpencil_sbuffer_get(struct Object *ob, bool show_fill);
struct GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(struct Object *ob,
bool show_fill);
struct GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(struct Object *ob, bool show_fill);
int DRW_gpencil_material_count_get(struct bGPdata *gpd);
struct GPUBatch *DRW_cache_gpencil_face_wireframe_get(struct Object *ob);

View File

@@ -574,7 +574,9 @@ bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(Object *ob)
gps->tot_triangles = max_ii(0, gpd->runtime.sbuffer_used - 2);
gps->caps[0] = gps->caps[1] = GP_STROKE_CAP_ROUND;
gps->runtime.stroke_start = 1; /* Add one for the adjacency index. */
gps->runtime.vertex_start = 0;
gps->runtime.fill_start = 0;
gps->runtime.stroke_start = 0;
copy_v4_v4(gps->vert_color_fill, gpd->runtime.vert_color_fill);
/* Caps. */
gps->caps[0] = gps->caps[1] = (short)brush->gpencil_settings->caps_type;
@@ -584,7 +586,7 @@ bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(Object *ob)
return gpd->runtime.sbuffer_gps;
}
static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_fill)
static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_fill)
{
tGPspoint *tpoints = (tGPspoint *)gpd->runtime.sbuffer;
bGPDstroke *gps = gpd->runtime.sbuffer_gps;
@@ -593,7 +595,7 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
/* DRW_cache_gpencil_sbuffer_stroke_data_get need to have been called previously. */
BLI_assert(gps != NULL);
if (do_stroke && (gpd->runtime.sbuffer_batch == NULL)) {
if (gpd->runtime.sbuffer_batch == NULL) {
gps->points = (bGPDspoint *)MEM_mallocN(vert_len * sizeof(*gps->points), __func__);
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -643,19 +645,18 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
/* Compute directly inside the IBO data buffer. */
/* OPTI: This is a bottleneck if the stroke is very long. */
BLI_polyfill_calc(tpoints2d, (uint)vert_len, 0, (uint(*)[3])ibo_builder.data);
/* Add stroke start offset. */
/* Add stroke start offset and shift. */
for (int i = 0; i < gps->tot_triangles * 3; i++) {
ibo_builder.data[i] += gps->runtime.stroke_start;
ibo_builder.data[i] = (ibo_builder.data[i] + 1) << GP_VERTEX_ID_SHIFT;
}
/* HACK since we didn't use the builder API to avoid another malloc and copy,
* we need to set the number of indices manually. */
ibo_builder.index_len = gps->tot_triangles * 3;
gps->runtime.stroke_start = gps->tot_triangles;
MEM_freeN(tpoints2d);
}
gps->runtime.stroke_start = do_fill ? gps->tot_triangles : 0;
gps->runtime.fill_start = 0;
gps->runtime.vertex_start = 0;
/* Fill buffers with data. */
gpencil_buffer_add_stroke(&ibo_builder, verts, cols, gps);
@@ -673,29 +674,29 @@ static void gpencil_sbuffer_stroke_ensure(bGPdata *gpd, bool do_stroke, bool do_
}
}
GPUBatch *DRW_cache_gpencil_sbuffer_get(Object *ob)
GPUBatch *DRW_cache_gpencil_sbuffer_get(Object *ob, bool show_fill)
{
bGPdata *gpd = (bGPdata *)ob->data;
/* Fill batch also need stroke batch to be created (vbo is shared). */
gpencil_sbuffer_stroke_ensure(gpd, true, true);
gpencil_sbuffer_stroke_ensure(gpd, show_fill);
return gpd->runtime.sbuffer_batch;
}
GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(Object *ob)
GPUVertBuf *DRW_cache_gpencil_sbuffer_position_buffer_get(Object *ob, bool show_fill)
{
bGPdata *gpd = (bGPdata *)ob->data;
/* Fill batch also need stroke batch to be created (vbo is shared). */
gpencil_sbuffer_stroke_ensure(gpd, true, true);
gpencil_sbuffer_stroke_ensure(gpd, show_fill);
return gpd->runtime.sbuffer_position_buf;
}
GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(Object *ob)
GPUVertBuf *DRW_cache_gpencil_sbuffer_color_buffer_get(Object *ob, bool show_fill)
{
bGPdata *gpd = (bGPdata *)ob->data;
/* Fill batch also need stroke batch to be created (vbo is shared). */
gpencil_sbuffer_stroke_ensure(gpd, true, true);
gpencil_sbuffer_stroke_ensure(gpd, show_fill);
return gpd->runtime.sbuffer_color_buf;
}