framebufferio: get more properties direct from underlying framebuffer

This commit is contained in:
Jeff Epler 2020-04-15 09:29:59 -05:00
parent a32337718d
commit 1a91a75b9c
2 changed files with 72 additions and 29 deletions

View File

@ -52,35 +52,21 @@ STATIC int get_int_property(mp_obj_t obj, qstr attr) {
//| objects in CircuitPython, Display objects live until `displayio.release_displays()`
//| is called. This is done so that CircuitPython can use the display itself.
//|
//| .. class:: FramebufferDisplay(framebuffer, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, bytes_per_cell=1, reverse_pixels_in_byte=False, backlight_pin=None, brightness=1.0, auto_brightness=False, auto_refresh=True, native_frames_per_second=60)
//| .. class:: FramebufferDisplay(framebuffer, *, rotation=0, auto_refresh=True)
//|
//| Create a Display object with the given framebuffer (a buffer, array, ulab.array, etc)
//|
//| :param framebuffer: The framebuffer that the display is connected to
//| :type framebuffer: any core object implementing the framebuffer protocol
//| :param int width: Width in pixels
//| :param int height: Height in pixels
//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270)
//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays
//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.)
//| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row.
//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight
//| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True.
//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism.
//| :param bool auto_refresh: Automatically refresh the screen
//| :param int native_frames_per_second: Number of display refreshes per second
//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270)
//|
STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_framebuffer, ARG_width, ARG_height, ARG_rotation, ARG_color_depth, ARG_bytes_per_cell, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS };
enum { ARG_framebuffer, ARG_rotation, ARG_auto_refresh, NUM_ARGS };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_framebuffer, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} },
{ MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
{ MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
{ MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} },
};
MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS );
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@ -88,31 +74,30 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t
mp_obj_t framebuffer = args[ARG_framebuffer].u_obj;
if (args[ARG_width].u_int == 0) {
args[ARG_width].u_int = get_int_property(framebuffer, MP_QSTR_width);
}
if (args[ARG_height].u_int == 0) {
args[ARG_height].u_int = get_int_property(framebuffer, MP_QSTR_height);
}
mp_int_t rotation = args[ARG_rotation].u_int;
if (rotation % 90 != 0) {
mp_raise_ValueError(translate("Display rotation must be in 90 degree increments"));
}
int width = get_int_property(framebuffer, MP_QSTR_width);
int height = get_int_property(framebuffer, MP_QSTR_height);
int color_depth = get_int_property(framebuffer, MP_QSTR_color_depth);
int bytes_per_cell = get_int_property(framebuffer, MP_QSTR_bytes_per_cell);
int native_frames_per_second = get_int_property(framebuffer, MP_QSTR_native_frames_per_second);
primary_display_t *disp = allocate_display_or_raise();
framebufferio_framebufferdisplay_obj_t *self = &disp->framebuffer_display;
self->base.type = &framebufferio_framebufferdisplay_type;
common_hal_framebufferio_framebufferdisplay_construct(
self,
framebuffer,
args[ARG_width].u_int, args[ARG_height].u_int,
width,
height,
rotation,
args[ARG_color_depth].u_int,
args[ARG_bytes_per_cell].u_int,
color_depth,
bytes_per_cell,
args[ARG_auto_refresh].u_bool,
args[ARG_native_frames_per_second].u_int
native_frames_per_second
);
return self;

View File

@ -350,6 +350,61 @@ const mp_obj_property_t protomatter_protomatter_height_obj = {
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: bytes_per_cell
//|
//| The bytes_per_cell of the display, in pixels. Always equal to 1.
//|
STATIC mp_obj_t protomatter_protomatter_get_bytes_per_cell(mp_obj_t self_in) {
protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in;
check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(1);
}
MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_bytes_per_cell_obj, protomatter_protomatter_get_bytes_per_cell);
const mp_obj_property_t protomatter_protomatter_bytes_per_cell_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&protomatter_protomatter_get_bytes_per_cell_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: color_depth
//|
//| The color_depth of the framebuffer, in bits. Always equal to 16. This
//| is different than the constructor's "bit_depth".
//|
STATIC mp_obj_t protomatter_protomatter_get_color_depth(mp_obj_t self_in) {
protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in;
check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(16);
}
MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_color_depth_obj, protomatter_protomatter_get_color_depth);
const mp_obj_property_t protomatter_protomatter_color_depth_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&protomatter_protomatter_get_color_depth_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
//| .. attribute:: native_frames_per_second
//|
//| The native_frames_per_second of the display. Always equal to 250.
//|
STATIC mp_obj_t protomatter_protomatter_get_native_frames_per_second(mp_obj_t self_in) {
protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in;
check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(250);
}
MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_native_frames_per_second_obj, protomatter_protomatter_get_native_frames_per_second);
const mp_obj_property_t protomatter_protomatter_native_frames_per_second_obj = {
.base.type = &mp_type_property,
.proxy = {(mp_obj_t)&protomatter_protomatter_get_native_frames_per_second_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
STATIC const mp_rom_map_elem_t protomatter_protomatter_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&protomatter_protomatter_deinit_obj) },
@ -357,6 +412,9 @@ STATIC const mp_rom_map_elem_t protomatter_protomatter_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&protomatter_protomatter_refresh_obj) },
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&protomatter_protomatter_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&protomatter_protomatter_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_color_depth), MP_ROM_PTR(&protomatter_protomatter_color_depth_obj) },
{ MP_ROM_QSTR(MP_QSTR_bytes_per_cell), MP_ROM_PTR(&protomatter_protomatter_bytes_per_cell_obj) },
{ MP_ROM_QSTR(MP_QSTR_native_frames_per_second), MP_ROM_PTR(&protomatter_protomatter_native_frames_per_second_obj) },
};
STATIC MP_DEFINE_CONST_DICT(protomatter_protomatter_locals_dict, protomatter_protomatter_locals_dict_table);