Fix GIF emoji flickering by merging lock scopes in SetEmotion() (#1880)
* Initial plan * Fix GIF emoji flickering by merging lock scopes in SetEmotion() Remove the separate first lock scope that hid emoji_image_ before destroying gif_controller_ (added by PR #1848). Instead, move the gif_controller_ cleanup into each lock scope where new content is set, so destruction and creation happen atomically. This prevents both the original race condition crash AND the visible flickering. Co-authored-by: 78 <4488133+78@users.noreply.github.com> Agent-Logs-Url: https://github.com/78/xiaozhi-esp32/sessions/2dd0ff3a-4556-47a6-8d40-a30e18c01923 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: 78 <4488133+78@users.noreply.github.com>
This commit is contained in:
@ -1075,18 +1075,6 @@ void LcdDisplay::SetEmotion(const char* emotion) {
|
||||
if (!setup_ui_called_) {
|
||||
ESP_LOGW(TAG, "SetEmotion('%s') called before SetupUI() - emotion will not be displayed!", emotion);
|
||||
}
|
||||
// Stop any running GIF animation
|
||||
if (gif_controller_) {
|
||||
DisplayLockGuard lock(this);
|
||||
gif_controller_->Stop();
|
||||
// Hide image before destroying GIF controller to prevent LVGL from
|
||||
// accessing freed image data during rendering between lock scopes
|
||||
if (emoji_image_) {
|
||||
lv_obj_add_flag(emoji_image_, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
gif_controller_.reset();
|
||||
}
|
||||
|
||||
if (emoji_image_ == nullptr) {
|
||||
if (setup_ui_called_) {
|
||||
ESP_LOGW(TAG, "SetEmotion('%s') failed: emoji_image_ is nullptr (SetupUI() was called but emoji image not created)", emotion);
|
||||
@ -1100,6 +1088,10 @@ void LcdDisplay::SetEmotion(const char* emotion) {
|
||||
const char* utf8 = font_awesome_get_utf8(emotion);
|
||||
if (utf8 != nullptr && emoji_label_ != nullptr) {
|
||||
DisplayLockGuard lock(this);
|
||||
if (gif_controller_) {
|
||||
gif_controller_->Stop();
|
||||
gif_controller_.reset();
|
||||
}
|
||||
lv_label_set_text(emoji_label_, utf8);
|
||||
lv_obj_add_flag(emoji_image_, LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_remove_flag(emoji_label_, LV_OBJ_FLAG_HIDDEN);
|
||||
@ -1108,6 +1100,12 @@ void LcdDisplay::SetEmotion(const char* emotion) {
|
||||
}
|
||||
|
||||
DisplayLockGuard lock(this);
|
||||
// Stop any running GIF animation in the same lock scope as setting new image
|
||||
// to prevent LVGL from accessing freed image data between operations
|
||||
if (gif_controller_) {
|
||||
gif_controller_->Stop();
|
||||
gif_controller_.reset();
|
||||
}
|
||||
if (image->IsGif()) {
|
||||
// Create new GIF controller
|
||||
gif_controller_ = std::make_unique<LvglGif>(image->image_dsc());
|
||||
|
||||
Reference in New Issue
Block a user