diff options
author | quou <quou@disroot.org> | 2025-01-19 22:31:04 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-01-19 22:31:04 +1100 |
commit | f68f2df575bca6e75cd8905e926ea823b1f379d5 (patch) | |
tree | 5fa40674882eb3a04562f5f0e70b0db20d0cb285 | |
parent | 74e8d3f0278a65fdf86a1185fec8a6016e628e88 (diff) |
Make the UI renderer more efficient
-rw-r--r-- | c2.cpp | 8 | ||||
-rw-r--r-- | ui.cpp | 29 | ||||
-rw-r--r-- | ui.hpp | 6 |
3 files changed, 24 insertions, 19 deletions
@@ -17,7 +17,7 @@ extern "C" { #define video_arena_size (1024 * 1024 * 16) #define asset_arena_size (1024 * 1024 * 4) -#define ui_arena_size (1024 * 1024 * 64) +#define ui_arena_size (1024 * 1024) #define scene_arena_size (1024) #define per_frame_memory_size (1024 * 1024) @@ -879,13 +879,13 @@ struct C2 : public App { ctx.debug_pop(); ctx.debug_push("ui"); - ui->render(&frame_arena); { int s = ui->ren.bound.w * ui->ren.bound.h * 4; void* pixels = dev->map_buffer(ui_buffer, 0, s); - memcpy(pixels, ui->ren.pixels, s); + bool dirty = ui->render(&frame_arena, pixels); dev->unmap_buffer(ui_buffer); - ctx.copy(ui_texture, ui_buffer); + if (dirty) + ctx.copy(ui_texture, ui_buffer); pb.begin_rp(); pb.rp_target(dev->get_backbuffer(), Clear_Mode::restore); @@ -310,8 +310,7 @@ void UI::Renderer::clear(const Rect& r) { } } -const App* g_app; -void UI::Renderer::flush(int x, int y) { +void UI::Renderer::flush_cell(int x, int y) { Cmd* cmd = (Cmd*)cmd_buf; Cmd* last = (Cmd*)(cmd_buf + cmd_buf_ptr); Rect cell = Rect( @@ -344,36 +343,43 @@ void UI::Renderer::flush(int x, int y) { } } -void UI::Renderer::flush() { +bool UI::Renderer::flush(void* target) { uint64_t* next = grid == grid_a? grid_b: grid_a; uint64_t* h = grid; uint64_t* p = next; + bool dirty = false; + pixels = (Colour*)target; int i, j; for (j = 0; j < grid_size; j++) { for (i = 0; i < grid_size; i++) { if (*p != *h) { - flush(i, j); + dirty = true; + flush_cell(i, j); } h++; p++; } } grid = next; + return dirty; } void UI::Renderer::resize(int w, int h) { - heap_free(arena, pixels); - pixels = (Colour*)heap_alloc(arena, w * h * sizeof *pixels); - assert(pixels != 0); + int i, e = grid_size * grid_size; + uint64_t* next = grid == grid_a? grid_b: grid_a; bound = Rect(0, 0, w, h); + for (i = 0; i < e; i++) + next[i] = 0; } void UI::Renderer::init(Heap* heap, int w, int h) { arena = heap; - pixels = (Colour*)heap_alloc(heap, w * h * sizeof *pixels); - assert(pixels != 0); + int i, e = grid_size * grid_size; + bound = Rect(0, 0, w, h); bound = Rect(0, 0, w, h); grid = grid_a; + for (i = 0; i < e; i++) + grid[i] = 0; } UI* UI::create( @@ -479,13 +485,12 @@ void UI::update(Arena* s) { layout(area.w, area.h); } -void UI::render(Arena* s) { +bool UI::render(Arena* s, void* pixels) { if (area.w != ren.bound.w || area.h != ren.bound.h) ren.resize(area.w, area.h); ren.reset(ren.bound); root->render(); - g_app = app; - ren.flush(); + return ren.flush(pixels); } void UI::draw_container(const Rect& bound, Colour c) { @@ -65,8 +65,8 @@ struct UI { void reset(const Rect& cl); void set_clip(const Rect& r); void clear(const Rect& r); - void flush(int x, int y); - void flush(); + void flush_cell(int x, int y); + bool flush(void* target); void resize(int w, int h); void init(Heap* heap, int w, int h); } ren; @@ -95,7 +95,7 @@ struct UI { void layout(int w, int h); void text_input(const char* buf); void update(Arena* s); - void render(Arena* s); + bool render(Arena* s, void* pixels); void draw_container(const Rect& r, Colour c); void draw_containeri(const Rect& r, Colour c); |