summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-04-26 10:21:23 +0200
committerMitya Selivanov <automainint@guattari.tech>2025-04-26 10:21:23 +0200
commitba0e0ab384f26b276c7ed658a38fef196a3ff382 (patch)
tree0b195105e0d8a968fac7955cb77743896fdcf771
parent7cac379388df5a551321e407c29256f92c3085b5 (diff)
downloadreduced_system_layer-ba0e0ab384f26b276c7ed658a38fef196a3ff382.zip
Use stencil in cache
-rw-r--r--graphics.c309
1 files changed, 97 insertions, 212 deletions
diff --git a/graphics.c b/graphics.c
index 22cc666..74d61f0 100644
--- a/graphics.c
+++ b/graphics.c
@@ -59,20 +59,10 @@ typedef struct {
f64 height;
} Box;
-// TODO:
-// typedef struct {
-// b8 enabled;
-// i64 x;
-// i64 y;
-// i64 width;
-// i64 height;
-// } Bounding_Box;
-
typedef struct {
i64 width;
i64 height;
i64 stride;
- // Bounding_Box bounds;
u8 *pixels;
} Stencil_Buffer;
@@ -80,13 +70,10 @@ typedef struct {
i64 width;
i64 height;
i64 stride;
- // Bounding_Box bounds;
vec4_f32 *pixels;
} Pixel_Buffer;
enum {
- GRAPHICS_DRAW_PIXELS,
- GRAPHICS_FILL_RECTANGLE,
GRAPHICS_FILL_TRIANGLE,
GRAPHICS_FILL_TRIANGLES,
GRAPHICS_FILL_QUAD,
@@ -104,56 +91,49 @@ typedef struct graphics_request_ {
Pixel_Buffer src;
} pixels;
struct {
- vec4_f32 color;
- Box area;
+ Box area;
} rectangle;
struct {
- vec4_f32 color;
- vec2 vertices[3];
+ vec2 vertices[3];
} triangle;
struct {
- vec4_f32 color;
- vec2 position;
- vec2 scale;
- i64 num_triangles;
- vec2 * vertices;
+ vec2 position;
+ vec2 scale;
+ i64 num_triangles;
+ vec2 *vertices;
} triangles;
struct {
- vec4_f32 color;
- vec2 vertices[4];
+ vec2 vertices[4];
} quad;
struct {
- vec4_f32 color;
- Box area;
+ Box area;
} ellipse;
struct {
- vec4_f32 color;
- vec2 vertices[2];
- f64 width;
+ vec2 vertices[2];
+ f64 width;
} line;
struct {
- vec4_f32 color;
- i32 font;
- Box area;
- vec2 max_size;
- i64 num_chars;
- c32 * text;
+ i32 font;
+ Box area;
+ vec2 max_size;
+ i64 num_chars;
+ c32 *text;
} text_area;
struct {
- vec4_f32 color;
- i32 font;
- Box area;
- vec2 max_size;
- i64 num_chars;
- c32 * text;
- i64 cursor;
- i64 selection;
+ i32 font;
+ Box area;
+ vec2 max_size;
+ i64 num_chars;
+ c32 *text;
+ i64 cursor;
+ i64 selection;
} text_cursor;
};
} Graphics_Request;
typedef struct {
b8 disable_cache;
+ vec4_f32 color;
vec2 scale;
Pixel_Buffer dst;
} Graphics_Context;
@@ -227,8 +207,6 @@ void fill_line_to_buffer (Pixel_Buffer dst, vec4_f32 color, vec2 vertices[
void draw_text_area_to_buffer (Pixel_Buffer dst, vec4_f32 color, i32 font, Box area, vec2 max_size, i64 num_chars, c32 *text, Stencil_Buffer stencil);
void draw_text_cursor_to_buffer(Pixel_Buffer dst, vec4_f32 color, i32 font, Box area, vec2 max_size, i64 num_chars, c32 *text, i64 cursor, i64 selection, Stencil_Buffer stencil);
-void draw_pixels_cached (Box area, Pixel_Buffer src);
-void fill_rectangle_cached (vec4_f32 color, Box area);
void fill_triangle_cached (vec4_f32 color, vec2 vertices[3]);
void fill_triangles_cached (vec4_f32 color, vec2 position, vec2 scale, i64 num_triangles, vec2 *vertices);
void fill_quad_cached (vec4_f32 color, vec2 vertices[4]);
@@ -1659,8 +1637,6 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, vec4_f32 color, i32 font, Box
//
// Requests cache
//
-// TODO: Cache stencils.
-//
// ================================================================
typedef struct {
@@ -1683,7 +1659,7 @@ typedef struct {
i64 width;
i64 height;
i64 buffer_len;
- vec4_f32 * buffer;
+ u8 * buffer;
} Graphics_Cache_Slot_;
static Graphics_Cache_Slot_ _graphics_cache[GRAPHICS_CACHE_SIZE] = {0};
@@ -1693,29 +1669,14 @@ static i64 _graphics_cache_gc_index = 0;
static void graphics_request_hash_(Blake2b_State *S, Graphics_Request req) {
switch (req.op) {
case GRAPHICS_FILL_TRIANGLES:
- blake2b_update(S, (u8 *) &req.triangles.color, sizeof req.triangles.color);
blake2b_update(S, (u8 *) &req.triangles.position, sizeof req.triangles.position);
blake2b_update(S, (u8 *) &req.triangles.scale, sizeof req.triangles.scale);
blake2b_update(S, (u8 *) &req.triangles.num_triangles, sizeof req.triangles.num_triangles);
blake2b_update(S, (u8 *) req.triangles.vertices, req.triangles.num_triangles * 3 * sizeof *req.triangles.vertices);
break;
- case GRAPHICS_DRAW_PIXELS:
- blake2b_update(S, (u8 *) &req.pixels.area, sizeof req.pixels.area);
- blake2b_update(S, (u8 *) &req.pixels.src.width, sizeof req.pixels.src.width);
- blake2b_update(S, (u8 *) &req.pixels.src.height, sizeof req.pixels.src.height);
- blake2b_update(S, (u8 *) &req.pixels.src.stride, sizeof req.pixels.src.stride);
- for (i64 j = 0; j < req.pixels.src.height; ++j)
- blake2b_update(
- S,
- (u8 *) (req.pixels.src.pixels + j * req.pixels.src.stride),
- req.pixels.src.width * sizeof *req.pixels.src.pixels
- );
- break;
-
case GRAPHICS_DRAW_TEXT_AREA:
blake2b_update(S, (u8 *) &req.text_area.font, sizeof req.text_area.font);
- blake2b_update(S, (u8 *) &req.text_area.color, sizeof req.text_area.color);
blake2b_update(S, (u8 *) &req.text_area.area, sizeof req.text_area.area);
blake2b_update(S, (u8 *) &req.text_area.max_size, sizeof req.text_area.max_size);
blake2b_update(S, (u8 *) &req.text_area.num_chars, sizeof req.text_area.num_chars);
@@ -1728,7 +1689,6 @@ static void graphics_request_hash_(Blake2b_State *S, Graphics_Request req) {
case GRAPHICS_DRAW_TEXT_CURSOR:
blake2b_update(S, (u8 *) &req.text_cursor.font, sizeof req.text_cursor.font);
- blake2b_update(S, (u8 *) &req.text_cursor.color, sizeof req.text_cursor.color);
blake2b_update(S, (u8 *) &req.text_cursor.area, sizeof req.text_cursor.area);
blake2b_update(S, (u8 *) &req.text_cursor.max_size, sizeof req.text_cursor.max_size);
blake2b_update(S, (u8 *) &req.text_cursor.num_chars, sizeof req.text_cursor.num_chars);
@@ -1759,20 +1719,6 @@ static Graphics_Request graphics_request_scaled_(Graphics_Request req, vec2 scal
Graphics_Request scaled = req;
switch (req.op) {
- case GRAPHICS_DRAW_PIXELS:
- scaled.pixels.area.x *= scale.x;
- scaled.pixels.area.y *= scale.y;
- scaled.pixels.area.width *= scale.x;
- scaled.pixels.area.height *= scale.y;
- break;
-
- case GRAPHICS_FILL_RECTANGLE:
- scaled.rectangle.area.x *= scale.x;
- scaled.rectangle.area.y *= scale.y;
- scaled.rectangle.area.width *= scale.x;
- scaled.rectangle.area.height *= scale.y;
- break;
-
case GRAPHICS_FILL_TRIANGLE:
scaled.triangle.vertices[0].x *= scale.x;
scaled.triangle.vertices[0].y *= scale.y;
@@ -1858,16 +1804,6 @@ static Graphics_Request graphics_request_moved_(Graphics_Request req, vec2 offse
Graphics_Request moved = req;
switch (req.op) {
- case GRAPHICS_DRAW_PIXELS:
- moved.pixels.area.x += offset.x;
- moved.pixels.area.y += offset.y;
- break;
-
- case GRAPHICS_FILL_RECTANGLE:
- moved.rectangle.area.x += offset.x;
- moved.rectangle.area.y += offset.y;
- break;
-
case GRAPHICS_FILL_TRIANGLE:
moved.triangle.vertices[0].x += offset.x;
moved.triangle.vertices[0].y += offset.y;
@@ -1942,8 +1878,6 @@ static Box graphics_request_area_(Graphics_Request req) {
Box area = {0};
switch (req.op) {
- case GRAPHICS_DRAW_PIXELS: area = req.pixels .area; break;
- case GRAPHICS_FILL_RECTANGLE: area = req.rectangle .area; break;
case GRAPHICS_FILL_ELLIPSE: area = req.ellipse .area; break;
case GRAPHICS_DRAW_TEXT_AREA: area = req.text_area .area; break;
case GRAPHICS_DRAW_TEXT_CURSOR: area = req.text_cursor.area; break;
@@ -2009,103 +1943,75 @@ static Graphics_Request_Norm_ normalize_graphics_request_(Graphics_Request req)
};
}
-static void perform_graphics_request_to_buffer_(Pixel_Buffer dst, Graphics_Request req) {
- Box area = graphics_request_area_(req);
-
- i64 width = (i64) floor(area.width + 0.5);
- i64 height = (i64) floor(area.height + 0.5);
-
+static void perform_graphics_request_to_stencil_(Stencil_Buffer dst, Graphics_Request req) {
switch (req.op) {
- case GRAPHICS_DRAW_PIXELS:
- draw_pixels_to_buffer(
- dst,
- req.pixels.area,
- req.pixels.src
- );
- break;
-
- case GRAPHICS_FILL_RECTANGLE:
- fill_rectangle_to_buffer(
- dst,
- req.rectangle.color,
- req.rectangle.area
- );
- break;
-
case GRAPHICS_FILL_TRIANGLE:
- fill_triangle_to_buffer(
+ fill_triangle_to_stencil(
dst,
- req.triangle.color,
- req.triangle.vertices,
- default_stencil(width, height)
+ 255,
+ req.triangle.vertices
);
break;
case GRAPHICS_FILL_TRIANGLES:
- fill_triangles_to_buffer(
+ fill_triangles_to_stencil(
dst,
- req.triangles.color,
+ 255,
req.triangles.position,
req.triangles.scale,
req.triangles.num_triangles,
- req.triangles.vertices,
- default_stencil(width, height)
+ req.triangles.vertices
);
break;
case GRAPHICS_FILL_QUAD:
- fill_quad_to_buffer(
+ fill_quad_to_stencil(
dst,
- req.quad.color,
- req.quad.vertices,
- default_stencil(width, height)
+ 255,
+ req.quad.vertices
);
break;
case GRAPHICS_FILL_ELLIPSE:
- fill_ellipse_to_buffer(
+ fill_ellipse_to_stencil(
dst,
- req.ellipse.color,
- req.ellipse.area,
- default_stencil(width, height)
+ 255,
+ req.ellipse.area
);
break;
case GRAPHICS_FILL_LINE:
- fill_line_to_buffer(
+ fill_line_to_stencil(
dst,
- req.line.color,
+ 255,
req.line.vertices,
- req.line.width,
- default_stencil(width, height)
+ req.line.width
);
break;
case GRAPHICS_DRAW_TEXT_AREA:
- draw_text_area_to_buffer(
+ draw_text_area_to_stencil(
dst,
- req.text_area.color,
+ 255,
req.text_area.font,
req.text_area.area,
req.text_area.max_size,
req.text_area.num_chars,
- req.text_area.text,
- default_stencil(width, height)
+ req.text_area.text
);
break;
case GRAPHICS_DRAW_TEXT_CURSOR:
- draw_text_cursor_to_buffer(
+ draw_text_cursor_to_stencil(
dst,
- req.text_cursor.color,
+ 255,
req.text_cursor.font,
req.text_cursor.area,
req.text_cursor.max_size,
req.text_cursor.num_chars,
req.text_cursor.text,
req.text_cursor.cursor,
- req.text_cursor.selection,
- default_stencil(width, height)
+ req.text_cursor.selection
);
break;
@@ -2134,7 +2040,7 @@ static void copy_pixels_quick_(Pixel_Buffer dst, i64 x, i64 y, Pixel_Buffer src)
}
}
-static void perform_graphics_request_cached_(Pixel_Buffer dst, Graphics_Request req) {
+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;
@@ -2189,7 +2095,7 @@ static void perform_graphics_request_cached_(Pixel_Buffer dst, Graphics_Request
s->occupied = 0;
else {
mem_set_(s->buffer, 0, s->buffer_len * sizeof *s->buffer);
- perform_graphics_request_to_buffer_((Pixel_Buffer) {
+ perform_graphics_request_to_stencil_((Stencil_Buffer) {
.width = s->width,
.height = s->height,
.stride = s->width,
@@ -2198,24 +2104,46 @@ static void perform_graphics_request_cached_(Pixel_Buffer dst, Graphics_Request
}
}
+ Box area = {
+ .x = norm.x,
+ .y = norm.y,
+ .width = norm.width,
+ .height = norm.height,
+ };
+
+ Stencil_Buffer stencil = {0};
+
if (s->occupied)
- copy_pixels_quick_(dst, norm.x, norm.y, (Pixel_Buffer) {
+ stencil = (Stencil_Buffer) {
.width = s->width,
.height = s->height,
.stride = s->width,
.pixels = s->buffer,
- });
- else
- perform_graphics_request_to_buffer_(dst, req);
+ };
+ else {
+ stencil = default_stencil(norm.width, norm.height);
+ perform_graphics_request_to_stencil_(stencil, norm.req);
+ }
+
+ 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);
- if (context.disable_cache)
- perform_graphics_request_to_buffer_(context.dst, scaled);
- else
- perform_graphics_request_cached_(context.dst, scaled);
+ 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,
+ .y = norm.y,
+ .width = norm.width,
+ .height = norm.height,
+ };
+ 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) {
@@ -2237,39 +2165,12 @@ static Graphics_Context graphics_context_defaults_(Graphics_Context context) {
return context;
}
-void draw_pixels_cached(Box area, Pixel_Buffer src) {
- perform_graphics_request(
- (Graphics_Context) {0},
- (Graphics_Request) {
- .op = GRAPHICS_DRAW_PIXELS,
- .pixels = {
- .area = area,
- .src = src,
- },
- }
- );
-}
-
-void fill_rectangle_cached(vec4_f32 color, Box area) {
- perform_graphics_request(
- (Graphics_Context) {0},
- (Graphics_Request) {
- .op = GRAPHICS_FILL_RECTANGLE,
- .rectangle = {
- .color = color,
- .area = area,
- },
- }
- );
-}
-
void fill_triangle_cached(vec4_f32 color, vec2 vertices[3]) {
perform_graphics_request(
(Graphics_Context) {0},
(Graphics_Request) {
.op = GRAPHICS_FILL_TRIANGLE,
.triangle = {
- .color = color,
.vertices = {
vertices[0],
vertices[1],
@@ -2286,7 +2187,6 @@ void fill_triangles_cached(vec4_f32 color, vec2 position, vec2 scale, i64 num_tr
(Graphics_Request) {
.op = GRAPHICS_FILL_TRIANGLES,
.triangles = {
- .color = color,
.position = position,
.scale = scale,
.num_triangles = num_triangles,
@@ -2302,7 +2202,6 @@ void fill_quad_cached(vec4_f32 color, vec2 vertices[4]) {
(Graphics_Request) {
.op = GRAPHICS_FILL_QUAD,
.quad = {
- .color = color,
.vertices = {
vertices[0],
vertices[1],
@@ -2320,8 +2219,7 @@ void fill_ellipse_cached(vec4_f32 color, Box area) {
(Graphics_Request) {
.op = GRAPHICS_FILL_ELLIPSE,
.ellipse = {
- .color = color,
- .area = area,
+ .area = area,
},
}
);
@@ -2333,7 +2231,6 @@ void fill_line_cached(vec4_f32 color, vec2 vertices[2], f64 width) {
(Graphics_Request) {
.op = GRAPHICS_FILL_LINE,
.line = {
- .color = color,
.vertices = { vertices[0], vertices[1], },
.width = width,
},
@@ -2348,7 +2245,6 @@ void draw_text_area_cached(i32 font, vec4_f32 color, Box area, vec2 max_size, i6
.op = GRAPHICS_DRAW_TEXT_AREA,
.text_area = {
.font = font,
- .color = color,
.area = area,
.max_size = max_size,
.num_chars = num_chars,
@@ -2365,7 +2261,6 @@ void draw_text_cursor_cached(i32 font, vec4_f32 color, Box area, vec2 max_size,
.op = GRAPHICS_DRAW_TEXT_CURSOR,
.text_cursor = {
.font = font,
- .color = color,
.area = area,
.max_size = max_size,
.num_chars = num_chars,
@@ -2377,30 +2272,23 @@ void draw_text_cursor_cached(i32 font, vec4_f32 color, Box area, vec2 max_size,
);
}
+Box area_scaled_(Box area, vec2 scale) {
+ return (Box) {
+ .x = area.x * scale.x,
+ .y = area.y * scale.y,
+ .width = area.width * scale.x,
+ .height = area.height * scale.y,
+ };
+}
+
void draw_pixels(Box area, Pixel_Buffer src) {
- perform_graphics_request(
- (Graphics_Context) { .disable_cache = 1, },
- (Graphics_Request) {
- .op = GRAPHICS_DRAW_PIXELS,
- .pixels = {
- .area = area,
- .src = src,
- },
- }
- );
+ Graphics_Context context = graphics_context_defaults_((Graphics_Context) {0});
+ draw_pixels_to_buffer(context.dst, area_scaled_(area, context.scale), src);
}
void fill_rectangle(vec4_f32 color, Box area) {
- perform_graphics_request(
- (Graphics_Context) { .disable_cache = 1, },
- (Graphics_Request) {
- .op = GRAPHICS_FILL_RECTANGLE,
- .rectangle = {
- .color = color,
- .area = area,
- },
- }
- );
+ Graphics_Context context = graphics_context_defaults_((Graphics_Context) {0});
+ fill_rectangle_to_buffer(context.dst, color, area_scaled_(area, context.scale));
}
void fill_triangle(vec4_f32 color, vec2 vertices[3]) {
@@ -2409,7 +2297,6 @@ void fill_triangle(vec4_f32 color, vec2 vertices[3]) {
(Graphics_Request) {
.op = GRAPHICS_FILL_TRIANGLE,
.triangle = {
- .color = color,
.vertices = {
vertices[0],
vertices[1],
@@ -2426,7 +2313,6 @@ void fill_triangles(vec4_f32 color, vec2 position, vec2 scale, i64 num_triangles
(Graphics_Request) {
.op = GRAPHICS_FILL_TRIANGLES,
.triangles = {
- .color = color,
.position = position,
.scale = scale,
.num_triangles = num_triangles,
@@ -2442,7 +2328,6 @@ void fill_quad(vec4_f32 color, vec2 vertices[4]) {
(Graphics_Request) {
.op = GRAPHICS_FILL_QUAD,
.quad = {
- .color = color,
.vertices = {
vertices[0],
vertices[1],
@@ -2460,8 +2345,7 @@ void fill_ellipse(vec4_f32 color, Box area) {
(Graphics_Request) {
.op = GRAPHICS_FILL_ELLIPSE,
.ellipse = {
- .color = color,
- .area = area,
+ .area = area,
},
}
);
@@ -2473,7 +2357,6 @@ void fill_line(vec4_f32 color, vec2 vertices[2], f64 width) {
(Graphics_Request) {
.op = GRAPHICS_FILL_LINE,
.line = {
- .color = color,
.vertices = { vertices[0], vertices[1], },
.width = width,
},
@@ -2488,7 +2371,6 @@ void draw_text_area(i32 font, vec4_f32 color, Box area, vec2 max_size, i64 num_c
.op = GRAPHICS_DRAW_TEXT_AREA,
.text_area = {
.font = font,
- .color = color,
.area = area,
.max_size = max_size,
.num_chars = num_chars,
@@ -2505,7 +2387,6 @@ void draw_text_cursor(i32 font, vec4_f32 color, Box area, vec2 max_size, i64 num
.op = GRAPHICS_DRAW_TEXT_CURSOR,
.text_cursor = {
.font = font,
- .color = color,
.area = area,
.max_size = max_size,
.num_chars = num_chars,
@@ -3802,6 +3683,10 @@ TEST("scale up aliasing underflow") {
REQUIRE(ok);
}
+TEST("cached requests") {
+ // TODO
+}
+
#undef TEST_FILE
#endif // ENABLE_TESTING