Skip to content

Commit 04f2d68

Browse files
committed
stream-chooser: Fix gbm bo fd leak
1 parent 415b9e1 commit 04f2d68

2 files changed

Lines changed: 32 additions & 38 deletions

File tree

src/stream-chooser/toplevelwidget.cpp

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,24 @@ static void frame_handle_presentation_time(void*,
123123
{}
124124

125125
static void frame_handle_ready(void *data,
126-
struct ext_image_copy_capture_frame_v1*)
126+
struct ext_image_copy_capture_frame_v1 *frame)
127127
{
128128
WayfireChooserTopLevel *toplevel = (WayfireChooserTopLevel*)data;
129+
129130
toplevel->buffer_ready();
130-
toplevel->frame_in_flight = false;
131+
132+
ext_image_copy_capture_frame_v1_destroy(frame);
133+
toplevel->frame = nullptr;
131134
}
132135

133136
static void frame_handle_failed(void *data,
134-
struct ext_image_copy_capture_frame_v1 *handle,
137+
struct ext_image_copy_capture_frame_v1 *frame,
135138
uint32_t reason)
136139
{
137140
WayfireChooserTopLevel *toplevel = (WayfireChooserTopLevel*)data;
138-
std::cerr << "Failed to copy frame because reason: " << reason << std::endl;
139-
ext_image_copy_capture_frame_v1_destroy(handle);
141+
142+
ext_image_copy_capture_frame_v1_destroy(frame);
140143
toplevel->frame = nullptr;
141-
toplevel->frame_in_flight = false;
142144
}
143145

