From 4f97be617c8687ddf450d5a783d7571a69507b2e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Aug 2017 17:42:05 +1000 Subject: [PATCH] Gawain: add ownership flag to Gwn_Batch Flag ownership for each index array & vbo's so we don't have to manually keep track of this and use the right free call. Instead this can be passed on creation. See D2676 --- intern/gawain/gawain/gwn_batch.h | 21 +++++++++++++++++--- intern/gawain/src/gwn_batch.c | 34 +++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/intern/gawain/gawain/gwn_batch.h b/intern/gawain/gawain/gwn_batch.h index 0667cfd751e..96d519450b5 100644 --- a/intern/gawain/gawain/gwn_batch.h +++ b/intern/gawain/gawain/gwn_batch.h @@ -36,19 +36,34 @@ typedef struct Gwn_Batch { Gwn_BatchPhase phase; bool program_dirty; bool program_in_use; + unsigned owns_flag; // state GLuint program; const Gwn_ShaderInterface* interface; } Gwn_Batch; -Gwn_Batch* GWN_batch_create(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*); -void GWN_batch_init(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*); +enum { + GWN_BATCH_OWNS_VBO = (1 << 0), + /* each vbo index gets bit-shifted */ + GWN_BATCH_OWNS_INDEX = (1 << 31), +}; + +Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag); +void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag); + +#define GWN_batch_create(prim, verts, elem) \ + GWN_batch_create_ex(prim, verts, elem, 0) +#define GWN_batch_init(batch, prim, verts, elem) \ + GWN_batch_init_ex(batch, prim, verts, elem, 0) void GWN_batch_discard(Gwn_Batch*); // verts & elem are not discarded void GWN_batch_discard_all(Gwn_Batch*); // including verts & elem -int GWN_batch_vertbuf_add(Gwn_Batch*, Gwn_VertBuf*); +int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo); + +#define GWN_batch_vertbuf_add(batch, verts) \ + GWN_batch_vertbuf_add_ex(batch, verts, false) void GWN_batch_program_set(Gwn_Batch*, GLuint program, const Gwn_ShaderInterface*); // Entire batch draws with one shader program, but can be redrawn later with another program. diff --git a/intern/gawain/src/gwn_batch.c b/intern/gawain/src/gwn_batch.c index b4e0632377d..23160668ca8 100644 --- a/intern/gawain/src/gwn_batch.c +++ b/intern/gawain/src/gwn_batch.c @@ -18,16 +18,20 @@ extern void gpuBindMatrices(const Gwn_ShaderInterface* shaderface); extern bool gpuMatricesDirty(void); // how best to use this here? -Gwn_Batch* GWN_batch_create(Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem) +Gwn_Batch* GWN_batch_create_ex( + Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, + unsigned owns_flag) { Gwn_Batch* batch = calloc(1, sizeof(Gwn_Batch)); - GWN_batch_init(batch, prim_type, verts, elem); + GWN_batch_init_ex(batch, prim_type, verts, elem, owns_flag); return batch; } -void GWN_batch_init(Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem) +void GWN_batch_init_ex( + Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem, + unsigned owns_flag) { #if TRUST_NO_ONE assert(verts != NULL); @@ -40,16 +44,32 @@ void GWN_batch_init(Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts batch->prim_type = prim_type; batch->gl_prim_type = convert_prim_type_to_gl(prim_type); batch->phase = GWN_BATCH_READY_TO_DRAW; + batch->owns_flag = owns_flag; } void GWN_batch_discard(Gwn_Batch* batch) { + if (batch->owns_flag & GWN_BATCH_OWNS_INDEX) + GWN_indexbuf_discard(batch->elem); + + if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0) + { + for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) + { + if (batch->verts[v] == NULL) + break; + if (batch->owns_flag & (1 << v)) + GWN_vertbuf_discard(batch->verts[v]); + } + } + if (batch->vao_id) GWN_vao_free(batch->vao_id); free(batch); } +/* TODO, remove */ void GWN_batch_discard_all(Gwn_Batch* batch) { for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) @@ -65,7 +85,9 @@ void GWN_batch_discard_all(Gwn_Batch* batch) GWN_batch_discard(batch); } -int GWN_batch_vertbuf_add(Gwn_Batch* batch, Gwn_VertBuf* verts) +int GWN_batch_vertbuf_add_ex( + Gwn_Batch* batch, Gwn_VertBuf* verts, + bool own_vbo) { for (unsigned v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v) { @@ -78,6 +100,8 @@ int GWN_batch_vertbuf_add(Gwn_Batch* batch, Gwn_VertBuf* verts) #endif batch->verts[v] = verts; // TODO: mark dirty so we can keep attrib bindings up-to-date + if (own_vbo) + batch->owns_flag |= (1 << v); return v; } } @@ -446,4 +470,4 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch* batch_instanced, Gwn_ // GWN_batch_program_use_end(batch); glBindVertexArray(0); - } \ No newline at end of file + }