Skip to content

Instantly share code, notes, and snippets.

@mtwilliams
Last active August 29, 2015 14:02
Show Gist options
  • Save mtwilliams/be92ee85ee8f827a1d33 to your computer and use it in GitHub Desktop.
Save mtwilliams/be92ee85ee8f827a1d33 to your computer and use it in GitHub Desktop.
struct renderable {
struct renderable *prev, *next;
bool (*render)(const struct renderable *r, ...);
};
static struct renderable *render_list_head_ = ...;
static struct renderable *render_list_tail_ = ...;
void render(...) {
const struct renderable* r = render_list_tail_;
for (;;) {
__builtin_prefetch(r->next, 1, 0);
if (r->render(r, ...))
continue;
return;
}
}
void add_to_render_list(struct renderable *renderable) {
renderable->prev = render_list_tail_->prev;
renderable->next = render_list_tail_;
}
void remove_from_render_list(struct renderable *renderable) {
renderable->prev->next = renderable->next;
renderable->next->prev = renderable->prev;
}
struct pre_frame {
struct renderable __renderable__;
};
bool pre_frame_render(const struct pre_frame *r, ...) {
glClearBits(...);
glClearColor(...);
glClear(...);
return true;
}
struct post_frame {
struct renderable __renderable__;
};
bool post_frame_render(const struct post_frame *r, ...) {
wglSwapBuffers(...);
return false;
}
void init_render_list(void) {
static pre_frame pre_frame_renderable;
static post_frame post_frame_renderable;
pre_frame_renderable.r.prev = NULL;
pre_frame_renderable.r.next = &post_frame_renderable;
pre_frame_renderable.r.render = &pre_frame_render;
post_frame_renderable.r.prev = &pre_frame_renderable;
post_frame_renderable.r.next = NULL;
post_frame_renderable.r.render = &post_frame_render;
render_list_head_ = &pre_frame_renderable;
render_list_tail_ = &post_frame_renderable;
}
// say we need want to guard (prevent reordering) certain sections, or go parallel:
struct parellel_render_list {
struct renderable r;
struct renderable *render_list_head;
struct renderable *render_list_tail;
};
bool parallel_render_list_render(const struct parellel_render_list *r, ...) {
// kick a task to handle the render list if going parallel
task_sched_add(...);
return true;
// just note that you need to handle state carefully here, because parallel command streams
// don't fly in anything but mantle. so you need to either wait on the task or provide
// more expressive control over render list consumption.
// if you just want to guard, keep a reference to this renderable and treat it like a list
// then:
for (;;} {
...
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment