standardize on the calculation in surface_get_index_of

and removed the conditional in it, but profiling shows it makes a
negligible difference in release builds
This commit is contained in:
Gered 2015-01-19 00:12:04 -05:00
parent 495b64a855
commit f25efe3d04
3 changed files with 45 additions and 8 deletions

View file

@ -27,6 +27,7 @@ typedef struct SURFACE {
int bytes_per_pixel;
int width;
int height;
uint32_t top_left_index;
int x_inc;
int y_inc;
RECT clip_region;
@ -83,10 +84,7 @@ static inline uint32_t surface_get_buffer_size(const SURFACE *surface) {
}
static inline uint32_t surface_get_index_of(const SURFACE *surface, int x, int y) {
if (surface->flags & SURFACE_FLAGS_SIDEWAYS_BUFFER)
return (uint32_t)((x * surface->height) + (surface->height - y - 1)) * surface->bytes_per_pixel;
else
return (uint32_t)(x + (y * surface->width)) * surface->bytes_per_pixel;
return (uint32_t)(surface->top_left_index + (surface->x_inc * x) + (surface->y_inc * y));
}
static inline COLOR_COMPONENT* surface_get_pointer_to(const SURFACE *surface, int x, int y) {

View file

@ -44,6 +44,13 @@ void surface_swap_framebuffers() {
*/
}
static uint32_t get_index(const SURFACE *surface, int x, int y) {
if (surface->flags & SURFACE_FLAGS_SIDEWAYS_BUFFER)
return (uint32_t)((x * surface->height) + (surface->height - y - 1)) * surface->bytes_per_pixel;
else
return (uint32_t)(x + (y * surface->width)) * surface->bytes_per_pixel;
}
void setup_initial_surface_properties(SURFACE *surface, int width, int height, SURFACE_FORMAT format, SURFACE_FLAGS flags) {
surface->width = width;
surface->height = height;
@ -54,10 +61,11 @@ void setup_initial_surface_properties(SURFACE *surface, int width, int height, S
surface->clip_region = rect_create(0, 0, surface->width, surface->height);
// lazy calculation for the win
uint32_t reference_index = surface_get_index_of(surface, 0, 0);
surface->x_inc = surface_get_index_of(surface, 1, 0) - reference_index;
surface->y_inc = surface_get_index_of(surface, 0, 1) - reference_index;
// lazy calculations for the win
uint32_t reference_index = get_index(surface, 0, 0);
surface->top_left_index = reference_index;
surface->x_inc = get_index(surface, 1, 0) - reference_index;
surface->y_inc = get_index(surface, 0, 1) - reference_index;
}
SURFACE* surface_create(int width, int height, SURFACE_FORMAT format, SURFACE_FLAGS flags) {

View file

@ -124,7 +124,38 @@ void test_coords_and_offsets(SURFACE_FLAGS flags) {
surface_destroy(surface);
}
void test_increments(SURFACE_FLAGS flags) {
SURFACE *surface = surface_create(1024, 1024, SURFACE_FORMAT_RGBA, flags);
assert(surface != NULL);
int x = 0;
int y = 0;
uint32_t index = surface_get_index_of(surface, x, y);
// this is a kind of silly test, but meh, a nice simple-ish validation
// over a wide range of possible coordinates
for (; y < surface->height; ++y) {
uint32_t temp = index;
for (; x < surface->width; ++x) {
uint32_t this_index = surface_get_index_of(surface, x, y);
assert(index == this_index);
index += surface->x_inc;
}
// because the previous x_inc increments make this unnecessary, but we want to test
// this increment too ...
index = temp;
index += surface->y_inc;
}
surface_destroy(surface);
}
int main(int argc, char **argv) {
test_increments(SURFACE_FLAGS_NONE);
test_increments(SURFACE_FLAGS_SIDEWAYS_BUFFER);
test_coords_and_offsets(SURFACE_FLAGS_NONE);
test_coords_and_offsets(SURFACE_FLAGS_SIDEWAYS_BUFFER);
test_rgba(SURFACE_FLAGS_NONE);