merge dev

This commit is contained in:
Gabor Kiss-Vamosi 2020-09-30 21:30:07 +02:00
commit 705a564ca8
27 changed files with 1122 additions and 95 deletions

View File

@ -1,8 +1,12 @@
# Changelog
## v7.7.0 (22.09.2020)
## v7.7.0 (06.10.2020)
### New features
- Add PXP GPU support (for NXP MCUs)
- Allow max. 16 cell types for table
- Add `lv_table_set_text_fmt()`
### Bugfixes
@ -14,6 +18,8 @@
### Bugfixes
- Fix selection of options with non-ASCII letters in dropdown list
- Fix font loader to support LV_FONT_FMT_TXT_LARGE
- Fix BIDI support in dropdown list
- Fix copying base dir in lv_obj_craete
## v7.5.0 (15.09.2020)

View File

@ -121,7 +121,7 @@ For more examples see the [lv_examples](https://github.com/lvgl/lv_examples) rep
### Button with label
```c
lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button the current screen*/
lv_obj_t * btn = lv_btn_create(lv_scr_act(), NULL); /*Add a button to the current screen*/
lv_obj_set_pos(btn, 10, 10); /*Set its position*/
lv_obj_set_size(btn, 100, 50); /*Set its size*/
lv_obj_set_event_cb(btn, btn_event_cb); /*Assign a callback to the button*/

View File

@ -22,7 +22,6 @@ Planned to September/October 2020
- Simplified File system interface ([feat/new_fs_api](https://github.com/lvgl/lvgl/tree/feat/new-fs-api) branch) to make porting easier
- Work in progress
- Remove the align parameter from `lv_canvas_draw_text`
- RGB888 support [#1722](https://github.com/lvgl/lvgl/issues/1722)
## v8.1
- Add radio button widget
@ -32,8 +31,11 @@ Planned to September/October 2020
- Unit testing (gtest?). See [#1658](https://github.com/lvgl/lvgl/issues/1658)
- Benchmarking (gem5?). See [#1660](https://github.com/lvgl/lvgl/issues/1660)
- Consider direct binary font format support
- Remove the copy paramter from create functions
## Ideas
- Text node. See [#1701](https://github.com/lvgl/lvgl/issues/1701#issuecomment-699479408)
- RGB888 support [#1722](https://github.com/lvgl/lvgl/issues/1722)
- CPP binding. See [Forum](https://forum.lvgl.io/t/is-it-possible-to-officially-support-optional-cpp-api/2736)
- Optmize font decompression
- Switch to RGBA colors in styles

View File

@ -195,6 +195,17 @@ typedef void * lv_group_user_data_t;
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#define LV_GPU_DMA2D_CMSIS_INCLUDE
/*1: Use PXP for CPU off-load on NXP RTxxx platforms */
#define LV_USE_GPU_NXP_PXP 0
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
* */
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
/* 1: Enable file system (might be required for images */
#define LV_USE_FILESYSTEM 1
#if LV_USE_FILESYSTEM

View File

@ -476,6 +476,20 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
# endif
#endif
/*1: Use PXP for CPU off-load on NXP RTxxx platforms */
#ifndef LV_USE_GPU_NXP_PXP
#define LV_USE_GPU_NXP_PXP 0
#endif
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
* */
#ifndef LV_USE_GPU_NXP_PXP_AUTO_INIT
#define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
#endif
/* 1: Enable file system (might be required for images */
#ifndef LV_USE_FILESYSTEM
# ifdef CONFIG_LV_USE_FILESYSTEM
@ -1251,7 +1265,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
/* Support bidirectional texts.
* Allows mixing Left-to-Right and Right-to-Left texts.
* The direction will be processed according to the Unicode Bidirectioanl Algorithm:
* The direction will be processed according to the Unicode Bidirectional Algorithm:
* https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
#ifndef LV_USE_BIDI
# ifdef CONFIG_LV_USE_BIDI

View File

@ -120,7 +120,6 @@ lv_obj_t * lv_disp_get_layer_sys(lv_disp_t * disp)
return disp->sys_layer;
}
/**
* Assign a screen to a display.
* @param disp pointer to a display where to assign the screen

View File

@ -184,7 +184,6 @@ static inline void lv_scr_load(lv_obj_t * scr)
lv_disp_load_scr(scr);
}
/**********************
* MACROS
**********************/

View File

@ -806,11 +806,11 @@ bool _lv_debug_check_obj_valid(const lv_obj_t * obj);
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
# define LV_ASSERT_OBJ(obj_p, obj_type) LV_ASSERT_NULL(obj_p)
# else
# define LV_ASSERT_OBJ(obj_p, obj_type) true
# define LV_ASSERT_OBJ(obj_p, obj_type)
# endif
# endif
#else
# define LV_ASSERT_OBJ(obj, obj_type) true
# define LV_ASSERT_OBJ(obj, obj_type)
#endif

View File

@ -641,13 +641,13 @@ bool lv_debug_check_style_list(const lv_style_list_t * list);
# define LV_ASSERT_STYLE_LIST(list_p) LV_DEBUG_ASSERT(LV_DEBUG_IS_STYLE_LIST(list_p), "Invalid style list", list_p);
# endif
# else
# define LV_ASSERT_STYLE(style_p) true
# define LV_ASSERT_STYLE_LIST(list_p) true
# define LV_ASSERT_STYLE(style_p)
# define LV_ASSERT_STYLE_LIST(list_p)
# endif
#else
# define LV_ASSERT_STYLE(p) true
# define LV_ASSERT_STYLE_LIST(p) true
# define LV_ASSERT_STYLE(p)
# define LV_ASSERT_STYLE_LIST(p)
#endif
#ifdef __cplusplus

View File

@ -12,13 +12,18 @@
#include "../lv_hal/lv_hal_disp.h"
#include "../lv_core/lv_refr.h"
#if LV_USE_GPU_NXP_PXP
#include "../lv_gpu/lv_gpu_nxp_pxp.h"
#elif LV_USE_GPU_STM32_DMA2D
#include "../lv_gpu/lv_gpu_stm32_dma2d.h"
#endif
/*********************
* DEFINES
*********************/
#define GPU_SIZE_LIMIT 240
/**********************
* TYPEDEFS
**********************/
@ -335,9 +340,12 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
disp->driver.gpu_fill_cb(&disp->driver, disp_buf, disp_w, draw_area, color);
return;
}
#endif
#if LV_USE_GPU_STM32_DMA2D
#elif LV_USE_GPU_NXP_PXP
if(lv_area_get_size(draw_area) >= GPU_NXP_PXP_FILL_SIZE_LIMIT) {
lv_gpu_nxp_pxp_fill(disp_buf, disp_w, draw_area, color, opa);
return;
}
#elif LV_USE_GPU_STM32_DMA2D
if(lv_area_get_size(draw_area) >= 240) {
lv_gpu_stm32_dma2d_fill(disp_buf_first, disp_w, color, draw_area_w, draw_area_h);
return;
@ -351,7 +359,13 @@ LV_ATTRIBUTE_FAST_MEM static void fill_normal(const lv_area_t * disp_area, lv_co
}
/*No mask with opacity*/
else {
#if LV_USE_GPU
#if LV_USE_GPU_NXP_PXP
if(lv_area_get_size(draw_area) >= GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT) {
lv_gpu_nxp_pxp_fill(disp_buf, disp_w, draw_area, color, opa);
return;
}
#elif LV_USE_GPU
if(disp->driver.gpu_blend_cb && lv_area_get_size(draw_area) > GPU_SIZE_LIMIT) {
for(x = 0; x < draw_area_w ; x++) blend_buf[x].full = color.full;
@ -726,11 +740,16 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
#endif
if(opa > LV_OPA_MAX) {
#if LV_USE_GPU_STM32_DMA2D
if(lv_area_get_size(draw_area) >= 240) {
lv_gpu_stm32_dma2d_copy(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h);
return;
}
#if LV_USE_GPU_NXP_PXP
if (lv_area_get_size(draw_area) >= GPU_NXP_PXP_BLIT_SIZE_LIMIT) {
lv_gpu_nxp_pxp_blit(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h, opa);
return;
}
#elif LV_USE_GPU_STM32_DMA2D
if(lv_area_get_size(draw_area) >= 240) {
lv_gpu_stm32_dma2d_copy(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h);
return;
}
#endif
/*Software rendering*/
@ -741,7 +760,12 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
}
}
else {
#if LV_USE_GPU_STM32_DMA2D
#if LV_USE_GPU_NXP_PXP
if (lv_area_get_size(draw_area) >= GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT) {
lv_gpu_nxp_pxp_blit(disp_buf_first, disp_w, map_buf_first, map_w, draw_area_w, draw_area_h, opa);
return;
}
#elif LV_USE_GPU_STM32_DMA2D
if(lv_area_get_size(draw_area) >= 240) {
lv_gpu_stm32_dma2d_blend(disp_buf_first, disp_w, map_buf_first, opa, map_w, draw_area_w, draw_area_h);
return;

View File

@ -13,8 +13,11 @@
#include "../lv_core/lv_refr.h"
#include "../lv_misc/lv_mem.h"
#include "../lv_misc/lv_math.h"
#if LV_USE_GPU_STM32_DMA2D
#include "../lv_gpu/lv_gpu_stm32_dma2d.h"
#elif LV_USE_GPU_NXP_PXP
#include "../lv_gpu/lv_gpu_nxp_pxp.h"
#endif
/*********************
* DEFINES
@ -355,6 +358,22 @@ LV_ATTRIBUTE_FAST_MEM static void lv_draw_map(const lv_area_t * map_area, const
_lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
draw_dsc->blend_mode);
}
#if LV_USE_GPU_NXP_PXP
/* Simple case without masking and transformations */
else if (other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false &&
chroma_key == true && draw_dsc->recolor_opa == LV_OPA_TRANSP) { /* copy with color keying (+ alpha) */
lv_gpu_nxp_pxp_enable_color_key();
_lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
draw_dsc->blend_mode);
lv_gpu_nxp_pxp_disable_color_key();
} else if (other_mask_cnt == 0 && draw_dsc->angle == 0 && draw_dsc->zoom == LV_IMG_ZOOM_NONE && alpha_byte == false &&
chroma_key == false && draw_dsc->recolor_opa != LV_OPA_TRANSP) { /* copy with recolor (+ alpha) */
lv_gpu_nxp_pxp_enable_recolor(draw_dsc->recolor, draw_dsc->recolor_opa);
_lv_blend_map(clip_area, map_area, (lv_color_t *)map_p, NULL, LV_DRAW_MASK_RES_FULL_COVER, draw_dsc->opa,
draw_dsc->blend_mode);
lv_gpu_nxp_pxp_disable_recolor();
}
#endif
/*In the other cases every pixel need to be checked one-by-one*/
else {
/*The pixel size in byte is different if an alpha byte is added too*/

View File

@ -1,7 +1,3 @@
/**
* @file lv_mask.c
*

474
src/lv_gpu/lv_gpu_nxp_pxp.c Normal file
View File

@ -0,0 +1,474 @@
/**
* @file lv_gpu_nxp_pxp.c
*
*/
/**
* MIT License
*
* Copyright (c) 2020 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next paragraph)
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#if LV_USE_GPU_NXP_PXP
#include "lvgl.h"
#include "lv_gpu_nxp_pxp.h"
#include "../lv_misc/lv_mem.h"
#include "../lv_misc/lv_log.h"
#include "fsl_pxp.h"
#include "fsl_cache.h"
/*********************
* DEFINES
*********************/
/* PXP instance ID */
#define PXP_ID PXP
#if LV_COLOR_16_SWAP
#error Color swap not implemented. Disable LV_COLOR_16_SWAP feature.
#endif
#if LV_COLOR_DEPTH==16
#define PXP_OUT_PIXEL_FORMAT kPXP_OutputPixelFormatRGB565
#define PXP_AS_PIXEL_FORMAT kPXP_AsPixelFormatRGB565
#define PXP_PS_PIXEL_FORMAT kPXP_PsPixelFormatRGB565
#elif
#error Only 16bit color depth is supported. Set LV_COLOR_DEPTH to 16.
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_gpu_nxp_pxp_run(void);
static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src,
lv_coord_t src_width,
lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa, lv_color_t recolor, lv_opa_t recolorOpa);
static void lv_gpu_nxp_invalidate_cache(uint32_t address, uint32_t width, uint32_t height, uint32_t stride, uint32_t pxSize);
/**********************
* STATIC VARIABLES
**********************/
static bool colorKeyEnabled = false;
static uint32_t colorKey = 0x0;
static bool recolorEnabled = false;
static lv_color_t recolor = {.full = 0x0};
static lv_opa_t recolorOpa = 0x0;
static lv_nxp_pxp_cfg_t pxp_cfg;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Reset and initialize PXP device. This function should be called as a part
* of display init sequence.
*
* @return LV_RES_OK: PXP init ok; LV_RES_INV: init error. See error log for more information.
*/
lv_res_t lv_gpu_nxp_pxp_init(lv_nxp_pxp_cfg_t * cfg)
{
if(!cfg || !cfg->pxp_interrupt_deinit || !cfg->pxp_interrupt_init || !cfg->pxp_run) {
LV_LOG_ERROR("PXP configuration error. Check callback pointers.");
return LV_RES_INV;
}
PXP_Init(PXP);
PXP_EnableCsc1(PXP, false); /* Disable CSC1, it is enabled by default. */
PXP_EnableInterrupts(PXP, kPXP_CompleteInterruptEnable);
pxp_cfg = *cfg;
if(pxp_cfg.pxp_interrupt_init() != LV_RES_OK) {
PXP_Deinit(PXP);
LV_LOG_ERROR("PXP interrupt init error. Check pxp_interrupt_init callback.");
return LV_RES_INV;
}
colorKey = lv_color_to32(LV_COLOR_TRANSP);
return LV_RES_OK;
}
/**
* Disable PXP device. Should be called during display deinit sequence.
*/
void lv_gpu_nxp_pxp_deinit(void)
{
pxp_cfg.pxp_interrupt_deinit();
PXP_DisableInterrupts(PXP, kPXP_CompleteInterruptEnable);
PXP_Deinit(PXP_ID);
}
/**
* Fill area, with optional opacity.
*
* @param[in/out] dest_buf destination buffer
* @param[in] dest_width width (stride) of destination buffer in pixels
* @param[in] fill_area area to fill
* @param[in] color color
* @param[in] opa transparency of the color
*/
void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_width, const lv_area_t * fill_area, lv_color_t color,
lv_opa_t opa)
{
PXP_Init(PXP_ID);
PXP_EnableCsc1(PXP_ID, false); /* Disable CSC1, it is enabled by default. */
PXP_SetProcessBlockSize(PXP, kPXP_BlockSize16); /* Block size 16x16 for higher performance */
/* OUT buffer configure */
pxp_output_buffer_config_t outputConfig = {
.pixelFormat = PXP_OUT_PIXEL_FORMAT,
.interlacedMode = kPXP_OutputProgressive,
.buffer0Addr = (uint32_t)(dest_buf + dest_width * fill_area->y1 + fill_area->x1),
.buffer1Addr = (uint32_t)NULL,
.pitchBytes = dest_width * sizeof(lv_color_t),
.width = fill_area->x2 - fill_area->x1 + 1,
.height = fill_area->y2 - fill_area->y1 + 1,
};
lv_gpu_nxp_invalidate_cache(outputConfig.buffer0Addr, outputConfig.width, outputConfig.height, outputConfig.pitchBytes, sizeof(lv_color_t));
PXP_SetOutputBufferConfig(PXP_ID, &outputConfig);
if(opa > LV_OPA_MAX) {
/* Simple color fill without opacity - AS disabled, PS as color generator */
PXP_SetAlphaSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); /* Disable AS. */
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U); /* Disable PS. */
PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to32(color));
}
else {
/* Fill with opacity - AS used as source (same as OUT), PS used as color generator, blended together */
pxp_as_buffer_config_t asBufferConfig;
pxp_porter_duff_config_t pdConfig;
/* Set AS to OUT */
asBufferConfig.pixelFormat = PXP_AS_PIXEL_FORMAT;
asBufferConfig.bufferAddr = (uint32_t)outputConfig.buffer0Addr;
asBufferConfig.pitchBytes = outputConfig.pitchBytes;
PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, fill_area->x2 - fill_area->x1 + 1, fill_area->y2 - fill_area->y1 + 1);
/* Disable PS, use as color generator */
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to32(color));
/* Configure Porter-Duff blending - For RGB 565 only! */
pdConfig.enable = 1;
pdConfig.dstColorMode = kPXP_PorterDuffColorStraight;
pdConfig.srcColorMode = kPXP_PorterDuffColorStraight;
pdConfig.dstGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha;
pdConfig.srcGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha;
pdConfig.srcFactorMode = kPXP_PorterDuffFactorStraight;
pdConfig.dstFactorMode = kPXP_PorterDuffFactorStraight;
pdConfig.srcGlobalAlpha = opa;
pdConfig.dstGlobalAlpha = 255 - opa;
pdConfig.srcAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */
pdConfig.dstAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */
PXP_SetPorterDuffConfig(PXP_ID, &pdConfig);
}
lv_gpu_nxp_pxp_run(); /* Start PXP task */
}
/**
* @brief BLock Image Transfer - copy rectangular image from src buffer to dst buffer with effects.
*
* By default, image is copied directly, with optional opacity configured by \p opa.
* Color keying can be enabled by calling lv_gpu_nxp_pxp_enable_color_key() before calling this function.
* Recoloring can be enabled by calling lv_gpu_nxp_pxp_enable_recolor() before calling this function.
* Note that color keying and recoloring at the same time is not supported and black rectangle is rendered.
*
* @param[in/out] dest destination buffer
* @param[in] dest_width width (stride) of destination buffer in pixels
* @param[in] src source buffer
* @param[in] src_with width (stride) of source buffer in pixels
* @param[in] copy_w width of area to be copied from src to dest
* @param[in] copy_h height of area to be copied from src to dest
* @param[in] opa opacity of the result
*/
void lv_gpu_nxp_pxp_blit(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src, lv_coord_t src_width,
lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa)
{
if(recolorEnabled) { /* switch to recolor version of blit */
lv_gpu_nxp_pxp_blit_recolor(dest, dest_width, src, src_width, copy_width, copy_height, opa, recolor, recolorOpa);
return;
};
PXP_Init(PXP);
PXP_EnableCsc1(PXP, false); /* Disable CSC1, it is enabled by default. */
PXP_SetProcessBlockSize(PXP, kPXP_BlockSize16); /* block size 16x16 for higher performance */
pxp_output_buffer_config_t outputBufferConfig;
pxp_as_buffer_config_t asBufferConfig;
pxp_as_blend_config_t asBlendConfig;
asBlendConfig.alpha = opa;
asBlendConfig.invertAlpha = false;
asBlendConfig.alphaMode = kPXP_AlphaRop;
asBlendConfig.ropMode = kPXP_RopMergeAs;
if(opa >= LV_OPA_MAX && !colorKeyEnabled) {
/* Simple blit, no effect - Disable PS buffer */
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
}
else {
/* Alpha blending or color keying enabled - PS must be enabled to fetch background pixels
PS and OUT buffers are the same, blend will be done in-place */
pxp_ps_buffer_config_t psBufferConfig = {
.pixelFormat = PXP_PS_PIXEL_FORMAT,
.swapByte = false,
.bufferAddr = (uint32_t)dest,
.bufferAddrU = 0U,
.bufferAddrV = 0U,
.pitchBytes = dest_width * sizeof(lv_color_t)
};
asBlendConfig.alphaMode = kPXP_AlphaOverride;
PXP_SetProcessSurfaceBufferConfig(PXP_ID, &psBufferConfig);
PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, copy_width - 1, copy_height - 1);
}
/* AS buffer - source image */
asBufferConfig.pixelFormat = PXP_AS_PIXEL_FORMAT;
asBufferConfig.bufferAddr = (uint32_t)src;
asBufferConfig.pitchBytes = src_width * sizeof(lv_color_t);
PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, copy_width - 1U, copy_height - 1U);
PXP_SetAlphaSurfaceBlendConfig(PXP_ID, &asBlendConfig);
lv_gpu_nxp_invalidate_cache(asBufferConfig.bufferAddr, copy_width, copy_height, asBufferConfig.pitchBytes, sizeof(lv_color_t));
if(colorKeyEnabled) {
PXP_SetAlphaSurfaceOverlayColorKey(PXP_ID, colorKey, colorKey);
}
PXP_EnableAlphaSurfaceOverlayColorKey(PXP_ID, colorKeyEnabled);
/* Output buffer. */
outputBufferConfig.pixelFormat = (pxp_output_pixel_format_t)PXP_OUT_PIXEL_FORMAT;
outputBufferConfig.interlacedMode = kPXP_OutputProgressive;
outputBufferConfig.buffer0Addr = (uint32_t)dest;
outputBufferConfig.buffer1Addr = (uint32_t)0U;
outputBufferConfig.pitchBytes = dest_width * sizeof(lv_color_t);
outputBufferConfig.width = copy_width;
outputBufferConfig.height = copy_height;
PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);
lv_gpu_nxp_invalidate_cache(outputBufferConfig.buffer0Addr, outputBufferConfig.width, outputBufferConfig.height, outputBufferConfig.pitchBytes, sizeof(lv_color_t));
lv_gpu_nxp_pxp_run(); /* Start PXP task */
}
/**
* @brief Enable color keying for subsequent calls to lv_gpu_nxp_pxp_blit()
*
* Color key is defined by LV_COLOR_TRANSP symbol in lv_conf.h
*/
void lv_gpu_nxp_pxp_enable_color_key(void)
{
colorKeyEnabled = true;
}
/**
* @brief Disable color keying for subsequent calls to lv_gpu_nxp_pxp_blit()
*
*/
void lv_gpu_nxp_pxp_disable_color_key(void)
{
colorKeyEnabled = false;
}
/**
* @brief Enable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit()
*
* @param[in] color recolor value
* @param[in] opa effect opacity
*/
void lv_gpu_nxp_pxp_enable_recolor(lv_color_t color, lv_opa_t opa)
{
recolorEnabled = true;
recolor = color;
recolorOpa = opa;
}
/**
* @brief Disable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit()
*/
void lv_gpu_nxp_pxp_disable_recolor(void)
{
recolorEnabled = false;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* @brief Start PXP job and wait for results
*
* Function used internally to start PXP task according current device
* configuration.
*/
static void lv_gpu_nxp_pxp_run(void)
{
pxp_cfg.pxp_run();
}
/**
* @brief BLock Image Transfer - copy rectangular image from src buffer to dst buffer with recoloring.
*
* Note that color keying and recoloring at the same time is not supported and black rectangle is rendered.
*
* @param[in/out] dest destination buffer
* @param[in] dest_width width (stride) of destination buffer in pixels
* @param[in] src source buffer
* @param[in] src_with width (stride) of source buffer in pixels
* @param[in] copy_w width of area to be copied from src to dest
* @param[in] copy_h height of area to be copied from src to dest
* @param[in] opa opacity of the result
* @param[in] recolor recolor value
* @param[in] recolorOpa effect opacity
*/
static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src,
lv_coord_t src_width,
lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa, lv_color_t recolor, lv_opa_t recolorOpa)
{
pxp_output_buffer_config_t outputBufferConfig;
pxp_as_buffer_config_t asBufferConfig;
if(colorKeyEnabled) {
/* should never get here, recolor & color keying not supported. Draw black box instead. */
const lv_area_t fill_area = {.x1 = 0, .y1 = 0, .x2 = copy_width - 1, .y2 = copy_height - 1};
lv_gpu_nxp_pxp_fill(dest, dest_width, &fill_area, LV_COLOR_BLACK, LV_OPA_MAX);
LV_LOG_WARN("Recoloring and color keying is not supported. Black rectangle rendered.");
return ;
}
else {
/* Recoloring without color keying */
if(opa > LV_OPA_MAX) {
/* Recolor with full opacity - AS source image, PS color generator, OUT destination */
PXP_Init(PXP);
PXP_EnableCsc1(PXP, false); /* Disable CSC1, it is enabled by default. */
PXP_SetProcessBlockSize(PXP, kPXP_BlockSize16); /* block size 16x16 for higher performance */
/* AS buffer - source image */
asBufferConfig.pixelFormat = PXP_AS_PIXEL_FORMAT;
asBufferConfig.bufferAddr = (uint32_t)src;
asBufferConfig.pitchBytes = src_width * sizeof(lv_color_t);
PXP_SetAlphaSurfaceBufferConfig(PXP_ID, &asBufferConfig);
PXP_SetAlphaSurfacePosition(PXP_ID, 0U, 0U, copy_width - 1U, copy_height - 1U);
lv_gpu_nxp_invalidate_cache(asBufferConfig.bufferAddr, copy_width, copy_height, asBufferConfig.pitchBytes, sizeof(lv_color_t));
/* Disable PS buffer, use as color generator */
PXP_SetProcessSurfacePosition(PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
PXP_SetProcessSurfaceBackGroundColor(PXP_ID, lv_color_to32(recolor));
/* Output buffer */
outputBufferConfig.pixelFormat = (pxp_output_pixel_format_t)PXP_OUT_PIXEL_FORMAT;
outputBufferConfig.interlacedMode = kPXP_OutputProgressive;
outputBufferConfig.buffer0Addr = (uint32_t)dest;
outputBufferConfig.buffer1Addr = (uint32_t)0U;
outputBufferConfig.pitchBytes = dest_width * sizeof(lv_color_t);
outputBufferConfig.width = copy_width;
outputBufferConfig.height = copy_height;
PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);
lv_gpu_nxp_invalidate_cache(outputBufferConfig.buffer0Addr, outputBufferConfig.width, outputBufferConfig.height, outputBufferConfig.pitchBytes, sizeof(lv_color_t));
pxp_porter_duff_config_t pdConfig;
/* Configure Porter-Duff blending - For RGB 565 only! */
pdConfig.enable = 1;
pdConfig.dstColorMode = kPXP_PorterDuffColorStraight;
pdConfig.srcColorMode = kPXP_PorterDuffColorStraight;
pdConfig.dstGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha;
pdConfig.srcGlobalAlphaMode = kPXP_PorterDuffGlobalAlpha;
pdConfig.srcFactorMode = kPXP_PorterDuffFactorStraight;
pdConfig.dstFactorMode = kPXP_PorterDuffFactorStraight;
pdConfig.srcGlobalAlpha = recolorOpa;
pdConfig.dstGlobalAlpha = 255 - recolorOpa;
pdConfig.srcAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */
pdConfig.dstAlphaMode = kPXP_PorterDuffAlphaStraight; /* don't care */
PXP_SetPorterDuffConfig(PXP_ID, &pdConfig);
lv_gpu_nxp_pxp_run(); /* Start PXP task */
}
else {
/* Recolor with transparency */
/* Step 1: Recolor with full opacity to temporary buffer */
lv_color_t * tmpBuf = (lv_color_t *) _lv_mem_buf_get(copy_width * copy_height * sizeof(lv_color_t));
lv_gpu_nxp_pxp_blit_recolor(tmpBuf, copy_width, src, src_width, copy_width, copy_height, LV_OPA_COVER, recolor,
recolorOpa);
/* Step 2: BLIT temporary results with required opacity to output */
lv_gpu_nxp_pxp_disable_recolor(); /* make sure to take BLIT path, not the recolor */
lv_gpu_nxp_pxp_blit(dest, dest_width, tmpBuf, copy_width, copy_width, copy_height, opa);
lv_gpu_nxp_pxp_enable_recolor(recolor, recolorOpa); /* restore state */
/* Step 3: Clean-up memory */
_lv_mem_buf_release(tmpBuf);
}
}
}
/**
* @brief Invalidate cache for rectangular area of memory
*
* @param[in] address starting address of area
* @param[in] width width of area in pixels
* @param[in] height height of area in pixels
* @param[in] stride stride in bytes
* @param[in] pxSize pixel size in bytes
*/
static void lv_gpu_nxp_invalidate_cache(uint32_t address, uint32_t width, uint32_t height, uint32_t stride, uint32_t pxSize) {
int y;
for (y = 0; y < height; y++) {
DCACHE_CleanInvalidateByRange(address, width*pxSize);
address += stride;
}
}
#endif /* LV_USE_GPU && LV_USE_GPU_NXP_PXP */

184
src/lv_gpu/lv_gpu_nxp_pxp.h Normal file
View File

@ -0,0 +1,184 @@
/**
* @file lv_gpu_nxp_pxp.h
*
*/
/**
* MIT License
*
* Copyright (c) 2020 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next paragraph)
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef LV_SRC_LV_GPU_LV_GPU_NXP_PXP_H_
#define LV_SRC_LV_GPU_LV_GPU_NXP_PXP_H_
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_color.h"
/*********************
* DEFINES
*********************/
/* PXP module instance to use */
#define PXP_ID PXP
/* PXP interrupt line ID */
#define PXP_IRQ_ID PXP_IRQn
/* Minimum area for image copy with 100% opacity to be handled by PXP */
#ifndef GPU_NXP_PXP_BLIT_SIZE_LIMIT
#define GPU_NXP_PXP_BLIT_SIZE_LIMIT 1
#endif
/* Minimum area for image copy with transparency to be handled by PXP */
#ifndef GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT
#define GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT 16
#endif
/* Minimum area to be filled by PXP with 100% opacity */
#ifndef GPU_NXP_PXP_FILL_SIZE_LIMIT
#define GPU_NXP_PXP_FILL_SIZE_LIMIT 64
#endif
/* Minimum area to be filled by PXP with transparency */
#ifndef GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT
#define GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT 32
#endif
/**********************
* TYPEDEFS
**********************/
/**
* NXP PXP device configuration - call-backs used for
* interrupt init/wait/deinit.
*/
typedef struct {
/** Callback for PXP interrupt initialization */
lv_res_t (*pxp_interrupt_init)(void);
/** Callback for PXP interrupt de-initialization */
void (*pxp_interrupt_deinit)(void);
/** Callback that should start PXP and wait for operation complete */
void (*pxp_run)(void);
} lv_nxp_pxp_cfg_t;
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Reset and initialize PXP device. This function should be called as a part
* of display init sequence.
*
* @return LV_RES_OK: PXP init ok; LV_RES_INV: init error. See error log for more information.
*/
lv_res_t lv_gpu_nxp_pxp_init(lv_nxp_pxp_cfg_t *cfg);
/**
* Disable PXP device. Should be called during display deinit sequence.
*/
void lv_gpu_nxp_pxp_deinit(void);
/**
* Fill area, with optional opacity.
*
* @param[in/out] dest_buf destination buffer
* @param[in] dest_width width (stride) of destination buffer in pixels
* @param[in] fill_area area to fill
* @param[in] color color
* @param[in] opa transparency of the color
*/
void lv_gpu_nxp_pxp_fill(lv_color_t *dest_buf, lv_coord_t dest_width, const lv_area_t *fill_area, lv_color_t color, lv_opa_t opa);
/**
* @brief BLock Image Transfer - copy rectangular image from src buffer to dst buffer with effects.
*
* By default, image is copied directly, with optional opacity configured by \p opa.
* Color keying can be enabled by calling lv_gpu_nxp_pxp_enable_color_key() before calling this function.
* Recoloring can be enabled by calling lv_gpu_nxp_pxp_enable_recolor() before calling this function.
* Note that color keying and recoloring at the same time is not supported and black rectangle is rendered.
*
* @param[in/out] dest destination buffer
* @param[in] dest_width width (stride) of destination buffer in pixels
* @param[in] src source buffer
* @param[in] src_with width (stride) of source buffer in pixels
* @param[in] copy_w width of area to be copied from src to dest
* @param[in] copy_h height of area to be copied from src to dest
* @param[in] opa opacity of the result
*/
void lv_gpu_nxp_pxp_blit(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src, lv_coord_t src_width, lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa);
/**
* @brief Enable color keying for subsequent calls to lv_gpu_nxp_pxp_blit()
*
* Color key is defined by LV_COLOR_TRANSP symbol in lv_conf.h
*/
void lv_gpu_nxp_pxp_enable_color_key(void);
/**
* @brief Disable color keying for subsequent calls to lv_gpu_nxp_pxp_blit()
*
*/
void lv_gpu_nxp_pxp_disable_color_key(void);
/**
* @brief Enable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit()
*
* @param[in] color recolor value
* @param[in] opa effect opacity
*/
void lv_gpu_nxp_pxp_enable_recolor(lv_color_t color, lv_opa_t opa);
/**
* @brief Disable recolor feature for subsequent calls to lv_gpu_nxp_pxp_blit()
*/
void lv_gpu_nxp_pxp_disable_recolor(void);
/**********************
* STATIC FUNCTIONS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV_SRC_LV_GPU_LV_GPU_NXP_PXP_H_ */

View File

@ -0,0 +1,166 @@
/**
* @file lv_gpu_nxp_pxp_osa.c
*
*/
/**
* MIT License
*
* Copyright (c) 2020 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next paragraph)
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_conf.h"
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
#include "lv_gpu_nxp_pxp.h"
#include "fsl_pxp.h"
#if defined(FSL_RTOS_FREE_RTOS)
#include "FreeRTOS.h"
#include "semphr.h"
#endif
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void);
static void _lv_gpu_nxp_pxp_interrupt_deinit(void);
static void _lv_gpu_nxp_pxp_run(void);
/**********************
* STATIC VARIABLES
**********************/
#if defined(FSL_RTOS_FREE_RTOS)
static SemaphoreHandle_t s_pxpIdle;
#else
static volatile bool s_pxpIdle;
#endif
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* PXP device interrupt handler. Used to check PXP task completion status.
*/
void PXP_IRQHandler(void)
{
#if defined(FSL_RTOS_FREE_RTOS)
BaseType_t taskAwake = pdFALSE;
#endif
if(kPXP_CompleteFlag & PXP_GetStatusFlags(PXP_ID)) {
PXP_ClearStatusFlags(PXP_ID, kPXP_CompleteFlag);
#if defined(FSL_RTOS_FREE_RTOS)
xSemaphoreGiveFromISR(s_pxpIdle, &taskAwake);
portYIELD_FROM_ISR(taskAwake);
#else
s_pxpIdle = true;
#endif
}
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* PXP interrupt initialization.
*/
static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void)
{
#if defined(FSL_RTOS_FREE_RTOS)
s_pxpIdle = xSemaphoreCreateBinary();
if(s_pxpIdle == NULL) {
return LV_RES_INV;
}
NVIC_SetPriority(PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
#else
s_pxpIdle = true;
#endif
NVIC_EnableIRQ(PXP_IRQ_ID);
return LV_RES_OK;
}
/**
* PXP interrupt de-initialization.
*/
static void _lv_gpu_nxp_pxp_interrupt_deinit(void)
{
NVIC_DisableIRQ(PXP_IRQ_ID);
#if defined(FSL_RTOS_FREE_RTOS)
vSemaphoreDelete(s_pxpIdle);
#endif
}
/**
* Function to start PXP job. This function must wait for task complete.
*/
static void _lv_gpu_nxp_pxp_run(void)
{
#if !defined(FSL_RTOS_FREE_RTOS)
s_pxpIdle = false;
#endif
PXP_EnableInterrupts(PXP_ID, kPXP_CompleteInterruptEnable);
PXP_Start(PXP_ID);
#if defined(FSL_RTOS_FREE_RTOS)
if(xSemaphoreTake(s_pxpIdle, portMAX_DELAY) != pdTRUE) {
LV_LOG_ERROR("xSemaphoreTake error. Task halted.");
for(; ;) ;
}
#else
while(s_pxpIdle == false) {
}
#endif
}
lv_nxp_pxp_cfg_t pxp_default_cfg = {
.pxp_interrupt_init = _lv_gpu_nxp_pxp_interrupt_init,
.pxp_interrupt_deinit = _lv_gpu_nxp_pxp_interrupt_deinit,
.pxp_run = _lv_gpu_nxp_pxp_run
};
#endif /* LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT */

View File

@ -0,0 +1,47 @@
/**
* @file lv_gpu_nxp_pxp_osa.h
*
*/
/**
* MIT License
*
* Copyright (c) 2020 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next paragraph)
* shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef LV_SRC_LV_GPU_LV_GPU_NXP_PXP_OSA_H_
#define LV_SRC_LV_GPU_LV_GPU_NXP_PXP_OSA_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "lv_conf.h"
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
extern lv_nxp_pxp_cfg_t pxp_default_cfg;
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV_SRC_LV_GPU_LV_GPU_NXP_PXP_OSA_H_ */

View File

@ -81,7 +81,7 @@ void lv_debug_log_error(const char * msg, uint64_t value);
# define LV_ASSERT_NULL(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "NULL pointer", p);
# endif
#else
# define LV_ASSERT_NULL(p) true
# define LV_ASSERT_NULL(p)
#endif
#if LV_USE_ASSERT_MEM
@ -89,7 +89,7 @@ void lv_debug_log_error(const char * msg, uint64_t value);
# define LV_ASSERT_MEM(p) LV_DEBUG_ASSERT(LV_DEBUG_IS_NULL(p), "Out of memory", p);
# endif
#else
# define LV_ASSERT_MEM(p) true
# define LV_ASSERT_MEM(p)
#endif
#if LV_USE_ASSERT_MEM_INTEGRITY
@ -97,7 +97,7 @@ void lv_debug_log_error(const char * msg, uint64_t value);
# define LV_ASSERT_MEM_INTEGRITY() LV_DEBUG_ASSERT(LV_DEBUG_CHECK_MEM_INTEGRITY(), "Memory integrity error", 0);
# endif
#else
# define LV_ASSERT_MEM_INTEGRITY() true
# define LV_ASSERT_MEM_INTEGRITY()
#endif
#if LV_USE_ASSERT_STR
@ -108,7 +108,7 @@ void lv_debug_log_error(const char * msg, uint64_t value);
# if LV_USE_ASSERT_NULL /*Use at least LV_ASSERT_NULL if enabled*/
# define LV_ASSERT_STR(str) LV_ASSERT_NULL(str)
# else
# define LV_ASSERT_STR(str) true
# define LV_ASSERT_STR(str)
# endif
#endif
@ -117,11 +117,11 @@ void lv_debug_log_error(const char * msg, uint64_t value);
#define LV_DEBUG_ASSERT(expr, msg, value) do{}while(0)
#define LV_ASSERT_NULL(p) true
#define LV_ASSERT_MEM(p) true
#define LV_ASSERT_MEM_INTEGRITY() true
#define LV_ASSERT_STR(p) true
#define LV_ASSERT_OBJ(obj, obj_type) true
#define LV_ASSERT_NULL(p)
#define LV_ASSERT_MEM(p)
#define LV_ASSERT_MEM_INTEGRITY()
#define LV_ASSERT_STR(p)
#define LV_ASSERT_OBJ(obj, obj_type)
#endif /* LV_USE_DEBUG */
/*clang-format on*/

View File

@ -79,75 +79,42 @@ void _lv_log_add(lv_log_level_t level, const char * file, int line, const char *
#if LV_LOG_LEVEL <= LV_LOG_LEVEL_TRACE
#define LV_LOG_TRACE(...) _lv_log_add(LV_LOG_LEVEL_TRACE, __FILE__, __LINE__, __func__, __VA_ARGS__);
#else
#define LV_LOG_TRACE(...) \
{ \
; \
}
#define LV_LOG_TRACE(...)
#endif
#if LV_LOG_LEVEL <= LV_LOG_LEVEL_INFO
#define LV_LOG_INFO(...) _lv_log_add(LV_LOG_LEVEL_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__);
#else
#define LV_LOG_INFO(...) \
{ \
; \
}
#define LV_LOG_INFO(...)
#endif
#if LV_LOG_LEVEL <= LV_LOG_LEVEL_WARN
#define LV_LOG_WARN(...) _lv_log_add(LV_LOG_LEVEL_WARN, __FILE__, __LINE__, __func__, __VA_ARGS__);
#else
#define LV_LOG_WARN(...) \
{ \
; \
}
#define LV_LOG_WARN(...)
#endif
#if LV_LOG_LEVEL <= LV_LOG_LEVEL_ERROR
#define LV_LOG_ERROR(...) _lv_log_add(LV_LOG_LEVEL_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__);
#else
#define LV_LOG_ERROR(...) \
{ \
; \
}
#define LV_LOG_ERROR(...)
#endif
#if LV_LOG_LEVEL <= LV_LOG_LEVEL_USER
#define LV_LOG_USER(...) _lv_log_add(LV_LOG_LEVEL_USER, __FILE__, __LINE__, __func__, __VA_ARGS__);
#else
#define LV_LOG_USER(...) \
{ \
; \
}
#define LV_LOG_USER(...)
#endif
#else /*LV_USE_LOG*/
/*Do nothing if `LV_USE_LOG 0`*/
#define _lv_log_add(level, file, line, ...) \
{ \
; \
}
#define LV_LOG_TRACE(...) \
{ \
; \
}
#define LV_LOG_INFO(...) \
{ \
; \
}
#define LV_LOG_WARN(...) \
{ \
; \
}
#define LV_LOG_ERROR(...) \
{ \
; \
}
#define LV_LOG_USER(...) \
{ \
; \
}
#define _lv_log_add(level, file, line, ...)
#define LV_LOG_TRACE(...)
#define LV_LOG_INFO(...)
#define LV_LOG_WARN(...)
#define LV_LOG_ERROR(...)
#define LV_LOG_USER(...)
#endif /*LV_USE_LOG*/
#ifdef __cplusplus

View File

@ -42,8 +42,6 @@ extern "C" {
#define LV_BEZIER_VAL_MAX 1024 /**< Max time in Bezier functions (not [0..1] to use integers) */
#define LV_BEZIER_VAL_SHIFT 10 /**< log2(LV_BEZIER_VAL_MAX): used to normalize up scaled values*/
/**********************
* TYPEDEFS
**********************/

View File

@ -705,6 +705,7 @@ static void lv_bar_set_value_with_anim(lv_obj_t * bar, int16_t new_value, int16_
anim_info->anim_start = anim_info->anim_end;
anim_info->anim_end = new_value;
}
*value_ptr = new_value;
/* Stop the previous animation if it exists */
lv_anim_del(anim_info, NULL);

View File

@ -621,6 +621,10 @@ void lv_dropdown_open(lv_obj_t * ddlist)
lv_obj_set_y(ext->list, lv_obj_get_y(ext->list) - (ext->list->coords.y2 - LV_VER_RES));
}
}
if(lv_label_get_align(label) == LV_LABEL_ALIGN_RIGHT) {
lv_obj_set_x(label, lv_obj_get_width_fit(ext->list) - lv_obj_get_width(label));
}
}
/**
@ -685,7 +689,11 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c
const char * txt;
txt = ext->dir != LV_DIR_LEFT ? opt_txt : ext->symbol;
bool rev = false;
if(ext->dir == LV_DIR_LEFT) rev = true;
if(lv_obj_get_base_dir(ddlist) == LV_BIDI_DIR_RTL) rev = true;
txt = rev ? ext->symbol : opt_txt;
if(txt) {
_lv_txt_get_size(&txt_size, txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX,
label_dsc.flag);
@ -705,7 +713,7 @@ static lv_design_res_t lv_dropdown_design(lv_obj_t * ddlist, const lv_area_t * c
lv_draw_label(&txt_area, clip_area, &label_dsc, txt, NULL);
}
txt = ext->dir != LV_DIR_LEFT ? ext->symbol : opt_txt;
txt = rev ? opt_txt : ext->symbol;
if(txt) {
_lv_txt_get_size(&txt_size, txt, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX,
label_dsc.flag);

View File

@ -1,4 +1,3 @@
/**
* @file lv_roller.c
*

View File

@ -123,8 +123,8 @@ void lv_switch_on(lv_obj_t * sw, lv_anim_enable_t anim)
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
lv_switch_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->state = 1;
if(lv_bar_get_value(sw) == 1)
return;
lv_bar_set_value(sw, 1, anim);
lv_obj_add_state(sw, LV_STATE_CHECKED);
}
@ -141,8 +141,8 @@ void lv_switch_off(lv_obj_t * sw, lv_anim_enable_t anim)
#if LV_USE_ANIMATION == 0
anim = LV_ANIM_OFF;
#endif
lv_switch_ext_t * ext = lv_obj_get_ext_attr(sw);
ext->state = 0;
if(lv_bar_get_value(sw) == 0)
return;
lv_bar_set_value(sw, 0, anim);
lv_obj_clear_state(sw, LV_STATE_CHECKED);
}

View File

@ -36,7 +36,6 @@ typedef struct {
lv_bar_ext_t bar; /*Ext. of ancestor*/
/*New data for this type */
lv_style_list_t style_knob; /*Style of the knob*/
uint8_t state : 1; /*The current state*/
} lv_switch_ext_t;
/**
@ -112,8 +111,7 @@ static inline void lv_switch_set_anim_time(lv_obj_t * sw, uint16_t anim_time)
*/
static inline bool lv_switch_get_state(const lv_obj_t * sw)
{
lv_switch_ext_t * ext = (lv_switch_ext_t *)lv_obj_get_ext_attr(sw);
return ext->state ? true : false;
return lv_bar_get_value(sw) == 1 ? true : false;
}
/**

View File

@ -14,6 +14,7 @@
#include "../lv_misc/lv_txt.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_label.h"
#include "../lv_misc/lv_printf.h"
#include "../lv_themes/lv_theme.h"
/*********************
@ -172,11 +173,117 @@ void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const
format.s.crop = 0;
}
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/
#if LV_USE_ARABIC_PERSIAN_CHARS
/*Get the size of the Arabic text and process it*/
size_t len_ap = _lv_txt_ap_calc_bytes_cnt(txt);
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], len_ap + 1);
LV_ASSERT_MEM(ext->cell_data[cell]);
if(ext->cell_data[cell] == NULL) return;
strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/
_lv_txt_ap_proc(txt, &ext->cell_data[cell][1]);
#else
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], strlen(txt) + 2); /*+1: trailing '\0; +1: format byte*/
LV_ASSERT_MEM(ext->cell_data[cell]);
if(ext->cell_data[cell] == NULL) return;
strcpy(ext->cell_data[cell] + 1, txt); /*+1 to skip the format byte*/
#endif
ext->cell_data[cell][0] = format.format_byte;
refr_size(table);
}
/**
* Set the value of a cell. Memory will be allocated to store the text by the table.
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param fmt `printf`-like format
*/
void lv_table_set_cell_value_fmt(lv_obj_t * table, uint16_t row, uint16_t col, const char * fmt, ...)
{
LV_ASSERT_OBJ(table, LV_OBJX_NAME);
LV_ASSERT_STR(fmt);
lv_table_ext_t * ext = lv_obj_get_ext_attr(table);
if(col >= ext->col_cnt) {
LV_LOG_WARN("lv_table_set_cell_value: invalid column");
return;
}
/*Auto expand*/
if(row >= ext->row_cnt) {
lv_table_set_row_cnt(table, row + 1);
}
uint32_t cell = row * ext->col_cnt + col;
lv_table_cell_format_t format;
/*Save the format byte*/
if(ext->cell_data[cell]) {
format.format_byte = ext->cell_data[cell][0];
}
/*Initialize the format byte*/
else {
lv_bidi_dir_t base_dir = lv_obj_get_base_dir(table);
if(base_dir == LV_BIDI_DIR_LTR) format.s.align = LV_LABEL_ALIGN_LEFT;
else if(base_dir == LV_BIDI_DIR_RTL) format.s.align = LV_LABEL_ALIGN_RIGHT;
else if(base_dir == LV_BIDI_DIR_AUTO)
#if LV_USE_BIDI
format.s.align = _lv_bidi_detect_base_dir(fmt);
#else
format.s.align = LV_LABEL_ALIGN_LEFT;
#endif
format.s.right_merge = 0;
format.s.type = 0;
format.s.crop = 0;
}
va_list ap, ap2;
va_start(ap, fmt);
va_copy(ap2, ap);
/*Allocate space for the new text by using trick from C99 standard section 7.19.6.12 */
uint32_t len = lv_vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
#if LV_USE_ARABIC_PERSIAN_CHARS
/*Put together the text according to the format string*/
char * raw_txt = _lv_mem_buf_get(len + 1);
LV_ASSERT_MEM(raw_txt);
if(raw_txt == NULL) {
va_end(ap2);
return;
}
lv_vsnprintf(raw_txt, len + 1, fmt, ap2);
/*Get the size of the Arabic text and process it*/
size_t len_ap = _lv_txt_ap_calc_bytes_cnt(raw_txt);
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], len_ap + 1);
LV_ASSERT_MEM(ext->cell_data[cell]);
if(ext->cell_data[cell] == NULL) {
va_end(ap2);
return;
}
_lv_txt_ap_proc(raw_txt, &ext->cell_data[cell][1]);
_lv_mem_buf_release(raw_txt);
#else
ext->cell_data[cell] = lv_mem_realloc(ext->cell_data[cell], len + 2); /*+1: trailing '\0; +1: format byte*/
LV_ASSERT_MEM(ext->cell_data[cell]);
if(ext->cell_data[cell] == NULL) {
va_end(ap2);
return;
}
ext->cell_data[cell][len + 1] = 0; /* Ensure NULL termination */
lv_vsnprintf(&ext->cell_data[cell][1], len + 1, fmt, ap2);
#endif
va_end(ap2);
ext->cell_data[cell][0] = format.format_byte;
refr_size(table);

View File

@ -111,6 +111,15 @@ lv_obj_t * lv_table_create(lv_obj_t * par, const lv_obj_t * copy);
*/
void lv_table_set_cell_value(lv_obj_t * table, uint16_t row, uint16_t col, const char * txt);
/**
* Set the value of a cell. Memory will be allocated to store the text by the table.
* @param table pointer to a Table object
* @param row id of the row [0 .. row_cnt -1]
* @param col id of the column [0 .. col_cnt -1]
* @param fmt `printf`-like format
*/
void lv_table_set_cell_value_fmt(lv_obj_t * table, uint16_t row, uint16_t col, const char * fmt, ...);
/**
* Set the number of rows
* @param table table pointer to a Table object

View File

@ -247,7 +247,6 @@ void lv_textarea_add_char(lv_obj_t * ta, uint32_t c)
return;
}
if(ext->pwd_mode != 0) pwd_char_hider(ta); /*Make sure all the current text contains only '*'*/
/*If the textarea is empty, invalidate it to hide the placeholder*/