diff options
-rw-r--r-- | core.c | 10 | ||||
-rw-r--r-- | memview.c | 26 | ||||
-rw-r--r-- | memview.h | 2 |
3 files changed, 30 insertions, 8 deletions
@@ -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() { @@ -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; } @@ -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); |