Skip to content

Commit fee3310

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents c60a5ae + bfa6e1d commit fee3310

3 files changed

Lines changed: 72 additions & 60 deletions

File tree

‎shared-module/busdisplay/BusDisplay.c‎

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are
233233
return true;
234234
}
235235
uint16_t rows_per_buffer = displayio_area_height(&clipped);
236+
uint16_t cols_per_buffer = displayio_area_width(&clipped);
236237
uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth;
237238
uint16_t pixels_per_buffer = displayio_area_size(&clipped);
238239

@@ -243,26 +244,29 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are
243244
subrectangles = rows_per_buffer / 8; // page addressing mode writes 8 rows at a time
244245
rows_per_buffer = 8;
245246
} else if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) {
246-
rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped);
247-
if (rows_per_buffer == 0) {
248-
rows_per_buffer = 1;
249-
}
250-
// If pixels are packed by column then ensure rows_per_buffer is on a byte boundary.
251-
if (self->core.colorspace.depth < 8 && !self->core.colorspace.pixels_in_byte_share_row) {
252-
uint8_t pixels_per_byte = 8 / self->core.colorspace.depth;
253-
if (rows_per_buffer % pixels_per_byte != 0) {
254-
rows_per_buffer -= rows_per_buffer % pixels_per_byte;
247+
uint16_t buffer_pixels = buffer_size * pixels_per_word;
248+
if (self->core.transform.transpose_xy && self->core.colorspace.depth >= 8) {
249+
// Rotated 90 or 270: a panel column is a source row. Send bands of columns so sources
250+
// are read along their rows, which OnDiskBitmap needs to avoid a file seek per pixel.
251+
rows_per_buffer = MIN(rows_per_buffer, buffer_pixels);
252+
cols_per_buffer = buffer_pixels / rows_per_buffer;
253+
} else {
254+
rows_per_buffer = buffer_pixels / cols_per_buffer;
255+
if (rows_per_buffer == 0) {
256+
rows_per_buffer = 1;
257+
}
258+
// If pixels are packed by column then ensure rows_per_buffer is on a byte boundary.
259+
if (self->core.colorspace.depth < 8 && !self->core.colorspace.pixels_in_byte_share_row) {
260+
uint8_t pixels_per_byte = 8 / self->core.colorspace.depth;
261+
if (rows_per_buffer % pixels_per_byte != 0) {
262+
rows_per_buffer -= rows_per_buffer % pixels_per_byte;
263+
}
255264
}
256265
}
257-
subrectangles = displayio_area_height(&clipped) / rows_per_buffer;
258-
if (displayio_area_height(&clipped) % rows_per_buffer != 0) {
259-
subrectangles++;
260-
}
261-
pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped);
262-
buffer_size = pixels_per_buffer / pixels_per_word;
263-
if (pixels_per_buffer % pixels_per_word) {
264-
buffer_size += 1;
265-
}
266+
subrectangles = ((displayio_area_height(&clipped) + rows_per_buffer - 1) / rows_per_buffer) *
267+
((displayio_area_width(&clipped) + cols_per_buffer - 1) / cols_per_buffer);
268+
pixels_per_buffer = rows_per_buffer * cols_per_buffer;
269+
buffer_size = (pixels_per_buffer + pixels_per_word - 1) / pixels_per_word;
266270
}
267271

268272
// Allocated and shared as a uint32_t array so the compiler knows the
@@ -271,19 +275,17 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are
271275
uint32_t buffer[buffer_size];
272276
uint32_t mask[mask_length];
273277

274-
uint16_t remaining_rows = displayio_area_height(&clipped);
278+
displayio_area_t subrectangle = clipped;
279+
subrectangle.next = NULL;
275280

