xserver: Branch 'master' - 4 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 26 15:46:17 UTC 2023


 glamor/glamor_compositerects.c |    8 +--
 glamor/glamor_copy.c           |    8 +--
 glamor/glamor_image.c          |    2 
 glamor/glamor_prepare.c        |    4 -
 glamor/glamor_priv.h           |   26 +++++++++
 glamor/glamor_render.c         |    2 
 glamor/glamor_text.c           |    7 --
 glamor/glamor_transfer.c       |    2 
 glamor/glamor_transform.h      |    3 -
 glamor/glamor_utils.c          |    3 -
 hw/xwayland/xwayland-glamor.c  |  109 +++++++++++++++++++++++++++++++++++++++++
 hw/xwayland/xwayland-screen.h  |    2 
 mi/miexpose.c                  |   24 +++++++++
 13 files changed, 177 insertions(+), 23 deletions(-)

New commits:
commit 4bb1f976d5397949be06510524bede5ae3bbfe0a
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Jul 20 10:15:15 2023 +0200

    xwayland/glamor: Avoid implicit redirection with depth 32 parent windows
    
    glamor ensures that a depth 32 pixmap backing a depth 24 window contains
    fully opaque alpha channel values for the window's pixels, so we can
    allow this without implicit redirection, saving pixmap storage and
    intermediate copies.
    
    Second attempt, after fixing a few regressions from the first attempt.

diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c
index 9ac1aa8d4..c6aa8eb17 100644
--- a/hw/xwayland/xwayland-glamor.c
+++ b/hw/xwayland/xwayland-glamor.c
@@ -25,6 +25,8 @@
 
 #include <xwayland-config.h>
 
+#include <compositeext.h>
+
 #define MESA_EGL_NO_X11_HEADERS
 #define EGL_NO_X11
 #include <glamor_egl.h>
@@ -893,6 +895,108 @@ xwl_glamor_allow_commits(struct xwl_window *xwl_window)
         return TRUE;
 }
 
