8000 Merge pull request #7209 from jepler/code-optimize-pixelbuf · kdb424/circuitpython@f637332 · GitHub
[go: up one dir, main page]

Skip to content

Commit f637332

Browse files
authored
Merge pull request adafruit#7209 from jepler/code-optimize-pixelbuf
Save code space by packing rgbw values into C union
2 parents 85ea801 + 14ba5a7 commit f637332

File tree

2 files changed

+37
-30
lines changed

2 files changed

+37
-30
lines changed

shared-bindings/adafruit_pixelbuf/PixelBuf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131

3232
extern const mp_obj_type_t pixelbuf_pixelbuf_type;
3333

34+
typedef union {
35+
struct {
36+
uint8_t r, g, b, w;
37+
};
38+
uint32_t rgbw;
39+
} color_u;
40+
3441
void common_hal_adafruit_pixelbuf_pixelbuf_construct(pixelbuf_pixelbuf_obj_t *self, size_t n,
3542
pixelbuf_byteorder_details_t *byteorder, mp_float_t brightness, bool auto_write, uint8_t *header,
3643
size_t header_len, uint8_t *trailer, size_t trailer_len);

shared-module/adafruit_pixelbuf/PixelBuf.c

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -143,59 +143,67 @@ void common_hal_adafruit_pixelbuf_pixelbuf_set_brightness(mp_obj_t self_in, mp_f
143143
STATIC uint8_t _pixelbuf_get_as_uint8(mp_obj_t obj) {
144144
if (mp_obj_is_small_int(obj)) {
145145
return MP_OBJ_SMALL_INT_VALUE(obj);
146+
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
146147
} else if (mp_obj_is_int(obj)) {
147148
return mp_obj_get_int_truncated(obj);
149+
#endif
148150
} else if (mp_obj_is_float(obj)) {
149151
return (uint8_t)mp_obj_get_float(obj);
150152
}
151153
mp_raise_TypeError_varg(
152154
translate("can't convert %q to %q"), mp_obj_get_type_qstr(obj), MP_QSTR_int);
153155
}
154156

155-
STATIC void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *w) {
157+
STATIC color_u _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t *self, mp_obj_t color) {
158+
color_u result;
156159
pixelbuf_byteorder_details_t *byteorder = &self->byteorder;
157160
// w is shared between white in NeoPixels and brightness in dotstars (so that DotStars can have
158161
// per-pixel brightness). Set the defaults here in case it isn't set below.
159162
if (byteorder->is_dotstar) {
160-
*w = 255;
163+
result.w = 255;
161164
} else {
162-
*w = 0;
165+
result.w = 0;
163166
}
164167

165168
if (mp_obj_is_int(color) || mp_obj_is_float(color)) {
166169
mp_int_t value = mp_obj_is_int(color) ? mp_obj_get_int_truncated(color) : (mp_int_t)mp_obj_get_float(color);
167-
*r = value >> 16 & 0xff;
168-
*g = (value >> 8) & 0xff;
169-
*b = value & 0xff;
170+
result.r = value >> 16 & 0xff;
171+
result.g = (value >> 8) & 0xff;
172+
result.b = value & 0xff;
170173
} else {
171174
mp_obj_t *items;
172175
size_t len;
173176
mp_obj_get_array(color, &len, &items);
174177
mp_arg_validate_length_range(len, 3, 4, MP_QSTR_color);
175178

176-
*r = _pixelbuf_get_as_uint8(items[PIXEL_R]);
177-
*g = _pixelbuf_get_as_uint8(items[PIXEL_G]);
178-
*b = _pixelbuf_get_as_uint8(items[PIXEL_B]);
179+
result.r = _pixelbuf_get_as_uint8(items[PIXEL_R]);
180+
result.g = _pixelbuf_get_as_uint8(items[PIXEL_G]);
181+
result.b = _pixelbuf_get_as_uint8(items[PIXEL_B]);
179182
if (len > 3) {
180183
if (mp_obj_is_float(items[PIXEL_W])) {
181-
*w = 255 * mp_obj_get_float(items[PIXEL_W]);
184+
result.w = 255 * mp_obj_get_float(items[PIXEL_W]);
182185
} else {
183-
*w = mp_obj_get_int_truncated(items[PIXEL_W]);
186+
result.w = mp_obj_get_int_truncated(items[PIXEL_W]);
184187
}
185-
return;
188+
return result;
186189
}
187190
}
188191
// Int colors can't set white directly so convert to white when all components are equal.
189192
// Also handles RGBW values assigned an RGB tuple.
190-
if (!byteorder->is_dotstar && byteorder->bpp == 4 && byteorder->has_white && *r == *g && *r == *b) {
191-
*w = *r;
192-
*r = 0;
193-
*g = 0;
194-
*b = 0;
193+
if (!byteorder->is_dotstar && byteorder->bpp == 4 && byteorder->has_white && result.r == result.g && result.r == result.b) {
194+
result.w = result.r;
195+
result.r = 0;
196+
result.g = 0;
197+
result.b = 0;
195198
}
199+
return result;
196200
}
197201

198-
STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t index, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
202+
STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t index, color_u rgbw) {
203+
uint8_t r = rgbw.r;
204+
uint8_t g = rgbw.g;
205+
uint8_t b = rgbw.b;
206+
uint8_t w = rgbw.w;
199207
// DotStars don't have white, instead they have 5 bit brightness so pack it into w. Shift right
200208
// by three to leave the top five bits.
201209
if (self->bytes_per_pixel == 4 && self->byteorder.is_dotstar) {
@@ -234,12 +242,8 @@ STATIC void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t *self, size_t inde
234242
}
235243

236244
STATIC void _pixelbuf_set_pixel(pixelbuf_pixelbuf_obj_t *self, size_t index, mp_obj_t value) {
237-
uint8_t r;
238-
uint8_t g;
239-
uint8_t b;
240-
uint8_t w;
241-
_pixelbuf_parse_color(self, value, &r, &g, &b, &w);
242-
_pixelbuf_set_pixel_color(self, index, r, g, b, w);
245+
color_u rgbw = _pixelbuf_parse_color(self, value);
246+
_pixelbuf_set_pixel_color(self, index, rgbw);
243247
}
244248

245249
void common_hal_adafruit_pixelbuf_pixelbuf_set_pixels(mp_obj_t self_in, size_t start, mp_int_t step, size_t slice_len, mp_obj_t *values,
@@ -318,14 +322,10 @@ void common_hal_adafruit_pixelbuf_pixelbuf_show(mp_obj_t self_in) {
318322
void common_hal_adafruit_pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t fill_color) {
319323
pixelbuf_pixelbuf_obj_t *self = native_pixelbuf(self_in);
320324

321-
uint8_t r;
322-
uint8_t g;
323-
uint8_t b;
324-
uint8_t w;
325-
_pixelbuf_parse_color(self, fill_color, &r, &g, &b, &w);
325+
color_u rgbw = _pixelbuf_parse_color(self, fill_color);
326326

327327
for (size_t i = 0; i < self->pixel_count; i++) {
328-
_pixelbuf_set_pixel_color(self, i, r, g, b, w);
328+
_pixelbuf_set_pixel_color(self, i, rgbw);
329329
}
330330
if (self->auto_write) {
331331
common_hal_adafruit_pixelbuf_pixelbuf_show(self_in);

0 commit comments

Comments
 (0)
0