How to shift color bits in fbdev?

Gregoire Gentil gregoire at gentil.com
Sun Mar 15 11:08:10 PDT 2009


Maarten,

Thanks again for your answer. I'm close as I have some parts of the
screen with the right colors but not all! More precisely:

- the background is still with a darken opacity
- the problem around the transparent icons have disappeared
- the png background of the bottom panel has the exact perfect colors
(no opacity problem) and it's a complex png shading background.
- The icons in the start menu have 95% of the right colors.

My best patch is below. I have a few questions and comments on your five
points.

1. It's the objective and I think that I should do it only when I write
to the framebuffer. It's what I'm explaining in my comment of your point
3 below.

2. I understand your point but it's the same, if I do it only when I'm
writing to the framebuffer, I should be safe. Shouldn't I?

3. I wrote this program:
int main(int argc, char** argv) {
        unsigned int color =  0xFF;
        while (1) {
                write(1, &color, 4);
        }
}
./a.out > /dev/fb0 and it gives whole blue. 0x00FF gives whole green.
0x0000FF gives whole red. 0x000000FF gives whole black.

4. I think that it's the key point of my problem. I have tried to do
something similar to the vermilion source code:

if ((pPixmap->devPrivate.ptr >= fPtr->fbmem) &&
((char*)pPixmap->devPrivate.ptr < ((char*)fPtr->fbmem + fPtr->lineLength
* 600 * 8)))

My screen is 1024x600 and defaultdepthcolor =
24. fPtr->lineLength=4096. Hence, fPtr->lineLength * 600 * 8 = 1024 *
600 * 32. I'm not sure if this number makes sense or how I can get the
true fbmem size. If I put 1024 * 600 * 8, I never reach the true case.

I don't understand your comment about the list but that sounds a good
idea to me. What should I put in the list and what should I compare to?

5. I don't understand this comment. Can you explain please?

Grégoire


--- fbdev.c.orig	2009-03-13 19:02:29.000000000 -0700
+++ fbdev.c	2009-03-15 10:48:08.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,59 @@
     return TRUE;
 }
 
+/*Modif Gregoire*/
+static FbBits
+ReadMemory(const void *src, int size)
+{
+    FbBits bits = 0;
+
+    memcpy(&bits, src, size);
+
+    return bits;
+}
+
+static void
+WriteMemoryPassthru(void *dst, FbBits value, int size)
+{
+    memcpy(dst, &value, size);
+}
+
+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);
+}
+
+int ind = 0;
+static void
+SetupWrap(ReadMemoryProcPtr *pRead, WriteMemoryProcPtr *pWrite,
+			DrawablePtr pDraw)
+{
+    ScreenPtr pScreen = pDraw->pScreen;
+    ScrnInfoPtr pScrn = xf86Screens[pDraw->pScreen->myNum];
+    FBDevGetRec(pScrn);
+    FBDevPtr fPtr = FBDEVPTR(pScrn);
+
+    PixmapPtr pPixmap;
+    if (pDraw->type == DRAWABLE_WINDOW)
+	pPixmap = pScreen->GetWindowPixmap((WindowPtr)pDraw);
+    else
+	pPixmap = (PixmapPtr)pDraw;
+
+    if ((pPixmap->devPrivate.ptr >= fPtr->fbmem) &&
+	((char*)pPixmap->devPrivate.ptr < ((char*)fPtr->fbmem +
fPtr->lineLength * 600 * 8))) {
+	*pWrite = WriteMemoryShiftBit;
+    } else {
+	*pWrite = WriteMemoryPassthru;
+    }
+
+    *pRead = ReadMemory;
+}
+
+static void
+FinishWrap(DrawablePtr pDraw) 
+{
+}
 
 static Bool
 FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char
**argv)
@@ -854,11 +913,12 @@
 		case 16:
 		case 24:
 		case 32:
-			ret = fbScreenInit(pScreen, fPtr->shadowFB ? fPtr->shadow
+			xf86DrvMsg(scrnIndex, X_ERROR, "Debug version 30\n");
+			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 +979,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 Sun, 2009-03-15 at 01:05 +0100, Maarten Maathuis wrote:
> Several things i see.
> 
> 1: you are throwing away bits in the colors
> 2: you should undo the mangling in the read function (the system
> doesn't understand your strange layout)
> 3: the alpha channel is in the upper 8 bits on little endian systems
> (typically) for A8R8G8B
> 4: read/write are used by more pixmaps than just the ones going to
> your videocard, you need to check if devPrivate.ptr lies in your
> fontbuffer range or you need to make a list (6 entries will be more
> than enough) in wrap and check in read/write to be sure (this is
> because pixman (sw rendering library) is shared between the xserver
> and cairo)
> 5: you only support A/XRGB pixmaps (no 8 or 16 bits formats)?
> 
> Maarten.




More information about the xorg mailing list