mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-09 14:11:47 +00:00
server: make more of cursor private
Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
This commit is contained in:
parent
c9e3b058e4
commit
e601e920bd
@ -19,6 +19,41 @@
|
|||||||
#include "common/generated_server_marshallers.h"
|
#include "common/generated_server_marshallers.h"
|
||||||
#include "cursor-channel.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)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PIPE_ITEM_TYPE_CURSOR = PIPE_ITEM_TYPE_COMMON_LAST,
|
||||||
|
PIPE_ITEM_TYPE_CURSOR_INIT,
|
||||||
|
PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct CursorItem {
|
||||||
|
QXLInstance *qxl;
|
||||||
|
uint32_t group_id;
|
||||||
|
int refs;
|
||||||
|
RedCursorCmd *red_cursor;
|
||||||
|
} CursorItem;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
|
||||||
|
|
||||||
|
typedef struct LocalCursor {
|
||||||
|
CursorItem base;
|
||||||
|
SpicePoint16 position;
|
||||||
|
uint32_t data_size;
|
||||||
|
SpiceCursor red_cursor;
|
||||||
|
} LocalCursor;
|
||||||
|
|
||||||
|
typedef struct CursorPipeItem {
|
||||||
|
PipeItem base;
|
||||||
|
CursorItem *cursor_item;
|
||||||
|
int refs;
|
||||||
|
} CursorPipeItem;
|
||||||
|
|
||||||
struct CursorChannel {
|
struct CursorChannel {
|
||||||
CommonChannel common; // Must be the first thing
|
CommonChannel common; // Must be the first thing
|
||||||
|
|
||||||
@ -34,6 +69,16 @@ struct CursorChannel {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CursorChannelClient {
|
||||||
|
CommonChannelClient common;
|
||||||
|
|
||||||
|
CacheItem *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 RCC_TO_CCC(rcc) SPICE_CONTAINEROF((rcc), CursorChannelClient, common.base)
|
||||||
|
|
||||||
#define CLIENT_CURSOR_CACHE
|
#define CLIENT_CURSOR_CACHE
|
||||||
@ -50,7 +95,7 @@ static inline CursorItem *alloc_cursor_item(void)
|
|||||||
return cursor_item;
|
return cursor_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorItem *cursor_item_new(RedCursorCmd *cmd, uint32_t group_id)
|
static CursorItem *cursor_item_new(RedCursorCmd *cmd, uint32_t group_id)
|
||||||
{
|
{
|
||||||
CursorItem *cursor_item;
|
CursorItem *cursor_item;
|
||||||
|
|
||||||
@ -63,7 +108,7 @@ CursorItem *cursor_item_new(RedCursorCmd *cmd, uint32_t group_id)
|
|||||||
return cursor_item;
|
return cursor_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor_item_unref(QXLInstance *qxl, CursorItem *cursor)
|
static void cursor_item_unref(QXLInstance *qxl, CursorItem *cursor)
|
||||||
{
|
{
|
||||||
if (!--cursor->refs) {
|
if (!--cursor->refs) {
|
||||||
QXLReleaseInfoExt release_info_ext;
|
QXLReleaseInfoExt release_info_ext;
|
||||||
@ -390,6 +435,17 @@ CursorChannel* cursor_channel_new(RedWorker *worker)
|
|||||||
return cursor_channel;
|
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, PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE);
|
||||||
|
red_channel_client_default_migrate(rcc);
|
||||||
|
}
|
||||||
|
|
||||||
CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, RedClient *client, RedsStream *stream,
|
CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, RedClient *client, RedsStream *stream,
|
||||||
int mig_target,
|
int mig_target,
|
||||||
uint32_t *common_caps, int num_common_caps,
|
uint32_t *common_caps, int num_common_caps,
|
||||||
@ -476,6 +532,23 @@ void cursor_channel_reset(CursorChannel *cursor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cursor_channel_init(CursorChannel *cursor, CursorChannelClient *client)
|
||||||
|
{
|
||||||
|
spice_return_if_fail(cursor);
|
||||||
|
|
||||||
|
if (red_channel_is_connected(&cursor->common.base)
|
||||||
|
|| COMMON_CHANNEL(cursor)->during_target_migrate) {
|
||||||
|
spice_debug("during_target_migrate: skip init");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
red_channel_client_pipe_add_type(RED_CHANNEL_CLIENT(client),
|
||||||
|
PIPE_ITEM_TYPE_CURSOR_INIT);
|
||||||
|
else
|
||||||
|
red_channel_pipes_add_type(RED_CHANNEL(cursor), PIPE_ITEM_TYPE_CURSOR_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode)
|
void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode)
|
||||||
{
|
{
|
||||||
spice_return_if_fail(cursor);
|
spice_return_if_fail(cursor);
|
||||||
|
|||||||
@ -25,66 +25,24 @@
|
|||||||
#include "cache-item.h"
|
#include "cache-item.h"
|
||||||
#include "stat.h"
|
#include "stat.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)
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PIPE_ITEM_TYPE_CURSOR = PIPE_ITEM_TYPE_COMMON_LAST,
|
|
||||||
PIPE_ITEM_TYPE_CURSOR_INIT,
|
|
||||||
PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct CursorChannel CursorChannel;
|
typedef struct CursorChannel CursorChannel;
|
||||||
|
typedef struct CursorChannelClient CursorChannelClient;
|
||||||
|
|
||||||
typedef struct CursorItem {
|
#define CURSOR_CHANNEL_CLIENT(Client) ((CursorChannelClient*)(Client))
|
||||||
uint32_t group_id;
|
|
||||||
int refs;
|
|
||||||
RedCursorCmd *red_cursor;
|
|
||||||
} CursorItem;
|
|
||||||
|
|
||||||
typedef struct CursorPipeItem {
|
|
||||||
PipeItem base;
|
|
||||||
CursorItem *cursor_item;
|
|
||||||
int refs;
|
|
||||||
} CursorPipeItem;
|
|
||||||
|
|
||||||
typedef struct LocalCursor {
|
|
||||||
CursorItem base;
|
|
||||||
SpicePoint16 position;
|
|
||||||
uint32_t data_size;
|
|
||||||
SpiceCursor red_cursor;
|
|
||||||
} LocalCursor;
|
|
||||||
|
|
||||||
typedef struct CursorChannelClient {
|
|
||||||
CommonChannelClient common;
|
|
||||||
|
|
||||||
CacheItem *cursor_cache[CURSOR_CACHE_HASH_SIZE];
|
|
||||||
Ring cursor_cache_lru;
|
|
||||||
long cursor_cache_available;
|
|
||||||
uint32_t cursor_cache_items;
|
|
||||||
} CursorChannelClient;
|
|
||||||
|
|
||||||
G_STATIC_ASSERT(sizeof(CursorItem) <= QXL_CURSUR_DEVICE_DATA_SIZE);
|
|
||||||
|
|
||||||
CursorChannel* cursor_channel_new (RedWorker *worker);
|
CursorChannel* cursor_channel_new (RedWorker *worker);
|
||||||
void cursor_channel_disconnect (CursorChannel *cursor_channel);
|
void cursor_channel_disconnect (CursorChannel *cursor_channel);
|
||||||
void cursor_channel_reset (CursorChannel *cursor);
|
void cursor_channel_reset (CursorChannel *cursor);
|
||||||
|
void cursor_channel_init (CursorChannel *cursor, CursorChannelClient* client);
|
||||||
void cursor_channel_process_cmd (CursorChannel *cursor, RedCursorCmd *cursor_cmd,
|
void cursor_channel_process_cmd (CursorChannel *cursor, RedCursorCmd *cursor_cmd,
|
||||||
uint32_t group_id);
|
uint32_t group_id);
|
||||||
void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode);
|
void cursor_channel_set_mouse_mode(CursorChannel *cursor, uint32_t mode);
|
||||||
|
|
||||||
CursorItem* cursor_item_new (RedCursorCmd *cmd, uint32_t group_id);
|
|
||||||
void cursor_item_unref (QXLInstance *qxl, CursorItem *cursor);
|
|
||||||
|
|
||||||
|
|
||||||
CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor,
|
CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor,
|
||||||
RedClient *client, RedsStream *stream,
|
RedClient *client, RedsStream *stream,
|
||||||
int mig_target,
|
int mig_target,
|
||||||
uint32_t *common_caps, int num_common_caps,
|
uint32_t *common_caps, int num_common_caps,
|
||||||
uint32_t *caps, int num_caps);
|
uint32_t *caps, int num_caps);
|
||||||
|
void cursor_channel_client_migrate(CursorChannelClient* client);
|
||||||
|
|
||||||
#endif /* CURSOR_CHANNEL_H_ */
|
#endif /* CURSOR_CHANNEL_H_ */
|
||||||
|
|||||||
@ -302,6 +302,8 @@ struct RedChannelClient {
|
|||||||
RedChannelClientConnectivityMonitor connectivity_monitor;
|
RedChannelClientConnectivityMonitor connectivity_monitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RED_CHANNEL_CLIENT(Client) ((RedChannelClient *)(Client))
|
||||||
|
|
||||||
struct RedChannel {
|
struct RedChannel {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|||||||
@ -9065,7 +9065,7 @@ static int common_channel_config_socket(RedChannelClient *rcc)
|
|||||||
RedClient *client = red_channel_client_get_client(rcc);
|
RedClient *client = red_channel_client_get_client(rcc);
|
||||||
MainChannelClient *mcc = red_client_get_main(client);
|
MainChannelClient *mcc = red_client_get_main(client);
|
||||||
RedsStream *stream = red_channel_client_get_stream(rcc);
|
RedsStream *stream = red_channel_client_get_stream(rcc);
|
||||||
CommonChannelClient *ccc = SPICE_CONTAINEROF(rcc, CommonChannelClient, base);
|
CommonChannelClient *ccc = COMMON_CHANNEL_CLIENT(rcc);
|
||||||
int flags;
|
int flags;
|
||||||
int delay_val;
|
int delay_val;
|
||||||
|
|
||||||
@ -9550,14 +9550,14 @@ static void red_connect_cursor(RedWorker *worker, RedClient *client, RedsStream
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RedChannelClient *rcc = &ccc->common.base;
|
RedChannelClient *rcc = RED_CHANNEL_CLIENT(ccc);
|
||||||
red_channel_client_ack_zero_messages_window(rcc);
|
red_channel_client_ack_zero_messages_window(rcc);
|
||||||
red_channel_client_push_set_ack(rcc);
|
red_channel_client_push_set_ack(rcc);
|
||||||
|
|
||||||
// TODO: why do we check for context.canvas? defer this to after display cc is connected
|
// TODO: why do we check for context.canvas? defer this to after display cc is connected
|
||||||
// and test it's canvas? this is just a test to see if there is an active renderer?
|
// and test it's canvas? this is just a test to see if there is an active renderer?
|
||||||
if (worker->surfaces[0].context.canvas && !COMMON_CHANNEL(channel)->during_target_migrate) {
|
if (worker->surfaces[0].context.canvas)
|
||||||
red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_CURSOR_INIT);
|
cursor_channel_init(channel, ccc);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void surface_dirty_region_to_rects(RedSurface *surface,
|
static void surface_dirty_region_to_rects(RedSurface *surface,
|
||||||
@ -9899,11 +9899,7 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
|
|||||||
red_channel_push(&worker->display_channel->common.base);
|
red_channel_push(&worker->display_channel->common.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor_is_connected(worker)
|
cursor_channel_init(worker->cursor_channel, NULL);
|
||||||
&& !COMMON_CHANNEL(worker->cursor_channel)->during_target_migrate) {
|
|
||||||
red_channel_pipes_add_type(RED_CHANNEL(worker->cursor_channel),
|
|
||||||
PIPE_ITEM_TYPE_CURSOR_INIT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_dev_create_primary_surface(void *opaque, void *payload)
|
void handle_dev_create_primary_surface(void *opaque, void *payload)
|
||||||
@ -10289,12 +10285,7 @@ void handle_dev_cursor_migrate(void *opaque, void *payload)
|
|||||||
RedChannelClient *rcc = msg->rcc;
|
RedChannelClient *rcc = msg->rcc;
|
||||||
|
|
||||||
spice_info("migrate cursor client");
|
spice_info("migrate cursor client");
|
||||||
spice_assert(rcc);
|
cursor_channel_client_migrate(CURSOR_CHANNEL_CLIENT(rcc));
|
||||||
if (!red_channel_client_is_connected(rcc))
|
|
||||||
return;
|
|
||||||
|
|
||||||
red_channel_client_pipe_add_type(rcc, PIPE_ITEM_TYPE_INVAL_CURSOR_CACHE);
|
|
||||||
red_channel_client_default_migrate(rcc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_dev_set_compression(void *opaque, void *payload)
|
void handle_dev_set_compression(void *opaque, void *payload)
|
||||||
|
|||||||
@ -33,6 +33,7 @@ typedef struct CommonChannelClient {
|
|||||||
int is_low_bandwidth;
|
int is_low_bandwidth;
|
||||||
} CommonChannelClient;
|
} CommonChannelClient;
|
||||||
|
|
||||||
|
#define COMMON_CHANNEL_CLIENT(Client) ((CommonChannelClient*)(Client))
|
||||||
#define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano
|
#define DISPLAY_CLIENT_TIMEOUT 30000000000ULL //nano
|
||||||
|
|
||||||
#define CHANNEL_RECEIVE_BUF_SIZE 1024
|
#define CHANNEL_RECEIVE_BUF_SIZE 1024
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user