From d09f6bdea361a671c23c9475c876ba16ecc7e263 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Mon, 11 Oct 2021 14:48:15 +0200 Subject: [PATCH] feat(disp): Enable rendering to display subsection (#2583) This change introduces new fields on `lv_disp_drv_t` that allow to specify the size of the full display and the offset of the display subsection that is being rendered to. The values are used to transform the drawing area before calling `flush_cb` so that only the desired part of the full display is being rendered to. Relates to: lvgl/lv_drivers#166 --- docs/CHANGELOG.md | 1 + docs/porting/display.md | 4 ++++ src/core/lv_refr.c | 10 ++++++++- src/hal/lv_hal_disp.c | 50 +++++++++++++++++++++++++++++++++++++++++ src/hal/lv_hal_disp.h | 19 ++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 6637b0601..c94c3a82a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -40,6 +40,7 @@ - feat(btnmatrix/keyboard): add option to show popovers on button press - fix(types) LV_FORMAT_ATTRIBUTE now works with gnu version greater than 4.4 - feat(event) add add LV_EVENT_CHILD_CREATED/DELETED +- feat(disp): Enable rendering to display subsection - feat(keyboard): add user-defined modes ## v8.0.2 (16.07.2021) diff --git a/docs/porting/display.md b/docs/porting/display.md index 3a2d1f517..0023dd243 100644 --- a/docs/porting/display.md +++ b/docs/porting/display.md @@ -69,6 +69,10 @@ LVGL might render the screen in multiple chunks and therefore call `flush_cb` mu ### Optional fields There are some optional display driver data fields: +- `physical_hor_res` horizontal resolution of the full / physical display in pixels. Only set this when _not_ using the full screen (defaults to -1 / same as `hor_res`). +- `physical_ver_res` vertical resolution of the full / physical display in pixels. Only set this when _not_ using the full screen (defaults to -1 / same as `ver_res`). +- `offset_x` horizontal offset from the the full / physical display in pixels. Only set this when _not_ using the full screen (defaults to 0). +- `offset_y` vertical offset from the the full / physical display in pixels. Only set this when _not_ using the full screen (defaults to 0). - `color_chroma_key` A color which will be drawn as transparent on chrome keyed images. Set to `LV_COLOR_CHROMA_KEY` from `lv_conf.h` by default. - `anti_aliasing` use anti-aliasing (edge smoothing). Enabled by default if `LV_COLOR_DEPTH` is set to at least 16 in `lv_conf.h`. - `rotated` and `sw_rotate` See the [Rotation](#rotation) section below. diff --git a/src/core/lv_refr.c b/src/core/lv_refr.c index 07c1306e0..60eb17728 100644 --- a/src/core/lv_refr.c +++ b/src/core/lv_refr.c @@ -964,5 +964,13 @@ static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_ { TRACE_REFR("Calling flush_cb on (%d;%d)(%d;%d) area with %p image pointer", area->x1, area->y1, area->x2, area->y2, color_p); - drv->flush_cb(drv, area, color_p); + + lv_area_t offset_area = { + .x1 = area->x1 + drv->offset_x, + .y1 = area->y1 + drv->offset_y, + .x2 = area->x2 + drv->offset_x, + .y2 = area->y2 + drv->offset_y + }; + + drv->flush_cb(drv, &offset_area, color_p); } diff --git a/src/hal/lv_hal_disp.c b/src/hal/lv_hal_disp.c index 233d0df84..e3e1fc8b6 100644 --- a/src/hal/lv_hal_disp.c +++ b/src/hal/lv_hal_disp.c @@ -77,6 +77,10 @@ void lv_disp_drv_init(lv_disp_drv_t * driver) driver->hor_res = 320; driver->ver_res = 240; + driver->physical_hor_res = -1; + driver->physical_ver_res = -1; + driver->offset_x = 0; + driver->offset_y = 0; driver->antialiasing = LV_COLOR_DEPTH > 8 ? 1 : 0; driver->screen_transp = LV_COLOR_SCREEN_TRANSP; driver->dpi = LV_DPI_DEF; @@ -325,6 +329,52 @@ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp) } } +/** + * Get the full / physical horizontal resolution of a display + * @param disp pointer to a display (NULL to use the default display) + * @return the full / physical horizontal resolution of the display + */ +lv_coord_t lv_disp_get_physical_hor_res(lv_disp_t * disp) +{ + if(disp == NULL) disp = lv_disp_get_default(); + + if(disp == NULL) { + return 0; + } + else { + switch(disp->driver->rotated) { + case LV_DISP_ROT_90: + case LV_DISP_ROT_270: + return disp->driver->physical_ver_res; + default: + return disp->driver->physical_hor_res; + } + } +} + +/** + * Get the full / physical vertical resolution of a display + * @param disp pointer to a display (NULL to use the default display) + * @return the full / physical vertical resolution of the display + */ +lv_coord_t lv_disp_get_physical_ver_res(lv_disp_t * disp) +{ + if(disp == NULL) disp = lv_disp_get_default(); + + if(disp == NULL) { + return 0; + } + else { + switch(disp->driver->rotated) { + case LV_DISP_ROT_90: + case LV_DISP_ROT_270: + return disp->driver->physical_hor_res; + default: + return disp->driver->physical_ver_res; + } + } +} + /** * Get if anti-aliasing is enabled for a display or not * @param disp pointer to a display (NULL to use the default display) diff --git a/src/hal/lv_hal_disp.h b/src/hal/lv_hal_disp.h index 96b605adf..96af056ba 100644 --- a/src/hal/lv_hal_disp.h +++ b/src/hal/lv_hal_disp.h @@ -80,6 +80,11 @@ typedef struct _lv_disp_drv_t { lv_coord_t hor_res; /**< Horizontal resolution.*/ lv_coord_t ver_res; /**< Vertical resolution.*/ + lv_coord_t physical_hor_res; /**< Horizontal resolution of the full / physical display. Set to -1 for fullscreen mode.*/ + lv_coord_t physical_ver_res; /**< Vertical resolution of the full / physical display. Set to -1 for fullscreen mode.*/ + lv_coord_t offset_x; /**< Horizontal offset from the full / physical display. Set to 0 for fullscreen mode.*/ + lv_coord_t offset_y; /**< Vertical offset from the full / physical display. Set to 0 for fullscreen mode.*/ + /** Pointer to a buffer initialized with `lv_disp_draw_buf_init()`. * LVGL will use this buffer(s) to draw the screens contents*/ lv_disp_draw_buf_t * draw_buf; @@ -254,6 +259,20 @@ lv_coord_t lv_disp_get_hor_res(lv_disp_t * disp); */ lv_coord_t lv_disp_get_ver_res(lv_disp_t * disp); +/** + * Get the full / physical horizontal resolution of a display + * @param disp pointer to a display (NULL to use the default display) + * @return the full / physical horizontal resolution of the display + */ +lv_coord_t lv_disp_get_physical_hor_res(lv_disp_t * disp); + +/** + * Get the full / physical vertical resolution of a display + * @param disp pointer to a display (NULL to use the default display) + * @return the full / physical vertical resolution of the display + */ +lv_coord_t lv_disp_get_physical_ver_res(lv_disp_t * disp); + /** * Get if anti-aliasing is enabled for a display or not * @param disp pointer to a display (NULL to use the default display)