summaryrefslogtreecommitdiff
path: root/shared-module/displayio
diff options
context:
space:
mode:
authorsommersoft <sommersoft@gmail.com>2019-08-19 21:23:27 -0500
committersommersoft <sommersoft@gmail.com>2019-08-19 21:23:27 -0500
commit1b2996a75ea4ba6d6d8b20cebb749d5f18a83049 (patch)
tree1e4cfe0343280227f36d5fcbbc4e45983cb6c0f0 /shared-module/displayio
parent17190ae63e8a5fb43c99ca7f1f91bf684bdbc16e (diff)
parent0ddfbb0c20432458cc8020ab5ad7538e6813b60b (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.c38
-rw-r--r--shared-module/displayio/Bitmap.h5
-rw-r--r--shared-module/displayio/Display.c25
-rw-r--r--shared-module/displayio/TileGrid.c32
-rw-r--r--shared-module/displayio/TileGrid.h3
-rw-r--r--shared-module/displayio/__init__.c6
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);
}
}