Skip to content

Commit 1323768

Browse files
aki1770-delclaude
andcommitted
fix: repair three memory issues contributing to animated image leak (#429)
1. elinux_window.h: Fix display refresh rate reported to Flutter engine. frame_rate_ is in milliHz (e.g. 60000 for a 60 Hz display); dividing 1000000 by it yielded ~16 instead of the required 60 Hz. FlutterEngineDisplay.refresh_rate expects frames-per-second. Correct formula is frame_rate_ / 1000.0. 2. elinux_window_wayland.cc: Add missing wl_callback_destroy() when wp_presentation is available and the done callback returns early. Without this the client-side wl_proxy object was leaked every time a new surface frame fires while wp_presentation is active. 3. elinux_egl_surface.cc: Guard PopulateExistingDamage against orphaned malloc. If the Flutter engine ever calls populate without a subsequent present_with_info (e.g. at shutdown or on a skipped frame), the previously allocated FlutterRect buffer is now freed before the new allocation rather than being silently overwritten. Fixes: #429 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1653fa6 commit 1323768

File tree

3 files changed

+11
-1
lines changed

3 files changed

+11
-1
lines changed

src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,15 @@ void ELinuxEGLSurface::PopulateExistingDamage(const intptr_t fbo_id,
166166

167167
existing_damage->num_rects = 1;
168168

169+
// Free any previous allocation for this FBO (defensive: guards against the
170+
// engine calling populate without a subsequent present_with_info, which would
171+
// otherwise orphan the malloc'd buffer).
172+
auto it = existing_damage_map_.find(fbo_id);
173+
if (it != existing_damage_map_.end() && it->second != nullptr) {
174+
free(it->second);
175+
it->second = nullptr;
176+
}
177+
169178
// Allocate the array of rectangles for the existing damage.
170179
existing_damage_map_[fbo_id] = static_cast<FlutterRect*>(
171180
malloc(sizeof(FlutterRect) * existing_damage->num_rects));

src/flutter/shell/platform/linux_embedded/window/elinux_window.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ELinuxWindow {
4545
void NotifyDisplayInfoUpdates() const {
4646
if (binding_handler_delegate_) {
4747
binding_handler_delegate_->UpdateDisplayInfo(
48-
std::trunc(1000000.0 / frame_rate_), GetCurrentWidth(),
48+
static_cast<double>(frame_rate_) / 1000.0, GetCurrentWidth(),
4949
GetCurrentHeight(), current_scale_);
5050
}
5151
}

src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ const wl_callback_listener ELinuxWindowWayland::kWlSurfaceFrameListener = {
269269
// by all compositors. This path is for when it wasn't supported.
270270
auto self = reinterpret_cast<ELinuxWindowWayland*>(data);
271271
if (self->wp_presentation_clk_id_ != UINT32_MAX) {
272+
wl_callback_destroy(wl_callback);
272273
return;
273274
}
274275

0 commit comments

Comments
 (0)