server: Refactor schedule_client_update_fb

tight-scheduling-fix
Andri Yngvason 2020-09-26 21:40:11 +00:00
parent 24a6e29cf2
commit 7e2b4fef8c
1 changed files with 23 additions and 16 deletions

View File

@ -69,7 +69,9 @@ struct fb_update_work {
struct nvnc_fb* fb; struct nvnc_fb* fb;
}; };
int schedule_client_update_fb(struct nvnc_client* client); int schedule_client_update_fb(struct nvnc_client* client,
struct pixman_region16* damage);
static int send_desktop_resize(struct nvnc_client* client, struct nvnc_fb* fb);
#if defined(GIT_VERSION) #if defined(GIT_VERSION)
EXPORT const char nvnc_version[] = GIT_VERSION; EXPORT const char nvnc_version[] = GIT_VERSION;
@ -490,7 +492,9 @@ static int on_client_set_encodings(struct nvnc_client* client)
static void process_fb_update_requests(struct nvnc_client* client) static void process_fb_update_requests(struct nvnc_client* client)
{ {
if (!client->server->display || !client->server->display->buffer) struct nvnc* server = client->server;
if (!server->display || !server->display->buffer)
return; return;
if (client->net_stream->state == STREAM_STATE_CLOSED) if (client->net_stream->state == STREAM_STATE_CLOSED)
@ -502,8 +506,21 @@ static void process_fb_update_requests(struct nvnc_client* client)
if (client->is_updating || client->n_pending_requests == 0) if (client->is_updating || client->n_pending_requests == 0)
return; return;
struct nvnc_fb* fb = client->server->display->buffer;
assert(fb);
if (fb->width != client->known_width
|| fb->height != client->known_height)
send_desktop_resize(client, fb);
DTRACE_PROBE1(neatvnc, update_fb_start, client);
/* The client's damage is exchanged for an empty one */
struct pixman_region16 damage = client->damage;
pixman_region_init(&client->damage);
client->is_updating = true; client->is_updating = true;
if (schedule_client_update_fb(client) < 0) if (schedule_client_update_fb(client, &damage) < 0)
client->is_updating = false; client->is_updating = false;
} }
@ -1180,13 +1197,12 @@ static int send_desktop_resize(struct nvnc_client* client, struct nvnc_fb* fb)
return 0; return 0;
} }
int schedule_client_update_fb(struct nvnc_client* client) int schedule_client_update_fb(struct nvnc_client* client,
struct pixman_region16* damage)
{ {
struct nvnc_fb* fb = client->server->display->buffer; struct nvnc_fb* fb = client->server->display->buffer;
assert(fb); assert(fb);
DTRACE_PROBE1(neatvnc, update_fb_start, client);
struct fb_update_work* work = calloc(1, sizeof(*work)); struct fb_update_work* work = calloc(1, sizeof(*work));
if (!work) if (!work)
return -1; return -1;
@ -1196,15 +1212,7 @@ int schedule_client_update_fb(struct nvnc_client* client)
work->client = client; work->client = client;
work->fb = fb; work->fb = fb;
work->region = *damage;
if (fb->width != client->known_width
|| fb->height != client->known_height)
if (send_desktop_resize(client, fb) < 0)
goto resize_failure;
/* The client's damage is exchanged for an empty one */
work->region = client->damage;
pixman_region_init(&client->damage);
int rc = vec_init(&work->frame, fb->width * fb->height * 3 / 2); int rc = vec_init(&work->frame, fb->width * fb->height * 3 / 2);
if (rc < 0) if (rc < 0)
@ -1237,7 +1245,6 @@ oom_failure:
vec_destroy(&work->frame); vec_destroy(&work->frame);
vec_failure: vec_failure:
pixfmt_failure: pixfmt_failure:
resize_failure:
free(work); free(work);
return -1; return -1;
} }