diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2025-04-07 01:33:07 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2025-04-07 01:33:07 +0200 |
commit | 1b72dceae8427a7e43bef44c7dbb47f53c0cb865 (patch) | |
tree | 0ccb209a12dcd733367a43b7d1899463234704c6 | |
parent | 068e4f94310953bf3d2ead074997b55d4c3c0091 (diff) | |
download | reduced_system_layer-1b72dceae8427a7e43bef44c7dbb47f53c0cb865.zip |
Rewrite antialiasing downscale code
-rw-r--r-- | examples/ui.c | 1 | ||||
-rwxr-xr-x | graphics.c | 12 | ||||
-rwxr-xr-x | reduced_system_layer.c | 77 |
3 files changed, 50 insertions, 40 deletions
diff --git a/examples/ui.c b/examples/ui.c index 943828d..ebc00c8 100644 --- a/examples/ui.c +++ b/examples/ui.c @@ -1,4 +1,3 @@ -#define MAX_FRAME_DURATION 100 #include "../graphics.c" b8 button_0_down = 0; @@ -961,6 +961,18 @@ vec4_f32 vec4_f32_lerp(vec4_f32 a, vec4_f32 b, f32 t) { // ================================================================ +static f64 gamma_(f64 x) { + if (x >= 0.0031308) + return 1.055 * pow(x, 1.0 / 2.4) - 0.055; + return 12.92 * x; +} + +static f64 gamma_re_(f64 x) { + if (x >= 0.04045) + return pow((x + 0.055) / 1.055, 2.4); + return x / 12.92; +} + vec3_f32 rgb_gamma_add(vec3_f32 rgb) { return (vec3_f32) { .x = (f32) gamma_(rgb.x), diff --git a/reduced_system_layer.c b/reduced_system_layer.c index 8a3cc69..6473039 100755 --- a/reduced_system_layer.c +++ b/reduced_system_layer.c @@ -53,6 +53,7 @@ #/ + [x] Requests cache #/ + [x] Global anti-aliasing #/ + [x] Fill triangles +#/ - Profiling #/ - Examples #/ - Conway's Game of Life #/ - Julia Set @@ -1464,10 +1465,12 @@ void resize_dynamic_array_capacity(i64 *num, i64 *capacity, void **data, i64 ele // // ================================================================ -static i64 _internal_pixels_len = 0; -static i32 _internal_width = 0; -static i32 _internal_height = 0; -static u32 *_internal_pixels = NULL; +static i32 _internal_width = 0; +static i32 _internal_height = 0; +static i64 _internal_pixels_len = 0; +static u32 *_internal_pixels = NULL; +static i64 _internal_row_len = 0; +static vec3_f32 *_internal_row = NULL; static i64 average_frame_duration_(i64 duration) { _frame_duration[_frame_index] = duration; @@ -1598,24 +1601,17 @@ static i8 pixel_size_update_(i64 real_width, i64 real_height) { resize_dynamic_array_exact(&_internal_pixels_len, (void **) &_internal_pixels, sizeof *_internal_pixels, internal_width * internal_height); if (_internal_pixels_len < internal_width * internal_height) LOG_ERROR("Failed to allocate %lld x %lld internal pixel buffer.", internal_width, internal_height); + + resize_dynamic_array_exact(&_internal_row_len, (void **) &_internal_row, sizeof *_internal_row, internal_width); + if (_internal_row_len < internal_width) + LOG_ERROR("Failed to allocate %lld internal immediate pixel buffer.", internal_width); + _internal_width = real_width; _internal_height = real_width <= 0 ? 0 : min2_i32_(_internal_pixels_len / real_width, real_height); return size_changed; } -static f64 gamma_(f64 x) { - if (x >= 0.0031308) - return 1.055 * pow(x, 1.0 / 2.4) - 0.055; - return 12.92 * x; -} - -static f64 gamma_re_(f64 x) { - if (x >= 0.04045) - return pow((x + 0.055) / 1.055, 2.4); - return x / 12.92; -} - static void convert_pixels_for_window_(void) { i32 aa_scale = g_platform.antialiasing_scale; @@ -1626,14 +1622,11 @@ static void convert_pixels_for_window_(void) { // Downscale pixels from vec4_f32 pixel buffer to internal u32 pixel buffer. // - // FIXME, PERF: - Read all pixels sequentially, store the intermediate - // sum for each row in a temporary buffer. - // - Check if the scale is 1:1. + // FIXME: Check if the scale is 1:1. { i64 dst_width = g_platform.frame_width / aa_scale; i64 dst_height = g_platform.frame_height / aa_scale; i64 src_width = g_platform.frame_width; - i64 src_stride = g_platform.frame_width * aa_scale; if (g_platform.num_pixels < src_width * g_platform.frame_height) { LOG_ERROR("Sanity"); @@ -1645,33 +1638,38 @@ static void convert_pixels_for_window_(void) { return; } - f32 k = 1.f / (aa_scale * aa_scale); + if (_internal_row_len < dst_width) { + LOG_ERROR("Sanity"); + return; + } + + f32 k = 1.f / (aa_scale * aa_scale); + vec4_f32 *s = g_platform.pixels; + u32 *d = _internal_pixels; for (i64 j = 0; j < dst_height; ++j) { - vec4_f32 *s = g_platform.pixels + j * src_stride; - u32 *d = _internal_pixels + j * dst_width; - u32 *d_end = d + dst_width; + mem_set_(_internal_row, 0, dst_width * sizeof *_internal_row); - for (; d < d_end; ++d, s += aa_scale) { - vec3_f32 color = {0}; + for (i64 jj = 0; jj < aa_scale; ++jj) { + vec3_f32 *im = _internal_row; + vec3_f32 *im_end = im + dst_width; - for (i32 jj = 0; jj < aa_scale; ++jj) { - vec4_f32 *ss = s + jj * src_width; - vec4_f32 *ss_end = ss + aa_scale; + for (; im < im_end; ++im) { + vec4_f32 *s_end = s + aa_scale; - for (; ss < ss_end; ++ss) { - color.x += gamma_re_(ss->z); - color.y += gamma_re_(ss->y); - color.z += gamma_re_(ss->x); + for (; s < s_end; ++s) { + im->x += s->x; + im->y += s->y; + im->z += s->z; } } + } - color.x = gamma_(color.x * k); - color.y = gamma_(color.y * k); - color.z = gamma_(color.z * k); + u32 *d_end = d + dst_width; + vec3_f32 *im = _internal_row; - *d = rgb_u32_from_f32_(color) | 0xff000000; - } + for (; d < d_end; ++d, ++im) + *d = rgb_u32_from_f32_((vec3_f32) { .x = im->x * k, .y = im->y * k, .z = im->z * k, }) | 0xff000000; } } @@ -1740,7 +1738,8 @@ static void pixel_size_calibrate_(i64 current_frame_duration) { } static void cleanup_pixel_buffers_(void) { - resize_dynamic_array_exact(&_internal_pixels_len, (void **) &_internal_pixels, sizeof *_internal_pixels, 0); + resize_dynamic_array_exact(&_internal_pixels_len, (void **) &_internal_pixels, sizeof *_internal_pixels, 0); + resize_dynamic_array_exact(&_internal_row_len, (void **) &_internal_row, sizeof *_internal_row, 0); resize_dynamic_array_exact(&g_platform.num_pixels, (void **) &g_platform.pixels, sizeof *g_platform.pixels, 0); } |