DRW: Fix crash caused by fixing the leak (badly).
authorClément Foucault <foucault.clem@gmail.com>
Wed, 7 Feb 2018 23:40:50 +0000 (00:40 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Wed, 7 Feb 2018 23:41:27 +0000 (00:41 +0100)
Previous commit was af425f3f7a08c09f7fbc7076b364fac75163b296

source/blender/draw/intern/draw_instance_data.c
source/blender/draw/intern/draw_instance_data.h
source/blender/draw/intern/draw_manager.c

index e7ce4374d1cf5de5b078da6efb134d0a4301f8f0..7f3bd246818c67e7cdf2bfdbde9c3c1556fb8859 100644 (file)
@@ -38,8 +38,6 @@
 #include "MEM_guardedalloc.h"
 #include "BLI_utildefines.h"
 
-#define MAX_INSTANCE_DATA_SIZE 32 /* Can be adjusted for more */
-
 struct DRWInstanceData {
        struct DRWInstanceData *next;
        bool used;                 /* If this data is used or not. */
index 637c0e3cc245d194bb98714f02a42d5351a3590a..c83761893963e8ba71fced366a3ff0243d3824be 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef __DRAW_INSTANCE_DATA_H__
 #define __DRAW_INSTANCE_DATA_H__
 
+#define MAX_INSTANCE_DATA_SIZE 42 /* Can be adjusted for more */
+
 typedef struct DRWInstanceData DRWInstanceData;
 typedef struct DRWInstanceDataList DRWInstanceDataList;
 
index 6ab6f20013e1bde26e13dafb41619d2acf374e37..96454fd087e053b2e3e0424c7f1440446cd3da90 100644 (file)
@@ -315,6 +315,7 @@ static struct DRWGlobalState {
        DRWCallGenerate *last_callgenerate;
        DRWShadingGroup *last_shgroup;
        DRWInstanceDataList *idatalist;
+       DRWInstanceData *common_instance_data[MAX_INSTANCE_DATA_SIZE];
 
        /* Rendering state */
        GPUShader *shader;
@@ -2676,6 +2677,7 @@ static void drw_viewport_var_init(void)
        }
 
        memset(viewport_matrix_override.override, 0x0, sizeof(viewport_matrix_override.override));
+       memset(DST.common_instance_data, 0x0, sizeof(DST.common_instance_data));
 }
 
 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
@@ -2824,10 +2826,15 @@ ObjectEngineData *DRW_object_engine_data_ensure(
        /* Allocate new data. */
        if ((ob->base_flag & BASE_FROMDUPLI) != 0) {
                /* NOTE: data is not persistent in this case. It is reset each redraw. */
+               BLI_assert(free_cb == NULL); /* No callback allowed. */
                /* Round to sizeof(float) for DRW_instance_data_request(). */
                const size_t t = sizeof(float) - 1;
                size = (size + t) & ~t;
-               oed = (ObjectEngineData *)DRW_instance_data_request(DST.idatalist, size / sizeof(float), 16);
+               size_t fsize = size / sizeof(float);
+               if (DST.common_instance_data[fsize] == NULL) {
+                       DST.common_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize, 16);
+               }
+               oed = (ObjectEngineData *)DRW_instance_data_next(DST.common_instance_data[fsize]);
                memset(oed, 0, size);
        }
        else {