From 0116b00e0334b692d662c065ec5d77df636b1bc5 Mon Sep 17 00:00:00 2001 From: the lemons Date: Mon, 6 Feb 2023 22:47:44 -0600 Subject: improve performance --- core.c | 10 +++++++--- memview.c | 26 ++++++++++++++++++++++---- memview.h | 2 +- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/core.c b/core.c index 97e0288..97953b0 100644 --- a/core.c +++ b/core.c @@ -146,18 +146,22 @@ static void handle_events() { switch (e.key.keysym.sym) { case SDLK_RIGHT: next_map(); + refresh = true; break; case SDLK_LEFT: prev_map(); + refresh = true; + break; + default: break; } default: break; } } - render_pages(viewer, pos_x, pos_y, - screen_width, screen_height, scale, refresh); - SDL_RenderPresent(renderer); + if (render_pages(viewer, pos_x, pos_y, + screen_width, screen_height, scale, refresh)) + SDL_RenderPresent(renderer); } void cleanup() { diff --git a/memview.c b/memview.c index c2af3ac..9acdd22 100644 --- a/memview.c +++ b/memview.c @@ -93,7 +93,18 @@ static void render_page(SDL_Texture *tex, uint8_t *data) { SDL_UnlockTexture(tex); } -void render_pages(struct viewer *v, +static uint64_t fnv(uint8_t *data, size_t size) { + uint64_t hash = 0xcbf29ce484222325; + for (size_t i = 0; i < size; i++) { + hash ^= data[i]; + hash *= 0x100000001b3; + } + return hash; +} + +static uint64_t hashes[1024] = {0}; + +bool render_pages(struct viewer *v, int x, int y, int width, int height, double scale, bool refresh) { int page_x = x / PAGE_WIDTH; int page_y = y / PAGE_HEIGHT; @@ -107,6 +118,7 @@ void render_pages(struct viewer *v, int view_width = width / page_width; int view_height = height / page_height; + bool present = false; for (int draw_y = -1; draw_y <= view_height + 1; draw_y++) { for (int draw_x = -1; draw_x <= view_width + 1; draw_x++) { SDL_Rect src = {0, 0, PAGE_WIDTH, PAGE_HEIGHT}; @@ -116,9 +128,15 @@ void render_pages(struct viewer *v, }; uintptr_t page = zorder(page_x + draw_x, page_y + draw_y); bool success = read_page(v->fd, page, v->page_buffer) != -1; - // TODO: unless refresh is true, do not redraw if page unaltered - render_page(v->page_texture, success ? v->page_buffer : NULL); - SDL_RenderCopy(v->renderer, v->page_texture, &src, &dest); + + uint64_t hash = fnv(v->page_buffer, success ? PAGE_SIZE : 0); + if (refresh || hashes[page % 1024] != hash) { + render_page(v->page_texture, success ? v->page_buffer : NULL); + SDL_RenderCopy(v->renderer, v->page_texture, &src, &dest); + present = true; + } + hashes[page % 1024] = hash; } } + return present; } diff --git a/memview.h b/memview.h index 186bfa8..2a73ec4 100644 --- a/memview.h +++ b/memview.h @@ -21,7 +21,7 @@ struct viewer; struct viewer *create_viewer(int fd, SDL_Renderer *renderer); void destroy_viewer(struct viewer *v); -void render_pages(struct viewer *v, +bool render_pages(struct viewer *v, int x, int y, int width, int height, double scale, bool refresh); void pencil(struct viewer *v, int x1, int y1, int x2, int y2, bool bit); -- cgit v1.2.3