feat(pxp): add PXP support for tiled images (#8846)
Arduino Lint / lint (push) Has been cancelled
Build Examples with C++ Compiler / build-examples (push) Has been cancelled
MicroPython CI / Build esp32 port (push) Has been cancelled
MicroPython CI / Build rp2 port (push) Has been cancelled
MicroPython CI / Build stm32 port (push) Has been cancelled
MicroPython CI / Build unix port (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_NORMAL_8BIT - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_SDL - Ubuntu (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_16BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_24BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - cl - Windows (push) Has been cancelled
C/C++ CI / Build OPTIONS_FULL_32BIT - gcc - Windows (push) Has been cancelled
C/C++ CI / Build ESP IDF ESP32S3 (push) Has been cancelled
C/C++ CI / Run tests with 32bit build (push) Has been cancelled
C/C++ CI / Run tests with 64bit build (push) Has been cancelled
BOM Check / bom-check (push) Has been cancelled
Verify that lv_conf_internal.h matches repository state / verify-conf-internal (push) Has been cancelled
Verify the widget property name / verify-property-name (push) Has been cancelled
Verify code formatting / verify-formatting (push) Has been cancelled
Compare file templates with file names / template-check (push) Has been cancelled
Build docs / build-and-deploy (push) Has been cancelled
Test API JSON generator / Test API JSON (push) Has been cancelled
Install LVGL using CMake / build-examples (push) Has been cancelled
Check Makefile / Build using Makefile (push) Has been cancelled
Check Makefile for UEFI / Build using Makefile for UEFI (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/benchmark_results_comment/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/filter_docker_logs/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Script Check (scripts/perf/tests/serialize_results/test.sh) (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 32b - lv_conf_perf32b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark 64b - lv_conf_perf64b (push) Has been cancelled
Emulated Performance Test / ARM Emulated Benchmark - Save PR Number (push) Has been cancelled
Hardware Performance Test / Hardware Performance Benchmark (push) Has been cancelled
Hardware Performance Test / HW Benchmark - Save PR Number (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_32B - Ubuntu (push) Has been cancelled
Performance Tests CI / Perf Tests OPTIONS_TEST_PERF_64B - Ubuntu (push) Has been cancelled
Port repo release update / run-release-branch-updater (push) Has been cancelled
Verify Font License / verify-font-license (push) Has been cancelled
Verify Kconfig / verify-kconfig (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
anaGrad
2025-09-25 22:28:26 +03:00
committed by GitHub
parent 83563b3619
commit f178e7b1ed
2 changed files with 55 additions and 87 deletions
-5
View File
@@ -210,11 +210,6 @@ static bool _pxp_draw_img_supported(const lv_draw_image_dsc_t * draw_dsc)
{
const lv_image_dsc_t * img_dsc = draw_dsc->src;
bool is_tiled = draw_dsc->tile;
/* Tiled image (repeat image) is currently not supported. */
if(is_tiled)
return false;
bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN);
bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
draw_dsc->scale_y != LV_SCALE_NONE);
+55 -82
View File
@@ -19,6 +19,8 @@
#if LV_USE_DRAW_PXP
#include "lv_pxp_cfg.h"
#include "lv_pxp_utils.h"
#include "../../lv_draw_image_private.h"
#include "../../lv_image_decoder_private.h"
#include <math.h>
@@ -33,6 +35,9 @@
/**********************
* STATIC PROTOTYPES
**********************/
static void _pxp_draw_core_cb(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
const lv_area_t * img_coords, const lv_area_t * clipped_img_area);
/* Blit w/ recolor for images w/o opa and alpha channel */
static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
@@ -69,54 +74,58 @@ void lv_draw_pxp_img(lv_draw_task_t * t)
if(dsc->opa <= (lv_opa_t)LV_OPA_MIN)
return;
lv_layer_t * layer = t->target_layer;
lv_draw_buf_t * draw_buf = layer->draw_buf;
const lv_image_dsc_t * img_dsc = dsc->src;
lv_area_t rel_coords;
lv_area_copy(&rel_coords, coords);
lv_area_move(&rel_coords, -layer->buf_area.x1, -layer->buf_area.y1);
lv_area_t rel_clip_area;
lv_area_copy(&rel_clip_area, &t->clip_area);
lv_area_move(&rel_clip_area, -layer->buf_area.x1, -layer->buf_area.y1);
lv_area_t blend_area;
bool has_transform = (dsc->rotation != 0 || dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
if(has_transform)
lv_area_copy(&blend_area, &rel_coords);
else if(!lv_area_intersect(&blend_area, &rel_coords, &rel_clip_area))
return; /*Fully clipped, nothing to do*/
const uint8_t * src_buf = img_dsc->data;
lv_area_t src_area;
src_area.x1 = blend_area.x1 - (coords->x1 - layer->buf_area.x1);
src_area.y1 = blend_area.y1 - (coords->y1 - layer->buf_area.y1);
src_area.x2 = src_area.x1 + lv_area_get_width(&blend_area) - 1;
src_area.y2 = src_area.y1 + lv_area_get_height(&blend_area) - 1;
int32_t src_stride = img_dsc->header.stride;
lv_color_format_t src_cf = img_dsc->header.cf;
uint8_t * dest_buf = draw_buf->data;
int32_t dest_stride = draw_buf->header.stride;
lv_color_format_t dest_cf = draw_buf->header.cf;
bool has_recolor = (dsc->recolor_opa > LV_OPA_MIN);
if(has_recolor && !has_transform)
_pxp_blit_recolor(dest_buf, &blend_area, dest_stride, dest_cf,
src_buf, &src_area, src_stride, src_cf, dsc);
else if(has_transform)
_pxp_blit_transform(dest_buf, &blend_area, dest_stride, dest_cf,
src_buf, &src_area, src_stride, src_cf, dsc);
bool is_tiled = (dsc->tile != 0);
if(is_tiled)
lv_draw_image_tiled_helper(t, dsc, coords, _pxp_draw_core_cb);
else
_pxp_blit(dest_buf, &blend_area, dest_stride, dest_cf,
src_buf, &src_area, src_stride, src_cf, dsc->opa);
lv_draw_image_normal_helper(t, dsc, coords, _pxp_draw_core_cb);
}
/**********************
* STATIC FUNCTIONS
**********************/
static void _pxp_draw_core_cb(lv_draw_task_t * t, const lv_draw_image_dsc_t * draw_dsc,
const lv_image_decoder_dsc_t * decoder_dsc, lv_draw_image_sup_t * sup,
const lv_area_t * img_coords, const lv_area_t * clipped_img_area)
{
lv_layer_t * layer = t->target_layer;
lv_draw_buf_t * draw_buf = layer->draw_buf;
const lv_draw_buf_t * decoded = decoder_dsc->decoded;
lv_area_t rel_clip_area;
lv_area_copy(&rel_clip_area, clipped_img_area);
lv_area_move(&rel_clip_area, -img_coords->x1, -img_coords->y1);
lv_area_t rel_img_coords;
lv_area_copy(&rel_img_coords, img_coords);
lv_area_move(&rel_img_coords, -img_coords->x1, -img_coords->y1);
const uint8_t * src_buf = decoded->data;
lv_area_t src_area;
if(!lv_area_intersect(&src_area, &rel_clip_area, &rel_img_coords))
return;
int32_t src_stride = draw_dsc->header.stride;
lv_color_format_t src_cf = draw_dsc->header.cf;
uint8_t * dest_buf = draw_buf->data;
int32_t dest_stride = draw_buf->header.stride;
lv_color_format_t dest_cf = draw_buf->header.cf;
bool has_recolor = (draw_dsc->recolor_opa > LV_OPA_MIN);
bool has_transform = (draw_dsc->rotation != 0 || draw_dsc->scale_x != LV_SCALE_NONE ||
draw_dsc->scale_y != LV_SCALE_NONE);
if(has_recolor && !has_transform)
_pxp_blit_recolor(dest_buf, clipped_img_area, dest_stride, dest_cf,
src_buf, &src_area, src_stride, src_cf, draw_dsc);
else if(has_transform)
_pxp_blit_transform(dest_buf, clipped_img_area, dest_stride, dest_cf,
src_buf, &src_area, src_stride, src_cf, draw_dsc);
else
_pxp_blit(dest_buf, clipped_img_area, dest_stride, dest_cf,
src_buf, &src_area, src_stride, src_cf, draw_dsc->opa);
}
static void _pxp_blit_recolor(uint8_t * dest_buf, const lv_area_t * dest_area, int32_t dest_stride,
lv_color_format_t dest_cf, const uint8_t * src_buf, const lv_area_t * src_area,
@@ -193,14 +202,6 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area,
int32_t dest_w = lv_area_get_width(dest_area);
int32_t dest_h = lv_area_get_height(dest_area);
lv_point_t pivot = dsc->pivot;
/*The offsets are now relative to the transformation result with pivot ULC*/
int32_t piv_offset_x = 0;
int32_t piv_offset_y = 0;
int32_t trim_x = 0;
int32_t trim_y = 0;
bool has_rotation = (dsc->rotation != 0);
bool has_scale = (dsc->scale_x != LV_SCALE_NONE || dsc->scale_y != LV_SCALE_NONE);
uint8_t src_px_size = lv_color_format_get_size(src_cf);
@@ -214,51 +215,23 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area,
switch(dsc->rotation) {
case 0:
pxp_angle = kPXP_Rotate0;
piv_offset_x = 0;
piv_offset_y = 0;
break;
case 900:
pxp_angle = kPXP_Rotate90;
piv_offset_x = pivot.x + pivot.y - src_h;
piv_offset_y = pivot.y - pivot.x;
break;
case 1800:
pxp_angle = kPXP_Rotate180;
piv_offset_x = 2 * pivot.x - src_w;
piv_offset_y = 2 * pivot.y - src_h;
break;
case 2700:
pxp_angle = kPXP_Rotate270;
piv_offset_x = pivot.x - pivot.y;
piv_offset_y = pivot.x + pivot.y - src_w;
break;
default:
pxp_angle = kPXP_Rotate0;
piv_offset_x = 0;
piv_offset_y = 0;
}
/*PS buffer rotation and decimation does not function at the same time*/
PXP_SetRotateConfig(PXP_ID, kPXP_RotateOutputBuffer, pxp_angle, kPXP_FlipDisable);
}
if(has_scale) {
float fp_scale_x = (float)dsc->scale_x / LV_SCALE_NONE;
float fp_scale_y = (float)dsc->scale_y / LV_SCALE_NONE;
int32_t int_scale_x = (int32_t)fp_scale_x;
int32_t int_scale_y = (int32_t)fp_scale_y;
/*Any scale_factor in (k, k + 1] will result in a trim equal to k*/
trim_x = (fp_scale_x == int_scale_x) ? int_scale_x - 1 : int_scale_x;
trim_y = (fp_scale_y == int_scale_y) ? int_scale_y - 1 : int_scale_y;
dest_w = src_w * fp_scale_x + trim_x;
dest_h = src_h * fp_scale_y + trim_y;
/*Final pivot offset = scale_factor * rotation_pivot_offset + scaling_pivot_offset*/
piv_offset_x = floorf(fp_scale_x * piv_offset_x) - floorf((fp_scale_x - 1) * pivot.x);
piv_offset_y = floorf(fp_scale_y * piv_offset_y) - floorf((fp_scale_y - 1) * pivot.y);
}
/*PS buffer - source image*/
pxp_ps_buffer_config_t psBufferConfig = {
.pixelFormat = pxp_get_ps_px_format(src_cf),
@@ -269,7 +242,7 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area,
.pitchBytes = src_stride
};
PXP_SetProcessSurfaceBufferConfig(PXP_ID, &psBufferConfig);
PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - trim_x - 1U, dest_h - trim_y - 1U);
PXP_SetProcessSurfacePosition(PXP_ID, 0U, 0U, dest_w - 1U, dest_h - 1U);
if(has_scale)
PXP_SetProcessSurfaceScaler(PXP_ID, src_w, src_h, dest_w, dest_h);
@@ -281,11 +254,11 @@ static void _pxp_blit_transform(uint8_t * dest_buf, const lv_area_t * dest_area,
pxp_output_buffer_config_t outputBufferConfig = {
.pixelFormat = pxp_get_out_px_format(dest_cf),
.interlacedMode = kPXP_OutputProgressive,
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * (dest_area->y1 + piv_offset_y) + dest_px_size * (dest_area->x1 + piv_offset_x)),
.buffer0Addr = (uint32_t)(dest_buf + dest_stride * (dest_area->y1) + dest_px_size * (dest_area->x1)),
.buffer1Addr = (uint32_t)0U,
.pitchBytes = dest_stride,
.width = dest_w - trim_x,
.height = dest_h - trim_y
.width = dest_w,
.height = dest_h
};
PXP_SetOutputBufferConfig(PXP_ID, &outputBufferConfig);