feat(gpu): improve NXP's PXP and VGLite accelerators (#3952)

Signed-off-by: Nicușor Cîțu <nicusor.citu@nxp.com>
Signed-off-by: Stefan Babatie <stefan.babatie@nxp.com>
Signed-off-by: Wenbin Yuan <wenbin.yuan@nxp.com>
Co-authored-by: Stefan Babatie <stefan.babatie@nxp.com>
Co-authored-by: Wenbin Yuan <wenbin.yuan@nxp.com>
This commit is contained in:
nicusorcitu
2023-02-01 11:35:24 +02:00
committed by GitHub
parent 39f424767f
commit 361ee79611
33 changed files with 2647 additions and 1696 deletions

View File

@@ -1,6 +1,6 @@
# NXP
NXP has integrated LVGL into the MCUXpresso SDK packages for several of their general purpose and crossover
microcontrollers, allowing easy evaluation and migration into your product design.
NXP has integrated LVGL into the MCUXpresso SDK packages for general purpose and crossover microcontrollers, allowing
easy evaluation and migration into your product design.
[Download an SDK for a supported board](https://www.nxp.com/design/software/embedded-software/littlevgl-open-source-graphics-library:LITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY?&tid=vanLITTLEVGL-OPEN-SOURCE-GRAPHICS-LIBRARY)
today and get started with your next GUI application.
@@ -10,42 +10,38 @@ with PXP/VGLite support if the modules are present), no additional integration w
## HW acceleration for NXP iMX RT platforms
Depending on the RT platform used, the acceleration can be done by NXP PXP (PiXel Pipeline) and/or the Verisilicon GPU
through an API named VGLite. There is a single NXP draw context that covers both GPUs allowing to have enabled either
one or even both at the same time. While enableing both 2D accelerators, the VGLite can be used to accelerate widget
drawing while the PXP accelerated blit and fill operations.
Supported draw callbacks are available in "src/draw/nxp/lv_gpu_nxp.c":
```c
nxp_draw_ctx->base_draw.draw_arc = lv_draw_nxp_arc;
nxp_draw_ctx->base_draw.draw_rect = lv_draw_nxp_rect;
nxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_nxp_img_decoded;
nxp_draw_ctx->blend = lv_draw_nxp_blend;
```
If enabled both GPUs, the PXP is the preffered one to be used for drawing operation. A fallback mechanism is
implemented so that if the feature is not supported by PXP (or if PXP fails), the VGLite will take over to handle the
task. At the end, the CPU will assure that every widget drawing is fully covered (if not already done by GPU).
through an API named VGLite. Each accelerator has its own context that allows them to be used individually as well
simultaneously (in LVGL multithreading mode).
### PXP accelerator
Several drawing features in LVGL can be offloaded to the PXP engine. The VGLite (if supported) and CPU are available for
other operations while the PXP is running. An RTOS is required to block the LVGL drawing thread and switch to another
task or suspend the CPU for power savings.
Several drawing features in LVGL can be offloaded to the PXP engine. The CPU is available for other operations while the
PXP is running. RTOS is required to block the LVGL drawing thread and switch to another task or suspend the CPU for
power savings.
Supported draw callbacks are available in "src/draw/nxp/pxp/lv_draw_pxp.c":
```c
pxp_draw_ctx->base_draw.draw_img_decoded = lv_draw_pxp_img_decoded;
pxp_draw_ctx->blend = lv_draw_pxp_blend;
pxp_draw_ctx->base_draw.wait_for_finish = lv_draw_pxp_wait_for_finish;
```
#### Features supported:
All operations can be used in conjunction with optional transparency.
- RGB565 and ARGB8888 color formats
- Area fill + optional transparency
- BLIT (BLock Image Transfer) + optional transparency
- Color keying + optional transparency
- Recoloring (color tint) + optional transparency
- Image Rotation (90, 180, 270 degree) + optional transparency
- Recoloring (color tint) + Image Rotation (90, 180, 270 degree) + optional transparency
- Area fill with color
- BLIT (BLock Image Transfer)
- Screen Rotation (90, 180, 270 degree)
- Color keying
- Recoloring (color tint)
- Image Rotation (90, 180, 270 degree)
- RTOS integration layer
- Default FreeRTOS and bare metal code provided
- Combination of recolor and/or rotation + color key/alpha blend/transparency is supported but PXP needs two steps.
First step is to recolor/rotate the image to a temporarly buffer (please check LV_MEM_SIZE value for allocation limit)
and another step is required to handle color keying, alpha chanel or to apply transparency.
- Combination of recolor and/or rotation + color key/alpha blend/transparency is supported.
That is achieved by PXP in two steps:
- First step is to recolor/rotate the image to a temporary buffer (statically allocated)
- Second step is required to handle color keying, alpha channel or to apply transparency
#### Known limitations:
- Rotation is not supported for images unaligned to blocks of 16x16 pixels.
@@ -78,51 +74,69 @@ and the final output image can look shifted.
#### Project setup:
- Add PXP related files to project:
- src/draw/nxp/pxp/lv_gpu_nxp_pxp.c, src/draw/nxp/pxp/lv_gpu_nxp_pxp.h: init, uninit, run/wait PXP device, log/trace
- src/draw/nxp/pxp/lv_draw_pxp_blend.c, src/draw/nxp/pxp/lv_draw_pxp_blend.h: fill and blit (w/o transformation)
- src/draw/nxp/pxp/lv_gpu_nxp_osa.c, src/draw/nxp/pxp/lv_gpu_osa.h: default implementation of OS-specific functions
(bare metal and FreeRTOS only)
- src/draw/nxp/pxp/lv_draw_pxp.c[.h]: draw context callbacks
- src/draw/nxp/pxp/lv_draw_pxp_blend.c[.h]: fill and blit (with optional transformation)
- src/draw/nxp/pxp/lv_gpu_nxp_pxp.c[.h]: init, uninit, run/wait PXP device
- src/draw/nxp/pxp/lv_gpu_nxp_pxp_osa.c[.h]: OS abstraction (FreeRTOS or bare metal)
- optional, required only if `LV_USE_GPU_NXP_PXP_AUTO_INIT` is set to 1
- PXP related code depends on two drivers provided by MCU SDK. These drivers need to be added to project:
- fsl_pxp.c, fsl_pxp.h: PXP driver
- fsl_cache.c, fsl_cache.h: CPU cache handling functions
- fsl_pxp.c[.h]: PXP driver
- fsl_cache.c[.h]: CPU cache handling functions
#### Logging:
- By default, LV_GPU_NXP_PXP_LOG_ERRORS is enabled so that any PXP error will be seen on LVGL output
- For tracing logs about the PXP limitations or size thresholds, the user can enable LV_GPU_NXP_PXP_LOG_TRACES
- By default, `LV_GPU_NXP_PXP_LOG_ERRORS` is enabled so that any PXP error will be seen on SDK debug console
- By default, `LV_GPU_NXP_PXP_LOG_TRACES` is disabled. Enable it for tracing logs (like PXP limitations)
#### Advanced configuration:
- Implementation depends on multiple OS-specific functions. The struct `lv_nxp_pxp_cfg_t` with callback pointers is
used as a parameter for the `lv_gpu_nxp_pxp_init()` function. Default implementation for FreeRTOS and baremetal is
provided in lv_gpu_nxp_osa.c
used as a parameter for the `lv_gpu_nxp_pxp_init()` function. Default implementation for FreeRTOS and bare metal is
provided in lv_gpu_nxp_pxp_osa.c
- `pxp_interrupt_init()`: Initialize PXP interrupt (HW setup, OS setup)
- `pxp_interrupt_deinit()`: Deinitialize PXP interrupt (HW setup, OS setup)
- `pxp_run()`: Start PXP job. Use OS-specific mechanism to block drawing thread. PXP must finish drawing before
leaving this function.
- There are configurable area thresholds which are used to decide whether the area will be processed by CPU or by PXP.
Areas smaller than a defined value will be processed by CPU and those bigger than the threshold will be processed by
PXP. These thresholds may be defined as preprocessor variables. Default values are defined in lv_draw_pxp_blend.h
- `LV_GPU_NXP_PXP_BLIT_SIZE_LIMIT`: size threshold for image BLIT, BLIT with color keying, BLIT with recolor and
BLIT with rotation (OPA >= LV_OPA_MAX)
- `LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT`: size threshold for image BLIT, BLIT with color keying, BLIT with recolor
and BLIT with rotation and transparency (OPA < LV_OPA_MAX)
- `LV_GPU_NXP_PXP_FILL_SIZE_LIMIT`: size threshold for fill operation (OPA >= LV_OPA_MAX)
- `LV_GPU_NXP_PXP_FILL_OPA_SIZE_LIMIT`: size threshold for fill operation with transparency (OPA < LV_OPA_MAX)
- Area threshold (size limit) is configurable and used to decide whether the area will be processed by PXP or not.
Areas smaller than the defined value will be processed by CPU and those bigger than the threshold will be processed by
PXP. The threshold is defined as a macro in lv_draw_pxp.c
- `LV_GPU_NXP_PXP_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)
### VGLite accelerator
Extra drawing features in LVGL can be handled by the VGLite engine. The PXP (if supported) and CPU are available for
other operations while the VGLite is running. An RTOS is required to block the LVGL drawing thread and switch to another
task or suspend the CPU for power savings.
Extra drawing features in LVGL can be handled by the VGLite engine. The CPU is available for other operations while the
VGLite is running. An RTOS is required to block the LVGL drawing thread and switch to another task or suspend the CPU
for power savings.
Supported draw callbacks are available in "src/draw/nxp/vglite/lv_draw_vglite.c":
```c
vglite_draw_ctx->base_draw.init_buf = lv_draw_vglite_init_buf;
vglite_draw_ctx->base_draw.draw_line = lv_draw_vglite_line;
vglite_draw_ctx->base_draw.draw_arc = lv_draw_vglite_arc;
vglite_draw_ctx->base_draw.draw_rect = lv_draw_vglite_rect;
vglite_draw_ctx->base_draw.draw_img_decoded = lv_draw_vglite_img_decoded;
vglite_draw_ctx->blend = lv_draw_vglite_blend;
vglite_draw_ctx->base_draw.wait_for_finish = lv_draw_vglite_wait_for_finish;
```
#### Features supported:
All operations can be used in conjunction with optional transparency.
- RGB565 and ARGB8888 color formats
- Area fill + optional transparency
- BLIT (BLock Image Transfer) + optional transparency
- Image Rotation (any degree with decimal) + optional transparency
- Image Scale + optional transparency
- Draw background rectangle with radius or gradient
- Draw arc
- RTOS integration layer
- Area fill with color
- BLIT (BLock Image Transfer)
- Image Rotation (any degree with decimal)
- Image Scale
- Draw rectangle background with optional radius or gradient
- Blit rectangle background image
- Draw rectangle border/outline with optional rounded corners
- Draw arc with optional rounded ending
- Draw line or dashed line with optional rounded ending
#### Known limitations:
- Source image alignment:
The byte alignment requirement for a pixel depends on the specific pixel format. Both buffer address and buffer stride
must be aligned. As general rule, the alignment is set to 16 pixels. This makes the buffer address alignment to be
32 bytes for RGB565 and 64 bytes for ARGB8888.
- For pixel engine (PE) destination, the alignment should be 64 bytes for all tiled (4x4) buffer layouts.
The pixel engine has no additional alignment requirement for linear buffer layouts (`VG_LITE_LINEAR`).
#### Basic configuration:
- Select NXP VGLite engine in lv_conf.h: Set `LV_USE_GPU_NXP_VG_LITE` to 1
@@ -130,8 +144,8 @@ task or suspend the CPU for power savings.
#### Basic initialization:
- Initialize VGLite before calling `lv_init()` by specifying the width/height of tessellation window. Value should be
a multiple of 16; minimum value is 16 pixels, maximum cannot be greater than frame width. If less than or equal to 0,
then no tessellation buffer is created, in which case the function is used for a blit init.
a multiple of 16; minimum value is 16 pixels, maximum cannot be greater than the frame width. If less than or equal
to 0, then no tessellation buffer is created, in which case VGLite is initialized only for blitting.
```c
#if LV_USE_GPU_NXP_VG_LITE
#include "vg_lite.h"
@@ -144,25 +158,21 @@ task or suspend the CPU for power savings.
#### Project setup:
- Add VGLite related files to project:
- src/draw/nxp/vglite/lv_gpu_nxp_vglite.c, src/draw/nxp/vglite/lv_gpu_nxp_vglite.h: buffer init, log/trace
- src/draw/nxp/vglite/lv_draw_vglite_blend.c, src/draw/nxp/vglite/lv_draw_vglite_blend.h: fill and blit
(w/o transformation)
- src/draw/nxp/vglite/lv_draw_vglite_rect.c, src/draw/nxp/vglite/lv_draw_vglite_rect.h: rectangle draw
- src/draw/nxp/vglite/lv_draw_vglite_arc.c, src/draw/nxp/vglite/lv_draw_vglite_arc.h: arc draw
- src/draw/nxp/vglite/lv_draw_vglite.c[.h]: draw context callbacks
- src/draw/nxp/vglite/lv_draw_vglite_blend.c[.h]: fill and blit (with optional transformation)
- src/draw/nxp/vglite/lv_draw_vglite_rect.c[.h]: draw rectangle
- src/draw/nxp/vglite/lv_draw_vglite_arc.c[.h]: draw arc
- src/draw/nxp/vglite/lv_draw_vglite_line.c[.h]: draw line
- src/draw/nxp/vglite/lv_vglite_buf.c[.h]: init/get vglite buffer
- src/draw/nxp/vglite/lv_vglite_utils.c[.h]: function helpers
#### Logging:
- By default, LV_GPU_NXP_VG_LITE_LOG_ERRORS is enabled so that any VGLite error will be seen on LVGL output
- For tracing logs about the VGLite limitations, size thresholds or stride alignment, the user can enable
LV_GPU_NXP_VG_LITE_LOG_TRACES
- By default, `LV_GPU_NXP_VG_LITE_LOG_ERRORS` is enabled so that any VGLite error will be seen on SDK debug console
- By default, `LV_GPU_NXP_VG_LITE_LOG_TRACES` is disabled. Enable it for tracing logs (like blit split workaround or
VGLite fallback to CPU due to any error on the driver)
#### Advanced configuration:
- There are configurable area thresholds which are used to decide whether the area will be processed by CPU or by
VGLite. Areas smaller than a defined value will be processed by CPU and those bigger than the threshold will be
processed by VGLite. These thresholds may be defined as preprocessor variables. Default values are defined in
lv_draw_vglite_blend.h
- `LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT`: size threshold for image BLIT, BLIT with scale and BLIT with rotation
(OPA >= LV_OPA_MAX)
- `LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT`: size threshold for image BLIT, BLIT with scale and BLIT with rotation
and transparency (OPA < LV_OPA_MAX)
- `LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT`: size threshold for fill operation (OPA >= LV_OPA_MAX)
- `LV_GPU_NXP_VG_LITE_FILL_OPA_SIZE_LIMIT`: size threshold for fill operation with transparency (OPA < LV_OPA_MAX)
- Area threshold (size limit) is configurable and used to decide whether the area will be processed by VGLite or not.
Areas smaller than the defined value will be processed by CPU and those bigger than the threshold will be processed by
VGLite. The threshold is defined as a macro in lv_draw_vglite.c
- `LV_GPU_NXP_VG_LITE_SIZE_LIMIT`: size threshold for fill/blit (with optional transformation)