mirror of
https://github.com/lvgl/lvgl.git
synced 2024-11-27 19:53:42 +08:00
arch(color): define generic color formats and add draw_ctx->buffer_convert
This commit is contained in:
parent
a16e6a83f5
commit
453ac21254
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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`
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
**********************/
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
**********************/
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
*********************/
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user