xserver: Branch 'master' - 5 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jan 10 17:35:32 UTC 2024
hw/xwayland/xwayland-glamor.c | 7 -
hw/xwayland/xwayland-window-buffers.c | 226 ++++++++++++++++++----------------
hw/xwayland/xwayland-window-buffers.h | 2
hw/xwayland/xwayland-window.c | 5
4 files changed, 135 insertions(+), 105 deletions(-)
New commits:
commit 777c3e0000cec4deefbf8bec20d71a1821d49863
Author: Michel Dänzer <mdaenzer at redhat.com>
Date: Tue Jan 9 17:10:23 2024 +0100
xwayland: Return NULL from xwl_window_buffer_get_available
If there's no available window buffer.
This allows keeping xwl_window_buffer->damage_region empty for a newly
allocated xwl_window_buffer in xwl_window_buffers_get_pixmap, instead
of first populating it in xwl_window_buffer_add_damage_region and then
emptying it again.
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 8bebd63a0..658ec2199 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -140,7 +140,7 @@ static struct xwl_window_buffer *
xwl_window_buffer_get_available(struct xwl_window *xwl_window)
{
if (xorg_list_is_empty(&xwl_window->window_buffers_available))
- return xwl_window_buffer_new(xwl_window);
+ return NULL;
return xorg_list_last_entry(&xwl_window->window_buffers_available,
struct xwl_window_buffer,
@@ -341,13 +341,10 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
return window_pixmap;
#endif /* XWL_HAS_GLAMOR */
- xwl_window_buffer = xwl_window_buffer_get_available(xwl_window);
- if (!xwl_window_buffer)
- return window_pixmap;
-
xwl_window_buffer_add_damage_region(xwl_window, damage_region);
- if (xwl_window_buffer->pixmap) {
+ xwl_window_buffer = xwl_window_buffer_get_available(xwl_window);
+ if (xwl_window_buffer) {
RegionPtr full_damage = xwl_window_buffer->damage_region;
BoxPtr pBox = RegionRects(full_damage);
int nBox = RegionNumRects(full_damage);
@@ -364,10 +361,16 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
pBox++;
}
+
+ RegionEmpty(xwl_window_buffer->damage_region);
} else {
+ xwl_window_buffer = xwl_window_buffer_new(xwl_window);
+
new_window_pixmap = xwl_window_allocate_pixmap(xwl_window);
- if (!new_window_pixmap)
+ if (!new_window_pixmap) {
+ xwl_window_buffer_maybe_dispose(xwl_window_buffer);
return window_pixmap;
+ }
copy_pixmap_area(window_pixmap,
new_window_pixmap,
@@ -376,7 +379,6 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
window_pixmap->drawable.height);
}
- RegionEmpty(xwl_window_buffer->damage_region);
xwl_window_buffer->pixmap = window_pixmap;
/* Hold a reference on the buffer until it's released by the compositor */
commit 6779ec5bf67a4686ffed052bf85fcc42b99f9575
Author: Michel Dänzer <mdaenzer at redhat.com>
Date: Wed Dec 20 15:04:36 2023 +0100
xwayland: Use window pixmap as a window buffer
Assuming the same number of window buffers, this results in one less
pixmap per toplevel window, saving pixmap storage.
v2:
* Preserve xwl_window_buffer_get_available behaviour (Olivier Fourdan)
v3:
* Leave RegionEmpty call where it was in xwl_window_buffers_get_pixmap,
so it takes effect for a newly allocated struct xwl_window_buffer.
* Consolidate xwl_window_buffer->pixmap assignment in the same place.
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 33a6f3168..17fa20c80 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -788,10 +788,11 @@ xwl_window_dmabuf_feedback_done(void *data,
xwl_window->window->drawable.id,
xwl_window->has_implicit_scanout_support ? "" : "not");
- /* If the linux-dmabuf v4 per-surface feedback changed, dispose of the
- * window buffers so that they get re-created with appropriate parameters.
+ /* If the linux-dmabuf v4 per-surface feedback changed, make sure the
+ * window buffers get re-created with appropriate parameters.
*/
xwl_window_buffers_dispose(xwl_window);
+ xwl_window_recycle_pixmap(xwl_window);
}
static void
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index c3b35c459..8bebd63a0 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -247,14 +247,92 @@ xwl_window_buffers_dispose(struct xwl_window *xwl_window)
TimerCancel(xwl_window->window_buffers_timer);
}
+struct pixmap_visit {
+ PixmapPtr old;
+ PixmapPtr new;
+};
+
+static int
+xwl_set_pixmap_visit_window(WindowPtr window, void *data)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ struct pixmap_visit *visit = data;
+
+ if (screen->GetWindowPixmap(window) == visit->old) {
+ screen->SetWindowPixmap(window, visit->new);
+ return WT_WALKCHILDREN;
+ }
+
+ return WT_DONTWALKCHILDREN;
+}
+
+static void
+xwl_window_set_pixmap(WindowPtr window, PixmapPtr pixmap)
+{
+ ScreenPtr screen = window->drawable.pScreen;
+ struct pixmap_visit visit;
+
+ visit.old = screen->GetWindowPixmap(window);
+ visit.new = pixmap;
+
+#ifdef COMPOSITE
+ pixmap->screen_x = visit.old->screen_x;
+ pixmap->screen_y = visit.old->screen_y;
+#endif
+
+ TraverseTree(window, xwl_set_pixmap_visit_window, &visit);
+}
+
+static PixmapPtr
+xwl_window_allocate_pixmap(struct xwl_window *xwl_window)
+{
+ ScreenPtr screen = xwl_window->xwl_screen->screen;
+ PixmapPtr window_pixmap;
+
+#ifdef XWL_HAS_GLAMOR
+ /* Try the xwayland/glamor direct hook first */
+ window_pixmap = xwl_glamor_create_pixmap_for_window(xwl_window);
+ if (window_pixmap)
+ return window_pixmap;
+#endif /* XWL_HAS_GLAMOR */
+
+ window_pixmap = screen->GetWindowPixmap(xwl_window->window);
+ return screen->CreatePixmap(screen,
+ window_pixmap->drawable.width,
+ window_pixmap->drawable.height,
+ window_pixmap->drawable.depth,
+ CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+}
+
+void
+xwl_window_recycle_pixmap(struct xwl_window *xwl_window)
+{
+ PixmapPtr window_pixmap, new_window_pixmap;
+ WindowPtr window;
+ ScreenPtr screen;
+
+ new_window_pixmap = xwl_window_allocate_pixmap(xwl_window);
+ if (!new_window_pixmap)
+ return;
+
+ window = xwl_window->window;
+ screen = window->drawable.pScreen;
+ window_pixmap = screen->GetWindowPixmap(window);
+ copy_pixmap_area(window_pixmap,
+ new_window_pixmap,
+ 0, 0,
+ window_pixmap->drawable.width,
+ window_pixmap->drawable.height);
+ xwl_window_set_pixmap(xwl_window->window, new_window_pixmap);
+}
+
PixmapPtr
xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
RegionPtr damage_region)
{
struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
struct xwl_window_buffer *xwl_window_buffer;
- PixmapPtr window_pixmap;
- RegionPtr full_damage;
+ PixmapPtr window_pixmap, new_window_pixmap;
window_pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
@@ -269,14 +347,16 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
xwl_window_buffer_add_damage_region(xwl_window, damage_region);
- full_damage = xwl_window_buffer->damage_region;
-
if (xwl_window_buffer->pixmap) {
+ RegionPtr full_damage = xwl_window_buffer->damage_region;
BoxPtr pBox = RegionRects(full_damage);
int nBox = RegionNumRects(full_damage);
+
+ new_window_pixmap = xwl_window_buffer->pixmap;
+
while (nBox--) {
copy_pixmap_area(window_pixmap,
- xwl_window_buffer->pixmap,
+ new_window_pixmap,
pBox->x1 + xwl_window->window->borderWidth,
pBox->y1 + xwl_window->window->borderWidth,
pBox->x2 - pBox->x1,
@@ -285,31 +365,19 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
pBox++;
}
} else {
-#ifdef XWL_HAS_GLAMOR
- /* Try the xwayland/glamor direct hook first */
- xwl_window_buffer->pixmap =
- xwl_glamor_create_pixmap_for_window(xwl_window);
-#endif /* XWL_HAS_GLAMOR */
- if (!xwl_window_buffer->pixmap) {
- xwl_window_buffer->pixmap =
- (*xwl_screen->screen->CreatePixmap) (window_pixmap->drawable.pScreen,
- window_pixmap->drawable.width,
- window_pixmap->drawable.height,
- window_pixmap->drawable.depth,
- CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
- }
-
- if (!xwl_window_buffer->pixmap)
+ new_window_pixmap = xwl_window_allocate_pixmap(xwl_window);
+ if (!new_window_pixmap)
return window_pixmap;
copy_pixmap_area(window_pixmap,
- xwl_window_buffer->pixmap,
+ new_window_pixmap,
0, 0,
window_pixmap->drawable.width,
window_pixmap->drawable.height);
}
RegionEmpty(xwl_window_buffer->damage_region);
+ xwl_window_buffer->pixmap = window_pixmap;
/* Hold a reference on the buffer until it's released by the compositor */
xwl_window_buffer->refcnt++;
@@ -321,6 +389,8 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
xorg_list_append(&xwl_window_buffer->link_buffer,
&xwl_window->window_buffers_unavailable);
+ xwl_window_set_pixmap(xwl_window->window, new_window_pixmap);
+
if (xorg_list_is_empty(&xwl_window->window_buffers_available))
TimerCancel(xwl_window->window_buffers_timer);
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index 585fa6df1..c795564bd 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -34,6 +34,7 @@
void xwl_window_buffers_init(struct xwl_window *xwl_window);
void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
+void xwl_window_recycle_pixmap(struct xwl_window *xwl_window);
PixmapPtr xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
RegionPtr damage_region);
commit 2b577c2e3bc2205b5b524068370ac195e9ef90d7
Author: Michel Dänzer <mdaenzer at redhat.com>
Date: Thu Dec 21 12:25:28 2023 +0100
xwayland: Drop xwl_window_buffers_recycle
Use xwl_window_buffers_dispose instead. The pixmaps will need to be
re-created anyway, so keeping around the xwl_window_buffers doesn't
buy much. And dropping this makes the next commit simpler.
Also fold xwl_window_buffer_destroy_pixmap into its only remaining
caller, xwl_window_buffer_maybe_dispose.
v2: (Olivier Fourdan)
* Fix up indentation in xwl_window_set_window_pixmap
* Leave xwl_window_buffer_destroy_pixmap helper
diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index e962ccc15..33a6f3168 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -788,10 +788,10 @@ xwl_window_dmabuf_feedback_done(void *data,
xwl_window->window->drawable.id,
xwl_window->has_implicit_scanout_support ? "" : "not");
- /* If the linux-dmabuf v4 per-surface feedback changed, recycle the
+ /* If the linux-dmabuf v4 per-surface feedback changed, dispose of the
* window buffers so that they get re-created with appropriate parameters.
*/
- xwl_window_buffers_recycle(xwl_window);
+ xwl_window_buffers_dispose(xwl_window);
}
static void
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index d2cf3c3fe..c3b35c459 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -39,7 +39,6 @@ struct xwl_window_buffer {
struct xwl_window *xwl_window;
PixmapPtr pixmap;
RegionPtr damage_region;
- Bool recycle_on_release;
int refcnt;
uint32_t time;
struct xorg_list link_buffer;
@@ -114,16 +113,6 @@ xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
return TRUE;
}
-static void
-xwl_window_buffer_recycle(struct xwl_window_buffer *xwl_window_buffer)
-{
- RegionEmpty(xwl_window_buffer->damage_region);
- xwl_window_buffer->recycle_on_release = FALSE;
-
- if (xwl_window_buffer->pixmap)
- xwl_window_buffer_destroy_pixmap (xwl_window_buffer);
-}
-
static void
xwl_window_buffer_add_damage_region(struct xwl_window *xwl_window,
RegionPtr damage_region)
@@ -199,9 +188,6 @@ xwl_window_buffer_release_callback(void *data)
if (xwl_window_buffer_maybe_dispose(xwl_window_buffer))
return;
- if (xwl_window_buffer->recycle_on_release)
- xwl_window_buffer_recycle(xwl_window_buffer);
-
/* We append the buffers to the end of the list, as we pick the last
* entry again when looking for new available buffers, that means the
* least used buffers will remain at the beginning of the list so that
@@ -234,29 +220,6 @@ xwl_window_buffers_init(struct xwl_window *xwl_window)
xorg_list_init(&xwl_window->window_buffers_unavailable);
}
-void
-xwl_window_buffers_recycle(struct xwl_window *xwl_window)
-{
- struct xwl_window_buffer *xwl_window_buffer, *tmp;
-
- /* Dispose available buffers */
- xorg_list_for_each_entry_safe(xwl_window_buffer, tmp,
- &xwl_window->window_buffers_available,
- link_buffer) {
- xwl_window_buffer_maybe_dispose(xwl_window_buffer);
- }
-
- if (xwl_window->window_buffers_timer)
- TimerCancel(xwl_window->window_buffers_timer);
-
- /* Mark the others for recycle on release */
- xorg_list_for_each_entry(xwl_window_buffer,
- &xwl_window->window_buffers_unavailable,
- link_buffer) {
- xwl_window_buffer->recycle_on_release = TRUE;
- }
-}
-
void
xwl_window_buffers_dispose(struct xwl_window *xwl_window)
{
@@ -280,10 +243,8 @@ xwl_window_buffers_dispose(struct xwl_window *xwl_window)
xwl_window_buffer_maybe_dispose(xwl_window_buffer);
}
- if (xwl_window->window_buffers_timer) {
- TimerFree(xwl_window->window_buffers_timer);
- xwl_window->window_buffers_timer = 0;
- }
+ if (xwl_window->window_buffers_timer)
+ TimerCancel(xwl_window->window_buffers_timer);
}
PixmapPtr
diff --git a/hw/xwayland/xwayland-window-buffers.h b/hw/xwayland/xwayland-window-buffers.h
index 8031f24d5..585fa6df1 100644
--- a/hw/xwayland/xwayland-window-buffers.h
+++ b/hw/xwayland/xwayland-window-buffers.h
@@ -33,7 +33,6 @@
#include "regionstr.h"
void xwl_window_buffers_init(struct xwl_window *xwl_window);
-void xwl_window_buffers_recycle(struct xwl_window *xwl_window);
void xwl_window_buffers_dispose(struct xwl_window *xwl_window);
PixmapPtr xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
RegionPtr damage_region);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 4978f37c7..a6a4cf8f5 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1192,6 +1192,9 @@ xwl_unrealize_window(WindowPtr window)
xwl_window_buffers_dispose(xwl_window);
+ if (xwl_window->window_buffers_timer)
+ TimerFree(xwl_window->window_buffers_timer);
+
if (xwl_window->frame_callback)
wl_callback_destroy(xwl_window->frame_callback);
@@ -1229,7 +1232,7 @@ xwl_window_set_window_pixmap(WindowPtr window,
xwl_window = xwl_window_get(window);
if (xwl_window)
- xwl_window_buffers_recycle(xwl_window);
+ xwl_window_buffers_dispose(xwl_window);
}
Bool
commit 2879032eccf6cca2b8132b8cebf6c285ee9f30f6
Author: Michel Dänzer <mdaenzer at redhat.com>
Date: Thu Dec 21 12:29:35 2023 +0100
xwayland: Rename helper to xwl_window_buffer_maybe_dispose
To make it clearer that it doesn't always dispose of the
xwl_window_buffer, only if the reference count drops to 0.
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index 011656f0d..d2cf3c3fe 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -96,7 +96,7 @@ xwl_window_buffer_destroy_pixmap(struct xwl_window_buffer *xwl_window_buffer)
}
static Bool
-xwl_window_buffer_dispose(struct xwl_window_buffer *xwl_window_buffer)
+xwl_window_buffer_maybe_dispose(struct xwl_window_buffer *xwl_window_buffer)
{
assert(xwl_window_buffer->refcnt > 0);
@@ -169,7 +169,7 @@ xwl_window_buffer_timer_callback(OsTimerPtr timer, CARD32 time, void *arg)
&xwl_window->window_buffers_available,
link_buffer) {
if ((int64_t)(time - xwl_window_buffer->time) >= BUFFER_TIMEOUT)
- xwl_window_buffer_dispose(xwl_window_buffer);
+ xwl_window_buffer_maybe_dispose(xwl_window_buffer);
}
/* If there are still available buffers, re-arm the timer */
@@ -196,7 +196,7 @@ xwl_window_buffer_release_callback(void *data)
/* Drop the reference on the buffer we took in get_pixmap. If that
* frees the window buffer, we're done.
*/
- if (xwl_window_buffer_dispose(xwl_window_buffer))
+ if (xwl_window_buffer_maybe_dispose(xwl_window_buffer))
return;
if (xwl_window_buffer->recycle_on_release)
@@ -243,7 +243,7 @@ xwl_window_buffers_recycle(struct xwl_window *xwl_window)
xorg_list_for_each_entry_safe(xwl_window_buffer, tmp,
&xwl_window->window_buffers_available,
link_buffer) {
- xwl_window_buffer_dispose(xwl_window_buffer);
+ xwl_window_buffer_maybe_dispose(xwl_window_buffer);
}
if (xwl_window->window_buffers_timer)
@@ -270,14 +270,14 @@ xwl_window_buffers_dispose(struct xwl_window *xwl_window)
&xwl_window->window_buffers_available,
link_buffer) {
xorg_list_del(&xwl_window_buffer->link_buffer);
- xwl_window_buffer_dispose(xwl_window_buffer);
+ xwl_window_buffer_maybe_dispose(xwl_window_buffer);
}
xorg_list_for_each_entry_safe(xwl_window_buffer, tmp,
&xwl_window->window_buffers_unavailable,
link_buffer) {
xorg_list_del(&xwl_window_buffer->link_buffer);
- xwl_window_buffer_dispose(xwl_window_buffer);
+ xwl_window_buffer_maybe_dispose(xwl_window_buffer);
}
if (xwl_window->window_buffers_timer) {
commit 114f060de5b08f439dcc238e1a63c00f5c5e4c23
Author: Michel Dänzer <mdaenzer at redhat.com>
Date: Thu Dec 21 12:06:07 2023 +0100
xwayland: Make copy_pixmap_area return void
GetScratchGC can't really fail without a bug elsewhere. Just FatalError
in that case, so we'd get a bug report if it ever happens, instead of
trying to limp along.
diff --git a/hw/xwayland/xwayland-window-buffers.c b/hw/xwayland/xwayland-window-buffers.c
index f7bb571bb..011656f0d 100644
--- a/hw/xwayland/xwayland-window-buffers.c
+++ b/hw/xwayland/xwayland-window-buffers.c
@@ -45,27 +45,24 @@ struct xwl_window_buffer {
struct xorg_list link_buffer;
};
-static Bool
+static void
copy_pixmap_area(PixmapPtr src_pixmap, PixmapPtr dst_pixmap,
int x, int y, int width, int height)
{
GCPtr pGC;
pGC = GetScratchGC(dst_pixmap->drawable.depth,
dst_pixmap->drawable.pScreen);
- if (pGC) {
- ValidateGC(&dst_pixmap->drawable, pGC);
- (void) (*pGC->ops->CopyArea) (&src_pixmap->drawable,
- &dst_pixmap->drawable,
- pGC,
- x, y,
- width, height,
- x, y);
- FreeScratchGC(pGC);
-
- return TRUE;
- }
-
- return FALSE;
+ if (!pGC)
+ FatalError("GetScratchGC failed for depth %d", dst_pixmap->drawable.depth);
+
+ ValidateGC(&dst_pixmap->drawable, pGC);
+ (void) (*pGC->ops->CopyArea) (&src_pixmap->drawable,
+ &dst_pixmap->drawable,
+ pGC,
+ x, y,
+ width, height,
+ x, y);
+ FreeScratchGC(pGC);
}
static struct xwl_window_buffer *
@@ -317,13 +314,12 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
BoxPtr pBox = RegionRects(full_damage);
int nBox = RegionNumRects(full_damage);
while (nBox--) {
- if (!copy_pixmap_area(window_pixmap,
- xwl_window_buffer->pixmap,
- pBox->x1 + xwl_window->window->borderWidth,
- pBox->y1 + xwl_window->window->borderWidth,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1))
- return window_pixmap;
+ copy_pixmap_area(window_pixmap,
+ xwl_window_buffer->pixmap,
+ pBox->x1 + xwl_window->window->borderWidth,
+ pBox->y1 + xwl_window->window->borderWidth,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1);
pBox++;
}
@@ -345,14 +341,11 @@ xwl_window_buffers_get_pixmap(struct xwl_window *xwl_window,
if (!xwl_window_buffer->pixmap)
return window_pixmap;
- if (!copy_pixmap_area(window_pixmap,
- xwl_window_buffer->pixmap,
- 0, 0,
- window_pixmap->drawable.width,
- window_pixmap->drawable.height)) {
- xwl_window_buffer_recycle(xwl_window_buffer);
- return window_pixmap;
- }
+ copy_pixmap_area(window_pixmap,
+ xwl_window_buffer->pixmap,
+ 0, 0,
+ window_pixmap->drawable.width,
+ window_pixmap->drawable.height);
}
RegionEmpty(xwl_window_buffer->damage_region);
More information about the xorg-commit
mailing list