[PATCH] hw: Fix visual colormap_size mixup causing "missing" visuals.
Alex Orange
crazycasta at gmail.com
Tue Jan 6 17:14:01 PST 2015
Bumping this. Hopefully the holiday rush has slimmed a bit by now.
Alex
On Sun, Nov 30, 2014 at 2:38 PM, Alex Orange <crazycasta at gmail.com> 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 <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/20150106/623f8e7f/attachment-0001.html>
More information about the xorg-devel
mailing list