Skip to content

Commit 121c6bc

Browse files
committed
Replace displaio.Group.children with a python list
This is a first go at it, done by naive replacing of all array operations with corresponding operations on the list. Note that there is a lot of unnecessary type conversions, here. Also, list_pop has been copied, because it's decalerd STATIC in py/objlist.h
1 parent 6e0ce23 commit 121c6bc

File tree

3 files changed

+82
-73
lines changed

3 files changed

+82
-73
lines changed

shared-module/displayio/Group.c

Lines changed: 66 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,31 @@
3333
#include "shared-bindings/vectorio/VectorShape.h"
3434
#endif
3535

36+
#include <string.h>
37+
#define LIST_MIN_ALLOC 4
38+
39+
STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) {
40+
mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_list));
41+
mp_obj_list_t *self = mp_instance_cast_to_native_base(args[0], &mp_type_list);
42+
if (self->len == 0) {
43+
mp_raise_IndexError_varg(translate("pop from empty %q"), MP_QSTR_list);
44+
}
45+
size_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false);
46+
mp_obj_t ret = self->items[index];
47+
self->len -= 1;
48+
memmove(self->items + index, self->items + index + 1, (self->len - index) * sizeof(mp_obj_t));
49+
// Clear stale pointer from slot which just got freed to prevent GC issues
50+
self->items[self->len] = MP_OBJ_NULL;
51+
if (self->alloc > LIST_MIN_ALLOC && self->alloc > 2 * self->len) {
52+
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc/2);
53+
self->alloc /= 2;
54+
}
55+
return ret;
56+
}
3657

3758
void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) {
38-
displayio_group_child_t* children = m_new(displayio_group_child_t, max_size);
39-
displayio_group_construct(self, children, max_size, scale, x, y);
59+
mp_obj_list_t *members = mp_obj_new_list(0, NULL);
60+
displayio_group_construct(self, members, scale, x, y);
4061
}
4162

