summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2023-02-06 22:47:44 -0600
committerthe lemons <citrons@mondecitronne.com>2023-02-06 22:47:44 -0600
commit0116b00e0334b692d662c065ec5d77df636b1bc5 (patch)
tree4feb48e0665d7fbde1264bf2a4227a481751aff9
parent9dacba5dff4c599298af7aa09b2d5c58a58f0aff (diff)
improve performance
-rw-r--r--core.c10
-rw-r--r--memview.c26
-rw-r--r--memview.h2
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);