mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-21 01:13:38 +00:00
fb: Don't widen the planemask over padding bits when ROOTLESS_SAFEALPHA is set
Wide LineDoubleDash lines drew black on screen under XQuartz while the server's own XGetImage readback showed the correct pixels, because at depth 24 that readback ignores alpha. Opaque text and dashed arcs take the same path. fbValidateGC widens a planemask that covers the drawable's depth to cover its full bits per pixel, so the blit and fill paths can take their all-ones shortcuts. On a rootless server that also writes the alpha channel of the window's premultiplied surface, which CoreGraphics then composites as black. Rootless keeps that alpha opaque by clearing the bits from the planemask, but only its own ValidateGC does so, and mi revalidates the GC in the middle of a drawing operation to swap the foreground for the background pixel. By then the damage layer has unwrapped the rootless funcs down to fb, so the reassertion never happens and the rest of the operation lands with a zero alpha channel. Fixes: https://github.com/XQuartz/XQuartz/issues/230 Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com>
This commit is contained in:
parent
bc968311fb
commit
3d20b6d253
1 changed files with 17 additions and 0 deletions
17
fb/fbgc.c
17
fb/fbgc.c
|
|
@ -152,7 +152,24 @@ fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
|||
pPriv->fg = pGC->fgPixel & mask;
|
||||
pPriv->bg = pGC->bgPixel & mask;
|
||||
|
||||
/*
|
||||
* Widening the planemask to cover the padding bits lets the blit and
|
||||
* fill paths take their "all ones" shortcuts, but it also makes them
|
||||
* write those bits. A rootless server keeps the alpha channel of its
|
||||
* on screen windows opaque by clearing the alpha bits from the
|
||||
* planemask (see miext/rootless/rootlessGC.c), and it can only do so
|
||||
* from its own ValidateGC. mi revalidates the GC in the middle of a
|
||||
* drawing operation for dashed lines, dashed arcs and opaque text,
|
||||
* and by then the rootless funcs have been unwrapped by the damage
|
||||
* layer, so that reassertion never happens. Leave the padding bits
|
||||
* alone when they aren't part of the depth.
|
||||
*/
|
||||
#ifdef ROOTLESS_SAFEALPHA
|
||||
if (pDrawable->depth == pDrawable->bitsPerPixel &&
|
||||
(pGC->planemask & depthMask) == depthMask)
|
||||
#else
|
||||
if ((pGC->planemask & depthMask) == depthMask)
|
||||
#endif
|
||||
pPriv->pm = mask;
|
||||
else
|
||||
pPriv->pm = pGC->planemask & mask;
|
||||
|
|
|
|||
Loading…
Reference in a new issue