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 /src | |
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.
Diffstat (limited to 'src')
-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); |