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 <crazyca...@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 <crazyca...@gmail.com> > Tested-by: Alex Orange <crazyca...@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 > >
_______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel