diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2025-04-26 10:21:23 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2025-04-26 10:21:23 +0200 |
commit | ba0e0ab384f26b276c7ed658a38fef196a3ff382 (patch) | |
tree | 0b195105e0d8a968fac7955cb77743896fdcf771 | |
parent | 7cac379388df5a551321e407c29256f92c3085b5 (diff) | |
download | reduced_system_layer-ba0e0ab384f26b276c7ed658a38fef196a3ff382.zip |
Use stencil in cache
-rw-r--r-- | graphics.c | 309 |
1 files changed, 97 insertions, 212 deletions
@@ -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 |