mirror of
https://github.com/artizirk/wdisplays.git
synced 2026-10-05 05:35:42 +03:00
Recycle failed capture buffers, release when off
This commit is contained in:
@@ -183,6 +183,7 @@ static void update_tick_callback(struct wd_state *state) {
|
||||
if (state->capture_timeout != -1) {
|
||||
g_source_remove(state->capture_timeout);
|
||||
state->capture_timeout = -1;
|
||||
wd_capture_release(state);
|
||||
}
|
||||
} else if (state->capture_timeout == -1) {
|
||||
state->capture_due = true;
|
||||
|
||||
+31
-8
@@ -252,6 +252,21 @@ static void capture_flags(void *data,
|
||||
frame->y_invert = !!(flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT);
|
||||
}
|
||||
|
||||
static void keep_as_spare(struct wd_frame *frame) {
|
||||
struct wd_output *output = frame->output;
|
||||
if (output->spare != NULL) {
|
||||
wd_frame_destroy(frame);
|
||||
return;
|
||||
}
|
||||
if (frame->wlr_frame != NULL) {
|
||||
zwlr_screencopy_frame_v1_destroy(frame->wlr_frame);
|
||||
frame->wlr_frame = NULL;
|
||||
}
|
||||
wl_list_remove(&frame->link);
|
||||
wl_list_init(&frame->link);
|
||||
output->spare = frame;
|
||||
}
|
||||
|
||||
static void capture_ready(void *data,
|
||||
struct zwlr_screencopy_frame_v1 *wlr_frame,
|
||||
uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec) {
|
||||
@@ -268,13 +283,7 @@ static void capture_ready(void *data,
|
||||
struct wd_frame *frame_iter, *frame_tmp;
|
||||
wl_list_for_each_safe(frame_iter, frame_tmp, &output->frames, link) {
|
||||
if (frame != frame_iter) {
|
||||
if (output->spare == NULL) {
|
||||
wl_list_remove(&frame_iter->link);
|
||||
wl_list_init(&frame_iter->link);
|
||||
output->spare = frame_iter;
|
||||
} else {
|
||||
wd_frame_destroy(frame_iter);
|
||||
}
|
||||
keep_as_spare(frame_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,7 +291,7 @@ static void capture_ready(void *data,
|
||||
static void capture_failed(void *data,
|
||||
struct zwlr_screencopy_frame_v1 *wlr_frame) {
|
||||
struct wd_frame *frame = data;
|
||||
wd_frame_destroy(frame);
|
||||
keep_as_spare(frame);
|
||||
}
|
||||
|
||||
struct zwlr_screencopy_frame_v1_listener capture_listener = {
|
||||
@@ -330,6 +339,20 @@ void wd_capture_frame(struct wd_state *state) {
|
||||
}
|
||||
}
|
||||
|
||||
void wd_capture_release(struct wd_state *state) {
|
||||
struct wd_output *output;
|
||||
wl_list_for_each(output, &state->outputs, link) {
|
||||
struct wd_frame *frame, *frame_tmp;
|
||||
wl_list_for_each_safe(frame, frame_tmp, &output->frames, link) {
|
||||
wd_frame_destroy(frame);
|
||||
}
|
||||
if (output->spare != NULL) {
|
||||
wd_frame_destroy(output->spare);
|
||||
output->spare = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wd_output_destroy(struct wd_output *output) {
|
||||
struct wd_frame *frame, *frame_tmp;
|
||||
wl_list_for_each_safe(frame, frame_tmp, &output->frames, link) {
|
||||
|
||||
@@ -285,6 +285,11 @@ void wd_capture_frame(struct wd_state *state);
|
||||
*/
|
||||
void wd_capture_wait(struct wd_state *state, struct wl_display *display);
|
||||
|
||||
/*
|
||||
* Frees all captured frames and their buffers.
|
||||
*/
|
||||
void wd_capture_release(struct wd_state *state);
|
||||
|
||||
/*
|
||||
* Updates the UI stack of all heads. Does not update individual head forms.
|
||||
* Useful for when a display is plugged/unplugged and we want to add/remove
|
||||
|
||||
Reference in New Issue
Block a user