[PATCH] render: Don't generate invalid pixman format when using a 24bpp framebuffer with a 32bit depth visual.
Takashi Iwai
tiwai at suse.de
Fri Aug 15 07:43:54 PDT 2014
At Fri, 15 Aug 2014 12:01:53 +0200,
Takashi Iwai wrote:
>
> At Tue, 12 Aug 2014 16:03:54 -0700,
> Keith Packard wrote:
> >
> > Robert Ancell <robert.ancell at canonical.com> writes:
> >
> > > When using the fb backend at 24bpp it allows a visual with 32 bit
> > > depth.
> >
> > That's not valid; depth must never be larger than bits per pixel.
>
> Can we put some assert to catch such a bug?
>
> > Please
> > fix your driver, don't break the insides of the X server.
>
> Which driver do you mean, X or KMS? It seems happening on both fbdev
> and modesetting X drivers when cirrus/mgag200 KMS is used with 24bpp.
Looking further down, I believe it's rather a X server problem, but
the real cause is in a different place.
The KMS driver advertises properly depth 24 and bpp 24. However,
fbFinishScreenInit() has the following code:
/*
* By default, a 24bpp screen will use 32bpp images, this avoids
* problems with many applications which just can't handle packed
* pixels. If you want real 24bit images, include a 24bpp
* format in the pixmap formats
*/
if (bpp == 24) {
int f;
imagebpp = 32;
/*
* Check to see if we're advertising a 24bpp image format,
* in which case windows will use it in preference to a 32 bit
* format.
*/
for (f = 0; f < screenInfo.numPixmapFormats; f++) {
if (screenInfo.formats[f].bitsPerPixel == 24) {
imagebpp = 24;
break;
}
}
}
if (imagebpp == 32) {
fbGetScreenPrivate(pScreen)->win32bpp = bpp;
fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
}
else {
fbGetScreenPrivate(pScreen)->win32bpp = 32;
fbGetScreenPrivate(pScreen)->pix32bpp = 32;
}
Since bpp = 24 and there is no format providing 24 bpp (fbdev takes
the default screen pixmap formats), imagebpp above is 32, thus
*->wind32bpp is set to bpp, i.e. 24.
This value is referred in fbCreateWindow():
if (pWin->drawable.bitsPerPixel == 32)
pWin->drawable.bitsPerPixel =
fbGetScreenPrivate(pWin->drawable.pScreen)->win32bpp;
That is, bitsPerPixel is replaced from 32 to 24 in CreateWindow().
Hence this results in the combination of depth=32/bpp=24. Ouch.
So, either we have to kill the hack in fb/* above, or accept that the
combo "depth 32 / bpp 24" can happen and fix the codes appropriately.
Or another better alternative?
Takashi
More information about the xorg-devel
mailing list