[PATCH 3/4] fb: Add support for 8-bpp pixmaps

Keith Packard keithp at keithp.com
Mon Jan 13 18:00:38 PST 2014


This allows the driver to ask for depth-1 pixmaps to be stored with 8
bits per pixel, keeping all 8 bits of each pixel either 0 or 0xff.

Images in Z-format remain 1bpp.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 fb/fb.h        | 107 +++++++++++++++++++++++++++++++++++++-----------------
 fb/fbbltone.c  | 111 ++++++++++++++++++++++++++++++---------------------------
 fb/fbcopy.c    |   3 +-
 fb/fbfill.c    |   2 +-
 fb/fbgc.c      |  10 ++++--
 fb/fbglyph.c   |   2 +-
 fb/fbimage.c   |  33 +++++++++++++----
 fb/fbpixmap.c  |   8 ++++-
 fb/fbpush.c    |  12 ++++---
 fb/fbscreen.c  |   9 +++++
 fb/fbstipple.c |  10 ++++--
 fb/wfbrename.h |   1 +
 12 files changed, 204 insertions(+), 104 deletions(-)

diff --git a/fb/fb.h b/fb/fb.h
index f5eb1e1..540538b 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -582,6 +582,9 @@ typedef void (*FinishWrapProcPtr) (DrawablePtr pDraw);
 
 #ifdef FB_ACCESS_WRAPPER
 
