From 3fad7de8db7f1f317ab6d00a00a82e406ec6fb33 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 16 May 2019 16:45:38 -0700 Subject: Rework the pixel computation to use areas This changes the displayio pixel computation from per-pixel to per-area. This is precursor work to updating portions of the screen (#1169). It should provide mild speedups because bounds checks are done once per area rather than once per pixel. Filling by area also allows TileGrid to maintain a row-associative fill pattern even when the display's refresh is orthogonal to it. --- shared-module/displayio/Group.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'shared-module/displayio/Group.c') diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 40f112bf1..c9be47f9a 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -134,32 +134,28 @@ void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* self->scale = scale; } -bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, uint16_t* pixel) { - x -= self->x; - y -= self->y; - // When we are scaled we need to substract all but one to ensure -scale to 0 divide down to -1. - // Normally -scale to scale both divide down to 0 because 0 is unsigned. - if (x < 0) { - x -= self->scale - 1; - } - if (y < 0) { - y -= self->scale - 1; - } - x /= self->scale; - y /= self->scale; +bool displayio_group_get_area(displayio_group_t *self, displayio_buffer_transform_t* transform, displayio_area_t* area, uint32_t* mask, uint32_t* buffer) { + displayio_area_shift(area, -self->x * transform->scale, -self->y * transform->scale); + transform->scale *= self->scale; + + bool full_coverage = false; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i].native; if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { - if (displayio_tilegrid_get_pixel(layer, x, y, pixel)) { - return true; + if (displayio_tilegrid_get_area(layer, transform, area, mask, buffer)) { + full_coverage = true; + break; } } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { - if (displayio_group_get_pixel(layer, x, y, pixel)) { - return true; + if (displayio_group_get_area(layer, transform, area, mask, buffer)) { + full_coverage = true; + break; } } } - return false; + transform->scale /= self->scale; + displayio_area_shift(area, self->x * transform->scale, self->y * transform->scale); + return full_coverage; } bool displayio_group_needs_refresh(displayio_group_t *self) { -- cgit v1.2.3