arch(color): define generic color formats and add draw_ctx->buffer_convert

This commit is contained in:
Gabor Kiss-Vamosi 2022-07-21 05:17:01 +02:00
parent a16e6a83f5
commit 453ac21254
14 changed files with 192 additions and 284 deletions

View File

@ -319,6 +319,11 @@ void _lv_disp_refr_timer(lv_timer_t * tmr)
return;
}
if(disp_refr->driver->direct_mode && disp_refr->driver->draw_ctx->color_format > _LV_COLOR_FORMAT_NATIVE_END) {
LV_LOG_WARN("In direct_mode the color_format must be LV_COLOR_FORMAT_NATIVE_...");
return;
}
lv_refr_join_area();
refr_invalid_areas();
@ -1241,6 +1246,8 @@ static void call_flush_cb(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_
.y2 = area->y2 + drv->offset_y
};
if(drv->draw_ctx->buffer_convert) drv->draw_ctx->buffer_convert(drv->draw_ctx);
drv->flush_cb(drv, &offset_area, color_p);
}

View File

@ -52,7 +52,7 @@ typedef struct _lv_draw_layer_ctx_t {
const lv_area_t * clip_area;
lv_area_t * buf_area;
void * buf;
bool screen_transp;
bool render_with_alpha;
} original;
} lv_draw_layer_ctx_t;
@ -72,6 +72,17 @@ typedef struct _lv_draw_ctx_t {
*/
const lv_area_t * clip_area;
/**
* If true and Alpha byte will be appended to the colors.
* It might make rendering slower.
*/
bool render_with_alpha;
/**
* The rendered image in draw_ctx->buf will be converted to this format
* using draw_ctx->buffer_convert.
*/
lv_color_format_t color_format;
void (*draw_rect)(struct _lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
@ -141,6 +152,12 @@ typedef struct _lv_draw_ctx_t {
const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
/**
* Convert the content of `draw_ctx->buf` to `draw_ctx->output_color_format`
* @param draw_ctx
*/
void (*buffer_convert)(struct _lv_draw_ctx_t * draw_ctx);
/**
* Initialize a new layer context.
* The original buffer and area data are already saved from `draw_ctx` to `layer_ctx`

View File

@ -48,11 +48,10 @@ lv_draw_layer_ctx_t * lv_draw_layer_create(lv_draw_ctx_t * draw_ctx, const lv_ar
lv_memzero(layer_ctx, draw_ctx->layer_instance_size);
lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
layer_ctx->original.buf = draw_ctx->buf;
layer_ctx->original.buf_area = draw_ctx->buf_area;
layer_ctx->original.clip_area = draw_ctx->clip_area;
layer_ctx->original.screen_transp = disp_refr->driver->screen_transp;
layer_ctx->original.render_with_alpha = draw_ctx->render_with_alpha;
layer_ctx->area_full = *layer_area;
lv_draw_layer_ctx_t * init_layer_ctx = draw_ctx->layer_init(draw_ctx, layer_ctx, flags);
@ -81,8 +80,7 @@ void lv_draw_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer
draw_ctx->buf = layer_ctx->original.buf;
draw_ctx->buf_area = layer_ctx->original.buf_area;
draw_ctx->clip_area = layer_ctx->original.clip_area;
lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
disp_refr->driver->screen_transp = layer_ctx->original.screen_transp;
draw_ctx->render_with_alpha = layer_ctx->original.render_with_alpha;
if(draw_ctx->layer_destroy) draw_ctx->layer_destroy(draw_ctx, layer_ctx);
lv_free(layer_ctx);

View File

@ -122,13 +122,10 @@ void lv_draw_nxp_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
* the target pixel format is ARGB8565 which is not supported by the GPU.
* In this case, the NXP callbacks should fallback to SW rendering.
*/
static inline bool need_argb8565_support()
static inline bool need_argb8565_support(lv_draw_ctx_t * draw_ctx)
{
#if LV_COLOR_DEPTH != 32
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
if(disp->driver->screen_transp == 1)
return true;
if(draw_ctx->render_with_alpha) return true;
#endif
return false;

View File

@ -56,6 +56,7 @@ void lv_draw_sw_init_ctx(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
draw_sw_ctx->base_draw.draw_transform = lv_draw_sw_transform;
draw_sw_ctx->base_draw.wait_for_finish = lv_draw_sw_wait_for_finish;
draw_sw_ctx->base_draw.buffer_copy = lv_draw_sw_buffer_copy;
draw_sw_ctx->base_draw.buffer_convert = lv_draw_sw_buffer_convert;
draw_sw_ctx->base_draw.layer_init = lv_draw_sw_layer_create;
draw_sw_ctx->base_draw.layer_adjust = lv_draw_sw_layer_adjust;
draw_sw_ctx->base_draw.layer_blend = lv_draw_sw_layer_blend;
@ -103,6 +104,73 @@ void lv_draw_sw_buffer_copy(lv_draw_ctx_t * draw_ctx,
}
}
void lv_draw_sw_buffer_convert(lv_draw_ctx_t * draw_ctx)
{
/*Keep the rendered image as it is*/
if(draw_ctx->color_format == LV_COLOR_FORMAT_NATIVE ||
draw_ctx->color_format >= LV_COLOR_FORMAT_CUSTOM_START) {
return;
}
/*Make both the clip and buf area relative to the buf area*/
lv_area_t clip_area = *draw_ctx->clip_area;
lv_area_t buf_area = *draw_ctx->buf_area;
lv_area_move(&clip_area, -buf_area.x1, -buf_area.y1);
lv_area_move(&buf_area, -buf_area.x1, -buf_area.y1);
int32_t a_h_px = lv_area_get_height(&clip_area);
int32_t buf_w_px = lv_area_get_width(&buf_area);
#if LV_COLOR_DEPTH == 16
if(draw_ctx->color_format == LV_COLOR_FORMAT_RGB565) return;
else if(draw_ctx->color_format == LV_COLOR_FORMAT_NATIVE_REVERSE) {
int32_t buf_w_byte = buf_w_px * 2;
int32_t a_w_byte = lv_area_get_width(&clip_area) * 2;
/*Go to the first byte on buf*/
uint8_t * buf8 = draw_ctx->buf;
buf8 += clip_area.y1 * buf_w_byte + clip_area.x1 * 2;
/*Swap all byte pairs*/
int32_t y;
for(y = 0; y < a_h_px; y++) {
int32_t x;
for(x = 0; x < a_w_byte - 1; x += 2) {
uint8_t tmp = buf8[x];
buf8[x] = buf8[x + 1];
buf8[x + 1] = tmp;
}
buf8 += buf_w_byte;
}
return;
}
else if(draw_ctx->color_format == LV_COLOR_FORMAT_RGBX8888) {
/*Go to the last byte on buf*/
lv_color_t * buf_in = draw_ctx->buf;
buf_in += clip_area.y2 * buf_w_px + clip_area.x1;
uint32_t * buf_out = draw_ctx->buf;
buf_out += clip_area.y2 * buf_w_px + clip_area.x1;
int32_t a_w_px = lv_area_get_width(&clip_area);
int32_t y;
for(y = 0; y < a_h_px; y++) {
int32_t x;
for(x = a_w_px - 1; x >= 0; x--) {
buf_out[x] = lv_color_to32(buf_in[x]);
}
buf_in -= buf_w_px;
buf_out -= buf_w_px;
}
return;
}
#endif
LV_LOG_WARN("Couldn't convert the image to the desired format");
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -40,9 +40,7 @@ typedef struct {
typedef struct {
lv_draw_layer_ctx_t base_draw;
uint32_t buf_size_bytes: 31;
uint32_t has_alpha : 1;
uint32_t buf_size_bytes;
} lv_draw_sw_layer_ctx_t;
/**********************
@ -76,6 +74,8 @@ void lv_draw_sw_buffer_copy(lv_draw_ctx_t * draw_ctx,
void * dest_buf, lv_coord_t dest_stride, const lv_area_t * dest_area,
void * src_buf, lv_coord_t src_stride, const lv_area_t * src_area);
void lv_draw_sw_buffer_convert(lv_draw_ctx_t * draw_ctx);
void lv_draw_sw_transform(lv_draw_ctx_t * draw_ctx, const lv_area_t * dest_area, const void * src_buf,
lv_coord_t src_w, lv_coord_t src_h, lv_coord_t src_stride,
const lv_draw_img_dsc_t * draw_dsc, lv_img_cf_t cf, lv_color_t * cbuf, lv_opa_t * abuf);

View File

@ -25,9 +25,6 @@
* STATIC PROTOTYPES
**********************/
static void fill_set_px(lv_color_t * dest_buf, const lv_area_t * blend_area, lv_coord_t dest_stride,
lv_color_t color, lv_opa_t opa, const lv_opa_t * mask, lv_coord_t mask_stide);
LV_ATTRIBUTE_FAST_MEM static void 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);
@ -38,9 +35,6 @@ LV_ATTRIBUTE_FAST_MEM static void fill_argb(lv_color_t * dest_buf, const lv_area
static void fill_blended(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_blend_mode_t blend_mode);
static void map_set_px(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);
LV_ATTRIBUTE_FAST_MEM static void map_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);
@ -107,19 +101,16 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_basic(lv_draw_ctx_t * draw_ctx, cons
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();
lv_color_t * dest_buf = draw_ctx->buf;
if(disp->driver->set_px_cb == NULL) {
if(disp->driver->screen_transp == 0) {
dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1);
}
else {
/*With LV_COLOR_DEPTH 16 it means ARGB8565 (3 bytes format)*/
uint8_t * dest_buf8 = (uint8_t *) dest_buf;
dest_buf8 += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) * LV_IMG_PX_SIZE_ALPHA_BYTE;
dest_buf8 += (blend_area.x1 - draw_ctx->buf_area->x1) * LV_IMG_PX_SIZE_ALPHA_BYTE;
dest_buf = (lv_color_t *)dest_buf8;
}
if(draw_ctx->render_with_alpha == 0) {
dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1);
}
else {
/*With LV_COLOR_DEPTH 16 it means ARGB8565 (3 bytes format)*/
uint8_t * dest_buf8 = (uint8_t *) dest_buf;
dest_buf8 += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) * LV_IMG_PX_SIZE_ALPHA_BYTE;
dest_buf8 += (blend_area.x1 - draw_ctx->buf_area->x1) * LV_IMG_PX_SIZE_ALPHA_BYTE;
dest_buf = (lv_color_t *)dest_buf8;
}
@ -145,15 +136,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_basic(lv_draw_ctx_t * draw_ctx, cons
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
if(disp->driver->set_px_cb) {
if(dsc->src_buf == NULL) {
fill_set_px(dest_buf, &blend_area, dest_stride, dsc->color, dsc->opa, mask, mask_stride);
}
else {
map_set_px(dest_buf, &blend_area, dest_stride, src_buf, src_stride, dsc->opa, mask, mask_stride);
}
}
else if(disp->driver->screen_transp) {
if(draw_ctx->render_with_alpha) {
if(dsc->src_buf == NULL) {
fill_argb(dest_buf, &blend_area, dest_stride, dsc->color, dsc->opa, mask, mask_stride);
}
@ -184,39 +167,6 @@ LV_ATTRIBUTE_FAST_MEM void lv_draw_sw_blend_basic(lv_draw_ctx_t * draw_ctx, cons
* STATIC FUNCTIONS
**********************/
static void fill_set_px(lv_color_t * dest_buf, const lv_area_t * blend_area, lv_coord_t dest_stride,
lv_color_t color, lv_opa_t opa, const lv_opa_t * mask, lv_coord_t mask_stide)
{
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
int32_t x;
int32_t y;
if(mask == NULL) {
for(y = blend_area->y1; y <= blend_area->y2; y++) {
for(x = blend_area->x1; x <= blend_area->x2; x++) {
disp->driver->set_px_cb(disp->driver, (void *)dest_buf, dest_stride, x, y, color, opa);
}
}
}
else {
int32_t w = lv_area_get_width(blend_area);
int32_t h = lv_area_get_height(blend_area);
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
if(mask[x]) {
disp->driver->set_px_cb(disp->driver, (void *)dest_buf, dest_stride, blend_area->x1 + x, blend_area->y1 + y, color,
(uint32_t)((uint32_t)opa * mask[x]) >> 8);
}
}
mask += mask_stide;
}
}
}
LV_ATTRIBUTE_FAST_MEM static void 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)
{
@ -575,41 +525,6 @@ static void fill_blended(lv_color_t * dest_buf, const lv_area_t * dest_area,
}
#endif
static void map_set_px(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)
{
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
int32_t w = lv_area_get_width(dest_area);
int32_t h = lv_area_get_height(dest_area);
int32_t x;
int32_t y;
if(mask == NULL) {
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
disp->driver->set_px_cb(disp->driver, (void *)dest_buf, dest_stride, dest_area->x1 + x, dest_area->y1 + y, src_buf[x],
opa);
}
src_buf += src_stride;
}
}
else {
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
if(mask[x]) {
disp->driver->set_px_cb(disp->driver, (void *)dest_buf, dest_stride, dest_area->x1 + x, dest_area->y1 + y, src_buf[x],
(uint32_t)((uint32_t)opa * mask[x]) >> 8);
}
}
mask += mask_stride;
src_buf += src_stride;
}
}
}
LV_ATTRIBUTE_FAST_MEM static void map_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)

