writefile: reuse SDNA between writes
authorCampbell Barton <ideasman42@gmail.com>
Tue, 12 Jul 2016 02:53:49 +0000 (12:53 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 12 Jul 2016 03:03:04 +0000 (13:03 +1000)
Avoids decoding the SDNA string every undo step.

source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_genfile.h
source/blender/makesdna/intern/dna_genfile.c
source/blender/windowmanager/intern/wm_init_exit.c
source/creator/creator.c

index eeb8a5d8dbd3b33f1fca12cfc4347276a794265f..059dce2459e172d9b13dcf02225b942c9a65933a 100644 (file)
@@ -1080,13 +1080,9 @@ static FileData *filedata_new(void)
        
        fd->filedes = -1;
        fd->gzfiledes = NULL;
-       
-       /* XXX, this doesn't need to be done all the time,
-        * but it keeps us re-entrant,  remove once we have
-        * a lib that provides a nice lock. - zr
-        */
-       fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
-       
+
+       fd->memsdna = DNA_sdna_current_get();
+
        fd->datamap = oldnewmap_new();
        fd->globmap = oldnewmap_new();
        fd->libmap = oldnewmap_new();
@@ -1280,9 +1276,7 @@ void blo_freefiledata(FileData *fd)
                
                // Free all BHeadN data blocks
                BLI_freelistN(&fd->listbase);
-               
-               if (fd->memsdna)
-                       DNA_sdna_free(fd->memsdna);
+
                if (fd->filesdna)
                        DNA_sdna_free(fd->filesdna);
                if (fd->compflags)
index 42728fd406fd45b9494c66d52a80a50eb04b9fe2..b054cd0031d4180ae03824a0986927591294b585 100644 (file)
@@ -74,7 +74,7 @@ typedef struct FileData {
        
        // general reading variables
        struct SDNA *filesdna;
-       struct SDNA *memsdna;
+       const struct SDNA *memsdna;
        char *compflags;        /* array of eSDNA_StructCompare */
        
        int fileversion;
index f898eea566dd477ab997015cc89cb264517fc061..88f1c4d5e4aaf1edc8d679cc4401e2508ef1bc4b 100644 (file)
@@ -303,7 +303,7 @@ static void ww_handle_init(eWriteWrapType ww_type, WriteWrap *r_ww)
 
 
 typedef struct {
-       struct SDNA *sdna;
+       const struct SDNA *sdna;
 
        unsigned char *buf;
        MemFile *compare, *current;
@@ -325,7 +325,7 @@ static WriteData *writedata_new(WriteWrap *ww)
 {
        WriteData *wd = MEM_callocN(sizeof(*wd), "writedata");
 
-       wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
+       wd->sdna = DNA_sdna_current_get();
 
        wd->ww = ww;
 
@@ -357,8 +357,6 @@ static void writedata_do_write(WriteData *wd, const void *mem, int memlen)
 
 static void writedata_free(WriteData *wd)
 {
-       DNA_sdna_free(wd->sdna);
-
        MEM_freeN(wd->buf);
        MEM_freeN(wd);
 }
index 27a3ff8f8cbe0fca04c1b275862865534fb6e0d8..bc127ac2c82a77da1b52acb9e6118c1ab410a687 100644 (file)
@@ -80,6 +80,12 @@ struct SDNA *DNA_sdna_from_data(
         const char **r_error_message);
 void DNA_sdna_free(struct SDNA *sdna);
 
+/* Access for current Blender versions SDNA*/
+void               DNA_sdna_current_init(void);
+/* borrowed reference */
+const struct SDNA *DNA_sdna_current_get(void);
+void               DNA_sdna_current_free(void);
+
 int DNA_struct_find_nr_ex(const struct SDNA *sdna, const char *str, unsigned int *index_last);
 int DNA_struct_find_nr(const struct SDNA *sdna, const char *str);
 void DNA_struct_switch_endian(const struct SDNA *oldsdna, int oldSDNAnr, char *data);
index f1d48c07de1a1b7cdfd2ab5180c3d61eb2622710..1e3c91d5ddc298c33f47919a249b8541c2f346c5 100644 (file)
@@ -605,6 +605,30 @@ SDNA *DNA_sdna_from_data(
        }
 }
 
+/**
+ * Using globals is acceptable here, the data is read-only and only changes between Blender versions.
+ *
+ * So it is safe to create once and reuse.
+ */
+static SDNA *g_sdna = NULL;
+
+void DNA_sdna_current_init(void)
+{
+       g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, NULL);
+}
+
+const struct SDNA *DNA_sdna_current_get(void)
+{
+       BLI_assert(g_sdna != NULL);
+       return g_sdna;
+}
+
+void DNA_sdna_current_free(void)
+{
+       DNA_sdna_free(g_sdna);
+       g_sdna = NULL;
+}
+
 /* ******************** END READ DNA ********************** */
 
 /* ******************* HANDLE DNA ***************** */
index 9d1083bbf639da520b2d52494f1bb509505d4ce3..3022d8654609670a2fafbc55cf27e00f9989858b 100644 (file)
@@ -40,6 +40,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_genfile.h"
 #include "DNA_scene_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_windowmanager_types.h"
@@ -584,6 +585,8 @@ void WM_exit_ext(bContext *C, const bool do_python)
        
        GHOST_DisposeSystemPaths();
 
+       DNA_sdna_current_free();
+
        BLI_threadapi_exit();
 
        BKE_blender_atexit();
index e2761c9ef38115e38348eca4e6a07e9ab6a6a375..289e68f6276ab26552c9f72ed07ea14f7c1b6f10 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_genfile.h"
+
 #include "BLI_args.h"
 #include "BLI_threads.h"
 #include "BLI_utildefines.h"
@@ -350,6 +352,8 @@ int main(
 
        BLI_threadapi_init();
 
+       DNA_sdna_current_init();
+
        BKE_blender_globals_init();  /* blender.c */
 
        IMB_init();