summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2019-06-12 13:26:31 -0700
committerVito Caputo <vcaputo@pengaru.com>2019-06-12 13:26:31 -0700
commitefda9aa3f0cee82cc3e2968326cf0df804d7e6d6 (patch)
treea01dc79046e93cf95bd7ecb2dfcf290b41be6e45
parent15fa5d5714ce286323f25468284be0b28136a3c8 (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.c40
-rw-r--r--src/stage.h3
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);
© All Rights Reserved