276281
for (uint16_t j = 0; j < subrectangles; j++) {
277-
displayio_area_t subrectangle = {
278-
.x1 = clipped.x1,
279-
.y1 = clipped.y1 + rows_per_buffer * j,
280-
.x2 = clipped.x2,
281-
.y2 = clipped.y1 + rows_per_buffer * (j + 1)
282-
};
283-
if (remaining_rows < rows_per_buffer) {
284-
subrectangle.y2 = subrectangle.y1 + remaining_rows;
282+
// Down the rows of a band first, then to the next band of columns.
283+
if (subrectangle.y1 >= clipped.y2) {
284+
subrectangle.y1 = clipped.y1;
285+
subrectangle.x1 += cols_per_buffer;
285286
}
286-
remaining_rows -= rows_per_buffer;
287+
subrectangle.x2 = MIN(subrectangle.x1 + cols_per_buffer, clipped.x2);
288+
subrectangle.y2 = MIN(subrectangle.y1 + rows_per_buffer, clipped.y2);
287289

288290
uint16_t subrectangle_size_bytes;
289291
if (self->core.colorspace.depth >= 8) {
@@ -305,6 +307,7 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are
305307
}
306308
_send_pixels(self, (uint8_t *)buffer, subrectangle_size_bytes);
307309
displayio_display_bus_end_transaction(&self->bus);
310+
subrectangle.y1 = subrectangle.y2;
308311

309312
// Run background tasks so they can run during an explicit refresh.
310313
// Auto-refresh won't run background tasks here because it is a background task itself.

‎shared-module/displayio/OnDiskBitmap.c‎

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static uint32_t read_word(uint16_t *bmp_header, uint16_t index) {
2828

2929
void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, mp_obj_t file) {
3030
self->file = file;
31+
self->cache_len = 0;
3132
uint16_t bmp_header[69];
3233
int errcode = 0;
3334

@@ -182,43 +183,47 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s
182183
} else {
183184
location = self->data_offset + (self->height - y - 1) * self->stride + x / pixels_per_byte;
184185
}
185-
// We don't cache here because the underlying FS caches sectors.
186186
int errcode = 0;
187-
mp_stream_seek(self->file, location, MP_SEEK_SET, &errcode);
188-
if (errcode != 0) {
189-
return 0;
187+
if (location < self->cache_start || location + bytes_per_pixel > self->cache_start + self->cache_len) {
188+
mp_stream_seek(self->file, location, MP_SEEK_SET, &errcode);
189+
if (errcode != 0) {
190+
return 0;
191+
}
192+
self->cache_start = location;
193+
self->cache_len = mp_stream_rw(self->file, self->cache, sizeof(self->cache), &errcode, MP_STREAM_RW_ONCE);
194+
if (errcode != 0 || self->cache_len < bytes_per_pixel) {
195+
self->cache_len = 0;
196+
return 0;
197+
}
190198
}
191199
uint32_t pixel_data = 0;
192-
mp_stream_rw(self->file, &pixel_data, bytes_per_pixel, &errcode, MP_STREAM_RW_ONCE);
193-
if (errcode == 0) {
194-
uint32_t tmp = 0;
195-
uint8_t red;
196-
uint8_t green;
197-
uint8_t blue;
198-
if (bytes_per_pixel == 1) {
199-
uint8_t offset = (x % pixels_per_byte) * self->bits_per_pixel;
200-
uint8_t mask = (1 << self->bits_per_pixel) - 1;
201-
202-
return (pixel_data >> ((8 - self->bits_per_pixel) - offset)) & mask;
203-
} else if (bytes_per_pixel == 2) {
204-
if (self->g_bitmask == 0x07e0) { // 565
205-
red = ((pixel_data & self->r_bitmask) >> 11);
206-
green = ((pixel_data & self->g_bitmask) >> 5);
207-
blue = ((pixel_data & self->b_bitmask) >> 0);
208-
} else { // 555
209-
red = ((pixel_data & self->r_bitmask) >> 10);
210-
green = ((pixel_data & self->g_bitmask) >> 4);
211-
blue = ((pixel_data & self->b_bitmask) >> 0);
212-
}
213-
tmp = (red << 19 | green << 10 | blue << 3);
214-
return tmp;
215-
} else if ((bytes_per_pixel == 4) && (self->bitfield_compressed)) {
216-
return pixel_data & 0x00FFFFFF;
217-
} else {
218-
return pixel_data;
200+
memcpy(&pixel_data, self->cache + (location - self->cache_start), bytes_per_pixel);
201+
uint32_t tmp = 0;
202+
uint8_t red;
203+
uint8_t green;
204+
uint8_t blue;
205+
if (bytes_per_pixel == 1) {
206+
uint8_t offset = (x % pixels_per_byte) * self->bits_per_pixel;
207+
uint8_t mask = (1 << self->bits_per_pixel) - 1;
208+
209+
return (pixel_data >> ((8 - self->bits_per_pixel) - offset)) & mask;
210+
} else if (bytes_per_pixel == 2) {
211+
if (self->g_bitmask == 0x07e0) { // 565
212+
red = ((pixel_data & self->r_bitmask) >> 11);
213+
green = ((pixel_data & self->g_bitmask) >> 5);
214+
blue = ((pixel_data & self->b_bitmask) >> 0);
215+
} else { // 555
216+
red = ((pixel_data & self->r_bitmask) >> 10);
217+
green = ((pixel_data & self->g_bitmask) >> 4);
218+
blue = ((pixel_data & self->b_bitmask) >> 0);
219219
}
220+
tmp = (red << 19 | green << 10 | blue << 3);
221+
return tmp;
222+
} else if ((bytes_per_pixel == 4) && (self->bitfield_compressed)) {
223+
return pixel_data & 0x00FFFFFF;
224+
} else {
225+
return pixel_data;
220226
}
221-
return 0;
222227
}
223228

224229
uint16_t common_hal_displayio_ondiskbitmap_get_height(displayio_ondiskbitmap_t *self) {

‎shared-module/displayio/OnDiskBitmap.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ typedef struct {
2828
};
2929
bool bitfield_compressed;
3030
uint8_t bits_per_pixel;
31+
// The last bytes read from the file. Pixels are read along rows, so most reads hit it.
32+
uint8_t cache_len;
33+
uint32_t cache_start;
34+
uint8_t cache[64];
3135
} displayio_ondiskbitmap_t;

0 commit comments

Comments
 (0)