diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2019-06-12 13:26:31 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2019-06-12 13:26:31 -0700 |
commit | efda9aa3f0cee82cc3e2968326cf0df804d7e6d6 (patch) | |
tree | a01dc79046e93cf95bd7ecb2dfcf290b41be6e45 | |
parent | 15fa5d5714ce286323f25468284be0b28136a3c8 (diff) |
libstage: add rudimentary dirty state
This adds a dirty bit to every stage_t, but only maintains the bit
at the root. This means rendering is assumed to occur at the root,
as that's the only place the dirty state will be correctly managed.
-rw-r--r-- | src/stage.c | 40 | ||||
-rw-r--r-- | src/stage.h | 3 |
2 files changed, 37 insertions, 6 deletions
diff --git a/src/stage.c b/src/stage.c index e596ab0..6420c87 100644 --- a/src/stage.c +++ b/src/stage.c @@ -31,6 +31,7 @@ struct stage_t { float alpha; /* alpha for the stage */ unsigned active:1; /* stage is active */ unsigned locked:1; /* stage is locked */ + unsigned dirty:1; /* stage is dirty (since last render) */ stage_render_func_t *render; /* render object */ stage_free_func_t *free; /* free object */ @@ -276,15 +277,44 @@ static void _render_stage(const stage_t *stage, float alpha, void *render_ctxt) } -/* recursively render the supplied stage tree, skipping inactive branches */ -void stage_render(const stage_t *stage, void *render_ctxt) +/* recursively render the supplied stage tree if dirty, skipping inactive branches */ +/* returns wether the stage was dirty or not, for influence of page flipping etc. */ +int stage_render(stage_t *stage, void *render_ctxt) { assert(stage); + assert(!stage->parent); /* XXX: Current dirty implementation is global and only + * maintains the dirty bit in the root node. So assert + * that render is only called on the root to not break + * dirty detection. + */ - if (!stage->active) - return; + if (stage->dirty) { + if (stage->active) + _render_stage(stage, 1.f, render_ctxt); + + stage->dirty = 0; + + return 1; + } + + return 0; +} + + +/* mark a stage as dirty */ +/* as the current stage_render() implementation only checks the dirty flag of + * the supplied stage, which is presumed to be the root, this currently + * walks up the chain of parents if any to update the root flag. + * TODO: perhaps stage_render() should assert that it's called on the root. + */ +void stage_dirty(stage_t *stage) +{ + assert(stage); + + while (stage->parent) + stage = stage->parent; - _render_stage(stage, 1.f, render_ctxt); + stage->dirty = 1; } diff --git a/src/stage.h b/src/stage.h index c5d0173..a2a2543 100644 --- a/src/stage.h +++ b/src/stage.h @@ -29,7 +29,8 @@ typedef stage_t * (stage_lookup_func_t)(const stage_t *stage, void *object, void stage_t * stage_new(stage_t *parent, int layer, const char *name, void *object, stage_render_func_t *render_func, stage_free_func_t *free_func, stage_lookup_func_t *lookup_func); void stage_replace(stage_t *stage, const char *name, void *object, stage_render_func_t *render_func, stage_free_func_t *free_func, stage_lookup_func_t *lookup_func); stage_t * stage_free(stage_t *stage); -void stage_render(const stage_t *stage, void *render_ctxt); +int stage_render(stage_t *stage, void *render_ctxt); +void stage_dirty(stage_t *stage); void stage_clear(stage_t *stage); void stage_set_object(stage_t *stage, void *object); void * stage_get_object(const stage_t *stage); |