feat(gpu): add gpu arm2d (#3162)
* feat(gpu): add support for arm-2d * fix(hal): fix typos * feat(cmsis-pack): v1.0.2-alpha2 for monthly update * update format for lv_gpu_arm2d.c * Update LVGL.lvgl.1.0.2-alpha1.pack
This commit is contained in:
6
Kconfig
6
Kconfig
@@ -208,8 +208,14 @@ menu "LVGL configuration"
|
|||||||
config LV_USE_EXTERNAL_RENDERER
|
config LV_USE_EXTERNAL_RENDERER
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
config LV_USE_GPU_ARM2D
|
||||||
|
bool "Enable Arm's 2D image processing library (Arm-2D) for all Cortex-M processors."
|
||||||
config LV_USE_GPU_STM32_DMA2D
|
config LV_USE_GPU_STM32_DMA2D
|
||||||
bool "Enable STM32 DMA2D (aka Chrom Art) GPU."
|
bool "Enable STM32 DMA2D (aka Chrom Art) GPU."
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Must deploy arm-2d library to your project and add include PATH for "arm_2d.h".
|
||||||
|
|
||||||
config LV_GPU_DMA2D_CMSIS_INCLUDE
|
config LV_GPU_DMA2D_CMSIS_INCLUDE
|
||||||
string "include path of CMSIS header of target processor"
|
string "include path of CMSIS header of target processor"
|
||||||
depends on LV_USE_GPU_STM32_DMA2D
|
depends on LV_USE_GPU_STM32_DMA2D
|
||||||
|
|||||||
Binary file not shown.
@@ -36,7 +36,12 @@
|
|||||||
<repository type="git">https://github.com/lvgl/lvgl.git</repository>
|
<repository type="git">https://github.com/lvgl/lvgl.git</repository>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
<release date="2022-02-26" version="1.0.1" url="https://raw.githubusercontent.com/lvgl/lvgl/master/env_support/cmsis-pack/LVGL.lvgl.1.0.1.pack">
|
<release date="2022-03-11" version="1.0.2-alpha1" url="https://raw.githubusercontent.com/lvgl/lvgl/master/env_support/cmsis-pack/LVGL.lvgl.1.0.2-alpha1.pack">
|
||||||
|
- LVGL 8.3.0-dev
|
||||||
|
- Monthly update for March
|
||||||
|
- Add GPU support for Arm-2D library
|
||||||
|
</release>
|
||||||
|
<release date="2022-02-26" version="1.0.1" url="https://github.com/lvgl/lvgl/raw/44f6f752386617a8812228b9c1357f180e73e4ff/env_support/cmsis-pack/LVGL.lvgl.1.0.1.pack">
|
||||||
- LVGL 8.3.0-dev
|
- LVGL 8.3.0-dev
|
||||||
- Monthly update for February
|
- Monthly update for February
|
||||||
</release>
|
</release>
|
||||||
@@ -121,6 +126,11 @@
|
|||||||
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
<require Cclass="LVGL" Cgroup="lvgl" Csub="Essential"/>
|
||||||
</condition>
|
</condition>
|
||||||
|
|
||||||
|
<condition id="Arm-2D">
|
||||||
|
<description>Require Arm-2D Support</description>
|
||||||
|
<require Cclass="Acceleration" Cgroup="Arm-2D"/>
|
||||||
|
</condition>
|
||||||
|
|
||||||
</conditions>
|
</conditions>
|
||||||
<!-- apis section (optional - for Application Programming Interface descriptions) -->
|
<!-- apis section (optional - for Application Programming Interface descriptions) -->
|
||||||
<!--
|
<!--
|
||||||
@@ -316,6 +326,20 @@
|
|||||||
</files>
|
</files>
|
||||||
</component>
|
</component>
|
||||||
|
|
||||||
|
<component Cgroup="lvgl" Csub="GPU Arm-2D" condition="LVGL-Essential" Cversion="1.0.0-dev">
|
||||||
|
<description>A 2D image processing library from Arm (i.e. Arm-2D) for All Cortex-M processors including Cortex-M0</description>
|
||||||
|
<files>
|
||||||
|
<file category="sourceC" name="src/draw/arm2d/lv_gpu_arm2d.c" condition="Arm-2D"/>
|
||||||
|
</files>
|
||||||
|
|
||||||
|
<RTE_Components_h>
|
||||||
|
|
||||||
|
/*! \brief enable Arm-2D support*/
|
||||||
|
#define LV_USE_GPU_ARM2D 1
|
||||||
|
</RTE_Components_h>
|
||||||
|
|
||||||
|
</component>
|
||||||
|
|
||||||
<component Cgroup="lvgl" Csub="GPU STM32-DMA2D" condition="LVGL-Essential">
|
<component Cgroup="lvgl" Csub="GPU STM32-DMA2D" condition="LVGL-Essential">
|
||||||
<description>An hardware acceleration from STM32-DMA2D</description>
|
<description>An hardware acceleration from STM32-DMA2D</description>
|
||||||
<files>
|
<files>
|
||||||
|
|||||||
@@ -157,6 +157,9 @@
|
|||||||
* GPU
|
* GPU
|
||||||
*-----------*/
|
*-----------*/
|
||||||
|
|
||||||
|
/*Use Arm's 2D acceleration library Arm-2D */
|
||||||
|
#define LV_USE_GPU_ARM2D 0
|
||||||
|
|
||||||
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
||||||
#define LV_USE_GPU_STM32_DMA2D 0
|
#define LV_USE_GPU_STM32_DMA2D 0
|
||||||
#if LV_USE_GPU_STM32_DMA2D
|
#if LV_USE_GPU_STM32_DMA2D
|
||||||
|
|||||||
774
src/draw/arm2d/lv_gpu_arm2d.c
Normal file
774
src/draw/arm2d/lv_gpu_arm2d.c
Normal file
@@ -0,0 +1,774 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_gpu_arm2d.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "lv_gpu_arm2d.h"
|
||||||
|
#include "../../core/lv_refr.h"
|
||||||
|
|
||||||
|
#if LV_USE_GPU_ARM2D
|
||||||
|
#include "arm_2d.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
#if LV_COLOR_DEPTH == 16
|
||||||
|
#define arm_2d_fill_colour arm_2d_rgb16_fill_colour
|
||||||
|
#define arm_2d_fill_colour_with_alpha arm_2d_rgb565_fill_colour_with_alpha
|
||||||
|
#define arm_2d_fill_colour_with_mask arm_2d_rgb565_fill_colour_with_mask
|
||||||
|
#define arm_2d_fill_colour_with_mask_and_opacity \
|
||||||
|
arm_2d_rgb565_fill_colour_with_mask_and_opacity
|
||||||
|
#define arm_2d_tile_copy arm_2d_rgb16_tile_copy
|
||||||
|
#define arm_2d_alpha_blending arm_2d_rgb565_alpha_blending
|
||||||
|
#define arm_2d_tile_copy_with_src_mask arm_2d_rgb565_tile_copy_with_src_mask
|
||||||
|
#define arm_2d_color_t arm_2d_color_rgb565_t
|
||||||
|
|
||||||
|
/* arm-2d direct mode apis */
|
||||||
|
#define __arm_2d_impl_colour_filling __arm_2d_impl_rgb16_colour_filling
|
||||||
|
#define __arm_2d_impl_colour_filling_with_opacity \
|
||||||
|
__arm_2d_impl_rgb565_colour_filling_with_opacity
|
||||||
|
#define __arm_2d_impl_colour_filling_mask \
|
||||||
|
__arm_2d_impl_rgb565_colour_filling_mask
|
||||||
|
#define __arm_2d_impl_colour_filling_mask_opacity \
|
||||||
|
__arm_2d_impl_rgb565_colour_filling_mask_opacity
|
||||||
|
#define __arm_2d_impl_copy __arm_2d_impl_rgb16_copy
|
||||||
|
#define __arm_2d_impl_alpha_blending __arm_2d_impl_rgb565_alpha_blending
|
||||||
|
#define __arm_2d_impl_src_msk_copy __arm_2d_impl_rgb565_src_msk_copy
|
||||||
|
#define color_int uint16_t
|
||||||
|
|
||||||
|
#elif LV_COLOR_DEPTH == 32
|
||||||
|
#define arm_2d_fill_colour arm_2d_rgb32_fill_colour
|
||||||
|
#define arm_2d_fill_colour_with_alpha arm_2d_cccn888_fill_colour_with_alpha
|
||||||
|
#define arm_2d_fill_colour_with_mask arm_2d_cccn888_fill_colour_with_mask
|
||||||
|
#define arm_2d_fill_colour_with_mask_and_opacity \
|
||||||
|
arm_2d_cccn888_fill_colour_with_mask_and_opacity
|
||||||
|
#define arm_2d_tile_copy arm_2d_rgb32_tile_copy
|
||||||
|
#define arm_2d_alpha_blending arm_2d_cccn888_alpha_blending
|
||||||
|
#define arm_2d_tile_copy_with_src_mask arm_2d_cccn888_tile_copy_with_src_mask
|
||||||
|
#define arm_2d_color_t arm_2d_color_cccn888_t
|
||||||
|
|
||||||
|
/* arm-2d direct mode apis */
|
||||||
|
#define __arm_2d_impl_colour_filling __arm_2d_impl_rgb32_colour_filling
|
||||||
|
#define __arm_2d_impl_colour_filling_with_opacity \
|
||||||
|
__arm_2d_impl_cccn888_colour_filling_with_opacity
|
||||||
|
#define __arm_2d_impl_colour_filling_mask \
|
||||||
|
__arm_2d_impl_cccn888_colour_filling_mask
|
||||||
|
#define __arm_2d_impl_colour_filling_mask_opacity \
|
||||||
|
__arm_2d_impl_cccn888_colour_filling_mask_opacity
|
||||||
|
#define __arm_2d_impl_copy __arm_2d_impl_rgb32_copy
|
||||||
|
#define __arm_2d_impl_alpha_blending __arm_2d_impl_cccn888_alpha_blending
|
||||||
|
#define __arm_2d_impl_src_msk_copy __arm_2d_impl_cccn888_src_msk_copy
|
||||||
|
#define color_int uint32_t
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error The specified LV_COLOR_DEPTH is not supported by this version of lv_gpu_arm2d.c.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#if __ARM_2D_HAS_ASYNC__
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool lv_draw_arm2d_fill_colour(const arm_2d_tile_t * target_tile,
|
||||||
|
const arm_2d_region_t * region,
|
||||||
|
lv_color_t color,
|
||||||
|
lv_opa_t opa,
|
||||||
|
const arm_2d_tile_t * mask_tile);
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool lv_draw_arm2d_tile_copy(const arm_2d_tile_t * target_tile,
|
||||||
|
const arm_2d_region_t * region,
|
||||||
|
arm_2d_tile_t * source_tile,
|
||||||
|
lv_opa_t opa,
|
||||||
|
arm_2d_tile_t * mask_tile);
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* arm-2d direct mode APIs */
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_colour_filling(color_int * __RESTRICT pTarget,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize,
|
||||||
|
color_int Colour);
|
||||||
|
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_colour_filling_with_opacity(
|
||||||
|
color_int * __RESTRICT pTargetBase,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize,
|
||||||
|
color_int Colour,
|
||||||
|
uint_fast8_t chRatio);
|
||||||
|
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_colour_filling_mask(
|
||||||
|
color_int * __RESTRICT pTarget,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
uint8_t * __RESTRICT pchAlpha,
|
||||||
|
int16_t iAlphaStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize,
|
||||||
|
color_int Colour);
|
||||||
|
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_colour_filling_mask_opacity(
|
||||||
|
color_int * __RESTRICT pTarget,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
uint8_t * __RESTRICT pchAlpha,
|
||||||
|
int16_t iAlphaStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize,
|
||||||
|
color_int Colour,
|
||||||
|
uint8_t chOpacity);
|
||||||
|
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_copy(color_int * __RESTRICT pSource,
|
||||||
|
int16_t iSourceStride,
|
||||||
|
color_int * __RESTRICT pTarget,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize);
|
||||||
|
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_alpha_blending(color_int * __RESTRICT pSource,
|
||||||
|
int16_t iSourceStride,
|
||||||
|
color_int * __RESTRICT pTarget,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize,
|
||||||
|
uint_fast8_t chRatio);
|
||||||
|
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_gray8_alpha_blending(uint8_t * __RESTRICT pSource,
|
||||||
|
int16_t iSourceStride,
|
||||||
|
uint8_t * __RESTRICT pTarget,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize,
|
||||||
|
uint_fast8_t chRatio);
|
||||||
|
|
||||||
|
extern
|
||||||
|
void __arm_2d_impl_src_msk_copy(color_int * __RESTRICT pSourceBase,
|
||||||
|
int16_t iSourceStride,
|
||||||
|
uint8_t * __RESTRICT ptSourceMaskBase,
|
||||||
|
int16_t iSourceMaskStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptSourceMaskSize,
|
||||||
|
color_int * __RESTRICT pTargetBase,
|
||||||
|
int16_t iTargetStride,
|
||||||
|
arm_2d_size_t * __RESTRICT ptCopySize);
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool arm_2d_fill_normal(lv_color_t * dest_buf,
|
||||||
|
const lv_area_t * dest_area,
|
||||||
|
lv_coord_t dest_stride,
|
||||||
|
lv_color_t color,
|
||||||
|
lv_opa_t opa,
|
||||||
|
const lv_opa_t * mask,
|
||||||
|
lv_coord_t mask_stride);
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool arm_2d_copy_normal(lv_color_t * dest_buf,
|
||||||
|
const lv_area_t * dest_area,
|
||||||
|
lv_coord_t dest_stride,
|
||||||
|
const lv_color_t * src_buf,
|
||||||
|
lv_coord_t src_stride,
|
||||||
|
lv_opa_t opa,
|
||||||
|
const lv_opa_t * mask,
|
||||||
|
lv_coord_t mask_stride);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static void lv_gpu_arm2d_wait_cb(lv_draw_ctx_t * draw_ctx);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
void lv_draw_arm2d_init(void)
|
||||||
|
{
|
||||||
|
arm_2d_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void lv_draw_arm2d_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||||
|
{
|
||||||
|
lv_draw_sw_init_ctx(drv, draw_ctx);
|
||||||
|
|
||||||
|
lv_draw_arm2d_ctx_t * arm2d_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx;
|
||||||
|
|
||||||
|
arm2d_draw_ctx->blend = lv_draw_arm2d_blend;
|
||||||
|
arm2d_draw_ctx->base_draw.wait_for_finish = lv_gpu_arm2d_wait_cb;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv_draw_arm2d_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
|
||||||
|
{
|
||||||
|
LV_UNUSED(drv);
|
||||||
|
LV_UNUSED(draw_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void test_flush(lv_color_t * color_p);
|
||||||
|
|
||||||
|
#if __ARM_2D_HAS_ASYNC__
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
||||||
|
{
|
||||||
|
const lv_opa_t * mask;
|
||||||
|
if(dsc->mask_buf == NULL) mask = NULL;
|
||||||
|
if(dsc->mask_buf && dsc->mask_res == LV_DRAW_MASK_RES_TRANSP) return;
|
||||||
|
else if(dsc->mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask = NULL;
|
||||||
|
else mask = dsc->mask_buf;
|
||||||
|
|
||||||
|
|
||||||
|
lv_area_t blend_area;
|
||||||
|
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static arm_2d_tile_t target_tile;
|
||||||
|
static arm_2d_tile_t source_tile_orig;
|
||||||
|
static arm_2d_tile_t source_tile;
|
||||||
|
static arm_2d_tile_t mask_tile_orig;
|
||||||
|
static arm_2d_tile_t mask_tile;
|
||||||
|
static arm_2d_region_t target_region;
|
||||||
|
|
||||||
|
bool is_accelerated = false;
|
||||||
|
|
||||||
|
if(dsc->blend_mode == LV_BLEND_MODE_NORMAL
|
||||||
|
&& lv_area_get_size(&blend_area) > 100) {
|
||||||
|
|
||||||
|
lv_color_t * dest_buf = draw_ctx->buf;
|
||||||
|
|
||||||
|
|
||||||
|
target_tile = (arm_2d_tile_t) {
|
||||||
|
.tRegion = {
|
||||||
|
.tSize = {
|
||||||
|
.iWidth = lv_area_get_width(draw_ctx->buf_area),
|
||||||
|
.iHeight = lv_area_get_height(draw_ctx->buf_area),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.tInfo.bIsRoot = true,
|
||||||
|
.phwBuffer = (uint16_t *)draw_ctx->buf,
|
||||||
|
};
|
||||||
|
|
||||||
|
target_region = (arm_2d_region_t) {
|
||||||
|
.tLocation = {
|
||||||
|
.iX = blend_area.x1 - draw_ctx->buf_area->x1,
|
||||||
|
.iY = blend_area.y1 - draw_ctx->buf_area->y1,
|
||||||
|
},
|
||||||
|
.tSize = {
|
||||||
|
.iWidth = lv_area_get_width(&blend_area),
|
||||||
|
.iHeight = lv_area_get_height(&blend_area),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if(NULL != mask) {
|
||||||
|
mask_tile_orig = (arm_2d_tile_t) {
|
||||||
|
.tRegion = {
|
||||||
|
.tSize = {
|
||||||
|
.iWidth = lv_area_get_width(dsc->mask_area),
|
||||||
|
.iHeight = lv_area_get_height(dsc->mask_area),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.tInfo = {
|
||||||
|
.bIsRoot = true,
|
||||||
|
.bHasEnforcedColour = true,
|
||||||
|
.tColourInfo = {
|
||||||
|
.chScheme = ARM_2D_COLOUR_8BIT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.pchBuffer = (uint8_t *)mask,
|
||||||
|
};
|
||||||
|
|
||||||
|
arm_2d_tile_generate_child(
|
||||||
|
&mask_tile_orig,
|
||||||
|
(arm_2d_region_t []) {
|
||||||
|
{
|
||||||
|
.tLocation = {
|
||||||
|
.iX = dsc->mask_area->x1 - blend_area.x1,
|
||||||
|
.iY = dsc->mask_area->y1 - blend_area.y1,
|
||||||
|
},
|
||||||
|
.tSize = mask_tile_orig.tRegion.tSize,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&mask_tile,
|
||||||
|
false);
|
||||||
|
mask_tile.tInfo.bDerivedResource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const lv_color_t * src_buf = dsc->src_buf;
|
||||||
|
if(src_buf) {
|
||||||
|
source_tile_orig = (arm_2d_tile_t) {
|
||||||
|
.tRegion = {
|
||||||
|
.tSize = {
|
||||||
|
.iWidth = lv_area_get_width(dsc->blend_area),
|
||||||
|
.iHeight = lv_area_get_height(dsc->blend_area),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.tInfo.bIsRoot = true,
|
||||||
|
.phwBuffer = (uint16_t *)src_buf,
|
||||||
|
};
|
||||||
|
|
||||||
|
arm_2d_tile_generate_child(
|
||||||
|
&source_tile_orig,
|
||||||
|
(arm_2d_region_t []) {
|
||||||
|
{
|
||||||
|
.tLocation = {
|
||||||
|
.iX = blend_area.x1 - dsc->blend_area->x1,
|
||||||
|
.iY = blend_area.y1 - dsc->blend_area->y1,
|
||||||
|
},
|
||||||
|
.tSize = source_tile_orig.tRegion.tSize,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&source_tile,
|
||||||
|
false);
|
||||||
|
source_tile.tInfo.bDerivedResource = true;
|
||||||
|
|
||||||
|
is_accelerated = lv_draw_arm2d_tile_copy(
|
||||||
|
&target_tile,
|
||||||
|
&target_region,
|
||||||
|
&source_tile,
|
||||||
|
dsc->opa,
|
||||||
|
(NULL == mask) ? NULL : &mask_tile);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
is_accelerated = lv_draw_arm2d_fill_colour(
|
||||||
|
&target_tile,
|
||||||
|
&target_region,
|
||||||
|
dsc->color,
|
||||||
|
dsc->opa,
|
||||||
|
(NULL == mask) ? NULL : &mask_tile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_accelerated) {
|
||||||
|
lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool lv_draw_arm2d_fill_colour(const arm_2d_tile_t * target_tile,
|
||||||
|
const arm_2d_region_t * region,
|
||||||
|
lv_color_t color,
|
||||||
|
lv_opa_t opa,
|
||||||
|
const arm_2d_tile_t * mask_tile)
|
||||||
|
{
|
||||||
|
arm_fsm_rt_t result = (arm_fsm_rt_t)ARM_2D_ERR_NONE;
|
||||||
|
|
||||||
|
if(NULL == mask_tile) {
|
||||||
|
if(opa >= LV_OPA_MAX) {
|
||||||
|
result = arm_2d_fill_colour(target_tile, region, color.full);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
result = arm_2d_fill_colour_with_alpha(
|
||||||
|
target_tile,
|
||||||
|
region,
|
||||||
|
(arm_2d_color_t) {
|
||||||
|
color.full
|
||||||
|
},
|
||||||
|
opa);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if(opa >= LV_OPA_MAX) {
|
||||||
|
result = arm_2d_fill_colour_with_mask(
|
||||||
|
target_tile,
|
||||||
|
region,
|
||||||
|
mask_tile,
|
||||||
|
(arm_2d_color_t) {
|
||||||
|
color.full
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
result = arm_2d_fill_colour_with_mask_and_opacity(
|
||||||
|
target_tile,
|
||||||
|
region,
|
||||||
|
mask_tile,
|
||||||
|
(arm_2d_color_t) {
|
||||||
|
color.full
|
||||||
|
},
|
||||||
|
opa);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result < 0) {
|
||||||
|
/* error detected */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool lv_draw_arm2d_tile_copy(const arm_2d_tile_t * target_tile,
|
||||||
|
const arm_2d_region_t * region,
|
||||||
|
arm_2d_tile_t * source_tile,
|
||||||
|
lv_opa_t opa,
|
||||||
|
arm_2d_tile_t * mask_tile)
|
||||||
|
{
|
||||||
|
arm_fsm_rt_t result = (arm_fsm_rt_t)ARM_2D_ERR_NONE;
|
||||||
|
|
||||||
|
if(NULL == mask_tile) {
|
||||||
|
if(opa >= LV_OPA_MAX) {
|
||||||
|
result = arm_2d_tile_copy(source_tile,
|
||||||
|
target_tile,
|
||||||
|
region,
|
||||||
|
ARM_2D_CP_MODE_COPY);
|
||||||
|
}
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
else {
|
||||||
|
return false; /* not supported */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
else {
|
||||||
|
result = arm_2d_alpha_blending(source_tile,
|
||||||
|
target_tile,
|
||||||
|
region,
|
||||||
|
opa);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false; /* not support */
|
||||||
|
#else
|
||||||
|
|
||||||
|
if(opa >= LV_OPA_MAX) {
|
||||||
|
result = arm_2d_tile_copy_with_src_mask(source_tile,
|
||||||
|
mask_tile,
|
||||||
|
target_tile,
|
||||||
|
region,
|
||||||
|
ARM_2D_CP_MODE_COPY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result < 0) {
|
||||||
|
/* error detected */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lv_gpu_arm2d_wait_cb(lv_draw_ctx_t * draw_ctx)
|
||||||
|
{
|
||||||
|
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||||
|
|
||||||
|
arm_2d_op_wait_async(NULL);
|
||||||
|
if(disp->driver && disp->driver->wait_cb) {
|
||||||
|
disp->driver->wait_cb(disp->driver);
|
||||||
|
}
|
||||||
|
lv_draw_sw_wait_for_finish(draw_ctx);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static void lv_draw_arm2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
||||||
|
{
|
||||||
|
const lv_opa_t * mask;
|
||||||
|
if(dsc->mask_buf == NULL) mask = NULL;
|
||||||
|
if(dsc->mask_buf && dsc->mask_res == LV_DRAW_MASK_RES_TRANSP) return;
|
||||||
|
else if(dsc->mask_res == LV_DRAW_MASK_RES_FULL_COVER) mask = NULL;
|
||||||
|
else mask = dsc->mask_buf;
|
||||||
|
|
||||||
|
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
|
||||||
|
|
||||||
|
lv_area_t blend_area;
|
||||||
|
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area)) return;
|
||||||
|
|
||||||
|
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||||
|
|
||||||
|
bool is_accelerated = false;
|
||||||
|
do {
|
||||||
|
if(NULL != disp->driver->set_px_cb) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_color_t * dest_buf = draw_ctx->buf;
|
||||||
|
if(disp->driver->set_px_cb == NULL) {
|
||||||
|
dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lv_color_t * src_buf = dsc->src_buf;
|
||||||
|
lv_coord_t src_stride;
|
||||||
|
if(src_buf) {
|
||||||
|
src_stride = lv_area_get_width(dsc->blend_area);
|
||||||
|
src_buf += src_stride * (blend_area.y1 - dsc->blend_area->y1) + (blend_area.x1 - dsc->blend_area->x1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
src_stride = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_coord_t mask_stride;
|
||||||
|
if(mask) {
|
||||||
|
mask_stride = lv_area_get_width(dsc->mask_area);
|
||||||
|
mask += mask_stride * (dsc->mask_area->y1 - blend_area.y1) + (dsc->mask_area->x1 - blend_area.x1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mask_stride = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
|
||||||
|
|
||||||
|
|
||||||
|
if(dsc->src_buf == NULL) {
|
||||||
|
if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) {
|
||||||
|
is_accelerated = arm_2d_fill_normal(dest_buf,
|
||||||
|
&blend_area,
|
||||||
|
dest_stride,
|
||||||
|
dsc->color,
|
||||||
|
dsc->opa,
|
||||||
|
mask,
|
||||||
|
mask_stride);
|
||||||
|
}
|
||||||
|
#if LV_DRAW_COMPLEX
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if(dsc->blend_mode == LV_BLEND_MODE_NORMAL) {
|
||||||
|
is_accelerated = arm_2d_copy_normal(dest_buf,
|
||||||
|
&blend_area,
|
||||||
|
dest_stride,
|
||||||
|
src_buf,
|
||||||
|
src_stride,
|
||||||
|
dsc->opa,
|
||||||
|
mask,
|
||||||
|
mask_stride);
|
||||||
|
}
|
||||||
|
#if LV_DRAW_COMPLEX
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
if(!is_accelerated) lv_draw_sw_blend_basic(draw_ctx, dsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool arm_2d_fill_normal(lv_color_t * dest_buf,
|
||||||
|
const lv_area_t * dest_area,
|
||||||
|
lv_coord_t dest_stride,
|
||||||
|
lv_color_t color,
|
||||||
|
lv_opa_t opa,
|
||||||
|
const lv_opa_t * mask,
|
||||||
|
lv_coord_t mask_stride)
|
||||||
|
{
|
||||||
|
arm_2d_size_t target_size = {
|
||||||
|
.iWidth = lv_area_get_width(dest_area),
|
||||||
|
.iHeight = lv_area_get_height(dest_area),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*No mask*/
|
||||||
|
if(mask == NULL) {
|
||||||
|
if(opa >= LV_OPA_MAX) {
|
||||||
|
__arm_2d_impl_colour_filling((color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
&target_size,
|
||||||
|
color.full);
|
||||||
|
}
|
||||||
|
/*Has opacity*/
|
||||||
|
else {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
__arm_2d_impl_colour_filling_with_opacity((color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
&target_size,
|
||||||
|
color.full,
|
||||||
|
opa);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*Masked*/
|
||||||
|
else {
|
||||||
|
/*Only the mask matters*/
|
||||||
|
if(opa >= LV_OPA_MAX) {
|
||||||
|
__arm_2d_impl_colour_filling_mask((color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
(uint8_t *)mask,
|
||||||
|
mask_stride,
|
||||||
|
&target_size,
|
||||||
|
color.full);
|
||||||
|
}
|
||||||
|
/*With opacity*/
|
||||||
|
else {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
__arm_2d_impl_colour_filling_mask_opacity((color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
(uint8_t *)mask,
|
||||||
|
mask_stride,
|
||||||
|
&target_size,
|
||||||
|
color.full,
|
||||||
|
opa);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM
|
||||||
|
static bool arm_2d_copy_normal(lv_color_t * dest_buf,
|
||||||
|
const lv_area_t * dest_area,
|
||||||
|
lv_coord_t dest_stride,
|
||||||
|
const lv_color_t * src_buf,
|
||||||
|
lv_coord_t src_stride,
|
||||||
|
lv_opa_t opa,
|
||||||
|
const lv_opa_t * mask,
|
||||||
|
lv_coord_t mask_stride)
|
||||||
|
|
||||||
|
{
|
||||||
|
int32_t w = lv_area_get_width(dest_area);
|
||||||
|
int32_t h = lv_area_get_height(dest_area);
|
||||||
|
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
|
||||||
|
arm_2d_size_t copy_size = {
|
||||||
|
.iWidth = lv_area_get_width(dest_area),
|
||||||
|
.iHeight = lv_area_get_height(dest_area),
|
||||||
|
};
|
||||||
|
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Simple fill (maybe with opacity), no masking*/
|
||||||
|
if(mask == NULL) {
|
||||||
|
if(opa >= LV_OPA_MAX) {
|
||||||
|
__arm_2d_impl_copy((color_int *)src_buf,
|
||||||
|
src_stride,
|
||||||
|
(color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
©_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
__arm_2d_impl_alpha_blending((color_int *)src_buf,
|
||||||
|
src_stride,
|
||||||
|
(color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
©_size,
|
||||||
|
opa);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*Masked*/
|
||||||
|
else {
|
||||||
|
/*Only the mask matters*/
|
||||||
|
if(opa > LV_OPA_MAX) {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
__arm_2d_impl_src_msk_copy((color_int *)src_buf,
|
||||||
|
src_stride,
|
||||||
|
(uint8_t *)mask,
|
||||||
|
mask_stride,
|
||||||
|
©_size,
|
||||||
|
(color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
©_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*Handle opa and mask values too*/
|
||||||
|
else {
|
||||||
|
#if LV_COLOR_SCREEN_TRANSP
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
__arm_2d_impl_gray8_alpha_blending((uint8_t *)mask,
|
||||||
|
mask_stride,
|
||||||
|
(uint8_t *)mask,
|
||||||
|
mask_stride,
|
||||||
|
©_size,
|
||||||
|
opa);
|
||||||
|
|
||||||
|
__arm_2d_impl_src_msk_copy((color_int *)src_buf,
|
||||||
|
src_stride,
|
||||||
|
(uint8_t *)mask,
|
||||||
|
mask_stride,
|
||||||
|
©_size,
|
||||||
|
(color_int *)dest_buf,
|
||||||
|
dest_stride,
|
||||||
|
©_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lv_gpu_arm2d_wait_cb(lv_draw_ctx_t * draw_ctx)
|
||||||
|
{
|
||||||
|
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||||
|
|
||||||
|
if(disp->driver && disp->driver->wait_cb) {
|
||||||
|
disp->driver->wait_cb(disp->driver);
|
||||||
|
}
|
||||||
|
lv_draw_sw_wait_for_finish(draw_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void invalidate_cache(void)
|
||||||
|
{
|
||||||
|
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||||
|
if(disp->driver->clean_dcache_cb) disp->driver->clean_dcache_cb(disp->driver);
|
||||||
|
else {
|
||||||
|
#if __CORTEX_M >= 0x07
|
||||||
|
if((SCB->CCR) & (uint32_t)SCB_CCR_DC_Msk)
|
||||||
|
SCB_CleanInvalidateDCache();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
53
src/draw/arm2d/lv_gpu_arm2d.h
Normal file
53
src/draw/arm2d/lv_gpu_arm2d.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_gpu_arm2d.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LV_GPU_ARM2D_H
|
||||||
|
#define LV_GPU_ARM2D_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "../../misc/lv_color.h"
|
||||||
|
#include "../../hal/lv_hal_disp.h"
|
||||||
|
#include "../sw/lv_draw_sw.h"
|
||||||
|
|
||||||
|
#if LV_USE_GPU_ARM2D
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
typedef lv_draw_sw_ctx_t lv_draw_arm2d_ctx_t;
|
||||||
|
|
||||||
|
struct _lv_disp_drv_t;
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
void lv_draw_arm2d_init(void);
|
||||||
|
|
||||||
|
void lv_draw_arm2d_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||||
|
|
||||||
|
void lv_draw_arm2d_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
#endif /*LV_USE_GPU_ARM2D*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /*extern "C"*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*LV_GPU_ARM2D_H*/
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "../draw/sw/lv_draw_sw.h"
|
#include "../draw/sw/lv_draw_sw.h"
|
||||||
#include "../draw/sdl/lv_draw_sdl.h"
|
#include "../draw/sdl/lv_draw_sdl.h"
|
||||||
#include "../draw/stm32_dma2d/lv_gpu_stm32_dma2d.h"
|
#include "../draw/stm32_dma2d/lv_gpu_stm32_dma2d.h"
|
||||||
|
#include "../draw/arm2d/lv_gpu_arm2d.h"
|
||||||
|
|
||||||
#if LV_USE_THEME_DEFAULT
|
#if LV_USE_THEME_DEFAULT
|
||||||
#include "../extra/themes/default/lv_theme_default.h"
|
#include "../extra/themes/default/lv_theme_default.h"
|
||||||
@@ -108,6 +109,10 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
|
|||||||
driver->draw_ctx_init = lv_draw_sdl_init_ctx;
|
driver->draw_ctx_init = lv_draw_sdl_init_ctx;
|
||||||
driver->draw_ctx_deinit = lv_draw_sdl_deinit_ctx;
|
driver->draw_ctx_deinit = lv_draw_sdl_deinit_ctx;
|
||||||
driver->draw_ctx_size = sizeof(lv_draw_sdl_ctx_t);
|
driver->draw_ctx_size = sizeof(lv_draw_sdl_ctx_t);
|
||||||
|
#elif LV_USE_GPU_ARM2D
|
||||||
|
driver->draw_ctx_init = lv_draw_arm2d_ctx_init;
|
||||||
|
driver->draw_ctx_deinit = lv_draw_arm2d_ctx_init;
|
||||||
|
driver->draw_ctx_size = sizeof(lv_draw_arm2d_ctx_t);
|
||||||
#else
|
#else
|
||||||
driver->draw_ctx_init = lv_draw_sw_init_ctx;
|
driver->draw_ctx_init = lv_draw_sw_init_ctx;
|
||||||
driver->draw_ctx_deinit = lv_draw_sw_init_ctx;
|
driver->draw_ctx_deinit = lv_draw_sw_init_ctx;
|
||||||
|
|||||||
@@ -373,6 +373,15 @@
|
|||||||
* GPU
|
* GPU
|
||||||
*-----------*/
|
*-----------*/
|
||||||
|
|
||||||
|
/*Use Arm's 2D acceleration library Arm-2D */
|
||||||
|
#ifndef LV_USE_GPU_ARM2D
|
||||||
|
#ifdef CONFIG_LV_USE_GPU_ARM2D
|
||||||
|
#define LV_USE_GPU_ARM2D CONFIG_LV_USE_GPU_ARM2D
|
||||||
|
#else
|
||||||
|
#define LV_USE_GPU_ARM2D 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
/*Use STM32's DMA2D (aka Chrom Art) GPU*/
|
||||||
#ifndef LV_USE_GPU_STM32_DMA2D
|
#ifndef LV_USE_GPU_STM32_DMA2D
|
||||||
#ifdef CONFIG_LV_USE_GPU_STM32_DMA2D
|
#ifdef CONFIG_LV_USE_GPU_STM32_DMA2D
|
||||||
|
|||||||
Reference in New Issue
Block a user