From f310109da341cfc106b16595b11bba5eb457ca86 Mon Sep 17 00:00:00 2001 From: lixianjing Date: Thu, 28 Nov 2024 08:08:43 +0800 Subject: [PATCH] add bitmap_set_dirty/bitmap_is_dirty --- docs/changes.md | 3 ++ src/base/bitmap.c | 53 +++++++++++++++---- src/base/bitmap.h | 21 +++++++- .../color_picker/color_component.c | 2 +- src/ext_widgets/mutable_image/mutable_image.c | 2 +- src/vgcanvas/texture.inc | 4 +- src/vgcanvas/vgcanvas_nanovg_plus.inc | 4 +- tests/bitmap_test.cc | 3 ++ 8 files changed, 76 insertions(+), 16 deletions(-) diff --git a/docs/changes.md b/docs/changes.md index e55033c116..39df937d22 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -1,5 +1,8 @@ # 最新动态 +2024/11/28 + * 增加函数 bitmap_set_dirty/bitmap_is_dirty + 2024/11/26 * 增加tab_button_group删除tab_button和对应page的函数(感谢智明提供补丁) diff --git a/src/base/bitmap.c b/src/base/bitmap.c index 89257e28cb..924a498b08 100644 --- a/src/base/bitmap.c +++ b/src/base/bitmap.c @@ -901,37 +901,55 @@ ret_t bitmap_mono_dump(const uint8_t* buff, uint32_t w, uint32_t h) { return RET_OK; } +typedef enum _bitmap_lock_type_t { + BITMAP_LOCK_NONE = 0, + BITMAP_LOCK_READ, + BITMAP_LOCK_WRITE +} bitmap_lock_type_t; + uint8_t* bitmap_lock_buffer_for_read(bitmap_t* bitmap) { + uint8_t* data = NULL; return_value_if_fail(bitmap != NULL, NULL); if (bitmap->buffer != NULL) { if (!graphic_buffer_is_valid_for(bitmap->buffer, bitmap)) { assert(!" graphic_buffer is not valid "); - return NULL; } - return graphic_buffer_lock_for_read(bitmap->buffer); - } else { - return NULL; + data = graphic_buffer_lock_for_read(bitmap->buffer); + } + + if (data != NULL) { + bitmap->lock_type = BITMAP_LOCK_READ; } + + return data; } uint8_t* bitmap_lock_buffer_for_write(bitmap_t* bitmap) { + uint8_t* data = NULL; return_value_if_fail(bitmap != NULL, NULL); if (bitmap->buffer != NULL) { if (!graphic_buffer_is_valid_for(bitmap->buffer, bitmap)) { assert(!" graphic_buffer is not valid "); - return NULL; } - return graphic_buffer_lock_for_write(bitmap->buffer); - } else { - return NULL; + data = graphic_buffer_lock_for_write(bitmap->buffer); } + + if (data != NULL) { + bitmap->lock_type = BITMAP_LOCK_WRITE; + } + + return data; } ret_t bitmap_unlock_buffer(bitmap_t* bitmap) { return_value_if_fail(bitmap != NULL, RET_BAD_PARAMS); + if (bitmap->lock_type == BITMAP_LOCK_WRITE) { + bitmap_set_dirty(bitmap, TRUE); + } + if (bitmap->buffer != NULL) { assert(graphic_buffer_is_valid_for(bitmap->buffer, bitmap)); return graphic_buffer_unlock(bitmap->buffer); @@ -940,6 +958,24 @@ ret_t bitmap_unlock_buffer(bitmap_t* bitmap) { } } +ret_t bitmap_set_dirty(bitmap_t* bitmap, bool_t dirty) { + return_value_if_fail(bitmap != NULL, RET_BAD_PARAMS); + + if (dirty) { + bitmap->flags |= BITMAP_FLAG_CHANGED; + } else { + bitmap->flags &= ~BITMAP_FLAG_CHANGED; + } + + return RET_OK; +} + +bool_t bitmap_is_dirty(bitmap_t* bitmap) { + return_value_if_fail(bitmap != NULL, FALSE); + + return (bitmap->flags & BITMAP_FLAG_CHANGED) ? TRUE : FALSE; +} + ret_t bitmap_transform(bitmap_t* bitmap, bitmap_transform_t transform, void* ctx) { uint32_t x = 0; uint32_t y = 0; @@ -1036,7 +1072,6 @@ ret_t bitmap_transform(bitmap_t* bitmap, bitmap_transform_t transform, void* ctx } } bitmap_unlock_buffer(bitmap); - bitmap->flags |= BITMAP_FLAG_CHANGED; return ret; } diff --git a/src/base/bitmap.h b/src/base/bitmap.h index ff2888f99a..90bb88793f 100644 --- a/src/base/bitmap.h +++ b/src/base/bitmap.h @@ -30,6 +30,7 @@ BEGIN_C_DECLS typedef ret_t (*bitmap_destroy_t)(bitmap_t* bitmap); + /** * @class bitmap_t * @order -9 @@ -111,9 +112,10 @@ struct _bitmap_t { /*用于销毁specific*/ bitmap_destroy_t specific_destroy; + int lock_type; + /*virtual functions*/ bitmap_destroy_t destroy; - image_manager_t* image_manager; }; @@ -320,6 +322,23 @@ ret_t bitmap_init(bitmap_t* bitmap, uint32_t w, uint32_t h, bitmap_format_t form ret_t bitmap_init_ex(bitmap_t* bitmap, uint32_t w, uint32_t h, uint32_t line_length, bitmap_format_t format, uint8_t* data); +/** + * @method bitmap_set_dirty + * 设置图片是否脏。 + * @param {bitmap_t*} bitmap bitmap对象。 + * @param {bool_t} dirty 是否脏。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t bitmap_set_dirty(bitmap_t* bitmap, bool_t dirty); + +/** + * @method bitmap_is_dirty + * 获取图片是否脏。 + * @param {bitmap_t*} bitmap bitmap对象。 + * @return {bool_t} 返回TRUE表示脏,FALSE表示不脏。 + */ +bool_t bitmap_is_dirty(bitmap_t* bitmap); + #if defined(WITH_STB_IMAGE) || defined(WITH_FS_RES) /*for helping debug drawing bugs*/ diff --git a/src/ext_widgets/color_picker/color_component.c b/src/ext_widgets/color_picker/color_component.c index 62f7b27fe0..9128138e00 100644 --- a/src/ext_widgets/color_picker/color_component.c +++ b/src/ext_widgets/color_picker/color_component.c @@ -201,7 +201,7 @@ static ret_t color_component_ensure_image(widget_t* widget) { bitmap_t* image = color_component->image; color_component->update(widget); - image->flags |= BITMAP_FLAG_CHANGED; + bitmap_set_dirty(image, TRUE); color_component->need_update = FALSE; } diff --git a/src/ext_widgets/mutable_image/mutable_image.c b/src/ext_widgets/mutable_image/mutable_image.c index c314bc449c..2fffe18b0a 100644 --- a/src/ext_widgets/mutable_image/mutable_image.c +++ b/src/ext_widgets/mutable_image/mutable_image.c @@ -64,7 +64,7 @@ static bitmap_t* mutable_image_prepare_image(widget_t* widget, canvas_t* c) { void* ctx = mutable_image->prepare_image_ctx; return_value_if_fail(mutable_image->prepare_image(ctx, image) == RET_OK, NULL); - image->flags |= BITMAP_FLAG_CHANGED; + bitmap_set_dirty(image, TRUE); } return mutable_image->image; diff --git a/src/vgcanvas/texture.inc b/src/vgcanvas/texture.inc index 034dba021f..c09a0875b3 100644 --- a/src/vgcanvas/texture.inc +++ b/src/vgcanvas/texture.inc @@ -38,8 +38,8 @@ static int vgcanvas_nanovg_ensure_image(vgcanvas_nanovg_t* canvas, bitmap_t* img if (result == RET_OK) { i = ((vgcanvas_nanovg_gl_texture_t*)specific)->image_id; - if (img->flags & BITMAP_FLAG_CHANGED) { - img->flags &= (~(BITMAP_FLAG_CHANGED)); + if (bitmap_is_dirty(img)) { + bitmap_set_dirty(img, FALSE); nvgUpdateImage(canvas->vg, i, img_data); } bitmap_unlock_buffer(img); diff --git a/src/vgcanvas/vgcanvas_nanovg_plus.inc b/src/vgcanvas/vgcanvas_nanovg_plus.inc index 89589842f0..38f66bbd34 100644 --- a/src/vgcanvas/vgcanvas_nanovg_plus.inc +++ b/src/vgcanvas/vgcanvas_nanovg_plus.inc @@ -327,8 +327,8 @@ static int vgcanvas_nanovg_plus_ensure_image(vgcanvas_nanovg_plus_t* canvas, bit if (result == RET_OK) { i = ((vgcanvas_nanovg_plus_gl_texture_t*)specific)->image_id; - if (img->flags & BITMAP_FLAG_CHANGED) { - img->flags &= (~(BITMAP_FLAG_CHANGED)); + if (bitmap_is_dirty(img)) { + bitmap_set_dirty(img, FALSE); nvgp_update_image_rgba(canvas->vg, i, img_data); } bitmap_unlock_buffer(img); diff --git a/tests/bitmap_test.cc b/tests/bitmap_test.cc index 74b5ce9752..e1d924ecb2 100644 --- a/tests/bitmap_test.cc +++ b/tests/bitmap_test.cc @@ -10,7 +10,10 @@ TEST(Bitmap, basic) { uint8_t* bdata = bitmap_lock_buffer_for_write(b); ASSERT_EQ(((intptr_t)(bdata)) % BITMAP_ALIGN_SIZE, (intptr_t)0); ASSERT_EQ(bitmap_get_line_length(b), b->w * 4u); + ASSERT_EQ(bitmap_is_dirty(b), TRUE); bitmap_unlock_buffer(b); + ASSERT_EQ(bitmap_is_dirty(b), FALSE); + bitmap_destroy(b); }