144146
static const struct ext_image_copy_capture_frame_v1_listener frame_listener = {
@@ -149,36 +151,31 @@ static const struct ext_image_copy_capture_frame_v1_listener frame_listener = {
149151
.failed = frame_handle_failed,
150152
};
151153

152-
static void dmabuf_created(void *data, struct zwp_linux_buffer_params_v1*,
153-
struct wl_buffer *wl_buffer)
154-
{
155-
auto toplevel = (WayfireChooserTopLevel*)data;
156-
toplevel->buffer->buffer = wl_buffer;
157-
}
158-
159-
static void dmabuf_failed(void*, struct zwp_linux_buffer_params_v1*)
160-
{
161-
std::cerr << "Failed to create dmabuf" << std::endl;
162-
}
163-
164-
static const struct zwp_linux_buffer_params_v1_listener params_listener = {
165-
.created = dmabuf_created,
166-
.failed = dmabuf_failed,
167-
};
168-
169154
static void frame_handle_linux_dmabuf(uint32_t width, uint32_t height, WayfireChooserTopLevel *toplevel)
170155
{
171156
auto format = (toplevel->current_buffer_format == WL_SHM_FORMAT_XRGB8888) ?
172157
GBM_FORMAT_XRGB8888 : GBM_FORMAT_ARGB8888;
173158

174159
auto buffer = toplevel->buffer;
175160

161+
if (buffer->gbm_fd > 0)
162+
{
163+
close(buffer->gbm_fd);
164+
buffer->gbm_fd = -1;
165+
}
166+
176167
if (buffer->bo)
177168
{
178169
gbm_bo_destroy(buffer->bo);
179170
buffer->bo = nullptr;
180171
}
181172

173+
if (buffer->buffer)
174+
{
175+
wl_buffer_destroy(buffer->buffer);
176+
buffer->buffer = nullptr;
177+
}
178+
182179
if (buffer->params)
183180
{
184181
zwp_linux_buffer_params_v1_destroy(buffer->params);
@@ -209,14 +206,14 @@ static void frame_handle_linux_dmabuf(uint32_t width, uint32_t height, WayfireCh
209206
buffer->params = zwp_linux_dmabuf_v1_create_params(WayfireStreamChooserApp::getInstance().dmabuf);
210207

211208
uint64_t mod = gbm_bo_get_modifier(buffer->bo);
209+
buffer->gbm_fd = gbm_bo_get_fd(buffer->bo);
212210
zwp_linux_buffer_params_v1_add(buffer->params,
213-
gbm_bo_get_fd(buffer->bo), 0,
211+
buffer->gbm_fd, 0,
214212
gbm_bo_get_offset(buffer->bo, 0),
215213
gbm_bo_get_stride(buffer->bo),
216214
mod >> 32, mod & 0xffffffff);
217215

218-
zwp_linux_buffer_params_v1_add_listener(buffer->params, &params_listener, toplevel);
219-
zwp_linux_buffer_params_v1_create(buffer->params, w, h, format, 0);
216+
buffer->buffer = zwp_linux_buffer_params_v1_create_immed(buffer->params, w, h, format, 0);
220217
}
221218

222219
void WayfireChooserTopLevel::start_toplevel_source_ssession()
@@ -265,11 +262,6 @@ void WayfireChooserTopLevel::frame_request()
265262
return;
266263
}
267264

268-
if (frame_in_flight)
269-
{
270-
return;
271-
}
272-
273265
if (frame)
274266
{
275267
ext_image_copy_capture_frame_v1_destroy(frame);
@@ -283,7 +275,6 @@ void WayfireChooserTopLevel::frame_request()
283275
ext_image_copy_capture_frame_v1_attach_buffer(buffer->frame, buffer->buffer);
284276
ext_image_copy_capture_frame_v1_damage_buffer(buffer->frame, 0, 0, buffer->width, buffer->height);
285277
ext_image_copy_capture_frame_v1_capture(buffer->frame);
286-
frame_in_flight = true;
287278
}
288279

289280
void WayfireChooserTopLevel::buffer_ready()
@@ -309,10 +300,10 @@ void WayfireChooserTopLevel::buffer_ready()
309300
std::shared_ptr<Glib::Bytes> bytes = 0;
310301
size_t size = stride * buffer->height;
311302
bytes = Glib::Bytes::create((unsigned char*)data, size);
303+
gbm_bo_unmap(buffer->bo, map_data);
312304

313305
if (!bytes)
314306
{
315-
gbm_bo_unmap(buffer->bo, map_data);
316307
return;
317308
}
318309

@@ -326,8 +317,6 @@ void WayfireChooserTopLevel::buffer_ready()
326317
auto texture = builder->build();
327318

328319
screenshot.set_paintable(texture);
329-
330-
gbm_bo_unmap(buffer->bo, map_data);
331320
}
332321

333322
void WayfireChooserTopLevel::stream()
@@ -486,16 +475,21 @@ WayfireChooserTopLevel::~WayfireChooserTopLevel()
486475
ext_image_copy_capture_session_v1_destroy(recording_session);
487476
}
488477

489-
if (buffer->buffer)
478+
if (buffer->gbm_fd > 0)
490479
{
491-
wl_buffer_destroy(buffer->buffer);
480+
close(buffer->gbm_fd);
492481
}
493482

494483
if (buffer->bo)
495484
{
496485
gbm_bo_destroy(buffer->bo);
497486
}
498487

488+
if (buffer->buffer)
489+
{
490+
wl_buffer_destroy(buffer->buffer);
491+
}
492+
499493
if (buffer->params)
500494
{
501495
zwp_linux_buffer_params_v1_destroy(buffer->params);

src/stream-chooser/toplevelwidget.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct toplevel_buffer
1414
int height = 0;
1515
int stride = 0;
1616
gbm_bo *bo = nullptr;
17+
int gbm_fd = -1;
1718
wl_buffer *buffer = nullptr;
1819
zwp_linux_buffer_params_v1 *params = nullptr;
1920
ext_image_copy_capture_frame_v1 *frame = NULL;
@@ -47,7 +48,6 @@ class WayfireChooserTopLevel : public Gtk::Box
4748
ext_foreign_toplevel_handle_v1 *handle = nullptr;
4849
std::shared_ptr<toplevel_buffer> buffer = nullptr;
4950
ext_image_copy_capture_frame_v1 *frame = NULL;
50-
bool frame_in_flight = false;
5151
WayfireChooserTopLevel(ext_foreign_toplevel_handle_v1 *handle);
5252
~WayfireChooserTopLevel();
5353
void commit();

0 commit comments

Comments
 (0)