修复: FB+视频共存 - compress(TRUE) + qua_gl_fill/transform
This commit is contained in:
parent
7466a2abd2
commit
cc425d5bbe
@ -46,6 +46,7 @@ extern "C"
|
||||
|
||||
void *fbdev_req_mem(int size);
|
||||
void *fbdev2_req_mem(int size);
|
||||
int fbdev_get_actual_height(void);
|
||||
void fbdev_set_hole(int x, int y, int width, int height);
|
||||
void fbdev2_set_hole(int x, int y, int width, int height);
|
||||
//
|
||||
|
||||
@ -23,9 +23,7 @@
|
||||
#include "system/qua_mm_system.h"
|
||||
#include "filter/qua_mm_filter.h"
|
||||
#include "quagl/qua_gl.h"
|
||||
// #include "qua_los_2d.h" //函数不全
|
||||
|
||||
extern qua_mm_tde_device_t *g_tde_device_for_hole;
|
||||
extern qua_mm_system_ops_t *g_sys_ops;
|
||||
extern int g_screen_rotation;
|
||||
|
||||
@ -34,8 +32,6 @@ static qua_tde2_rect_t hole_rect, statusbar_rect;
|
||||
static struct fb_var_screeninfo vinfo;
|
||||
static struct fb_fix_screeninfo finfo;
|
||||
static char *fbp = 0;
|
||||
static uint32_t lvglAddr = 0;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
@ -45,7 +41,6 @@ extern void fbdev_get_info(struct fb_var_screeninfo *pOutScreenInfo, struct fb_f
|
||||
extern int fbdev_pan_disp(void);
|
||||
static void fbdev_draw_hole();
|
||||
|
||||
//
|
||||
void fbdev_init(void)
|
||||
{
|
||||
extern void fbdev_init_xd(void);
|
||||
@ -54,34 +49,16 @@ void fbdev_init(void)
|
||||
fbdev_get_info(&vinfo, &finfo);
|
||||
fb_surface.data = fbp;
|
||||
fb_surface.phy_addr = finfo.smem_start;
|
||||
fb_surface.width = vinfo.xres;
|
||||
fb_surface.height = vinfo.yres;
|
||||
fb_surface.stride = vinfo.xres;
|
||||
fb_surface.width = vinfo.xres_virtual;
|
||||
fb_surface.height = vinfo.yres_virtual;
|
||||
fb_surface.stride = vinfo.xres_virtual;
|
||||
fb_surface.format = QUA_PIXEL_FMT_RGB_8888;
|
||||
fb_surface.crop_x = 0;
|
||||
fb_surface.crop_y = 0;
|
||||
fb_surface.crop_w = vinfo.xres;
|
||||
fb_surface.crop_h = vinfo.yres;
|
||||
printf("设备信息: vinfo.xres:%d,vinfo.yres:%d \n", vinfo.xres, vinfo.yres);
|
||||
if (g_screen_rotation == 1)
|
||||
{
|
||||
#ifdef CONFIG_XOS_FB_ROTATION
|
||||
lvgl_surface.phy_addr = finfo.smem_start + finfo.smem_len / 2;
|
||||
lvgl_surface.data = fbp + finfo.smem_len / 2;
|
||||
lvgl_surface.width = vinfo.yres;
|
||||
lvgl_surface.height = vinfo.xres;
|
||||
lvgl_surface.stride = vinfo.yres;
|
||||
lvgl_surface.format = QUA_PIXEL_FMT_RGB_8888;
|
||||
lvgl_surface.crop_x = 0;
|
||||
lvgl_surface.crop_y = 0;
|
||||
lvgl_surface.crop_w = vinfo.yres;
|
||||
lvgl_surface.crop_h = vinfo.xres;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lvgl_surface = fb_surface;
|
||||
}
|
||||
printf("fbdev_init: %dx%d smem_start=0x%lx\n", vinfo.xres, vinfo.yres, (unsigned long)finfo.smem_start);
|
||||
lvgl_surface = fb_surface;
|
||||
}
|
||||
|
||||
void fbdev_exit(void)
|
||||
@ -94,19 +71,8 @@ void fbdev_exit(void)
|
||||
|
||||
void *fbdev_req_mem(int size)
|
||||
{
|
||||
// qm_effect_init_scr_info(lvgl_surface.width, lvgl_surface.height, lvgl_surface.data, lvgl_surface.phy_addr);
|
||||
// return lvgl_surface.data;
|
||||
|
||||
void *buf = NULL;
|
||||
int ret = posix_memalign(&buf, 64, size); // 64 字节对齐
|
||||
if (ret != 0 || buf == NULL)
|
||||
{
|
||||
LV_LOG_ERROR("fbdev_req_mem malloc failed: ret=%d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
memset(buf, 0, size);
|
||||
|
||||
return buf;
|
||||
(void)size;
|
||||
return lvgl_surface.data;
|
||||
}
|
||||
|
||||
int fbdev_get_actual_height(void)
|
||||
@ -136,16 +102,9 @@ void fbdev_set_statusbar(int x, int y, int width, int height)
|
||||
|
||||
static void fbdev_draw_hole()
|
||||
{
|
||||
QUA_S32 ret;
|
||||
QUA_TDE_HANDLE handle;
|
||||
qua_tde2_surface_t hole_surface = {};
|
||||
|
||||
if (hole_rect.width == 0 || hole_rect.height == 0)
|
||||
return;
|
||||
|
||||
if (g_tde_device_for_hole == NULL)
|
||||
return;
|
||||
|
||||
qua_tde2_rect_t tmp_rect = hole_rect;
|
||||
QUA_S32 new_y = statusbar_rect.y_pos + statusbar_rect.height;
|
||||
if (new_y > tmp_rect.y_pos)
|
||||
@ -154,36 +113,15 @@ static void fbdev_draw_hole()
|
||||
tmp_rect.y_pos = new_y;
|
||||
}
|
||||
|
||||
hole_surface.phy_addr = lvgl_surface.phy_addr;
|
||||
hole_surface.color_fmt = QUA_TDE2_COLOR_FMT_ARGB8888;
|
||||
hole_surface.width = lvgl_surface.width;
|
||||
hole_surface.height = lvgl_surface.height;
|
||||
hole_surface.stride = lvgl_surface.width * 4;
|
||||
hole_surface.alpha_max255 = QUA_TRUE;
|
||||
hole_surface.fbc_compress = QUA_FALSE;
|
||||
|
||||
if (g_tde_device_for_hole->qua_tde2_begin_job == NULL ||
|
||||
g_tde_device_for_hole->qua_tde2_quick_fill == NULL ||
|
||||
g_tde_device_for_hole->qua_tde2_end_job == NULL)
|
||||
return;
|
||||
|
||||
handle = g_tde_device_for_hole->qua_tde2_begin_job();
|
||||
if (handle == QUA_FAILURE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ret = g_tde_device_for_hole->qua_tde2_quick_fill(handle, &hole_surface, &tmp_rect, 0x000000FF); // fill transparent blue color
|
||||
if (ret != QUA_SUCCESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ret = g_tde_device_for_hole->qua_tde2_end_job(handle, QUA_FALSE, QUA_TRUE, 5000);
|
||||
if (ret != QUA_SUCCESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fb_surface.crop_x = tmp_rect.x_pos;
|
||||
fb_surface.crop_y = tmp_rect.y_pos;
|
||||
fb_surface.crop_w = tmp_rect.width;
|
||||
fb_surface.crop_h = tmp_rect.height;
|
||||
qua_gl_fill(&fb_surface, 0);
|
||||
fb_surface.crop_x = 0;
|
||||
fb_surface.crop_y = 0;
|
||||
fb_surface.crop_w = fb_surface.width;
|
||||
fb_surface.crop_h = fb_surface.height;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,8 +139,7 @@ void fbdev_flush(lv_display_t *drv, const lv_area_t *area, uint8_t *color_p)
|
||||
return;
|
||||
}
|
||||
|
||||
if (fbp == NULL ||
|
||||
area->x2 < 0 ||
|
||||
if (area->x2 < 0 ||
|
||||
area->y2 < 0 ||
|
||||
area->x1 > (int32_t)vinfo.xres - 1 ||
|
||||
area->y1 > (int32_t)vinfo.yres - 1)
|
||||
@ -211,166 +148,49 @@ void fbdev_flush(lv_display_t *drv, const lv_area_t *area, uint8_t *color_p)
|
||||
return;
|
||||
}
|
||||
|
||||
/* use qua_gl_transform to copy LVGL buffer to FB (compress mode compatible) */
|
||||
lv_area_t buf_area = drv->layer_head->buf_area;
|
||||
int32_t act_x1 = LV_MAX(area->x1, 0);
|
||||
int32_t act_y1 = LV_MAX(area->y1, 0);
|
||||
int32_t act_x2 = LV_MIN(area->x2, (int32_t)vinfo.xres - 1);
|
||||
int32_t act_y2 = LV_MIN(area->y2, (int32_t)vinfo.yres - 1);
|
||||
int32_t act_x2 = LV_MIN(area->x2, (int32_t)lvgl_surface.width - 1);
|
||||
int32_t act_y2 = LV_MIN(area->y2, (int32_t)lvgl_surface.height - 1);
|
||||
|
||||
int32_t w = act_x2 - act_x1 + 1;
|
||||
int32_t h = act_y2 - act_y1 + 1;
|
||||
|
||||
// 根据旋转角度处理像素映射
|
||||
lv_display_rotation_t rotation = lv_display_get_rotation(drv);
|
||||
qua_gl_surface_t src_surface = {};
|
||||
qua_gl_transform_t trans = {};
|
||||
|
||||
if (rotation == LV_DISPLAY_ROTATION_180)
|
||||
{
|
||||
// 180度旋转:从右下角开始绘制
|
||||
for (int32_t y = 0; y < h; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < w; x++)
|
||||
{
|
||||
// 计算源像素位置 (来自LVGL缓冲区)
|
||||
uint32_t src_idx = (y * w + x) * 4;
|
||||
src_surface.phy_addr = lvgl_surface.phy_addr;
|
||||
src_surface.format = QUA_PIXEL_FMT_RGB_8888;
|
||||
src_surface.width = buf_area.x2 - buf_area.x1 + 1;
|
||||
src_surface.height = buf_area.y2 - buf_area.y1 + 1;
|
||||
src_surface.stride = src_surface.width;
|
||||
src_surface.crop_x = act_x1 - buf_area.x1;
|
||||
src_surface.crop_y = act_y1 - buf_area.y1;
|
||||
src_surface.crop_w = w;
|
||||
src_surface.crop_h = h;
|
||||
|
||||
// 计算目标像素位置 (在帧缓冲区中)
|
||||
int32_t dst_x = vinfo.xres - 1 - (act_x1 + x);
|
||||
int32_t dst_y = vinfo.yres - 1 - (act_y1 + y);
|
||||
fb_surface.crop_x = act_x1;
|
||||
fb_surface.crop_y = act_y1;
|
||||
fb_surface.crop_w = w;
|
||||
fb_surface.crop_h = h;
|
||||
|
||||
if (dst_x >= 0 && dst_x < (int32_t)vinfo.xres &&
|
||||
dst_y >= 0 && dst_y < (int32_t)vinfo.yres)
|
||||
{
|
||||
trans.conversion = 1;
|
||||
QUA_BOOL ret = qua_gl_transform(&trans, &src_surface, &fb_surface);
|
||||
if (ret == QUA_FALSE)
|
||||
printf("%s, transform failed area=[%d,%d,%d,%d] buf=[%d,%d,%d,%d]\n", __func__,
|
||||
area->x1, area->y1, area->x2, area->y2,
|
||||
buf_area.x1, buf_area.y1, buf_area.x2, buf_area.y2);
|
||||
|
||||
uint8_t *dst_pixel = (uint8_t *)fbp +
|
||||
(dst_y + vinfo.yoffset) * finfo.line_length +
|
||||
(dst_x + vinfo.xoffset) * 4;
|
||||
fb_surface.crop_x = 0;
|
||||
fb_surface.crop_y = 0;
|
||||
fb_surface.crop_w = fb_surface.width;
|
||||
fb_surface.crop_h = fb_surface.height;
|
||||
|
||||
// 复制像素 (RGBA)
|
||||
dst_pixel[0] = color_p[src_idx + 0]; // R
|
||||
dst_pixel[1] = color_p[src_idx + 1]; // G
|
||||
dst_pixel[2] = color_p[src_idx + 2]; // B
|
||||
dst_pixel[3] = color_p[src_idx + 3]; // A
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rotation == LV_DISPLAY_ROTATION_90)
|
||||
{
|
||||
// 90度旋转:逆时针旋转90度 (x,y) -> (y, width-1-x)
|
||||
for (int32_t y = 0; y < h; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < w; x++)
|
||||
{
|
||||
uint32_t src_idx = (y * w + x) * 4;
|
||||
|
||||
// 计算旋转后的坐标
|
||||
int32_t dst_x = act_y1 + y;
|
||||
int32_t dst_y = vinfo.yres - 1 - (act_x1 + x);
|
||||
|
||||
if (dst_x >= 0 && dst_x < (int32_t)vinfo.xres &&
|
||||
dst_y >= 0 && dst_y < (int32_t)vinfo.yres)
|
||||
{
|
||||
|
||||
uint8_t *dst_pixel = (uint8_t *)fbp +
|
||||
(dst_y + vinfo.yoffset) * finfo.line_length +
|
||||
(dst_x + vinfo.xoffset) * 4;
|
||||
|
||||
dst_pixel[0] = color_p[src_idx + 0]; // R
|
||||
dst_pixel[1] = color_p[src_idx + 1]; // G
|
||||
dst_pixel[2] = color_p[src_idx + 2]; // B
|
||||
dst_pixel[3] = color_p[src_idx + 3]; // A
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rotation == LV_DISPLAY_ROTATION_270)
|
||||
{
|
||||
// 270度旋转:逆时针旋转270度 (x,y) -> (height-1-y, x)
|
||||
for (int32_t y = 0; y < h; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < w; x++)
|
||||
{
|
||||
uint32_t src_idx = (y * w + x) * 4;
|
||||
|
||||
// 计算旋转后的坐标
|
||||
int32_t dst_x = vinfo.xres - 1 - (act_y1 + y);
|
||||
int32_t dst_y = act_x1 + x;
|
||||
|
||||
if (dst_x >= 0 && dst_x < (int32_t)vinfo.xres &&
|
||||
dst_y >= 0 && dst_y < (int32_t)vinfo.yres)
|
||||
{
|
||||
|
||||
uint8_t *dst_pixel = (uint8_t *)fbp +
|
||||
(dst_y + vinfo.yoffset) * finfo.line_length +
|
||||
(dst_x + vinfo.xoffset) * 4;
|
||||
|
||||
dst_pixel[0] = color_p[src_idx + 0]; // R
|
||||
dst_pixel[1] = color_p[src_idx + 1]; // G
|
||||
dst_pixel[2] = color_p[src_idx + 2]; // B
|
||||
dst_pixel[3] = color_p[src_idx + 3]; // A
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 无旋转:正常处理
|
||||
// ✅ 性能优化:如果是小区域刷新,使用单行拷贝;如果是大区域或全屏,使用更高效的内存拷贝
|
||||
|
||||
// 检查计算是否会超出帧缓冲区范围
|
||||
uint32_t line_offset = (act_y1 + vinfo.yoffset) * finfo.line_length + (act_x1 + vinfo.xoffset) * 4;
|
||||
if (line_offset >= finfo.smem_len)
|
||||
{
|
||||
lv_display_flush_ready(drv);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *fb_line = ((uint8_t *)fbp) + line_offset;
|
||||
|
||||
// 计算刷新区域大小,判断是否为小区域刷新
|
||||
uint32_t refresh_area = w * h;
|
||||
uint32_t screen_area = vinfo.xres * vinfo.yres;
|
||||
|
||||
if (refresh_area < screen_area / 4)
|
||||
{
|
||||
// 小区域刷新,使用单行拷贝
|
||||
for (int32_t y = 0; y < h; y++)
|
||||
{
|
||||
// 检查当前行是否会超出缓冲区
|
||||
if ((uint8_t *)fb_line - (uint8_t *)fbp + w * 4 > finfo.smem_len)
|
||||
break;
|
||||
|
||||
memcpy(fb_line, color_p, w * 4); // copy one line
|
||||
fb_line += finfo.line_length; // go to next line in framebuffer
|
||||
color_p += w * 4; // go to next line in lvgl buffer
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 大区域刷新,使用更高效的内存拷贝
|
||||
uint32_t fb_pitch = finfo.line_length / 4; // 每一行的像素数
|
||||
uint32_t lvgl_pitch = w; // LVGL缓冲区每一行的像素数
|
||||
|
||||
uint32_t *fb_ptr = (uint32_t *)fb_line;
|
||||
uint32_t *lvgl_ptr = (uint32_t *)color_p;
|
||||
|
||||
for (int32_t y = 0; y < h; y++)
|
||||
{
|
||||
// 检查当前行是否会超出缓冲区
|
||||
if ((uint8_t *)fb_ptr - (uint8_t *)fbp + w * 4 > finfo.smem_len)
|
||||
break;
|
||||
|
||||
memcpy(fb_ptr, lvgl_ptr, w * 4); // copy one line
|
||||
fb_ptr += fb_pitch; // go to next line in framebuffer
|
||||
lvgl_ptr += lvgl_pitch; // go to next line in lvgl buffer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printf("2222刷新屏幕挖孔区域 \n");
|
||||
if (lv_display_flush_is_last(drv))
|
||||
{
|
||||
// printf("刷新屏幕挖孔区域 \n");
|
||||
fbdev_draw_hole(); // 播放视频打洞使用
|
||||
fbdev_draw_hole();
|
||||
fbdev_pan_disp();
|
||||
}
|
||||
lv_display_flush_ready(drv);
|
||||
|
||||
@ -93,7 +93,6 @@ static QUA_S32 init_fyfb()
|
||||
qua_fb_bitfield_t stB = {0, 8, 0};
|
||||
qua_fb_bitfield_t stA = {24, 8, 0};
|
||||
fb_device->show(fb_device, QUA_FALSE);
|
||||
fb_device->compress(fb_device, QUA_FALSE);
|
||||
|
||||
qua_point_t position = {0, 0};
|
||||
if (fb_device->put_origin != NULL)
|
||||
@ -143,9 +142,9 @@ static QUA_S32 init_fyfb()
|
||||
|
||||
qua_fb_alpha_t alpha;
|
||||
alpha.alpha_enable = QUA_TRUE;
|
||||
alpha.alpha_channel = QUA_FALSE;
|
||||
alpha.alpha_channel = QUA_TRUE;
|
||||
alpha.alpha0 = 0;
|
||||
alpha.alpha1 = 0;
|
||||
alpha.alpha1 = 128;
|
||||
alpha.global_alpha = 128;
|
||||
alpha.reserved = 0;
|
||||
if (fb_device->put_alpha(fb_device, &alpha) != QUA_SUCCESS)
|
||||
@ -161,6 +160,7 @@ static QUA_S32 init_fyfb()
|
||||
goto map_failed;
|
||||
}
|
||||
memset(pShowScreen, 0x00, finfo.smem_len);
|
||||
fb_device->compress(fb_device, QUA_TRUE);
|
||||
return QUA_SUCCESS;
|
||||
map_failed:
|
||||
fb_device->unmap(fb_device, pShowScreen, finfo.smem_len);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user