summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-04-26 13:07:40 +0200
committerMitya Selivanov <automainint@guattari.tech>2025-04-26 13:07:40 +0200
commite0f99749e364de10917b2f06d41a0fd98048f74b (patch)
tree4bf24e80fa291196d495d4f8f5bd724cfe5ae995
parentba0e0ab384f26b276c7ed658a38fef196a3ff382 (diff)
downloadreduced_system_layer-e0f99749e364de10917b2f06d41a0fd98048f74b.zip
Requests cache cleanup
-rw-r--r--graphics.c211
-rw-r--r--runtime.c11
2 files changed, 105 insertions, 117 deletions
diff --git a/graphics.c b/graphics.c
index 74d61f0..0ed1791 100644
--- a/graphics.c
+++ b/graphics.c
@@ -87,13 +87,6 @@ typedef struct graphics_request_ {
u16 op;
union {
struct {
- Box area;
- Pixel_Buffer src;
- } pixels;
- struct {
- Box area;
- } rectangle;
- struct {
vec2 vertices[3];
} triangle;
struct {
@@ -944,7 +937,9 @@ void fill_stencil_to_buffer(Pixel_Buffer dst, vec4_f32 color, Box area, Stencil_
u8 *s = src.pixels + src_j * src.stride;
for (u32 i = i0 - x0; d < d_end; ++d, ++i) {
u32 src_i = (i * x_ratio + x_half) >> 16;
- put_pixel_(d, mix_u8_color_(s[src_i], color));
+ u8 value = s[src_i];
+ if (value == 0) continue;
+ put_pixel_(d, mix_u8_color_(value, color));
}
}
}
@@ -1800,55 +1795,55 @@ static Graphics_Request graphics_request_scaled_(Graphics_Request req, vec2 scal
return scaled;
}
-static Graphics_Request graphics_request_moved_(Graphics_Request req, vec2 offset) {
+static Graphics_Request graphics_request_moved_(Graphics_Request req, i64 dx, i64 dy) {
Graphics_Request moved = req;
switch (req.op) {
case GRAPHICS_FILL_TRIANGLE:
- moved.triangle.vertices[0].x += offset.x;
- moved.triangle.vertices[0].y += offset.y;
- moved.triangle.vertices[1].x += offset.x;
- moved.triangle.vertices[1].y += offset.y;
- moved.triangle.vertices[2].x += offset.x;
- moved.triangle.vertices[2].y += offset.y;
+ moved.triangle.vertices[0].x += dx;
+ moved.triangle.vertices[0].y += dy;
+ moved.triangle.vertices[1].x += dx;
+ moved.triangle.vertices[1].y += dy;
+ moved.triangle.vertices[2].x += dx;
+ moved.triangle.vertices[2].y += dy;
break;
case GRAPHICS_FILL_TRIANGLES:
- moved.triangles.position.x += offset.x;
- moved.triangles.position.y += offset.y;
+ moved.triangles.position.x += dx;
+ moved.triangles.position.y += dy;
break;
case GRAPHICS_FILL_QUAD:
- moved.quad.vertices[0].x += offset.x;
- moved.quad.vertices[0].y += offset.y;
- moved.quad.vertices[1].x += offset.x;
- moved.quad.vertices[1].y += offset.y;
- moved.quad.vertices[2].x += offset.x;
- moved.quad.vertices[2].y += offset.y;
- moved.quad.vertices[3].x += offset.x;
- moved.quad.vertices[3].y += offset.y;
+ moved.quad.vertices[0].x += dx;
+ moved.quad.vertices[0].y += dy;
+ moved.quad.vertices[1].x += dx;
+ moved.quad.vertices[1].y += dy;
+ moved.quad.vertices[2].x += dx;
+ moved.quad.vertices[2].y += dy;
+ moved.quad.vertices[3].x += dx;
+ moved.quad.vertices[3].y += dy;
break;
case GRAPHICS_FILL_ELLIPSE:
- moved.ellipse.area.x += offset.x;
- moved.ellipse.area.y += offset.y;
+ moved.ellipse.area.x += dx;
+ moved.ellipse.area.y += dy;
break;
case GRAPHICS_FILL_LINE:
- moved.line.vertices[0].x += offset.x;
- moved.line.vertices[0].y += offset.y;
- moved.line.vertices[1].x += offset.x;
- moved.line.vertices[1].y += offset.y;
+ moved.line.vertices[0].x += dx;
+ moved.line.vertices[0].y += dy;
+ moved.line.vertices[1].x += dx;
+ moved.line.vertices[1].y += dy;
break;
case GRAPHICS_DRAW_TEXT_AREA:
- moved.text_area.area.x += offset.x;
- moved.text_area.area.y += offset.y;
+ moved.text_area.area.x += dx;
+ moved.text_area.area.y += dy;
break;
case GRAPHICS_DRAW_TEXT_CURSOR:
- moved.text_cursor.area.x += offset.x;
- moved.text_cursor.area.y += offset.y;
+ moved.text_cursor.area.x += dx;
+ moved.text_cursor.area.y += dy;
break;
default:;
@@ -1883,7 +1878,8 @@ static Box graphics_request_area_(Graphics_Request req) {
case GRAPHICS_DRAW_TEXT_CURSOR: area = req.text_cursor.area; break;
case GRAPHICS_FILL_TRIANGLE: {
- vec2 *v = req.triangle.vertices;
+ vec2 *v = req.triangle.vertices;
+
area.x = min3_(v[0].x, v[1].x, v[2].x);
area.y = min3_(v[0].y, v[1].y, v[2].y);
area.width = max3_(v[0].x, v[1].x, v[2].x) - area.x;
@@ -1902,23 +1898,23 @@ static Box graphics_request_area_(Graphics_Request req) {
}
break;
- case GRAPHICS_FILL_QUAD:
+ case GRAPHICS_FILL_QUAD: {
+ vec2 *v = req.quad.vertices;
+
+ area.x = min4_(v[0].x, v[1].x, v[2].x, v[3].x);
+ area.y = min4_(v[0].y, v[1].y, v[2].y, v[3].y);
+ area.width = max4_(v[0].x, v[1].x, v[2].x, v[3].x) - area.x;
+ area.height = max4_(v[0].y, v[1].y, v[2].y, v[3].y) - area.y;
+ } break;
+
case GRAPHICS_FILL_LINE: {
- vec2 quad[4] = {0};
-
- if (req.op == GRAPHICS_FILL_LINE)
- quad_from_line_(quad, req.line.vertices, req.line.width);
- else {
- quad[0] = req.quad.vertices[0];
- quad[1] = req.quad.vertices[1];
- quad[2] = req.quad.vertices[2];
- quad[3] = req.quad.vertices[3];
- }
+ vec2 *v = req.line.vertices;
+ f64 half_w = req.line.width * 0.5;
- area.x = min4_(quad[0].x, quad[1].x, quad[2].x, quad[3].x);
- area.y = min4_(quad[0].y, quad[1].y, quad[2].y, quad[3].y);
- area.width = max4_(quad[0].x, quad[1].x, quad[2].x, quad[3].x) - area.x;
- area.height = max4_(quad[0].y, quad[1].y, quad[2].y, quad[3].y) - area.y;
+ area.x = min2_(v[0].x, v[1].x) - half_w;
+ area.y = min2_(v[0].y, v[1].y) - half_w;
+ area.width = max2_(v[0].x, v[1].x) + half_w - area.x;
+ area.height = max2_(v[0].y, v[1].y) + half_w - area.y;
} break;
default:;
@@ -1929,13 +1925,13 @@ static Box graphics_request_area_(Graphics_Request req) {
static Graphics_Request_Norm_ normalize_graphics_request_(Graphics_Request req) {
Box area = graphics_request_area_(req);
- i64 x = (i64) floor(area.x - 0.5);
- i64 y = (i64) floor(area.y - 0.5);
- i64 w = (i64) ceil (area.x + area.width + 0.5) - x;
- i64 h = (i64) ceil (area.y + area.height + 0.5) - y;
+ i64 x = (i64) floor(area.x + 0.5);
+ i64 y = (i64) floor(area.y + 0.5);
+ i64 w = (i64) floor(area.x + area.width + 0.5) - x;
+ i64 h = (i64) floor(area.y + area.height + 0.5) - y;
return (Graphics_Request_Norm_) {
- .req = graphics_request_moved_(req, (vec2) { -x, -y }),
+ .req = graphics_request_moved_(req, -x, -y),
.x = x,
.y = y,
.width = w,
@@ -2019,32 +2015,7 @@ static void perform_graphics_request_to_stencil_(Stencil_Buffer dst, Graphics_Re
}
}
-static b8 mem_eq_(i64 size, void *x, void *y) {
- for (i64 i = 0; i < size; ++i)
- if (((u8 *) x)[i] != ((u8 *) y)[i])
- return 0;
- return 1;
-}
-
-static void copy_pixels_quick_(Pixel_Buffer dst, i64 x, i64 y, Pixel_Buffer src) {
- for (i64 j = 0; j < src.height; ++j) {
- vec4_f32 *s = src.pixels + j * src.stride;
- vec4_f32 *d = dst.pixels + (y + j) * dst.stride + x;
- vec4_f32 *d_end = d + src.width;
-
- for (; d < d_end; ++d, ++s) {
- d->x = d->x * (1.f - s->w) + s->x * s->w;
- d->y = d->y * (1.f - s->w) + s->y * s->w;
- d->z = d->z * (1.f - s->w) + s->z * s->w;
- }
- }
-}
-
-static void perform_graphics_request_cached_(Pixel_Buffer dst, vec4_f32 color, Graphics_Request req) {
- Graphics_Request_Norm_ norm = normalize_graphics_request_(req);
- if (norm.width <= 0 || norm.height <= 0)
- return;
-
+static void perform_graphics_request_cached_(Pixel_Buffer dst, vec4_f32 color, Graphics_Request_Norm_ norm) {
Graphics_Request_Id_ id = graphics_request_id_(norm.req);
b8 reset_slot = 1;
@@ -2057,7 +2028,7 @@ static void perform_graphics_request_cached_(Pixel_Buffer dst, vec4_f32 color, G
continue;
if (!mem_eq_(BLAKE2B_OUTBYTES, _graphics_cache[n + i].id.hash, id.hash))
continue;
- if (!mem_eq_(sizeof req, &_graphics_cache[n + i].req, &norm.req))
+ if (!mem_eq_(sizeof norm.req, &_graphics_cache[n + i].req, &norm.req))
continue;
reset_slot = 0;
slot = n + i;
@@ -2128,11 +2099,44 @@ static void perform_graphics_request_cached_(Pixel_Buffer dst, vec4_f32 color, G
fill_stencil_to_buffer(dst, color, area, stencil);
}
-static void scale_and_perform_graphics_request_(Graphics_Context context, Graphics_Request req) {
- Graphics_Request scaled = graphics_request_scaled_(req, context.scale);
+static Pixel_Buffer default_pixel_buffer_(void) {
+ i64 max_height = g_platform.num_pixels / g_platform.frame_width;
+
+ return (Pixel_Buffer) {
+ .width = g_platform.frame_width,
+ .height = min2_i64_(max_height, g_platform.frame_height),
+ .stride = g_platform.frame_width,
+ .pixels = g_platform.pixels,
+ };
+}
+
+static vec2 default_scale_(void) {
+ return (vec2) {
+ .x = ((f64) g_platform.frame_width) / g_platform.real_width,
+ .y = ((f64) g_platform.frame_height) / g_platform.real_height,
+ };
+}
+
+static Graphics_Context graphics_context_defaults_(Graphics_Context context) {
+ if (context.dst.pixels == NULL) {
+ context.dst = default_pixel_buffer_();
+ if (context.scale.x == 0.0 && context.scale.y == 0.0)
+ context.scale = default_scale_();
+ }
+
+ return context;
+}
+
+void perform_graphics_request(Graphics_Context context, Graphics_Request req) {
+ context = graphics_context_defaults_(context);
+
+ Graphics_Request scaled = graphics_request_scaled_(req, context.scale);
+ Graphics_Request_Norm_ norm = normalize_graphics_request_(scaled);
+
+ if (norm.width <= 0 || norm.height <= 0)
+ return;
if (context.disable_cache) {
- Graphics_Request_Norm_ norm = normalize_graphics_request_(req);
Stencil_Buffer stencil = default_stencil(norm.width, norm.height);
Box area = {
.x = norm.x,
@@ -2143,26 +2147,7 @@ static void scale_and_perform_graphics_request_(Graphics_Context context, Graphi
perform_graphics_request_to_stencil_(stencil, norm.req);
fill_stencil_to_buffer(context.dst, context.color, area, stencil);
} else
- perform_graphics_request_cached_(context.dst, context.color, scaled);
-}
-
-static Graphics_Context graphics_context_defaults_(Graphics_Context context) {
- if (context.dst.pixels == NULL) {
- i64 max_height = g_platform.num_pixels / g_platform.frame_width;
-
- context.dst.width = g_platform.frame_width;
- context.dst.height = min2_i64_(max_height, g_platform.frame_height);
- context.dst.stride = g_platform.frame_width;
- context.dst.pixels = g_platform.pixels;
-
- if (context.scale.x == 0. && context.scale.y == 0.)
- context.scale = (vec2) {
- .x = ((f64) g_platform.frame_width) / g_platform.real_width,
- .y = ((f64) g_platform.frame_height) / g_platform.real_height,
- };
- }
-
- return context;
+ perform_graphics_request_cached_(context.dst, context.color, norm);
}
void fill_triangle_cached(vec4_f32 color, vec2 vertices[3]) {
@@ -2282,13 +2267,11 @@ Box area_scaled_(Box area, vec2 scale) {
}
void draw_pixels(Box area, Pixel_Buffer src) {
- Graphics_Context context = graphics_context_defaults_((Graphics_Context) {0});
- draw_pixels_to_buffer(context.dst, area_scaled_(area, context.scale), src);
+ draw_pixels_to_buffer(default_pixel_buffer_(), area_scaled_(area, default_scale_()), src);
}
void fill_rectangle(vec4_f32 color, Box area) {
- Graphics_Context context = graphics_context_defaults_((Graphics_Context) {0});
- fill_rectangle_to_buffer(context.dst, color, area_scaled_(area, context.scale));
+ fill_rectangle_to_buffer(default_pixel_buffer_(), color, area_scaled_(area, default_scale_()));
}
void fill_triangle(vec4_f32 color, vec2 vertices[3]) {
@@ -2311,7 +2294,7 @@ void fill_triangles(vec4_f32 color, vec2 position, vec2 scale, i64 num_triangles
perform_graphics_request(
(Graphics_Context) { .disable_cache = 1, },
(Graphics_Request) {
- .op = GRAPHICS_FILL_TRIANGLES,
+ .op = GRAPHICS_FILL_TRIANGLES,
.triangles = {
.position = position,
.scale = scale,
@@ -2398,12 +2381,6 @@ void draw_text_cursor(i32 font, vec4_f32 color, Box area, vec2 max_size, i64 num
);
}
-// ================================================================
-
-void perform_graphics_request(Graphics_Context context, Graphics_Request req) {
- scale_and_perform_graphics_request_(graphics_context_defaults_(context), req);
-}
-
void clean_graphics_requests_cache(i64 amount) {
for (; amount > 0; --amount) {
Graphics_Cache_Slot_ *s = _graphics_cache + _graphics_cache_gc_index;
diff --git a/runtime.c b/runtime.c
index e0e1b5b..c91382d 100644
--- a/runtime.c
+++ b/runtime.c
@@ -797,6 +797,17 @@ static void mem_cpy_(void *dst, void *src, i64 len) {
*d = *s;
}
+static b8 mem_eq_(i64 len, void *x, void *y) {
+ u8 *i = (u8 *) x;
+ u8 *j = (u8 *) y;
+ u8 *i_end = i + len;
+
+ for (; i < i_end; ++i, ++j)
+ if (*i != *j)
+ return 0;
+ return 1;
+}
+
static f64 min2_(f64 x, f64 y) {
return x < y ? x : y;
}