screencast: remove swap_buffer function

Dequeuing a new buffer imidiately creates a problem when the buffer is
destroid while renegotiation of a valid modifier because we can end up using
a buffer which was freed while waiting for the buffer_done event. Then
xdpw will segfault when requesting a copy with a nonexisting buffer. To fix
this we can just dequeue a buffer right before we need it. This makes
the fallback via on_process obsolete since we dequeue the buffer at the
lates possible time.
This commit is contained in:
columbarius 2022-04-24 11:35:19 +02:00
parent 657b9edad5
commit 2f32d17448
5 changed files with 1 additions and 36 deletions

View file

@ -9,7 +9,6 @@
void xdpw_pwr_dequeue_buffer(struct xdpw_screencast_instance *cast);
void xdpw_pwr_enqueue_buffer(struct xdpw_screencast_instance *cast);
void xdpw_pwr_swap_buffer(struct xdpw_screencast_instance *cast);
void pwr_update_stream_param(struct xdpw_screencast_instance *cast);
void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast);
void xdpw_pwr_stream_destroy(struct xdpw_screencast_instance *cast);

View file

@ -144,7 +144,6 @@ struct xdpw_screencast_instance {
bool with_cursor;
int err;
bool quit;
bool need_buffer;
enum buffer_type buffer_type;
// fps limit

View file

@ -111,18 +111,6 @@ static uint32_t build_formats(struct spa_pod_builder *b, struct xdpw_screencast_
return param_count;
}
static void pwr_handle_stream_on_process(void *data) {
logprint(TRACE, "pipewire: stream process");
struct xdpw_screencast_instance *cast = data;
if (cast->need_buffer) {
xdpw_pwr_dequeue_buffer(cast);
if (cast->current_frame.pw_buffer) {
cast->need_buffer = false;
}
}
}
static void pwr_handle_stream_state_changed(void *data,
enum pw_stream_state old, enum pw_stream_state state, const char *error) {
struct xdpw_screencast_instance *cast = data;
@ -270,7 +258,6 @@ static const struct pw_stream_events pwr_stream_events = {
.param_changed = pwr_handle_stream_param_changed,
.add_buffer = pwr_handle_stream_add_buffer,
.remove_buffer = pwr_handle_stream_remove_buffer,
.process = pwr_handle_stream_on_process,
};
void xdpw_pwr_dequeue_buffer(struct xdpw_screencast_instance *cast) {
@ -337,24 +324,6 @@ done:
cast->current_frame.pw_buffer = NULL;
}
void xdpw_pwr_swap_buffer(struct xdpw_screencast_instance *cast) {
logprint(TRACE, "pipewire: swapping buffers");
if (!cast->current_frame.pw_buffer) {
goto dequeue_buffer;
}
xdpw_pwr_enqueue_buffer(cast);
dequeue_buffer:
assert(!cast->current_frame.pw_buffer);
cast->need_buffer = false;
xdpw_pwr_dequeue_buffer(cast);
if (!cast->current_frame.pw_buffer) {
cast->need_buffer = true;
}
}
void pwr_update_stream_param(struct xdpw_screencast_instance *cast) {
logprint(TRACE, "pipewire: stream update parameters");
struct pw_stream *stream = cast->stream;

View file

@ -70,7 +70,6 @@ void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx,
cast->with_cursor = with_cursor;
cast->refcount = 1;
cast->node_id = SPA_ID_INVALID;
cast->need_buffer = false;
wl_list_init(&cast->buffer_list);
logprint(INFO, "xdpw: screencast instance %p has %d references", cast, cast->refcount);
wl_list_insert(&ctx->screencast_instances, &cast->link);

View file

@ -51,7 +51,7 @@ void xdpw_wlr_frame_finish(struct xdpw_screencast_instance *cast) {
}
if (cast->frame_state == XDPW_FRAME_STATE_SUCCESS) {
xdpw_pwr_swap_buffer(cast);
xdpw_pwr_enqueue_buffer(cast);
uint64_t delay_ns = fps_limit_measure_end(&cast->fps_limit, cast->framerate);
if (delay_ns > 0) {
xdpw_add_timer(cast->ctx->state, delay_ns,
@ -137,7 +137,6 @@ static void wlr_frame_buffer_done(void *data,
xdpw_pwr_dequeue_buffer(cast);
}
cast->need_buffer = false;
if (!cast->current_frame.xdpw_buffer) {
logprint(WARN, "wlroots: no current buffer");
xdpw_wlr_frame_finish(cast);