GP: Fix memory leak in draw engine for buffer strokes

This memory leak was undetected during a long time, but with new memory checking is visible.

The problem was the stroke buffer batch was realocating new batches without free the memory.
This commit is contained in:
Antonio Vazquez 2018-08-08 19:48:57 +02:00
parent 5c4fd52612
commit 211ad6bf9a
3 changed files with 35 additions and 9 deletions

View File

@ -932,19 +932,26 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
e_data, vedata, psl->drawing_pass, e_data->gpencil_point_sh, NULL, gpd, gp_style, -1, false);
}
/* clean previous version of the batch */
if (stl->storage->buffer_stroke) {
GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_stroke);
MEM_SAFE_FREE(e_data->batch_buffer_stroke);
stl->storage->buffer_stroke = false;
}
/* use unit matrix because the buffer is in screen space and does not need conversion */
if (gpd->runtime.mode == GP_STYLE_MODE_LINE) {
stl->g_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(
e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(
gpd, stl->storage->unit_matrix, lthick);
}
else {
stl->g_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(
e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(
gpd, stl->storage->unit_matrix, lthick);
}
DRW_shgroup_call_add(
stl->g_data->shgrps_drawing_stroke,
stl->g_data->batch_buffer_stroke,
e_data->batch_buffer_stroke,
stl->storage->unit_matrix);
if ((gpd->runtime.sbuffer_size >= 3) && (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) &&
@ -956,12 +963,22 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
}
stl->g_data->shgrps_drawing_fill = DRW_shgroup_create(
e_data->gpencil_drawing_fill_sh, psl->drawing_pass);
stl->g_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
/* clean previous version of the batch */
if (stl->storage->buffer_fill) {
GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_fill);
MEM_SAFE_FREE(e_data->batch_buffer_fill);
stl->storage->buffer_fill = false;
}
e_data->batch_buffer_fill = DRW_gpencil_get_buffer_fill_geom(gpd);
DRW_shgroup_call_add(
stl->g_data->shgrps_drawing_fill,
stl->g_data->batch_buffer_fill,
e_data->batch_buffer_fill,
stl->storage->unit_matrix);
stl->storage->buffer_fill = true;
}
stl->storage->buffer_stroke = true;
}
}
}

View File

@ -267,6 +267,12 @@ static void GPENCIL_engine_free(void)
DRW_TEXTURE_FREE_SAFE(e_data.gpencil_blank_texture);
GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_stroke);
MEM_SAFE_FREE(e_data.batch_buffer_stroke);
GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill);
MEM_SAFE_FREE(e_data.batch_buffer_fill);
/* effects */
GPENCIL_delete_fx_shaders(&e_data);
}

View File

@ -108,6 +108,8 @@ typedef struct GPENCIL_Storage {
bool is_playing;
bool is_render;
bool is_mat_preview;
bool buffer_stroke;
bool buffer_fill;
const float *pixsize;
float render_pixsize;
int tonemapping;
@ -189,10 +191,6 @@ typedef struct g_data {
struct DRWShadingGroup *shgrps_drawing_fill;
struct DRWShadingGroup *shgrps_grid;
/* for buffer only one batch is nedeed because the drawing is only of one stroke */
GPUBatch *batch_buffer_stroke;
GPUBatch *batch_buffer_fill;
/* grid geometry */
GPUBatch *batch_grid;
@ -256,6 +254,11 @@ typedef struct GPENCIL_e_data {
struct GPUTexture *temp_color_tx_rim;
struct GPUTexture *temp_depth_tx_rim;
/* for buffer only one batch is nedeed because the drawing is only of one stroke */
GPUBatch *batch_buffer_stroke;
GPUBatch *batch_buffer_fill;
} GPENCIL_e_data; /* Engine data */
/* GPUBatch Cache */