[Bf-blender-cvs] [2cba992] particles_refactor: Basic functions for creating/destroying buffers, adding/removing layers and adding elements.
Lukas Tönne
noreply at git.blender.org
Tue Apr 22 12:05:17 CEST 2014
Commit: 2cba992e9fc4d8a96abd340fc8a54d6a9f4457cf
Author: Lukas Tönne
Date: Tue Jun 4 10:20:14 2013 +0200
https://developer.blender.org/rB2cba992e9fc4d8a96abd340fc8a54d6a9f4457cf
Basic functions for creating/destroying buffers, adding/removing layers and adding elements.
===================================================================
M source/blender/blenlib/BLI_pagedbuffer.h
M source/blender/blenlib/intern/pagedbuffer.c
M source/blender/makesdna/DNA_pagedbuffer_types.h
===================================================================
diff --git a/source/blender/blenlib/BLI_pagedbuffer.h b/source/blender/blenlib/BLI_pagedbuffer.h
index 621e018..e0dbe54 100644
--- a/source/blender/blenlib/BLI_pagedbuffer.h
+++ b/source/blender/blenlib/BLI_pagedbuffer.h
@@ -34,7 +34,18 @@
#include "BLI_utildefines.h"
-#include "DNA_pagedbuffer_types.h"
+struct bPagedBuffer;
+struct bPagedBufferLayer;
+
+void BLI_pbuf_init(struct bPagedBuffer *pbuf, size_t page_bytes);
+void BLI_pbuf_free(struct bPagedBuffer *pbuf);
+void BLI_pbuf_copy(struct bPagedBuffer *to, struct bPagedBuffer *from);
+
+struct bPagedBufferLayer *BLI_pbuf_layer_insert(struct bPagedBuffer *pbuf, size_t elem_bytes, int pos);
+void BLI_pbuf_layer_add(struct bPagedBuffer *pbuf, size_t elem_bytes);
+struct bPagedBufferLayer *BLI_pbuf_layer_copy(struct bPagedBuffer *pbuf, int pos, int insert_pos);
+void BLI_pbuf_layer_remove(struct bPagedBuffer *pbuf, int pos);
+void BLI_pbuf_layer_move(struct bPagedBuffer *pbuf, int from_pos, int to_pos);
diff --git a/source/blender/blenlib/intern/pagedbuffer.c b/source/blender/blenlib/intern/pagedbuffer.c
index 356a6a5..d2565d9 100644
--- a/source/blender/blenlib/intern/pagedbuffer.c
+++ b/source/blender/blenlib/intern/pagedbuffer.c
@@ -30,75 +30,217 @@
#include "DNA_pagedbuffer_types.h"
#include "BLI_listbase.h"
+#include "BLI_math.h"
#include "BLI_pagedbuffer.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#define PBUF_ALIGN_STRICT
-#define div_ceil(a, b) \
- (1 + ((a) - 1) / (b))
+BLI_INLINE div_t div_ceil(int a, int b)
+{
+ div_t result = div(a, b);
+ if (result.rem > 0)
+ result.quot += 1;
+ return result;
+}
static int pbuf_layer_page_size_from_bytes(size_t page_bytes, size_t elem_bytes)
{
- div_t page_size = div(page_bytes, elem_size);
+ div_t page_size = div(page_bytes, elem_bytes);
#ifdef PBUF_ALIGN_STRICT
BLI_assert(page_size.rem == 0);
#endif
return page_size.quot;
}
-static bPagedBufferLayer *pbuf_layer_new(int totelem, size_t page_bytes, size_t elem_bytes)
+static void pbuf_layer_page_alloc(bPagedBufferLayer *layer, int p, size_t page_bytes)
{
- bPagedBufferLayer *layer = MEM_callocN(sizeof(bPagedBufferLayer), "paged buffer layer");
+ bPagedBufferPage *page = &layer->pages[p];
+ if (!page->data) {
+ page->data = MEM_mallocN(page_bytes, "paged buffer page");
+ layer->totalloc += layer->page_size;
+ }
+}
+
+static void pbuf_layer_page_free(bPagedBufferLayer *layer, int p)
+{
+ bPagedBufferPage *page = &layer->pages[p];
+ if (page->data) {
+ MEM_freeN(page->data);
+ layer->totalloc -= layer->page_size;
+ }
+}
+
+typedef enum ePagedBufferLayerPageAlloc {
+ PBUF_PAGE_ALLOC_NONE, /* don't allocate any page data */
+ PBUF_PAGE_ALLOC_EXTEND, /* allocate only new page data */
+ PBUF_PAGE_ALLOC_ALL /* allocate all page data */
+} ePagedBufferLayerPageAlloc;
+
+static void pbuf_layer_set_totelem(bPagedBufferLayer *layer, size_t page_bytes, int totelem, int new_totelem, ePagedBufferLayerPageAlloc alloc_mode)
+{
+ div_t div_elem = div_ceil(new_totelem, layer->page_size);
+ int ntotpages = div_elem.quot;
+ // int npagefill = div_elem.rem;
+ bPagedBufferPage *npages;
+ int startp = totelem / layer->page_size;
int p;
+ if (ntotpages == 0) {
+ layer->pages = NULL;
+ layer->totpages = 0;
+ return;
+ }
+
+ npages = MEM_callocN(sizeof(bPagedBufferPage) * ntotpages, "paged buffer page array");
+ if (layer->pages) {
+ int copyp = min_ii(layer->totpages, ntotpages);
+ memcpy(npages, layer->pages, sizeof(bPagedBufferPage) * copyp);
+ MEM_freeN(layer->pages);
+ }
+
+ layer->pages = npages;
+ layer->totpages = ntotpages;
+
+ /* init data */
+ switch (alloc_mode) {
+ case PBUF_PAGE_ALLOC_EXTEND:
+ for (p = startp; p < ntotpages; ++p)
+ pbuf_layer_page_alloc(layer, p, page_bytes);
+ break;
+ case PBUF_PAGE_ALLOC_ALL:
+ for (p = 0; p < ntotpages; ++p)
+ pbuf_layer_page_alloc(layer, p, page_bytes);
+ break;
+ case PBUF_PAGE_ALLOC_NONE:
+ /* nothing to do, data pointers are NULL already */
+ break;
+ }
+}
+
+/* XXX TODO add optional iterator to determine dead pages? */
+static bPagedBufferLayer *pbuf_layer_new(int totelem, size_t page_bytes, size_t elem_bytes)
+{
+ bPagedBufferLayer *layer = MEM_callocN(sizeof(bPagedBufferLayer), "paged buffer layer");
+ layer->elem_bytes = elem_bytes;
layer->page_size = pbuf_layer_page_size_from_bytes(page_bytes, elem_bytes);
- layer->totpages = div_ceil(totelem, layer->page_size);
- layer->pages = MEM_callocN(sizeof(void *) * layer->totpages, "paged buffer page array");
- for (p = 0; p < layer->totpages; ++p)
- layer->pages[p] = MEM_mallocN(elem_bytes * layer->page_size, "paged buffer page");
+
+ pbuf_layer_set_totelem(layer, page_bytes, 0, totelem, PBUF_PAGE_ALLOC_ALL);
return layer;
}
static void pbuf_layer_free(bPagedBufferLayer *layer)
{
+ if (layer->pages) {
+ int p;
+ for (p = 0; p < layer->totpages; ++p)
+ pbuf_layer_page_free(layer, p);
+ MEM_freeN(layer->pages);
+ }
+ MEM_freeN(layer);
}
static bPagedBufferLayer *pbuf_layer_copy(bPagedBufferLayer *layer)
{
+ bPagedBufferLayer *nlayer = MEM_dupallocN(layer);
+ if (layer->pages) {
+ int p;
+ nlayer->pages = MEM_dupallocN(layer->pages);
+ for (p = 0; p < nlayer->totpages; ++p)
+ if (layer->pages[p].data)
+ nlayer->pages[p].data = MEM_dupallocN(layer->pages[p].data);
+ }
+ return nlayer;
}
-void BLI_pbuf_init(bPagedBuffer *pbuf)
+void BLI_pbuf_init(bPagedBuffer *pbuf, size_t page_bytes)
{
- pbuf->layers = NULL;
- pbuf->totlayers = 0;
+ pbuf->page_bytes = page_bytes;
+
+ pbuf->layers.first = pbuf->layers.last = NULL;
pbuf->totelem = 0;
}
void BLI_pbuf_free(bPagedBuffer *pbuf)
{
- int l;
- for (l = 0; l < pbuf->totlayers; ++l)
- pbuf_layer_free(&pbuf->layers[l]);
- pbuf->layers = NULL;
- pbuf->totlayers = 0;
+ bPagedBufferLayer *layer;
+ for (layer = pbuf->layers.first; layer; layer = layer->next)
+ pbuf_layer_free(layer);
+ pbuf->layers.first = pbuf->layers.last = NULL;
pbuf->totelem = 0;
}
void BLI_pbuf_copy(bPagedBuffer *to, bPagedBuffer *from)
{
- int l;
- to->layers = MEM_dupallocN(from->layers);
- for (l = 0; l < from->totlayers; ++l) {
- to->layers[l] = pbuf_layer_copy(from->layers[l]);
- }
- to->totlayers = from->totlayers;
+ bPagedBufferLayer *layer;
+
+ to->page_bytes = from->page_bytes;
+
+ for (layer = from->layers.first; layer; layer = layer->next)
+ BLI_addtail(&to->layers, pbuf_layer_copy(layer));
to->totelem = from->totelem;
}
+bPagedBufferLayer *BLI_pbuf_layer_insert(bPagedBuffer *pbuf, size_t elem_bytes, int pos)
+{
+ bPagedBufferLayer *layer = pbuf_layer_new(pbuf->totelem, pbuf->page_bytes, elem_bytes);
+ bPagedBufferLayer *next = BLI_findlink(&pbuf->layers, pos);
+ BLI_insertlinkbefore(&pbuf->layers, next, layer);
+ return layer;
+}
+
+void BLI_pbuf_layer_add(bPagedBuffer *pbuf, size_t elem_bytes)
+{
+ bPagedBufferLayer *layer = pbuf_layer_new(pbuf->totelem, pbuf->page_bytes, elem_bytes);
+ BLI_addtail(&pbuf->layers, layer);
+}
+
+bPagedBufferLayer *BLI_pbuf_layer_copy(bPagedBuffer *pbuf, int pos, int insert_pos)
+{
+ bPagedBufferLayer *layer = BLI_findlink(&pbuf->layers, pos);
+ if (layer) {
+ bPagedBufferLayer *nlayer = pbuf_layer_copy(layer);
+ bPagedBufferLayer *next = BLI_findlink(&pbuf->layers, insert_pos);
+ BLI_insertlinkbefore(&pbuf->layers, next, nlayer);
+ return nlayer;
+ }
+ return NULL;
+}
+
+void BLI_pbuf_layer_remove(bPagedBuffer *pbuf, int pos)
+{
+ bPagedBufferLayer *layer = BLI_findlink(&pbuf->layers, pos);
+ if (layer) {
+ BLI_remlink(&pbuf->layers, layer);
+ pbuf_layer_free(layer);
+ }
+}
+
+void BLI_pbuf_layer_move(bPagedBuffer *pbuf, int from_pos, int to_pos)
+{
+ if (from_pos != to_pos) {
+ bPagedBufferLayer *layer = BLI_findlink(&pbuf->layers, from_pos);
+ if (layer) {
+ bPagedBufferLayer *next = BLI_findlink(&pbuf->layers, to_pos);
+ BLI_remlink(&pbuf->layers, layer);
+ BLI_insertlinkbefore(&pbuf->layers, next, layer);
+ }
+ }
+}
+
+
+void BLI_pbuf_add_elements(bPagedBuffer *pbuf, int num_elem)
+{
+ int ntotelem = pbuf->totelem + num_elem;
+ bPagedBufferLayer *layer;
+ for (layer = pbuf->layers.first; layer; layer = layer->next) {
+ pbuf_layer_set_totelem(layer, pbuf->page_bytes, pbuf->totelem, ntotelem, PBUF_PAGE_ALLOC_EXTEND);
+ }
+}
+
#if 0
/************************************************/
/* Buffer Management */
diff --git a/source/blender/makesdna/DNA_pagedbuffer_types.h b/source/blender/makesdna/DNA_pagedbuffer_types.h
index 767b0f4..fd1a2eb 100644
--- a/source/blender/makesdna/DNA_pagedbuffer_types.h
+++ b/source/blender/makesdna/DNA_pagedbuffer_types.h
@@ -38,16 +38,19 @@ typedef struct bPagedBufferPage {
} bPagedBufferPage;
typedef struct bPagedBufferLayer {
+ struct bPagedBufferLayer *next, *prev;
+
struct bPagedBufferPage *pages; /* page list */
+ int elem_bytes; /* size of a single element in bytes */
int page_size; /* elements per page */
int totpages; /* number of allocated pages */
int totalloc; /* actually allocated elements (dead pages not counted) */
} bPagedBufferLayer;
typedef struct bPagedBuffer {
- struct bPagedBufferLayer *layers; /* layer list */
- int totlayers; /* number of layers */
+ ListBase layers; /* layer list */
int totelem; /* number of elements in the buffer */
+ int page_bytes; /* size of a page in bytes */
} bPagedBuffer;
#endif
More information about the Bf-blender-cvs
mailing list