perf(qrcode): improve drawing speed (#6475)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
@@ -70,7 +70,7 @@ void lv_qrcode_set_size(lv_obj_t * obj, int32_t size)
|
|||||||
LV_LOG_INFO("set canvas buffer: %p, size = %d", (void *)new_buf, (int)size);
|
LV_LOG_INFO("set canvas buffer: %p, size = %d", (void *)new_buf, (int)size);
|
||||||
|
|
||||||
/*Clear canvas buffer*/
|
/*Clear canvas buffer*/
|
||||||
lv_canvas_fill_bg(obj, lv_color_white(), LV_OPA_COVER);
|
lv_draw_buf_clear(new_buf, NULL);
|
||||||
|
|
||||||
if(old_buf != NULL) lv_draw_buf_destroy(old_buf);
|
if(old_buf != NULL) lv_draw_buf_destroy(old_buf);
|
||||||
}
|
}
|
||||||
@@ -100,10 +100,12 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le
|
|||||||
return LV_RESULT_INVALID;
|
return LV_RESULT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_canvas_set_palette(obj, 0, lv_color_to_32(qrcode->dark_color, 0xff));
|
lv_draw_buf_clear(draw_buf, NULL);
|
||||||
lv_canvas_set_palette(obj, 1, lv_color_to_32(qrcode->light_color, 0xff));
|
lv_canvas_set_palette(obj, 0, lv_color_to_32(qrcode->light_color, LV_OPA_COVER));
|
||||||
lv_color_t c = lv_color_hex(1);
|
lv_canvas_set_palette(obj, 1, lv_color_to_32(qrcode->dark_color, LV_OPA_COVER));
|
||||||
lv_canvas_fill_bg(obj, c, LV_OPA_COVER);
|
lv_image_cache_drop(draw_buf);
|
||||||
|
|
||||||
|
lv_obj_invalidate(obj);
|
||||||
|
|
||||||
if(data_len > qrcodegen_BUFFER_LEN_MAX) return LV_RESULT_INVALID;
|
if(data_len > qrcodegen_BUFFER_LEN_MAX) return LV_RESULT_INVALID;
|
||||||
|
|
||||||
@@ -140,12 +142,16 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le
|
|||||||
return LV_RESULT_INVALID;
|
return LV_RESULT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Temporarily disable invalidation to improve the efficiency of lv_canvas_set_px */
|
||||||
|
lv_display_enable_invalidation(lv_obj_get_display(obj), false);
|
||||||
|
|
||||||
int32_t obj_w = draw_buf->header.w;
|
int32_t obj_w = draw_buf->header.w;
|
||||||
qr_size = qrcodegen_getSize(qr0);
|
qr_size = qrcodegen_getSize(qr0);
|
||||||
scale = obj_w / qr_size;
|
scale = obj_w / qr_size;
|
||||||
int scaled = qr_size * scale;
|
int scaled = qr_size * scale;
|
||||||
int margin = (obj_w - scaled) / 2;
|
int margin = (obj_w - scaled) / 2;
|
||||||
uint8_t * buf_u8 = (uint8_t *)draw_buf->data + 8; /*+8 skip the palette*/
|
uint8_t * buf_u8 = (uint8_t *)draw_buf->data + 8; /*+8 skip the palette*/
|
||||||
|
lv_color_t c = lv_color_hex(1);
|
||||||
|
|
||||||
/* Copy the qr code canvas:
|
/* Copy the qr code canvas:
|
||||||
* A simple `lv_canvas_set_px` would work but it's slow for so many pixels.
|
* A simple `lv_canvas_set_px` would work but it's slow for so many pixels.
|
||||||
@@ -163,15 +169,16 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le
|
|||||||
if(aligned == false && (x & 0x7) == 0) aligned = true;
|
if(aligned == false && (x & 0x7) == 0) aligned = true;
|
||||||
|
|
||||||
if(aligned == false) {
|
if(aligned == false) {
|
||||||
c = lv_color_hex(a ? 0 : 1);
|
if(a) {
|
||||||
lv_canvas_set_px(obj, x, y, c, LV_OPA_COVER);
|
lv_canvas_set_px(obj, x, y, c, LV_OPA_COVER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!a) b |= (1 << (7 - p));
|
if(!a) b |= (1 << (7 - p));
|
||||||
p++;
|
p++;
|
||||||
if(p == 8) {
|
if(p == 8) {
|
||||||
uint32_t px = row_byte_cnt * y + (x >> 3);
|
uint32_t px = row_byte_cnt * y + (x >> 3);
|
||||||
buf_u8[px] = b;
|
buf_u8[px] = ~b;
|
||||||
b = 0;
|
b = 0;
|
||||||
p = 0;
|
p = 0;
|
||||||
}
|
}
|
||||||
@@ -184,7 +191,7 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le
|
|||||||
b |= (1 << (8 - p)) - 1;
|
b |= (1 << (8 - p)) - 1;
|
||||||
|
|
||||||
uint32_t px = row_byte_cnt * y + (x >> 3);
|
uint32_t px = row_byte_cnt * y + (x >> 3);
|
||||||
buf_u8[px] = b;
|
buf_u8[px] = ~b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*The Qr is probably scaled so simply to the repeated rows*/
|
/*The Qr is probably scaled so simply to the repeated rows*/
|
||||||
@@ -195,6 +202,9 @@ lv_result_t lv_qrcode_update(lv_obj_t * obj, const void * data, uint32_t data_le
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* invalidate the canvas to refresh it */
|
||||||
|
lv_display_enable_invalidation(lv_obj_get_display(obj), true);
|
||||||
|
|
||||||
lv_free(qr0);
|
lv_free(qr0);
|
||||||
lv_free(data_tmp);
|
lv_free(data_tmp);
|
||||||
return LV_RESULT_OK;
|
return LV_RESULT_OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user