Bumping this. Hopefully the holiday rush has slimmed a bit by now. Alex
On Sun, Nov 30, 2014 at 2:38 PM, Alex Orange <[email protected]> wrote: > 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 <[email protected]> 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 <[email protected]> >> Tested-by: Alex Orange <[email protected]> >> --- >> 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 >> >> >
_______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
