231 lines
7.6 KiB
C
231 lines
7.6 KiB
C
/**
|
|
* @file lv_draw_sw_blend.c
|
|
*
|
|
*/
|
|
|
|
/*********************
|
|
* INCLUDES
|
|
*********************/
|
|
#include "../../../misc/lv_area_private.h"
|
|
#include "lv_draw_sw_blend_private.h"
|
|
#include "../../lv_draw_private.h"
|
|
#include "../lv_draw_sw.h"
|
|
#if LV_DRAW_SW_SUPPORT_L8
|
|
#include "lv_draw_sw_blend_to_l8.h"
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_AL88
|
|
#include "lv_draw_sw_blend_to_al88.h"
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_RGB565
|
|
#include "lv_draw_sw_blend_to_rgb565.h"
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_ARGB8888
|
|
#include "lv_draw_sw_blend_to_argb8888.h"
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_RGB888 || LV_DRAW_SW_SUPPORT_XRGB8888
|
|
#include "lv_draw_sw_blend_to_rgb888.h"
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_I1
|
|
#include "lv_draw_sw_blend_to_i1.h"
|
|
#endif
|
|
#if LV_USE_DRAW_SW
|
|
|
|
/*********************
|
|
* DEFINES
|
|
*********************/
|
|
|
|
/**********************
|
|
* TYPEDEFS
|
|
**********************/
|
|
|
|
/**********************
|
|
* STATIC PROTOTYPES
|
|
**********************/
|
|
/**********************
|
|
* STATIC VARIABLES
|
|
**********************/
|
|
|
|
/**********************
|
|
* MACROS
|
|
**********************/
|
|
|
|
/**********************
|
|
* GLOBAL FUNCTIONS
|
|
**********************/
|
|
|
|
void lv_draw_sw_blend(lv_draw_task_t * t, const lv_draw_sw_blend_dsc_t * blend_dsc)
|
|
{
|
|
/*Do not draw transparent things*/
|
|
if(blend_dsc->opa <= LV_OPA_MIN) return;
|
|
if(blend_dsc->mask_buf && blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_TRANSP) return;
|
|
|
|
lv_area_t blend_area;
|
|
if(!lv_area_intersect(&blend_area, blend_dsc->blend_area, &t->clip_area)) return;
|
|
|
|
LV_PROFILER_DRAW_BEGIN;
|
|
lv_layer_t * layer = t->target_layer;
|
|
uint32_t layer_stride_byte = layer->draw_buf->header.stride;
|
|
|
|
if(blend_dsc->src_buf == NULL) {
|
|
lv_draw_sw_blend_fill_dsc_t fill_dsc;
|
|
fill_dsc.dest_w = lv_area_get_width(&blend_area);
|
|
fill_dsc.dest_h = lv_area_get_height(&blend_area);
|
|
fill_dsc.dest_stride = layer_stride_byte;
|
|
fill_dsc.opa = blend_dsc->opa;
|
|
fill_dsc.color = blend_dsc->color;
|
|
fill_dsc.mask_stride = 0;
|
|
|
|
if(blend_dsc->mask_buf == NULL) fill_dsc.mask_buf = NULL;
|
|
else if(blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) fill_dsc.mask_buf = NULL;
|
|
else fill_dsc.mask_buf = blend_dsc->mask_buf;
|
|
|
|
|
|
fill_dsc.relative_area = blend_area;
|
|
lv_area_move(&fill_dsc.relative_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
|
fill_dsc.dest_buf = lv_draw_layer_go_to_xy(layer, blend_area.x1 - layer->buf_area.x1,
|
|
blend_area.y1 - layer->buf_area.y1);
|
|
if(fill_dsc.mask_buf) {
|
|
fill_dsc.mask_stride = blend_dsc->mask_stride == 0 ? lv_area_get_width(blend_dsc->mask_area) : blend_dsc->mask_stride;
|
|
fill_dsc.mask_buf += fill_dsc.mask_stride * (blend_area.y1 - blend_dsc->mask_area->y1) +
|
|
(blend_area.x1 - blend_dsc->mask_area->x1);
|
|
}
|
|
|
|
switch(layer->color_format) {
|
|
#if LV_DRAW_SW_SUPPORT_RGB565
|
|
case LV_COLOR_FORMAT_RGB565:
|
|
lv_draw_sw_blend_color_to_rgb565(&fill_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_ARGB8888
|
|
case LV_COLOR_FORMAT_ARGB8888:
|
|
lv_draw_sw_blend_color_to_argb8888(&fill_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_RGB888
|
|
case LV_COLOR_FORMAT_RGB888:
|
|
lv_draw_sw_blend_color_to_rgb888(&fill_dsc, 3);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_XRGB8888
|
|
case LV_COLOR_FORMAT_XRGB8888:
|
|
lv_draw_sw_blend_color_to_rgb888(&fill_dsc, 4);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_L8
|
|
case LV_COLOR_FORMAT_L8:
|
|
lv_draw_sw_blend_color_to_l8(&fill_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_AL88
|
|
case LV_COLOR_FORMAT_AL88:
|
|
lv_draw_sw_blend_color_to_al88(&fill_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_I1
|
|
case LV_COLOR_FORMAT_I1:
|
|
lv_draw_sw_blend_color_to_i1(&fill_dsc);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
if(!lv_area_intersect(&blend_area, &blend_area, blend_dsc->src_area)) {
|
|
LV_PROFILER_DRAW_END;
|
|
return;
|
|
}
|
|
|
|
if(blend_dsc->mask_area && !lv_area_intersect(&blend_area, &blend_area, blend_dsc->mask_area)) {
|
|
LV_PROFILER_DRAW_END;
|
|
return;
|
|
}
|
|
|
|
lv_draw_sw_blend_image_dsc_t image_dsc;
|
|
image_dsc.dest_w = lv_area_get_width(&blend_area);
|
|
image_dsc.dest_h = lv_area_get_height(&blend_area);
|
|
image_dsc.dest_stride = layer_stride_byte;
|
|
|
|
image_dsc.opa = blend_dsc->opa;
|
|
image_dsc.blend_mode = blend_dsc->blend_mode;
|
|
image_dsc.src_stride = blend_dsc->src_stride;
|
|
image_dsc.src_color_format = blend_dsc->src_color_format;
|
|
|
|
const uint8_t * src_buf = blend_dsc->src_buf;
|
|
uint32_t src_px_size = lv_color_format_get_bpp(blend_dsc->src_color_format);
|
|
src_buf += image_dsc.src_stride * (blend_area.y1 - blend_dsc->src_area->y1);
|
|
src_buf += ((blend_area.x1 - blend_dsc->src_area->x1) * src_px_size) >> 3;
|
|
image_dsc.src_buf = src_buf;
|
|
image_dsc.mask_stride = 0;
|
|
|
|
if(blend_dsc->mask_buf == NULL) image_dsc.mask_buf = NULL;
|
|
else if(blend_dsc->mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) image_dsc.mask_buf = NULL;
|
|
else image_dsc.mask_buf = blend_dsc->mask_buf;
|
|
|
|
if(image_dsc.mask_buf) {
|
|
LV_ASSERT_NULL(blend_dsc->mask_area);
|
|
image_dsc.mask_buf = blend_dsc->mask_buf;
|
|
image_dsc.mask_stride = blend_dsc->mask_stride ? blend_dsc->mask_stride : lv_area_get_width(blend_dsc->mask_area);
|
|
image_dsc.mask_buf += image_dsc.mask_stride * (blend_area.y1 - blend_dsc->mask_area->y1) +
|
|
(blend_area.x1 - blend_dsc->mask_area->x1);
|
|
}
|
|
|
|
image_dsc.relative_area = blend_area;
|
|
lv_area_move(&image_dsc.relative_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
|
|
|
image_dsc.src_area = *blend_dsc->src_area;
|
|
lv_area_move(&image_dsc.src_area, -layer->buf_area.x1, -layer->buf_area.y1);
|
|
|
|
image_dsc.dest_buf = lv_draw_layer_go_to_xy(layer, blend_area.x1 - layer->buf_area.x1,
|
|
blend_area.y1 - layer->buf_area.y1);
|
|
|
|
switch(layer->color_format) {
|
|
#if LV_DRAW_SW_SUPPORT_RGB565
|
|
case LV_COLOR_FORMAT_RGB565:
|
|
case LV_COLOR_FORMAT_RGB565A8:
|
|
lv_draw_sw_blend_image_to_rgb565(&image_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_ARGB8888
|
|
case LV_COLOR_FORMAT_ARGB8888:
|
|
lv_draw_sw_blend_image_to_argb8888(&image_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_RGB888
|
|
case LV_COLOR_FORMAT_RGB888:
|
|
lv_draw_sw_blend_image_to_rgb888(&image_dsc, 3);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_XRGB8888
|
|
case LV_COLOR_FORMAT_XRGB8888:
|
|
lv_draw_sw_blend_image_to_rgb888(&image_dsc, 4);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_L8
|
|
case LV_COLOR_FORMAT_L8:
|
|
lv_draw_sw_blend_image_to_l8(&image_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_AL88
|
|
case LV_COLOR_FORMAT_AL88:
|
|
lv_draw_sw_blend_image_to_al88(&image_dsc);
|
|
break;
|
|
#endif
|
|
#if LV_DRAW_SW_SUPPORT_I1
|
|
case LV_COLOR_FORMAT_I1:
|
|
lv_draw_sw_blend_image_to_i1(&image_dsc);
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
LV_PROFILER_DRAW_END;
|
|
}
|
|
|
|
/**********************
|
|
* STATIC FUNCTIONS
|
|
**********************/
|
|
|
|
#endif
|