zrle: Keep the stream alive per connection

Otherwise the client doesn't want to play with the server.
tight-png
Andri Yngvason 2019-09-01 18:40:11 +00:00 committed by Andri Yngvason
parent 46dc074370
commit ff67e2fed3
6 changed files with 31 additions and 23 deletions

View File

@ -3,6 +3,7 @@
#include "util.h" #include "util.h"
#include "vec.h" #include "vec.h"
#include "neatvnc.h" #include "neatvnc.h"
#include "miniz.h"
#include <stdlib.h> #include <stdlib.h>
#include <libdrm/drm_fourcc.h> #include <libdrm/drm_fourcc.h>
@ -39,15 +40,21 @@ int run_benchmark(const char *image)
struct vec frame; struct vec frame;
vec_init(&frame, fb.width * fb.height * 3 / 2); vec_init(&frame, fb.width * fb.height * 3 / 2);
z_stream zs = { 0 };
deflateInit(&zs, Z_DEFAULT_COMPRESSION);
uint64_t start_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID); uint64_t start_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID);
rc = zrle_encode_frame(&frame, &pixfmt, fb.addr, &pixfmt, rc = zrle_encode_frame(&zs, &frame, &pixfmt, fb.addr, &pixfmt,
fb.width, fb.height, &region); fb.width, fb.height, &region);
uint64_t end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID); uint64_t end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID);
printf("Encoding %s took %"PRIu64" micro seconds\n", image, printf("Encoding %s took %"PRIu64" micro seconds\n", image,
end_time - start_time); end_time - start_time);
deflateEnd(&zs);
if (rc < 0) if (rc < 0)
goto failure; goto failure;

View File

@ -50,7 +50,7 @@ void on_pointer_event(struct nvnc_client *client, uint16_t x, uint16_t y,
struct pixman_region16 region; struct pixman_region16 region;
pixman_region_init_rect(&region, 0, 0, draw->fb.width, pixman_region_init_rect(&region, 0, 0, draw->fb.width,
draw->fb.height); draw->fb.height);
// pixman_region_init_rect(&region, x, y, 1, 1); pixman_region_intersect_rect(&region, &region, x, y, 1, 1);
nvnc_update_fb(server, &draw->fb, &region); nvnc_update_fb(server, &draw->fb, &region);
pixman_region_fini(&region); pixman_region_fini(&region);
} }

View File

@ -132,7 +132,6 @@ struct rfb_server_fb_update_msg {
uint8_t type; uint8_t type;
uint8_t padding; uint8_t padding;
uint16_t n_rects; uint16_t n_rects;
struct rfb_server_fb_rect rects[0];
} RFB_PACKED; } RFB_PACKED;
static inline int rfb_send_security_types(void *client) static inline int rfb_send_security_types(void *client)

View File

@ -4,6 +4,8 @@
#include <stdint.h> #include <stdint.h>
#include <unistd.h> #include <unistd.h>
#include "miniz.h"
struct rfb_pixel_format; struct rfb_pixel_format;
struct pixman_region16; struct pixman_region16;
struct vec; struct vec;
@ -14,7 +16,8 @@ void pixel32_to_cpixel(uint8_t *restrict dst,
const struct rfb_pixel_format* src_fmt, const struct rfb_pixel_format* src_fmt,
size_t bytes_per_cpixel, size_t len); size_t bytes_per_cpixel, size_t len);
int zrle_encode_frame(struct vec *dst, int zrle_encode_frame(z_stream *zs,
struct vec *dst,
const struct rfb_pixel_format *dst_fmt, const struct rfb_pixel_format *dst_fmt,
const uint8_t *src, const uint8_t *src,
const struct rfb_pixel_format *src_fmt, const struct rfb_pixel_format *src_fmt,

View File

@ -55,6 +55,7 @@ struct nvnc_client {
LIST_ENTRY(nvnc_client) link; LIST_ENTRY(nvnc_client) link;
struct pixman_region16 requested_region; struct pixman_region16 requested_region;
nvnc_client_fn cleanup_fn; nvnc_client_fn cleanup_fn;
z_stream z_stream;
size_t buffer_index; size_t buffer_index;
size_t buffer_len; size_t buffer_len;
uint8_t msg_buffer[MSG_BUFFER_SIZE]; uint8_t msg_buffer[MSG_BUFFER_SIZE];
@ -113,6 +114,8 @@ static void cleanup_client(uv_handle_t* handle)
if (fn) if (fn)
fn(client); fn(client);
deflateEnd(&client->z_stream);
LIST_REMOVE(client, link); LIST_REMOVE(client, link);
pixman_region_fini(&client->requested_region); pixman_region_fini(&client->requested_region);
free(client); free(client);
@ -655,6 +658,11 @@ static void on_connection(uv_stream_t *server_stream, int status)
client->server = server; client->server = server;
if (deflateInit(&client->z_stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
free(client);
return;
}
pixman_region_init(&client->requested_region); pixman_region_init(&client->requested_region);
uv_tcp_init(uv_default_loop(), &client->stream_handle); uv_tcp_init(uv_default_loop(), &client->stream_handle);
@ -771,8 +779,9 @@ int nvnc_update_fb(struct nvnc *self, const struct nvnc_fb *fb,
pixman_region_intersect(cregion, cregion, &region); pixman_region_intersect(cregion, cregion, &region);
zrle_encode_frame(&frame, &client->pixfmt, fb->addr, zrle_encode_frame(&client->z_stream, &frame, &client->pixfmt,
&server_fmt, fb->width, fb->height, &region); fb->addr, &server_fmt, fb->width, fb->height,
&region);
pixman_region_clear(cregion); pixman_region_clear(cregion);

View File

@ -180,36 +180,30 @@ int zrle_deflate(struct vec* dst, const struct vec* src, z_stream* zs,
zs->next_out = ((Bytef*)dst->data) + dst->len; zs->next_out = ((Bytef*)dst->data) + dst->len;
zs->avail_out = dst->cap - dst->len; zs->avail_out = dst->cap - dst->len;
r = deflate(zs, flush ? Z_FINISH : Z_NO_FLUSH); r = deflate(zs, flush ? Z_SYNC_FLUSH : Z_NO_FLUSH);
assert(r != Z_STREAM_ERROR); assert(r != Z_STREAM_ERROR);
dst->len = zs->next_out - (Bytef*)dst->data; dst->len = zs->next_out - (Bytef*)dst->data;
} while (zs->avail_out == 0); } while (zs->avail_out == 0);
assert(zs->avail_in == 0); assert(zs->avail_in == 0);
assert(!flush || r == Z_STREAM_END);
return 0; return 0;
} }
int zrle_encode_box(struct vec* out, const struct rfb_pixel_format *dst_fmt, int zrle_encode_box(struct vec* out, const struct rfb_pixel_format *dst_fmt,
const uint8_t *src, const struct rfb_pixel_format *src_fmt, const uint8_t *src, const struct rfb_pixel_format *src_fmt,
int x, int y, int stride, int width, int height) int x, int y, int stride, int width, int height,
z_stream* zs)
{ {
int r = -1; int r = -1;
int bytes_per_cpixel = dst_fmt->depth / 8; int bytes_per_cpixel = dst_fmt->depth / 8;
int chunk_size = 1 + bytes_per_cpixel * 64 * 64; int chunk_size = 1 + bytes_per_cpixel * 64 * 64;
z_stream zs = { 0 };
struct vec in; struct vec in;
if (vec_init(&in, 1 + bytes_per_cpixel * 64 * 64) < 0) if (vec_init(&in, 1 + bytes_per_cpixel * 64 * 64) < 0)
goto failure; goto failure;
r = deflateInit(&zs, Z_DEFAULT_COMPRESSION);
if (r != Z_OK)
goto failure;
struct rfb_server_fb_rect rect = { struct rfb_server_fb_rect rect = {
.encoding = htonl(RFB_ENCODING_ZRLE), .encoding = htonl(RFB_ENCODING_ZRLE),
.x = htons(x), .x = htons(x),
@ -239,16 +233,11 @@ int zrle_encode_box(struct vec* out, const struct rfb_pixel_format *dst_fmt,
((uint32_t*)src) + x + tile_x + (y + tile_y) * stride, ((uint32_t*)src) + x + tile_x + (y + tile_y) * stride,
src_fmt, stride, tile_width, tile_height); src_fmt, stride, tile_width, tile_height);
r = zrle_deflate(out, &in, &zs, i == n_tiles - 1); r = zrle_deflate(out, &in, zs, i == n_tiles - 1);
if (r < 0) if (r < 0)
goto failure; goto failure;
} }
deflateEnd(&zs);
/* There seems to be something extra at the end */
out->len -= 4;
uint32_t out_size = htonl(out->len - size_index - 4); uint32_t out_size = htonl(out->len - size_index - 4);
memcpy(((uint8_t*)out->data) + size_index, &out_size, sizeof(out_size)); memcpy(((uint8_t*)out->data) + size_index, &out_size, sizeof(out_size));
@ -258,7 +247,8 @@ failure:
#undef CHUNK #undef CHUNK
} }
int zrle_encode_frame(struct vec* dst, int zrle_encode_frame(z_stream *zs,
struct vec* dst,
const struct rfb_pixel_format *dst_fmt, const struct rfb_pixel_format *dst_fmt,
const uint8_t *src, const uint8_t *src,
const struct rfb_pixel_format *src_fmt, const struct rfb_pixel_format *src_fmt,
@ -290,7 +280,7 @@ int zrle_encode_frame(struct vec* dst,
int box_height = box[i].y2 - y; int box_height = box[i].y2 - y;
rc = zrle_encode_box(dst, dst_fmt, src, src_fmt, x, y, rc = zrle_encode_box(dst, dst_fmt, src, src_fmt, x, y,
width, box_width, box_height); width, box_width, box_height, zs);
if (rc < 0) if (rc < 0)
return -1; return -1;
} }