fix(draw): fix minor issues in SW render

This commit is contained in:
Gabor Kiss-Vamosi
2023-11-15 09:47:34 +01:00
parent 6cda061c65
commit 628fb98b52
6 changed files with 103 additions and 22 deletions

View File

@@ -115,7 +115,6 @@ static void fill_cb(lv_obj_t * parent)
static lv_obj_t * border_obj_create(lv_obj_t * parent, int32_t col, int32_t row)
{
lv_obj_t * obj = lv_obj_create(parent);
lv_obj_remove_style_all(obj);
lv_obj_set_style_border_color(obj, lv_color_hex3(0x000), 0);

View File

@@ -422,6 +422,22 @@ static void lv_obj_draw(lv_event_t * e)
return;
}
if(lv_obj_get_style_bg_grad_dir(obj, 0) != LV_GRAD_DIR_NONE) {
if(lv_obj_get_style_bg_grad_opa(obj, 0) < LV_OPA_MAX) {
info->res = LV_COVER_RES_NOT_COVER;
return;
}
const lv_grad_dsc_t * grad_dsc = lv_obj_get_style_bg_grad(obj, 0);
if(grad_dsc) {
uint32_t i;
for(i = 0; i < grad_dsc->stops_count; i++) {
if(grad_dsc->stops[i].opa < LV_OPA_MAX) {
info->res = LV_COVER_RES_NOT_COVER;
return;
}
}
}
}
info->res = LV_COVER_RES_COVER;
}

View File

