--- server/Makefile.am | 2 + server/cursor-channel-client.c | 122 +++++++++++++++++++++++++++++++++++++++++ server/cursor-channel-client.h | 44 +++++++++++++++ server/cursor-channel.c | 104 ++++------------------------------- server/cursor-channel.h | 15 +---- server/red-worker.c | 1 + 6 files changed, 183 insertions(+), 105 deletions(-) create mode 100644 server/cursor-channel-client.c create mode 100644 server/cursor-channel-client.h diff --git a/server/Makefile.am b/server/Makefile.am index 1643b93..f5822ad 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -120,6 +120,8 @@ libserver_la_SOURCES = \ red-worker.h \ display-channel.c \ display-channel.h \ + cursor-channel-client.c \ + cursor-channel-client.h \ cursor-channel.c \ cursor-channel.h \ red-pipe-item.c \ diff --git a/server/cursor-channel-client.c b/server/cursor-channel-client.c new file mode 100644 index 0000000..8cddd6c --- /dev/null +++ b/server/cursor-channel-client.c @@ -0,0 +1,122 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2009 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "common/generated_server_marshallers.h" +#include "common-graphics-channel-client-private.h" +#include "cache-item.h" +#include "cursor-channel.h" + +#define CLIENT_CURSOR_CACHE_SIZE 256 + +#define CURSOR_CACHE_HASH_SHIFT 8 +#define CURSOR_CACHE_HASH_SIZE (1 << CURSOR_CACHE_HASH_SHIFT) +#define CURSOR_CACHE_HASH_MASK (CURSOR_CACHE_HASH_SIZE - 1) +#define CURSOR_CACHE_HASH_KEY(id) ((id) & CURSOR_CACHE_HASH_MASK) +#define CURSOR_CLIENT_TIMEOUT 30000000000ULL //nano + +enum { + RED_PIPE_ITEM_TYPE_CURSOR = RED_PIPE_ITEM_TYPE_COMMON_LAST, + RED_PIPE_ITEM_TYPE_CURSOR_INIT, + RED_PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE, +}; + +struct CursorChannelClient { + CommonGraphicsChannelClient common; + + RedCacheItem *cursor_cache[CURSOR_CACHE_HASH_SIZE]; + Ring cursor_cache_lru; + long cursor_cache_available; + uint32_t cursor_cache_items; +}; + + +#define RCC_TO_CCC(rcc) ((CursorChannelClient*)rcc) + +#define CLIENT_CURSOR_CACHE +#include "cache-item.tmpl.c" +#undef CLIENT_CURSOR_CACHE + +#ifdef DEBUG_CURSORS +static int _cursor_count = 0; +#endif + +void cursor_channel_client_reset_cursor_cache(RedChannelClient *rcc) +{ + red_cursor_cache_reset(RCC_TO_CCC(rcc), CLIENT_CURSOR_CACHE_SIZE); +} + +void cursor_channel_client_on_disconnect(RedChannelClient *rcc) +{ + if (!rcc) { + return; + } + cursor_channel_client_reset_cursor_cache(rcc); +} + +void cursor_channel_client_migrate(CursorChannelClient* client) +{ + RedChannelClient *rcc; + + spice_return_if_fail(client); + rcc = RED_CHANNEL_CLIENT(client); + + red_channel_client_pipe_add_type(rcc, RED_PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE); + red_channel_client_default_migrate(rcc); +} + +CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, RedClient *client, RedsStream *stream, + int mig_target, + uint32_t *common_caps, int num_common_caps, + uint32_t *caps, int num_caps) +{ + spice_return_val_if_fail(cursor, NULL); + spice_return_val_if_fail(client, NULL); + spice_return_val_if_fail(stream, NULL); + spice_return_val_if_fail(!num_common_caps || common_caps, NULL); + spice_return_val_if_fail(!num_caps || caps, NULL); + + CursorChannelClient *ccc = + (CursorChannelClient*)common_graphics_channel_client_new((CommonGraphicsChannel*)cursor, + sizeof(CursorChannelClient), + client, stream, + mig_target, + FALSE, + common_caps, + num_common_caps, + caps, + num_caps); + spice_return_val_if_fail(ccc != NULL, NULL); + + ring_init(&ccc->cursor_cache_lru); + ccc->cursor_cache_available = CLIENT_CURSOR_CACHE_SIZE; + + return ccc; +} + +RedCacheItem* cursor_channel_client_cache_find(CursorChannelClient *ccc, uint64_t id) +{ + return red_cursor_cache_find(ccc, id); +} + +int cursor_channel_client_cache_add(CursorChannelClient *ccc, uint64_t id, size_t size) +{ + return red_cursor_cache_add(ccc, id, size); +} diff --git a/server/cursor-channel-client.h b/server/cursor-channel-client.h new file mode 100644 index 0000000..3e18d65 --- /dev/null +++ b/server/cursor-channel-client.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2009 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ +#ifndef CURSOR_CHANNEL_CLIENT_H_ +# define CURSOR_CHANNEL_CLIENT_H_ + +#include "cache-item.h" +#include "red-common.h" +#include "red-channel.h" +#include "reds-stream.h" + +typedef struct CursorChannel CursorChannel; +typedef struct CursorChannelClient CursorChannelClient; + +#define CURSOR_CHANNEL_CLIENT(Client) ((CursorChannelClient*)(Client)) + +CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, + RedClient *client, + RedsStream *stream, + int mig_target, + uint32_t *common_caps, + int num_common_caps, + uint32_t *caps, int num_caps); +void cursor_channel_client_migrate(CursorChannelClient* client); +void cursor_channel_client_reset_cursor_cache(RedChannelClient *rcc); +void cursor_channel_client_on_disconnect(RedChannelClient *rcc); +RedCacheItem* cursor_channel_client_cache_find(CursorChannelClient *ccc, uint64_t id); +int cursor_channel_client_cache_add(CursorChannelClient *ccc, uint64_t id, size_t size); + +#endif /* CURSOR_CHANNEL_CLIENT_H_ */ diff --git a/server/cursor-channel.c b/server/cursor-channel.c index ae4b408..63be056 100644 --- a/server/cursor-channel.c +++ b/server/cursor-channel.c @@ -23,14 +23,7 @@ #include "common/generated_server_marshallers.h" #include "common-graphics-channel-client-private.h" #include "cursor-channel.h" -#include "cache-item.h" - -#define CLIENT_CURSOR_CACHE_SIZE 256 - -#define CURSOR_CACHE_HASH_SHIFT 8 -#define CURSOR_CACHE_HASH_SIZE (1 << CURSOR_CACHE_HASH_SHIFT) -#define CURSOR_CACHE_HASH_MASK (CURSOR_CACHE_HASH_SIZE - 1) -#define CURSOR_CACHE_HASH_KEY(id) ((id) & CURSOR_CACHE_HASH_MASK) +#include "reds.h" enum { RED_PIPE_ITEM_TYPE_CURSOR = RED_PIPE_ITEM_TYPE_COMMON_LAST, @@ -67,22 +60,6 @@ struct CursorChannel { #endif }; -struct CursorChannelClient { - CommonGraphicsChannelClient common; - - RedCacheItem *cursor_cache[CURSOR_CACHE_HASH_SIZE]; - Ring cursor_cache_lru; - long cursor_cache_available; - uint32_t cursor_cache_items; -}; - - -#define RCC_TO_CCC(rcc) SPICE_CONTAINEROF((rcc), CursorChannelClient, common.base) - -#define CLIENT_CURSOR_CACHE -#include "cache-item.tmpl.c" -#undef CLIENT_CURSOR_CACHE - static CursorItem *cursor_item_new(QXLInstance *qxl, RedCursorCmd *cmd) { CursorItem *cursor_item; @@ -139,8 +116,7 @@ static RedPipeItem *new_cursor_pipe_item(void *data, int num) red_pipe_item_init(&item->base, RED_PIPE_ITEM_TYPE_CURSOR); item->refs = 1; - item->cursor_item = data; - item->cursor_item->refs++; + item->cursor_item = cursor_item_ref(data); return &item->base; } @@ -171,11 +147,11 @@ static void cursor_fill(CursorChannelClient *ccc, SpiceCursor *red_cursor, *red_cursor = cursor_cmd->u.set.shape; if (red_cursor->header.unique) { - if (red_cursor_cache_find(ccc, red_cursor->header.unique)) { + if (cursor_channel_client_cache_find(ccc, red_cursor->header.unique)) { red_cursor->flags |= SPICE_CURSOR_FLAGS_FROM_CACHE; return; } - if (red_cursor_cache_add(ccc, red_cursor->header.unique, 1)) { + if (cursor_channel_client_cache_add(ccc, red_cursor->header.unique, 1)) { red_cursor->flags |= SPICE_CURSOR_FLAGS_CACHE_ME; } } @@ -186,12 +162,6 @@ static void cursor_fill(CursorChannelClient *ccc, SpiceCursor *red_cursor, } } - -static void red_reset_cursor_cache(RedChannelClient *rcc) -{ - red_cursor_cache_reset(RCC_TO_CCC(rcc), CLIENT_CURSOR_CACHE_SIZE); -} - void cursor_channel_disconnect(CursorChannel *cursor_channel) { RedChannel *channel = (RedChannel *)cursor_channel; @@ -199,11 +169,10 @@ void cursor_channel_disconnect(CursorChannel *cursor_channel) if (!channel || !red_channel_is_connected(channel)) { return; } - red_channel_apply_clients(channel, red_reset_cursor_cache); + red_channel_apply_clients(channel, cursor_channel_client_reset_cursor_cache); red_channel_disconnect(channel); } - static void put_cursor_pipe_item(CursorChannelClient *ccc, RedCursorPipeItem *pipe_item) { @@ -220,14 +189,6 @@ static void put_cursor_pipe_item(CursorChannelClient *ccc, free(pipe_item); } -static void cursor_channel_client_on_disconnect(RedChannelClient *rcc) -{ - if (!rcc) { - return; - } - red_reset_cursor_cache(rcc); -} - // TODO: share code between before/after_push since most of the items need the same // release static void cursor_channel_client_release_item_before_push(CursorChannelClient *ccc, @@ -268,12 +229,12 @@ static void red_marshall_cursor_init(RedChannelClient *rcc, SpiceMarshaller *bas RedPipeItem *pipe_item) { CursorChannel *cursor_channel; - CursorChannelClient *ccc = RCC_TO_CCC(rcc); + CursorChannelClient *ccc = (CursorChannelClient*)rcc; SpiceMsgCursorInit msg; AddBufInfo info; spice_assert(rcc); - cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base); + cursor_channel = (CursorChannel*)rcc->channel; red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INIT, NULL); msg.visible = cursor_channel->cursor_visible; @@ -291,7 +252,7 @@ static void cursor_marshall(RedChannelClient *rcc, RedCursorPipeItem *cursor_pipe_item) { CursorChannel *cursor_channel = SPICE_CONTAINEROF(rcc->channel, CursorChannel, common.base); - CursorChannelClient *ccc = RCC_TO_CCC(rcc); + CursorChannelClient *ccc = (CursorChannelClient*)rcc; CursorItem *item = cursor_pipe_item->cursor_item; RedPipeItem *pipe_item = &cursor_pipe_item->base; RedCursorCmd *cmd; @@ -355,7 +316,7 @@ static inline void red_marshall_inval(RedChannelClient *rcc, static void cursor_channel_send_item(RedChannelClient *rcc, RedPipeItem *pipe_item) { SpiceMarshaller *m = red_channel_client_get_marshaller(rcc); - CursorChannelClient *ccc = RCC_TO_CCC(rcc); + CursorChannelClient *ccc = (CursorChannelClient*)rcc; switch (pipe_item->type) { case RED_PIPE_ITEM_TYPE_CURSOR: @@ -368,11 +329,11 @@ static void cursor_channel_send_item(RedChannelClient *rcc, RedPipeItem *pipe_it red_marshall_verb(rcc, (RedVerbItem*)pipe_item); break; case RED_PIPE_ITEM_TYPE_CURSOR_INIT: - red_reset_cursor_cache(rcc); + cursor_channel_client_reset_cursor_cache(rcc); red_marshall_cursor_init(rcc, m, pipe_item); break; case RED_PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE: - red_reset_cursor_cache(rcc); + cursor_channel_client_reset_cursor_cache(rcc); red_channel_client_init_send_data(rcc, SPICE_MSG_CURSOR_INVAL_ALL, NULL); break; default: @@ -392,7 +353,6 @@ static RedCursorPipeItem *cursor_pipe_item_ref(RedCursorPipeItem *item) return item; } - static void cursor_channel_hold_pipe_item(RedChannelClient *rcc, RedPipeItem *item) { RedCursorPipeItem *cursor_pipe_item; @@ -405,7 +365,7 @@ static void cursor_channel_hold_pipe_item(RedChannelClient *rcc, RedPipeItem *it static void cursor_channel_release_item(RedChannelClient *rcc, RedPipeItem *item, int item_pushed) { - CursorChannelClient *ccc = RCC_TO_CCC(rcc); + CursorChannelClient *ccc = (CursorChannelClient*)rcc; spice_assert(item); @@ -440,46 +400,6 @@ CursorChannel* cursor_channel_new(RedWorker *worker) return cursor_channel; } -void cursor_channel_client_migrate(CursorChannelClient* client) -{ - RedChannelClient *rcc; - - spice_return_if_fail(client); - rcc = RED_CHANNEL_CLIENT(client); - - red_channel_client_pipe_add_type(rcc, RED_PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE); - red_channel_client_default_migrate(rcc); -} - -CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, RedClient *client, RedsStream *stream, - int mig_target, - uint32_t *common_caps, int num_common_caps, - uint32_t *caps, int num_caps) -{ - spice_return_val_if_fail(cursor, NULL); - spice_return_val_if_fail(client, NULL); - spice_return_val_if_fail(stream, NULL); - spice_return_val_if_fail(!num_common_caps || common_caps, NULL); - spice_return_val_if_fail(!num_caps || caps, NULL); - - CursorChannelClient *ccc = - (CursorChannelClient*)common_graphics_channel_client_new(&cursor->common, - sizeof(CursorChannelClient), - client, stream, - mig_target, - FALSE, - common_caps, - num_common_caps, - caps, - num_caps); - spice_return_val_if_fail(ccc != NULL, NULL); - - ring_init(&ccc->cursor_cache_lru); - ccc->cursor_cache_available = CLIENT_CURSOR_CACHE_SIZE; - - return ccc; -} - void cursor_channel_process_cmd(CursorChannel *cursor, RedCursorCmd *cursor_cmd) { CursorItem *cursor_item; diff --git a/server/cursor-channel.h b/server/cursor-channel.h index 4dad4b6..2b09b21 100644 --- a/server/cursor-channel.h +++ b/server/cursor-channel.h @@ -18,15 +18,11 @@ #ifndef CURSOR_CHANNEL_H_ # define CURSOR_CHANNEL_H_ -#include "spice.h" -#include "reds.h" +#include "cursor-channel-client.h" #include "red-worker.h" -#include "red-parse-qxl.h" typedef struct CursorChannel CursorChannel; -typedef struct CursorChannelClient CursorChannelClient; - -#define CURSOR_CHANNEL_CLIENT(Client) ((CursorChannelClient*)(Client)) +typedef struct CursorItem CursorItem; CursorChannel* cursor_channel_new (RedWorker *worker); void cursor_channel_disconnect (CursorChannel *cursor_channel); @@ -35,11 +31,4 @@ void cursor_channel_init (CursorChannel *cursor, CursorCh void cursor_channel_process_cmd (CursorChannel *cursor, RedCursorCmd *cursor_cmd); void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode); -CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, - RedClient *client, RedsStream *stream, - int mig_target, - uint32_t *common_caps, int num_common_caps, - uint32_t *caps, int num_caps); -void cursor_channel_client_migrate(CursorChannelClient* client); - #endif /* CURSOR_CHANNEL_H_ */ diff --git a/server/red-worker.c b/server/red-worker.c index 8e3a90a..5be29aa 100644 --- a/server/red-worker.c +++ b/server/red-worker.c @@ -50,6 +50,7 @@ #include "spice.h" #include "red-worker.h" #include "cursor-channel.h" +#include "cursor-channel-client.h" #include "tree.h" #include "main-channel-client.h" -- 2.4.11 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel