diff options
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 8 | ||||
-rw-r--r-- | source/blender/blenloader/intern/undofile.c | 16 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_250.c | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 148 |
4 files changed, 89 insertions, 85 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 82a92d3f654..5d0de6526b6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -113,7 +113,6 @@ #include "BKE_action.h" #include "BKE_armature.h" -#include "BKE_blender_version.h" #include "BKE_brush.h" #include "BKE_cloth.h" #include "BKE_constraint.h" @@ -916,7 +915,7 @@ static int read_file_dna(FileData *fd) if (bhead->code == DNA1) { const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0; - fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap); + fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap, true); if (fd->filesdna) { fd->compflags = DNA_struct_get_compareflags(fd->filesdna, fd->memsdna); /* used to retrieve ID names from (bhead+1) */ @@ -1076,7 +1075,7 @@ static FileData *filedata_new(void) * 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); + fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false); fd->datamap = oldnewmap_new(); fd->globmap = oldnewmap_new(); @@ -7896,9 +7895,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) blo_do_versions_260(fd, lib, main); blo_do_versions_270(fd, lib, main); - main->versionfile = BLENDER_VERSION; - main->subversionfile = BLENDER_SUBVERSION; - /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */ diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c index d0dc9a88cc0..c191e48a143 100644 --- a/source/blender/blenloader/intern/undofile.c +++ b/source/blender/blenloader/intern/undofile.c @@ -80,20 +80,6 @@ void BLO_memfile_merge(MemFile *first, MemFile *second) BLO_memfile_free(first); } -static int my_memcmp(const int *mem1, const int *mem2, const int len) -{ - register int a = len; - register const int *mema = mem1; - register const int *memb = mem2; - - while (a--) { - if (*mema != *memb) return 1; - mema++; - memb++; - } - return 0; -} - void memfile_chunk_add(MemFile *compare, MemFile *current, const char *buf, unsigned int size) { static MemFileChunk *compchunk = NULL; @@ -118,7 +104,7 @@ void memfile_chunk_add(MemFile *compare, MemFile *current, const char *buf, unsi /* we compare compchunk with buf */ if (compchunk) { if (compchunk->size == curchunk->size) { - if (my_memcmp((int *)compchunk->buf, (const int *)buf, size / 4) == 0) { + if (memcmp(compchunk->buf, buf, size) == 0) { curchunk->buf = compchunk->buf; curchunk->ident = 1; } diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 119754fe567..631aec545c2 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -1087,6 +1087,8 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) sce->gm.flag |= GAME_GLSL_NO_NODES; if (fd->fileflags & G_FILE_GLSL_NO_EXTRA_TEX) sce->gm.flag |= GAME_GLSL_NO_EXTRA_TEX; + if (fd->fileflags & G_FILE_GLSL_NO_ENV_LIGHTING) + sce->gm.flag |= GAME_GLSL_NO_ENV_LIGHTING; if (fd->fileflags & G_FILE_IGNORE_DEPRECATION_WARNINGS) sce->gm.flag |= GAME_IGNORE_DEPRECATION_WARNINGS; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 87fe6db96d0..9c7aa87f3cc 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -189,9 +189,9 @@ /* ********* my write, buffered writing with minimum size chunks ************ */ -#define MYWRITE_BUFFER_SIZE 100000 -#define MYWRITE_MAX_CHUNK 32768 - +/* Use optimal allocation since blocks of this size are kept in memory for undo. */ +#define MYWRITE_BUFFER_SIZE (MEM_SIZE_OPTIMAL(1 << 17)) /* 128kb */ +#define MYWRITE_MAX_CHUNK (MEM_SIZE_OPTIMAL(1 << 15)) /* ~32kb */ /** \name Small API to handle compression. @@ -323,7 +323,7 @@ static WriteData *writedata_new(WriteWrap *ww) { WriteData *wd = MEM_callocN(sizeof(*wd), "writedata"); - wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false); + wd->sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false); wd->ww = ww; @@ -364,26 +364,31 @@ static void writedata_free(WriteData *wd) /***/ /** + * Flush helps the de-duplicating memory for undo-save by logically segmenting data, + * so differences in one part of memory won't cause unrelated data to be duplicated. + */ +static void mywrite_flush(WriteData *wd) +{ + if (wd->count) { + writedata_do_write(wd, wd->buf, wd->count); + wd->count = 0; + } +} + +/** * Low level WRITE(2) wrapper that buffers data * \param adr Pointer to new chunk of data * \param len Length of new chunk of data * \warning Talks to other functions with global parameters */ - -#define MYWRITE_FLUSH NULL - static void mywrite(WriteData *wd, const void *adr, int len) { if (UNLIKELY(wd->error)) { return; } - /* flush helps compression for undo-save */ - if (adr == MYWRITE_FLUSH) { - if (wd->count) { - writedata_do_write(wd, wd->buf, wd->count); - wd->count = 0; - } + if (adr == NULL) { + BLI_assert(0); return; } @@ -814,8 +819,7 @@ static void write_actions(WriteData *wd, ListBase *idbase) } } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_keyingsets(WriteData *wd, ListBase *list) @@ -1666,8 +1670,7 @@ static void write_objects(WriteData *wd, ListBase *idbase) ob = ob->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } @@ -1694,6 +1697,8 @@ static void write_vfonts(WriteData *wd, ListBase *idbase) vf = vf->id.next; } + + mywrite_flush(wd); } @@ -1726,8 +1731,8 @@ static void write_keys(WriteData *wd, ListBase *idbase) key = key->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + + mywrite_flush(wd); } static void write_cameras(WriteData *wd, ListBase *idbase) @@ -1829,8 +1834,7 @@ static void write_curves(WriteData *wd, ListBase *idbase) cu = cu->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_dverts(WriteData *wd, int count, MDeformVert *dvlist) @@ -2104,6 +2108,8 @@ static void write_meshes(WriteData *wd, ListBase *idbase) mesh = mesh->id.next; } + + mywrite_flush(wd); } static void write_lattices(WriteData *wd, ListBase *idbase) @@ -2130,6 +2136,8 @@ static void write_lattices(WriteData *wd, ListBase *idbase) } lt = lt->id.next; } + + mywrite_flush(wd); } static void write_images(WriteData *wd, ListBase *idbase) @@ -2173,8 +2181,8 @@ static void write_images(WriteData *wd, ListBase *idbase) } ima = ima->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + + mywrite_flush(wd); } static void write_textures(WriteData *wd, ListBase *idbase) @@ -2226,8 +2234,7 @@ static void write_textures(WriteData *wd, ListBase *idbase) tex = tex->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_materials(WriteData *wd, ListBase *idbase) @@ -2343,6 +2350,8 @@ static void write_lamps(WriteData *wd, ListBase *idbase) } la = la->id.next; } + + mywrite_flush(wd); } static void write_sequence_modifiers(WriteData *wd, ListBase *modbase) @@ -2589,8 +2598,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase) sce = sce->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + + mywrite_flush(wd); } static void write_gpencils(WriteData *wd, ListBase *lb) @@ -2627,6 +2636,8 @@ static void write_gpencils(WriteData *wd, ListBase *lb) } } } + + mywrite_flush(wd); } static void write_windowmanagers(WriteData *wd, ListBase *lb) @@ -2643,6 +2654,10 @@ static void write_windowmanagers(WriteData *wd, ListBase *lb) writestruct(wd, DATA, Stereo3dFormat, 1, win->stereo3d_format); } } + + /* typically flushing wouldn't be needed however this data _always_ changes, + * so flush here for more efficient undo. */ + mywrite_flush(wd); } static void write_region(WriteData *wd, ARegion *ar, int spacetype) @@ -2682,43 +2697,43 @@ static void write_uilist(WriteData *wd, uiList *ui_list) } } -static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list) +static void write_soops(WriteData *wd, SpaceOops *so) { BLI_mempool *ts = so->treestore; if (ts) { + SpaceOops so_flat = *so; + int elems = BLI_mempool_count(ts); /* linearize mempool to array */ TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL; if (data) { - TreeStore *ts_flat = MEM_callocN(sizeof(TreeStore), "TreeStore"); + /* In this block we use the memory location of the treestore + * but _not_ its data, the addresses in this case are UUID's, + * since we can't rely on malloc giving us different values each time. + */ + TreeStore ts_flat = {0}; - ts_flat->usedelem = elems; - ts_flat->totelem = elems; - ts_flat->data = data; + /* we know the treestore is at least as big as a pointer, + * so offsetting works to give us a UUID. */ + void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *)); + + ts_flat.usedelem = elems; + ts_flat.totelem = elems; + ts_flat.data = data_addr; - /* temporarily replace mempool-treestore by flat-treestore */ - so->treestore = (BLI_mempool *)ts_flat; writestruct(wd, DATA, SpaceOops, 1, so); - writestruct(wd, DATA, TreeStore, 1, ts_flat); - writestruct(wd, DATA, TreeStoreElem, elems, data); + writestruct_at_address(wd, DATA, TreeStore, 1, ts, &ts_flat); + writestruct_at_address(wd, DATA, TreeStoreElem, elems, data_addr, data); - /* we do not free the pointers immediately, because if we have multiple - * outliners in a screen we might get the same address on the next - * malloc, which makes the address no longer unique and so invalid for - * lookups on file read, causing crashes or double frees */ - BLI_linklist_prepend(tmp_mem_list, ts_flat); - BLI_linklist_prepend(tmp_mem_list, data); + MEM_freeN(data); } else { - so->treestore = NULL; - writestruct(wd, DATA, SpaceOops, 1, so); + so_flat.treestore = NULL; + writestruct_at_address(wd, DATA, SpaceOops, 1, so, &so_flat); } - - /* restore old treestore */ - so->treestore = ts; } else { writestruct(wd, DATA, SpaceOops, 1, so); @@ -2731,7 +2746,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase) ScrArea *sa; ScrVert *sv; ScrEdge *se; - LinkNode *tmp_mem_list = NULL; sc = scrbase->first; while (sc) { @@ -2835,7 +2849,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *so = (SpaceOops *)sl; - write_soops(wd, so, &tmp_mem_list); + write_soops(wd, so); } else if (sl->spacetype == SPACE_IMAGE) { writestruct(wd, DATA, SpaceImage, 1, sl); @@ -2903,10 +2917,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase) sc = sc->id.next; } - BLI_linklist_freeN(tmp_mem_list); - - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_bone(WriteData *wd, Bone *bone) @@ -2954,8 +2965,7 @@ static void write_armatures(WriteData *wd, ListBase *idbase) arm = arm->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_texts(WriteData *wd, ListBase *idbase) @@ -2996,8 +3006,7 @@ static void write_texts(WriteData *wd, ListBase *idbase) text = text->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_speakers(WriteData *wd, ListBase *idbase) @@ -3041,8 +3050,7 @@ static void write_sounds(WriteData *wd, ListBase *idbase) sound = sound->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_groups(WriteData *wd, ListBase *idbase) @@ -3065,6 +3073,8 @@ static void write_groups(WriteData *wd, ListBase *idbase) } } } + + mywrite_flush(wd); } static void write_nodetrees(WriteData *wd, ListBase *idbase) @@ -3277,8 +3287,7 @@ static void write_movieclips(WriteData *wd, ListBase *idbase) clip = clip->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_masks(WriteData *wd, ListBase *idbase) @@ -3338,8 +3347,7 @@ static void write_masks(WriteData *wd, ListBase *idbase) mask = mask->id.next; } - /* flush helps the compression for undo-save */ - mywrite(wd, MYWRITE_FLUSH, 0); + mywrite_flush(wd); } static void write_linestyle_color_modifiers(WriteData *wd, ListBase *modifiers) @@ -3688,6 +3696,8 @@ static void write_libraries(WriteData *wd, Main *main) } } } + + mywrite_flush(wd); } /* context is usually defined by WM, two cases where no WM is available: @@ -3787,6 +3797,10 @@ static bool write_file_handle( write_thumb(wd, thumb); write_global(wd, write_flags, mainvar); + /* The windowmanager and screen often change, + * avoid thumbnail detecting changes because of this. */ + mywrite_flush(wd); + write_windowmanagers(wd, &mainvar->wm); write_screens(wd, &mainvar->screen); write_movieclips(wd, &mainvar->movieclip); @@ -3819,11 +3833,17 @@ static bool write_file_handle( write_linestyles(wd, &mainvar->linestyle); write_libraries(wd, mainvar->next); + /* So changes above don't cause a 'DNA1' to be detected as changed on undo. */ + mywrite_flush(wd); + if (write_flags & G_FILE_USERPREFS) { write_userdef(wd); } - /* dna as last, because (to be implemented) test for which structs are written */ + /* Write DNA last, because (to be implemented) test for which structs are written. + * + * Note that we *borrow* the pointer to 'DNAstr', + * so writing each time uses the same address and doesn't cause unnecessary undo overhead. */ writedata(wd, DNA1, wd->sdna->datalen, wd->sdna->data); #ifdef USE_NODE_COMPAT_CUSTOMNODES |