@@ -278,7 +278,7 @@ void lv_draw_label_iterate_letters(lv_draw_unit_t * draw_unit, const lv_draw_lab
/*Always set the bg_coordinates for placeholder drawing*/
bg_coords.x1 = pos.x;
bg_coords.y1 = pos.y;
bg_coords.x2 = pos.x + letter_w + dsc->letter_space - 1;
bg_coords.x2 = pos.x + letter_w - 1;
bg_coords.y2 = pos.y + line_height - 1;
if(i >= line_end - line_start) {
@@ -387,7 +387,8 @@ static void draw_letter(lv_draw_unit_t * draw_unit, lv_draw_glyph_dsc_t * dsc,
letter_coords.y2 = letter_coords.y1 + g.box_h - 1;
/*If the letter is completely out of mask don't draw it*/
if(_lv_area_is_out(&letter_coords, draw_unit->clip_area, 0)) {
if(_lv_area_is_out(&letter_coords, draw_unit->clip_area, 0) &&
_lv_area_is_out(dsc->bg_coords, draw_unit->clip_area, 0)) {
LV_PROFILER_END;
return;
}

View File

@@ -132,7 +132,9 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
blend_dsc.mask_res = lv_draw_sw_mask_apply(mask_list, mask_buf, blend_area.x1, top_y, clipped_w);
if(blend_dsc.mask_res == LV_DRAW_SW_MASK_RES_FULL_COVER) blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
bool hor_grad_processed;
if(top_y >= clipped_coords.y1) {
hor_grad_processed = false;
blend_area.y1 = top_y;
blend_area.y2 = top_y;
@@ -141,6 +143,7 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
blend_dsc.opa = grad->opa_map[top_y - bg_coords.y1];
}
else if(grad_dir == LV_GRAD_DIR_HOR) {
hor_grad_processed = true;
if(grad_opa_map) {
int32_t i;
for(i = 0; i < clipped_w; i++) {
@@ -160,6 +163,15 @@ void lv_draw_sw_fill(lv_draw_unit_t * draw_unit, const lv_draw_fill_dsc_t * dsc,
blend_dsc.color = grad->color_map[bottom_y - bg_coords.y1];
blend_dsc.opa = grad->opa_map[bottom_y - bg_coords.y1];
}
else if(hor_grad_processed == false && grad_dir == LV_GRAD_DIR_HOR) {
if(grad_opa_map) {
int32_t i;
for(i = 0; i < clipped_w; i++) {
if(grad_opa_map[i] < LV_OPA_MAX) mask_buf[i] = (mask_buf[i] * grad_opa_map[i]) >> 8;
}
blend_dsc.mask_res = LV_DRAW_SW_MASK_RES_CHANGED;
}
}
lv_draw_sw_blend(draw_unit, &blend_dsc);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -11,7 +11,7 @@
/*********************
* INCLUDES
*********************/
#if LV_BUILD_TEST
#if LV_BUILD_TEST || 1
#include "../lvgl.h"
#include <unistd.h>
#include <stdlib.h>
@@ -47,6 +47,7 @@ typedef struct {
/**********************
* STATIC PROTOTYPES
**********************/
static bool screenhot_compare(const char * fn_ref, const char * mode, uint8_t tolerance);
static int read_png_file(png_image_t * p, const char * file_name);
static int write_png_file(void * raw_img, uint32_t width, uint32_t height, char * file_name);
static void png_release(png_image_t * p);
@@ -65,11 +66,69 @@ static void png_release(png_image_t * p);
bool lv_test_assert_image_eq(const char * fn_ref)
{
bool pass;
lv_obj_t * scr = lv_screen_active();
lv_obj_invalidate(scr);
pass = screenhot_compare(fn_ref, "full refresh", 0);
if(!pass) return false;
//Software has minor rounding errors when not the whole image is updated
//so ignore stripe invalidation for now
// uint32_t i;
// for(i = 0; i < 800; i += 50 ) {
// lv_area_t a;
// a.y1 = 0;
// a.y2 = 479;
// a.x1 = i;
// a.x2 = i + 12;
// lv_obj_invalidate_area(scr, &a);
//
// a.x1 = i + 25;
// a.x2 = i + 32;
// lv_obj_invalidate_area(scr, &a);
// }
//
// pass = screenhot_compare(fn_ref, "vertical stripes", 32);
// if(!pass) return false;
//
//
// for(i = 0; i < 480; i += 40) {
// lv_area_t a;
// a.x1 = 0;
// a.x2 = 799;
// a.y1 = i;
// a.y2 = i + 9;
// lv_obj_invalidate_area(scr, &a);
//
// a.y1 = i + 25;
// a.y2 = i + 32;
// lv_obj_invalidate_area(scr, &a);
// }
//
// pass = screenhot_compare(fn_ref, "horizontal stripes", 32);
// if(!pass) return false;
return true;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Compare the content of the frame buffer with a reference image
* @param fn_ref reference image name
* @param mode arbitrary string to tell more about the compare
* @return true: test passed; false: test failed
*/
static bool screenhot_compare(const char * fn_ref, const char * mode, uint8_t tolerance)
{
char fn_ref_full[512];
sprintf(fn_ref_full, "%s%s", REF_IMGS_PATH, fn_ref);
//lv_obj_invalidate(lv_screen_active());
lv_refr_now(NULL);
extern uint8_t * last_flushed_buf;
@@ -91,13 +150,14 @@ bool lv_test_assert_image_eq(const char * fn_ref)
const png_byte * ptr_ref = NULL;
bool err = false;
int x, y, i_buf = 0;
uint32_t stride = lv_draw_buf_width_to_stride(800, LV_COLOR_FORMAT_ARGB8888);
int x, y;
for(y = 0; y < p.height; y++) {
uint8_t * screen_buf_tmp = screen_buf + stride * y;
png_byte * row = p.row_pointers[y];
for(x = 0; x < p.width; x++) {
ptr_ref = &(row[x * 3]);
ptr_act = &(screen_buf[i_buf * 4]);
ptr_act = screen_buf_tmp;
uint32_t ref_px = 0;
uint32_t act_px = 0;
@@ -106,13 +166,16 @@ bool lv_test_assert_image_eq(const char * fn_ref)
uint8_t act_swap[3] = {ptr_act[2], ptr_act[1], ptr_act[0]};
if(memcmp(act_swap, ptr_ref, 3) != 0) {
TEST_PRINTF("Error on x:%d, y:%d. Expected %X, Actual %X", x, y, ref_px, act_px);
if(LV_ABS((int32_t) act_swap[0] - ptr_ref[0]) > tolerance ||
LV_ABS((int32_t) act_swap[1] - ptr_ref[1]) > tolerance ||
LV_ABS((int32_t) act_swap[2] - ptr_ref[2]) > tolerance) {
uint32_t act_swap_32 = (act_swap[2] << 16) + (act_swap[1] << 8) + (act_swap[0] << 0);
TEST_PRINTF("Error %s on x:%d, y:%d.\nExpected: %X\nActual: %X", mode, x, y, ref_px, act_swap_32);
fflush(stderr);
err = true;
break;
}
i_buf++;
screen_buf_tmp += 4;
}
if(err) break;
}
@@ -128,7 +191,6 @@ bool lv_test_assert_image_eq(const char * fn_ref)
write_png_file(screen_buf, 800, 480, fn_err_full);
}
png_release(&p);
fflush(stdout);
@@ -136,10 +198,6 @@ bool lv_test_assert_image_eq(const char * fn_ref)
}
/**********************
* STATIC FUNCTIONS
**********************/
static int read_png_file(png_image_t * p, const char * file_name)
{
char header[8]; // 8 is the maximum size that can be checked
@@ -204,7 +262,6 @@ static int read_png_file(png_image_t * p, const char * file_name)
return 0;
}
static int write_png_file(void * raw_img, uint32_t width, uint32_t height, char * file_name)
{
png_structp png_ptr;
@@ -253,7 +310,6 @@ static int write_png_file(void * raw_img, uint32_t width, uint32_t height, char
png_write_info(png_ptr, info_ptr);
/* write bytes */
if(setjmp(png_jmpbuf(png_ptr))) {
TEST_PRINTF("[write_png_file %s] Error during writing bytes", file_name);
@@ -273,7 +329,6 @@ static int write_png_file(void * raw_img, uint32_t width, uint32_t height, char
}
png_write_image(png_ptr, row_pointers);
/* end write */
if(setjmp(png_jmpbuf(png_ptr))) {
TEST_PRINTF("[write_png_file %s] Error during end of write", file_name);
@@ -291,7 +346,6 @@ static int write_png_file(void * raw_img, uint32_t width, uint32_t height, char
return 0;
}
static void png_release(png_image_t * p)
{
int y;
@@ -302,5 +356,4 @@ static void png_release(png_image_t * p)
png_destroy_read_struct(&p->png_ptr, &p->info_ptr, NULL);
}
#endif