diff options
| author | sommersoft <sommersoft@gmail.com> | 2019-08-19 21:23:27 -0500 |
|---|---|---|
| committer | sommersoft <sommersoft@gmail.com> | 2019-08-19 21:23:27 -0500 |
| commit | 1b2996a75ea4ba6d6d8b20cebb749d5f18a83049 (patch) | |
| tree | 1e4cfe0343280227f36d5fcbbc4e45983cb6c0f0 /shared-module/displayio | |
| parent | 17190ae63e8a5fb43c99ca7f1f91bf684bdbc16e (diff) | |
| parent | 0ddfbb0c20432458cc8020ab5ad7538e6813b60b (diff) | |
Merge branch 'master' of https://github.com/adafruit/circuitpython into mixer_voice
Diffstat (limited to 'shared-module/displayio')
| -rw-r--r-- | shared-module/displayio/Bitmap.c | 38 | ||||
| -rw-r--r-- | shared-module/displayio/Bitmap.h | 5 | ||||
| -rw-r--r-- | shared-module/displayio/Display.c | 25 | ||||
| -rw-r--r-- | shared-module/displayio/TileGrid.c | 32 | ||||
| -rw-r--r-- | shared-module/displayio/TileGrid.h | 3 | ||||
| -rw-r--r-- | shared-module/displayio/__init__.c | 6 |
6 files changed, 95 insertions, 14 deletions
diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index f8dc24c15..59971d25c 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -63,6 +63,11 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi } self->x_mask = (1 << self->x_shift) - 1; // Used as a modulus on the x value self->bitmask = (1 << bits_per_value) - 1; + + self->dirty_area.x1 = 0; + self->dirty_area.x2 = width; + self->dirty_area.y1 = 0; + self->dirty_area.y2 = height; } uint16_t common_hal_displayio_bitmap_get_height(displayio_bitmap_t *self) { @@ -104,6 +109,26 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, if (self->read_only) { mp_raise_RuntimeError(translate("Read-only object")); } + // Update the dirty area. + if (self->dirty_area.x1 == self->dirty_area.x2) { + self->dirty_area.x1 = x; + self->dirty_area.x2 = x + 1; + self->dirty_area.y1 = y; + self->dirty_area.y2 = y + 1; + } else { + if (x < self->dirty_area.x1) { + self->dirty_area.x1 = x; + } else if (x >= self->dirty_area.x2) { + self->dirty_area.x2 = x + 1; + } + if (y < self->dirty_area.y1) { + self->dirty_area.y1 = y; + } else if (y >= self->dirty_area.y2) { + self->dirty_area.y2 = y + 1; + } + } + + // Update our data int32_t row_start = y * self->stride; uint32_t bytes_per_value = self->bits_per_value / 8; if (bytes_per_value < 1) { @@ -124,3 +149,16 @@ void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *self, int16_t x, } } } + +displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail) { + if (self->dirty_area.x1 == self->dirty_area.x2) { + return tail; + } + self->dirty_area.next = tail; + return &self->dirty_area; +} + +void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { + self->dirty_area.x1 = 0; + self->dirty_area.x2 = 0; +} diff --git a/shared-module/displayio/Bitmap.h b/shared-module/displayio/Bitmap.h index 48ca9e2cf..f4bd7ce4d 100644 --- a/shared-module/displayio/Bitmap.h +++ b/shared-module/displayio/Bitmap.h @@ -31,6 +31,7 @@ #include <stdint.h> #include "py/obj.h" +#include "shared-module/displayio/area.h" typedef struct { mp_obj_base_t base; @@ -41,8 +42,12 @@ typedef struct { uint8_t bits_per_value; uint8_t x_shift; size_t x_mask; + displayio_area_t dirty_area; uint16_t bitmask; bool read_only; } displayio_bitmap_t; +void displayio_bitmap_finish_refresh(displayio_bitmap_t *self); +displayio_area_t* displayio_bitmap_get_refresh_areas(displayio_bitmap_t *self, displayio_area_t* tail); + #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_BITMAP_H diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 51c6f292a..c23c66b8b 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -85,9 +85,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, uint32_t i = 0; while (!self->begin_transaction(self->bus)) { -#ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP ; -#endif + RUN_BACKGROUND_TASKS; } while (i < init_sequence_len) { uint8_t *cmd = init_sequence + i; @@ -199,19 +197,26 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { if (root_group == NULL) { - root_group = &circuitpython_splash; + if (!circuitpython_splash.in_group) { + root_group = &circuitpython_splash; + } else if (self->current_group == &circuitpython_splash) { + return false; + } } if (root_group == self->current_group) { return true; } - if (root_group->in_group) { + if (root_group != NULL && root_group->in_group) { return false; } if (self->current_group != NULL) { self->current_group->in_group = false; } - displayio_group_update_transform(root_group, &self->transform); - root_group->in_group = true; + + if (root_group != NULL) { + displayio_group_update_transform(root_group, &self->transform); + root_group->in_group = true; + } self->current_group = root_group; self->full_refresh = true; common_hal_displayio_display_refresh_soon(self); @@ -235,7 +240,7 @@ int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* sel uint64_t last_refresh = self->last_refresh; // Don't try to refresh if we got an exception. while (last_refresh == self->last_refresh && MP_STATE_VM(mp_pending_exception) == NULL) { - MICROPY_VM_HOOK_LOOP + RUN_BACKGROUND_TASKS; } return 0; } @@ -402,6 +407,10 @@ void displayio_display_update_backlight(displayio_display_obj_t* self) { } void release_display(displayio_display_obj_t* self) { + if (self->current_group != NULL) { + self->current_group->in_group = false; + } + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index fee2ae978..6144f8f99 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -26,6 +26,7 @@ #include "shared-bindings/displayio/TileGrid.h" +#include "py/runtime.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/OnDiskBitmap.h" @@ -33,7 +34,7 @@ #include "shared-bindings/displayio/Shape.h" void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, - uint16_t bitmap_width_in_tiles, + uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) { uint32_t total_tiles = width * height; @@ -54,6 +55,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->inline_tiles = false; } self->bitmap_width_in_tiles = bitmap_width_in_tiles; + self->tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles; self->width_in_tiles = width; self->height_in_tiles = height; self->x = x; @@ -204,6 +206,9 @@ uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint1 } void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) { + if (tile_index >= self->tiles_in_bitmap) { + mp_raise_ValueError(translate("Tile value out of bounds")); + } uint8_t* tiles = self->tiles; if (self->inline_tiles) { tiles = (uint8_t*) &self->tiles; @@ -462,6 +467,14 @@ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self) { } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type)) { displayio_colorconverter_finish_refresh(self->pixel_shader); } + if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + displayio_bitmap_finish_refresh(self->bitmap); + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { + // TODO: Support shape changes. + } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { + // OnDiskBitmap changes will trigger a complete reload so no need to + // track changes. + } // TODO(tannewt): We could double buffer changes to position and move them over here. // That way they won't change during a refresh and tear. } @@ -478,8 +491,21 @@ displayio_area_t* displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel return &self->current_area; } - // We must recheck if our sources require a refresh because needs_refresh may or may not have - // been called. + // If we have an in-memory bitmap, then check it for modifications. + if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { + displayio_area_t* refresh_area = displayio_bitmap_get_refresh_areas(self->bitmap, tail); + if (refresh_area != tail) { + // Special case a TileGrid that shows a full bitmap and use its + // dirty area. Copy it to ours so we can transform it. + if (self->tiles_in_bitmap == 1) { + displayio_area_copy(refresh_area, &self->dirty_area); + self->partial_change = true; + } else { + self->full_change = true; + } + } + } + self->full_change = self->full_change || (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) || diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index fb6033e9c..222aaed19 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -42,7 +42,8 @@ typedef struct { int16_t y; uint16_t pixel_width; uint16_t pixel_height; - uint16_t bitmap_width_in_tiles; + uint16_t bitmap_width_in_tiles;; + uint8_t tiles_in_bitmap; uint16_t width_in_tiles; uint16_t height_in_tiles; uint16_t tile_width; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 8f6e650a1..3e9c4aa2a 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -163,7 +163,7 @@ void displayio_refresh_displays(void) { void common_hal_displayio_release_displays(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; - if (bus_type == NULL) { + if (bus_type == NULL || bus_type == &mp_type_NoneType) { continue; } else if (bus_type == &displayio_fourwire_type) { common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); @@ -235,12 +235,14 @@ void reset_displays(void) { // Not an active display. continue; } + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { // Reset the displayed group. Only the first will get the terminal but // that's ok. displayio_display_obj_t* display = &displays[i].display; display->auto_brightness = true; - common_hal_displayio_display_show(display, &circuitpython_splash); + common_hal_displayio_display_show(display, NULL); } } |
