diff options
-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); |