[Spice-commits] 7 commits - server/cursor-channel.cpp server/cursor-channel.h server/dcc.cpp server/dcc-send.cpp server/display-channel.cpp server/display-channel.h server/display-channel-private.h server/image-encoders.cpp server/Makefile.am server/meson.build server/red-parse-qxl.cpp server/red-parse-qxl.h server/red-record-qxl.c server/red-record-qxl.cpp server/red-stream-device.cpp server/red-worker.cpp server/tests server/tree.cpp server/utils.hpp server/video-stream.cpp
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Aug 4 12:03:19 UTC 2021
server/Makefile.am | 2
server/cursor-channel.cpp | 32 +---
server/cursor-channel.h | 2
server/dcc-send.cpp | 68 ++++-----
server/dcc.cpp | 2
server/display-channel-private.h | 4
server/display-channel.cpp | 46 ++----
server/display-channel.h | 14 +-
server/image-encoders.cpp | 8 -
server/meson.build | 2
server/red-parse-qxl.cpp | 262 ++++++++++----------------------------
server/red-parse-qxl.h | 87 +++++-------
server/red-stream-device.cpp | 21 +--
server/red-worker.cpp | 52 ++-----
server/tests/Makefile.am | 1
server/tests/meson.build | 2
server/tests/test-qxl-parsing.cpp | 38 ++---
server/tree.cpp | 2
server/utils.hpp | 62 ++++++++
server/video-stream.cpp | 6
20 files changed, 307 insertions(+), 406 deletions(-)
New commits:
commit 708cd97212e5f39ffd971123a45eee87d3d24566
Author: Frediano Ziglio <freddy77 at gmail.com>
Date: Tue May 5 18:33:42 2020 +0100
red-parse-qxl: Encapsulate QXL resource management
Reuse code.
Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
Acked-by: Victor Toso <victortoso at redhat.com>
diff --git a/server/red-parse-qxl.cpp b/server/red-parse-qxl.cpp
index 25675e7f..87b6448d 100644
--- a/server/red-parse-qxl.cpp
+++ b/server/red-parse-qxl.cpp
@@ -77,6 +77,22 @@ static void hexdump_qxl(RedMemSlotInfo *slots, int group_id,
}
#endif
+template <typename T>
+inline RedQXLResource<T>::~RedQXLResource()
+{
+ if (qxl) {
+ red_qxl_release_resource(qxl, release_info_ext);
+ }
+}
+
+template <typename T>
+inline void RedQXLResource<T>::set_resource(QXLInstance *qxl_instance, QXLReleaseInfo *info, uint32_t group_id)
+{
+ qxl = qxl_instance;
+ release_info_ext.info = info;
+ release_info_ext.group_id = group_id;
+}
+
static inline uint32_t color_16_to_32(uint32_t color)
{
uint32_t ret;
@@ -1026,9 +1042,7 @@ static bool red_get_native_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s
if (qxl == nullptr) {
return false;
}
- red->qxl = qxl_instance;
- red->release_info_ext.info = &qxl->release_info;
- red->release_info_ext.group_id = group_id;
+ red->set_resource(qxl_instance, &qxl->release_info, group_id);
red_get_rect_ptr(&red->bbox, &qxl->bbox);
red_get_clip_ptr(slots, group_id, &red->clip, &qxl->clip);
@@ -1106,9 +1120,7 @@ static bool red_get_compat_drawable(QXLInstance *qxl_instance, RedMemSlotInfo *s
if (qxl == nullptr) {
return false;
}
- red->qxl = qxl_instance;
- red->release_info_ext.info = &qxl->release_info;
- red->release_info_ext.group_id = group_id;
+ red->set_resource(qxl_instance, &qxl->release_info, group_id);
red_get_rect_ptr(&red->bbox, &qxl->bbox);
red_get_clip_ptr(slots, group_id, &red->clip, &qxl->clip);
@@ -1240,9 +1252,6 @@ RedDrawable::~RedDrawable()
red_put_whiteness(&u.whiteness);
break;
}
- if (qxl != nullptr) {
- red_qxl_release_resource(qxl, release_info_ext);
- }
}
red::shared_ptr<RedDrawable>
@@ -1267,9 +1276,7 @@ static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
if (qxl == nullptr) {
return false;
}
- red->qxl = qxl_instance;
- red->release_info_ext.info = &qxl->release_info;
- red->release_info_ext.group_id = group_id;
+ red->set_resource(qxl_instance, &qxl->release_info, group_id);
red_get_rect_ptr(&red->area, &qxl->area);
red->update_id = qxl->update_id;
@@ -1277,12 +1284,7 @@ static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
return true;
}
-RedUpdateCmd::~RedUpdateCmd()
-{
- if (qxl != nullptr) {
- red_qxl_release_resource(qxl, release_info_ext);
- }
-}
+RedUpdateCmd::~RedUpdateCmd() = default;
red::shared_ptr<const RedUpdateCmd>
red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
@@ -1315,9 +1317,7 @@ static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, in
if (qxl == nullptr) {
return false;
}
- red->qxl = qxl_instance;
- red->release_info_ext.info = &qxl->release_info;
- red->release_info_ext.group_id = group_id;
+ red->set_resource(qxl_instance, &qxl->release_info, group_id);
red->data = qxl->data;
memslot_id = memslot_get_id(slots, addr+sizeof(*qxl));
len = memslot_max_size_virt(slots, ((intptr_t) qxl)+sizeof(*qxl), memslot_id, group_id);
@@ -1330,12 +1330,7 @@ static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, in
return true;
}
-RedMessage::~RedMessage()
-{
- if (qxl != nullptr) {
- red_qxl_release_resource(qxl, release_info_ext);
- }
-}
+RedMessage::~RedMessage() = default;
red::shared_ptr<const RedMessage>
red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots,
@@ -1403,9 +1398,7 @@ static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots
if (qxl == nullptr) {
return false;
}
- red->qxl = qxl_instance;
- red->release_info_ext.info = &qxl->release_info;
- red->release_info_ext.group_id = group_id;
+ red->set_resource(qxl_instance, &qxl->release_info, group_id);
red->surface_id = qxl->surface_id;
red->type = qxl->type;
@@ -1434,12 +1427,7 @@ static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots
return true;
}
-RedSurfaceCmd::~RedSurfaceCmd()
-{
- if (qxl) {
- red_qxl_release_resource(qxl, release_info_ext);
- }
-}
+RedSurfaceCmd::~RedSurfaceCmd() = default;
red::shared_ptr<const RedSurfaceCmd>
red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
@@ -1513,9 +1501,7 @@ static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
if (qxl == nullptr) {
return false;
}
- red->qxl = qxl_instance;
- red->release_info_ext.info = &qxl->release_info;
- red->release_info_ext.group_id = group_id;
+ red->set_resource(qxl_instance, &qxl->release_info, group_id);
red->type = qxl->type;
switch (red->type) {
@@ -1553,7 +1539,4 @@ RedCursorCmd::~RedCursorCmd()
red_put_cursor(&u.set.shape);
break;
}
- if (qxl) {
- red_qxl_release_resource(qxl, release_info_ext);
- }
}
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index 7ed0cbd9..cbea4504 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -27,10 +27,17 @@
#include "push-visibility.h"
-struct RedDrawable final: public red::simple_ptr_counted<RedDrawable> {
- ~RedDrawable();
- QXLInstance *qxl;
+template <typename T>
+struct RedQXLResource: public red::simple_ptr_counted<T> {
+ ~RedQXLResource();
+ void set_resource(QXLInstance *qxl, QXLReleaseInfo *info, uint32_t group_id);
+private:
+ QXLInstance *qxl = nullptr;
QXLReleaseInfoExt release_info_ext;
+};
+
+struct RedDrawable final: public RedQXLResource<RedDrawable> {
+ ~RedDrawable();
uint32_t surface_id;
uint8_t effect;
uint8_t type;
@@ -62,19 +69,15 @@ struct RedDrawable final: public red::simple_ptr_counted<RedDrawable> {
} u;
};
-struct RedUpdateCmd final: public red::simple_ptr_counted<RedUpdateCmd> {
+struct RedUpdateCmd final: public RedQXLResource<RedUpdateCmd> {
~RedUpdateCmd();
- QXLInstance *qxl;
- QXLReleaseInfoExt release_info_ext;
SpiceRect area;
uint32_t update_id;
uint32_t surface_id;
};
-struct RedMessage final: public red::simple_ptr_counted<RedMessage> {
+struct RedMessage final: public RedQXLResource<RedMessage> {
~RedMessage();
- QXLInstance *qxl;
- QXLReleaseInfoExt release_info_ext;
int len;
uint8_t *data;
};
@@ -87,10 +90,8 @@ typedef struct RedSurfaceCreate {
uint8_t *data;
} RedSurfaceCreate;
-struct RedSurfaceCmd final: public red::simple_ptr_counted<RedSurfaceCmd> {
+struct RedSurfaceCmd final: public RedQXLResource<RedSurfaceCmd> {
~RedSurfaceCmd();
- QXLInstance *qxl;
- QXLReleaseInfoExt release_info_ext;
uint32_t surface_id;
uint8_t type;
uint32_t flags;
@@ -99,10 +100,8 @@ struct RedSurfaceCmd final: public red::simple_ptr_counted<RedSurfaceCmd> {
} u;
};
-struct RedCursorCmd final: public red::simple_ptr_counted<RedCursorCmd> {
+struct RedCursorCmd final: public RedQXLResource<RedCursorCmd> {
~RedCursorCmd();
- QXLInstance *qxl;
- QXLReleaseInfoExt release_info_ext;
uint8_t type;
union {
struct {
commit b6aa5798b7ee1754bf2f375db09eae8dd162c7fb
Author: Frediano Ziglio <freddy77 at gmail.com>
Date: Tue May 5 17:39:14 2020 +0100
red-parse-qxl: Use a base reference class for RedDrawable
Don't code manually reference counting for this structure
Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
Acked-by: Victor Toso <victortoso at redhat.com>
diff --git a/server/dcc-send.cpp b/server/dcc-send.cpp
index 4d1558a9..b43b7a1f 100644
--- a/server/dcc-send.cpp
+++ b/server/dcc-send.cpp
@@ -530,7 +530,7 @@ static void marshall_qxl_draw_fill(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *brush_pat_out;
SpiceMarshaller *mask_bitmap_out;
SpiceFill fill;
@@ -561,7 +561,7 @@ static void surface_lossy_region_update(DisplayChannelClient *dcc,
}
surface_lossy_region = &dcc->priv->surface_client_lossy_region[item->surface_id];
- drawable = item->red_drawable;
+ drawable = item->red_drawable.get();
if (drawable->clip.type == SPICE_CLIP_TYPE_RECTS ) {
QRegion clip_rgn;
@@ -636,7 +636,7 @@ static bool drawable_depends_on_areas(Drawable *drawable, int surface_ids[],
int drawable_has_shadow;
SpiceRect shadow_rect = {0, 0, 0, 0};
- red_drawable = drawable->red_drawable;
+ red_drawable = drawable->red_drawable.get();
drawable_has_shadow = has_shadow(red_drawable);
if (drawable_has_shadow) {
@@ -737,7 +737,7 @@ static void red_add_lossless_drawable_dependencies(DisplayChannelClient *dcc,
int num_deps)
{
DisplayChannel *display = DCC_TO_DC(dcc);
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int sync_rendered = FALSE;
int i;
@@ -803,7 +803,7 @@ static void red_lossy_marshall_qxl_draw_fill(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int dest_allowed_lossy = FALSE;
int dest_is_lossy = FALSE;
@@ -860,7 +860,7 @@ static FillBitsType red_marshall_qxl_draw_opaque(DisplayChannelClient *dcc,
int src_allowed_lossy)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *brush_pat_out;
SpiceMarshaller *src_bitmap_out;
SpiceMarshaller *mask_bitmap_out;
@@ -892,7 +892,7 @@ static void red_lossy_marshall_qxl_draw_opaque(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int src_allowed_lossy;
int rop;
@@ -956,7 +956,7 @@ static FillBitsType red_marshall_qxl_draw_copy(DisplayChannelClient *dcc,
int src_allowed_lossy)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *src_bitmap_out;
SpiceMarshaller *mask_bitmap_out;
SpiceCopy copy;
@@ -981,7 +981,7 @@ static void red_lossy_marshall_qxl_draw_copy(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int has_mask = !!drawable->u.copy.mask.bitmap;
int src_is_lossy;
BitmapData src_bitmap_data;
@@ -1005,7 +1005,7 @@ static void red_marshall_qxl_draw_transparent(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *src_bitmap_out;
SpiceTransparent transparent;
@@ -1023,7 +1023,7 @@ static void red_lossy_marshall_qxl_draw_transparent(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int src_is_lossy;
BitmapData src_bitmap_data;
@@ -1051,7 +1051,7 @@ static FillBitsType red_marshall_qxl_draw_alpha_blend(DisplayChannelClient *dcc,
int src_allowed_lossy)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *src_bitmap_out;
SpiceAlphaBlend alpha_blend;
FillBitsType src_send_type;
@@ -1073,7 +1073,7 @@ static void red_lossy_marshall_qxl_draw_alpha_blend(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int src_is_lossy;
BitmapData src_bitmap_data;
FillBitsType src_send_type;
@@ -1099,7 +1099,7 @@ static void red_marshall_qxl_copy_bits(RedChannelClient *rcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpicePoint copy_bits;
rcc->init_send_data(SPICE_MSG_DISPLAY_COPY_BITS);
@@ -1114,7 +1114,7 @@ static void red_lossy_marshall_qxl_copy_bits(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceRect src_rect;
int horz_offset;
int vert_offset;
@@ -1142,7 +1142,7 @@ static void red_marshall_qxl_draw_blend(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *src_bitmap_out;
SpiceMarshaller *mask_bitmap_out;
SpiceBlend blend;
@@ -1165,7 +1165,7 @@ static void red_lossy_marshall_qxl_draw_blend(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int src_is_lossy;
BitmapData src_bitmap_data;
int dest_is_lossy;
@@ -1206,7 +1206,7 @@ static void red_marshall_qxl_draw_blackness(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *mask_bitmap_out;
SpiceBlackness blackness;
@@ -1226,7 +1226,7 @@ static void red_lossy_marshall_qxl_draw_blackness(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int has_mask = !!drawable->u.blackness.mask.bitmap;
red_marshall_qxl_draw_blackness(dcc, base_marshaller, dpi);
@@ -1239,7 +1239,7 @@ static void red_marshall_qxl_draw_whiteness(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *mask_bitmap_out;
SpiceWhiteness whiteness;
@@ -1259,7 +1259,7 @@ static void red_lossy_marshall_qxl_draw_whiteness(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int has_mask = !!drawable->u.whiteness.mask.bitmap;
red_marshall_qxl_draw_whiteness(dcc, base_marshaller, dpi);
@@ -1271,7 +1271,7 @@ static void red_marshall_qxl_draw_inverse(DisplayChannelClient *dcc,
SpiceMarshaller *base_marshaller,
Drawable *item)
{
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *mask_bitmap_out;
SpiceInvers inverse;
@@ -1298,7 +1298,7 @@ static void red_marshall_qxl_draw_rop3(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceRop3 rop3;
SpiceMarshaller *src_bitmap_out;
SpiceMarshaller *brush_pat_out;
@@ -1326,7 +1326,7 @@ static void red_lossy_marshall_qxl_draw_rop3(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int src_is_lossy;
BitmapData src_bitmap_data;
int brush_is_lossy;
@@ -1380,7 +1380,7 @@ static void red_marshall_qxl_draw_composite(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceMarshaller *src_bitmap_out;
SpiceMarshaller *mask_bitmap_out;
SpiceComposite composite;
@@ -1404,7 +1404,7 @@ static void red_lossy_marshall_qxl_draw_composite(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int src_is_lossy;
BitmapData src_bitmap_data;
int mask_is_lossy;
@@ -1459,7 +1459,7 @@ static void red_marshall_qxl_draw_stroke(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceStroke stroke;
SpiceMarshaller *brush_pat_out;
SpiceMarshaller *style_out;
@@ -1483,7 +1483,7 @@ static void red_lossy_marshall_qxl_draw_stroke(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int brush_is_lossy;
BitmapData brush_bitmap_data;
int dest_is_lossy = FALSE;
@@ -1537,7 +1537,7 @@ static void red_marshall_qxl_draw_text(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
SpiceText text;
SpiceMarshaller *brush_pat_out;
SpiceMarshaller *back_brush_pat_out;
@@ -1563,7 +1563,7 @@ static void red_lossy_marshall_qxl_draw_text(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
int fg_is_lossy;
BitmapData fg_bitmap_data;
int bg_is_lossy;
@@ -1669,7 +1669,7 @@ static bool red_marshall_stream_data(DisplayChannelClient *dcc,
frame_mm_time,
©->src_bitmap->u.bitmap,
©->src_area, stream->top_down,
- drawable->red_drawable,
+ drawable->red_drawable.get(),
&outbuf);
switch (ret) {
case VIDEO_ENCODER_FRAME_DROP:
@@ -2019,7 +2019,7 @@ static void marshall_lossless_qxl_drawable(DisplayChannelClient *dcc,
RedDrawablePipeItem *dpi)
{
Drawable *item = dpi->drawable;
- RedDrawable *drawable = item->red_drawable;
+ RedDrawable *drawable = item->red_drawable.get();
switch (drawable->type) {
case QXL_DRAW_FILL:
@@ -2117,7 +2117,7 @@ static void marshall_stream_start(DisplayChannelClient *dcc,
stream_create.dest = stream->dest_area;
if (stream->current) {
- RedDrawable *red_drawable = stream->current->red_drawable;
+ RedDrawable *red_drawable = stream->current->red_drawable.get();
stream_create.clip = red_drawable->clip;
} else {
stream_create.clip.type = SPICE_CLIP_TYPE_RECTS;
@@ -2171,7 +2171,7 @@ static void marshall_upgrade(DisplayChannelClient *dcc, SpiceMarshaller *m,
spice_assert(channel && item && item->drawable);
dcc->init_send_data(SPICE_MSG_DISPLAY_DRAW_COPY);
- red_drawable = item->drawable->red_drawable;
+ red_drawable = item->drawable->red_drawable.get();
spice_assert(red_drawable->type == QXL_DRAW_COPY);
spice_assert(red_drawable->u.copy.rop_descriptor == SPICE_ROPD_OP_PUT);
spice_assert(red_drawable->u.copy.mask.bitmap == nullptr);
diff --git a/server/dcc.cpp b/server/dcc.cpp
index ef98af3b..74e4a821 100644
--- a/server/dcc.cpp
+++ b/server/dcc.cpp
@@ -665,7 +665,7 @@ int dcc_compress_image(DisplayChannelClient *dcc,
break;
case SPICE_IMAGE_COMPRESSION_GLZ:
success = image_encoders_compress_glz(&dcc->priv->encoders, dest, src,
- drawable->red_drawable, &drawable->glz_retention,
+ drawable->red_drawable.get(), &drawable->glz_retention,
o_comp_data,
display_channel->priv->enable_zlib_glz_wrap);
if (success) {
diff --git a/server/display-channel.cpp b/server/display-channel.cpp
index 00f2e861..5093ae03 100644
--- a/server/display-channel.cpp
+++ b/server/display-channel.cpp
@@ -799,7 +799,7 @@ static bool current_add_with_shadow(DisplayChannel *display, Ring *ring, Drawabl
++display->priv->add_with_shadow_count;
#endif
- RedDrawable *red_drawable = item->red_drawable;
+ RedDrawable *red_drawable = item->red_drawable.get();
SpicePoint delta = {
.x = red_drawable->u.copy_bits.src_pos.x - red_drawable->bbox.left,
.y = red_drawable->u.copy_bits.src_pos.y - red_drawable->bbox.top
@@ -1043,7 +1043,7 @@ static bool current_add(DisplayChannel *display, Ring *ring, Drawable *drawable)
static bool drawable_can_stream(DisplayChannel *display, Drawable *drawable)
{
- RedDrawable *red_drawable = drawable->red_drawable;
+ RedDrawable *red_drawable = drawable->red_drawable.get();
SpiceImage *image;
if (display->priv->stream_video == SPICE_STREAM_VIDEO_OFF) {
@@ -1131,7 +1131,7 @@ static void surface_read_bits(DisplayChannel *display, int surface_id,
static void handle_self_bitmap(DisplayChannel *display, Drawable *drawable)
{
- RedDrawable *red_drawable = drawable->red_drawable;
+ RedDrawable *red_drawable = drawable->red_drawable.get();
SpiceImage *image;
int32_t width;
int32_t height;
@@ -1274,7 +1274,7 @@ static bool validate_drawable_bbox(DisplayChannel *display, RedDrawable *drawabl
* @return initialized Drawable or NULL on failure
*/
static Drawable *display_channel_get_drawable(DisplayChannel *display, uint8_t effect,
- RedDrawable *red_drawable,
+ red::shared_ptr<RedDrawable> &&red_drawable,
uint32_t process_commands_generation)
{
Drawable *drawable;
@@ -1282,7 +1282,7 @@ static Drawable *display_channel_get_drawable(DisplayChannel *display, uint8_t e
/* Validate all surface ids before updating counters
* to avoid invalid updates if we find an invalid id.
*/
- if (!validate_drawable_bbox(display, red_drawable)) {
+ if (!validate_drawable_bbox(display, red_drawable.get())) {
return nullptr;
}
for (const auto surface_id : red_drawable->surface_deps) {
@@ -1297,12 +1297,14 @@ static Drawable *display_channel_get_drawable(DisplayChannel *display, uint8_t e
}
drawable->tree_item.effect = effect;
- drawable->red_drawable = red_drawable_ref(red_drawable);
drawable->surface_id = red_drawable->surface_id;
display->priv->surfaces[drawable->surface_id].refs++;
memcpy(drawable->surface_deps, red_drawable->surface_deps, sizeof(drawable->surface_deps));
+
+ drawable->red_drawable = red_drawable;
+
/*
surface->refs is affected by a drawable (that is
dependent on the surface) as long as the drawable is alive.
@@ -1321,7 +1323,7 @@ static Drawable *display_channel_get_drawable(DisplayChannel *display, uint8_t e
static void display_channel_add_drawable(DisplayChannel *display, Drawable *drawable)
{
int surface_id = drawable->surface_id;
- RedDrawable *red_drawable = drawable->red_drawable;
+ RedDrawable *red_drawable = drawable->red_drawable.get();
red_drawable->mm_time = reds_get_mm_time();
@@ -1368,11 +1370,12 @@ static void display_channel_add_drawable(DisplayChannel *display, Drawable *draw
#endif
}
-void display_channel_process_draw(DisplayChannel *display, RedDrawable *red_drawable,
+void display_channel_process_draw(DisplayChannel *display,
+ red::shared_ptr<RedDrawable> &&red_drawable,
uint32_t process_commands_generation)
{
Drawable *drawable =
- display_channel_get_drawable(display, red_drawable->effect, red_drawable,
+ display_channel_get_drawable(display, red_drawable->effect, std::move(red_drawable),
process_commands_generation);
if (!drawable) {
@@ -1630,9 +1633,6 @@ void drawable_unref(Drawable *drawable)
glz_retention_detach_drawables(&drawable->glz_retention);
- if (drawable->red_drawable) {
- red_drawable_unref(drawable->red_drawable);
- }
drawable_free(display, drawable);
}
diff --git a/server/display-channel.h b/server/display-channel.h
index eb25407c..86784131 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -64,7 +64,7 @@ struct Drawable {
RingItem list_link;
DrawItem tree_item;
GList *pipes;
- RedDrawable *red_drawable;
+ red::shared_ptr<RedDrawable> red_drawable;
GlzImageRetention glz_retention;
@@ -121,14 +121,14 @@ void display_channel_free_glz_drawables (DisplayCha
void display_channel_destroy_surface_wait (DisplayChannel *display,
uint32_t surface_id);
void display_channel_destroy_surfaces (DisplayChannel *display);
-void display_channel_process_draw (DisplayChannel *display,
- RedDrawable *red_drawable,
- uint32_t process_commands_generation);
void display_channel_gl_scanout (DisplayChannel *display);
void display_channel_gl_draw (DisplayChannel *display,
SpiceMsgDisplayGlDraw *draw);
void display_channel_gl_draw_done (DisplayChannel *display);
+void display_channel_process_draw(DisplayChannel *display,
+ red::shared_ptr<RedDrawable> &&red_drawable,
+ uint32_t process_commands_generation);
void display_channel_process_surface_cmd(DisplayChannel *display,
red::shared_ptr<const RedSurfaceCmd> &&surface_cmd,
bool loadvm);
diff --git a/server/image-encoders.cpp b/server/image-encoders.cpp
index bb70fa63..4ebcb753 100644
--- a/server/image-encoders.cpp
+++ b/server/image-encoders.cpp
@@ -67,7 +67,7 @@ struct GlzDrawableInstanceItem {
struct RedGlzDrawable {
RingItem link; // ordered by the time it was encoded
RingItem drawable_link;
- RedDrawable *red_drawable;
+ red::shared_ptr<RedDrawable> red_drawable;
GlzDrawableInstanceItem instances_pool[MAX_GLZ_DRAWABLE_INSTANCES];
Ring instances;
uint8_t instances_count;
@@ -524,7 +524,7 @@ static void glz_drawable_instance_item_free(GlzDrawableInstanceItem *instance)
if (glz_drawable->has_drawable) {
ring_remove(&glz_drawable->drawable_link);
}
- red_drawable_unref(glz_drawable->red_drawable);
+ glz_drawable->red_drawable.reset();
glz_drawable->encoders->shared_data->glz_drawable_count--;
if (ring_item_is_linked(&glz_drawable->link)) {
ring_remove(&glz_drawable->link);
@@ -1166,10 +1166,10 @@ static RedGlzDrawable *get_glz_drawable(ImageEncoders *enc, RedDrawable *red_dra
}
}
- ret = g_new(RedGlzDrawable, 1);
+ ret = g_new0(RedGlzDrawable, 1);
ret->encoders = enc;
- ret->red_drawable = red_drawable_ref(red_drawable);
+ ret->red_drawable.reset(red_drawable);
ret->has_drawable = TRUE;
ret->instances_count = 0;
ring_init(&ret->instances);
diff --git a/server/red-parse-qxl.cpp b/server/red-parse-qxl.cpp
index 6dc877d5..25675e7f 100644
--- a/server/red-parse-qxl.cpp
+++ b/server/red-parse-qxl.cpp
@@ -1193,89 +1193,71 @@ static bool red_get_drawable(QXLInstance *qxl, RedMemSlotInfo *slots, int group_
return ret;
}
-static void red_put_drawable(RedDrawable *red)
+RedDrawable::~RedDrawable()
{
- red_put_clip(&red->clip);
- if (red->self_bitmap_image) {
- red_put_image(red->self_bitmap_image);
+ red_put_clip(&clip);
+ if (self_bitmap_image) {
+ red_put_image(self_bitmap_image);
}
- switch (red->type) {
+ switch (type) {
case QXL_DRAW_ALPHA_BLEND:
- red_put_alpha_blend(&red->u.alpha_blend);
+ red_put_alpha_blend(&u.alpha_blend);
break;
case QXL_DRAW_BLACKNESS:
- red_put_blackness(&red->u.blackness);
+ red_put_blackness(&u.blackness);
break;
case QXL_DRAW_BLEND:
- red_put_blend(&red->u.blend);
+ red_put_blend(&u.blend);
break;
case QXL_DRAW_COPY:
- red_put_copy(&red->u.copy);
+ red_put_copy(&u.copy);
break;
case QXL_DRAW_FILL:
- red_put_fill(&red->u.fill);
+ red_put_fill(&u.fill);
break;
case QXL_DRAW_OPAQUE:
- red_put_opaque(&red->u.opaque);
+ red_put_opaque(&u.opaque);
break;
case QXL_DRAW_INVERS:
- red_put_invers(&red->u.invers);
+ red_put_invers(&u.invers);
break;
case QXL_DRAW_ROP3:
- red_put_rop3(&red->u.rop3);
+ red_put_rop3(&u.rop3);
break;
case QXL_DRAW_COMPOSITE:
- red_put_composite(&red->u.composite);
+ red_put_composite(&u.composite);
break;
case QXL_DRAW_STROKE:
- red_put_stroke(&red->u.stroke);
+ red_put_stroke(&u.stroke);
break;
case QXL_DRAW_TEXT:
- red_put_text_ptr(&red->u.text);
+ red_put_text_ptr(&u.text);
break;
case QXL_DRAW_TRANSPARENT:
- red_put_transparent(&red->u.transparent);
+ red_put_transparent(&u.transparent);
break;
case QXL_DRAW_WHITENESS:
- red_put_whiteness(&red->u.whiteness);
+ red_put_whiteness(&u.whiteness);
break;
}
- if (red->qxl != nullptr) {
- red_qxl_release_resource(red->qxl, red->release_info_ext);
+ if (qxl != nullptr) {
+ red_qxl_release_resource(qxl, release_info_ext);
}
}
-RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr,
- uint32_t flags)
+red::shared_ptr<RedDrawable>
+red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr, uint32_t flags)
{
- auto red = g_new0(RedDrawable, 1);
+ auto red = red::make_shared<RedDrawable>();
- red->refs = 1;
-
- if (!red_get_drawable(qxl, slots, group_id, red, addr, flags)) {
- red_drawable_unref(red);
- return nullptr;
+ if (!red_get_drawable(qxl, slots, group_id, red.get(), addr, flags)) {
+ red.reset();
}
return red;
}
-RedDrawable *red_drawable_ref(RedDrawable *drawable)
-{
- drawable->refs++;
- return drawable;
-}
-
-void red_drawable_unref(RedDrawable *red_drawable)
-{
- if (--red_drawable->refs) {
- return;
- }
- red_put_drawable(red_drawable);
- g_free(red_drawable);
-}
-
static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
RedUpdateCmd *red, QXLPHYSICAL addr)
{
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index 52c5e376..7ed0cbd9 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -27,8 +27,8 @@
#include "push-visibility.h"
-typedef struct RedDrawable {
- int refs;
+struct RedDrawable final: public red::simple_ptr_counted<RedDrawable> {
+ ~RedDrawable();
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
uint32_t surface_id;
@@ -60,7 +60,7 @@ typedef struct RedDrawable {
SpiceWhiteness whiteness;
SpiceComposite composite;
} u;
-} RedDrawable;
+};
struct RedUpdateCmd final: public red::simple_ptr_counted<RedUpdateCmd> {
~RedUpdateCmd();
@@ -120,11 +120,9 @@ struct RedCursorCmd final: public red::simple_ptr_counted<RedCursorCmd> {
void red_get_rect_ptr(SpiceRect *red, const QXLRect *qxl);
-RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr,
- uint32_t flags);
-RedDrawable *red_drawable_ref(RedDrawable *drawable);
-void red_drawable_unref(RedDrawable *red_drawable);
+red::shared_ptr<RedDrawable>
+red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr, uint32_t flags);
red::shared_ptr<const RedUpdateCmd>
red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
diff --git a/server/red-worker.cpp b/server/red-worker.cpp
index 3d91da13..d52f375a 100644
--- a/server/red-worker.cpp
+++ b/server/red-worker.cpp
@@ -191,15 +191,13 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
worker->display_poll_tries = 0;
switch (ext_cmd.cmd.type) {
case QXL_CMD_DRAW: {
- RedDrawable *red_drawable;
- red_drawable = red_drawable_new(worker->qxl, &worker->mem_slots,
- ext_cmd.group_id, ext_cmd.cmd.data,
- ext_cmd.flags); // returns with 1 ref
+ auto red_drawable = red_drawable_new(worker->qxl, &worker->mem_slots,
+ ext_cmd.group_id, ext_cmd.cmd.data,
+ ext_cmd.flags); // returns with 1 ref
- if (red_drawable != nullptr) {
- display_channel_process_draw(worker->display_channel, red_drawable,
+ if (red_drawable) {
+ display_channel_process_draw(worker->display_channel, std::move(red_drawable),
worker->process_display_generation);
- red_drawable_unref(red_drawable);
}
break;
}
diff --git a/server/tree.cpp b/server/tree.cpp
index 8567ae13..b95ae602 100644
--- a/server/tree.cpp
+++ b/server/tree.cpp
@@ -136,7 +136,7 @@ static void dump_item(TreeItem *item, void *data)
printf(" ");
}
printf(item_prefix, 0);
- show_red_drawable(drawable->red_drawable, nullptr);
+ show_red_drawable(drawable->red_drawable.get(), nullptr);
for (i = 0; i < di->level; i++) {
printf(" ");
}
diff --git a/server/video-stream.cpp b/server/video-stream.cpp
index 162bb25d..9281d5f4 100644
--- a/server/video-stream.cpp
+++ b/server/video-stream.cpp
@@ -224,7 +224,7 @@ static bool is_next_stream_frame(const Drawable *candidate,
return FALSE;
}
- red_drawable = candidate->red_drawable;
+ red_drawable = candidate->red_drawable.get();
if (!container_candidate_allowed) {
SpiceRect* candidate_src;
@@ -692,13 +692,13 @@ static void update_client_playback_delay(void *opaque, uint32_t delay_ms)
static void bitmap_ref(gpointer data)
{
auto red_drawable = (RedDrawable*)data;
- red_drawable_ref(red_drawable);
+ shared_ptr_add_ref(red_drawable);
}
static void bitmap_unref(gpointer data)
{
auto red_drawable = (RedDrawable*)data;
- red_drawable_unref(red_drawable);
+ shared_ptr_unref(red_drawable);
}
/* A helper for dcc_create_stream(). */
commit 110b97e51e02ace4a17e95ae4236deed42acba2d
Author: Frediano Ziglio <freddy77 at gmail.com>
Date: Tue May 5 17:03:58 2020 +0100
red-parse-qxl: Use a base reference class for RedUpdateCmd
Don't code manually reference counting for this structure
Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
Acked-by: Victor Toso <victortoso at redhat.com>
diff --git a/server/red-parse-qxl.cpp b/server/red-parse-qxl.cpp
index 419da12b..6dc877d5 100644
--- a/server/red-parse-qxl.cpp
+++ b/server/red-parse-qxl.cpp
@@ -1295,45 +1295,26 @@ static bool red_get_update_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
return true;
}
-static void red_put_update_cmd(RedUpdateCmd *red)
+RedUpdateCmd::~RedUpdateCmd()
{
- if (red->qxl != nullptr) {
- red_qxl_release_resource(red->qxl, red->release_info_ext);
+ if (qxl != nullptr) {
+ red_qxl_release_resource(qxl, release_info_ext);
}
}
-RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr)
+red::shared_ptr<const RedUpdateCmd>
+red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr)
{
- RedUpdateCmd *red;
-
- red = g_new0(RedUpdateCmd, 1);
+ auto red = red::make_shared<RedUpdateCmd>();
- red->refs = 1;
-
- if (!red_get_update_cmd(qxl, slots, group_id, red, addr)) {
- red_update_cmd_unref(red);
- return nullptr;
+ if (!red_get_update_cmd(qxl, slots, group_id, red.get(), addr)) {
+ red.reset();
}
return red;
}
-RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red)
-{
- red->refs++;
- return red;
-}
-
-void red_update_cmd_unref(RedUpdateCmd *red)
-{
- if (--red->refs) {
- return;
- }
- red_put_update_cmd(red);
- g_free(red);
-}
-
static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, int group_id,
RedMessage *red, QXLPHYSICAL addr)
{
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index 0226659a..52c5e376 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -62,14 +62,14 @@ typedef struct RedDrawable {
} u;
} RedDrawable;
-typedef struct RedUpdateCmd {
+struct RedUpdateCmd final: public red::simple_ptr_counted<RedUpdateCmd> {
+ ~RedUpdateCmd();
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
- int refs;
SpiceRect area;
uint32_t update_id;
uint32_t surface_id;
-} RedUpdateCmd;
+};
struct RedMessage final: public red::simple_ptr_counted<RedMessage> {
~RedMessage();
@@ -126,10 +126,9 @@ RedDrawable *red_drawable_new(QXLInstance *qxl, RedMemSlotInfo *slots,
RedDrawable *red_drawable_ref(RedDrawable *drawable);
void red_drawable_unref(RedDrawable *red_drawable);
-RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr);
-RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red);
-void red_update_cmd_unref(RedUpdateCmd *red);
+red::shared_ptr<const RedUpdateCmd>
+red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr);
red::shared_ptr<const RedMessage>
red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots,
diff --git a/server/red-worker.cpp b/server/red-worker.cpp
index 6e2eeb6d..3d91da13 100644
--- a/server/red-worker.cpp
+++ b/server/red-worker.cpp
@@ -204,11 +204,9 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
break;
}
case QXL_CMD_UPDATE: {
- RedUpdateCmd *update;
-
- update = red_update_cmd_new(worker->qxl, &worker->mem_slots,
- ext_cmd.group_id, ext_cmd.cmd.data);
- if (update == nullptr) {
+ auto update = red_update_cmd_new(worker->qxl, &worker->mem_slots,
+ ext_cmd.group_id, ext_cmd.cmd.data);
+ if (!update) {
break;
}
if (!display_channel_validate_surface(worker->display_channel, update->surface_id)) {
@@ -217,7 +215,6 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
display_channel_draw(worker->display_channel, &update->area, update->surface_id);
red_qxl_notify_update(worker->qxl, update->update_id);
}
- red_update_cmd_unref(update);
break;
}
case QXL_CMD_MESSAGE: {
commit 45f2d94ac36c67ec6a610ae2b043631de0d7d37e
Author: Frediano Ziglio <freddy77 at gmail.com>
Date: Tue May 5 16:59:52 2020 +0100
red-parse-qxl: Use a base reference class for RedMessage
Don't code manually reference counting for this structure
Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
Acked-by: Victor Toso <victortoso at redhat.com>
diff --git a/server/red-parse-qxl.cpp b/server/red-parse-qxl.cpp
index 66f6b5d7..419da12b 100644
--- a/server/red-parse-qxl.cpp
+++ b/server/red-parse-qxl.cpp
@@ -1367,45 +1367,26 @@ static bool red_get_message(QXLInstance *qxl_instance, RedMemSlotInfo *slots, in
return true;
}
-static void red_put_message(RedMessage *red)
+RedMessage::~RedMessage()
{
- if (red->qxl != nullptr) {
- red_qxl_release_resource(red->qxl, red->release_info_ext);
+ if (qxl != nullptr) {
+ red_qxl_release_resource(qxl, release_info_ext);
}
}
-RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr)
+red::shared_ptr<const RedMessage>
+red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr)
{
- RedMessage *red;
-
- red = g_new0(RedMessage, 1);
-
- red->refs = 1;
+ auto red = red::make_shared<RedMessage>();
- if (!red_get_message(qxl, slots, group_id, red, addr)) {
- red_message_unref(red);
- return nullptr;
+ if (!red_get_message(qxl, slots, group_id, red.get(), addr)) {
+ red.reset();
}
return red;
}
-RedMessage *red_message_ref(RedMessage *red)
-{
- red->refs++;
- return red;
-}
-
-void red_message_unref(RedMessage *red)
-{
- if (--red->refs) {
- return;
- }
- red_put_message(red);
- g_free(red);
-}
-
static unsigned int surface_format_to_bpp(uint32_t format)
{
switch (format) {
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index 1eb0d928..0226659a 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -71,13 +71,13 @@ typedef struct RedUpdateCmd {
uint32_t surface_id;
} RedUpdateCmd;
-typedef struct RedMessage {
+struct RedMessage final: public red::simple_ptr_counted<RedMessage> {
+ ~RedMessage();
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
- int refs;
int len;
uint8_t *data;
-} RedMessage;
+};
typedef struct RedSurfaceCreate {
uint32_t format;
@@ -131,10 +131,9 @@ RedUpdateCmd *red_update_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
RedUpdateCmd *red_update_cmd_ref(RedUpdateCmd *red);
void red_update_cmd_unref(RedUpdateCmd *red);
-RedMessage *red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr);
-RedMessage *red_message_ref(RedMessage *red);
-void red_message_unref(RedMessage *red);
+red::shared_ptr<const RedMessage>
+red_message_new(QXLInstance *qxl, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr);
bool red_validate_surface(uint32_t width, uint32_t height,
int32_t stride, uint32_t format);
diff --git a/server/red-worker.cpp b/server/red-worker.cpp
index 62028a53..6e2eeb6d 100644
--- a/server/red-worker.cpp
+++ b/server/red-worker.cpp
@@ -221,17 +221,14 @@ static int red_process_display(RedWorker *worker, int *ring_is_empty)
break;
}
case QXL_CMD_MESSAGE: {
- RedMessage *message;
-
- message = red_message_new(worker->qxl, &worker->mem_slots,
- ext_cmd.group_id, ext_cmd.cmd.data);
- if (message == nullptr) {
+ auto message = red_message_new(worker->qxl, &worker->mem_slots,
+ ext_cmd.group_id, ext_cmd.cmd.data);
+ if (!message) {
break;
}
#ifdef DEBUG
spice_warning("MESSAGE: %.*s", message->len, message->data);
#endif
- red_message_unref(message);
break;
}
case QXL_CMD_SURFACE:
commit 6eac8cc08f30cd769849f0a0c71702c1bb93b6b8
Author: Frediano Ziglio <freddy77 at gmail.com>
Date: Tue May 5 16:34:39 2020 +0100
red-parse-qxl: Use a base reference class for RedSurfaceCmd
Don't code manually reference counting for this structure
Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
Acked-by: Victor Toso <victortoso at redhat.com>
diff --git a/server/display-channel-private.h b/server/display-channel-private.h
index 03077de1..49026663 100644
--- a/server/display-channel-private.h
+++ b/server/display-channel-private.h
@@ -54,10 +54,10 @@ typedef struct RedSurface {
//fix me - better handling here
/* 'create_cmd' holds surface data through a pointer to guest memory, it
* must be valid as long as the surface is valid */
- RedSurfaceCmd *create_cmd;
+ red::shared_ptr<const RedSurfaceCmd> create_cmd;
/* QEMU expects the guest data for the command to be valid as long as the
* surface is valid */
- RedSurfaceCmd *destroy_cmd;
+ red::shared_ptr<const RedSurfaceCmd> destroy_cmd;
} RedSurface;
typedef struct MonitorsConfig {
diff --git a/server/display-channel.cpp b/server/display-channel.cpp
index 52abe18f..00f2e861 100644
--- a/server/display-channel.cpp
+++ b/server/display-channel.cpp
@@ -241,14 +241,8 @@ void display_channel_surface_unref(DisplayChannel *display, uint32_t surface_id)
spice_assert(surface->context.canvas);
surface->context.canvas->ops->destroy(surface->context.canvas);
- if (surface->create_cmd != nullptr) {
- red_surface_cmd_unref(surface->create_cmd);
- surface->create_cmd = nullptr;
- }
- if (surface->destroy_cmd != nullptr) {
- red_surface_cmd_unref(surface->destroy_cmd);
- surface->destroy_cmd = nullptr;
- }
+ surface->create_cmd.reset();
+ surface->destroy_cmd.reset();
region_destroy(&surface->draw_dirty_region);
surface->context.canvas = nullptr;
@@ -2098,8 +2092,8 @@ void display_channel_create_surface(DisplayChannel *display, uint32_t surface_id
}
memset(data, 0, height*abs(stride));
}
- g_warn_if_fail(surface->create_cmd == nullptr);
- g_warn_if_fail(surface->destroy_cmd == nullptr);
+ g_warn_if_fail(!surface->create_cmd);
+ g_warn_if_fail(!surface->destroy_cmd);
ring_init(&surface->current);
ring_init(&surface->current_list);
ring_init(&surface->depend_on_me);
@@ -2230,8 +2224,8 @@ DisplayChannel::DisplayChannel(RedsState *reds,
}
void display_channel_process_surface_cmd(DisplayChannel *display,
- RedSurfaceCmd *surface_cmd,
- int loadvm)
+ red::shared_ptr<const RedSurfaceCmd> &&surface_cmd,
+ bool loadvm)
{
uint32_t surface_id;
RedSurface *surface;
@@ -2266,7 +2260,7 @@ void display_channel_process_surface_cmd(DisplayChannel *display,
reloaded_surface,
// reloaded surfaces will be sent on demand
!reloaded_surface);
- surface->create_cmd = red_surface_cmd_ref(surface_cmd);
+ surface->create_cmd = surface_cmd;
break;
}
case QXL_SURFACE_CMD_DESTROY:
@@ -2274,7 +2268,7 @@ void display_channel_process_surface_cmd(DisplayChannel *display,
spice_warning("avoiding destroying a surface twice");
break;
}
- surface->destroy_cmd = red_surface_cmd_ref(surface_cmd);
+ surface->destroy_cmd = surface_cmd;
display_channel_destroy_surface(display, surface_id);
break;
default:
diff --git a/server/display-channel.h b/server/display-channel.h
index da8ae07f..eb25407c 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -124,14 +124,14 @@ void display_channel_destroy_surfaces (DisplayCha
void display_channel_process_draw (DisplayChannel *display,
RedDrawable *red_drawable,
uint32_t process_commands_generation);
-void display_channel_process_surface_cmd (DisplayChannel *display,
- RedSurfaceCmd *surface_cmd,
- int loadvm);
void display_channel_gl_scanout (DisplayChannel *display);
void display_channel_gl_draw (DisplayChannel *display,
SpiceMsgDisplayGlDraw *draw);
void display_channel_gl_draw_done (DisplayChannel *display);
+void display_channel_process_surface_cmd(DisplayChannel *display,
+ red::shared_ptr<const RedSurfaceCmd> &&surface_cmd,
+ bool loadvm);
void display_channel_update_monitors_config(DisplayChannel *display, const QXLMonitorsConfig *config,
uint16_t count, uint16_t max_allowed);
void display_channel_set_monitors_config_to_primary(DisplayChannel *display);
diff --git a/server/red-parse-qxl.cpp b/server/red-parse-qxl.cpp
index 198179a3..66f6b5d7 100644
--- a/server/red-parse-qxl.cpp
+++ b/server/red-parse-qxl.cpp
@@ -1490,45 +1490,26 @@ static bool red_get_surface_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots
return true;
}
-static void red_put_surface_cmd(RedSurfaceCmd *red)
+RedSurfaceCmd::~RedSurfaceCmd()
{
- if (red->qxl) {
- red_qxl_release_resource(red->qxl, red->release_info_ext);
+ if (qxl) {
+ red_qxl_release_resource(qxl, release_info_ext);
}
}
-RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr)
+red::shared_ptr<const RedSurfaceCmd>
+red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr)
{
- RedSurfaceCmd *cmd;
-
- cmd = g_new0(RedSurfaceCmd, 1);
+ auto cmd = red::make_shared<RedSurfaceCmd>();
- cmd->refs = 1;
-
- if (!red_get_surface_cmd(qxl_instance, slots, group_id, cmd, addr)) {
- red_surface_cmd_unref(cmd);
- return nullptr;
+ if (!red_get_surface_cmd(qxl_instance, slots, group_id, cmd.get(), addr)) {
+ cmd.reset();
}
return cmd;
}
-RedSurfaceCmd *red_surface_cmd_ref(RedSurfaceCmd *cmd)
-{
- cmd->refs++;
- return cmd;
-}
-
-void red_surface_cmd_unref(RedSurfaceCmd *cmd)
-{
- if (--cmd->refs) {
- return;
- }
- red_put_surface_cmd(cmd);
- g_free(cmd);
-}
-
static bool red_get_cursor(RedMemSlotInfo *slots, int group_id,
SpiceCursor *red, QXLPHYSICAL addr)
{
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index d1aab512..1eb0d928 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -87,17 +87,17 @@ typedef struct RedSurfaceCreate {
uint8_t *data;
} RedSurfaceCreate;
-typedef struct RedSurfaceCmd {
+struct RedSurfaceCmd final: public red::simple_ptr_counted<RedSurfaceCmd> {
+ ~RedSurfaceCmd();
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
- int refs;
uint32_t surface_id;
uint8_t type;
uint32_t flags;
union {
RedSurfaceCreate surface_create;
} u;
-} RedSurfaceCmd;
+};
struct RedCursorCmd final: public red::simple_ptr_counted<RedCursorCmd> {
~RedCursorCmd();
@@ -139,10 +139,9 @@ void red_message_unref(RedMessage *red);
bool red_validate_surface(uint32_t width, uint32_t height,
int32_t stride, uint32_t format);
-RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr);
-RedSurfaceCmd *red_surface_cmd_ref(RedSurfaceCmd *cmd);
-void red_surface_cmd_unref(RedSurfaceCmd *cmd);
+red::shared_ptr<const RedSurfaceCmd>
+red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
+ int group_id, QXLPHYSICAL addr);
red::shared_ptr<const RedCursorCmd>
red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr);
diff --git a/server/red-worker.cpp b/server/red-worker.cpp
index 9aad023b..62028a53 100644
--- a/server/red-worker.cpp
+++ b/server/red-worker.cpp
@@ -145,15 +145,12 @@ static int red_process_cursor(RedWorker *worker, int *ring_is_empty)
static gboolean red_process_surface_cmd(RedWorker *worker, QXLCommandExt *ext, gboolean loadvm)
{
- RedSurfaceCmd *surface_cmd;
-
- surface_cmd = red_surface_cmd_new(worker->qxl, &worker->mem_slots,
- ext->group_id, ext->cmd.data);
- if (surface_cmd == nullptr) {
+ auto surface_cmd = red_surface_cmd_new(worker->qxl, &worker->mem_slots,
+ ext->group_id, ext->cmd.data);
+ if (!surface_cmd) {
return false;
}
- display_channel_process_surface_cmd(worker->display_channel, surface_cmd, loadvm);
- red_surface_cmd_unref(surface_cmd);
+ display_channel_process_surface_cmd(worker->display_channel, std::move(surface_cmd), loadvm);
return true;
}
diff --git a/server/tests/test-qxl-parsing.cpp b/server/tests/test-qxl-parsing.cpp
index 510e275b..d68879f1 100644
--- a/server/tests/test-qxl-parsing.cpp
+++ b/server/tests/test-qxl-parsing.cpp
@@ -111,16 +111,15 @@ static void test_memslot_invalid_addresses(void)
static void test_no_issues(void)
{
RedMemSlotInfo mem_info;
- RedSurfaceCmd *cmd;
QXLSurfaceCmd qxl;
init_meminfo(&mem_info);
init_qxl_surface(&qxl);
/* try to create a surface with no issues, should succeed */
- cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
- g_assert_nonnull(cmd);
- red_surface_cmd_unref(cmd);
+ auto cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
+ g_assert(cmd);
+ cmd.reset();
deinit_qxl_surface(&qxl);
memslot_info_destroy(&mem_info);
@@ -129,7 +128,6 @@ static void test_no_issues(void)
static void test_stride_too_small(void)
{
RedMemSlotInfo mem_info;
- RedSurfaceCmd *cmd;
QXLSurfaceCmd qxl;
init_meminfo(&mem_info);
@@ -140,8 +138,8 @@ static void test_stride_too_small(void)
* This can be used to cause buffer overflows so refuse it.
*/
qxl.u.surface_create.stride = 256;
- cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
- g_assert_null(cmd);
+ auto cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
+ g_assert(!cmd);
deinit_qxl_surface(&qxl);
memslot_info_destroy(&mem_info);
@@ -150,7 +148,6 @@ static void test_stride_too_small(void)
static void test_too_big_image(void)
{
RedMemSlotInfo mem_info;
- RedSurfaceCmd *cmd;
QXLSurfaceCmd qxl;
init_meminfo(&mem_info);
@@ -166,8 +163,8 @@ static void test_too_big_image(void)
qxl.u.surface_create.stride = 0x08000004 * 4;
qxl.u.surface_create.width = 0x08000004;
qxl.u.surface_create.height = 0x40000020;
- cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
- g_assert_null(cmd);
+ auto cmd = red_surface_cmd_new(NULL, &mem_info, 0, to_physical(&qxl));
+ g_assert(!cmd);
deinit_qxl_surface(&qxl);
memslot_info_destroy(&mem_info);
commit 1d4fb2fee7a0703ceba67c27d5d8f657caf339a0
Author: Frediano Ziglio <freddy77 at gmail.com>
Date: Tue May 5 15:42:47 2020 +0100
red-parse-qxl: Use a base reference class for RedCursorCmd
Don't code manually reference counting for this structure
Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
Acked-by: Victor Toso <victortoso at redhat.com>
diff --git a/server/Makefile.am b/server/Makefile.am
index 2c7479d9..5260051b 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -157,7 +157,7 @@ libserver_la_SOURCES = \
red-pipe-item.h \
red-qxl.cpp \
red-qxl.h \
- red-record-qxl.c \
+ red-record-qxl.cpp \
red-record-qxl.h \
red-replay-qxl.cpp \
reds.cpp \
diff --git a/server/cursor-channel.cpp b/server/cursor-channel.cpp
index 8bb06134..beb004ea 100644
--- a/server/cursor-channel.cpp
+++ b/server/cursor-channel.cpp
@@ -26,37 +26,24 @@
#include "reds.h"
struct RedCursorPipeItem: public RedPipeItemNum<RED_PIPE_ITEM_TYPE_CURSOR> {
- explicit RedCursorPipeItem(RedCursorCmd *cmd);
- ~RedCursorPipeItem() override;
- RedCursorCmd *red_cursor;
+ explicit RedCursorPipeItem(const red::shared_ptr<const RedCursorCmd>& cmd);
+ red::shared_ptr<const RedCursorCmd> red_cursor;
};
-RedCursorPipeItem::RedCursorPipeItem(RedCursorCmd *cmd):
- red_cursor(red_cursor_cmd_ref(cmd))
+RedCursorPipeItem::RedCursorPipeItem(const red::shared_ptr<const RedCursorCmd>& cmd):
+ red_cursor(cmd)
{
}
-RedCursorPipeItem::~RedCursorPipeItem()
-{
- red_cursor_cmd_unref(red_cursor);
-}
-
-static void cursor_channel_set_item(CursorChannel *cursor, RedCursorPipeItem *item)
-{
- cursor->item.reset(item);
-}
-
static void cursor_fill(CursorChannelClient *ccc, RedCursorPipeItem *cursor,
SpiceCursor *red_cursor, SpiceMarshaller *m)
{
- RedCursorCmd *cursor_cmd;
-
if (!cursor) {
red_cursor->flags = SPICE_CURSOR_FLAGS_NONE;
return;
}
- cursor_cmd = cursor->red_cursor;
+ auto cursor_cmd = cursor->red_cursor.get();
*red_cursor = cursor_cmd->u.set.shape;
if (red_cursor->header.unique) {
@@ -100,11 +87,10 @@ static void red_marshall_cursor(CursorChannelClient *ccc,
{
CursorChannel *cursor_channel = ccc->get_channel();
RedCursorPipeItem *item = cursor_pipe_item;
- RedCursorCmd *cmd;
spice_return_if_fail(cursor_channel);
- cmd = item->red_cursor;
+ auto cmd = item->red_cursor.get();
switch (cmd->type) {
case QXL_CURSOR_MOVE:
{
@@ -189,7 +175,7 @@ cursor_channel_new(RedsState *server, int id,
return red::make_shared<CursorChannel>(server, id, core, dispatcher);
}
-void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
+void CursorChannel::process_cmd(red::shared_ptr<const RedCursorCmd> &&cursor_cmd)
{
bool cursor_show = false;
@@ -200,7 +186,7 @@ void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
switch (cursor_cmd->type) {
case QXL_CURSOR_SET:
cursor_visible = !!cursor_cmd->u.set.visible;
- cursor_channel_set_item(this, cursor_pipe_item.get());
+ item = cursor_pipe_item;
break;
case QXL_CURSOR_MOVE:
cursor_show = !cursor_visible;
@@ -229,7 +215,7 @@ void CursorChannel::process_cmd(RedCursorCmd *cursor_cmd)
void CursorChannel::reset()
{
- cursor_channel_set_item(this, nullptr);
+ item.reset();
cursor_visible = true;
cursor_position.x = cursor_position.y = 0;
cursor_trail_length = cursor_trail_frequency = 0;
diff --git a/server/cursor-channel.h b/server/cursor-channel.h
index f0f59436..0461a942 100644
--- a/server/cursor-channel.h
+++ b/server/cursor-channel.h
@@ -38,7 +38,7 @@ struct CursorChannel final: public CommonGraphicsChannel
~CursorChannel();
void reset();
void do_init();
- void process_cmd(RedCursorCmd *cursor_cmd);
+ void process_cmd(red::shared_ptr<const RedCursorCmd> &&cursor_cmd);
void set_mouse_mode(uint32_t mode);
void on_connect(RedClient *client, RedStream *stream, int migration,
RedChannelCapabilities *caps) override;
diff --git a/server/meson.build b/server/meson.build
index fe8d5d63..a8da777f 100644
--- a/server/meson.build
+++ b/server/meson.build
@@ -136,7 +136,7 @@ spice_server_sources = [
'red-pipe-item.h',
'red-qxl.cpp',
'red-qxl.h',
- 'red-record-qxl.c',
+ 'red-record-qxl.cpp',
'red-record-qxl.h',
'red-replay-qxl.cpp',
'reds.cpp',
diff --git a/server/red-parse-qxl.cpp b/server/red-parse-qxl.cpp
index ec4b17e6..198179a3 100644
--- a/server/red-parse-qxl.cpp
+++ b/server/red-parse-qxl.cpp
@@ -1609,46 +1609,26 @@ static bool red_get_cursor_cmd(QXLInstance *qxl_instance, RedMemSlotInfo *slots,
return true;
}
-RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr)
+red::shared_ptr<const RedCursorCmd>
+red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr)
{
- RedCursorCmd *cmd;
-
- cmd = g_new0(RedCursorCmd, 1);
+ auto cmd = red::make_shared<RedCursorCmd>();
- cmd->refs = 1;
-
- if (!red_get_cursor_cmd(qxl, slots, group_id, cmd, addr)) {
- red_cursor_cmd_unref(cmd);
- return nullptr;
+ if (!red_get_cursor_cmd(qxl, slots, group_id, cmd.get(), addr)) {
+ cmd.reset();
}
return cmd;
}
-static void red_put_cursor_cmd(RedCursorCmd *red)
+RedCursorCmd::~RedCursorCmd()
{
- switch (red->type) {
+ switch (type) {
case QXL_CURSOR_SET:
- red_put_cursor(&red->u.set.shape);
+ red_put_cursor(&u.set.shape);
break;
}
- if (red->qxl) {
- red_qxl_release_resource(red->qxl, red->release_info_ext);
- }
-}
-
-RedCursorCmd *red_cursor_cmd_ref(RedCursorCmd *red)
-{
- red->refs++;
- return red;
-}
-
-void red_cursor_cmd_unref(RedCursorCmd *red)
-{
- if (--red->refs) {
- return;
+ if (qxl) {
+ red_qxl_release_resource(qxl, release_info_ext);
}
- red_put_cursor_cmd(red);
- g_free(red);
}
diff --git a/server/red-parse-qxl.h b/server/red-parse-qxl.h
index c7206516..d1aab512 100644
--- a/server/red-parse-qxl.h
+++ b/server/red-parse-qxl.h
@@ -23,8 +23,9 @@
#include "red-common.h"
#include "memslot.h"
+#include "utils.hpp"
-SPICE_BEGIN_DECLS
+#include "push-visibility.h"
typedef struct RedDrawable {
int refs;
@@ -98,10 +99,10 @@ typedef struct RedSurfaceCmd {
} u;
} RedSurfaceCmd;
-typedef struct RedCursorCmd {
+struct RedCursorCmd final: public red::simple_ptr_counted<RedCursorCmd> {
+ ~RedCursorCmd();
QXLInstance *qxl;
QXLReleaseInfoExt release_info_ext;
- int refs;
uint8_t type;
union {
struct {
@@ -115,7 +116,7 @@ typedef struct RedCursorCmd {
} trail;
SpicePoint16 position;
} u;
-} RedCursorCmd;
+};
void red_get_rect_ptr(SpiceRect *red, const QXLRect *qxl);
@@ -143,11 +144,9 @@ RedSurfaceCmd *red_surface_cmd_new(QXLInstance *qxl_instance, RedMemSlotInfo *sl
RedSurfaceCmd *red_surface_cmd_ref(RedSurfaceCmd *cmd);
void red_surface_cmd_unref(RedSurfaceCmd *cmd);
-RedCursorCmd *red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots,
- int group_id, QXLPHYSICAL addr);
-RedCursorCmd *red_cursor_cmd_ref(RedCursorCmd *red);
-void red_cursor_cmd_unref(RedCursorCmd *red);
+red::shared_ptr<const RedCursorCmd>
+red_cursor_cmd_new(QXLInstance *qxl, RedMemSlotInfo *slots, int group_id, QXLPHYSICAL addr);
-SPICE_END_DECLS
+#include "pop-visibility.h"
#endif /* RED_PARSE_QXL_H_ */
diff --git a/server/red-record-qxl.c b/server/red-record-qxl.cpp
similarity index 100%
rename from server/red-record-qxl.c
rename to server/red-record-qxl.cpp
diff --git a/server/red-stream-device.cpp b/server/red-stream-device.cpp
index 65eb0d61..92ba0d94 100644
--- a/server/red-stream-device.cpp
+++ b/server/red-stream-device.cpp
@@ -378,10 +378,10 @@ get_cursor_type_bits(unsigned int cursor_type)
}
}
-static RedCursorCmd *
+static red::shared_ptr<const RedCursorCmd>
stream_msg_cursor_set_to_cursor_cmd(const StreamMsgCursorSet *msg, size_t msg_size)
{
- auto cmd = g_new0(RedCursorCmd, 1);
+ auto cmd = red::make_shared<RedCursorCmd>();
cmd->type = QXL_CURSOR_SET;
cmd->u.set.position.x = 0; // TODO
cmd->u.set.position.y = 0; // TODO
@@ -397,14 +397,12 @@ stream_msg_cursor_set_to_cursor_cmd(const StreamMsgCursorSet *msg, size_t msg_si
/* Limit cursor size to prevent DoS */
if (cursor->header.width > STREAM_MSG_CURSOR_SET_MAX_WIDTH ||
cursor->header.height > STREAM_MSG_CURSOR_SET_MAX_HEIGHT) {
- g_free(cmd);
- return nullptr;
+ return red::shared_ptr<const RedCursorCmd>();
}
const unsigned int cursor_bits = get_cursor_type_bits(cursor->header.type);
if (cursor_bits == 0) {
- g_free(cmd);
- return nullptr;
+ return red::shared_ptr<const RedCursorCmd>();
}
/* Check that enough data has been sent for the cursor.
@@ -413,8 +411,7 @@ stream_msg_cursor_set_to_cursor_cmd(const StreamMsgCursorSet *msg, size_t msg_si
size_t size_required = cursor->header.width * cursor->header.height;
size_required = SPICE_ALIGN(size_required * cursor_bits, 8) / 8U;
if (msg_size < sizeof(StreamMsgCursorSet) + size_required) {
- g_free(cmd);
- return nullptr;
+ return red::shared_ptr<const RedCursorCmd>();
}
cursor->data_size = size_required;
cursor->data = (uint8_t*) g_memdup2(msg->data, size_required);
@@ -453,11 +450,11 @@ StreamDevice::handle_msg_cursor_set()
}
// transform the message to a cursor command and process it
- RedCursorCmd *cmd = stream_msg_cursor_set_to_cursor_cmd(&msg->cursor_set, msg_pos);
+ auto cmd = stream_msg_cursor_set_to_cursor_cmd(&msg->cursor_set, msg_pos);
if (!cmd) {
return handle_msg_invalid(nullptr);
}
- cursor_channel->process_cmd(cmd);
+ cursor_channel->process_cmd(std::move(cmd));
return true;
}
@@ -478,12 +475,12 @@ StreamDevice::handle_msg_cursor_move()
move->x = GINT32_FROM_LE(move->x);
move->y = GINT32_FROM_LE(move->y);
- auto cmd = g_new0(RedCursorCmd, 1);
+ auto cmd = red::make_shared<RedCursorCmd>();
cmd->type = QXL_CURSOR_MOVE;
cmd->u.position.x = move->x;
cmd->u.position.y = move->y;
- cursor_channel->process_cmd(cmd);
+ cursor_channel->process_cmd(std::move(cmd));
return true;
}
diff --git a/server/red-worker.cpp b/server/red-worker.cpp
index 2be223b4..9aad023b 100644
--- a/server/red-worker.cpp
+++ b/server/red-worker.cpp
@@ -90,16 +90,13 @@ struct RedWorker {
static gboolean red_process_cursor_cmd(RedWorker *worker, const QXLCommandExt *ext)
{
- RedCursorCmd *cursor_cmd;
-
- cursor_cmd = red_cursor_cmd_new(worker->qxl, &worker->mem_slots,
- ext->group_id, ext->cmd.data);
- if (cursor_cmd == nullptr) {
+ auto cursor_cmd = red_cursor_cmd_new(worker->qxl, &worker->mem_slots,
+ ext->group_id, ext->cmd.data);
+ if (!cursor_cmd) {
return FALSE;
}
- worker->cursor_channel->process_cmd(cursor_cmd);
- red_cursor_cmd_unref(cursor_cmd);
+ worker->cursor_channel->process_cmd(std::move(cursor_cmd));
return TRUE;
}
diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am
index 19058037..5918cb9d 100644
--- a/server/tests/Makefile.am
+++ b/server/tests/Makefile.am
@@ -83,6 +83,7 @@ endif
test_channel_SOURCES = test-channel.cpp
test_stream_device_SOURCES = test-stream-device.cpp
test_dispatcher_SOURCES = test-dispatcher.cpp
+test_qxl_parsing_SOURCES = test-qxl-parsing.cpp
if !OS_WIN32
check_PROGRAMS += \
diff --git a/server/tests/meson.build b/server/tests/meson.build
index 4f150a0b..1ae7d37c 100644
--- a/server/tests/meson.build
+++ b/server/tests/meson.build
@@ -44,7 +44,7 @@ tests = [
['test-stat', true],
['test-agent-msg-filter', true],
['test-loop', true],
- ['test-qxl-parsing', true],
+ ['test-qxl-parsing', true, 'cpp'],
['test-leaks', true],
['test-vdagent', true],
['test-fail-on-null-core-interface', true],
diff --git a/server/tests/test-qxl-parsing.c b/server/tests/test-qxl-parsing.cpp
similarity index 94%
rename from server/tests/test-qxl-parsing.c
rename to server/tests/test-qxl-parsing.cpp
index ee234b61..510e275b 100644
--- a/server/tests/test-qxl-parsing.c
+++ b/server/tests/test-qxl-parsing.cpp
@@ -176,7 +176,6 @@ static void test_too_big_image(void)
static void test_cursor_command(void)
{
RedMemSlotInfo mem_info;
- RedCursorCmd *red_cursor_cmd;
QXLCursorCmd cursor_cmd;
QXLCursor *cursor;
@@ -194,9 +193,9 @@ static void test_cursor_command(void)
cursor_cmd.u.set.shape = to_physical(cursor);
- red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
- g_assert_nonnull(red_cursor_cmd);
- red_cursor_cmd_unref(red_cursor_cmd);
+ auto red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
+ g_assert(red_cursor_cmd);
+ red_cursor_cmd.reset();
g_free(cursor);
memslot_info_destroy(&mem_info);
}
@@ -204,7 +203,6 @@ static void test_cursor_command(void)
static void test_circular_empty_chunks(void)
{
RedMemSlotInfo mem_info;
- RedCursorCmd *red_cursor_cmd;
QXLCursorCmd cursor_cmd;
QXLCursor *cursor;
QXLDataChunk *chunks[2];
@@ -228,14 +226,14 @@ static void test_circular_empty_chunks(void)
cursor_cmd.u.set.shape = to_physical(cursor);
- red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
- if (red_cursor_cmd != NULL) {
+ auto red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
+ if (red_cursor_cmd) {
/* function does not return errors so there should be no data */
g_assert_cmpuint(red_cursor_cmd->type, ==, QXL_CURSOR_SET);
g_assert_cmpuint(red_cursor_cmd->u.set.position.x, ==, 0);
g_assert_cmpuint(red_cursor_cmd->u.set.position.y, ==, 0);
g_assert_cmpuint(red_cursor_cmd->u.set.shape.data_size, ==, 0);
- red_cursor_cmd_unref(red_cursor_cmd);
+ red_cursor_cmd.reset();
}
g_test_assert_expected_messages();
@@ -247,7 +245,6 @@ static void test_circular_empty_chunks(void)
static void test_circular_small_chunks(void)
{
RedMemSlotInfo mem_info;
- RedCursorCmd *red_cursor_cmd;
QXLCursorCmd cursor_cmd;
QXLCursor *cursor;
QXLDataChunk *chunks[2];
@@ -271,14 +268,14 @@ static void test_circular_small_chunks(void)
cursor_cmd.u.set.shape = to_physical(cursor);
- red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
- if (red_cursor_cmd != NULL) {
+ auto red_cursor_cmd = red_cursor_cmd_new(NULL, &mem_info, 0, to_physical(&cursor_cmd));
+ if (red_cursor_cmd) {
/* function does not return errors so there should be no data */
g_assert_cmpuint(red_cursor_cmd->type, ==, QXL_CURSOR_SET);
g_assert_cmpuint(red_cursor_cmd->u.set.position.x, ==, 0);
g_assert_cmpuint(red_cursor_cmd->u.set.position.y, ==, 0);
g_assert_cmpuint(red_cursor_cmd->u.set.shape.data_size, ==, 0);
- red_cursor_cmd_unref(red_cursor_cmd);
+ red_cursor_cmd.reset();
}
g_test_assert_expected_messages();
commit a3656e217d30488be86dd435a6cd541b6743d96a
Author: Frediano Ziglio <freddy77 at gmail.com>
Date: Wed Jun 24 19:07:51 2020 +0100
utils: Add a base light class for reference counting
Similar to shared_ptr_counted but avoid atomic counter and
polymorphism.
Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
Acked-by: Victor Toso <victortoso at redhat.com>
diff --git a/server/utils.hpp b/server/utils.hpp
index 063e3f62..e25e1c5e 100644
--- a/server/utils.hpp
+++ b/server/utils.hpp
@@ -430,6 +430,68 @@ inline bool weak_ptr_lock(shared_ptr_counted_weak* p)
}
+/**
+ * Utility to help implementing shared_ptr requirements.
+ *
+ * You should inherit publicly this class in order to have base internal reference counting
+ * implementation.
+ *
+ * This class does not use atomic operations and virtual destructor so it's more light than
+ * shared_ptr_counted.
+ *
+ * To avoid issues with inheritance not calling proper destructor the derived objects should
+ * follow this pattern (note the final):
+ *
+ * @code{.cpp}
+ * class Name final: public simple_ptr_counted<Name> {
+ * ...
+ * }
+ * @endcode
+ *
+ * or
+ *
+ * @code{.cpp}
+ * class Name: public simple_ptr_counted<Name> {
+ * ...
+ * virtual ~Name();
+ * ...
+ * }
+ * @endcode
+ */
+template <typename T>
+class simple_ptr_counted
+{
+public:
+ SPICE_CXX_GLIB_ALLOCATOR
+
+ simple_ptr_counted(): ref_count(0)
+ {
+ }
+private:
+ mutable int ref_count;
+ simple_ptr_counted(const simple_ptr_counted<T>& rhs)=delete;
+ void operator=(const simple_ptr_counted<T>& rhs)=delete;
+ template <typename Q>
+ friend inline void shared_ptr_add_ref(const simple_ptr_counted<Q>*);
+ template <typename Q>
+ friend inline void shared_ptr_unref(const simple_ptr_counted<Q>*);
+};
+
+template <typename T>
+inline void shared_ptr_add_ref(const simple_ptr_counted<T>* p)
+{
+ ++p->ref_count;
+}
+
+template <typename T>
+inline void shared_ptr_unref(const simple_ptr_counted<T>* p)
+{
+ if (--p->ref_count == 0) {
+ delete const_cast<T*>(static_cast<const T*>(p));
+ }
+}
+
+
} // namespace red
#include "pop-visibility.h"
More information about the Spice-commits
mailing list