diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-08-28 06:07:54 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-08-28 06:07:54 +0400 |
commit | 27df6a3b546bf4188b0f29bcb90df201a6730574 (patch) | |
tree | 2669a91593815f28dd15177ef6620778d5259909 /source | |
parent | 4d2b50ad74f29a4a22eb8a3376552430b2c0666d (diff) |
scanfill curves, ngons, masks had their own memarena code and would allocate a new one for every fill.
now use BLI_memarena and support passing the arena into the fill function, so the arena is re-used, when scanfill is called in a loop.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editmesh.c | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mask_rasterize.c | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 15 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_scanfill.h | 24 | ||||
-rw-r--r-- | source/blender/blenlib/intern/scanfill.c | 138 |
6 files changed, 107 insertions, 104 deletions
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 77ec333c173..6a89ca2cb84 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -43,6 +43,7 @@ #include "DNA_material_types.h" #include "BLI_blenlib.h" +#include "BLI_memarena.h" #include "BLI_math.h" #include "BLI_scanfill.h" #include "BLI_utildefines.h" @@ -450,6 +451,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, const float normal_proj ScanFillContext sf_ctx; ScanFillVert *sf_vert, *sf_vert_new, *sf_vert_last; ScanFillFace *sf_tri; + MemArena *sf_arena; DispList *dlnew = NULL, *dl; float *f1; int colnr = 0, charidx = 0, cont = 1, tot, a, *index, nextcol = 0; @@ -460,12 +462,14 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, const float normal_proj if (dispbase->first == NULL) return; + sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); + while (cont) { cont = 0; totvert = 0; nextcol = 0; - BLI_scanfill_begin(&sf_ctx); + BLI_scanfill_begin_arena(&sf_ctx, sf_arena); dl = dispbase->first; while (dl) { @@ -553,7 +557,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, const float normal_proj BLI_addhead(to, dlnew); } - BLI_scanfill_end(&sf_ctx); + BLI_scanfill_end_arena(&sf_ctx, sf_arena); if (nextcol) { /* stay at current char but fill polys with next material */ @@ -566,6 +570,8 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, const float normal_proj } } + BLI_memarena_free(sf_arena); + /* do not free polys, needed for wireframe display */ } diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index 74cd8834d5d..6a89d16d7bf 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -36,6 +36,7 @@ #include "DNA_mesh_types.h" #include "BLI_math.h" +#include "BLI_memarena.h" #include "BLI_scanfill.h" #include "BKE_editmesh.h" @@ -123,6 +124,7 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em) int i = 0; ScanFillContext sf_ctx; + MemArena *sf_arena = NULL; #if 0 /* note, we could be clever and re-use this array but would need to ensure @@ -217,7 +219,11 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em) ScanFillFace *sf_tri; int totfilltri; - BLI_scanfill_begin(&sf_ctx); + if (UNLIKELY(sf_arena == NULL)) { + sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); + } + + BLI_scanfill_begin_arena(&sf_ctx, sf_arena); /* scanfill time */ j = 0; @@ -262,10 +268,15 @@ static void editmesh_tessface_calc_intern(BMEditMesh *em) l_ptr[2] = l3; } - BLI_scanfill_end(&sf_ctx); + BLI_scanfill_end_arena(&sf_ctx, sf_arena); } } + if (sf_arena) { + BLI_memarena_free(sf_arena); + sf_arena = NULL; + } + em->tottri = i; em->looptris = looptris; diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index ac48eaa3185..e5e49763784 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -575,11 +575,14 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas const float zvec[3] = {0.0f, 0.0f, 1.0f}; MaskLayer *masklay; unsigned int masklay_index; + MemArena *sf_arena; mr_handle->layers_tot = (unsigned int)BLI_countlist(&mask->masklayers); mr_handle->layers = MEM_mallocN(sizeof(MaskRasterLayer) * mr_handle->layers_tot, "MaskRasterLayer"); BLI_rctf_init_minmax(&mr_handle->bounds); + sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); + for (masklay = mask->masklayers.first, masklay_index = 0; masklay; masklay = masklay->next, masklay_index++) { /* we need to store vertex ranges for open splines for filling */ @@ -613,7 +616,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas tot_splines = (unsigned int)BLI_countlist(&masklay->splines); open_spline_ranges = MEM_callocN(sizeof(*open_spline_ranges) * tot_splines, __func__); - BLI_scanfill_begin(&sf_ctx); + BLI_scanfill_begin_arena(&sf_ctx, sf_arena); for (spline = masklay->splines.first; spline; spline = spline->next) { const unsigned int is_cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; @@ -1148,8 +1151,10 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mas } /* add trianges */ - BLI_scanfill_end(&sf_ctx); + BLI_scanfill_end_arena(&sf_ctx, sf_arena); } + + BLI_memarena_free(sf_arena); } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 9465044ba0b..0d3bc1b71e3 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -46,6 +46,7 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" +#include "BLI_memarena.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_bitmap.h" @@ -2733,6 +2734,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, ScanFillContext sf_ctx; ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first; ScanFillFace *sf_tri; + MemArena *sf_arena = NULL; int *mface_to_poly_map; int lindex[4]; /* only ever use 3 in this case */ int poly_index, j, mface_index; @@ -2815,7 +2817,11 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, #endif ml = mloop + mp->loopstart; - BLI_scanfill_begin(&sf_ctx); + if (UNLIKELY(sf_arena == NULL)) { + sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); + } + + BLI_scanfill_begin_arena(&sf_ctx, sf_arena); sf_vert_first = NULL; sf_vert_last = NULL; for (j = 0; j < mp->totloop; j++, ml++) { @@ -2867,12 +2873,17 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mface_index++; } - BLI_scanfill_end(&sf_ctx); + BLI_scanfill_end_arena(&sf_ctx, sf_arena); #undef USE_TESSFACE_CALCNORMAL } } + if (sf_arena) { + BLI_memarena_free(sf_arena); + sf_arena = NULL; + } + CustomData_free(fdata, totface); totface = mface_index; diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h index 21197670640..40658095fd9 100644 --- a/source/blender/blenlib/BLI_scanfill.h +++ b/source/blender/blenlib/BLI_scanfill.h @@ -46,20 +46,13 @@ typedef struct ScanFillContext { ListBase filledgebase; ListBase fillfacebase; - /* simple optimization for allocating thousands of small memory blocks - * only to be used within loops, and not by one function at a time - * free in the end, with argument '-1' - */ -#define MEM_ELEM_BLOCKSIZE 16384 - struct mem_elements *melem__cur; - int melem__offs; /* the current free address */ - ListBase melem__lb; - /* private */ struct ScanFillVertLink *_scdata; + struct MemArena *arena; } ScanFillContext; -/* note; changing this also might affect the undo copy in editmesh.c */ +#define BLI_SCANFILL_ARENA_SIZE 16384 + typedef struct ScanFillVert { struct ScanFillVert *next, *prev; union { @@ -68,9 +61,9 @@ typedef struct ScanFillVert { intptr_t l; unsigned int u; } tmp; - float co[3]; /* vertex location */ - float xy[2]; /* 2D copy of vertex location (using dominant axis) */ - unsigned int keyindex; /* original index #, for restoring key information */ + float co[3]; /* vertex location */ + float xy[2]; /* 2D projection of vertex location */ + unsigned int keyindex; /* index, caller can use how it likes to match the scanfill result with own data */ short poly_nr; unsigned char edge_tot; /* number of edges using this vertex */ unsigned char f; @@ -91,7 +84,7 @@ typedef struct ScanFillFace { struct ScanFillVert *v1, *v2, *v3; } ScanFillFace; -/* scanfill.c: used in displist only... */ +/* scanfill.c */ struct ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3]); struct ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx, struct ScanFillVert *v1, struct ScanFillVert *v2); @@ -113,6 +106,9 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3]); void BLI_scanfill_end(ScanFillContext *sf_ctx); +void BLI_scanfill_begin_arena(ScanFillContext *sf_ctx, struct MemArena *arena); +void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, struct MemArena *arena); + /* These callbacks are needed to make the lib finction properly */ void BLI_setErrorCallBack(void (*f)(const char *)); diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index c7163874dca..ae9f36b957c 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -40,6 +40,7 @@ #include "BLI_callbacks.h" #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_memarena.h" #include "BLI_scanfill.h" #include "BLI_utildefines.h" @@ -132,99 +133,45 @@ static int vergpoly(const void *a1, const void *a2) return 0; } -/* ************* MEMORY MANAGEMENT ************* */ - -/* memory management */ -struct mem_elements { - struct mem_elements *next, *prev; - char *data; -}; +/* **** FILL ROUTINES *************************** */ -static void *mem_element_new(ScanFillContext *sf_ctx, int size) +ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3]) { - BLI_assert(!(size > 10000 || size == 0)); /* this is invalid use! */ - - size = (size + 3) & ~3; /* allocate in units of 4 */ + ScanFillVert *sf_v; - if (sf_ctx->melem__cur && (size + sf_ctx->melem__offs < MEM_ELEM_BLOCKSIZE)) { - void *adr = (void *) (sf_ctx->melem__cur->data + sf_ctx->melem__offs); - sf_ctx->melem__offs += size; - return adr; - } - else { - sf_ctx->melem__cur = MEM_callocN(sizeof(struct mem_elements), "newmem"); - sf_ctx->melem__cur->data = MEM_callocN(MEM_ELEM_BLOCKSIZE, "newmem"); - BLI_addtail(&sf_ctx->melem__lb, sf_ctx->melem__cur); + sf_v = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillVert)); - sf_ctx->melem__offs = size; - return sf_ctx->melem__cur->data; - } -} -static void mem_element_reset(ScanFillContext *sf_ctx, int keep_first) -{ - struct mem_elements *first; - - if ((first = sf_ctx->melem__lb.first)) { /* can be false if first fill fails */ - if (keep_first) { - BLI_remlink(&sf_ctx->melem__lb, first); - } - - sf_ctx->melem__cur = sf_ctx->melem__lb.first; - while (sf_ctx->melem__cur) { - MEM_freeN(sf_ctx->melem__cur->data); - sf_ctx->melem__cur = sf_ctx->melem__cur->next; - } - BLI_freelistN(&sf_ctx->melem__lb); - - /*reset the block we're keeping*/ - if (keep_first) { - BLI_addtail(&sf_ctx->melem__lb, first); - memset(first->data, 0, MEM_ELEM_BLOCKSIZE); - } - else { - first = NULL; + BLI_addtail(&sf_ctx->fillvertbase, sf_v); - } - } + sf_v->tmp.p = NULL; + copy_v3_v3(sf_v->co, vec); - sf_ctx->melem__cur = first; - sf_ctx->melem__offs = 0; -} + /* just zero out the rest */ + zero_v2(sf_v->xy); + sf_v->keyindex = 0; + sf_v->poly_nr = 0; + sf_v->edge_tot = 0; + sf_v->f = 0; -void BLI_scanfill_end(ScanFillContext *sf_ctx) -{ - mem_element_reset(sf_ctx, FALSE); - - sf_ctx->fillvertbase.first = sf_ctx->fillvertbase.last = NULL; - sf_ctx->filledgebase.first = sf_ctx->filledgebase.last = NULL; - sf_ctx->fillfacebase.first = sf_ctx->fillfacebase.last = NULL; -} - -/* **** FILL ROUTINES *************************** */ - -ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3]) -{ - ScanFillVert *eve; - - eve = mem_element_new(sf_ctx, sizeof(ScanFillVert)); - BLI_addtail(&sf_ctx->fillvertbase, eve); - - copy_v3_v3(eve->co, vec); - - return eve; + return sf_v; } ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2) { - ScanFillEdge *newed; + ScanFillEdge *sf_ed; - newed = mem_element_new(sf_ctx, sizeof(ScanFillEdge)); - BLI_addtail(&sf_ctx->filledgebase, newed); + sf_ed = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillEdge)); + BLI_addtail(&sf_ctx->filledgebase, sf_ed); - newed->v1 = v1; - newed->v2 = v2; + sf_ed->v1 = v1; + sf_ed->v2 = v2; + + /* just zero out the rest */ + sf_ed->poly_nr = 0; + sf_ed->f = 0; + sf_ed->tmp.c = 0; - return newed; + return sf_ed; } static void addfillface(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2, ScanFillVert *v3) @@ -232,7 +179,7 @@ static void addfillface(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert /* does not make edges */ ScanFillFace *sf_tri; - sf_tri = mem_element_new(sf_ctx, sizeof(ScanFillFace)); + sf_tri = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillFace)); BLI_addtail(&sf_ctx->fillfacebase, sf_tri); sf_tri->v1 = v1; @@ -826,11 +773,33 @@ static int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag) void BLI_scanfill_begin(ScanFillContext *sf_ctx) { memset(sf_ctx, 0, sizeof(*sf_ctx)); + sf_ctx->arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__); } -int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag) +void BLI_scanfill_begin_arena(ScanFillContext *sf_ctx, MemArena *arena) { - return BLI_scanfill_calc_ex(sf_ctx, flag, NULL); + memset(sf_ctx, 0, sizeof(*sf_ctx)); + sf_ctx->arena = arena; +} + +void BLI_scanfill_end(ScanFillContext *sf_ctx) +{ + BLI_memarena_free(sf_ctx->arena); + sf_ctx->arena = NULL; + + sf_ctx->fillvertbase.first = sf_ctx->fillvertbase.last = NULL; + sf_ctx->filledgebase.first = sf_ctx->filledgebase.last = NULL; + sf_ctx->fillfacebase.first = sf_ctx->fillfacebase.last = NULL; +} + +void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, MemArena *arena) +{ + BLI_memarena_clear(arena); + BLI_assert(sf_ctx->arena == arena); + + sf_ctx->fillvertbase.first = sf_ctx->fillvertbase.last = NULL; + sf_ctx->filledgebase.first = sf_ctx->filledgebase.last = NULL; + sf_ctx->fillfacebase.first = sf_ctx->fillfacebase.last = NULL; } int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3]) @@ -1177,3 +1146,8 @@ int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float no return totfaces; } + +int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag) +{ + return BLI_scanfill_calc_ex(sf_ctx, flag, NULL); +} |