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