View File

@ -71,18 +71,15 @@ struct _lv_draw_layer_ctx_t * lv_draw_sw_layer_create(struct _lv_draw_ctx_t * dr
layer_sw_ctx->base_draw.area_act = layer_sw_ctx->base_draw.area_full;
layer_sw_ctx->buf_size_bytes = lv_area_get_size(&layer_sw_ctx->base_draw.area_full) * px_size;
layer_sw_ctx->base_draw.buf = lv_malloc(layer_sw_ctx->buf_size_bytes);
LV_ASSERT_MALLOC(layer_sw_ctx->base_draw.buf);
if(layer_sw_ctx->base_draw.buf == NULL) return NULL;
lv_memzero(layer_sw_ctx->base_draw.buf, layer_sw_ctx->buf_size_bytes);
layer_sw_ctx->has_alpha = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? 1 : 0;
if(layer_sw_ctx->base_draw.buf == NULL) {
return NULL;
}
draw_ctx->buf = layer_sw_ctx->base_draw.buf;
draw_ctx->buf_area = &layer_sw_ctx->base_draw.area_act;
draw_ctx->clip_area = &layer_sw_ctx->base_draw.area_act;
lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
disp_refr->driver->screen_transp = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? 1 : 0;
draw_ctx->render_with_alpha = flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA ? 1 : 0;
}
return layer_ctx;
@ -93,15 +90,12 @@ void lv_draw_sw_layer_adjust(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_l
{
lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
if(flags & LV_DRAW_LAYER_FLAG_HAS_ALPHA) {
lv_memzero(layer_ctx->buf, layer_sw_ctx->buf_size_bytes);
layer_sw_ctx->has_alpha = 1;
disp_refr->driver->screen_transp = 1;
draw_ctx->render_with_alpha = 1;
}
else {
layer_sw_ctx->has_alpha = 0;
disp_refr->driver->screen_transp = 0;
draw_ctx->render_with_alpha = 0;
}
draw_ctx->buf = layer_ctx->buf;
@ -112,22 +106,19 @@ void lv_draw_sw_layer_adjust(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_l
void lv_draw_sw_layer_blend(struct _lv_draw_ctx_t * draw_ctx, struct _lv_draw_layer_ctx_t * layer_ctx,
const lv_draw_img_dsc_t * draw_dsc)
{
lv_draw_sw_layer_ctx_t * layer_sw_ctx = (lv_draw_sw_layer_ctx_t *) layer_ctx;
lv_img_dsc_t img;
img.data = draw_ctx->buf;
img.header.always_zero = 0;
img.header.w = lv_area_get_width(draw_ctx->buf_area);
img.header.h = lv_area_get_height(draw_ctx->buf_area);
img.header.cf = layer_sw_ctx->has_alpha ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR;
img.header.cf = draw_ctx->render_with_alpha ? LV_IMG_CF_TRUE_COLOR_ALPHA : LV_IMG_CF_TRUE_COLOR;
lv_img_cache_invalidate_src(&img);
/*Restore the original draw_ctx*/
draw_ctx->buf = layer_ctx->original.buf;
draw_ctx->buf_area = layer_ctx->original.buf_area;
draw_ctx->clip_area = layer_ctx->original.clip_area;
lv_disp_t * disp_refr = _lv_refr_get_disp_refreshing();
disp_refr->driver->screen_transp = layer_ctx->original.screen_transp;
draw_ctx->render_with_alpha = layer_ctx->original.render_with_alpha;
/*Blend the layer*/
lv_draw_img(draw_ctx, draw_dsc, &layer_ctx->area_act, &img);

View File

@ -87,8 +87,7 @@ void lv_draw_sw_rect(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, c
void lv_draw_sw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords)
{
#if LV_COLOR_DEPTH == 32
lv_disp_t * d = _lv_refr_get_disp_refreshing();
if(d->driver->screen_transp) {
if(draw_ctx->render_with_alpha) {
lv_memzero(draw_ctx->buf, lv_area_get_size(draw_ctx->buf_area) * sizeof(lv_color_t));
}
#endif

View File

@ -44,24 +44,6 @@
**********************/
static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_data);
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x,
lv_coord_t y,
lv_color_t color, lv_opa_t opa);
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa);
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa);
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa);
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa);
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa);
/**********************
* STATIC VARIABLES
**********************/
@ -96,6 +78,13 @@ void lv_disp_drv_init(lv_disp_drv_t * driver)
driver->dpi = LV_DPI_DEF;
driver->color_chroma_key = LV_COLOR_CHROMA_KEY;
#if LV_COLOR_DEPTH == 1
driver->color_format = LV_COLOR_FORMAT_L1;
#elif LV_COLOR_DEPTH == 8
driver->color_format = LV_COLOR_FORMAT_L8;
#else
driver->color_format = LV_COLOR_FORMAT_NATIVE;
#endif
#if LV_USE_GPU_STM32_DMA2D
driver->draw_ctx_init = lv_draw_stm32_dma2d_ctx_init;
@ -173,6 +162,9 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
driver->draw_ctx = draw_ctx;
}
driver->draw_ctx->color_format = driver->color_format;
driver->draw_ctx->render_with_alpha = driver->screen_transp;
lv_memzero(disp, sizeof(lv_disp_t));
disp->driver = driver;
@ -568,29 +560,6 @@ lv_disp_rot_t lv_disp_get_rotation(lv_disp_t * disp)
return disp->driver->rotated;
}
void lv_disp_drv_use_generic_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf)
{
switch(cf) {
case LV_IMG_CF_TRUE_COLOR_ALPHA:
disp_drv->set_px_cb = set_px_true_color_alpha;
break;
case LV_IMG_CF_ALPHA_1BIT:
disp_drv->set_px_cb = set_px_cb_alpha1;
break;
case LV_IMG_CF_ALPHA_2BIT:
disp_drv->set_px_cb = set_px_cb_alpha2;
break;
case LV_IMG_CF_ALPHA_4BIT:
disp_drv->set_px_cb = set_px_cb_alpha4;
break;
case LV_IMG_CF_ALPHA_8BIT:
disp_drv->set_px_cb = set_px_cb_alpha8;
break;
default:
disp_drv->set_px_cb = NULL;
}
}
/**********************
* STATIC FUNCTIONS
**********************/
@ -601,106 +570,3 @@ static lv_obj_tree_walk_res_t invalidate_layout_cb(lv_obj_t * obj, void * user_d
lv_obj_mark_layout_as_dirty(obj);
return LV_OBJ_TREE_WALK_NEXT;
}
static void set_px_cb_alpha1(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
(void) disp_drv; /*Unused*/
if(opa <= LV_OPA_MIN) return;
lv_img_dsc_t d;
d.data = buf;
d.header.w = buf_w;
d.header.cf = LV_IMG_CF_ALPHA_1BIT;
set_px_alpha_generic(&d, x, y, color, opa);
}
static void set_px_cb_alpha2(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
(void) disp_drv; /*Unused*/
if(opa <= LV_OPA_MIN) return;
lv_img_dsc_t d;
d.data = buf;
d.header.w = buf_w;
d.header.cf = LV_IMG_CF_ALPHA_2BIT;
set_px_alpha_generic(&d, x, y, color, opa);
}
static void set_px_cb_alpha4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
(void) disp_drv; /*Unused*/
if(opa <= LV_OPA_MIN) return;
lv_img_dsc_t d;
d.data = buf;
d.header.w = buf_w;
d.header.cf = LV_IMG_CF_ALPHA_4BIT;
set_px_alpha_generic(&d, x, y, color, opa);
}
static void set_px_cb_alpha8(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
(void) disp_drv; /*Unused*/
if(opa <= LV_OPA_MIN) return;
lv_img_dsc_t d;
d.data = buf;
d.header.w = buf_w;
d.header.cf = LV_IMG_CF_ALPHA_8BIT;
set_px_alpha_generic(&d, x, y, color, opa);
}
static void set_px_alpha_generic(lv_img_dsc_t * d, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa)
{
d->header.always_zero = 0;
d->header.h = 1; /*Doesn't matter*/
uint8_t br = lv_color_brightness(color);
if(opa < LV_OPA_MAX) {
uint8_t bg = lv_img_buf_get_px_alpha(d, x, y);
br = (uint16_t)((uint16_t)br * opa + (bg * (255 - opa))) >> 8;
}
lv_img_buf_set_px_alpha(d, x, y, br);
}
static void set_px_true_color_alpha(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w,
lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
{
(void) disp_drv; /*Unused*/
uint8_t * buf_px = buf + (buf_w * y * LV_IMG_PX_SIZE_ALPHA_BYTE + x * LV_IMG_PX_SIZE_ALPHA_BYTE);
lv_color_t bg_color;
lv_color_t res_color;
lv_opa_t bg_opa = buf_px[LV_IMG_PX_SIZE_ALPHA_BYTE - 1];
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
bg_color.full = buf_px[0];
lv_color_mix_with_alpha(bg_color, bg_opa, color, opa, &res_color, &buf_px[2]);
if(buf_px[1] <= LV_OPA_MIN) return;
buf_px[0] = res_color.full;
#elif LV_COLOR_DEPTH == 16
bg_color.full = buf_px[0] + (buf_px[1] << 8);
lv_color_mix_with_alpha(bg_color, bg_opa, color, opa, &res_color, &buf_px[2]);
if(buf_px[2] <= LV_OPA_MIN) return;
buf_px[0] = res_color.full & 0xff;
buf_px[1] = res_color.full >> 8;
#elif LV_COLOR_DEPTH == 32
bg_color = *((lv_color_t *)buf_px);
lv_color_mix_with_alpha(bg_color, bg_opa, color, opa, &res_color, &buf_px[3]);
if(buf_px[3] <= LV_OPA_MIN) return;
buf_px[0] = res_color.ch.blue;
buf_px[1] = res_color.ch.green;
buf_px[2] = res_color.ch.red;
#endif
}

View File

@ -104,6 +104,8 @@ typedef struct _lv_disp_drv_t {
uint32_t dpi : 10; /** DPI (dot per inch) of the display. Default value is `LV_DPI_DEF`.*/
lv_color_format_t color_format;
/** MANDATORY: Write the internal buffer (draw_buf) to the display. 'lv_disp_flush_ready()' has to be
* called when finished*/
void (*flush_cb)(struct _lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
@ -112,15 +114,9 @@ typedef struct _lv_disp_drv_t {
* E.g. round `y` to, 8, 16 ..) on a monochrome display*/
void (*rounder_cb)(struct _lv_disp_drv_t * disp_drv, lv_area_t * area);
/** OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
* Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
* @note Much slower then drawing with supported color formats.*/
void (*set_px_cb)(struct _lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa);
void (*clear_cb)(struct _lv_disp_drv_t * disp_drv, uint8_t * buf, uint32_t size);
/** OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the
* number of flushed pixels*/
void (*monitor_cb)(struct _lv_disp_drv_t * disp_drv, uint32_t time, uint32_t px);
@ -361,8 +357,6 @@ lv_disp_t * lv_disp_get_next(lv_disp_t * disp);
*/
lv_disp_draw_buf_t * lv_disp_get_draw_buf(lv_disp_t * disp);
void lv_disp_drv_use_generic_set_px_cb(lv_disp_drv_t * disp_drv, lv_img_cf_t cf);
/**********************
* MACROS
**********************/

View File

@ -230,6 +230,46 @@ typedef struct _lv_color_filter_dsc_t {
} lv_color_filter_dsc_t;
typedef enum {
LV_COLOR_FORMAT_NATIVE = 0, /*Keep original format. Used in color conversation*/
LV_COLOR_FORMAT_NATIVE_REVERSE, /*Change endianess*/
_LV_COLOR_FORMAT_NATIVE_END = 16,
LV_COLOR_FORMAT_RGB232,
LV_COLOR_FORMAT_RGBA2328,
LV_COLOR_FORMAT_RGBA2222,
LV_COLOR_FORMAT_RGB565,
LV_COLOR_FORMAT_RGBA5658,
LV_COLOR_FORMAT_RGBA5551,
LV_COLOR_FORMAT_RGBA4444,
LV_COLOR_FORMAT_RGB565A8,
LV_COLOR_FORMAT_RGB888,
LV_COLOR_FORMAT_RGBA8888,
LV_COLOR_FORMAT_RGBX8888,
LV_COLOR_FORMAT_L1,
LV_COLOR_FORMAT_L2,
LV_COLOR_FORMAT_L4,
LV_COLOR_FORMAT_L8,
LV_COLOR_FORMAT_A1,
LV_COLOR_FORMAT_A2,
LV_COLOR_FORMAT_A4,
LV_COLOR_FORMAT_A8,
LV_COLOR_FORMAT_I1,
LV_COLOR_FORMAT_I2,
LV_COLOR_FORMAT_I4,
LV_COLOR_FORMAT_I8,
LV_COLOR_FORMAT_CUSTOM_START = 0xff, /*Custom formats can be added from here*/
} lv_color_format_t;
typedef enum {
LV_PALETTE_RED,
LV_PALETTE_PINK,

View File

@ -10,8 +10,8 @@
#if LV_USE_SNAPSHOT
#include <stdbool.h>
#include "../../../core/lv_disp.h"
#include "../../../core/lv_refr.h"
#include "../../core/lv_disp.h"
#include "../../core/lv_refr.h"
/*********************
* DEFINES
*********************/

View File

@ -784,9 +784,25 @@ static void init_fake_disp(lv_obj_t * canvas, lv_disp_t * disp, lv_disp_drv_t *
draw_ctx->buf_area = clip_area;
draw_ctx->buf = (void *)dsc->data;
lv_disp_drv_use_generic_set_px_cb(disp->driver, dsc->header.cf);
if(dsc->header.cf != LV_IMG_CF_TRUE_COLOR_ALPHA) drv->screen_transp = 0;
else drv->screen_transp = 1;
switch(dsc->header.cf) {
case LV_IMG_CF_ALPHA_1BIT:
draw_ctx->color_format = LV_COLOR_FORMAT_L1;
break;
case LV_IMG_CF_ALPHA_2BIT:
draw_ctx->color_format = LV_COLOR_FORMAT_L2;
break;
case LV_IMG_CF_ALPHA_4BIT:
draw_ctx->color_format = LV_COLOR_FORMAT_L4;
break;
case LV_IMG_CF_ALPHA_8BIT:
draw_ctx->color_format = LV_COLOR_FORMAT_L8;
break;
default:
break;
}
if(dsc->header.cf != LV_IMG_CF_TRUE_COLOR_ALPHA) draw_ctx->render_with_alpha = false;
else draw_ctx->render_with_alpha = true;
}
static void deinit_fake_disp(lv_obj_t * canvas, lv_disp_t * disp)