420 lines
10 KiB
Diff
420 lines
10 KiB
Diff
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 {
|