diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-06-02 16:57:58 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-06-02 17:14:21 +0300 |
commit | 68d1348ca2f4ae7fcd6eff5b7bdbd84d75988ae8 (patch) | |
tree | e8ee1c93ebc2fa36ed72330ac8f3ae9e4eddfde5 /source/blender/gpu/GPU_buffers.h | |
parent | ac8246cd893c417d89dfde9704cc0ae2edbbc936 (diff) |
Fix T47637: Multiple multires objects in Sculpt mode make blender crash.
That was a nice and funny hunt, albeit rather time consumming!
To summarize, so far code was using a static global gpu_buffer for pbvh vbo drawing
of 'grid' types (multires mostly?).
There were two issues here:
1) Global gpu buffer was assigned to GPU_PBVH_Buffers->index_buf, but then nearly no
check was done when freeing that buffer, to ensure we were not freeing the global one
(not totally sure this one was actually causing any issue, but was bad and unsafe anyway).
Was solved by adding a flag to GPU_PBVH_Buffers to indicate when we are using some
'common' buffer here, which freeing is handled separately.
2) Main issue: if several multires objects in sculpt mode with different grid size
were present simultaneously, the global gpu buffer had to be resized for each object draw
(i.e., freed and re-allocated), but then the pbvh nodes from other objects storing freed reference
to that global buffer had no way to know that it had been freed, which was causing the segfault & crash.
Was solved by getting rid of that global buffer, and instead allocating one 'grid_commmon_gpu_buffer' per pbvh.
Told ya baby, globals are *PURE EVIL*!
Diffstat (limited to 'source/blender/gpu/GPU_buffers.h')
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index ee7abe08aba..aefaf1a0f54 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -49,6 +49,7 @@ struct DerivedMesh; struct GSet; struct GPUVertPointLink; struct GPUDrawObject; +struct GridCommonGPUBuffer; struct PBVH; struct MVert; @@ -160,9 +161,6 @@ void GPU_buffer_free(GPUBuffer *buffer); void GPU_drawobject_free(struct DerivedMesh *dm); -/* free special global multires grid buffer */ -void GPU_buffer_multires_free(bool force); - /* flag that controls data type to fill buffer with, a modifier will prepare. */ typedef enum { GPU_BUFFER_VERTEX = 0, @@ -231,8 +229,9 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers( const int *face_indices, const int face_indices_len); -GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid, - unsigned int **grid_hidden, int gridsize, const struct CCGKey *key); +GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers( + int *grid_indices, int totgrid,unsigned int **grid_hidden, int gridsize, const struct CCGKey *key, + struct GridCommonGPUBuffer **grid_common_gpu_buffer); GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading); @@ -267,5 +266,6 @@ void GPU_init_draw_pbvh_BB(void); bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, struct GSet *bm_faces, bool show_diffuse_color); void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers); +void GPU_free_pbvh_buffer_multires(struct GridCommonGPUBuffer **grid_common_gpu_buffer); #endif |