displaio: don't store group children native object

Since we want to expose the list of group's children to the user,
we should only have the original objects in it, without any other
additional data, and compute the native object as needed.
This commit is contained in:
Radomir Dopieralski 2021-02-20 23:04:06 +01:00
parent f4886a6f46
commit 6e0ce23f3e
3 changed files with 117 additions and 63 deletions

View File

@ -52,11 +52,18 @@ void common_hal_displayio_group_set_hidden(displayio_group_t* self, bool hidden)
return;
}
for (size_t i = 0; i < self->size; i++) {
mp_obj_t layer = self->children[i].native;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
mp_obj_t layer;
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
displayio_tilegrid_set_hidden_by_parent(layer, hidden);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
continue;
}
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
displayio_group_set_hidden_by_parent(layer, hidden);
continue;
}
}
}
@ -71,11 +78,18 @@ void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden)
return;
}
for (size_t i = 0; i < self->size; i++) {
mp_obj_t layer = self->children[i].native;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
mp_obj_t layer;
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
displayio_tilegrid_set_hidden_by_parent(layer, hidden);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
continue;
}
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
displayio_group_set_hidden_by_parent(layer, hidden);
continue;
}
}
}
@ -87,15 +101,21 @@ uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) {
bool displayio_group_get_previous_area(displayio_group_t *self, displayio_area_t* area) {
bool first = true;
for (size_t i = 0; i < self->size; i++) {
mp_obj_t layer = self->children[i].native;
mp_obj_t layer;
displayio_area_t layer_area;
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
if (!displayio_tilegrid_get_previous_area(layer, &layer_area)) {
continue;
}
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
if (!displayio_group_get_previous_area(layer, &layer_area)) {
continue;
} else {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
if (!displayio_group_get_previous_area(layer, &layer_area)) {
continue;
}
}
}
if (first) {
@ -121,17 +141,26 @@ static void _update_child_transforms(displayio_group_t* self) {
return;
}
for (size_t i = 0; i < self->size; i++) {
mp_obj_t layer = self->children[i].native;
mp_obj_t layer;
#if CIRCUITPY_VECTORIO
if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &vectorio_vector_shape_type);
if (layer != MP_OBJ_NULL) {
vectorio_vector_shape_update_transform(layer, &self->absolute_transform);
continue;
}
else
#endif
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
displayio_tilegrid_update_transform(layer, &self->absolute_transform);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
continue;
}
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
displayio_group_update_transform(layer, &self->absolute_transform);
continue;
}
}
}
@ -210,21 +239,17 @@ void common_hal_displayio_group_set_y(displayio_group_t* self, mp_int_t y) {
_update_child_transforms(self);
}
static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) {
static void _add_layer(displayio_group_t* self, mp_obj_t layer) {
mp_obj_t native_layer;
#if CIRCUITPY_VECTORIO
native_layer = mp_instance_cast_to_native_base(layer, &vectorio_vector_shape_type);
if (native_layer != MP_OBJ_NULL) {
vectorio_vector_shape_update_transform(native_layer, &self->absolute_transform);
return native_layer;
return;
}
#endif
native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type);
if (native_layer == MP_OBJ_NULL) {
native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type);
if (native_layer == MP_OBJ_NULL) {
mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass."));
}
native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type);
if (native_layer != MP_OBJ_NULL) {
displayio_tilegrid_t* tilegrid = native_layer;
if (tilegrid->in_group) {
mp_raise_ValueError(translate("Layer already in a group."));
@ -232,7 +257,10 @@ static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) {
tilegrid->in_group = true;
}
displayio_tilegrid_update_transform(tilegrid, &self->absolute_transform);
} else {
return;
}
native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type);
if (native_layer != MP_OBJ_NULL) {
displayio_group_t* group = native_layer;
if (group->in_group) {
mp_raise_ValueError(translate("Layer already in a group."));
@ -240,27 +268,34 @@ static mp_obj_t _add_layer(displayio_group_t* self, mp_obj_t layer) {
group->in_group = true;
}
displayio_group_update_transform(group, &self->absolute_transform);
return;
}
return native_layer;
mp_raise_ValueError(translate("Layer must be a Group or TileGrid subclass."));
}
static void _remove_layer(displayio_group_t* self, size_t index) {
mp_obj_t layer = self->children[index].native;
mp_obj_t layer;
displayio_area_t layer_area;
bool rendered_last_frame = false;
#if CIRCUITPY_VECTORIO
if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) {
layer = mp_instance_cast_to_native_base(
self->children[index].original, &vectorio_vector_shape_type);
if (layer != MP_OBJ_NULL) {
bool has_dirty_area = vectorio_vector_shape_get_dirty_area(layer, &layer_area);
rendered_last_frame = has_dirty_area;
vectorio_vector_shape_update_transform(layer, NULL);
}
else
#endif
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
layer = mp_instance_cast_to_native_base(
self->children[index].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
displayio_tilegrid_t* tilegrid = layer;
rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area);
displayio_tilegrid_update_transform(tilegrid, NULL);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
}
layer = mp_instance_cast_to_native_base(
self->children[index].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
displayio_group_t* group = layer;
rendered_last_frame = displayio_group_get_previous_area(group, &layer_area);
displayio_group_update_transform(group, NULL);
@ -280,12 +315,11 @@ void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp
if (self->size == self->max_size) {
mp_raise_RuntimeError(translate("Group full"));
}
mp_obj_t native_layer = _add_layer(self, layer);
_add_layer(self, layer);
// Shift everything right.
for (size_t i = self->size; i > index; i--) {
self->children[i] = self->children[i - 1];
}
self->children[index].native = native_layer;
self->children[index].original = layer;
self->size++;
}
@ -299,7 +333,6 @@ mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index) {
for (size_t i = index; i < self->size; i++) {
self->children[i] = self->children[i + 1];
}
self->children[self->size].native = NULL;
self->children[self->size].original = NULL;
return item;
}
@ -322,9 +355,8 @@ mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) {
}
void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) {
mp_obj_t native_layer = _add_layer(self, layer);
_add_layer(self, layer);
_remove_layer(self, index);
self->children[index].native = native_layer;
self->children[index].original = layer;
}
@ -341,47 +373,61 @@ void displayio_group_construct(displayio_group_t* self, displayio_group_child_t*
bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t* buffer) {
// Track if any of the layers finishes filling in the given area. We can ignore any remaining
// layers at that point.
bool full_coverage = false;
for (int32_t i = self->size - 1; i >= 0 ; i--) {
mp_obj_t layer = self->children[i].native;
mp_obj_t layer;
#if CIRCUITPY_VECTORIO
if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &vectorio_vector_shape_type);
if (layer != MP_OBJ_NULL) {
if (vectorio_vector_shape_fill_area(layer, colorspace, area, mask, buffer)) {
full_coverage = true;
break;
return true;
}
continue;
}
else
#endif
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
if (displayio_tilegrid_fill_area(layer, colorspace, area, mask, buffer)) {
full_coverage = true;
break;
return true;
}
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
continue;
}
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
if (displayio_group_fill_area(layer, colorspace, area, mask, buffer)) {
full_coverage = true;
break;
return true;
}
continue;
}
}
return full_coverage;
return false;
}
void displayio_group_finish_refresh(displayio_group_t *self) {
self->item_removed = false;
for (int32_t i = self->size - 1; i >= 0 ; i--) {
mp_obj_t layer = self->children[i].native;
mp_obj_t layer;
#if CIRCUITPY_VECTORIO
if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &vectorio_vector_shape_type);
if (layer != MP_OBJ_NULL) {
vectorio_vector_shape_finish_refresh(layer);
continue;
}
else
#endif
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
displayio_tilegrid_finish_refresh(layer);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
continue;
}
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
displayio_group_finish_refresh(layer);
continue;
}
}
}
@ -393,17 +439,26 @@ displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, dis
}
for (int32_t i = self->size - 1; i >= 0 ; i--) {
mp_obj_t layer = self->children[i].native;
mp_obj_t layer;
#if CIRCUITPY_VECTORIO
if (MP_OBJ_IS_TYPE(layer, &vectorio_vector_shape_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &vectorio_vector_shape_type);
if (layer != MP_OBJ_NULL) {
tail = vectorio_vector_shape_get_refresh_areas(layer, tail);
continue;
}
else
#endif
if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) {
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_tilegrid_type);
if (layer != MP_OBJ_NULL) {
tail = displayio_tilegrid_get_refresh_areas(layer, tail);
} else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) {
continue;
}
layer = mp_instance_cast_to_native_base(
self->children[i].original, &displayio_group_type);
if (layer != MP_OBJ_NULL) {
tail = displayio_group_get_refresh_areas(layer, tail);
continue;
}
}

View File

@ -35,7 +35,6 @@
#include "shared-module/displayio/Palette.h"
typedef struct {
mp_obj_t native;
mp_obj_t original;
} displayio_group_child_t;

View File

@ -272,13 +272,13 @@ displayio_tilegrid_t blinka_sprite = {
#if CIRCUITPY_TERMINALIO
#define CHILD_COUNT 2
displayio_group_child_t splash_children[2] = {
{&blinka_sprite, &blinka_sprite},
{&supervisor_terminal_text_grid, &supervisor_terminal_text_grid}
{&blinka_sprite},
{&supervisor_terminal_text_grid},
};
#else
#define CHILD_COUNT 1
displayio_group_child_t splash_children[1] = {
{&blinka_sprite, &blinka_sprite},
{&blinka_sprite},
};
#endif