Skip to content

Commit 94ae6c0

Browse files
authored
feat(canvas): add api to skip canvas invalidation when setting pixel (#9592)
1 parent 0648b6d commit 94ae6c0

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

docs/src/widgets/canvas.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ To set an individual pixel's color on the Canvas, use
7171
(``LV_COLOR_FORMAT_I1/2/4/8``) pass the color index as the ``color`` argument by using
7272
the *blue* channel in the ``color`` value, e.g. :cpp:expr:`lv_color_make(0, 0, index)`.
7373

74+
.. tip::
75+
76+
When updating multiple pixels in a loop, follow these steps to improve performance:
77+
78+
1. Use :cpp:func:`lv_canvas_set_px_skip_invalidate` to set pixel colors without triggering a redraw.
79+
2. Call :cpp:func:`lv_obj_invalidate` once after the loop is finished.
80+
81+
This prevents the canvas from being redundantly invalidated for every single pixel update.
82+
7483
:cpp:expr:`lv_canvas_fill_bg(canvas, lv_color_hex(0x00ff00), LV_OPA_50)` fills the whole
7584
Canvas to blue with 50% opacity. Note that if the current color format
7685
doesn't support colors (e.g. :cpp:enumerator:`LV_COLOR_FORMAT_A8`) the color will be

src/widgets/canvas/lv_canvas.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ void lv_canvas_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf)
108108
lv_image_cache_drop(draw_buf);
109109
}
110110

111-
void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv_opa_t opa)
111+
void lv_canvas_set_px_skip_invalidate(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv_opa_t opa)
112112
{
113113
LV_ASSERT_OBJ(obj, MY_CLASS);
114114

@@ -182,6 +182,11 @@ void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv
182182
buf->lumi = lv_color_luminance(color);
183183
buf->alpha = 255;
184184
}
185+
}
186+
187+
void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv_opa_t opa)
188+
{
189+
lv_canvas_set_px_skip_invalidate(obj, x, y, color, opa);
185190
lv_obj_invalidate(obj);
186191
}
187192

src/widgets/canvas/lv_canvas.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,22 @@ void lv_canvas_set_draw_buf(lv_obj_t * obj, lv_draw_buf_t * draw_buf);
8484
*/
8585
void lv_canvas_set_px(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv_opa_t opa);
8686

87+
/**
88+
* Set a pixel's color and opacity without invalidating the canvas object
89+
* In order for the canvas to be redrawn, the user is required to manually call `lv_obj_invalidate`
90+
*
91+
* @param obj pointer to a canvas
92+
* @param x X coordinate of the pixel
93+
* @param y Y coordinate of the pixel
94+
* @param color the color
95+
* @param opa the opacity
96+
* @note The following color formats are supported
97+
* LV_COLOR_FORMAT_I1/2/4/8, LV_COLOR_FORMAT_A8,
98+
* LV_COLOR_FORMAT_RGB565, LV_COLOR_FORMAT_RGB888,
99+
* LV_COLOR_FORMAT_XRGB8888, LV_COLOR_FORMAT_ARGB8888
100+
*/
101+
void lv_canvas_set_px_skip_invalidate(lv_obj_t * obj, int32_t x, int32_t y, lv_color_t color, lv_opa_t opa);
102+
87103
/**
88104
* Set the palette color of a canvas for index format. Valid only for `LV_COLOR_FORMAT_I1/2/4/8`
89105
* @param obj pointer to canvas object

tests/src/test_cases/widgets/test_canvas.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ void test_canvas_functions_invalidate(void)
6868
lv_refr_now(NULL);
6969
TEST_ASSERT(draw_counter == 2);
7070

71+
lv_canvas_set_px_skip_invalidate(canvas, 0, 0, lv_color_black(), LV_OPA_COVER);
72+
lv_refr_now(NULL);
73+
TEST_ASSERT(draw_counter == 2);
74+
7175
lv_canvas_fill_bg(canvas, lv_color_black(), LV_OPA_COVER);
7276
lv_refr_now(NULL);
7377
TEST_ASSERT(draw_counter == 3);

0 commit comments

Comments
 (0)