aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-06-04 14:30:06 +0200
committerBad Diode <bd@badd10de.dev>2021-06-04 14:30:06 +0200
commitef15a89a8cf161241c3c382e0e332427e46be8a9 (patch)
treee18ace788ed3d29c7c3682582359b8bcd29325e2 /src
parentf3f221524e6be30217838661b4750820a7bebecf (diff)
downloadstepper-ef15a89a8cf161241c3c382e0e332427e46be8a9.tar.gz
stepper-ef15a89a8cf161241c3c382e0e332427e46be8a9.zip
Add more perf improvements to draw rect
Diffstat (limited to 'src')
-rw-r--r--src/renderer.c51
-rw-r--r--src/renderer.h5
2 files changed, 41 insertions, 15 deletions
diff --git a/src/renderer.c b/src/renderer.c
index 51647cb..c66b87b 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -26,7 +26,7 @@ static u32 dirty_tiles[21] = {0};
26 26
27IWRAM_CODE 27IWRAM_CODE
28void 28void
29draw_pixel(u16 x, u16 y, u8 color) { 29draw_pixel(size_t x, size_t y, u8 color) {
30 BOUNDCHECK_SCREEN(x, y); 30 BOUNDCHECK_SCREEN(x, y);
31 31
32 // Find row position for the given x/y coordinates. 32 // Find row position for the given x/y coordinates.
@@ -46,7 +46,7 @@ draw_pixel(u16 x, u16 y, u8 color) {
46 46
47IWRAM_CODE 47IWRAM_CODE
48void 48void
49draw_rect(int x0, int y0, int x1, int y1, u8 clr) { 49draw_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) {
50 BOUNDCHECK_SCREEN(x0, y0); 50 BOUNDCHECK_SCREEN(x0, y0);
51 BOUNDCHECK_SCREEN(x1, y1); 51 BOUNDCHECK_SCREEN(x1, y1);
52 52
@@ -64,8 +64,8 @@ draw_rect(int x0, int y0, int x1, int y1, u8 clr) {
64 u32 *backbuffer0 = &BACKBUF[start_row0 + (tile_x0 + tile_y0 * 32) * 8]; 64 u32 *backbuffer0 = &BACKBUF[start_row0 + (tile_x0 + tile_y0 * 32) * 8];
65 u32 *backbuffer1 = &BACKBUF[start_row1 + (tile_x0 + tile_y1 * 32) * 8]; 65 u32 *backbuffer1 = &BACKBUF[start_row1 + (tile_x0 + tile_y1 * 32) * 8];
66 66
67 u16 dx = tile_x1 - tile_x0; 67 size_t dx = tile_x1 - tile_x0;
68 u16 dy = y1 - y0; 68 size_t dy = tile_y1 - tile_y0;
69 69
70 // There are 3 cases: 70 // There are 3 cases:
71 // 1. Lines fit on a single tile. 71 // 1. Lines fit on a single tile.
@@ -93,24 +93,49 @@ draw_rect(int x0, int y0, int x1, int y1, u8 clr) {
93 for (size_t i = 1; i < dx; i++) { 93 for (size_t i = 1; i < dx; i++) {
94 backbuffer0[i * 8] = row; 94 backbuffer0[i * 8] = row;
95 backbuffer1[i * 8] = row; 95 backbuffer1[i * 8] = row;
96 dirty_tiles[tile_y0] |= 1 << tile_x0 + i; 96 dirty_tiles[tile_y0] |= 1 << (tile_x0 + i);
97 dirty_tiles[tile_y1] |= 1 << tile_x0 + i; 97 dirty_tiles[tile_y1] |= 1 << (tile_x0 + i);
98 } 98 }
99 backbuffer0[dx * 8] = (backbuffer0[dx * 8] & ~(row_mask >> shift_right)) | (row >> shift_right); 99 backbuffer0[dx * 8] = (backbuffer0[dx * 8] & ~(row_mask >> shift_right)) | (row >> shift_right);
100 backbuffer1[dx * 8] = (backbuffer1[dx * 8] & ~(row_mask >> shift_right)) | (row >> shift_right); 100 backbuffer1[dx * 8] = (backbuffer1[dx * 8] & ~(row_mask >> shift_right)) | (row >> shift_right);
101 dirty_tiles[tile_y0] |= 1 << tile_x0 + dx; 101 dirty_tiles[tile_y0] |= 1 << (tile_x0 + dx);
102 dirty_tiles[tile_y1] |= 1 << tile_x0 + dx; 102 dirty_tiles[tile_y1] |= 1 << (tile_x0 + dx);
103 } 103 }
104 // The vertical line cases are analogous to the horizontal cases. 104 // The vertical line cases are analogous to the horizontal ones.
105 for (int i = 1; i < dy; ++i) { 105 u32 row_mask_left = 0xF << start_col0 * 4;
106 draw_pixel(x0, y0 + i, clr); 106 u32 row_mask_right = 0xF << start_col1 * 4;
107 draw_pixel(x1, y0 + i, clr); 107 u32 row_left = (0x11111111 * clr) & row_mask_left;
108 u32 row_right = (0x11111111 * clr) & row_mask_right;
109 if (dy < 1) {
110 for (size_t i = 1; i < y1 - y0; i++, backbuffer0++) {
111 backbuffer0[1] = (backbuffer0[1] & ~row_mask_left) | row_left;
112 backbuffer0[1 + 8 * dx] = (backbuffer0[1 + 8 * dx] & ~row_mask_right) | row_right;
113 }
114 } else {
115 for (size_t i = 1; i < (8 - start_row0); i++, backbuffer0++) {
116 backbuffer0[1] = (backbuffer0[1] & ~row_mask_left) | row_left;
117 backbuffer0[1 + 8 * dx] = (backbuffer0[1 + 8 * dx] & ~row_mask_right) | row_right;
118 }
119 backbuffer0 += 8 * 31;
120 for (size_t j = 1; j < dy; j++) {
121 for (size_t i = 0; i < 8; i++, backbuffer0++) {
122 backbuffer0[1] = (backbuffer0[1] & ~row_mask_left) | row_left;
123 backbuffer0[1 + 8 * dx] = (backbuffer0[1 + 8 * dx] & ~row_mask_right) | row_right;
124 }
125 backbuffer0 += 8 * 31;
126 dirty_tiles[tile_y0 + j] |= 1 << tile_x0;
127 dirty_tiles[tile_y0 + j] |= 1 << (tile_x0 + dx);
128 }
129 for (size_t i = 0; i < start_row1; i++, backbuffer0++) {
130 backbuffer0[1] = (backbuffer0[1] & ~row_mask_left) | row_left;
131 backbuffer0[1 + 8 * dx] = (backbuffer0[1 + 8 * dx] & ~row_mask_right) | row_right;
132 }
108 } 133 }
109} 134}
110 135
111IWRAM_CODE 136IWRAM_CODE
112void 137void
113draw_tile(u16 x, u16 y, Tile *tile, bool merge) { 138draw_tile(size_t x, size_t y, Tile *tile, bool merge) {
114 BOUNDCHECK_SCREEN(x, y); 139 BOUNDCHECK_SCREEN(x, y);
115 140
116 // Find row position for the given x/y coordinates. 141 // Find row position for the given x/y coordinates.
diff --git a/src/renderer.h b/src/renderer.h
index f056f6a..fc2f6b3 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -28,8 +28,9 @@
28#define FONT_SB 15 28#define FONT_SB 15
29#define FONT_OFFSET 192 29#define FONT_OFFSET 192
30 30
31void draw_pixel(u16 x, u16 y, u8 color); 31void draw_pixel(size_t x, size_t y, u8 color);
32void draw_tile(u16 x, u16 y, Tile *tile, bool merge); 32void draw_tile(size_t x, size_t y, Tile *tile, bool merge);
33void draw_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr);
33void flip_buffer(void); 34void flip_buffer(void);
34void renderer_init(void); 35void renderer_init(void);
35 36