nvnc_fb: Add a mechanism for signaling that a frame is in use
parent
8c27878dd1
commit
f45f90ed9b
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
struct nvnc_fb {
|
struct nvnc_fb {
|
||||||
int ref;
|
int ref;
|
||||||
void* addr;
|
void* addr;
|
||||||
|
atomic_bool is_locked;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
|
|
|
@ -73,6 +73,9 @@ struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height,
|
||||||
void nvnc_fb_ref(struct nvnc_fb* fb);
|
void nvnc_fb_ref(struct nvnc_fb* fb);
|
||||||
void nvnc_fb_unref(struct nvnc_fb* fb);
|
void nvnc_fb_unref(struct nvnc_fb* fb);
|
||||||
|
|
||||||
|
bool nvnc_fb_lock(struct nvnc_fb*);
|
||||||
|
void nvnc_fb_unlock(struct nvnc_fb*);
|
||||||
|
|
||||||
void* nvnc_fb_get_addr(const struct nvnc_fb* fb);
|
void* nvnc_fb_get_addr(const struct nvnc_fb* fb);
|
||||||
uint16_t nvnc_fb_get_width(const struct nvnc_fb* fb);
|
uint16_t nvnc_fb_get_width(const struct nvnc_fb* fb);
|
||||||
uint16_t nvnc_fb_get_height(const struct nvnc_fb* fb);
|
uint16_t nvnc_fb_get_height(const struct nvnc_fb* fb);
|
||||||
|
|
14
src/fb.c
14
src/fb.c
|
@ -4,6 +4,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
#define UDIV_UP(a, b) (((a) + (b) - 1) / (b))
|
#define UDIV_UP(a, b) (((a) + (b) - 1) / (b))
|
||||||
#define ALIGN_UP(n, a) (UDIV_UP(n, a) * a)
|
#define ALIGN_UP(n, a) (UDIV_UP(n, a) * a)
|
||||||
|
@ -39,6 +40,19 @@ struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height,
|
||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT
|
||||||
|
bool nvnc_fb_lock(struct nvnc_fb* fb)
|
||||||
|
{
|
||||||
|
bool expected = false;
|
||||||
|
return atomic_compare_exchange_strong(&fb->is_locked, &expected, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT
|
||||||
|
void nvnc_fb_unlock(struct nvnc_fb* fb)
|
||||||
|
{
|
||||||
|
fb->is_locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT
|
EXPORT
|
||||||
void* nvnc_fb_get_addr(const struct nvnc_fb* fb)
|
void* nvnc_fb_get_addr(const struct nvnc_fb* fb)
|
||||||
{
|
{
|
||||||
|
|
13
src/server.c
13
src/server.c
|
@ -474,9 +474,13 @@ 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;
|
||||||
|
|
||||||
|
if (!nvnc_fb_lock(client->server->frame))
|
||||||
|
return;
|
||||||
|
|
||||||
client->is_updating = true;
|
client->is_updating = true;
|
||||||
|
|
||||||
schedule_client_update_fb(client);
|
if (schedule_client_update_fb(client) < 0)
|
||||||
|
nvnc_fb_unlock(client->server->frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_client_fb_update_request(struct nvnc_client* client)
|
static int on_client_fb_update_request(struct nvnc_client* client)
|
||||||
|
@ -855,7 +859,7 @@ void do_client_update_fb(void* work)
|
||||||
{
|
{
|
||||||
struct fb_update_work* update = aml_get_userdata(work);
|
struct fb_update_work* update = aml_get_userdata(work);
|
||||||
struct nvnc_client* client = update->client;
|
struct nvnc_client* client = update->client;
|
||||||
const struct nvnc_fb* fb = update->fb;
|
struct nvnc_fb* fb = update->fb;
|
||||||
|
|
||||||
enum rfb_encodings encoding = choose_frame_encoding(client);
|
enum rfb_encodings encoding = choose_frame_encoding(client);
|
||||||
if (encoding == -1) {
|
if (encoding == -1) {
|
||||||
|
@ -896,8 +900,10 @@ void on_client_update_fb_done(void* work)
|
||||||
struct nvnc_client* client = update->client;
|
struct nvnc_client* client = update->client;
|
||||||
struct vec* frame = &update->frame;
|
struct vec* frame = &update->frame;
|
||||||
|
|
||||||
client_ref(client);
|
nvnc_fb_unlock(update->fb);
|
||||||
|
nvnc_fb_unref(update->fb);
|
||||||
|
|
||||||
|
client_ref(client);
|
||||||
|
|
||||||
if (client->net_stream->state != STREAM_STATE_CLOSED) {
|
if (client->net_stream->state != STREAM_STATE_CLOSED) {
|
||||||
struct rcbuf* payload = rcbuf_new(frame->data, frame->len);
|
struct rcbuf* payload = rcbuf_new(frame->data, frame->len);
|
||||||
|
@ -913,7 +919,6 @@ void on_client_update_fb_done(void* work)
|
||||||
|
|
||||||
client->n_pending_requests--;
|
client->n_pending_requests--;
|
||||||
process_fb_update_requests(client);
|
process_fb_update_requests(client);
|
||||||
nvnc_fb_unref(update->fb);
|
|
||||||
|
|
||||||
DTRACE_PROBE1(neatvnc, update_fb_done, client);
|
DTRACE_PROBE1(neatvnc, update_fb_done, client);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue