diff options
Diffstat (limited to 'memview.c')
-rw-r--r-- | memview.c | 26 |
1 files changed, 22 insertions, 4 deletions
@@ -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; } |