+static void
+xwl_avoid_implicit_redirect(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    WindowOptPtr parent_optional;
+    VisualPtr parent_visual = NULL;
+    VisualPtr window_visual = NULL;
+    DepthPtr depth32 = NULL;
+    int i;
+
+    if (!window->optional)
+        return;
+
+    parent_optional = FindWindowWithOptional(window)->optional;
+    if (window->optional == parent_optional ||
+        window->optional->visual == parent_optional->visual ||
+        CompositeIsImplicitRedirectException(screen, parent_optional->visual,
+                                             window->optional->visual))
+        return;
+
+    for (i = 0; i < screen->numDepths; i++) {
+        if (screen->allowedDepths[i].depth == 32) {
+            depth32 = &screen->allowedDepths[i];
+            break;
+        }
+    }
+
+    if (!depth32)
+        return;
+
+    for (i = 0; i < depth32->numVids; i++) {
+        XID argb_vid = depth32->vids[i];
+
+        if (argb_vid != parent_optional->visual)
+            continue;
+
+        if (!compIsAlternateVisual(screen, argb_vid))
+            break;
+
+        for (i = 0; i < screen->numVisuals; i++) {
+            if (screen->visuals[i].vid == argb_vid) {
+                parent_visual = &screen->visuals[i];
+                break;
+            }
+        }
+    }
+
+    if (!parent_visual)
+        return;
+
+    for (i = 0; i < screen->numVisuals; i++) {
+        if (screen->visuals[i].vid == window->optional->visual) {
+            window_visual = &screen->visuals[i];
+            break;
+        }
+    }
+
+    if ((window_visual->class != TrueColor &&
+         window_visual->class != DirectColor) ||
+        window_visual->redMask != parent_visual->redMask ||
+        window_visual->greenMask != parent_visual->greenMask ||
+        window_visual->blueMask != parent_visual->blueMask ||
+        window_visual->offsetRed != parent_visual->offsetRed ||
+        window_visual->offsetGreen != parent_visual->offsetGreen ||
+        window_visual->offsetBlue != parent_visual->offsetBlue)
+        return;
+
+    CompositeRegisterImplicitRedirectionException(screen, parent_visual->vid, window_visual->vid);
+}
+
+static Bool
+xwl_glamor_create_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    Bool ret;
+
+    if (window->parent)
+        xwl_avoid_implicit_redirect(window);
+
+    screen->CreateWindow = xwl_screen->CreateWindow;
+    ret = (*screen->CreateWindow) (window);
+    xwl_screen->CreateWindow = screen->CreateWindow;
+    screen->CreateWindow = xwl_glamor_create_window;
+
+    return ret;
+}
+
+static void
+xwl_glamor_reparent_window(WindowPtr window, WindowPtr old_parent)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+
+    xwl_avoid_implicit_redirect(window);
+
+    screen->ReparentWindow = xwl_screen->ReparentWindow;
+    (*screen->ReparentWindow) (window, old_parent);
+    xwl_screen->ReparentWindow = screen->ReparentWindow;
+    screen->ReparentWindow = xwl_glamor_reparent_window;
+}
+
 static Bool
 xwl_glamor_create_screen_resources(ScreenPtr screen)
 {
@@ -907,6 +1011,11 @@ xwl_glamor_create_screen_resources(ScreenPtr screen)
     if (!ret)
         return ret;
 
+    xwl_screen->CreateWindow = screen->CreateWindow;
+    screen->CreateWindow = xwl_glamor_create_window;
+    xwl_screen->ReparentWindow = screen->ReparentWindow;
+    screen->ReparentWindow = xwl_glamor_reparent_window;
+
     if (xwl_screen->rootless) {
         screen->devPrivate =
             fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0);
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index da97d7f1d..94033aabf 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -70,12 +70,14 @@ struct xwl_screen {
 
     CreateScreenResourcesProcPtr CreateScreenResources;
     CloseScreenProcPtr CloseScreen;
+    CreateWindowProcPtr CreateWindow;
     RealizeWindowProcPtr RealizeWindow;
     UnrealizeWindowProcPtr UnrealizeWindow;
     DestroyWindowProcPtr DestroyWindow;
     XYToWindowProcPtr XYToWindow;
     SetWindowPixmapProcPtr SetWindowPixmap;
     ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+    ReparentWindowProcPtr ReparentWindow;
     ResizeWindowProcPtr ResizeWindow;
     MoveWindowProcPtr MoveWindow;
 
commit d4e11f4c922a119dfb5130b15ac22f58589783e7
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Jul 19 18:00:18 2023 +0200

    glamor: Make glamor_solid_boxes take a DrawablePtr
    
    Instead of a PixmapPtr. Gives better results if the window depth
    doesn't match the backing pixmap depth.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1565

diff --git a/glamor/glamor_compositerects.c b/glamor/glamor_compositerects.c
index 199e62705..0796fed41 100644
--- a/glamor/glamor_compositerects.c
+++ b/glamor/glamor_compositerects.c
@@ -227,12 +227,10 @@ glamor_composite_rectangles(CARD8 op,
     boxes = pixman_region_rectangles(&region, &num_boxes);
     if (op == PictOpSrc || op == PictOpClear) {
         CARD32 pixel;
-        int dst_x, dst_y;
 
-        glamor_get_drawable_deltas(dst->pDrawable, pixmap, &dst_x, &dst_y);
-        pixman_region_translate(&region, dst_x, dst_y);
+        pixman_region_translate(&region, -dst->pDrawable->x, -dst->pDrawable->y);
 
-        DEBUGF("%s: pixmap +(%d, %d) extents (%d, %d),(%d, %d)\n",
+        DEBUGF("%s: drawable extents (%d, %d),(%d, %d)\n",
                __FUNCTION__, dst_x, dst_y,
                RegionExtents(&region)->x1, RegionExtents(&region)->y1,
                RegionExtents(&region)->x2, RegionExtents(&region)->y2);
@@ -241,7 +239,7 @@ glamor_composite_rectangles(CARD8 op,
             pixel = 0;
         else
             miRenderColorToPixel(dst->pFormat, color, &pixel);
-        glamor_solid_boxes(pixmap, boxes, num_boxes, pixel);
+        glamor_solid_boxes(dst->pDrawable, boxes, num_boxes, pixel);
 
         goto done;
     }
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 2f787015d..898380d82 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -895,7 +895,7 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
              unsigned long fg_pixel);
 
 void
-glamor_solid_boxes(PixmapPtr pixmap,
+glamor_solid_boxes(DrawablePtr drawable,
                    BoxPtr box, int nbox, unsigned long fg_pixel);
 
 
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index a559aea8a..5343cc93b 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -432,7 +432,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
         int c;
         RegionRec region;
         BoxRec box;
-        int off_x, off_y;
 
         /* Check planemask before drawing background to
          * bail early if it's not OK
@@ -443,8 +442,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
             if (charinfo[c])
                 width += charinfo[c]->metrics.characterWidth;
 
-        glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
-
         if (width >= 0) {
             box.x1 = drawable->x + x;
             box.x2 = drawable->x + x + width;
@@ -456,8 +453,8 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
         box.y2 = drawable->y + y + gc->font->info.fontDescent;
         RegionInit(&region, &box, 1);
         RegionIntersect(&region, &region, gc->pCompositeClip);
-        RegionTranslate(&region, off_x, off_y);
-        glamor_solid_boxes(pixmap, RegionRects(&region), RegionNumRects(&region), gc->bgPixel);
+        RegionTranslate(&region, -drawable->x, -drawable->y);
+        glamor_solid_boxes(drawable, RegionRects(&region), RegionNumRects(&region), gc->bgPixel);
         RegionUninit(&region);
     }
 
diff --git a/glamor/glamor_utils.c b/glamor/glamor_utils.c
index d3e6fd3ff..8f085da3f 100644
--- a/glamor/glamor_utils.c
+++ b/glamor/glamor_utils.c
@@ -23,10 +23,9 @@
 #include "glamor_priv.h"
 
 void
-glamor_solid_boxes(PixmapPtr pixmap,
+glamor_solid_boxes(DrawablePtr drawable,
                    BoxPtr box, int nbox, unsigned long fg_pixel)
 {
-    DrawablePtr drawable = &pixmap->drawable;
     GCPtr gc;
     xRectangle *rect;
     int n;
commit 2de50de563df9d2315d74a63ce5ffbaf3c25f1ae
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Jul 19 10:43:56 2023 +0200

    mi: Fix up alpha channel if needed in miPaintWindow
    
    See also the previous commit log.
    
    Fixes the issues with xterm & xcalc described in the GitLab issue below.
    
    Issue: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1564

diff --git a/mi/miexpose.c b/mi/miexpose.c
index 6b6938a75..6239365b5 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -405,6 +405,9 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     BoxPtr pbox;
     xRectangle *prect;
     int numRects, regionnumrects;
+#ifdef COMPOSITE
+    WindowPtr orig_pWin = pWin;
+#endif
 
     /*
      * Distance from screen to destination drawable, use this
@@ -488,6 +491,27 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
         gcval[1].val =
             fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel);
 #else
+#ifdef COMPOSITE
+        /* Make sure alpha will sample as 1.0 for opaque windows */
+        if (drawable->depth == 32) {
+            int effective_depth = orig_pWin->drawable.depth;
+
+            if (effective_depth == 32) {
+                orig_pWin = orig_pWin->parent;
+                while (orig_pWin && orig_pWin->parent) {
+                    if (orig_pWin->drawable.depth == 24) {
+                        effective_depth = 24;
+                        break;
+                    }
+
+                    orig_pWin = orig_pWin->parent;
+                }
+            }
+
+            if (effective_depth == 24)
+                fill.pixel |= 0xff000000;
+        }
+#endif
         gcval[1].val = fill.pixel;
 #endif
         gcval[2].val = FillSolid;
commit 3e044b1e64c9eead030031cc98bfc345a5629bcf
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Jul 19 12:26:21 2023 +0200

    glamor: Add and use glamor_drawable_effective_depth helper
    
    Consider the following window hierarchy, from ancestors to descendants:
    
     A
     |
     B
     |
     C
    
    If both A & C have depth 32, but B has depth 24, C must effectively
    behave as if it had depth 24, even if its backing pixmap has depth 32
    as well.
    
    Fixes the xmag issue described in the GitLab issue below.
    
    Issue: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1564

diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
index 58bfa2b0e..08b55b67b 100644
--- a/glamor/glamor_copy.c
+++ b/glamor/glamor_copy.c
@@ -77,7 +77,7 @@ use_copyplane(DrawablePtr drawable, GCPtr gc, glamor_program *prog, void *arg)
     glamor_set_color(drawable, gc->bgPixel, prog->bg_uniform);
 
     /* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */
-    switch (args->src_drawable->depth) {
+    switch (glamor_drawable_effective_depth(args->src_drawable)) {
     case 30:
         glUniform4ui(prog->bitplane_uniform,
                      (args->bitplane >> 20) & 0x3ff,
@@ -235,7 +235,7 @@ glamor_copy_cpu_fbo(DrawablePtr src,
 
         PixmapPtr tmp_pix = fbCreatePixmap(screen, dst_pixmap->drawable.width,
                                            dst_pixmap->drawable.height,
-                                           dst->depth, 0);
+                                           glamor_drawable_effective_depth(dst), 0);
 
         if (!tmp_pix) {
             glamor_finish_access(src);
@@ -547,7 +547,7 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
     tmp_pixmap = glamor_create_pixmap(screen,
                                       bounds.x2 - bounds.x1,
                                       bounds.y2 - bounds.y1,
-                                      src->depth, 0);
+                                      glamor_drawable_effective_depth(src), 0);
     if (!tmp_pixmap)
         goto bail;
 
@@ -757,7 +757,7 @@ glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
                   int srcx, int srcy, int width, int height, int dstx, int dsty,
                   unsigned long bitplane)
 {
-    if ((bitplane & FbFullMask(src->depth)) == 0)
+    if ((bitplane & FbFullMask(glamor_drawable_effective_depth(src))) == 0)
         return miHandleExposures(src, dst, gc,
                                  srcx, srcy, width, height, dstx, dsty);
     return miDoCopy(src, dst, gc,
diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
index 1a8e527b6..28bdc159f 100644
--- a/glamor/glamor_image.c
+++ b/glamor/glamor_image.c
@@ -129,7 +129,7 @@ glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
                           -x, -y,
                           (uint8_t *) d, byte_stride);
 
-    if (!glamor_pm_is_solid(drawable->depth, plane_mask)) {
+    if (!glamor_pm_is_solid(glamor_drawable_effective_depth(drawable), plane_mask)) {
         FbStip pm = fbReplicatePixel(plane_mask, drawable->bitsPerPixel);
         FbStip *dst = (void *)d;
         uint32_t dstStride = byte_stride / sizeof(FbStip);
diff --git a/glamor/glamor_prepare.c b/glamor/glamor_prepare.c
index 2bab2b613..fba875e28 100644
--- a/glamor/glamor_prepare.c
+++ b/glamor/glamor_prepare.c
@@ -163,7 +163,7 @@ glamor_finish_access(DrawablePtr drawable)
         return;
 
     if (priv->pbo &&
-        !(drawable->depth == 24 && pixmap->drawable.depth == 32)) {
+        !(glamor_drawable_effective_depth(drawable) == 24 && pixmap->drawable.depth == 32)) {
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo);
         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
         pixmap->devPrivate.ptr = NULL;
@@ -179,7 +179,7 @@ glamor_finish_access(DrawablePtr drawable)
     RegionUninit(&priv->prepare_region);
 
     if (priv->pbo) {
-        if (drawable->depth == 24 && pixmap->drawable.depth == 32)
+        if (glamor_drawable_effective_depth(drawable) == 24 && pixmap->drawable.depth == 32)
             pixmap->devPrivate.ptr = NULL;
         else
             glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 1032b880b..2f787015d 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -513,6 +513,30 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv)
     for (box_index = 0; box_index < glamor_pixmap_hcnt(priv) *         \
              glamor_pixmap_wcnt(priv); box_index++)                    \
 
+static inline int
+glamor_drawable_effective_depth(DrawablePtr drawable)
+{
+    WindowPtr window;
+
+    if (drawable->type != DRAWABLE_WINDOW ||
+        drawable->depth != 32)
+        return drawable->depth;
+
+    window = (WindowPtr)drawable;
+    window = window->parent;
+    while (window && window->parent) {
+        /* A depth 32 window with any depth 24 ancestors (other than the root
+         * window) effectively behaves like depth 24
+         */
+        if (window->drawable.depth == 24)
+            return 24;
+
+        window = window->parent;
+    }
+
+    return 32;
+}
+
 /* GC private structure. Currently holds only any computed dash pixmap */
 
 typedef struct {
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 889fe1b36..ed1222621 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -806,7 +806,7 @@ glamor_render_format_is_supported(PicturePtr picture)
         return TRUE;
 
     glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen);
-    f = &glamor_priv->formats[picture->pDrawable->depth];
+    f = &glamor_priv->formats[glamor_drawable_effective_depth(picture->pDrawable)];
 
     if (!f->rendering_supported)
         return FALSE;
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index a2727f109..9404e899c 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -41,7 +41,7 @@ glamor_upload_boxes(DrawablePtr drawable, BoxPtr in_boxes, int in_nbox,
     const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
     char *tmp_bits = NULL;
 
-    if (drawable->depth == 24 && pixmap->drawable.depth == 32)
+    if (glamor_drawable_effective_depth(drawable) == 24 && pixmap->drawable.depth == 32)
         tmp_bits = xnfalloc(byte_stride * pixmap->drawable.height);
 
     glamor_make_current(glamor_priv);
diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h
index 305253310..6eef2fc7a 100644
--- a/glamor/glamor_transform.h
+++ b/glamor/glamor_transform.h
@@ -44,7 +44,8 @@ glamor_set_color(DrawablePtr    drawable,
                  GLint          uniform)
 {
     glamor_set_color_depth(drawable->pScreen,
-                           drawable->depth, pixel, uniform);
+                           glamor_drawable_effective_depth(drawable),
+                           pixel, uniform);
 }
 
 Bool


More information about the xorg-commit mailing list