Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Signed-off-by: FASTSHIFT <vifextech@foxmail.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
1079 lines
33 KiB
C
1079 lines
33 KiB
C
/**
|
|
* @file vg_lite_utils.c
|
|
*
|
|
*/
|
|
|
|
/*********************
|
|
* INCLUDES
|
|
*********************/
|
|
|
|
#include "lv_vg_lite_utils.h"
|
|
|
|
#if LV_USE_DRAW_VG_LITE
|
|
|
|
#include "lv_vg_lite_decoder.h"
|
|
#include "lv_vg_lite_path.h"
|
|
#include "lv_draw_vg_lite_type.h"
|
|
#include <string.h>
|
|
|
|
/*********************
|
|
* DEFINES
|
|
*********************/
|
|
|
|
#define ENUM_TO_STRING(e) \
|
|
case (e): \
|
|
return #e
|
|
|
|
#define VG_LITE_ENUM_TO_STRING(e) \
|
|
case (VG_LITE_##e): \
|
|
return #e
|
|
|
|
#define VLC_OP_ENUM_TO_STRING(e) \
|
|
case (VLC_OP_##e): \
|
|
return #e
|
|
|
|
#define FEATURE_ENUM_TO_STRING(e) \
|
|
case (gcFEATURE_BIT_VG_##e): \
|
|
return #e
|
|
|
|
/**********************
|
|
* TYPEDEFS
|
|
**********************/
|
|
|
|
/**********************
|
|
* STATIC PROTOTYPES
|
|
**********************/
|
|
|
|
/**********************
|
|
* STATIC VARIABLES
|
|
**********************/
|
|
|
|
/**********************
|
|
* MACROS
|
|
**********************/
|
|
|
|
/**********************
|
|
* GLOBAL FUNCTIONS
|
|
**********************/
|
|
|
|
void lv_vg_lite_dump_info(void)
|
|
{
|
|
char name[64];
|
|
vg_lite_uint32_t chip_id;
|
|
vg_lite_uint32_t chip_rev;
|
|
vg_lite_uint32_t cid;
|
|
vg_lite_get_product_info(name, &chip_id, &chip_rev);
|
|
vg_lite_get_register(0x30, &cid);
|
|
LV_LOG_USER("Product Info: %s"
|
|
" | Chip ID: 0x%" LV_PRIx32
|
|
" | Revision: 0x%" LV_PRIx32
|
|
" | CID: 0x%" LV_PRIx32,
|
|
name, (uint32_t)chip_id, (uint32_t)chip_rev, (uint32_t)cid);
|
|
|
|
vg_lite_info_t info;
|
|
vg_lite_get_info(&info);
|
|
LV_LOG_USER("VGLite API version: 0x%" LV_PRIx32, (uint32_t)info.api_version);
|
|
LV_LOG_USER("VGLite API header version: 0x%" LV_PRIx32, (uint32_t)info.header_version);
|
|
LV_LOG_USER("VGLite release version: 0x%" LV_PRIx32, (uint32_t)info.release_version);
|
|
|
|
for(int feature = 0; feature < gcFEATURE_COUNT; feature++) {
|
|
vg_lite_uint32_t ret = vg_lite_query_feature((vg_lite_feature_t)feature);
|
|
LV_UNUSED(ret);
|
|
LV_LOG_USER("Feature-%d: %s\t - %s",
|
|
feature, lv_vg_lite_feature_string((vg_lite_feature_t)feature),
|
|
ret ? "YES" : "NO");
|
|
}
|
|
|
|
vg_lite_uint32_t mem_avail = 0;
|
|
vg_lite_get_mem_size(&mem_avail);
|
|
LV_LOG_USER("Memory Avaliable: %" LV_PRId32 " Bytes", (uint32_t)mem_avail);
|
|
}
|
|
|
|
const char * lv_vg_lite_error_string(vg_lite_error_t error)
|
|
{
|
|
switch(error) {
|
|
VG_LITE_ENUM_TO_STRING(SUCCESS);
|
|
VG_LITE_ENUM_TO_STRING(INVALID_ARGUMENT);
|
|
VG_LITE_ENUM_TO_STRING(OUT_OF_MEMORY);
|
|
VG_LITE_ENUM_TO_STRING(NO_CONTEXT);
|
|
VG_LITE_ENUM_TO_STRING(TIMEOUT);
|
|
VG_LITE_ENUM_TO_STRING(OUT_OF_RESOURCES);
|
|
VG_LITE_ENUM_TO_STRING(GENERIC_IO);
|
|
VG_LITE_ENUM_TO_STRING(NOT_SUPPORT);
|
|
VG_LITE_ENUM_TO_STRING(ALREADY_EXISTS);
|
|
VG_LITE_ENUM_TO_STRING(NOT_ALIGNED);
|
|
VG_LITE_ENUM_TO_STRING(FLEXA_TIME_OUT);
|
|
VG_LITE_ENUM_TO_STRING(FLEXA_HANDSHAKE_FAIL);
|
|
default:
|
|
break;
|
|
}
|
|
return "UNKNOW_ERROR";
|
|
}
|
|
|
|
const char * lv_vg_lite_feature_string(vg_lite_feature_t feature)
|
|
{
|
|
switch(feature) {
|
|
FEATURE_ENUM_TO_STRING(IM_INDEX_FORMAT);
|
|
FEATURE_ENUM_TO_STRING(SCISSOR);
|
|
FEATURE_ENUM_TO_STRING(BORDER_CULLING);
|
|
FEATURE_ENUM_TO_STRING(RGBA2_FORMAT);
|
|
FEATURE_ENUM_TO_STRING(QUALITY_8X);
|
|
FEATURE_ENUM_TO_STRING(IM_FASTCLAER);
|
|
FEATURE_ENUM_TO_STRING(RADIAL_GRADIENT);
|
|
FEATURE_ENUM_TO_STRING(GLOBAL_ALPHA);
|
|
FEATURE_ENUM_TO_STRING(RGBA8_ETC2_EAC);
|
|
FEATURE_ENUM_TO_STRING(COLOR_KEY);
|
|
FEATURE_ENUM_TO_STRING(DOUBLE_IMAGE);
|
|
FEATURE_ENUM_TO_STRING(YUV_OUTPUT);
|
|
FEATURE_ENUM_TO_STRING(FLEXA);
|
|
FEATURE_ENUM_TO_STRING(24BIT);
|
|
FEATURE_ENUM_TO_STRING(DITHER);
|
|
FEATURE_ENUM_TO_STRING(USE_DST);
|
|
FEATURE_ENUM_TO_STRING(PE_CLEAR);
|
|
FEATURE_ENUM_TO_STRING(IM_INPUT);
|
|
FEATURE_ENUM_TO_STRING(DEC_COMPRESS);
|
|
FEATURE_ENUM_TO_STRING(LINEAR_GRADIENT_EXT);
|
|
FEATURE_ENUM_TO_STRING(MASK);
|
|
FEATURE_ENUM_TO_STRING(MIRROR);
|
|
FEATURE_ENUM_TO_STRING(GAMMA);
|
|
FEATURE_ENUM_TO_STRING(NEW_BLEND_MODE);
|
|
FEATURE_ENUM_TO_STRING(STENCIL);
|
|
FEATURE_ENUM_TO_STRING(SRC_PREMULTIPLIED); /*! Valid only if FEATURE_ENUM_TO_STRING(HW_PREMULTIPLY is 0 */
|
|
FEATURE_ENUM_TO_STRING(HW_PREMULTIPLY); /*! HW multiplier can accept either premultiplied or not */
|
|
FEATURE_ENUM_TO_STRING(COLOR_TRANSFORMATION);
|
|
FEATURE_ENUM_TO_STRING(LVGL_SUPPORT);
|
|
FEATURE_ENUM_TO_STRING(INDEX_ENDIAN);
|
|
FEATURE_ENUM_TO_STRING(24BIT_PLANAR);
|
|
FEATURE_ENUM_TO_STRING(PIXEL_MATRIX);
|
|
FEATURE_ENUM_TO_STRING(NEW_IMAGE_INDEX);
|
|
FEATURE_ENUM_TO_STRING(PARALLEL_PATHS);
|
|
FEATURE_ENUM_TO_STRING(STRIPE_MODE);
|
|
FEATURE_ENUM_TO_STRING(IM_DEC_INPUT);
|
|
FEATURE_ENUM_TO_STRING(GAUSSIAN_BLUR);
|
|
FEATURE_ENUM_TO_STRING(RECTANGLE_TILED_OUT);
|
|
FEATURE_ENUM_TO_STRING(TESSELLATION_TILED_OUT);
|
|
FEATURE_ENUM_TO_STRING(IM_REPEAT_REFLECT);
|
|
FEATURE_ENUM_TO_STRING(YUY2_INPUT);
|
|
FEATURE_ENUM_TO_STRING(YUV_INPUT);
|
|
FEATURE_ENUM_TO_STRING(YUV_TILED_INPUT);
|
|
FEATURE_ENUM_TO_STRING(AYUV_INPUT);
|
|
FEATURE_ENUM_TO_STRING(16PIXELS_ALIGN);
|
|
default:
|
|
break;
|
|
}
|
|
return "UNKNOW_FEATURE";
|
|
}
|
|
|
|
const char * lv_vg_lite_buffer_format_string(vg_lite_buffer_format_t format)
|
|
{
|
|
switch(format) {
|
|
VG_LITE_ENUM_TO_STRING(RGBA8888);
|
|
VG_LITE_ENUM_TO_STRING(BGRA8888);
|
|
VG_LITE_ENUM_TO_STRING(RGBX8888);
|
|
VG_LITE_ENUM_TO_STRING(BGRX8888);
|
|
VG_LITE_ENUM_TO_STRING(RGB565);
|
|
VG_LITE_ENUM_TO_STRING(BGR565);
|
|
VG_LITE_ENUM_TO_STRING(RGBA4444);
|
|
VG_LITE_ENUM_TO_STRING(BGRA4444);
|
|
VG_LITE_ENUM_TO_STRING(BGRA5551);
|
|
VG_LITE_ENUM_TO_STRING(A4);
|
|
VG_LITE_ENUM_TO_STRING(A8);
|
|
VG_LITE_ENUM_TO_STRING(L8);
|
|
VG_LITE_ENUM_TO_STRING(YUYV);
|
|
VG_LITE_ENUM_TO_STRING(YUY2);
|
|
VG_LITE_ENUM_TO_STRING(NV12);
|
|
VG_LITE_ENUM_TO_STRING(ANV12);
|
|
VG_LITE_ENUM_TO_STRING(AYUY2);
|
|
VG_LITE_ENUM_TO_STRING(YV12);
|
|
VG_LITE_ENUM_TO_STRING(YV24);
|
|
VG_LITE_ENUM_TO_STRING(YV16);
|
|
VG_LITE_ENUM_TO_STRING(NV16);
|
|
VG_LITE_ENUM_TO_STRING(YUY2_TILED);
|
|
VG_LITE_ENUM_TO_STRING(NV12_TILED);
|
|
VG_LITE_ENUM_TO_STRING(ANV12_TILED);
|
|
VG_LITE_ENUM_TO_STRING(AYUY2_TILED);
|
|
VG_LITE_ENUM_TO_STRING(INDEX_1);
|
|
VG_LITE_ENUM_TO_STRING(INDEX_2);
|
|
VG_LITE_ENUM_TO_STRING(INDEX_4);
|
|
VG_LITE_ENUM_TO_STRING(INDEX_8);
|
|
VG_LITE_ENUM_TO_STRING(RGBA2222);
|
|
VG_LITE_ENUM_TO_STRING(BGRA2222);
|
|
VG_LITE_ENUM_TO_STRING(ABGR2222);
|
|
VG_LITE_ENUM_TO_STRING(ARGB2222);
|
|
VG_LITE_ENUM_TO_STRING(ABGR4444);
|
|
VG_LITE_ENUM_TO_STRING(ARGB4444);
|
|
VG_LITE_ENUM_TO_STRING(ABGR8888);
|
|
VG_LITE_ENUM_TO_STRING(ARGB8888);
|
|
VG_LITE_ENUM_TO_STRING(ABGR1555);
|
|
VG_LITE_ENUM_TO_STRING(RGBA5551);
|
|
VG_LITE_ENUM_TO_STRING(ARGB1555);
|
|
VG_LITE_ENUM_TO_STRING(XBGR8888);
|
|
VG_LITE_ENUM_TO_STRING(XRGB8888);
|
|
VG_LITE_ENUM_TO_STRING(RGBA8888_ETC2_EAC);
|
|
VG_LITE_ENUM_TO_STRING(RGB888);
|
|
VG_LITE_ENUM_TO_STRING(BGR888);
|
|
VG_LITE_ENUM_TO_STRING(ABGR8565);
|
|
VG_LITE_ENUM_TO_STRING(BGRA5658);
|
|
VG_LITE_ENUM_TO_STRING(ARGB8565);
|
|
VG_LITE_ENUM_TO_STRING(RGBA5658);
|
|
default:
|
|
break;
|
|
}
|
|
return "UNKNOW_BUFFER_FORMAT";
|
|
}
|
|
|
|
const char * lv_vg_lite_vlc_op_string(uint8_t vlc_op)
|
|
{
|
|
switch(vlc_op) {
|
|
VLC_OP_ENUM_TO_STRING(END);
|
|
VLC_OP_ENUM_TO_STRING(CLOSE);
|
|
VLC_OP_ENUM_TO_STRING(MOVE);
|
|
VLC_OP_ENUM_TO_STRING(MOVE_REL);
|
|
VLC_OP_ENUM_TO_STRING(LINE);
|
|
VLC_OP_ENUM_TO_STRING(LINE_REL);
|
|
VLC_OP_ENUM_TO_STRING(QUAD);
|
|
VLC_OP_ENUM_TO_STRING(QUAD_REL);
|
|
VLC_OP_ENUM_TO_STRING(CUBIC);
|
|
VLC_OP_ENUM_TO_STRING(CUBIC_REL);
|
|
|
|
VLC_OP_ENUM_TO_STRING(SCCWARC);
|
|
VLC_OP_ENUM_TO_STRING(SCCWARC_REL);
|
|
VLC_OP_ENUM_TO_STRING(SCWARC);
|
|
VLC_OP_ENUM_TO_STRING(SCWARC_REL);
|
|
VLC_OP_ENUM_TO_STRING(LCCWARC);
|
|
VLC_OP_ENUM_TO_STRING(LCCWARC_REL);
|
|
VLC_OP_ENUM_TO_STRING(LCWARC);
|
|
VLC_OP_ENUM_TO_STRING(LCWARC_REL);
|
|
default:
|
|
break;
|
|
}
|
|
return "UNKNOW_VLC_OP";
|
|
}
|
|
|
|
static void path_data_print_cb(void * user_data, uint8_t op_code, const float * data, uint32_t len)
|
|
{
|
|
LV_UNUSED(user_data);
|
|
|
|
LV_LOG("%s, ", lv_vg_lite_vlc_op_string(op_code));
|
|
for(uint32_t i = 0; i < len; i++) {
|
|
LV_LOG("%0.2f, ", data[i]);
|
|
}
|
|
LV_LOG("\n");
|
|
}
|
|
|
|
void lv_vg_lite_path_dump_info(const vg_lite_path_t * path)
|
|
{
|
|
LV_ASSERT(path != NULL);
|
|
LV_ASSERT(path->path != NULL);
|
|
uint8_t fmt_len = lv_vg_lite_path_format_len(path->format);
|
|
size_t len = path->path_length / fmt_len;
|
|
|
|
LV_ASSERT(len > 0);
|
|
|
|
LV_LOG_USER("address: %p", path->path);
|
|
LV_LOG_USER("length: %d", (int)len);
|
|
LV_LOG_USER("bonding box: (%0.2f, %0.2f) - (%0.2f, %0.2f)",
|
|
path->bounding_box[0], path->bounding_box[1],
|
|
path->bounding_box[2], path->bounding_box[3]);
|
|
LV_LOG_USER("format: %d", (int)path->format);
|
|
LV_LOG_USER("quality: %d", (int)path->quality);
|
|
|
|
lv_vg_lite_path_for_each_data(path, path_data_print_cb, NULL);
|
|
}
|
|
|
|
void lv_vg_lite_buffer_dump_info(const vg_lite_buffer_t * buffer)
|
|
{
|
|
LV_LOG_USER("memory: %p", (buffer)->memory);
|
|
LV_LOG_USER("address: 0x%08x", (int)(buffer)->address);
|
|
LV_LOG_USER("size: W%d x H%d", (int)((buffer)->width), (int)((buffer)->height));
|
|
LV_LOG_USER("stride: %d", (int)((buffer)->stride));
|
|
LV_LOG_USER("format: %d (%s)",
|
|
(int)((buffer)->format),
|
|
lv_vg_lite_buffer_format_string((buffer)->format));
|
|
LV_LOG_USER("tiled: %d", (int)((buffer)->tiled));
|
|
}
|
|
|
|
void lv_vg_lite_matrix_dump_info(const vg_lite_matrix_t * matrix)
|
|
{
|
|
for(int i = 0; i < 3; i++) {
|
|
LV_LOG_USER("| %0.2f, %0.2f, %0.2f |",
|
|
(matrix)->m[i][0], (matrix)->m[i][1], (matrix)->m[i][2]);
|
|
}
|
|
}
|
|
|
|
bool lv_vg_lite_is_dest_cf_supported(lv_color_format_t cf)
|
|
{
|
|
switch(cf) {
|
|
case LV_COLOR_FORMAT_RGB565:
|
|
case LV_COLOR_FORMAT_RGB565A8:
|
|
case LV_COLOR_FORMAT_RGB888:
|
|
case LV_COLOR_FORMAT_ARGB8888:
|
|
case LV_COLOR_FORMAT_XRGB8888:
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool lv_vg_lite_is_src_cf_supported(lv_color_format_t cf)
|
|
{
|
|
switch(cf) {
|
|
case LV_COLOR_FORMAT_A4:
|
|
case LV_COLOR_FORMAT_A8:
|
|
case LV_COLOR_FORMAT_I8:
|
|
case LV_COLOR_FORMAT_RGB565:
|
|
case LV_COLOR_FORMAT_RGB565A8:
|
|
case LV_COLOR_FORMAT_RGB888:
|
|
case LV_COLOR_FORMAT_ARGB8888:
|
|
case LV_COLOR_FORMAT_XRGB8888:
|
|
case LV_COLOR_FORMAT_NV12:
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
vg_lite_buffer_format_t lv_vg_lite_vg_fmt(lv_color_format_t cf)
|
|
{
|
|
switch(cf) {
|
|
case LV_COLOR_FORMAT_A4:
|
|
return VG_LITE_A4;
|
|
|
|
case LV_COLOR_FORMAT_A8:
|
|
return VG_LITE_A8;
|
|
|
|
case LV_COLOR_FORMAT_L8:
|
|
return VG_LITE_L8;
|
|
|
|
case LV_COLOR_FORMAT_I1:
|
|
return VG_LITE_INDEX_1;
|
|
|
|
case LV_COLOR_FORMAT_I2:
|
|
return VG_LITE_INDEX_2;
|
|
|
|
case LV_COLOR_FORMAT_I4:
|
|
return VG_LITE_INDEX_4;
|
|
|
|
case LV_COLOR_FORMAT_I8:
|
|
return VG_LITE_INDEX_8;
|
|
|
|
case LV_COLOR_FORMAT_RGB565:
|
|
return VG_LITE_BGR565;
|
|
|
|
case LV_COLOR_FORMAT_RGB565A8:
|
|
return VG_LITE_BGRA5658;
|
|
|
|
case LV_COLOR_FORMAT_RGB888:
|
|
return VG_LITE_BGR888;
|
|
|
|
case LV_COLOR_FORMAT_ARGB8888:
|
|
return VG_LITE_BGRA8888;
|
|
|
|
case LV_COLOR_FORMAT_XRGB8888:
|
|
return VG_LITE_BGRX8888;
|
|
|
|
case LV_COLOR_FORMAT_NV12:
|
|
return VG_LITE_NV12;
|
|
|
|
default:
|
|
LV_LOG_ERROR("unsupport color format: %d", cf);
|
|
break;
|
|
}
|
|
|
|
LV_ASSERT(false);
|
|
return 0;
|
|
}
|
|
|
|
void lv_vg_lite_buffer_format_bytes(
|
|
vg_lite_buffer_format_t format,
|
|
uint32_t * mul,
|
|
uint32_t * div,
|
|
uint32_t * bytes_align)
|
|
{
|
|
/* Get the bpp information of a color format. */
|
|
*mul = *div = 1;
|
|
*bytes_align = 4;
|
|
switch(format) {
|
|
case VG_LITE_L8:
|
|
case VG_LITE_A8:
|
|
case VG_LITE_RGBA8888_ETC2_EAC:
|
|
break;
|
|
case VG_LITE_A4:
|
|
*div = 2;
|
|
break;
|
|
case VG_LITE_ABGR1555:
|
|
case VG_LITE_ARGB1555:
|
|
case VG_LITE_BGRA5551:
|
|
case VG_LITE_RGBA5551:
|
|
case VG_LITE_RGBA4444:
|
|
case VG_LITE_BGRA4444:
|
|
case VG_LITE_ABGR4444:
|
|
case VG_LITE_ARGB4444:
|
|
case VG_LITE_RGB565:
|
|
case VG_LITE_BGR565:
|
|
case VG_LITE_YUYV:
|
|
case VG_LITE_YUY2:
|
|
case VG_LITE_YUY2_TILED:
|
|
/* AYUY2 buffer memory = YUY2 + alpha. */
|
|
case VG_LITE_AYUY2:
|
|
case VG_LITE_AYUY2_TILED:
|
|
*mul = 2;
|
|
break;
|
|
case VG_LITE_RGBA8888:
|
|
case VG_LITE_BGRA8888:
|
|
case VG_LITE_ABGR8888:
|
|
case VG_LITE_ARGB8888:
|
|
case VG_LITE_RGBX8888:
|
|
case VG_LITE_BGRX8888:
|
|
case VG_LITE_XBGR8888:
|
|
case VG_LITE_XRGB8888:
|
|
*mul = 4;
|
|
break;
|
|
case VG_LITE_NV12:
|
|
case VG_LITE_NV12_TILED:
|
|
*mul = 1;
|
|
break;
|
|
case VG_LITE_ANV12:
|
|
case VG_LITE_ANV12_TILED:
|
|
*mul = 4;
|
|
break;
|
|
case VG_LITE_INDEX_1:
|
|
*div = 8;
|
|
*bytes_align = 8;
|
|
break;
|
|
case VG_LITE_INDEX_2:
|
|
*div = 4;
|
|
*bytes_align = 8;
|
|
break;
|
|
case VG_LITE_INDEX_4:
|
|
*div = 2;
|
|
*bytes_align = 8;
|
|
break;
|
|
case VG_LITE_INDEX_8:
|
|
*bytes_align = 1;
|
|
break;
|
|
case VG_LITE_RGBA2222:
|
|
case VG_LITE_BGRA2222:
|
|
case VG_LITE_ABGR2222:
|
|
case VG_LITE_ARGB2222:
|
|
*mul = 1;
|
|
break;
|
|
case VG_LITE_RGB888:
|
|
case VG_LITE_BGR888:
|
|
case VG_LITE_ABGR8565:
|
|
case VG_LITE_BGRA5658:
|
|
case VG_LITE_ARGB8565:
|
|
case VG_LITE_RGBA5658:
|
|
*mul = 3;
|
|
break;
|
|
default:
|
|
LV_LOG_ERROR("unsupport color format: 0x%" PRIx32, (uint32_t)format);
|
|
LV_ASSERT(false);
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint32_t lv_vg_lite_width_to_stride(uint32_t w, vg_lite_buffer_format_t color_format)
|
|
{
|
|
w = lv_vg_lite_width_align(w);
|
|
|
|
uint32_t mul, div, align;
|
|
lv_vg_lite_buffer_format_bytes(color_format, &mul, &div, &align);
|
|
return LV_VG_LITE_ALIGN((w * mul / div), align);
|
|
}
|
|
|
|
uint32_t lv_vg_lite_width_align(uint32_t w)
|
|
{
|
|
if(lv_vg_lite_16px_align()) {
|
|
w = LV_VG_LITE_ALIGN(w, 16);
|
|
}
|
|
|
|
return w;
|
|
}
|
|
|
|
void lv_vg_lite_buffer_init(
|
|
vg_lite_buffer_t * buffer,
|
|
const void * ptr,
|
|
int32_t width,
|
|
int32_t height,
|
|
vg_lite_buffer_format_t format,
|
|
bool tiled)
|
|
{
|
|
uint32_t mul;
|
|
uint32_t div;
|
|
uint32_t align;
|
|
LV_ASSERT_NULL(buffer);
|
|
LV_ASSERT_NULL(ptr);
|
|
|
|
lv_memzero(buffer, sizeof(vg_lite_buffer_t));
|
|
|
|
buffer->format = format;
|
|
if(tiled || format == VG_LITE_RGBA8888_ETC2_EAC) {
|
|
buffer->tiled = VG_LITE_TILED;
|
|
}
|
|
else {
|
|
buffer->tiled = VG_LITE_LINEAR;
|
|
}
|
|
buffer->image_mode = VG_LITE_NORMAL_IMAGE_MODE;
|
|
buffer->transparency_mode = VG_LITE_IMAGE_OPAQUE;
|
|
buffer->width = width;
|
|
buffer->height = height;
|
|
lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align);
|
|
buffer->stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align);
|
|
|
|
if(format == VG_LITE_NV12) {
|
|
lv_yuv_buf_t * frame_p = (lv_yuv_buf_t *)ptr;
|
|
buffer->memory = (void *)frame_p->semi_planar.y.buf;
|
|
buffer->address = (uintptr_t)frame_p->semi_planar.y.buf;
|
|
buffer->yuv.swizzle = VG_LITE_SWIZZLE_UV;
|
|
buffer->yuv.alpha_stride = buffer->stride;
|
|
buffer->yuv.uv_height = buffer->height / 2;
|
|
buffer->yuv.uv_memory = (void *)frame_p->semi_planar.uv.buf;
|
|
buffer->yuv.uv_planar = (uint32_t)(uintptr_t)frame_p->semi_planar.uv.buf;
|
|
buffer->yuv.uv_stride = frame_p->semi_planar.uv.stride;
|
|
}
|
|
else {
|
|
buffer->memory = (void *)ptr;
|
|
buffer->address = (uintptr_t)ptr;
|
|
}
|
|
}
|
|
|
|
void lv_vg_lite_buffer_from_draw_buf(vg_lite_buffer_t * buffer, const lv_draw_buf_t * draw_buf)
|
|
{
|
|
LV_ASSERT_NULL(buffer);
|
|
LV_ASSERT_NULL(draw_buf);
|
|
|
|
const uint8_t * ptr = draw_buf->data;
|
|
int32_t width = draw_buf->header.w;
|
|
int32_t height = draw_buf->header.h;
|
|
vg_lite_buffer_format_t format = lv_vg_lite_vg_fmt(draw_buf->header.cf);
|
|
|
|
if(LV_COLOR_FORMAT_IS_INDEXED(draw_buf->header.cf))
|
|
ptr += LV_COLOR_INDEXED_PALETTE_SIZE(draw_buf->header.cf) * 4;
|
|
|
|
width = lv_vg_lite_width_align(width);
|
|
|
|
lv_vg_lite_buffer_init(buffer, ptr, width, height, format, false);
|
|
|
|
/* Alpha image need to be multiplied by color */
|
|
if(LV_COLOR_FORMAT_IS_ALPHA_ONLY(draw_buf->header.cf)) {
|
|
buffer->image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
|
}
|
|
}
|
|
|
|
void lv_vg_lite_image_matrix(vg_lite_matrix_t * matrix, int32_t x, int32_t y, const lv_draw_image_dsc_t * dsc)
|
|
{
|
|
LV_ASSERT_NULL(matrix);
|
|
LV_ASSERT_NULL(dsc);
|
|
|
|
int32_t rotation = dsc->rotation;
|
|
int32_t scale_x = dsc->scale_x;
|
|
int32_t scale_y = dsc->scale_y;
|
|
|
|
vg_lite_translate(x, y, matrix);
|
|
|
|
if(rotation != 0 || scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) {
|
|
lv_point_t pivot = dsc->pivot;
|
|
vg_lite_translate(pivot.x, pivot.y, matrix);
|
|
|
|
if(rotation != 0) {
|
|
vg_lite_rotate(rotation * 0.1f, matrix);
|
|
}
|
|
|
|
if(scale_x != LV_SCALE_NONE || scale_y != LV_SCALE_NONE) {
|
|
vg_lite_scale(
|
|
(vg_lite_float_t)scale_x / LV_SCALE_NONE,
|
|
(vg_lite_float_t)scale_y / LV_SCALE_NONE,
|
|
matrix);
|
|
}
|
|
|
|
vg_lite_translate(-pivot.x, -pivot.y, matrix);
|
|
}
|
|
}
|
|
|
|
void lv_vg_lite_push_image_decoder_dsc(lv_draw_unit_t * draw_unit, lv_image_decoder_dsc_t * img_dsc)
|
|
{
|
|
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
|
lv_array_push_back(&u->img_dsc_pending, img_dsc);
|
|
}
|
|
|
|
void lv_vg_lite_clear_image_decoder_dsc(lv_draw_unit_t * draw_unit)
|
|
{
|
|
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
|
lv_array_t * arr = &u->img_dsc_pending;
|
|
uint32_t size = lv_array_size(arr);
|
|
if(size == 0) {
|
|
return;
|
|
}
|
|
|
|
/* Close all pending image decoder dsc */
|
|
for(uint32_t i = 0; i < size; i++) {
|
|
lv_image_decoder_dsc_t * img_dsc = lv_array_at(arr, i);
|
|
lv_image_decoder_close(img_dsc);
|
|
}
|
|
lv_array_clear(arr);
|
|
}
|
|
|
|
bool lv_vg_lite_buffer_open_image(vg_lite_buffer_t * buffer, lv_image_decoder_dsc_t * decoder_dsc, const void * src,
|
|
bool no_cache)
|
|
{
|
|
LV_ASSERT_NULL(buffer);
|
|
LV_ASSERT_NULL(decoder_dsc);
|
|
LV_ASSERT_NULL(src);
|
|
|
|
lv_image_decoder_args_t args;
|
|
lv_memzero(&args, sizeof(lv_image_decoder_args_t));
|
|
args.premultiply = !lv_vg_lite_support_blend_normal();
|
|
args.stride_align = true;
|
|
args.use_indexed = true;
|
|
args.no_cache = no_cache;
|
|
|
|
lv_result_t res = lv_image_decoder_open(decoder_dsc, src, &args);
|
|
if(res != LV_RESULT_OK) {
|
|
LV_LOG_ERROR("Failed to open image");
|
|
return false;
|
|
}
|
|
|
|
const lv_draw_buf_t * decoded = decoder_dsc->decoded;
|
|
if(decoded == NULL || decoded->data == NULL) {
|
|
lv_image_decoder_close(decoder_dsc);
|
|
LV_LOG_ERROR("image data is NULL");
|
|
return false;
|
|
}
|
|
|
|
if(!lv_vg_lite_is_src_cf_supported(decoded->header.cf)) {
|
|
LV_LOG_ERROR("unsupported color format: %d", decoded->header.cf);
|
|
lv_image_decoder_close(decoder_dsc);
|
|
return false;
|
|
}
|
|
|
|
if(LV_COLOR_FORMAT_IS_INDEXED(decoded->header.cf)) {
|
|
uint32_t palette_size = LV_COLOR_INDEXED_PALETTE_SIZE(decoded->header.cf);
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_set_CLUT(palette_size, (vg_lite_uint32_t *)decoded->data));
|
|
}
|
|
|
|
lv_vg_lite_buffer_from_draw_buf(buffer, decoded);
|
|
return true;
|
|
}
|
|
|
|
void lv_vg_lite_rect(vg_lite_rectangle_t * rect, const lv_area_t * area)
|
|
{
|
|
rect->x = area->x1;
|
|
rect->y = area->y1;
|
|
rect->width = lv_area_get_width(area);
|
|
rect->height = lv_area_get_height(area);
|
|
}
|
|
|
|
uint32_t lv_vg_lite_get_palette_size(vg_lite_buffer_format_t format)
|
|
{
|
|
uint32_t size = 0;
|
|
switch(format) {
|
|
case VG_LITE_INDEX_1:
|
|
size = 1 << 1;
|
|
break;
|
|
case VG_LITE_INDEX_2:
|
|
size = 1 << 2;
|
|
break;
|
|
case VG_LITE_INDEX_4:
|
|
size = 1 << 4;
|
|
break;
|
|
case VG_LITE_INDEX_8:
|
|
size = 1 << 8;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
vg_lite_color_t lv_vg_lite_color(lv_color_t color, lv_opa_t opa, bool pre_mul)
|
|
{
|
|
if(pre_mul && opa < LV_OPA_MAX) {
|
|
color.red = LV_UDIV255(color.red * opa);
|
|
color.green = LV_UDIV255(color.green * opa);
|
|
color.blue = LV_UDIV255(color.blue * opa);
|
|
}
|
|
return (uint32_t)opa << 24 | (uint32_t)color.blue << 16 | (uint32_t)color.green << 8 | color.red;
|
|
}
|
|
|
|
vg_lite_blend_t lv_vg_lite_blend_mode(lv_blend_mode_t blend_mode)
|
|
{
|
|
if(lv_vg_lite_support_blend_normal()) {
|
|
switch(blend_mode) {
|
|
case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/
|
|
return VG_LITE_BLEND_NORMAL_LVGL;
|
|
|
|
case LV_BLEND_MODE_ADDITIVE: /**< Add the respective color channels*/
|
|
return VG_LITE_BLEND_ADDITIVE_LVGL;
|
|
|
|
case LV_BLEND_MODE_SUBTRACTIVE: /**< Subtract the foreground from the background*/
|
|
return VG_LITE_BLEND_SUBTRACT_LVGL;
|
|
|
|
case LV_BLEND_MODE_MULTIPLY: /**< Multiply the foreground and background*/
|
|
return VG_LITE_BLEND_MULTIPLY_LVGL;
|
|
|
|
default:
|
|
return VG_LITE_BLEND_NONE;
|
|
}
|
|
}
|
|
|
|
switch(blend_mode) {
|
|
case LV_BLEND_MODE_NORMAL: /**< Simply mix according to the opacity value*/
|
|
return VG_LITE_BLEND_SRC_OVER;
|
|
|
|
case LV_BLEND_MODE_ADDITIVE: /**< Add the respective color channels*/
|
|
return VG_LITE_BLEND_ADDITIVE;
|
|
|
|
case LV_BLEND_MODE_SUBTRACTIVE: /**< Subtract the foreground from the background*/
|
|
return VG_LITE_BLEND_SUBTRACT;
|
|
|
|
case LV_BLEND_MODE_MULTIPLY: /**< Multiply the foreground and background*/
|
|
return VG_LITE_BLEND_MULTIPLY;
|
|
|
|
default:
|
|
return VG_LITE_BLEND_NONE;
|
|
}
|
|
}
|
|
|
|
bool lv_vg_lite_buffer_check(const vg_lite_buffer_t * buffer, bool is_src)
|
|
{
|
|
uint32_t mul;
|
|
uint32_t div;
|
|
uint32_t align;
|
|
int32_t stride;
|
|
|
|
if(!buffer) {
|
|
LV_LOG_ERROR("buffer is NULL");
|
|
return false;
|
|
}
|
|
|
|
if(buffer->width < 1) {
|
|
LV_LOG_ERROR("buffer width(%d) < 1", (int)buffer->width);
|
|
return false;
|
|
}
|
|
|
|
if(buffer->height < 1) {
|
|
LV_LOG_ERROR("buffer height(%d) < 1", (int)buffer->height);
|
|
return false;
|
|
}
|
|
|
|
if(buffer->stride < 1) {
|
|
LV_LOG_ERROR("buffer stride(%d) < 1", (int)buffer->stride);
|
|
return false;
|
|
}
|
|
|
|
if(!(buffer->tiled == VG_LITE_LINEAR || buffer->tiled == VG_LITE_TILED)) {
|
|
LV_LOG_ERROR("buffer tiled(%d) is invalid", (int)buffer->tiled);
|
|
return false;
|
|
}
|
|
|
|
if(buffer->memory == NULL) {
|
|
LV_LOG_ERROR("buffer memory is NULL");
|
|
return false;
|
|
}
|
|
|
|
if((uint32_t)(uintptr_t)buffer->memory != buffer->address) {
|
|
LV_LOG_ERROR("buffer memory(%p) != address(%p)",
|
|
buffer->memory, (void *)(uintptr_t)buffer->address);
|
|
return false;
|
|
}
|
|
|
|
if(is_src && buffer->width != (vg_lite_int32_t)lv_vg_lite_width_align(buffer->width)) {
|
|
LV_LOG_ERROR("buffer width(%d) is not aligned", (int)buffer->width);
|
|
return false;
|
|
}
|
|
|
|
if(!LV_VG_LITE_IS_ALIGNED(buffer->memory, LV_DRAW_BUF_ALIGN)) {
|
|
LV_LOG_ERROR("buffer address(%p) is not aligned to %d", buffer->memory, LV_DRAW_BUF_ALIGN);
|
|
return false;
|
|
}
|
|
|
|
lv_vg_lite_buffer_format_bytes(buffer->format, &mul, &div, &align);
|
|
stride = LV_VG_LITE_ALIGN((buffer->width * mul / div), align);
|
|
|
|
if(buffer->stride != stride) {
|
|
LV_LOG_ERROR("buffer stride(%d) != %d", (int)buffer->stride, (int)stride);
|
|
return false;
|
|
}
|
|
|
|
if(!(buffer->image_mode == VG_LITE_NORMAL_IMAGE_MODE
|
|
|| buffer->image_mode == VG_LITE_NONE_IMAGE_MODE
|
|
|| buffer->image_mode == VG_LITE_MULTIPLY_IMAGE_MODE)) {
|
|
LV_LOG_ERROR("buffer image_mode(%d) is invalid", (int)buffer->image_mode);
|
|
return false;
|
|
}
|
|
|
|
if(!(buffer->transparency_mode == VG_LITE_IMAGE_OPAQUE
|
|
|| buffer->transparency_mode == VG_LITE_IMAGE_TRANSPARENT)) {
|
|
LV_LOG_ERROR("buffer transparency_mode(%d) is invalid",
|
|
(int)buffer->transparency_mode);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool lv_vg_lite_path_check(const vg_lite_path_t * path)
|
|
{
|
|
if(path == NULL) {
|
|
LV_LOG_ERROR("path is NULL");
|
|
return false;
|
|
}
|
|
|
|
if(path->path == NULL) {
|
|
LV_LOG_ERROR("path->path is NULL");
|
|
return false;
|
|
}
|
|
|
|
uint8_t fmt_len = lv_vg_lite_path_format_len(path->format);
|
|
if(!fmt_len) {
|
|
LV_LOG_ERROR("path format(%d) is invalid", (int)path->format);
|
|
return false;
|
|
}
|
|
|
|
size_t len = path->path_length / fmt_len;
|
|
|
|
if(len < 1) {
|
|
LV_LOG_ERROR("path length(%d) error", (int)path->path_length);
|
|
return false;
|
|
}
|
|
|
|
const uint8_t * cur = path->path;
|
|
const uint8_t * end = cur + path->path_length;
|
|
|
|
while(cur < end) {
|
|
/* get op code */
|
|
uint8_t op_code = VLC_GET_OP_CODE(cur);
|
|
|
|
/* get arguments length */
|
|
uint8_t arg_len = lv_vg_lite_vlc_op_arg_len(op_code);
|
|
|
|
/* get next op code */
|
|
cur += (fmt_len * (1 + arg_len)) ;
|
|
|
|
/* break if end */
|
|
if(op_code == VLC_OP_END) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(cur != end) {
|
|
LV_LOG_ERROR("path length(%d) error", (int)path->path_length);
|
|
return false;
|
|
}
|
|
|
|
uint8_t end_op_code = VLC_GET_OP_CODE(end - fmt_len);
|
|
if(end_op_code != VLC_OP_END) {
|
|
LV_LOG_ERROR("%d (%s) -> is NOT VLC_OP_END", end_op_code, lv_vg_lite_vlc_op_string(end_op_code));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool lv_vg_lite_support_blend_normal(void)
|
|
{
|
|
return vg_lite_query_feature(gcFEATURE_BIT_VG_LVGL_SUPPORT);
|
|
}
|
|
|
|
bool lv_vg_lite_16px_align(void)
|
|
{
|
|
return vg_lite_query_feature(gcFEATURE_BIT_VG_16PIXELS_ALIGN);
|
|
}
|
|
|
|
void lv_vg_lite_draw_linear_grad(
|
|
vg_lite_buffer_t * buffer,
|
|
vg_lite_path_t * path,
|
|
const lv_area_t * area,
|
|
const lv_grad_dsc_t * grad,
|
|
const vg_lite_matrix_t * matrix,
|
|
vg_lite_fill_t fill,
|
|
vg_lite_blend_t blend)
|
|
{
|
|
LV_ASSERT_NULL(buffer);
|
|
LV_ASSERT_NULL(path);
|
|
LV_ASSERT_NULL(area);
|
|
LV_ASSERT_NULL(grad);
|
|
|
|
LV_ASSERT(grad->dir != LV_GRAD_DIR_NONE);
|
|
|
|
vg_lite_uint32_t colors[VLC_MAX_GRADIENT_STOPS];
|
|
vg_lite_uint32_t stops[VLC_MAX_GRADIENT_STOPS];
|
|
|
|
/* Gradient setup */
|
|
uint8_t cnt = grad->stops_count;
|
|
LV_ASSERT(cnt < VLC_MAX_GRADIENT_STOPS);
|
|
for(uint8_t i = 0; i < cnt; i++) {
|
|
stops[i] = grad->stops[i].frac;
|
|
const lv_color_t * c = &grad->stops[i].color;
|
|
lv_opa_t opa = grad->stops[i].opa;
|
|
|
|
/* lvgl color -> gradient color */
|
|
lv_color_t grad_color = lv_color_make(c->blue, c->green, c->red);
|
|
colors[i] = lv_vg_lite_color(grad_color, opa, true);
|
|
}
|
|
|
|
vg_lite_linear_gradient_t gradient;
|
|
lv_memzero(&gradient, sizeof(gradient));
|
|
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_init_grad(&gradient));
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_set_grad(&gradient, cnt, colors, stops));
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_update_grad(&gradient));
|
|
|
|
vg_lite_matrix_t * grad_matrix = vg_lite_get_grad_matrix(&gradient);
|
|
vg_lite_identity(grad_matrix);
|
|
vg_lite_translate(area->x1, area->y1, grad_matrix);
|
|
|
|
if(grad->dir == LV_GRAD_DIR_VER) {
|
|
vg_lite_scale(1, lv_area_get_height(area) / 256.0f, grad_matrix);
|
|
vg_lite_rotate(90, grad_matrix);
|
|
}
|
|
else { /*LV_GRAD_DIR_HOR*/
|
|
vg_lite_scale(lv_area_get_width(area) / 256.0f, 1, grad_matrix);
|
|
}
|
|
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_draw_grad(
|
|
buffer,
|
|
path,
|
|
fill,
|
|
(vg_lite_matrix_t *)matrix,
|
|
&gradient,
|
|
blend));
|
|
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_clear_grad(&gradient));
|
|
}
|
|
|
|
void lv_vg_lite_matrix_multiply(vg_lite_matrix_t * matrix, const vg_lite_matrix_t * mult)
|
|
{
|
|
vg_lite_matrix_t temp;
|
|
int row, column;
|
|
|
|
/* Process all rows. */
|
|
for(row = 0; row < 3; row++) {
|
|
/* Process all columns. */
|
|
for(column = 0; column < 3; column++) {
|
|
/* Compute matrix entry. */
|
|
temp.m[row][column] = (matrix->m[row][0] * mult->m[0][column])
|
|
+ (matrix->m[row][1] * mult->m[1][column])
|
|
+ (matrix->m[row][2] * mult->m[2][column]);
|
|
}
|
|
}
|
|
|
|
/* Copy temporary matrix into result. */
|
|
lv_memcpy(matrix, &temp, sizeof(temp));
|
|
}
|
|
|
|
void lv_vg_lite_matrix_flip_y(vg_lite_matrix_t * matrix)
|
|
{
|
|
matrix->m[1][1] = -matrix->m[1][1];
|
|
}
|
|
|
|
bool lv_vg_lite_matrix_inverse(vg_lite_matrix_t * result, const vg_lite_matrix_t * matrix)
|
|
{
|
|
vg_lite_float_t det00, det01, det02;
|
|
vg_lite_float_t d;
|
|
bool is_affine;
|
|
|
|
/* Test for identity matrix. */
|
|
if(matrix == NULL) {
|
|
result->m[0][0] = 1.0f;
|
|
result->m[0][1] = 0.0f;
|
|
result->m[0][2] = 0.0f;
|
|
result->m[1][0] = 0.0f;
|
|
result->m[1][1] = 1.0f;
|
|
result->m[1][2] = 0.0f;
|
|
result->m[2][0] = 0.0f;
|
|
result->m[2][1] = 0.0f;
|
|
result->m[2][2] = 1.0f;
|
|
|
|
/* Success. */
|
|
return true;
|
|
}
|
|
|
|
det00 = (matrix->m[1][1] * matrix->m[2][2]) - (matrix->m[2][1] * matrix->m[1][2]);
|
|
det01 = (matrix->m[2][0] * matrix->m[1][2]) - (matrix->m[1][0] * matrix->m[2][2]);
|
|
det02 = (matrix->m[1][0] * matrix->m[2][1]) - (matrix->m[2][0] * matrix->m[1][1]);
|
|
|
|
/* Compute determinant. */
|
|
d = (matrix->m[0][0] * det00) + (matrix->m[0][1] * det01) + (matrix->m[0][2] * det02);
|
|
|
|
/* Return 0 if there is no inverse matrix. */
|
|
if(d == 0.0f)
|
|
return false;
|
|
|
|
/* Compute reciprocal. */
|
|
d = 1.0f / d;
|
|
|
|
/* Determine if the matrix is affine. */
|
|
is_affine = (matrix->m[2][0] == 0.0f) && (matrix->m[2][1] == 0.0f) && (matrix->m[2][2] == 1.0f);
|
|
|
|
result->m[0][0] = d * det00;
|
|
result->m[0][1] = d * ((matrix->m[2][1] * matrix->m[0][2]) - (matrix->m[0][1] * matrix->m[2][2]));
|
|
result->m[0][2] = d * ((matrix->m[0][1] * matrix->m[1][2]) - (matrix->m[1][1] * matrix->m[0][2]));
|
|
result->m[1][0] = d * det01;
|
|
result->m[1][1] = d * ((matrix->m[0][0] * matrix->m[2][2]) - (matrix->m[2][0] * matrix->m[0][2]));
|
|
result->m[1][2] = d * ((matrix->m[1][0] * matrix->m[0][2]) - (matrix->m[0][0] * matrix->m[1][2]));
|
|
result->m[2][0] = is_affine ? 0.0f : d * det02;
|
|
result->m[2][1] = is_affine ? 0.0f : d * ((matrix->m[2][0] * matrix->m[0][1]) - (matrix->m[0][0] * matrix->m[2][1]));
|
|
result->m[2][2] = is_affine ? 1.0f : d * ((matrix->m[0][0] * matrix->m[1][1]) - (matrix->m[1][0] * matrix->m[0][1]));
|
|
|
|
/* Success. */
|
|
return true;
|
|
}
|
|
|
|
lv_point_precise_t lv_vg_lite_matrix_transform_point(const vg_lite_matrix_t * matrix, const lv_point_precise_t * point)
|
|
{
|
|
lv_point_precise_t p;
|
|
p.x = (lv_value_precise_t)(point->x * matrix->m[0][0] + point->y * matrix->m[0][1] + matrix->m[0][2]);
|
|
p.y = (lv_value_precise_t)(point->x * matrix->m[1][0] + point->y * matrix->m[1][1] + matrix->m[1][2]);
|
|
return p;
|
|
}
|
|
|
|
void lv_vg_lite_set_scissor_area(const lv_area_t * area)
|
|
{
|
|
vg_lite_enable_scissor();
|
|
vg_lite_set_scissor(
|
|
area->x1,
|
|
area->y1,
|
|
lv_area_get_width(area),
|
|
lv_area_get_height(area));
|
|
}
|
|
|
|
void lv_vg_lite_disable_scissor(void)
|
|
{
|
|
vg_lite_disable_scissor();
|
|
}
|
|
|
|
void lv_vg_lite_flush(lv_draw_unit_t * draw_unit)
|
|
{
|
|
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
|
|
|
u->flush_count++;
|
|
if(u->flush_count < LV_VG_LITE_FLUSH_MAX_COUNT) {
|
|
/* Do not flush too often */
|
|
return;
|
|
}
|
|
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_flush());
|
|
u->flush_count = 0;
|
|
}
|
|
|
|
void lv_vg_lite_finish(lv_draw_unit_t * draw_unit)
|
|
{
|
|
lv_draw_vg_lite_unit_t * u = (lv_draw_vg_lite_unit_t *)draw_unit;
|
|
|
|
LV_VG_LITE_CHECK_ERROR(vg_lite_finish());
|
|
|
|
/* Clear image decoder dsc reference */
|
|
lv_vg_lite_clear_image_decoder_dsc(draw_unit);
|
|
u->flush_count = 0;
|
|
}
|
|
|
|
/**********************
|
|
* STATIC FUNCTIONS
|
|
**********************/
|
|
|
|
#endif /*LV_USE_DRAW_VG_LITE*/
|