summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <freddy77@gmail.com>2021-05-31 21:57:17 +0100
committerFrediano Ziglio <freddy77@gmail.com>2023-11-22 07:39:19 +0000
commit14a6d05aa94b175ded148b40017d24294bd80231 (patch)
tree7c360883ae0b14a702d9ea5aa9ff4d162a49f0b6
parent85793bc60420bce4b7139f88a2fe7a3df46b2c0e (diff)
Another Ring
TODO merge stuff for ring, check tab/spaces
-rw-r--r--server/display-channel-private.h2
-rw-r--r--server/display-channel.cpp36
-rw-r--r--server/display-channel.h5
-rw-r--r--server/ring.hpp4
4 files changed, 21 insertions, 26 deletions
diff --git a/server/display-channel-private.h b/server/display-channel-private.h
index 718d7fc0..49edcfbf 100644
--- a/server/display-channel-private.h
+++ b/server/display-channel-private.h
@@ -49,7 +49,7 @@ struct RedSurface {
/* A ring of pending Drawables associated with this surface. This ring is
* actually used for drawing. The ring is maintained in order of age, the
* tail being the oldest drawable. */
- Ring current_list;
+ SurfaceDrawableRing current_list;
DrawContext context;
DependItemRing depend_on_me;
diff --git a/server/display-channel.cpp b/server/display-channel.cpp
index 6e857732..3630c06f 100644
--- a/server/display-channel.cpp
+++ b/server/display-channel.cpp
@@ -346,7 +346,7 @@ static void current_add_drawable(DisplayChannel *display,
surface = drawable->surface;
ring_add_after(&drawable->tree_item.base.siblings_link, pos);
display->priv->current_list.push_front(drawable);
- ring_add(&surface->current_list, &drawable->surface_list_link);
+ surface->current_list.push_front(drawable);
drawable->refs++;
}
@@ -358,7 +358,6 @@ static void current_remove_drawable(DisplayChannel *display, Drawable *item)
video_stream_trace_add_drawable(display, item);
draw_item_remove_shadow(&item->tree_item);
ring_remove(&item->tree_item.base.siblings_link);
- ring_remove(&item->surface_list_link);
drawable_unref(item);
}
@@ -1455,7 +1454,7 @@ static bool free_one_drawable(DisplayChannel *display, int force_glz_free)
void display_channel_current_flush(DisplayChannel *display, RedSurface *surface)
{
- while (!ring_is_empty(&surface->current_list)) {
+ while (!surface->current_list.empty()) {
free_one_drawable(display, FALSE);
}
current_remove_all(display, surface);
@@ -1543,7 +1542,6 @@ static Drawable *display_channel_drawable_try_new(DisplayChannel *display,
drawable->display = display;
drawable->refs = 1;
drawable->creation_time = drawable->first_frame_time = spice_get_monotonic_time_ns();
- ring_item_init(&drawable->surface_list_link);
ring_item_init(&drawable->tree_item.base.siblings_link);
drawable->tree_item.base.type = TREE_ITEM_TYPE_DRAWABLE;
region_init(&drawable->tree_item.base.rgn);
@@ -1783,13 +1781,12 @@ static void surface_update_dest(RedSurface *surface, const SpiceRect *area)
* ring, and stopping after it draws @last */
static void draw_until(DisplayChannel *display, RedSurface *surface, Drawable *last)
{
- RingItem *ring_item;
Container *container;
Drawable *now;
do {
- ring_item = ring_get_tail(&surface->current_list);
- now = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link);
+ auto it = surface->current_list.end();
+ now = &*--it;
now->refs++;
container = now->tree_item.base.container;
current_remove_drawable(display, now);
@@ -1809,20 +1806,19 @@ static void draw_until(DisplayChannel *display, RedSurface *surface, Drawable *l
*
* NOTE: this function expects @current to be a ring of Drawables, and more
* specifically an instance of Surface::current_list (not Surface::current) */
-static Drawable* current_find_intersects_rect(Ring *current, RingItem *from,
+static Drawable* current_find_intersects_rect(RedSurface *surface, SurfaceDrawableRing::iterator it,
const SpiceRect *area)
{
- RingItem *it;
+ auto *current = &surface->current_list;
QRegion rgn;
Drawable *last = nullptr;
region_init(&rgn);
region_add(&rgn, area);
- for (it = from ? from : ring_next(current, current); it != nullptr; it = ring_next(current, it)) {
- Drawable *now = SPICE_CONTAINEROF(it, Drawable, surface_list_link);
- if (region_intersects(&rgn, &now->tree_item.base.rgn)) {
- last = now;
+ for (; it != current->end(); ++it) {
+ if (region_intersects(&rgn, &it->tree_item.base.rgn)) {
+ last = &*it;
break;
}
}
@@ -1840,7 +1836,6 @@ void display_channel_draw_until(DisplayChannel *display, const SpiceRect *area,
Drawable *last)
{
Drawable *surface_last = nullptr;
- RingItem *ring_item;
spice_return_if_fail(last);
spice_return_if_fail(DisplayDrawableRing::is_linked(last));
@@ -1856,17 +1851,17 @@ void display_channel_draw_until(DisplayChannel *display, const SpiceRect *area,
}
}
} else {
- ring_item = ring_next(&surface->current_list, &last->surface_list_link);
- if (ring_item) {
- surface_last = SPICE_CONTAINEROF(ring_item, Drawable, surface_list_link);
+ auto it = SurfaceDrawableRing::iterator(last);
+ if (++it != surface->current_list.end()) {
+ surface_last = &*it;
}
}
if (!surface_last)
return;
- last = current_find_intersects_rect(&surface->current_list,
- &surface_last->surface_list_link, area);
+ last = current_find_intersects_rect(surface,
+ SurfaceDrawableRing::iterator(surface_last), area);
if (!last)
return;
@@ -1893,7 +1888,7 @@ static void display_channel_surface_draw(DisplayChannel *display, RedSurface *su
{
Drawable *last;
- last = current_find_intersects_rect(&surface->current_list, nullptr, area);
+ last = current_find_intersects_rect(surface, surface->current_list.begin(), area);
if (last)
draw_until(display, surface, last);
@@ -2091,7 +2086,6 @@ display_channel_create_surface(DisplayChannel *display, uint32_t surface_id, uin
// finish initialization
ring_init(&surface->current);
- ring_init(&surface->current_list);
region_init(&surface->draw_dirty_region);
if (display->priv->surfaces_[surface_id]) {
diff --git a/server/display-channel.h b/server/display-channel.h
index 583f585f..b47e7115 100644
--- a/server/display-channel.h
+++ b/server/display-channel.h
@@ -63,10 +63,10 @@ struct DependItem final:
using DependItemRing = red::Ring<DependItem,0>;
struct Drawable final:
- public red::RingItem<Drawable,0>
+ public red::RingItem<Drawable,0>,
+ public red::RingItem<Drawable,1>
{
uint32_t refs;
- ::RingItem surface_list_link;
DrawItem tree_item;
GList *pipes;
red::shared_ptr<RedDrawable> red_drawable;
@@ -92,6 +92,7 @@ struct Drawable final:
DisplayChannel *display;
};
using DisplayDrawableRing = red::Ring<Drawable,0>;
+using SurfaceDrawableRing = red::Ring<Drawable,1>;
red::shared_ptr<DisplayChannel>
display_channel_new(RedsState *reds, QXLInstance *qxl,
diff --git a/server/ring.hpp b/server/ring.hpp
index 9579648b..f2a3277a 100644
--- a/server/ring.hpp
+++ b/server/ring.hpp
@@ -86,11 +86,11 @@ struct Ring
}
static void remove(T *item)
{
- item->remove();
+ item->RingItem<T,n>::remove();
}
static bool is_linked(const T *item)
{
- return item->is_linked();
+ return item->RingItem<T,n>::is_linked();
}
private:
RingItem<T, n> link;