Don't show partial frames to new clients
parent
f45f90ed9b
commit
8fc5c18b28
|
@ -70,6 +70,7 @@ struct nvnc_client {
|
||||||
struct pixman_region16 damage;
|
struct pixman_region16 damage;
|
||||||
int n_pending_requests;
|
int n_pending_requests;
|
||||||
bool is_updating;
|
bool is_updating;
|
||||||
|
bool needs_whole_frame;
|
||||||
nvnc_client_fn cleanup_fn;
|
nvnc_client_fn cleanup_fn;
|
||||||
z_stream z_stream;
|
z_stream z_stream;
|
||||||
struct tight_encoder tight_encoder;
|
struct tight_encoder tight_encoder;
|
||||||
|
|
|
@ -4,10 +4,13 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
|
|
||||||
|
#include "neatvnc.h"
|
||||||
|
|
||||||
struct nvnc_fb {
|
struct nvnc_fb {
|
||||||
int ref;
|
int ref;
|
||||||
void* addr;
|
void* addr;
|
||||||
atomic_bool is_locked;
|
atomic_bool is_locked;
|
||||||
|
enum nvnc_fb_flags flags;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
|
|
|
@ -32,6 +32,10 @@ enum nvnc_button_mask {
|
||||||
NVNC_SCROLL_DOWN = 1 << 4,
|
NVNC_SCROLL_DOWN = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum nvnc_fb_flags {
|
||||||
|
NVNC_FB_PARTIAL = 1 << 0, // The buffer contains only the damaged region
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*nvnc_key_fn)(struct nvnc_client*, uint32_t keysym,
|
typedef void (*nvnc_key_fn)(struct nvnc_client*, uint32_t keysym,
|
||||||
bool is_pressed);
|
bool is_pressed);
|
||||||
typedef void (*nvnc_pointer_fn)(struct nvnc_client*, uint16_t x, uint16_t y,
|
typedef void (*nvnc_pointer_fn)(struct nvnc_client*, uint16_t x, uint16_t y,
|
||||||
|
@ -76,6 +80,9 @@ void nvnc_fb_unref(struct nvnc_fb* fb);
|
||||||
bool nvnc_fb_lock(struct nvnc_fb*);
|
bool nvnc_fb_lock(struct nvnc_fb*);
|
||||||
void nvnc_fb_unlock(struct nvnc_fb*);
|
void nvnc_fb_unlock(struct nvnc_fb*);
|
||||||
|
|
||||||
|
enum nvnc_fb_flags nvnc_fb_get_flags(const struct nvnc_fb*);
|
||||||
|
void nvnc_fb_set_flags(struct nvnc_fb*, enum nvnc_fb_flags);
|
||||||
|
|
||||||
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);
|
||||||
|
|
12
src/fb.c
12
src/fb.c
|
@ -53,6 +53,18 @@ void nvnc_fb_unlock(struct nvnc_fb* fb)
|
||||||
fb->is_locked = false;
|
fb->is_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT
|
||||||
|
enum nvnc_fb_flags nvnc_fb_get_flags(const struct nvnc_fb* fb)
|
||||||
|
{
|
||||||
|
return fb->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT
|
||||||
|
void nvnc_fb_set_flags(struct nvnc_fb* fb, enum nvnc_fb_flags flags)
|
||||||
|
{
|
||||||
|
fb->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT
|
EXPORT
|
||||||
void* nvnc_fb_get_addr(const struct nvnc_fb* fb)
|
void* nvnc_fb_get_addr(const struct nvnc_fb* fb)
|
||||||
{
|
{
|
||||||
|
|
20
src/server.c
20
src/server.c
|
@ -474,13 +474,23 @@ 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))
|
struct nvnc_fb* fb = client->server->frame;
|
||||||
|
|
||||||
|
if (!nvnc_fb_lock(fb))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
client->is_updating = true;
|
if (client->needs_whole_frame && (fb->flags & NVNC_FB_PARTIAL))
|
||||||
|
goto abort;
|
||||||
|
|
||||||
|
client->is_updating = true;
|
||||||
if (schedule_client_update_fb(client) < 0)
|
if (schedule_client_update_fb(client) < 0)
|
||||||
nvnc_fb_unlock(client->server->frame);
|
goto abort;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
abort:
|
||||||
|
nvnc_fb_unlock(fb);
|
||||||
|
client->is_updating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int on_client_fb_update_request(struct nvnc_client* client)
|
static int on_client_fb_update_request(struct nvnc_client* client)
|
||||||
|
@ -500,6 +510,9 @@ static int on_client_fb_update_request(struct nvnc_client* client)
|
||||||
int width = ntohs(msg->width);
|
int width = ntohs(msg->width);
|
||||||
int height = ntohs(msg->height);
|
int height = ntohs(msg->height);
|
||||||
|
|
||||||
|
if (!incremental)
|
||||||
|
client->needs_whole_frame = true;
|
||||||
|
|
||||||
client->n_pending_requests++;
|
client->n_pending_requests++;
|
||||||
|
|
||||||
/* Note: The region sent from the client is ignored for incremental
|
/* Note: The region sent from the client is ignored for incremental
|
||||||
|
@ -911,6 +924,7 @@ void on_client_update_fb_done(void* work)
|
||||||
stream_send(client->net_stream, payload, on_write_frame_done,
|
stream_send(client->net_stream, payload, on_write_frame_done,
|
||||||
client);
|
client);
|
||||||
DTRACE_PROBE1(neatvnc, send_fb_done, client);
|
DTRACE_PROBE1(neatvnc, send_fb_done, client);
|
||||||
|
client->needs_whole_frame = false;
|
||||||
} else {
|
} else {
|
||||||
client->is_updating = false;
|
client->is_updating = false;
|
||||||
vec_destroy(frame);
|
vec_destroy(frame);
|
||||||
|
|
Loading…
Reference in New Issue