+extern _X_EXPORT ReadMemoryProcPtr wfbReadMemory;
+extern _X_EXPORT WriteMemoryProcPtr wfbWriteMemory;
+
 #define fbPrepareAccess(pDraw) \
 	fbGetScreenPrivate((pDraw)->pScreen)->setupWrap( \
 		&wfbReadMemory, \
@@ -597,6 +600,46 @@ typedef void (*FinishWrapProcPtr) (DrawablePtr pDraw);
 
 #endif
 
+/*
+ * Given a depth 1, 8bpp stipple, pull out
+ * a full FbStip worth of packed bits
+ */
+static inline FbStip
+fb_pack_stip_8_1(FbStip *bits) {
+    FbStip      r = 0;
+    int         i;
+
+    for (i = 0; i < 8; i++) {
+        FbStip  b;
+        uint8_t p;
+
+        b = FB_READ(bits++);
+#if BITMAP_BIT_ORDER == LSBFirst
+        p = (b & 1) | ((b >> 7) & 2) | ((b >> 14) & 4) | ((b >> 21) & 8);
+        r |= p << (i << 2);
+#else
+        p = (b & 0x80000000) | ((b << 7) & 0x40000000) |
+            ((b << 14) & 0x20000000) | ((b << 21) & 0x10000000);
+        r |= p >> (i << 2);
+#endif
+    }
+    return r;
+}
+
+/*
+ * Return packed stipple bits from src
+ */
+static inline FbStip
+fb_stip_read(FbStip *bits, int bpp)
+{
+    switch (bpp) {
+    default:
+        return FB_READ(bits);
+    case 8:
+        return fb_pack_stip_8_1(bits);
+    }
+}
+
 extern _X_EXPORT DevPrivateKey
 fbGetScreenPrivateKey(void);
 
@@ -604,6 +647,7 @@ fbGetScreenPrivateKey(void);
 typedef struct {
     unsigned char win32bpp;     /* window bpp for 32-bpp images */
     unsigned char pix32bpp;     /* pixmap bpp for 32-bpp images */
+    unsigned char bitmap8bpp;   /* bitmaps are 8bpp */
 #ifdef FB_ACCESS_WRAPPER
     SetupWrapProcPtr setupWrap; /* driver hook to set pixmap access wrapping */
     FinishWrapProcPtr finishWrap;       /* driver hook to clean up pixmap access wrapping */
@@ -1009,18 +1053,18 @@ fbBlt24(FbBits * srcLine,
         int height, int alu, FbBits pm, Bool reverse, Bool upsidedown);
 
 extern _X_EXPORT void
- fbBltStip(FbStip * src, FbStride srcStride,    /* in FbStip units, not FbBits units */
-           int srcX, FbStip * dst, FbStride dstStride,  /* in FbStip units, not FbBits units */
-           int dstX, int width, int height, int alu, FbBits pm, int bpp);
+fbBltStip(FbStip * src, FbStride srcStride,    /* in FbStip units, not FbBits units */
+          int srcX, FbStip * dst, FbStride dstStride,  /* in FbStip units, not FbBits units */
+          int dstX, int width, int height, int alu, FbBits pm, int bpp);
 
 /*
  * fbbltone.c
  */
 extern _X_EXPORT void
-
 fbBltOne(FbStip * src,
          FbStride srcStride,
          int srcX,
+         int srcBpp,
          FbBits * dst,
          FbStride dstStride,
          int dstX,
@@ -1029,18 +1073,18 @@ fbBltOne(FbStip * src,
          int height, FbBits fgand, FbBits fbxor, FbBits bgand, FbBits bgxor);
 
 extern _X_EXPORT void
- fbBltOne24(FbStip * src, FbStride srcStride,   /* FbStip units per scanline */
-            int srcX,           /* bit position of source */
-            FbBits * dst, FbStride dstStride,   /* FbBits units per scanline */
-            int dstX,           /* bit position of dest */
-            int dstBpp,         /* bits per destination unit */
-            int width,          /* width in bits of destination */
-            int height,         /* height in scanlines */
-            FbBits fgand,       /* rrop values */
-            FbBits fgxor, FbBits bgand, FbBits bgxor);
+fbBltOne24(FbStip * src, FbStride srcStride,   /* FbStip units per scanline */
+           int srcX,           /* bit position of source */
+           int srcBpp,         /* bits per pixel for source */
+           FbBits * dst, FbStride dstStride,   /* FbBits units per scanline */
+           int dstX,           /* bit position of dest */
+           int dstBpp,         /* bits per destination unit */
+           int width,          /* width in bits of destination */
+           int height,         /* height in scanlines */
+           FbBits fgand,       /* rrop values */
+           FbBits fgxor, FbBits bgand, FbBits bgxor);
 
 extern _X_EXPORT void
-
 fbBltPlane(FbBits * src,
            FbStride srcStride,
            int srcX,
@@ -1366,14 +1410,16 @@ extern _X_EXPORT void
 fbPushFill(DrawablePtr pDrawable,
            GCPtr pGC,
            FbStip * src,
-           FbStride srcStride, int srcX, int x, int y, int width, int height);
+           FbStride srcStride, int srcX, int srcBpp,
+           int x, int y, int width, int height);
 
 extern _X_EXPORT void
 
 fbPushImage(DrawablePtr pDrawable,
             GCPtr pGC,
             FbStip * src,
-            FbStride srcStride, int srcX, int x, int y, int width, int height);
+            FbStride srcStride, int srcX, int srcBpp,
+            int x, int y, int width, int height);
 
 extern _X_EXPORT void
 
@@ -1386,35 +1432,34 @@ fbPushPixels(GCPtr pGC,
  */
 
 extern _X_EXPORT Bool
- fbCloseScreen(ScreenPtr pScreen);
+fbCloseScreen(ScreenPtr pScreen);
 
 extern _X_EXPORT Bool
- fbRealizeFont(ScreenPtr pScreen, FontPtr pFont);
+fbRealizeFont(ScreenPtr pScreen, FontPtr pFont);
 
 extern _X_EXPORT Bool
- fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
+fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
 
 extern _X_EXPORT void
-
 fbQueryBestSize(int class,
                 unsigned short *width, unsigned short *height,
                 ScreenPtr pScreen);
 
 extern _X_EXPORT PixmapPtr
- _fbGetWindowPixmap(WindowPtr pWindow);
+_fbGetWindowPixmap(WindowPtr pWindow);
 
 extern _X_EXPORT void
- _fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap);
+_fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap);
 
 extern _X_EXPORT Bool
- fbSetupScreen(ScreenPtr pScreen, void *pbits,        /* pointer to screen bitmap */
+fbSetupScreen(ScreenPtr pScreen, void *pbits,        /* pointer to screen bitmap */
                int xsize,       /* in pixels */
                int ysize, int dpix,     /* dots per inch */
                int dpiy, int width,     /* pixel width of frame buffer */
                int bpp);        /* bits per pixel of frame buffer */
 
-extern _X_EXPORT Bool
 
+extern _X_EXPORT Bool
 wfbFinishScreenInit(ScreenPtr pScreen,
                     void *pbits,
                     int xsize,
@@ -1426,7 +1471,6 @@ wfbFinishScreenInit(ScreenPtr pScreen,
                     SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap);
 
 extern _X_EXPORT Bool
-
 wfbScreenInit(ScreenPtr pScreen,
               void *pbits,
               int xsize,
@@ -1438,18 +1482,19 @@ wfbScreenInit(ScreenPtr pScreen,
               SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap);
 
 extern _X_EXPORT Bool
-
 fbFinishScreenInit(ScreenPtr pScreen,
                    void *pbits,
                    int xsize,
                    int ysize, int dpix, int dpiy, int width, int bpp);
 
 extern _X_EXPORT Bool
-
 fbScreenInit(ScreenPtr pScreen,
              void *pbits,
              int xsize, int ysize, int dpix, int dpiy, int width, int bpp);
 
+extern _X_EXPORT void
+fbSetBitmap8bpp(ScreenPtr screen, int bitmap8bpp);
+
 /*
  * fbseg.c
  */
@@ -1521,6 +1566,7 @@ fbEvenStipple(FbBits * dst,
               int height,
               FbStip * stip,
               FbStride stipStride,
+              int stipBpp,
               int stipHeight,
               FbBits fgand,
               FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot);
@@ -1535,6 +1581,7 @@ fbOddStipple(FbBits * dst,
              int height,
              FbStip * stip,
              FbStride stipStride,
+             int stipBpp,
              int stipWidth,
              int stipHeight,
              FbBits fgand,
@@ -1550,6 +1597,7 @@ fbStipple(FbBits * dst,
           int height,
           FbStip * stip,
           FbStride stipStride,
+          int stipBpp,
           int stipWidth,
           int stipHeight,
           Bool even,
@@ -1603,11 +1651,6 @@ extern _X_EXPORT FbBits fbReplicatePixel(Pixel p, int bpp);
 extern _X_EXPORT void
  fbReduceRasterOp(int rop, FbBits fg, FbBits pm, FbBits * andp, FbBits * xorp);
 
-#ifdef FB_ACCESS_WRAPPER
-extern _X_EXPORT ReadMemoryProcPtr wfbReadMemory;
-extern _X_EXPORT WriteMemoryProcPtr wfbWriteMemory;
-#endif
-
 /*
  * fbwindow.c
  */
diff --git a/fb/fbbltone.c b/fb/fbbltone.c
index 4ef87c6..ceabeff 100644
--- a/fb/fbbltone.c
+++ b/fb/fbbltone.c
@@ -52,15 +52,16 @@
  *  rightShift = 8
  */
 
-#define LoadBits {\
-    if (leftShift) { \
-	bitsRight = (src < srcEnd ? FB_READ(src++) : 0); \
-	bits = (FbStipLeft (bitsLeft, leftShift) | \
-		FbStipRight(bitsRight, rightShift)); \
-	bitsLeft = bitsRight; \
-    } else \
-	bits = (src < srcEnd ? FB_READ(src++) : 0); \
-}
+#define LoadBits do {                                                   \
+        if (leftShift) {                                                \
+            bitsRight = (src < srcEnd ? fb_stip_read(src, srcBpp) : 0); \
+            bits = (FbStipLeft (bitsLeft, leftShift) |                  \
+                    FbStipRight(bitsRight, rightShift));                \
+            bitsLeft = bitsRight;                                       \
+        } else                                                          \
+            bits = (src < srcEnd ? fb_stip_read(src, srcBpp) : 0);      \
+        src += srcBpp;                                                  \
+    } while(0)
 
 #define LaneCases1(n,a)	    case n: FbLaneCase(n,a); break
 #define LaneCases2(n,a)	    LaneCases1(n,a); LaneCases1(n+1,a)
@@ -144,6 +145,7 @@ CARD8 *fbLaneTable[33] = {
 void
 fbBltOne(FbStip * src, FbStride srcStride,      /* FbStip units per scanline */
          int srcX,              /* bit position of source */
+         int srcBpp,            /* source bpp */
          FbBits * dst, FbStride dstStride,      /* FbBits units per scanline */
          int dstX,              /* bit position of dest */
          int dstBpp,            /* bits per destination unit */
@@ -173,7 +175,7 @@ fbBltOne(FbStip * src, FbStride srcStride,      /* FbStip units per scanline */
     int startbyte, endbyte;
 
     if (dstBpp == 24) {
-        fbBltOne24(src, srcStride, srcX,
+        fbBltOne24(src, srcStride, srcX, srcBpp,
                    dst, dstStride, dstX, dstBpp,
                    width, height, fgand, fgxor, bgand, bgxor);
         return;
@@ -263,7 +265,7 @@ fbBltOne(FbStip * src, FbStride srcStride,      /* FbStip units per scanline */
             srcinc++;
     }
 
-    srcStride -= srcinc;
+    srcStride -= srcinc * srcBpp;
 
     /*
      * Copy rectangle
@@ -275,8 +277,10 @@ fbBltOne(FbStip * src, FbStride srcStride,      /* FbStip units per scanline */
             n = w;
 
         bitsLeft = 0;
-        if (srcX > dstS)
-            bitsLeft = FB_READ(src++);
+        if (srcX > dstS) {
+            bitsLeft = fb_stip_read(src, srcBpp);
+            src += srcBpp;
+        }
         if (n) {
             /*
              * Load first set of stipple bits
@@ -498,36 +502,38 @@ const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
 
 #endif
 
-#define fbFirstStipBits(len,stip) {\
-    int	__len = (len); \
-    if (len <= remain) { \
-	stip = FbLeftStipBits(bits, len); \
-    } else { \
-	stip = FbLeftStipBits(bits, remain); \
-	bits = (src < srcEnd ? FB_READ(src++) : 0); \
-	__len = (len) - remain; \
-	stip = FbMergePartStip24Bits(stip, FbLeftStipBits(bits, __len), \
-				     remain, __len); \
-	remain = FB_STIP_UNIT; \
-    } \
-    bits = FbStipLeft (bits, __len); \
-    remain -= __len; \
-}
-
-#define fbInitStipBits(offset,len,stip) {\
-    bits = FbStipLeft (FB_READ(src++),offset); \
-    remain = FB_STIP_UNIT - offset; \
-    fbFirstStipBits(len,stip); \
-    stip = FbMergeStip24Bits (0, stip, len); \
-}
-
-#define fbNextStipBits(rot,stip) {\
-    int	    __new = FbStip24New(rot); \
-    FbStip  __right; \
-    fbFirstStipBits(__new, __right); \
-    stip = FbMergeStip24Bits (stip, __right, __new); \
-    rot = FbNext24Rot (rot); \
-}
+#define fbFirstStipBits(len,stip,bpp) do {                              \
+        int	__len = (len);                                          \
+        if (len <= remain) {                                            \
+            stip = FbLeftStipBits(bits, len);                           \
+        } else {                                                        \
+            stip = FbLeftStipBits(bits, remain);                        \
+            bits = (src < srcEnd ? fb_stip_read(src,bpp) : 0);          \
+            src += bpp;                                                 \
+            __len = (len) - remain;                                     \
+            stip = FbMergePartStip24Bits(stip, FbLeftStipBits(bits, __len), \
+                                         remain, __len);                \
+            remain = FB_STIP_UNIT;                                      \
+        }                                                               \
+        bits = FbStipLeft (bits, __len);                                \
+        remain -= __len;                                                \
+    } while(0)
+
+#define fbInitStipBits(offset,len,stip,bpp) do {                \
+        bits = FbStipLeft (fb_stip_read(src, bpp),offset);      \
+        src += bpp;                                             \
+        remain = FB_STIP_UNIT - offset;                         \
+        fbFirstStipBits(len,stip,bpp);                          \
+        stip = FbMergeStip24Bits (0, stip, len);                \
+    } while(0)
+
+#define fbNextStipBits(rot,stip,bpp) do {                       \
+        int	    __new = FbStip24New(rot);                   \
+        FbStip  __right;                                        \
+        fbFirstStipBits(__new, __right,bpp);                    \
+        stip = FbMergeStip24Bits (stip, __right, __new);        \
+        rot = FbNext24Rot (rot);                                \
+    } while(0)
 
 /*
  * Use deep mask tables that incorporate rotation, pull
@@ -541,6 +547,7 @@ const FbBits fbStipple24Bits[3][1 << FbStip24Len] = {
 void
 fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scanline */
            int srcX,            /* bit position of source */
+           int srcBpp,          /* bits per pixel for source */
            FbBits * dst, FbStride dstStride,    /* FbBits units per scanline */
            int dstX,            /* bit position of dest */
            int dstBpp,          /* bits per destination unit */
@@ -586,7 +593,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
             rot = rot0;
             src = srcLine;
             srcLine += srcStride;
-            fbInitStipBits(srcX, firstlen, stip);
+            fbInitStipBits(srcX, firstlen, stip, srcBpp);
             if (leftMask) {
                 mask = fbStipple24Bits[rot >> 3][stip];
                 FB_WRITE(dst, (FB_READ(dst) & ~leftMask) |
@@ -594,7 +601,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
                                        FbRot24(fgxor, rot), FbRot24(bgxor, rot))
                        & leftMask));
                 dst++;
-                fbNextStipBits(rot, stip);
+                fbNextStipBits(rot, stip, srcBpp);
             }
             nl = nlMiddle;
             while (nl--) {
@@ -603,7 +610,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
                                            FbRot24(fgxor, rot),
                                            FbRot24(bgxor, rot)));
                 dst++;
-                fbNextStipBits(rot, stip);
+                fbNextStipBits(rot, stip, srcBpp);
             }
             if (rightMask) {
                 mask = fbStipple24Bits[rot >> 3][stip];
@@ -622,7 +629,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
             rot = rot0;
             src = srcLine;
             srcLine += srcStride;
-            fbInitStipBits(srcX, firstlen, stip);
+            fbInitStipBits(srcX, firstlen, stip, srcBpp);
             if (leftMask) {
                 if (stip) {
                     mask = fbStipple24Bits[rot >> 3][stip] & leftMask;
@@ -630,7 +637,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
                           (FB_READ(dst) & ~mask) | (FbRot24(fgxor, rot) & mask));
                 }
                 dst++;
-                fbNextStipBits(rot, stip);
+                fbNextStipBits(rot, stip, srcBpp);
             }
             nl = nlMiddle;
             while (nl--) {
@@ -640,7 +647,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
                           (FB_READ(dst) & ~mask) | (FbRot24(fgxor, rot) & mask));
                 }
                 dst++;
-                fbNextStipBits(rot, stip);
+                fbNextStipBits(rot, stip, srcBpp);
             }
             if (rightMask) {
                 if (stip) {
@@ -657,7 +664,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
             rot = rot0;
             src = srcLine;
             srcLine += srcStride;
-            fbInitStipBits(srcX, firstlen, stip);
+            fbInitStipBits(srcX, firstlen, stip, srcBpp);
             if (leftMask) {
                 mask = fbStipple24Bits[rot >> 3][stip];
                 FB_WRITE(dst, FbStippleRRopMask(FB_READ(dst), mask,
@@ -666,7 +673,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
                                              FbRot24(bgand, rot),
                                              FbRot24(bgxor, rot), leftMask));
                 dst++;
-                fbNextStipBits(rot, stip);
+                fbNextStipBits(rot, stip, srcBpp);
             }
             nl = nlMiddle;
             while (nl--) {
@@ -677,7 +684,7 @@ fbBltOne24(FbStip * srcLine, FbStride srcStride,        /* FbStip units per scan
                                          FbRot24(bgand, rot),
                                          FbRot24(bgxor, rot)));
                 dst++;
-                fbNextStipBits(rot, stip);
+                fbNextStipBits(rot, stip, srcBpp);
             }
             if (rightMask) {
                 mask = fbStipple24Bits[rot >> 3][stip];
diff --git a/fb/fbcopy.c b/fb/fbcopy.c
index 541ef71..d4404c7 100644
--- a/fb/fbcopy.c
+++ b/fb/fbcopy.c
@@ -121,7 +121,7 @@ fbCopy1toN(DrawablePtr pSrcDrawable,
         }
         else {
             fbBltOne((FbStip *) (src + (pbox->y1 + dy + srcYoff) * srcStride),
-                     srcStride * (FB_UNIT / FB_STIP_UNIT),
+                     srcStride * (FB_UNIT / FB_STIP_UNIT), srcBpp,
                      (pbox->x1 + dx + srcXoff),
                      dst + (pbox->y1 + dstYoff) * dstStride,
                      dstStride,
@@ -219,6 +219,7 @@ fbCopyNto1(DrawablePtr pSrcDrawable,
             fbBltOne(tmp,
                      tmpStride,
                      0,
+                     1,
                      dst + (pbox->y1 + dstYoff) * dstStride,
                      dstStride,
                      (pbox->x1 + dstXoff) * dstBpp,
diff --git a/fb/fbfill.c b/fb/fbfill.c
index de9d6b3..6eb9dc9 100644
--- a/fb/fbfill.c
+++ b/fb/fbfill.c
@@ -96,7 +96,7 @@ fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height)
                               stipXoff, stipYoff);
             fbStipple(dst + (y + dstYoff) * dstStride, dstStride,
                       (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height,
-                      stip, stipStride, stipWidth, stipHeight,
+                      stip, stipStride, stipBpp, stipWidth, stipHeight,
                       pPriv->evenStipple, fgand, fgxor, bgand, bgxor,
                       pGC->patOrg.x + pDrawable->x + dstXoff,
                       pGC->patOrg.y + pDrawable->y - y);
diff --git a/fb/fbgc.c b/fb/fbgc.c
index 0e3d498..a187537 100644
--- a/fb/fbgc.c
+++ b/fb/fbgc.c
@@ -261,9 +261,16 @@ fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
         int s;
         FbBits depthMask;
 
-        mask = FbFullMask(pDrawable->bitsPerPixel);
         depthMask = FbFullMask(pDrawable->depth);
 
+        if (pDrawable->depth == 1) {
+            s = 1;
+            mask = depthMask;
+        } else {
+            s = pDrawable->bitsPerPixel;
+            mask = FbFullMask(pDrawable->bitsPerPixel);
+        }
+
         pPriv->fg = pGC->fgPixel & mask;
         pPriv->bg = pGC->bgPixel & mask;
 
@@ -272,7 +279,6 @@ fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
         else
             pPriv->pm = pGC->planemask & mask;
 
-        s = pDrawable->bitsPerPixel;
         while (s < FB_UNIT) {
             pPriv->fg |= pPriv->fg << s;
             pPriv->bg |= pPriv->bg << s;
diff --git a/fb/fbglyph.c b/fb/fbglyph.c
index 1520890..408fea0 100644
--- a/fb/fbglyph.c
+++ b/fb/fbglyph.c
@@ -297,7 +297,7 @@ fbPolyGlyphBlt(DrawablePtr pDrawable,
                 fbPushImage(pDrawable,
                             pGC,
                             (FbStip *) pglyph,
-                            gStride, 0, gx, gy, gWidth, gHeight);
+                            gStride, 0, 1, gx, gy, gWidth, gHeight);
             }
         }
         x += pci->metrics.characterWidth;
diff --git a/fb/fbimage.c b/fb/fbimage.c
index 75e38c2..75e5310 100644
--- a/fb/fbimage.c
+++ b/fb/fbimage.c
@@ -38,6 +38,10 @@ fbPutImage(DrawablePtr pDrawable,
     unsigned long i;
     FbStride srcStride;
     FbStip *src = (FbStip *) pImage;
+    int replicate = pDrawable->bitsPerPixel;
+
+    if (pDrawable->depth == 1)
+        replicate = 1;
 
     x += pDrawable->x;
     y += pDrawable->y;
@@ -60,7 +64,7 @@ fbPutImage(DrawablePtr pDrawable,
                              fbGetCompositeClip(pGC),
                              FB_ALLONES,
                              0,
-                             fbReplicatePixel(i, pDrawable->bitsPerPixel),
+                             fbReplicatePixel(i, replicate),
                              pGC->alu,
                              TRUE, x, y, w, h, src, srcStride, leftPad);
                 src += srcStride * h;
@@ -69,12 +73,23 @@ fbPutImage(DrawablePtr pDrawable,
         break;
     case ZPixmap:
         if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
-            srcStride = PixmapBytePad(w, pDrawable->depth);
-            fb24_32PutZImage(pDrawable,
+            if (pDrawable->depth == 1) {
+                srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
+                fbPutXYImage(pDrawable,
                              fbGetCompositeClip(pGC),
+                             FB_ALLONES,
+                             0,
+                             pPriv->pm,
                              pGC->alu,
-                             (FbBits) pGC->planemask,
-                             x, y, w, h, (CARD8 *) pImage, srcStride);
+                             TRUE, x, y, w, h, src, srcStride, leftPad);
+            } else {
+                srcStride = PixmapBytePad(w, pDrawable->depth);
+                fb24_32PutZImage(pDrawable,
+                                 fbGetCompositeClip(pGC),
+                                 pGC->alu,
+                                 (FbBits) pGC->planemask,
+                                 x, y, w, h, (CARD8 *) pImage, srcStride);
+            }
         }
         else {
             srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof(FbStip);
@@ -202,6 +217,7 @@ fbPutXYImage(DrawablePtr pDrawable,
             fbBltOne(src + (y1 - y) * srcStride,
                      srcStride,
                      (x1 - x) + srcX,
+                     BitsPerPixel(1),
                      dst + (y1 + dstYoff) * dstStride,
                      dstStride,
                      (x1 + dstXoff) * dstBpp,
@@ -234,7 +250,9 @@ fbGetImage(DrawablePtr pDrawable,
         return;
 
     if (format == ZPixmap &&
-        pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) {
+        pDrawable->bitsPerPixel == 24 && BitsPerPixel(pDrawable->depth) == 32)
+    {
+
         fb24_32GetImage(pDrawable, x, y, w, h, format, planeMask, d);
         return;
     }
@@ -245,7 +263,8 @@ fbGetImage(DrawablePtr pDrawable,
     y += pDrawable->y;
 
     dst = (FbStip *) d;
-    if (format == ZPixmap || srcBpp == 1) {
+
+    if (srcBpp == BitsPerPixel(pDrawable->depth) && (format == ZPixmap || srcBpp == 1)) {
         FbBits pm;
 
         pm = fbReplicatePixel(planeMask, srcBpp);
diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c
index 9e8ab52..6d3df15 100644
--- a/fb/fbpixmap.c
+++ b/fb/fbpixmap.c
@@ -38,7 +38,11 @@ fbCreatePixmapBpp(ScreenPtr pScreen, int width, int height, int depth, int bpp,
     int adjust;
     int base;
 
-    paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+    if (depth == 1 && bpp != 1) {
+        paddedWidth = ((width + FB_MASK) >> FB_SHIFT) * bpp * sizeof (FbBits);
+    } else {
+        paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+    }
     if (paddedWidth / 4 > 32767 || height > 32767)
         return NullPixmap;
     datasize = height * paddedWidth;
@@ -94,6 +98,8 @@ fbCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
     bpp = BitsPerPixel(depth);
     if (bpp == 32 && depth <= 24)
         bpp = fbGetScreenPrivate(pScreen)->pix32bpp;
+    if (depth == 1 && fbGetScreenPrivate(pScreen)->bitmap8bpp)
+        bpp = 8;
     return fbCreatePixmapBpp(pScreen, width, height, depth, bpp, usage_hint);
 }
 
diff --git a/fb/fbpush.c b/fb/fbpush.c
index 28add03..c669413 100644
--- a/fb/fbpush.c
+++ b/fb/fbpush.c
@@ -88,7 +88,8 @@ void
 fbPushFill(DrawablePtr pDrawable,
            GCPtr pGC,
            FbStip * src,
-           FbStride srcStride, int srcX, int x, int y, int width, int height)
+           FbStride srcStride, int srcX, int srcBpp,
+           int x, int y, int width, int height)
 {
     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
 
@@ -119,6 +120,7 @@ fbPushFill(DrawablePtr pDrawable,
             fbBltOne(src,
                      srcStride,
                      srcX,
+                     srcBpp,
                      dst,
                      dstStride,
                      dstX,
@@ -141,7 +143,8 @@ void
 fbPushImage(DrawablePtr pDrawable,
             GCPtr pGC,
             FbStip * src,
-            FbStride srcStride, int srcX, int x, int y, int width, int height)
+            FbStride srcStride, int srcX, int srcBpp,
+            int x, int y, int width, int height)
 {
     RegionPtr pClip = fbGetCompositeClip(pGC);
     int nbox;
@@ -167,7 +170,8 @@ fbPushImage(DrawablePtr pDrawable,
         fbPushFill(pDrawable,
                    pGC,
                    src + (y1 - y) * srcStride,
-                   srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1);
+                   srcStride, srcX + (x1 - x), srcBpp,
+                   x1, y1, x2 - x1, y2 - y1);
     }
 }
 
@@ -184,5 +188,5 @@ fbPushPixels(GCPtr pGC,
     fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff,
                       stipYoff);
 
-    fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy);
+    fbPushImage(pDrawable, pGC, stip, stipStride, 0, stipBpp, xOrg, yOrg, dx, dy);
 }
diff --git a/fb/fbscreen.c b/fb/fbscreen.c
index b2b9739..c715cd5 100644
--- a/fb/fbscreen.c
+++ b/fb/fbscreen.c
@@ -198,6 +198,9 @@ fbFinishScreenInit(ScreenPtr pScreen,
         fbGetScreenPrivate(pScreen)->win32bpp = 32;
         fbGetScreenPrivate(pScreen)->pix32bpp = 32;
     }
+
+    fbGetScreenPrivate(pScreen)->bitmap8bpp = 0;
+
 #ifdef FB_ACCESS_WRAPPER
     fbGetScreenPrivate(pScreen)->setupWrap = setupWrap;
     fbGetScreenPrivate(pScreen)->finishWrap = finishWrap;
@@ -220,6 +223,12 @@ fbFinishScreenInit(ScreenPtr pScreen,
     return TRUE;
 }
 
+void
+fbSetBitmap8bpp(ScreenPtr screen, int bitmap8bpp)
+{
+    fbGetScreenPrivate(screen)->bitmap8bpp = bitmap8bpp;
+}
+
 /* dts * (inch/dot) * (25.4 mm / inch) = mm */
 #ifdef FB_ACCESS_WRAPPER
 Bool
diff --git a/fb/fbstipple.c b/fb/fbstipple.c
index 41ce5ef..b76f1c6 100644
--- a/fb/fbstipple.c
+++ b/fb/fbstipple.c
@@ -84,6 +84,7 @@ fbEvenStipple(FbBits * dst,
               int height,
               FbStip * stip,
               FbStride stipStride,
+              int stipBpp,
               int stipHeight,
               FbBits fgand,
               FbBits fgxor, FbBits bgand, FbBits bgxor, int xRot, int yRot)
@@ -138,7 +139,7 @@ fbEvenStipple(FbBits * dst,
         /*
          * Extract stipple bits for this scanline;
          */
-        bits = FB_READ(s);
+        bits = fb_stip_read(s, stipBpp);
         s += stipStride;
         if (s == stipEnd)
             s = stip;
@@ -199,6 +200,7 @@ fbOddStipple(FbBits * dst,
              int height,
              FbStip * stip,
              FbStride stipStride,
+             int stipBpp,
              int stipWidth,
              int stipHeight,
              FbBits fgand,
@@ -228,6 +230,7 @@ fbOddStipple(FbBits * dst,
             fbBltOne(stip + stipY * stipStride,
                      stipStride,
                      sx,
+                     stipBpp,
                      dst + y * dstStride,
                      dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
             x += w;
@@ -247,6 +250,7 @@ fbStipple(FbBits * dst,
           int height,
           FbStip * stip,
           FbStride stipStride,
+          int stipBpp,
           int stipWidth,
           int stipHeight,
           Bool even,
@@ -255,10 +259,10 @@ fbStipple(FbBits * dst,
 {
     if (even)
         fbEvenStipple(dst, dstStride, dstX, dstBpp, width, height,
-                      stip, stipStride, stipHeight,
+                      stip, stipStride, stipBpp, stipHeight,
                       fgand, fgxor, bgand, bgxor, xRot, yRot);
     else
         fbOddStipple(dst, dstStride, dstX, dstBpp, width, height,
-                     stip, stipStride, stipWidth, stipHeight,
+                     stip, stipStride, stipBpp, stipWidth, stipHeight,
                      fgand, fgxor, bgand, bgxor, xRot, yRot);
 }
diff --git a/fb/wfbrename.h b/fb/wfbrename.h
index 54d00d0..e0d96bb 100644
--- a/fb/wfbrename.h
+++ b/fb/wfbrename.h
@@ -168,3 +168,4 @@
 #define fbZeroSegment wfbZeroSegment
 #define free_pixman_pict wfb_free_pixman_pict
 #define image_from_pict wfb_image_from_pict
+#define fbSetBitmap8bpp wfbSetBitmap8bpp
-- 
1.8.5.2



More information about the xorg-devel mailing list