fix(draw): fix minor issues in SW render
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user