How to shift color bits in fbdev?

Gregoire Gentil gregoire at gentil.com
Sat Mar 14 16:48:47 PDT 2009


Maarten, Daniel,

Thanks for your answers. Yes, wfb is what I need for my temporary
solution. And it works as you advertise it without too much complexity
of implementation. That's great! I include the patch below in case
somebody wants to do something similar in the future.

Now, I'm still unsure what to do exactly in the function I acces the
bits. More precisely, I'm unsure to understand what is the structure of
FbBits value.

In xorg.log, I have:
(**) FBDEV(0): Depth 24, (--) framebuffer bpp
32                                
(==) FBDEV(0): RGB weight
888                                                   

in xorg.conf, I'm in DefaultDepthColor 24.

And if I do the following
value = (((value & 0xff) >> 2) & 0xff) | (((value & 0xff00) >> 2) &
0xff00) | (((value & 0xff0000) >> 2) & 0xff0000) | (value & ~0xffffff);
(remember, my hardware is screwed and instead of discarding the two
wires corresponding to the two lower bits of the 24-wire output, I
discard the two higher bits, so my objective was to shift everything).

The color are fixed (yupee!) but the screen is extremelly dark. And some
portions which should be transparent around some icons or the cursor for
instance are black. Obviously, I'm messing something with the 32 bits
vs. 24 bits.

How the colors are ordered in the FbBits value? Is there a fourth 8-bit
of transparency? What should I do about it?

I'm very close but I'm obviously missing something.

Thanks in advance for any advice,

Grégoire


--- fbdev.c.orig	2009-03-13 19:02:29.000000000 -0700
+++ fbdev.c	2009-03-14 16:24:31.000000000 -0700
@@ -147,6 +147,12 @@
 	NULL
 };
 
+static const char *wfbSymbols[] = {
+	"wfbScreenInit",
+	"wfbPictureInit",
+	NULL
+};
+
 static const char *fbSymbols[] = {
 	"fbScreenInit",
 	"fbPictureInit",
@@ -230,7 +236,7 @@
 	if (!setupDone) {
 		setupDone = TRUE;
 		xf86AddDriver(&FBDEV, module, HaveDriverFuncs);
-		LoaderRefSymLists(afbSymbols, fbSymbols,
+		LoaderRefSymLists(afbSymbols, wfbSymbols, fbSymbols,
 				  shadowSymbols, fbdevHWSymbols, NULL);
 		return (pointer)1;
 	} else {
@@ -627,7 +633,7 @@
 		case 24:
 		case 32:
 			mod = "fb";
-			syms = fbSymbols;
+			syms = wfbSymbols;
 			break;
 		default:
 			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -725,6 +731,40 @@
     return TRUE;
 }
 
+/*Modif Gregoire*/
+static FbBits
+ReadMemory(const void *src, int size)
+{
+    FbBits bits = 0;
+
+    memcpy(&bits, src, size);
+
+    return bits;
+}
+
+/*Modif Gregoire*/
+static void
+WriteMemoryShiftBit(void *dst, FbBits value, int size)
+{
+    value = (((value & 0xff) >> 2) & 0xff) | (((value & 0xff00) >> 2) &
0xff00) | (((value & 0xff0000) >> 2) & 0xff0000) | (value & ~0xffffff);
+    memcpy(dst, &value, size);
+}
+
+/*Modif Gregoire*/
+static void
+SetupWrap(ReadMemoryProcPtr *pRead, WriteMemoryProcPtr *pWrite,
+			DrawablePtr pDraw)
+{
+    *pWrite = WriteMemoryShiftBit;
+
+    *pRead = ReadMemory;
+}
+
+/*Modif Gregoire*/
+static void
+FinishWrap(DrawablePtr pDraw) 
+{
+}
 
 static Bool
 FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char
**argv)
@@ -854,11 +894,11 @@
 		case 16:
 		case 24:
 		case 32:
-			ret = fbScreenInit(pScreen, fPtr->shadowFB ? fPtr->shadow
+			ret = wfbScreenInit(pScreen, fPtr->shadowFB ? fPtr->shadow
 					   : fPtr->fbstart, pScrn->virtualX,
 					   pScrn->virtualY, pScrn->xDpi,
 					   pScrn->yDpi, pScrn->displayWidth,
-					   pScrn->bitsPerPixel);
+					   pScrn->bitsPerPixel, SetupWrap, FinishWrap);
 			init_picture = 1;
 			break;
 	 	default:
@@ -919,7 +959,7 @@
 	}
 
 	/* must be after RGB ordering fixed */
-	if (init_picture && !fbPictureInit(pScreen, NULL, 0))
+	if (init_picture && !wfbPictureInit(pScreen, NULL, 0))
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "Render extension initialisation failed\n");
 




On Fri, 2009-03-13 at 21:49 +0100, Maarten Maathuis wrote:
> You could hack wrapped fb support into the fbdev driver, but that will
> only work for software rendering in X. And you'll loose some
> performance because every pixel access goes through a wrapper
> 
> The vermillion driver has a simple wfb implementation
> http://cgit.freedesktop.org/xorg/driver/xf86-video-vermilion/tree/src/vermilion.c
> 
> Maarten.




More information about the xorg mailing list