4263
bool common_hal_displayio_group_get_hidden(displayio_group_t* self) {
@@ -51,16 +72,16 @@ void common_hal_displayio_group_set_hidden(displayio_group_t* self, bool hidden)
5172
if (self->hidden_by_parent) {
5273
return;
5374
}
54-
for (size_t i = 0; i < self->size; i++) {
75+
for (size_t i = 0; i < self->members->len; i++) {
5576
mp_obj_t layer;
5677
layer = mp_instance_cast_to_native_base(
57-
self->children[i].original, &displayio_tilegrid_type);
78+
self->members->items[i], &displayio_tilegrid_type);
5879
if (layer != MP_OBJ_NULL) {
5980
displayio_tilegrid_set_hidden_by_parent(layer, hidden);
6081
continue;
6182
}
6283
layer = mp_instance_cast_to_native_base(
63-
self->children[i].original, &displayio_group_type);
84+
self->members->items[i], &displayio_group_type);
6485
if (layer != MP_OBJ_NULL) {
6586
displayio_group_set_hidden_by_parent(layer, hidden);
6687
continue;
@@ -77,16 +98,16 @@ void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden)
7798
if (self->hidden) {
7899
return;
79100
}
80-
for (size_t i = 0; i < self->size; i++) {
101+
for (size_t i = 0; i < self->members->len; i++) {
81102
mp_obj_t layer;
82103
layer = mp_instance_cast_to_native_base(
83-
self->children[i].original, &displayio_tilegrid_type);
104+
self->members->items[i], &displayio_tilegrid_type);
84105
if (layer != MP_OBJ_NULL) {
85106
displayio_tilegrid_set_hidden_by_parent(layer, hidden);
86107
continue;
87108
}
88109
layer = mp_instance_cast_to_native_base(
89-
self->children[i].original, &displayio_group_type);
110+
self->members->items[i], &displayio_group_type);
90111
if (layer != MP_OBJ_NULL) {
91112
displayio_group_set_hidden_by_parent(layer, hidden);
92113
continue;
@@ -100,18 +121,18 @@ uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self) {
100121

101122
bool displayio_group_get_previous_area(displayio_group_t *self, displayio_area_t* area) {
102123
bool first = true;
103-
for (size_t i = 0; i < self->size; i++) {
124+
for (size_t i = 0; i < self->members->len; i++) {
104125
mp_obj_t layer;
105126
displayio_area_t layer_area;
106127
layer = mp_instance_cast_to_native_base(
107-
self->children[i].original, &displayio_tilegrid_type);
128+
self->members->items[i], &displayio_tilegrid_type);
108129
if (layer != MP_OBJ_NULL) {
109130
if (!displayio_tilegrid_get_previous_area(layer, &layer_area)) {
110131
continue;
111132
}
112133
} else {
113134
layer = mp_instance_cast_to_native_base(
114-
self->children[i].original, &displayio_group_type);
135+
self->members->items[i], &displayio_group_type);
115136
if (layer != MP_OBJ_NULL) {
116137
if (!displayio_group_get_previous_area(layer, &layer_area)) {
117138
continue;
@@ -140,24 +161,24 @@ static void _update_child_transforms(displayio_group_t* self) {
140161
if (!self->in_group) {
141162
return;
142163
}
143-
for (size_t i = 0; i < self->size; i++) {
164+
for (size_t i = 0; i < self->members->len; i++) {
144165
mp_obj_t layer;
145166
#if CIRCUITPY_VECTORIO
146167
layer = mp_instance_cast_to_native_base(
147-
self->children[i].original, &vectorio_vector_shape_type);
168+
self->members->items[i], &vectorio_vector_shape_type);
148169
if (layer != MP_OBJ_NULL) {
149170
vectorio_vector_shape_update_transform(layer, &self->absolute_transform);
150171
continue;
151172
}
152173
#endif
153174
layer = mp_instance_cast_to_native_base(
154-
self->children[i].original, &displayio_tilegrid_type);
175+
self->members->items[i], &displayio_tilegrid_type);
155176
if (layer != MP_OBJ_NULL) {
156177
displayio_tilegrid_update_transform(layer, &self->absolute_transform);
157178
continue;
158179
}
159180
layer = mp_instance_cast_to_native_base(
160-
self->children[i].original, &displayio_group_type);
181+
self->members->items[i], &displayio_group_type);
161182
if (layer != MP_OBJ_NULL) {
162183
displayio_group_update_transform(layer, &self->absolute_transform);
163184
continue;
@@ -279,22 +300,22 @@ static void _remove_layer(displayio_group_t* self, size_t index) {
279300
bool rendered_last_frame = false;
280301
#if CIRCUITPY_VECTORIO
281302
layer = mp_instance_cast_to_native_base(
282-
self->children[index].original, &vectorio_vector_shape_type);
303+
self->members->items[index], &vectorio_vector_shape_type);
283304
if (layer != MP_OBJ_NULL) {
284305
bool has_dirty_area = vectorio_vector_shape_get_dirty_area(layer, &layer_area);
285306
rendered_last_frame = has_dirty_area;
286307
vectorio_vector_shape_update_transform(layer, NULL);
287308
}
288309
#endif
289310
layer = mp_instance_cast_to_native_base(
290-
self->children[index].original, &displayio_tilegrid_type);
311+
self->members->items[index], &displayio_tilegrid_type);
291312
if (layer != MP_OBJ_NULL) {
292313
displayio_tilegrid_t* tilegrid = layer;
293314
rendered_last_frame = displayio_tilegrid_get_previous_area(tilegrid, &layer_area);
294315
displayio_tilegrid_update_transform(tilegrid, NULL);
295316
}
296317
layer = mp_instance_cast_to_native_base(
297-
self->children[index].original, &displayio_group_type);
318+
self->members->items[index], &displayio_group_type);
298319
if (layer != MP_OBJ_NULL) {
299320
displayio_group_t* group = layer;
300321
rendered_last_frame = displayio_group_get_previous_area(group, &layer_area);
@@ -312,59 +333,45 @@ static void _remove_layer(displayio_group_t* self, size_t index) {
312333
}
313334

314335
void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer) {
315-
if (self->size == self->max_size) {
316-
mp_raise_RuntimeError(translate("Group full"));
317-
}
318336
_add_layer(self, layer);
319-
// Shift everything right.
320-
for (size_t i = self->size; i > index; i--) {
321-
self->children[i] = self->children[i - 1];
337+
mp_obj_list_append(self->members, mp_const_none);
338+
for (size_t i = self->members->len - 1; i > index; i--) {
339+
self->members->items[i] = self->members->items[i - 1];
322340
}
323-
self->children[index].original = layer;
324-
self->size++;
341+
self->members->items[index] = layer;
325342
}
326343

327344
mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index) {
328-
self->size--;
329-
mp_obj_t item = self->children[index].original;
330345
_remove_layer(self, index);
331-
332-
// Shift everything left.
333-
for (size_t i = index; i < self->size; i++) {
334-
self->children[i] = self->children[i + 1];
335-
}
336-
self->children[self->size].original = NULL;
337-
return item;
346+
mp_obj_t args[] = {self->members, MP_OBJ_NEW_SMALL_INT(index)};
347+
return list_pop(2, args);
338348
}
339349

340350
mp_int_t common_hal_displayio_group_index(displayio_group_t* self, mp_obj_t layer) {
341-
for (size_t i = 0; i < self->size; i++) {
342-
if (self->children[i].original == layer) {
343-
return i;
344-
}
345-
}
346-
return -1;
351+
mp_obj_t args[] = {self->members, layer};
352+
mp_obj_t *index = mp_seq_index_obj(
353+
self->members->items, self->members->len, 2, args);
354+
return MP_OBJ_SMALL_INT_VALUE(index);
347355
}
348356

349357
size_t common_hal_displayio_group_get_len(displayio_group_t* self) {
350-
return self->size;
358+
return self->members->len;
351359
}
352360

353361
mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index) {
354-
return self->children[index].original;
362+
return self->members->items[index];
355363
}
356364

357365
void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer) {
358366
_add_layer(self, layer);
359367
_remove_layer(self, index);
360-
self->children[index].original = layer;
368+
mp_obj_list_store(self, MP_OBJ_NEW_SMALL_INT(index), layer);
361369
}
362370

363-
void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y) {
371+
void displayio_group_construct(displayio_group_t* self, mp_obj_list_t* members, uint32_t scale, mp_int_t x, mp_int_t y) {
364372
self->x = x;
365373
self->y = y;
366-
self->children = child_array;
367-
self->max_size = max_size;
374+
self->members = members;
368375
self->item_removed = false;
369376
self->scale = scale;
370377
self->in_group = false;
@@ -373,11 +380,11 @@ void displayio_group_construct(displayio_group_t* self, displayio_group_child_t*
373380
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) {
374381
// Track if any of the layers finishes filling in the given area. We can ignore any remaining
375382
// layers at that point.
376-
for (int32_t i = self->size - 1; i >= 0 ; i--) {
383+
for (int32_t i = self->members->len - 1; i >= 0 ; i--) {
377384
mp_obj_t layer;
378385
#if CIRCUITPY_VECTORIO
379386
layer = mp_instance_cast_to_native_base(
380-
self->children[i].original, &vectorio_vector_shape_type);
387+
self->members->items[i], &vectorio_vector_shape_type);
381388
if (layer != MP_OBJ_NULL) {
382389
if (vectorio_vector_shape_fill_area(layer, colorspace, area, mask, buffer)) {
383390
return true;
@@ -386,15 +393,15 @@ bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorsp
386393
}
387394
#endif
388395
layer = mp_instance_cast_to_native_base(
389-
self->children[i].original, &displayio_tilegrid_type);
396+
self->members->items[i], &displayio_tilegrid_type);
390397
if (layer != MP_OBJ_NULL) {
391398
if (displayio_tilegrid_fill_area(layer, colorspace, area, mask, buffer)) {
392399
return true;
393400
}
394401
continue;
395402
}
396403
layer = mp_instance_cast_to_native_base(
397-
self->children[i].original, &displayio_group_type);
404+
self->members->items[i], &displayio_group_type);
398405
if (layer != MP_OBJ_NULL) {
399406
if (displayio_group_fill_area(layer, colorspace, area, mask, buffer)) {
400407
return true;
@@ -407,24 +414,24 @@ bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorsp
407414

408415
void displayio_group_finish_refresh(displayio_group_t *self) {
409416
self->item_removed = false;
410-
for (int32_t i = self->size - 1; i >= 0 ; i--) {
417+
for (int32_t i = self->members->len - 1; i >= 0 ; i--) {
411418
mp_obj_t layer;
412419
#if CIRCUITPY_VECTORIO
413420
layer = mp_instance_cast_to_native_base(
414-
self->children[i].original, &vectorio_vector_shape_type);
421+
self->members->items[i], &vectorio_vector_shape_type);
415422
if (layer != MP_OBJ_NULL) {
416423
vectorio_vector_shape_finish_refresh(layer);
417424
continue;
418425
}
419426
#endif
420427
layer = mp_instance_cast_to_native_base(
421-
self->children[i].original, &displayio_tilegrid_type);
428+
self->members->items[i], &displayio_tilegrid_type);
422429
if (layer != MP_OBJ_NULL) {
423430
displayio_tilegrid_finish_refresh(layer);
424431
continue;
425432
}
426433
layer = mp_instance_cast_to_native_base(
427-
self->children[i].original, &displayio_group_type);
434+
self->members->items[i], &displayio_group_type);
428435
if (layer != MP_OBJ_NULL) {
429436
displayio_group_finish_refresh(layer);
430437
continue;
@@ -438,24 +445,24 @@ displayio_area_t* displayio_group_get_refresh_areas(displayio_group_t *self, dis
438445
tail = &self->dirty_area;
439446
}
440447

441-
for (int32_t i = self->size - 1; i >= 0 ; i--) {
448+
for (int32_t i = self->members->len - 1; i >= 0 ; i--) {
442449
mp_obj_t layer;
443450
#if CIRCUITPY_VECTORIO
444451
layer = mp_instance_cast_to_native_base(
445-
self->children[i].original, &vectorio_vector_shape_type);
452+
self->members->items[i], &vectorio_vector_shape_type);
446453
if (layer != MP_OBJ_NULL) {
447454
tail = vectorio_vector_shape_get_refresh_areas(layer, tail);
448455
continue;
449456
}
450457
#endif
451458
layer = mp_instance_cast_to_native_base(
452-
self->children[i].original, &displayio_tilegrid_type);
459+
self->members->items[i], &displayio_tilegrid_type);
453460
if (layer != MP_OBJ_NULL) {
454461
tail = displayio_tilegrid_get_refresh_areas(layer, tail);
455462
continue;
456463
}
457464
layer = mp_instance_cast_to_native_base(
458-
self->children[i].original, &displayio_group_type);
465+
self->members->items[i], &displayio_group_type);
459466
if (layer != MP_OBJ_NULL) {
460467
tail = displayio_group_get_refresh_areas(layer, tail);
461468
continue;

shared-module/displayio/Group.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <stdint.h>
3232

3333
#include "py/obj.h"
34+
#include "py/objlist.h"
3435
#include "shared-module/displayio/area.h"
3536
#include "shared-module/displayio/Palette.h"
3637

@@ -40,22 +41,20 @@ typedef struct {
4041

4142
typedef struct {
4243
mp_obj_base_t base;
43-
displayio_group_child_t* children;
44+
mp_obj_list_t *members;
4445
displayio_buffer_transform_t absolute_transform;
4546
displayio_area_t dirty_area; // Catch all for changed area
4647
int16_t x;
4748
int16_t y;
4849
uint16_t scale;
49-
uint16_t size;
50-
uint16_t max_size;
5150
bool item_removed :1;
5251
bool in_group :1;
5352
bool hidden :1;
5453
bool hidden_by_parent :1;
5554
uint8_t padding :4;
5655
} displayio_group_t;
5756

58-
void displayio_group_construct(displayio_group_t* self, displayio_group_child_t* child_array, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y);
57+
void displayio_group_construct(displayio_group_t* self, mp_obj_list_t* members, uint32_t scale, mp_int_t x, mp_int_t y);
5958
void displayio_group_set_hidden_by_parent(displayio_group_t *self, bool hidden);
6059
bool displayio_group_get_previous_area(displayio_group_t *group, displayio_area_t* area);
6160
bool displayio_group_fill_area(displayio_group_t *group, const _displayio_colorspace_t* colorspace, const displayio_area_t* area, uint32_t* mask, uint32_t *buffer);

supervisor/shared/display.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,20 @@ displayio_tilegrid_t blinka_sprite = {
270270
};
271271

272272
#if CIRCUITPY_TERMINALIO
273-
#define CHILD_COUNT 2
274-
displayio_group_child_t splash_children[2] = {
275-
{&blinka_sprite},
276-
{&supervisor_terminal_text_grid},
273+
mp_obj_t members[] = { &blinka_sprite, &supervisor_terminal_text_grid, };
274+
mp_obj_list_t splash_children = {
275+
.base = {.type = &mp_type_list },
276+
.alloc = 2,
277+
.len = 2,
278+
.items = members,
277279
};
278280
#else
279-
#define CHILD_COUNT 1
280-
displayio_group_child_t splash_children[1] = {
281-
{&blinka_sprite},
281+
mp_obj_t members[] = { &blinka_sprite };
282+
mp_obj_list_t splash_children = {
283+
.base = {.type = &mp_type_list },
284+
.alloc = 1,
285+
.len = 1,
286+
.items = members,
282287
};
283288
#endif
284289

@@ -287,9 +292,7 @@ displayio_group_t circuitpython_splash = {
287292
.x = 0,
288293
.y = 0,
289294
.scale = 2,
290-
.size = CHILD_COUNT,
291-
.max_size = CHILD_COUNT,
292-
.children = splash_children,
295+
.members = &splash_children,
293296
.item_removed = false,
294297
.in_group = false,
295298
.hidden = false,

0 commit comments

Comments
 (0)