From 0532ef17923e62842b43f10f643e5f64a8f70fc0 Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 16 Jun 2023 16:19:52 +0200 Subject: [PATCH] Attach command buffer to Renderer Window (#1472) --- src/api/renderer.c | 4 ++-- src/rencache.c | 49 ++++++++++++++++++++++------------------------ src/rencache.h | 4 ++-- src/renderer.c | 9 ++++----- src/renwindow.c | 6 ++++++ src/renwindow.h | 4 ++++ 6 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/api/renderer.c b/src/api/renderer.c index 1fade6a9..871e18a4 100644 --- a/src/api/renderer.c +++ b/src/api/renderer.c @@ -311,7 +311,7 @@ static int f_set_clip_rect(lua_State *L) { lua_Number w = luaL_checknumber(L, 3); lua_Number h = luaL_checknumber(L, 4); RenRect rect = rect_to_grid(x, y, w, h); - rencache_set_clip_rect(rect); + rencache_set_clip_rect(&window_renderer, rect); return 0; } @@ -323,7 +323,7 @@ static int f_draw_rect(lua_State *L) { lua_Number h = luaL_checknumber(L, 4); RenRect rect = rect_to_grid(x, y, w, h); RenColor color = checkcolor(L, 5, 255); - rencache_draw_rect(rect, color); + rencache_draw_rect(&window_renderer, rect, color); return 0; } diff --git a/src/rencache.c b/src/rencache.c index 52527969..d28ed543 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -65,10 +65,7 @@ static unsigned cells_buf2[CELLS_X * CELLS_Y]; static unsigned *cells_prev = cells_buf1; static unsigned *cells = cells_buf2; static RenRect rect_buf[CELLS_X * CELLS_Y / 2]; -size_t command_buf_size = 0; -uint8_t *command_buf = NULL; static bool resize_issue; -static int command_buf_idx; static RenRect screen_rect; static RenRect last_clip_rect; static bool show_debug; @@ -116,21 +113,21 @@ static RenRect merge_rects(RenRect a, RenRect b) { return (RenRect) { x1, y1, x2 - x1, y2 - y1 }; } -static bool expand_command_buffer() { - size_t new_size = command_buf_size * CMD_BUF_RESIZE_RATE; +static bool expand_command_buffer(RenWindow *window_renderer) { + size_t new_size = window_renderer->command_buf_size * CMD_BUF_RESIZE_RATE; if (new_size == 0) { new_size = CMD_BUF_INIT_SIZE; } - uint8_t *new_command_buf = realloc(command_buf, new_size); + uint8_t *new_command_buf = realloc(window_renderer->command_buf, new_size); if (!new_command_buf) { return false; } - command_buf_size = new_size; - command_buf = new_command_buf; + window_renderer->command_buf_size = new_size; + window_renderer->command_buf = new_command_buf; return true; } -static void* push_command(enum CommandType type, int size) { +static void* push_command(RenWindow *window_renderer, enum CommandType type, int size) { if (resize_issue) { // Don't push new commands as we had problems resizing the command buffer. // Let's wait for the next frame. @@ -139,17 +136,17 @@ static void* push_command(enum CommandType type, int size) { size_t alignment = alignof(max_align_t) - 1; size += COMMAND_BARE_SIZE; size = (size + alignment) & ~alignment; - int n = command_buf_idx + size; - while (n > command_buf_size) { - if (!expand_command_buffer()) { + int n = window_renderer->command_buf_idx + size; + while (n > window_renderer->command_buf_size) { + if (!expand_command_buffer(window_renderer)) { fprintf(stderr, "Warning: (" __FILE__ "): unable to resize command buffer (%zu)\n", - (size_t)(command_buf_size * CMD_BUF_RESIZE_RATE)); + (size_t)(window_renderer->command_buf_size * CMD_BUF_RESIZE_RATE)); resize_issue = true; return NULL; } } - Command *cmd = (Command*) (command_buf + command_buf_idx); - command_buf_idx = n; + Command *cmd = (Command*) (window_renderer->command_buf + window_renderer->command_buf_idx); + window_renderer->command_buf_idx = n; memset(cmd, 0, size); cmd->type = type; cmd->size = size; @@ -157,13 +154,13 @@ static void* push_command(enum CommandType type, int size) { } -static bool next_command(Command **prev) { +static bool next_command(RenWindow *window_renderer, Command **prev) { if (*prev == NULL) { - *prev = (Command*) command_buf; + *prev = (Command*) window_renderer->command_buf; } else { *prev = (Command*) (((char*) *prev) + (*prev)->size); } - return *prev != ((Command*) (command_buf + command_buf_idx)); + return *prev != ((Command*) (window_renderer->command_buf + window_renderer->command_buf_idx)); } @@ -172,8 +169,8 @@ void rencache_show_debug(bool enable) { } -void rencache_set_clip_rect(RenRect rect) { - SetClipCommand *cmd = push_command(SET_CLIP, sizeof(SetClipCommand)); +void rencache_set_clip_rect(RenWindow *window_renderer, RenRect rect) { + SetClipCommand *cmd = push_command(window_renderer, SET_CLIP, sizeof(SetClipCommand)); if (cmd) { cmd->rect = intersect_rects(rect, screen_rect); last_clip_rect = cmd->rect; @@ -181,11 +178,11 @@ void rencache_set_clip_rect(RenRect rect) { } -void rencache_draw_rect(RenRect rect, RenColor color) { +void rencache_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color) { if (rect.width == 0 || rect.height == 0 || !rects_overlap(last_clip_rect, rect)) { return; } - DrawRectCommand *cmd = push_command(DRAW_RECT, sizeof(DrawRectCommand)); + DrawRectCommand *cmd = push_command(window_renderer, DRAW_RECT, sizeof(DrawRectCommand)); if (cmd) { cmd->rect = rect; cmd->color = color; @@ -198,7 +195,7 @@ double rencache_draw_text(RenWindow *window_renderer, RenFont **fonts, const cha RenRect rect = { x, y, (int)width, ren_font_group_get_height(fonts) }; if (rects_overlap(last_clip_rect, rect)) { int sz = len + 1; - DrawTextCommand *cmd = push_command(DRAW_TEXT, sizeof(DrawTextCommand) + sz); + DrawTextCommand *cmd = push_command(window_renderer, DRAW_TEXT, sizeof(DrawTextCommand) + sz); if (cmd) { memcpy(cmd->text, text, sz); cmd->color = color; @@ -265,7 +262,7 @@ void rencache_end_frame(RenWindow *window_renderer) { /* update cells from commands */ Command *cmd = NULL; RenRect cr = screen_rect; - while (next_command(&cmd)) { + while (next_command(window_renderer, &cmd)) { /* cmd->command[0] should always be the Command rect */ if (cmd->type == SET_CLIP) { cr = cmd->command[0]; } RenRect r = intersect_rects(cmd->command[0], cr); @@ -308,7 +305,7 @@ void rencache_end_frame(RenWindow *window_renderer) { ren_set_clip_rect(window_renderer, r); cmd = NULL; - while (next_command(&cmd)) { + while (next_command(window_renderer, &cmd)) { SetClipCommand *ccmd = (SetClipCommand*)&cmd->command; DrawRectCommand *rcmd = (DrawRectCommand*)&cmd->command; DrawTextCommand *tcmd = (DrawTextCommand*)&cmd->command; @@ -341,6 +338,6 @@ void rencache_end_frame(RenWindow *window_renderer) { unsigned *tmp = cells; cells = cells_prev; cells_prev = tmp; - command_buf_idx = 0; + window_renderer->command_buf_idx = 0; } diff --git a/src/rencache.h b/src/rencache.h index d649de01..327671ec 100644 --- a/src/rencache.h +++ b/src/rencache.h @@ -6,8 +6,8 @@ #include "renderer.h" void rencache_show_debug(bool enable); -void rencache_set_clip_rect(RenRect rect); -void rencache_draw_rect(RenRect rect, RenColor color); +void rencache_set_clip_rect(RenWindow *window_renderer, RenRect rect); +void rencache_draw_rect(RenWindow *window_renderer, RenRect rect, RenColor color); double rencache_draw_text(RenWindow *window_renderer, RenFont **font, const char *text, size_t len, double x, int y, RenColor color); void rencache_invalidate(void); void rencache_begin_frame(RenWindow *window_renderer); diff --git a/src/renderer.c b/src/renderer.c index 854e10f4..5ce3424c 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -507,13 +507,11 @@ void ren_draw_rect(RenSurface *rs, RenRect rect, RenColor color) { /*************** Window Management ****************/ void ren_free_window_resources(RenWindow *window_renderer) { - extern uint8_t *command_buf; - extern size_t command_buf_size; renwin_free(window_renderer); SDL_FreeSurface(draw_rect_surface); - free(command_buf); - command_buf = NULL; - command_buf_size = 0; + free(window_renderer->command_buf); + window_renderer->command_buf = NULL; + window_renderer->command_buf_size = 0; } // TODO remove global and return RenWindow* @@ -526,6 +524,7 @@ void ren_init(SDL_Window *win) { } window_renderer.window = win; renwin_init_surface(&window_renderer); + renwin_init_command_buf(&window_renderer); renwin_clip_to_surface(&window_renderer); draw_rect_surface = SDL_CreateRGBSurface(0, 1, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); diff --git a/src/renwindow.c b/src/renwindow.c index 8ac8e56c..cdfab9a6 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -57,6 +57,12 @@ void renwin_init_surface(UNUSED RenWindow *ren) { #endif } +void renwin_init_command_buf(RenWindow *ren) { + ren->command_buf = NULL; + ren->command_buf_idx = 0; + ren->command_buf_size = 0; +} + static RenRect scaled_rect(const RenRect rect, const int scale) { return (RenRect) {rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale}; diff --git a/src/renwindow.h b/src/renwindow.h index 6b0b9eaa..a80586a0 100644 --- a/src/renwindow.h +++ b/src/renwindow.h @@ -3,6 +3,9 @@ struct RenWindow { SDL_Window *window; + uint8_t *command_buf; + size_t command_buf_idx; + size_t command_buf_size; #ifdef LITE_USE_SDL_RENDERER SDL_Renderer *renderer; SDL_Texture *texture; @@ -12,6 +15,7 @@ struct RenWindow { typedef struct RenWindow RenWindow; void renwin_init_surface(RenWindow *ren); +void renwin_init_command_buf(RenWindow *ren); void renwin_clip_to_surface(RenWindow *ren); void renwin_set_clip_rect(RenWindow *ren, RenRect rect); void renwin_resize_surface(RenWindow *ren);