Merge frames rather than dropping them when encoder is too slow

pull/31/head
Andri Yngvason 2020-04-04 21:03:49 +00:00
parent 238c196e6b
commit 6e521a07a0
1 changed files with 24 additions and 14 deletions

View File

@ -110,7 +110,12 @@ static struct nvnc_fb* get_current_fb(struct wayvnc* self)
return self->fb[self->fb_index]; return self->fb[self->fb_index];
} }
static void swap_fds(struct wayvnc* self) static struct nvnc_fb* get_last_fb(struct wayvnc* self)
{
return self->fb[!self->fb_index];
}
static void swap_fbs(struct wayvnc* self)
{ {
self->fb_index ^= 1; self->fb_index ^= 1;
} }
@ -496,19 +501,16 @@ static void on_damage_check_done(struct pixman_region16* damage, void* userdata)
struct nvnc_fb* fb = get_current_fb(self); struct nvnc_fb* fb = get_current_fb(self);
uint32_t* addr = nvnc_fb_get_addr(fb); uint32_t* addr = nvnc_fb_get_addr(fb);
uint32_t fb_width = nvnc_fb_get_width(fb); uint32_t fb_width = nvnc_fb_get_width(fb);
uint32_t fb_height = nvnc_fb_get_height(fb);
renderer_read_frame(&self->renderer, addr + y * fb_width, y, renderer_read_frame(&self->renderer, addr + y * fb_width, y,
damage_height); damage_height);
if (damage_height != fb_height) nvnc_fb_set_flags(fb, nvnc_fb_get_flags(fb) | NVNC_FB_PARTIAL);
nvnc_fb_set_flags(fb, nvnc_fb_get_flags(fb) |
NVNC_FB_PARTIAL);
nvnc_fb_unlock(fb); nvnc_fb_unlock(fb);
nvnc_feed_frame(self->nvnc, fb, damage); nvnc_feed_frame(self->nvnc, fb, damage);
swap_fds(self); swap_fbs(self);
} else { } else {
nvnc_fb_unlock(get_current_fb(self)); nvnc_fb_unlock(get_current_fb(self));
} }
@ -539,20 +541,28 @@ void wayvnc_process_frame(struct wayvnc* self)
} }
/* Check if frame is still in use. This can happen when encoding is too /* Check if frame is still in use. This can happen when encoding is too
* slow to keep up with frames being fed to it. When this happens the * slow to keep up with frames being fed to it.
* user can choose to do one of three things: *
* - Grow the swap chain * We'll just add to the frame that was added last if Neat VNC is busy.
* - Remove the frame from the swap chain and add a new one
* - Drop the frame. This is what we'll be doing here.
* *
* TODO: Damage hints are not being used now, but if they will be used * TODO: Damage hints are not being used now, but if they will be used
* then this breaks things. * then this breaks things.
*/ */
if (!nvnc_fb_lock(fb)) { if (!nvnc_fb_lock(fb)) {
log_debug("nvnc_fb(%p) still in use. Dropping frame.\n", fb); log_debug("nvnc_fb %d still in use. Merging frame.\n",
self->fb_index);
struct nvnc_fb* last_fb = get_last_fb(self);
if (!nvnc_fb_lock(last_fb)) {
log_error("Whole swap chain locked. Dropping frame.\n");
goto done; goto done;
} }
swap_fbs(self);
fb = get_current_fb(self);
assert(fb == last_fb);
}
frame_capture_render(self->capture_backend, &self->renderer, fb); frame_capture_render(self->capture_backend, &self->renderer, fb);
if (!self->please_send_full_frame_next && !is_first_frame) { if (!self->please_send_full_frame_next && !is_first_frame) {
@ -593,7 +603,7 @@ void wayvnc_process_frame(struct wayvnc* self)
struct pixman_region16 damage; struct pixman_region16 damage;
pixman_region_init_rect(&damage, 0, 0, width, height); pixman_region_init_rect(&damage, 0, 0, width, height);
nvnc_feed_frame(self->nvnc, fb, &damage); nvnc_feed_frame(self->nvnc, fb, &damage);
swap_fds(self); swap_fbs(self);
pixman_region_fini(&damage); pixman_region_fini(&damage);
done: done: