Replace libuv with aml
parent
3b7839e53b
commit
fefaf8060c
|
@ -19,7 +19,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <uv.h>
|
||||
#include <aml.h>
|
||||
#include <assert.h>
|
||||
#include <pixman.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
|
@ -66,6 +66,9 @@ int main(int argc, char* argv[])
|
|||
|
||||
memset(addr, 0xff, width * height * 4);
|
||||
|
||||
struct aml* aml = aml_new(NULL, 0);
|
||||
aml_set_default(aml);
|
||||
|
||||
struct nvnc* server = nvnc_open("127.0.0.1", 5900);
|
||||
|
||||
nvnc_set_dimensions(server, width, height, format);
|
||||
|
@ -73,7 +76,7 @@ int main(int argc, char* argv[])
|
|||
nvnc_set_pointer_fn(server, on_pointer_event);
|
||||
nvnc_set_userdata(server, &draw);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
aml_run(aml);
|
||||
|
||||
nvnc_close(server);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ executable(
|
|||
dependencies: [
|
||||
neatvnc_dep,
|
||||
pixman,
|
||||
libuv,
|
||||
aml,
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -22,7 +22,7 @@ if libpng.found()
|
|||
dependencies: [
|
||||
neatvnc_dep,
|
||||
pixman,
|
||||
libuv,
|
||||
aml,
|
||||
libpng,
|
||||
]
|
||||
)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <neatvnc.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <uv.h>
|
||||
#include <aml.h>
|
||||
#include <assert.h>
|
||||
#include <pixman.h>
|
||||
|
||||
|
@ -38,6 +38,9 @@ int main(int argc, char* argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
struct aml* aml = aml_new(NULL, 0);
|
||||
aml_set_default(aml);
|
||||
|
||||
struct nvnc* server = nvnc_open("127.0.0.1", 5900);
|
||||
|
||||
int width = nvnc_fb_get_width(fb);
|
||||
|
@ -53,7 +56,7 @@ int main(int argc, char* argv[])
|
|||
nvnc_feed_frame(server, fb, ®ion);
|
||||
pixman_region_fini(®ion);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
aml_run(aml);
|
||||
|
||||
nvnc_close(server);
|
||||
nvnc_fb_unref(fb);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <uv.h>
|
||||
#include <stdbool.h>
|
||||
#include <pixman.h>
|
||||
|
||||
|
@ -50,6 +49,7 @@ enum nvnc_client_state {
|
|||
|
||||
struct nvnc;
|
||||
struct stream;
|
||||
struct aml_handler;
|
||||
|
||||
struct nvnc_common {
|
||||
void* userdata;
|
||||
|
@ -88,7 +88,7 @@ struct vnc_display {
|
|||
struct nvnc {
|
||||
struct nvnc_common common;
|
||||
int fd;
|
||||
uv_poll_t poll_handle;
|
||||
struct aml_handler* poll_handle;
|
||||
struct nvnc_client_list clients;
|
||||
struct vnc_display display;
|
||||
void* userdata;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "sys/queue.h"
|
||||
#include "rcbuf.h"
|
||||
|
@ -66,7 +64,7 @@ struct stream {
|
|||
enum stream_state state;
|
||||
|
||||
int fd;
|
||||
uv_poll_t uv_poll;
|
||||
struct aml_handler* handler;
|
||||
stream_event_fn on_event;
|
||||
void* userdata;
|
||||
|
||||
|
|
10
meson.build
10
meson.build
|
@ -34,10 +34,16 @@ cc = meson.get_compiler('c')
|
|||
libm = cc.find_library('m', required: false)
|
||||
|
||||
pixman = dependency('pixman-1')
|
||||
libuv = dependency('libuv')
|
||||
libturbojpeg = dependency('libturbojpeg', required: get_option('tight-encoding'))
|
||||
gnutls = dependency('gnutls', required: get_option('tls'))
|
||||
|
||||
aml_project = subproject('aml', required: false)
|
||||
if aml_project.found()
|
||||
aml = aml_project.get_variable('aml_dep')
|
||||
else
|
||||
aml = dependency('aml')
|
||||
endif
|
||||
|
||||
inc = include_directories('include', 'contrib/miniz')
|
||||
|
||||
sources = [
|
||||
|
@ -56,7 +62,7 @@ sources = [
|
|||
dependencies = [
|
||||
libm,
|
||||
pixman,
|
||||
libuv,
|
||||
aml,
|
||||
]
|
||||
|
||||
config = configuration_data()
|
||||
|
|
38
src/damage.c
38
src/damage.c
|
@ -8,14 +8,14 @@
|
|||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#include <uv.h>
|
||||
#include <aml.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
#define ALIGN_DOWN(a, b) (((a) / (b)) * (b))
|
||||
|
||||
struct damage_check {
|
||||
uv_work_t work;
|
||||
struct aml_work* work;
|
||||
struct nvnc_fb* fb0;
|
||||
struct nvnc_fb* fb1;
|
||||
int x_hint;
|
||||
|
@ -86,20 +86,18 @@ int check_damage_linear(struct pixman_region16* damage,
|
|||
}
|
||||
#undef TILE_SIDE_LENGTH
|
||||
|
||||
void do_damage_check_linear(uv_work_t* work)
|
||||
void do_damage_check_linear(void* work)
|
||||
{
|
||||
struct damage_check* check = (void*)work;
|
||||
struct damage_check* check = aml_get_userdata(work);
|
||||
|
||||
check_damage_linear(&check->damage, check->fb0, check->fb1,
|
||||
check->x_hint, check->y_hint, check->width_hint,
|
||||
check->height_hint);
|
||||
}
|
||||
|
||||
void on_damage_check_done_linear(uv_work_t* work, int status)
|
||||
void on_damage_check_done_linear(void* work)
|
||||
{
|
||||
(void)status;
|
||||
|
||||
struct damage_check* check = (void*)work;
|
||||
struct damage_check* check = aml_get_userdata(work);
|
||||
|
||||
check->on_done(&check->damage, check->userdata);
|
||||
|
||||
|
@ -130,17 +128,25 @@ int check_damage_linear_threaded(struct nvnc_fb* fb0, struct nvnc_fb* fb1,
|
|||
pixman_region_init(&work->damage);
|
||||
|
||||
/* TODO: Spread the work into more tasks */
|
||||
int rc = uv_queue_work(uv_default_loop(), &work->work,
|
||||
do_damage_check_linear,
|
||||
on_damage_check_done_linear);
|
||||
if (rc >= 0) {
|
||||
nvnc_fb_ref(fb0);
|
||||
nvnc_fb_ref(fb1);
|
||||
} else {
|
||||
struct aml_work* obj =
|
||||
aml_work_new(do_damage_check_linear, on_damage_check_done_linear,
|
||||
work, free);
|
||||
if (!obj) {
|
||||
free(work);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
int rc = aml_start(aml_get_default(), obj);
|
||||
aml_unref(obj);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
|
||||
work->work = obj;
|
||||
|
||||
nvnc_fb_ref(fb0);
|
||||
nvnc_fb_ref(fb1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT
|
||||
|
|
68
src/server.c
68
src/server.c
|
@ -33,10 +33,11 @@
|
|||
#include <sys/queue.h>
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <uv.h>
|
||||
#include <aml.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#include <pixman.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef ENABLE_TLS
|
||||
#include <gnutls/gnutls.h>
|
||||
|
@ -55,7 +56,7 @@
|
|||
#define EXPORT __attribute__((visibility("default")))
|
||||
|
||||
struct fb_update_work {
|
||||
uv_work_t work;
|
||||
struct aml_work* work;
|
||||
struct nvnc_client* client;
|
||||
struct pixman_region16 region;
|
||||
struct rfb_pixel_format server_fmt;
|
||||
|
@ -65,19 +66,6 @@ struct fb_update_work {
|
|||
|
||||
int schedule_client_update_fb(struct nvnc_client* client);
|
||||
|
||||
static const char* fourcc_to_string(uint32_t fourcc)
|
||||
{
|
||||
static char buffer[5];
|
||||
|
||||
buffer[0] = (fourcc >> 0) & 0xff;
|
||||
buffer[1] = (fourcc >> 8) & 0xff;
|
||||
buffer[2] = (fourcc >> 16) & 0xff;
|
||||
buffer[3] = (fourcc >> 24) & 0xff;
|
||||
buffer[4] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void client_close(struct nvnc_client* client)
|
||||
{
|
||||
log_debug("client_close(%p): ref %d\n", client, client->ref);
|
||||
|
@ -688,10 +676,9 @@ static void on_client_event(struct stream* stream, enum stream_event event)
|
|||
client->buffer_index = 0;
|
||||
}
|
||||
|
||||
static void on_connection(uv_poll_t* poll_handle, int status, int events)
|
||||
static void on_connection(void* obj)
|
||||
{
|
||||
struct nvnc* server =
|
||||
container_of(poll_handle, struct nvnc, poll_handle);
|
||||
struct nvnc* server = aml_get_userdata(obj);
|
||||
|
||||
struct nvnc_client* client = calloc(1, sizeof(*client));
|
||||
if (!client)
|
||||
|
@ -749,6 +736,8 @@ accept_failure:
|
|||
EXPORT
|
||||
struct nvnc* nvnc_open(const char* address, uint16_t port)
|
||||
{
|
||||
aml_require_workers(aml_get_default(), 4);
|
||||
|
||||
struct nvnc* self = calloc(1, sizeof(*self));
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
@ -776,11 +765,17 @@ struct nvnc* nvnc_open(const char* address, uint16_t port)
|
|||
if (listen(self->fd, 16) < 0)
|
||||
goto failure;
|
||||
|
||||
uv_poll_init(uv_default_loop(), &self->poll_handle, self->fd);
|
||||
uv_poll_start(&self->poll_handle, UV_READABLE, on_connection);
|
||||
self->poll_handle = aml_handler_new(self->fd, on_connection, self, NULL);
|
||||
if (!self->poll_handle)
|
||||
goto failure;
|
||||
|
||||
if (aml_start(aml_get_default(), self->poll_handle) < 0)
|
||||
goto start_failure;
|
||||
|
||||
return self;
|
||||
|
||||
start_failure:
|
||||
aml_unref(self->poll_handle);
|
||||
failure:
|
||||
close(self->fd);
|
||||
return NULL;
|
||||
|
@ -798,7 +793,7 @@ void nvnc_close(struct nvnc* self)
|
|||
LIST_FOREACH_SAFE (client, &self->clients, link, tmp)
|
||||
client_unref(client);
|
||||
|
||||
uv_poll_stop(&self->poll_handle);
|
||||
aml_stop(aml_get_default(), self->poll_handle);
|
||||
close(self->fd);
|
||||
|
||||
#ifdef ENABLE_TLS
|
||||
|
@ -808,6 +803,7 @@ void nvnc_close(struct nvnc* self)
|
|||
}
|
||||
#endif
|
||||
|
||||
aml_unref(self->poll_handle);
|
||||
free(self);
|
||||
}
|
||||
|
||||
|
@ -835,9 +831,9 @@ enum rfb_encodings choose_frame_encoding(struct nvnc_client* client)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void do_client_update_fb(uv_work_t* work)
|
||||
void do_client_update_fb(void* work)
|
||||
{
|
||||
struct fb_update_work* update = (void*)work;
|
||||
struct fb_update_work* update = aml_get_userdata(work);
|
||||
struct nvnc_client* client = update->client;
|
||||
const struct nvnc_fb* fb = update->fb;
|
||||
|
||||
|
@ -873,11 +869,9 @@ void do_client_update_fb(uv_work_t* work)
|
|||
}
|
||||
}
|
||||
|
||||
void on_client_update_fb_done(uv_work_t* work, int status)
|
||||
void on_client_update_fb_done(void* work)
|
||||
{
|
||||
(void)status;
|
||||
|
||||
struct fb_update_work* update = (void*)work;
|
||||
struct fb_update_work* update = aml_get_userdata(work);
|
||||
struct nvnc_client* client = update->client;
|
||||
struct vec* frame = &update->frame;
|
||||
|
||||
|
@ -901,7 +895,6 @@ void on_client_update_fb_done(uv_work_t* work, int status)
|
|||
pixman_region_fini(&update->region);
|
||||
|
||||
client_unref(client);
|
||||
free(update);
|
||||
}
|
||||
|
||||
int schedule_client_update_fb(struct nvnc_client* client)
|
||||
|
@ -930,14 +923,25 @@ int schedule_client_update_fb(struct nvnc_client* client)
|
|||
client_ref(client);
|
||||
nvnc_fb_ref(fb);
|
||||
|
||||
rc = uv_queue_work(uv_default_loop(), &work->work, do_client_update_fb,
|
||||
on_client_update_fb_done);
|
||||
struct aml_work* obj =
|
||||
aml_work_new(do_client_update_fb, on_client_update_fb_done,
|
||||
work, free);
|
||||
if (!obj) {
|
||||
goto oom_failure;
|
||||
}
|
||||
|
||||
rc = aml_start(aml_get_default(), obj);
|
||||
aml_unref(obj);
|
||||
if (rc < 0)
|
||||
goto queue_failure;
|
||||
goto start_failure;
|
||||
|
||||
work->work = obj;
|
||||
|
||||
return 0;
|
||||
|
||||
queue_failure:
|
||||
start_failure:
|
||||
work = NULL; /* handled in unref */
|
||||
oom_failure:
|
||||
nvnc_fb_unref(fb);
|
||||
client_unref(client);
|
||||
vec_destroy(&work->frame);
|
||||
|
|
54
src/stream.c
54
src/stream.c
|
@ -21,38 +21,37 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/uio.h>
|
||||
#include <uv.h>
|
||||
#include <limits.h>
|
||||
#include <aml.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
||||
#ifdef ENABLE_TLS
|
||||
#include <gnutls/gnutls.h>
|
||||
#endif
|
||||
|
||||
#include "type-macros.h"
|
||||
#include "rcbuf.h"
|
||||
#include "stream.h"
|
||||
#include "sys/queue.h"
|
||||
|
||||
static void stream__on_event(uv_poll_t* uv_poll, int status, int events);
|
||||
static void stream__on_event(void* obj);
|
||||
#ifdef ENABLE_TLS
|
||||
static int stream__try_tls_accept(struct stream* self);
|
||||
#endif
|
||||
|
||||
static inline void stream__poll_r(struct stream* self)
|
||||
{
|
||||
uv_poll_start(&self->uv_poll, UV_READABLE | UV_DISCONNECT,
|
||||
stream__on_event);
|
||||
aml_set_event_mask(self->handler, POLLIN);
|
||||
}
|
||||
|
||||
static inline void stream__poll_w(struct stream* self)
|
||||
{
|
||||
uv_poll_start(&self->uv_poll, UV_WRITABLE | UV_DISCONNECT,
|
||||
stream__on_event);
|
||||
aml_set_event_mask(self->handler, POLLOUT);
|
||||
}
|
||||
|
||||
static inline void stream__poll_rw(struct stream* self)
|
||||
{
|
||||
uv_poll_start(&self->uv_poll, UV_READABLE | UV_DISCONNECT | UV_WRITABLE,
|
||||
stream__on_event);
|
||||
aml_set_event_mask(self->handler, POLLIN | POLLOUT);
|
||||
}
|
||||
|
||||
static void stream_req__finish(struct stream_req* req, enum stream_req_status status)
|
||||
|
@ -83,24 +82,18 @@ int stream_close(struct stream* self)
|
|||
self->tls_session = NULL;
|
||||
#endif
|
||||
|
||||
uv_poll_stop(&self->uv_poll);
|
||||
// TODO: Maybe use explicit loop object instead of the default one?
|
||||
aml_stop(aml_get_default(), self->handler);
|
||||
close(self->fd);
|
||||
self->fd = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stream__free_poll_handle(uv_handle_t* handle)
|
||||
{
|
||||
uv_poll_t* uv_poll = (uv_poll_t*)handle;
|
||||
struct stream* self = container_of(uv_poll, struct stream, uv_poll);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void stream_destroy(struct stream* self)
|
||||
{
|
||||
stream_close(self);
|
||||
uv_close((uv_handle_t*)&self->uv_poll, stream__free_poll_handle);
|
||||
aml_unref(self->handler);
|
||||
}
|
||||
|
||||
static void stream__remote_closed(struct stream* self)
|
||||
|
@ -268,19 +261,15 @@ static void stream__on_writable(struct stream* self)
|
|||
}
|
||||
}
|
||||
|
||||
static void stream__on_event(uv_poll_t* uv_poll, int status, int events)
|
||||
static void stream__on_event(void* obj)
|
||||
{
|
||||
struct stream* self = container_of(uv_poll, struct stream, uv_poll);
|
||||
struct stream* self = aml_get_userdata(obj);
|
||||
uint32_t events = aml_get_revents(obj);
|
||||
|
||||
if (events & UV_DISCONNECT) {
|
||||
stream__remote_closed(self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (events & UV_READABLE)
|
||||
if (events & POLLIN)
|
||||
stream__on_readable(self);
|
||||
|
||||
if (events & UV_WRITABLE)
|
||||
if (events & POLLOUT)
|
||||
stream__on_writable(self);
|
||||
}
|
||||
|
||||
|
@ -298,13 +287,20 @@ struct stream* stream_new(int fd, stream_event_fn on_event, void* userdata)
|
|||
|
||||
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
if (uv_poll_init(uv_default_loop(), &self->uv_poll, fd) < 0)
|
||||
self->handler = aml_handler_new(fd, stream__on_event, self, free);
|
||||
if (!self->handler)
|
||||
goto failure;
|
||||
|
||||
if (aml_start(aml_get_default(), self->handler) < 0)
|
||||
goto start_failure;
|
||||
|
||||
stream__poll_r(self);
|
||||
|
||||
return self;
|
||||
|
||||
start_failure:
|
||||
aml_unref(self->handler);
|
||||
self = NULL; /* Handled in unref */
|
||||
failure:
|
||||
free(self);
|
||||
return NULL;
|
||||
|
@ -393,7 +389,7 @@ static int stream__try_tls_accept(struct stream* self)
|
|||
}
|
||||
|
||||
if (gnutls_error_is_fatal(rc)) {
|
||||
uv_poll_stop(&self->uv_poll);
|
||||
aml_stop(aml_get_default(), &self->handler);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue