From 7a21db5914dd7a5666e603d66ed3948b659ba2fc Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 8 May 2010 23:21:48 -0600 Subject: New DMNSN_ARRAY_FOREACH() macro, faster than iterating with dmnsn_array_get(). --- libdimension/canvas.c | 15 +++++---------- libdimension/dimension/array.h | 22 +++++++++++++++++++++- libdimension/gl.c | 15 ++++++--------- libdimension/png.c | 12 +++++------- libdimension/prtree.c | 13 ++++--------- libdimension/raytrace.c | 10 +++------- libdimension/scene.c | 14 ++++---------- 7 files changed, 48 insertions(+), 53 deletions(-) (limited to 'libdimension') diff --git a/libdimension/canvas.c b/libdimension/canvas.c index 4ed7fd5..2c60c60 100644 --- a/libdimension/canvas.c +++ b/libdimension/canvas.c @@ -48,11 +48,9 @@ dmnsn_delete_canvas(dmnsn_canvas *canvas) { if (canvas) { /* Free the optimizers */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_canvas_optimizer optimizer; - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.free_fn) { - (*optimizer.free_fn)(optimizer.ptr); + DMNSN_ARRAY_FOREACH(dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->free_fn) { + (*i->free_fn)(i->ptr); } } dmnsn_delete_array(canvas->optimizers); @@ -75,15 +73,12 @@ void dmnsn_set_pixel(dmnsn_canvas *canvas, size_t x, size_t y, dmnsn_color color) { - dmnsn_canvas_optimizer optimizer; - /* Set the pixel */ canvas->pixels[y*canvas->x + x] = color; /* Call the optimizers */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - (*optimizer.optimizer_fn)(canvas, optimizer, x, y); + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + (*i->optimizer_fn)(canvas, *i, x, y); } } diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h index e3dc7b4..afd5e16 100644 --- a/libdimension/dimension/array.h +++ b/libdimension/dimension/array.h @@ -100,7 +100,21 @@ dmnsn_array_set(dmnsn_array *array, size_t i, const void *obj) memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); } -/* Element access */ +/* First element */ +DMNSN_INLINE void * +dmnsn_array_first(const dmnsn_array *array) +{ + return array->ptr; +} + +/* Last element */ +DMNSN_INLINE void * +dmnsn_array_last(const dmnsn_array *array) +{ + return (char *)array->ptr + array->obj_size*(array->length - 1); +} + +/* Arbitrary element access */ DMNSN_INLINE void * dmnsn_array_at(const dmnsn_array *array, size_t i) { @@ -156,4 +170,10 @@ dmnsn_array_remove(dmnsn_array *array, size_t i) dmnsn_array_resize(array, size - 1); } +/* Macro to shorten array iteration */ +#define DMNSN_ARRAY_FOREACH(type, i, array) \ + for (type i = dmnsn_array_first(array); \ + i <= (type)dmnsn_array_last(array); \ + ++i) + #endif /* DIMENSION_ARRAY_H */ diff --git a/libdimension/gl.c b/libdimension/gl.c index 84dcc91..d07465f 100644 --- a/libdimension/gl.c +++ b/libdimension/gl.c @@ -32,16 +32,14 @@ static void dmnsn_gl_optimizer_fn(dmnsn_canvas *canvas, int dmnsn_gl_optimize_canvas(dmnsn_canvas *canvas) { - dmnsn_canvas_optimizer optimizer; - /* Check if we've already optimized this canvas */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_gl_optimizer_fn) { + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_gl_optimizer_fn) { return 0; } } + dmnsn_canvas_optimizer optimizer; optimizer.optimizer_fn = &dmnsn_gl_optimizer_fn; optimizer.free_fn = &free; @@ -67,10 +65,9 @@ dmnsn_gl_write_canvas(const dmnsn_canvas *canvas) size_t height = canvas->y; /* Check if we can optimize this */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_gl_optimizer_fn) { - glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_SHORT, optimizer.ptr); + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_gl_optimizer_fn) { + glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_SHORT, i->ptr); return glGetError() == GL_NO_ERROR ? 0 : 1; } } diff --git a/libdimension/png.c b/libdimension/png.c index 021b9f2..177293c 100644 --- a/libdimension/png.c +++ b/libdimension/png.c @@ -39,9 +39,8 @@ dmnsn_png_optimize_canvas(dmnsn_canvas *canvas) dmnsn_canvas_optimizer optimizer; /* Check if we've already optimized this canvas */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_png_optimizer_fn) { + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_png_optimizer_fn) { return 0; } } @@ -287,12 +286,11 @@ dmnsn_png_write_canvas_impl(dmnsn_progress *progress, } /* Check if we can optimize this */ - for (size_t i = 0; i < dmnsn_array_size(canvas->optimizers); ++i) { - dmnsn_array_get(canvas->optimizers, i, &optimizer); - if (optimizer.optimizer_fn == &dmnsn_png_optimizer_fn) { + DMNSN_ARRAY_FOREACH (dmnsn_canvas_optimizer *, i, canvas->optimizers) { + if (i->optimizer_fn == &dmnsn_png_optimizer_fn) { for (size_t y = 0; y < height; ++y) { /* Invert the rows. PNG coordinates are fourth quadrant. */ - uint16_t *row = (uint16_t *)optimizer.ptr + 4*(height - y - 1)*width; + uint16_t *row = (uint16_t *)i->ptr + 4*(height - y - 1)*width; png_write_row(png_ptr, (png_bytep)row); dmnsn_increment_progress(progress); } diff --git a/libdimension/prtree.c b/libdimension/prtree.c index 04d8cc4..dc3ed38 100644 --- a/libdimension/prtree.c +++ b/libdimension/prtree.c @@ -430,10 +430,8 @@ dmnsn_pseudo_prtree_leaves(const dmnsn_pseudo_prtree *pseudo) static void dmnsn_precompute_objects(const dmnsn_array *objects) { - for (size_t i = 0; i < dmnsn_array_size(objects); ++i) { - dmnsn_object *object; - dmnsn_array_get(objects, i, &object); - dmnsn_object_precompute(object); + DMNSN_ARRAY_FOREACH (dmnsn_object **, object, objects) { + dmnsn_object_precompute(*object); } } @@ -555,12 +553,9 @@ dmnsn_prtree_search(const dmnsn_prtree *tree, dmnsn_line ray, double t = -1.0; /* Search the unbounded objects */ - for (size_t i = 0; i < dmnsn_array_size(tree->unbounded); ++i) { - dmnsn_object *object; - dmnsn_array_get(tree->unbounded, i, &object); - + DMNSN_ARRAY_FOREACH (dmnsn_object **, object, tree->unbounded) { dmnsn_intersection local_intersection; - if ((*object->intersection_fn)(object, ray, &local_intersection)) { + if ((*(*object)->intersection_fn)(*object, ray, &local_intersection)) { if (t < 0.0 || local_intersection.t < t) { *intersection = local_intersection; t = local_intersection.t; diff --git a/libdimension/raytrace.c b/libdimension/raytrace.c index f5d0885..0c3b738 100644 --- a/libdimension/raytrace.c +++ b/libdimension/raytrace.c @@ -315,17 +315,13 @@ dmnsn_raytrace_lighting(dmnsn_raytrace_state *state) return; } - const dmnsn_light *light; - /* Iterate over each light */ - for (size_t i = 0; i < dmnsn_array_size(state->scene->lights); ++i) { - dmnsn_array_get(state->scene->lights, i, &light); - - dmnsn_color light_color = dmnsn_raytrace_light_ray(state, light); + DMNSN_ARRAY_FOREACH (dmnsn_light **, light, state->scene->lights) { + dmnsn_color light_color = dmnsn_raytrace_light_ray(state, *light); if (!dmnsn_color_is_black(light_color)) { if (state->scene->quality & DMNSN_RENDER_FINISH) { dmnsn_vector ray = dmnsn_vector_normalize( - dmnsn_vector_sub(light->x0, state->r) + dmnsn_vector_sub((*light)->x0, state->r) ); /* Get this light's color contribution to the object */ diff --git a/libdimension/scene.c b/libdimension/scene.c index 177e7fe..58d2eda 100644 --- a/libdimension/scene.c +++ b/libdimension/scene.c @@ -50,17 +50,11 @@ void dmnsn_delete_scene(dmnsn_scene *scene) { if (scene) { - dmnsn_light *light; - dmnsn_object *object; - - for (size_t i = 0; i < dmnsn_array_size(scene->lights); ++i) { - dmnsn_array_get(scene->lights, i, &light); - dmnsn_delete_light(light); + DMNSN_ARRAY_FOREACH (dmnsn_light **, light, scene->lights) { + dmnsn_delete_light(*light); } - - for (size_t i = 0; i < dmnsn_array_size(scene->objects); ++i) { - dmnsn_array_get(scene->objects, i, &object); - dmnsn_delete_object(object); + DMNSN_ARRAY_FOREACH (dmnsn_object **, object, scene->objects) { + dmnsn_delete_object(*object); } dmnsn_delete_array(scene->lights); -- cgit v1.2.3