From efda9aa3f0cee82cc3e2968326cf0df804d7e6d6 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Wed, 12 Jun 2019 13:26:31 -0700 Subject: 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. --- src/stage.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'src/stage.c') 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; } -- cgit v1.2.3