kdrive-1.3-18bpp.patch: add, but not activate a patch to have 18bpp support in kdrive 1.3
authorKoen Kooi <koen@openembedded.org>
Sat, 15 Sep 2007 14:57:12 +0000 (14:57 +0000)
committerKoen Kooi <koen@openembedded.org>
Sat, 15 Sep 2007 14:57:12 +0000 (14:57 +0000)
* people with 18bpp hardware (motorola a1200, motorola rokre6, gumstix lcd) should test this and activate it if it works

packages/xorg-xserver/xserver-kdrive-1.3.0.0/kdrive-1.3-18bpp.patch [new file with mode: 0644]

diff --git a/packages/xorg-xserver/xserver-kdrive-1.3.0.0/kdrive-1.3-18bpp.patch b/packages/xorg-xserver/xserver-kdrive-1.3.0.0/kdrive-1.3-18bpp.patch
new file mode 100644 (file)
index 0000000..7145369
--- /dev/null
@@ -0,0 +1,419 @@
+diff -Nurd xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.c xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.c
+--- xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.c        2006-11-16 19:01:23.000000000 +0100
++++ xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.c        2007-09-15 16:53:20.152045000 +0200
+@@ -213,6 +213,24 @@
+     /* Now get the new screeninfo */
+     ioctl (priv->fd, FBIOGET_VSCREENINFO, &priv->var);
++    /* Special treatment of 18bpp */
++    if ((priv->var.red.length == 6) && (priv->var.green.length == 6) && 
++      (priv->var.blue.length == 6))
++    {
++      priv->var.red.length = 8;
++      if (priv->var.red.offset != 0)
++        priv->var.red.offset = 16;
++      priv->var.green.length = 8;
++      priv->var.green.offset = 8;
++      priv->var.blue.length = 8;
++      if (priv->var.blue.offset != 0)
++        priv->var.blue.offset = 16;
++      priv->var.bits_per_pixel = 32;
++      priv->Have18Bpp = TRUE;
++    }
++    else
++      priv->Have18Bpp = FALSE;
++
+     depth = priv->var.bits_per_pixel;
+     gray = priv->var.grayscale;
+     
+@@ -334,7 +352,7 @@
+     KdMouseMatrix     m;
+     FbdevPriv         *priv = screen->card->driver;
+-    if (scrpriv->randr != RR_Rotate_0)
++    if (scrpriv->randr != RR_Rotate_0 || priv->Have18Bpp)
+       scrpriv->shadow = TRUE;
+     else
+       scrpriv->shadow = FALSE;
+@@ -398,6 +416,354 @@
+     return TRUE;
+ }
++void
++shadowUpdatePacked18 (ScreenPtr           pScreen,
++                       shadowBufPtr    pBuf)
++{
++    RegionPtr damage = shadowDamage (pBuf);
++    PixmapPtr pShadow = pBuf->pPixmap;
++    int               nbox = REGION_NUM_RECTS (damage);
++    BoxPtr    pbox = REGION_RECTS (damage);
++    FbBits    *shaBase, *shaLine, *sha;
++    FbStride  shaStride;
++    int               scrBase, scrLine, scr;
++    int               shaBpp;
++    int               shaXoff, shaYoff; /* XXX assumed to be zero */
++    int               x, y, w, h, width;
++    int         i;
++    char      *winBase = NULL, *win;
++    CARD32      winSize;
++
++    fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
++    while (nbox--)
++    {
++      x = pbox->x1 * shaBpp;
++      y = pbox->y1;
++      w = (pbox->x2 - pbox->x1) * shaBpp;
++      h = pbox->y2 - pbox->y1;
++
++      scrLine = (x >> FB_SHIFT);
++      shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
++                                 
++      x &= FB_MASK;
++      w = (w + x + FB_MASK) >> FB_SHIFT;
++      
++      while (h--)
++      {
++          winSize = 0;
++          scrBase = 0;
++          width = w;
++          scr = scrLine;
++          sha = shaLine;
++          while (width) {
++              /* how much remains in this window */
++              i = scrBase + winSize - scr;
++              if (i <= 0 || scr < scrBase)
++              {
++                  winBase = (char *) (*pBuf->window) (pScreen,
++                                                        y,
++                                                        scr * 3,
++                                                        SHADOW_WINDOW_WRITE,
++                                                        &winSize,
++                                                        pBuf->closure);
++                  if(!winBase)
++                      return;
++                  scrBase = scr;
++                  winSize /= 3;
++                  i = winSize;
++              }
++              win = winBase + (scr - scrBase);
++              if (i > width)
++                  i = width;
++              width -= i;
++              scr += i;
++#define PickBit(a,i)  (((a) >> (i)) & 1)
++              while (i--)
++                {
++                  FbBits bits = *sha++;
++                  *win++ = ((bits & 0xFC) >> 2) | 
++                ((bits & 0xC00) >> 4);
++                  *win++ = ((bits & 0xF000) >> 12) | 
++                    ((bits & 0x3C0000) >> 14);
++                  *win++ = (bits & 0xC00000) >> 22;
++                }
++          }
++          shaLine += shaStride;
++          y++;
++      }
++      pbox++;
++    }
++}
++
++#define LEFT_TO_RIGHT 1
++#define RIGHT_TO_LEFT -1
++#define TOP_TO_BOTTOM 2
++#define BOTTOM_TO_TOP -2
++
++void
++shadowUpdateRotatePacked18 (ScreenPtr pScreen,
++                             shadowBufPtr     pBuf)
++{
++    RegionPtr damage = shadowDamage (pBuf);
++    PixmapPtr pShadow = pBuf->pPixmap;
++    int               nbox = REGION_NUM_RECTS (damage);
++    BoxPtr    pbox = REGION_RECTS (damage);
++    FbBits    *shaBits;
++    FbStride  shaStride;
++    int               shaBpp;
++    int               shaXoff, shaYoff;
++    int               box_x1, box_x2, box_y1, box_y2;
++    int               sha_x1 = 0, sha_y1 = 0;
++    int               scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h;
++    int               scr_x, scr_y;
++    int               w;
++    int               pixelsPerBits;
++    int               pixelsMask;
++    FbStride  shaStepOverY = 0, shaStepDownY = 0;
++    FbStride  shaStepOverX = 0, shaStepDownX = 0;
++    FbBits    *shaLine, *sha;
++    int               shaHeight = pShadow->drawable.height;
++    int               shaWidth = pShadow->drawable.width;
++    FbBits    shaMask;
++    int               shaFirstShift, shaShift;
++    int               o_x_dir;
++    int               o_y_dir;
++    int               x_dir;
++    int               y_dir;
++
++    fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
++    pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp;
++    pixelsMask = ~(pixelsPerBits - 1);
++    shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp);
++    /*
++     * Compute rotation related constants to walk the shadow
++     */
++    o_x_dir = LEFT_TO_RIGHT;
++    o_y_dir = TOP_TO_BOTTOM;
++    if (pBuf->randr & SHADOW_REFLECT_X)
++      o_x_dir = -o_x_dir;
++    if (pBuf->randr & SHADOW_REFLECT_Y)
++      o_y_dir = -o_y_dir;
++    switch (pBuf->randr & (SHADOW_ROTATE_ALL)) {
++    case SHADOW_ROTATE_0:     /* upper left shadow -> upper left screen */
++    default:
++      x_dir = o_x_dir;
++      y_dir = o_y_dir;
++      break;
++    case SHADOW_ROTATE_90:            /* upper right shadow -> upper left screen */
++      x_dir = o_y_dir;
++      y_dir = -o_x_dir;
++      break;
++    case SHADOW_ROTATE_180:   /* lower right shadow -> upper left screen */
++      x_dir = -o_x_dir;
++      y_dir = -o_y_dir;
++      break;
++    case SHADOW_ROTATE_270:   /* lower left shadow -> upper left screen */
++      x_dir = -o_y_dir;
++      y_dir = o_x_dir;
++      break;
++    }
++    switch (x_dir) {
++    case LEFT_TO_RIGHT:
++      shaStepOverX = shaBpp;
++      shaStepOverY = 0;
++      break;
++    case TOP_TO_BOTTOM:
++      shaStepOverX = 0;
++      shaStepOverY = shaStride;
++      break;
++    case RIGHT_TO_LEFT:
++      shaStepOverX = -shaBpp;
++      shaStepOverY = 0;
++      break;
++    case BOTTOM_TO_TOP:
++      shaStepOverX = 0;
++      shaStepOverY = -shaStride;
++      break;
++    }
++    switch (y_dir) {
++    case TOP_TO_BOTTOM:
++      shaStepDownX = 0;
++      shaStepDownY = shaStride;
++      break;
++    case RIGHT_TO_LEFT:
++      shaStepDownX = -shaBpp;
++      shaStepDownY = 0;
++      break;
++    case BOTTOM_TO_TOP:
++      shaStepDownX = 0;
++      shaStepDownY = -shaStride;
++      break;
++    case LEFT_TO_RIGHT:
++      shaStepDownX = shaBpp;
++      shaStepDownY = 0;
++      break;
++    }
++    
++    while (nbox--)
++    {
++        box_x1 = pbox->x1;
++        box_y1 = pbox->y1;
++        box_x2 = pbox->x2;
++        box_y2 = pbox->y2;
++        pbox++;
++
++      /*
++       * Compute screen and shadow locations for this box
++       */
++      switch (x_dir) {
++      case LEFT_TO_RIGHT:
++          scr_x1 = box_x1 & pixelsMask;
++          scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
++          
++          sha_x1 = scr_x1;
++          break;
++      case TOP_TO_BOTTOM:
++          scr_x1 = box_y1 & pixelsMask;
++          scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
++
++          sha_y1 = scr_x1;
++          break;
++      case RIGHT_TO_LEFT:
++          scr_x1 = (shaWidth - box_x2) & pixelsMask;
++          scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
++
++          sha_x1 = (shaWidth - scr_x1 - 1);
++          break;
++      case BOTTOM_TO_TOP:
++          scr_x1 = (shaHeight - box_y2) & pixelsMask;
++          scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
++          
++          sha_y1 = (shaHeight - scr_x1 - 1);
++          break;
++      }
++      switch (y_dir) {
++      case TOP_TO_BOTTOM:
++          scr_y1 = box_y1;
++          scr_y2 = box_y2;
++
++          sha_y1 = scr_y1;
++          break;
++      case RIGHT_TO_LEFT:
++          scr_y1 = (shaWidth - box_x2);
++          scr_y2 = (shaWidth - box_x1);
++
++          sha_x1 = box_x2 - 1;
++          break;
++      case BOTTOM_TO_TOP:
++          scr_y1 = shaHeight - box_y2;
++          scr_y2 = shaHeight - box_y1;
++          
++          sha_y1 = box_y2 - 1;
++          break;
++      case LEFT_TO_RIGHT:
++          scr_y1 = box_x1;
++          scr_y2 = box_x2;
++
++          sha_x1 = box_x1;
++          break;
++      }
++      scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
++      scr_h = scr_y2 - scr_y1;
++      scr_y = scr_y1;
++
++      /* shift amount for first pixel on screen */ 
++      shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
++      
++      /* pointer to shadow data first placed on screen */
++      shaLine = (shaBits + 
++                 sha_y1 * shaStride + 
++                 ((sha_x1 * shaBpp) >> FB_SHIFT));
++
++      /*
++       * Copy the bits, always write across the physical frame buffer
++       * to take advantage of write combining.
++       */
++      while (scr_h--)
++      {
++          int     p;
++          FbBits  bits;
++          char  *win;
++          int     i;
++          CARD32  winSize;
++          
++          sha = shaLine;
++          shaShift = shaFirstShift;
++          w = scr_w;
++          scr_x = scr_x1 * shaBpp >> FB_SHIFT;
++
++          while (w)
++          {
++              /*
++               * Map some of this line
++               */
++              win = (char *) (*pBuf->window) (pScreen,
++                                              scr_y,
++                                              scr_x * 3,
++                                              SHADOW_WINDOW_WRITE,
++                                              &winSize,
++                                              pBuf->closure);
++              i = winSize / 3;
++              if (i > w)
++                  i = w;
++              w -= i;
++              scr_x += i;
++              /*
++               * Copy the portion of the line mapped
++               */
++              while (i--)
++              {
++                  bits = 0;
++                  p = pixelsPerBits;
++                  /*
++                   * Build one word of output from multiple inputs
++                   * 
++                   * Note that for 90/270 rotations, this will walk
++                   * down the shadow hitting each scanline once.
++                   * This is probably not very efficient.
++                   */
++                  while (p--)
++                  {
++                      bits = FbScrLeft(bits, shaBpp);
++                      bits |= FbScrRight (*sha, shaShift) & shaMask;
++
++                      shaShift -= shaStepOverX;
++                      if (shaShift >= FB_UNIT)
++                      {
++                          shaShift -= FB_UNIT;
++                          sha--;
++                      }
++                      else if (shaShift < 0)
++                      {
++                          shaShift += FB_UNIT;
++                          sha++;
++                      }
++                      sha += shaStepOverY;
++                  }
++                  *win++ = ((bits & 0xFC) >> 2) | 
++                ((bits & 0xC00) >> 4);
++                  *win++ = ((bits & 0xF000) >> 12) | 
++                    ((bits & 0x3C0000) >> 14);
++                  *win++ = (bits & 0xC00000) >> 22;
++              }
++          }
++          scr_y++;
++          shaFirstShift -= shaStepDownX;
++          if (shaFirstShift >= FB_UNIT)
++          {
++              shaFirstShift -= FB_UNIT;
++              shaLine--;
++          }
++          else if (shaFirstShift < 0)
++          {
++              shaFirstShift += FB_UNIT;
++              shaLine++;
++          }
++          shaLine += shaStepDownY;
++      }
++    }
++}
++
+ Bool
+ fbdevSetShadow (ScreenPtr pScreen)
+ {
+@@ -418,7 +784,14 @@
+     window = fbdevWindowLinear;
+     update = 0;
+-    if (scrpriv->randr)
++      if (priv->Have18Bpp)
++        {
++        if (scrpriv->randr != RR_Rotate_0)
++          update = shadowUpdateRotatePacked18;
++        else
++          update = shadowUpdatePacked18;
++        }
++      else if (scrpriv->randr)
+       if (priv->var.bits_per_pixel == 16) {
+           switch (scrpriv->randr) {
+           case RR_Rotate_90:
+diff -Nurd xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.h xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.h
+--- xorg-server-1.3.0.0/hw/kdrive/fbdev/fbdev.h        2006-09-18 08:04:17.000000000 +0200
++++ xorg-server-1.3.0.0.patched/hw/kdrive/fbdev/fbdev.h        2007-09-15 16:45:07.362045000 +0200
+@@ -44,6 +44,7 @@
+     int                               fd;
+     char                      *fb;
+     char                      *fb_base;
++    Bool                      Have18Bpp;
+ } FbdevPriv;
+     
+ typedef struct _fbdevScrPriv {