[PATCH] hw: Fix visual colormap_size mixup causing "missing" visuals.
Alex Orange
crazycasta at gmail.com
Sun Nov 30 13:38:42 PST 2014
Please ignore the first patch, got old comment lines left in by accident.
Probably forgot to git add.
Alex
On Sun, Nov 30, 2014 at 2:37 PM, Alex Orange <crazycasta at gmail.com> wrote:
> Likely fixes: https://bugs.freedesktop.org/show_bug.cgi?id=24642
>
> dmx uses fb to handle many action. As such is uses fbScreenInit. The
> trouble is that fbScreenInit uses mi to generate the visuals. mi has
> trouble with 32-bit (rgba) depths. It tries to treat these depths as
> 10-bits per pixels. This results in colormap_sizes in the visuals being
> 2048 instead of 256. Also, the comments in micmap.c about the macros,
> _CE is the relevant one, suggest that these numbers may be driver
> defined. To this end, this patch simply copies the visuals into the
> visuals and depths structs instead of trying to coax mi into creating
> the right visuals. The code was mostly just taken from xnest with
> changes since dmx uses fb. The result depends on miScreenInit simply
> stuffing visuals in the screen and not doing anything more with them. In
> the future perhaps fbScreenInit can take an optional set of visuals to
> use instead of calling miInitVisuals.
>
> Signed-off-by: Alex Orange <crazycasta at gmail.com>
> Tested-by: Alex Orange <crazycasta at gmail.com>
> ---
> hw/dmx/dmxscrinit.c | 159
> ++++++++++++++++++++++++++++++++++++++++------------
> hw/dmx/dmxscrinit.h | 5 ++
> 2 files changed, 129 insertions(+), 35 deletions(-)
>
> diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c
> index 963d3a9..3c68708 100644
> --- a/hw/dmx/dmxscrinit.c
> +++ b/hw/dmx/dmxscrinit.c
> @@ -54,9 +54,12 @@
>
> #include "dmxpict.h"
>
> -#include "fb.h"
> +#include <X11/X.h>
> +#include "mi.h"
> #include "mipointer.h"
> #include "micmap.h"
> +#include "resource.h"
> +#include "fb.h"
>
> extern Bool dmxCloseScreen(ScreenPtr pScreen);
> static Bool dmxSaveScreen(ScreenPtr pScreen, int what);
> @@ -172,12 +175,28 @@ dmxBEScreenInit(ScreenPtr pScreen)
> }
> }
>
> +static int
> +offset(unsigned long mask)
> +{
> + int count;
> +
> + for (count = 0; !(mask & 1) && count < 32; count++)
> + mask >>= 1;
> +
> + return count;
> +}
> +
> /** Initialize screen number \a pScreen->myNum. */
> Bool
> dmxScreenInit(ScreenPtr pScreen, int argc, char *argv[])
> {
> DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
> - int i, j;
> + int i, j, depthIndex;
> + VisualPtr visuals;
> + DepthPtr depths;
> + int numVisuals, numDepths;
> + VisualID defaultBEVisual, defaultVisual;
> + int rootDepth;
>
> if (!dixRegisterPrivateKey(&dmxScreenPrivateKeyRec, PRIVATE_SCREEN,
> 0))
> return FALSE;
> @@ -202,41 +221,95 @@ dmxScreenInit(ScreenPtr pScreen, int argc, char
> *argv[])
> if (!dmxInitPixmap(pScreen))
> return FALSE;
>
> - /*
> - * Initalise the visual types. miSetVisualTypesAndMasks() requires
> - * that all of the types for each depth be collected together. It's
> - * intended for slightly different usage to what we would like here.
> - * Maybe a miAddVisualTypeAndMask() function will be added to make
> - * things easier here.
> - */
> - for (i = 0; i < dmxScreen->beNumDepths; i++) {
> - int depth;
> - int visuals = 0;
> - int bitsPerRgb = 0;
> - int preferredClass = -1;
> - Pixel redMask = 0;
> - Pixel greenMask = 0;
> - Pixel blueMask = 0;
> -
> - depth = dmxScreen->beDepths[i];
> - for (j = 0; j < dmxScreen->beNumVisuals; j++) {
> - XVisualInfo *vi;
> -
> - vi = &dmxScreen->beVisuals[j];
> - if (vi->depth == depth) {
> - /* Assume the masks are all the same. */
> - visuals |= (1 << vi->class);
> - bitsPerRgb = vi->bits_per_rgb;
> - redMask = vi->red_mask;
> - greenMask = vi->green_mask;
> - blueMask = vi->blue_mask;
> - if (j == dmxScreen->beDefVisualIndex) {
> - preferredClass = vi->class;
> - }
> + visuals = (VisualPtr) malloc(dmxScreen->beNumVisuals *
> sizeof(VisualRec));
> + numVisuals = 0;
> +
> + depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
> + depths[0].depth = 1;
> + depths[0].numVids = 0;
> + depths[0].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH *
> sizeof(VisualID));
> + numDepths = 1;
> +
> + defaultBEVisual =
> XVisualIDFromVisual(DefaultVisual(dmxScreen->beDisplay,
> + DefaultScreen
> +
> (dmxScreen->beDisplay)));
> + rootDepth = UNDEFINED;
> + defaultVisual = UNDEFINED;
> +
> + for (i = 0; i < dmxScreen->beNumVisuals; i++) {
> + visuals[numVisuals].class = dmxScreen->beVisuals[i].class;
> + visuals[numVisuals].bitsPerRGBValue =
> + dmxScreen->beVisuals[i].bits_per_rgb;
> + visuals[numVisuals].ColormapEntries =
> + dmxScreen->beVisuals[i].colormap_size;
> + visuals[numVisuals].nplanes = dmxScreen->beVisuals[i].depth;
> + visuals[numVisuals].redMask = dmxScreen->beVisuals[i].red_mask;
> + visuals[numVisuals].greenMask =
> dmxScreen->beVisuals[i].green_mask;
> + visuals[numVisuals].blueMask = dmxScreen->beVisuals[i].blue_mask;
> + visuals[numVisuals].offsetRed =
> + offset(dmxScreen->beVisuals[i].red_mask);
> + visuals[numVisuals].offsetGreen =
> + offset(dmxScreen->beVisuals[i].green_mask);
> + visuals[numVisuals].offsetBlue =
> + offset(dmxScreen->beVisuals[i].blue_mask);
> +
> + /* Check for and remove duplicates. */
> + for (j = 0; j < numVisuals; j++) {
> + if (visuals[numVisuals].class == visuals[j].class &&
> + visuals[numVisuals].bitsPerRGBValue ==
> + visuals[j].bitsPerRGBValue &&
> + visuals[numVisuals].ColormapEntries ==
> + visuals[j].ColormapEntries &&
> + visuals[numVisuals].nplanes == visuals[j].nplanes &&
> + visuals[numVisuals].redMask == visuals[j].redMask &&
> + visuals[numVisuals].greenMask == visuals[j].greenMask &&
> + visuals[numVisuals].blueMask == visuals[j].blueMask &&
> + visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
> + visuals[numVisuals].offsetGreen == visuals[j].offsetGreen
> &&
> + visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
> + break;
> + }
> + if (j < numVisuals)
> + break;
> +
> + visuals[numVisuals].vid = FakeClientID(0);
> +
> + depthIndex = UNDEFINED;
> + for (j = 0; j < numDepths; j++)
> + if (depths[j].depth == dmxScreen->beVisuals[i].depth) {
> + depthIndex = j;
> + break;
> }
> +
> + if (depthIndex == UNDEFINED) {
> + depthIndex = numDepths;
> + depths[depthIndex].depth = dmxScreen->beVisuals[i].depth;
> + depths[depthIndex].numVids = 0;
> + depths[depthIndex].vids =
> + (VisualID *) malloc(MAXVISUALSPERDEPTH *
> sizeof(VisualID));
> + numDepths++;
> }
> - miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb,
> preferredClass,
> - redMask, greenMask, blueMask);
> + if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
> + FatalError("Visual table overflow");
> + }
> + depths[depthIndex].vids[depths[depthIndex].numVids] =
> + visuals[numVisuals].vid;
> + depths[depthIndex].numVids++;
> +
> + if (dmxScreen->beVisuals[i].visualid == defaultBEVisual) {
> + rootDepth = visuals[numVisuals].nplanes;
> + defaultVisual = visuals[numVisuals].vid;
> + }
> +
> + numVisuals++;
> + }
> + visuals = (VisualPtr) realloc(visuals, numVisuals *
> sizeof(VisualRec));
> +
> + if (rootDepth == UNDEFINED) {
> + rootDepth = visuals[0].nplanes;
> + }
> + if (defaultVisual == UNDEFINED) {
> + defaultVisual = visuals[0].vid;
> }
>
> fbScreenInit(pScreen,
> @@ -245,6 +318,22 @@ dmxScreenInit(ScreenPtr pScreen, int argc, char
> *argv[])
> dmxScreen->scrnHeight,
> dmxScreen->beXDPI,
> dmxScreen->beXDPI, dmxScreen->scrnWidth,
> dmxScreen->beBPP);
> +
> + // fbScreenInit calls miInitVisuals which makes uncontrollable
> colormap
> + // sizes. The following overrides these visuals (pending a better
> method).
> + for (i = 0; i < pScreen->numDepths; i++) {
> + free(pScreen->allowedDepths[i].vids);
> + }
> + free(pScreen->allowedDepths);
> + free(pScreen->visuals);
> +
> + pScreen->visuals = visuals;
> + pScreen->numVisuals = numVisuals;
> + pScreen->rootVisual = defaultVisual;
> + pScreen->allowedDepths = depths;
> + pScreen->numDepths = numDepths;
> + pScreen->rootDepth = rootDepth;
> +
> (void) dmxPictureInit(pScreen, 0, 0);
>
> /* Not yet... */
> diff --git a/hw/dmx/dmxscrinit.h b/hw/dmx/dmxscrinit.h
> index 9fe9c98..23d2f62 100644
> --- a/hw/dmx/dmxscrinit.h
> +++ b/hw/dmx/dmxscrinit.h
> @@ -40,6 +40,11 @@
>
> #include "scrnintstr.h"
>
> +#define UNDEFINED -1
> +
> +#define MAXDEPTH 32
> +#define MAXVISUALSPERDEPTH 256
> +
> extern Bool dmxScreenInit(ScreenPtr pScreen, int argc, char *argv[]);
>
> extern void dmxBEScreenInit(ScreenPtr pScreen);
> --
> 1.8.5.5
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.x.org/archives/xorg-devel/attachments/20141130/616d60d8/attachment-0001.html>
More information about the xorg-devel
mailing list