framebufferio: add dirty row tracking

This commit is contained in:
Jeff Epler 2020-08-06 14:51:52 -05:00
parent 5e4ed93415
commit 9c4f644641
3 changed files with 10 additions and 5 deletions

View File

@ -352,7 +352,8 @@ STATIC void rgbmatrix_rgbmatrix_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *
// These version exists so that the prototype matches the protocol, // These version exists so that the prototype matches the protocol,
// avoiding a type cast that can hide errors // avoiding a type cast that can hide errors
STATIC void rgbmatrix_rgbmatrix_swapbuffers(mp_obj_t self_in) { STATIC void rgbmatrix_rgbmatrix_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) {
(void)dirty_row_bitmap;
common_hal_rgbmatrix_rgbmatrix_refresh(self_in); common_hal_rgbmatrix_rgbmatrix_refresh(self_in);
} }

View File

@ -156,7 +156,8 @@ STATIC const displayio_area_t* _get_refresh_areas(framebufferio_framebufferdispl
return NULL; return NULL;
} }
STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const displayio_area_t* area) { #define MARK_ROW_DIRTY(r) (dirty_row_bitmask[r/8] = (1 << (r & 7)))
STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const displayio_area_t* area, uint8_t *dirty_row_bitmask) {
uint16_t buffer_size = 128; // In uint32_ts uint16_t buffer_size = 128; // In uint32_ts
displayio_area_t clipped; displayio_area_t clipped;
@ -235,6 +236,7 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di
for (uint16_t i = subrectangle.y1; i < subrectangle.y2; i++) { for (uint16_t i = subrectangle.y1; i < subrectangle.y2; i++) {
assert(dest >= buf && dest < endbuf && dest+rowsize <= endbuf); assert(dest >= buf && dest < endbuf && dest+rowsize <= endbuf);
MARK_ROW_DIRTY(i);
memcpy(dest, src, rowsize); memcpy(dest, src, rowsize);
dest += rowstride; dest += rowstride;
src += rowsize; src += rowsize;
@ -251,12 +253,14 @@ STATIC void _refresh_display(framebufferio_framebufferdisplay_obj_t* self) {
displayio_display_core_start_refresh(&self->core); displayio_display_core_start_refresh(&self->core);
const displayio_area_t* current_area = _get_refresh_areas(self); const displayio_area_t* current_area = _get_refresh_areas(self);
if (current_area) { if (current_area) {
uint8_t dirty_row_bitmask[(self->core.height + 7) / 8];
memset(dirty_row_bitmask, 0, sizeof(dirty_row_bitmask));
self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo); self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo);
while (current_area != NULL) { while (current_area != NULL) {
_refresh_area(self, current_area); _refresh_area(self, current_area, dirty_row_bitmask);
current_area = current_area->next; current_area = current_area->next;
} }
self->framebuffer_protocol->swapbuffers(self->framebuffer); self->framebuffer_protocol->swapbuffers(self->framebuffer, dirty_row_bitmask);
} }
displayio_display_core_finish_refresh(&self->core); displayio_display_core_finish_refresh(&self->core);
} }

View File

@ -79,7 +79,7 @@ typedef int (*framebuffer_get_width_fun)(mp_obj_t);
typedef mp_float_t (*framebuffer_get_brightness_fun)(mp_obj_t); typedef mp_float_t (*framebuffer_get_brightness_fun)(mp_obj_t);
typedef void (*framebuffer_deinit_fun)(mp_obj_t); typedef void (*framebuffer_deinit_fun)(mp_obj_t);
typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo); typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo);
typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t); typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t, uint8_t *dirty_row_bitmask);
typedef struct _framebuffer_p_t { typedef struct _framebuffer_p_t {
MP_PROTOCOL_HEAD // MP_QSTR_protocol_framebuffer MP_PROTOCOL_HEAD // MP_QSTR_protocol_framebuffer