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
This commit is contained in:
Michel Dänzer 2023-07-19 12:26:21 +02:00 committed by Michel Dänzer
parent c4ee35ef24
commit 3e044b1e64
7 changed files with 35 additions and 10 deletions

View File

@ -77,7 +77,7 @@ use_copyplane(DrawablePtr drawable, GCPtr gc, glamor_program *prog, void *arg)
glamor_set_color(drawable, gc->bgPixel, prog->bg_uniform); glamor_set_color(drawable, gc->bgPixel, prog->bg_uniform);
/* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */ /* 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: case 30:
glUniform4ui(prog->bitplane_uniform, glUniform4ui(prog->bitplane_uniform,
(args->bitplane >> 20) & 0x3ff, (args->bitplane >> 20) & 0x3ff,
@ -235,7 +235,7 @@ glamor_copy_cpu_fbo(DrawablePtr src,
PixmapPtr tmp_pix = fbCreatePixmap(screen, dst_pixmap->drawable.width, PixmapPtr tmp_pix = fbCreatePixmap(screen, dst_pixmap->drawable.width,
dst_pixmap->drawable.height, dst_pixmap->drawable.height,
dst->depth, 0); glamor_drawable_effective_depth(dst), 0);
if (!tmp_pix) { if (!tmp_pix) {
glamor_finish_access(src); glamor_finish_access(src);
@ -547,7 +547,7 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src,
tmp_pixmap = glamor_create_pixmap(screen, tmp_pixmap = glamor_create_pixmap(screen,
bounds.x2 - bounds.x1, bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1, bounds.y2 - bounds.y1,
src->depth, 0); glamor_drawable_effective_depth(src), 0);
if (!tmp_pixmap) if (!tmp_pixmap)
goto bail; 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, int srcx, int srcy, int width, int height, int dstx, int dsty,
unsigned long bitplane) unsigned long bitplane)
{ {
if ((bitplane & FbFullMask(src->depth)) == 0) if ((bitplane & FbFullMask(glamor_drawable_effective_depth(src))) == 0)
return miHandleExposures(src, dst, gc, return miHandleExposures(src, dst, gc,
srcx, srcy, width, height, dstx, dsty); srcx, srcy, width, height, dstx, dsty);
return miDoCopy(src, dst, gc, return miDoCopy(src, dst, gc,

View File

@ -129,7 +129,7 @@ glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
-x, -y, -x, -y,
(uint8_t *) d, byte_stride); (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 pm = fbReplicatePixel(plane_mask, drawable->bitsPerPixel);
FbStip *dst = (void *)d; FbStip *dst = (void *)d;
uint32_t dstStride = byte_stride / sizeof(FbStip); uint32_t dstStride = byte_stride / sizeof(FbStip);

View File

@ -163,7 +163,7 @@ glamor_finish_access(DrawablePtr drawable)
return; return;
if (priv->pbo && 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); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
pixmap->devPrivate.ptr = NULL; pixmap->devPrivate.ptr = NULL;
@ -179,7 +179,7 @@ glamor_finish_access(DrawablePtr drawable)
RegionUninit(&priv->prepare_region); RegionUninit(&priv->prepare_region);
if (priv->pbo) { 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; pixmap->devPrivate.ptr = NULL;
else else
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

View File

@ -513,6 +513,30 @@ glamor_pixmap_hcnt(glamor_pixmap_private *priv)
for (box_index = 0; box_index < glamor_pixmap_hcnt(priv) * \ for (box_index = 0; box_index < glamor_pixmap_hcnt(priv) * \
glamor_pixmap_wcnt(priv); box_index++) \ 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 */ /* GC private structure. Currently holds only any computed dash pixmap */
typedef struct { typedef struct {

View File

@ -806,7 +806,7 @@ glamor_render_format_is_supported(PicturePtr picture)
return TRUE; return TRUE;
glamor_priv = glamor_get_screen_private(picture->pDrawable->pScreen); 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) if (!f->rendering_supported)
return FALSE; return FALSE;

View File

@ -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); const struct glamor_format *f = glamor_format_for_pixmap(pixmap);
char *tmp_bits = NULL; 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); tmp_bits = xnfalloc(byte_stride * pixmap->drawable.height);
glamor_make_current(glamor_priv); glamor_make_current(glamor_priv);

View File

@ -44,7 +44,8 @@ glamor_set_color(DrawablePtr drawable,
GLint uniform) GLint uniform)
{ {
glamor_set_color_depth(drawable->pScreen, glamor_set_color_depth(drawable->pScreen,
drawable->depth, pixel, uniform); glamor_drawable_effective_depth(drawable),
pixel, uniform);
} }
Bool Bool