Merge pull request #8440 from jepler/dotclock-overscan-rotation

Dotclock: fix overscan and rotation
This commit is contained in:
Jeff Epler 2023-09-27 18:07:50 -05:00 committed by GitHub
commit aa0d7aad83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 5 deletions

View File

@ -175,9 +175,10 @@ void common_hal_dotclockframebuffer_framebuffer_construct(dotclockframebuffer_fr
self->frequency = frequency; self->frequency = frequency;
self->row_stride = 2 * (width + overscan_left); self->row_stride = 2 * (width + overscan_left);
self->first_pixel_offset = 2 * overscan_left;
self->refresh_rate = frequency / (width + hsync_front_porch + hsync_back_porch) / (height + vsync_front_porch + vsync_back_porch); self->refresh_rate = frequency / (width + hsync_front_porch + hsync_back_porch) / (height + vsync_front_porch + vsync_back_porch);
self->bufinfo.buf = (uint8_t *)fb + 2 * overscan_left; // first line starts after overscan_left pixels self->bufinfo.buf = (uint8_t *)fb;
self->bufinfo.len = 2 * (cfg->timings.h_res * cfg->timings.v_res - overscan_left); // no overscan after last line self->bufinfo.len = 2 * (cfg->timings.h_res * cfg->timings.v_res);
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW; self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
// LCD_CAM.lcd_ctrl2.lcd_vsync_idle_pol = _vsync_polarity; // LCD_CAM.lcd_ctrl2.lcd_vsync_idle_pol = _vsync_polarity;
@ -202,7 +203,7 @@ bool common_hal_dotclockframebuffer_framebuffer_deinitialized(dotclockframebuffe
mp_int_t common_hal_dotclockframebuffer_framebuffer_get_width(dotclockframebuffer_framebuffer_obj_t *self) { mp_int_t common_hal_dotclockframebuffer_framebuffer_get_width(dotclockframebuffer_framebuffer_obj_t *self) {
return self->panel_config.timings.h_res; return self->panel_config.timings.h_res - self->first_pixel_offset / 2;
} }
mp_int_t common_hal_dotclockframebuffer_framebuffer_get_height(dotclockframebuffer_framebuffer_obj_t *self) { mp_int_t common_hal_dotclockframebuffer_framebuffer_get_height(dotclockframebuffer_framebuffer_obj_t *self) {
@ -217,6 +218,10 @@ mp_int_t common_hal_dotclockframebuffer_framebuffer_get_row_stride(dotclockframe
return self->row_stride; return self->row_stride;
} }
mp_int_t common_hal_dotclockframebuffer_framebuffer_get_first_pixel_offset(dotclockframebuffer_framebuffer_obj_t *self) {
return self->first_pixel_offset;
}
void common_hal_dotclockframebuffer_framebuffer_refresh(dotclockframebuffer_framebuffer_obj_t *self) { void common_hal_dotclockframebuffer_framebuffer_refresh(dotclockframebuffer_framebuffer_obj_t *self) {
Cache_WriteBack_Addr((uint32_t)(self->bufinfo.buf), self->bufinfo.len); Cache_WriteBack_Addr((uint32_t)(self->bufinfo.buf), self->bufinfo.len);
} }

View File

@ -39,6 +39,7 @@ typedef struct dotclockframebuffer_framebuffer_obj {
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_int_t row_stride; mp_int_t row_stride;
uint32_t frequency, refresh_rate; uint32_t frequency, refresh_rate;
uint32_t first_pixel_offset;
uint64_t used_pins_mask; uint64_t used_pins_mask;
volatile int32_t frame_count; volatile int32_t frame_count;
esp_lcd_rgb_panel_config_t panel_config; esp_lcd_rgb_panel_config_t panel_config;

View File

@ -269,6 +269,24 @@ MP_DEFINE_CONST_FUN_OBJ_1(dotclockframebuffer_framebuffer_get_row_stride_obj, do
MP_PROPERTY_GETTER(dotclockframebuffer_framebuffer_row_stride_obj, MP_PROPERTY_GETTER(dotclockframebuffer_framebuffer_row_stride_obj,
(mp_obj_t)&dotclockframebuffer_framebuffer_get_row_stride_obj); (mp_obj_t)&dotclockframebuffer_framebuffer_get_row_stride_obj);
//| first_pixel_offset: int
//| """The first_pixel_offset of the display, in bytes
//|
//| Due to overscan or alignment requirements, the memory address for row N+1 may not be exactly ``2*width`` bytes after the memory address for row N.
//| This property gives the stride in **bytes**.
//|
//| On Espressif this value is **guaranteed** to be a multiple of the 2 (i.e., it is a whole number of pixels)"""
//|
STATIC mp_obj_t dotclockframebuffer_framebuffer_get_first_pixel_offset(mp_obj_t self_in) {
dotclockframebuffer_framebuffer_obj_t *self = (dotclockframebuffer_framebuffer_obj_t *)self_in;
check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_dotclockframebuffer_framebuffer_get_first_pixel_offset(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(dotclockframebuffer_framebuffer_get_first_pixel_offset_obj, dotclockframebuffer_framebuffer_get_first_pixel_offset);
MP_PROPERTY_GETTER(dotclockframebuffer_framebuffer_first_pixel_offset_obj,
(mp_obj_t)&dotclockframebuffer_framebuffer_get_first_pixel_offset_obj);
STATIC mp_int_t dotclockframebuffer_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { STATIC mp_int_t dotclockframebuffer_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
dotclockframebuffer_framebuffer_obj_t *self = (dotclockframebuffer_framebuffer_obj_t *)self_in; dotclockframebuffer_framebuffer_obj_t *self = (dotclockframebuffer_framebuffer_obj_t *)self_in;
// a readonly framebuffer would be unusual but not impossible // a readonly framebuffer would be unusual but not impossible
@ -331,6 +349,11 @@ STATIC int dotclockframebuffer_framebuffer_get_row_stride_proto(mp_obj_t self_in
return common_hal_dotclockframebuffer_framebuffer_get_row_stride(self); return common_hal_dotclockframebuffer_framebuffer_get_row_stride(self);
} }
STATIC int dotclockframebuffer_framebuffer_get_first_pixel_offset_proto(mp_obj_t self_in) {
dotclockframebuffer_framebuffer_obj_t *self = (dotclockframebuffer_framebuffer_obj_t *)self_in;
return common_hal_dotclockframebuffer_framebuffer_get_first_pixel_offset(self);
}
STATIC const framebuffer_p_t dotclockframebuffer_framebuffer_proto = { STATIC const framebuffer_p_t dotclockframebuffer_framebuffer_proto = {
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer)
.get_bufinfo = dotclockframebuffer_framebuffer_get_bufinfo, .get_bufinfo = dotclockframebuffer_framebuffer_get_bufinfo,
@ -340,6 +363,7 @@ STATIC const framebuffer_p_t dotclockframebuffer_framebuffer_proto = {
.get_height = dotclockframebuffer_framebuffer_get_height_proto, .get_height = dotclockframebuffer_framebuffer_get_height_proto,
.get_color_depth = dotclockframebuffer_framebuffer_get_color_depth_proto, .get_color_depth = dotclockframebuffer_framebuffer_get_color_depth_proto,
.get_row_stride = dotclockframebuffer_framebuffer_get_row_stride_proto, .get_row_stride = dotclockframebuffer_framebuffer_get_row_stride_proto,
.get_first_pixel_offset = dotclockframebuffer_framebuffer_get_first_pixel_offset_proto,
.get_bytes_per_cell = dotclockframebuffer_framebuffer_get_bytes_per_cell_proto, .get_bytes_per_cell = dotclockframebuffer_framebuffer_get_bytes_per_cell_proto,
.get_native_frames_per_second = dotclockframebuffer_framebuffer_get_native_frames_per_second_proto, .get_native_frames_per_second = dotclockframebuffer_framebuffer_get_native_frames_per_second_proto,
.swapbuffers = dotclockframebuffer_framebuffer_swapbuffers, .swapbuffers = dotclockframebuffer_framebuffer_swapbuffers,
@ -351,6 +375,7 @@ STATIC const mp_rom_map_elem_t dotclockframebuffer_framebuffer_locals_dict_table
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&dotclockframebuffer_framebuffer_width_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&dotclockframebuffer_framebuffer_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&dotclockframebuffer_framebuffer_height_obj) }, { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&dotclockframebuffer_framebuffer_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_row_stride), MP_ROM_PTR(&dotclockframebuffer_framebuffer_row_stride_obj) }, { MP_ROM_QSTR(MP_QSTR_row_stride), MP_ROM_PTR(&dotclockframebuffer_framebuffer_row_stride_obj) },
{ MP_ROM_QSTR(MP_QSTR_first_pixel_offset), MP_ROM_PTR(&dotclockframebuffer_framebuffer_first_pixel_offset_obj) },
{ MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&dotclockframebuffer_framebuffer_frequency_obj) }, { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&dotclockframebuffer_framebuffer_frequency_obj) },
{ MP_ROM_QSTR(MP_QSTR_refresh_rate), MP_ROM_PTR(&dotclockframebuffer_framebuffer_refresh_rate_obj) }, { MP_ROM_QSTR(MP_QSTR_refresh_rate), MP_ROM_PTR(&dotclockframebuffer_framebuffer_refresh_rate_obj) },
{ MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&dotclockframebuffer_framebuffer_refresh_obj) }, { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&dotclockframebuffer_framebuffer_refresh_obj) },

View File

@ -56,4 +56,5 @@ mp_int_t common_hal_dotclockframebuffer_framebuffer_get_height(dotclockframebuff
mp_int_t common_hal_dotclockframebuffer_framebuffer_get_frequency(dotclockframebuffer_framebuffer_obj_t *self); mp_int_t common_hal_dotclockframebuffer_framebuffer_get_frequency(dotclockframebuffer_framebuffer_obj_t *self);
mp_int_t common_hal_dotclockframebuffer_framebuffer_get_refresh_rate(dotclockframebuffer_framebuffer_obj_t *self); mp_int_t common_hal_dotclockframebuffer_framebuffer_get_refresh_rate(dotclockframebuffer_framebuffer_obj_t *self);
mp_int_t common_hal_dotclockframebuffer_framebuffer_get_row_stride(dotclockframebuffer_framebuffer_obj_t *self); mp_int_t common_hal_dotclockframebuffer_framebuffer_get_row_stride(dotclockframebuffer_framebuffer_obj_t *self);
mp_int_t common_hal_dotclockframebuffer_framebuffer_get_first_pixel_offset(dotclockframebuffer_framebuffer_obj_t *self);
void common_hal_dotclockframebuffer_framebuffer_refresh(dotclockframebuffer_framebuffer_obj_t *self); void common_hal_dotclockframebuffer_framebuffer_refresh(dotclockframebuffer_framebuffer_obj_t *self);

View File

@ -85,7 +85,7 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu
} }
self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo); self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo);
size_t framebuffer_size = self->first_pixel_offset + self->row_stride * self->core.height; size_t framebuffer_size = self->first_pixel_offset + self->row_stride * (self->core.height - 1) + self->core.width * self->core.colorspace.depth / 8;
mp_arg_validate_length_min(self->bufinfo.len, framebuffer_size, MP_QSTR_framebuffer); mp_arg_validate_length_min(self->bufinfo.len, framebuffer_size, MP_QSTR_framebuffer);
@ -252,7 +252,9 @@ STATIC void _refresh_display(framebufferio_framebufferdisplay_obj_t *self) {
displayio_display_core_start_refresh(&self->core); displayio_display_core_start_refresh(&self->core);
const displayio_area_t *current_area = _get_refresh_areas(self); const displayio_area_t *current_area = _get_refresh_areas(self);
if (current_area) { if (current_area) {
uint8_t dirty_row_bitmask[(self->core.height + 7) / 8]; bool transposed = (self->core.rotation == 90 || self->core.rotation == 270);
int row_count = transposed ? self->core.width : self->core.height;
uint8_t dirty_row_bitmask[(row_count + 7) / 8];
memset(dirty_row_bitmask, 0, sizeof(dirty_row_bitmask)); memset(dirty_row_bitmask, 0, sizeof(dirty_row_bitmask));
self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo); self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo);
while (current_area != NULL) { while (current_area != NULL) {