Merge pull request #8440 from jepler/dotclock-overscan-rotation
Dotclock: fix overscan and rotation
This commit is contained in:
commit
aa0d7aad83
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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) },
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user