summaryrefslogtreecommitdiff
path: root/packages/xorg-xserver/xserver-kdrive
diff options
context:
space:
mode:
authorManuel Teira <manuel.teira@telefonica.net>2007-06-14 19:57:28 +0000
committerManuel Teira <manuel.teira@telefonica.net>2007-06-14 19:57:28 +0000
commitec123df895a70f2f065159e0318cee6afd2a166f (patch)
tree6b0ed4a07e22e4b993d16a8c3b1a810ade9ba8a2 /packages/xorg-xserver/xserver-kdrive
parentd0ef53fabcf86956214e1cbae3f112f6825689bb (diff)
xserver-kdrive-imageon X11R7.1-1.1.0 : XV Port changes, cleanups
* Avoid recalculation of surface boundaries when possible * Cleanups and optimizations in support functions * More rational APIs for blitting functions. * Release bumped up to r2
Diffstat (limited to 'packages/xorg-xserver/xserver-kdrive')
-rw-r--r--packages/xorg-xserver/xserver-kdrive/kdrive-imageon.patch1700
1 files changed, 944 insertions, 756 deletions
diff --git a/packages/xorg-xserver/xserver-kdrive/kdrive-imageon.patch b/packages/xorg-xserver/xserver-kdrive/kdrive-imageon.patch
index f4272f80e0..2f7f5ca020 100644
--- a/packages/xorg-xserver/xserver-kdrive/kdrive-imageon.patch
+++ b/packages/xorg-xserver/xserver-kdrive/kdrive-imageon.patch
@@ -902,7 +902,7 @@
+#endif
--- /dev/null
+++ xorg-server-X11R7.1-1.1.0.work/hw/kdrive/imageon/imageon_cursor.c
-@@ -0,0 +1,566 @@
+@@ -0,0 +1,565 @@
+/*
+ * Copyright © 2007 Manuel Teira
+ *
@@ -934,8 +934,9 @@
+#include "imageon_regs.h"
+
+#define W100_CURSOR_HEIGHT (16)
-+#define W100_CURSOR_PITCH (4)
+#define W100_CURSOR_WIDTH (16)
++#define W100_CURSOR_PITCH (W100_CURSOR_WIDTH / 4)
++
+#define W100_CURSOR_SIZE W100_CURSOR_PITCH * W100_CURSOR_WIDTH
+
+static CARD16 expand2bpp[256];
@@ -968,7 +969,7 @@
+ (((y) * W100_CURSOR_PITCH + ((x) / 4)) >> 2)
+
+#define PixelShift(x, y) \
-+ (2 * ((x) % W100_CURSOR_WIDTH))
++ (2 * ((x) % 16))
+
+#define PixelMask(x, y) \
+ ((0xc0000000) >> PixelShift(x, y))
@@ -1210,7 +1211,7 @@
+ cursor_v_pos_u vpos;
+ graphic_h_disp_u graphic_hdisp;
+ graphic_v_disp_u graphic_vdisp;
-+ int tx, ty, tw, th;
++ BoxRec cursorBox, deviceBox;
+
+
+ if (!pCurPriv->has_cursor) {
@@ -1224,30 +1225,28 @@
+ graphic_vdisp.val = w100c->regs.GRAPHIC_V_DISP;
+ xoffs = 0;
+ yoffs = 0;
-+ x -= pCurPriv->xhot;
-+ y -= pCurPriv->yhot;
-+ tx = W100MapToHWX(w100c, x, y, pCurPriv->width, pCurPriv->height);
-+ ty = W100MapToHWY(w100c, x, y, pCurPriv->width, pCurPriv->height);
-+ tw = W100MapToHWW(w100c, x, y, pCurPriv->width, pCurPriv->height);
-+ th = W100MapToHWH(w100c, x, y, pCurPriv->width, pCurPriv->height);
++ cursorBox.x1 = x - pCurPriv->xhot;
++ cursorBox.y1 = y - pCurPriv->yhot;
++ cursorBox.x2 = cursorBox.x1 + pCurPriv->width - 1;
++ cursorBox.y2 = cursorBox.y1 + pCurPriv->height - 1;
++ W100MapToDevice(w100c, &cursorBox, &deviceBox);
+
-+ if (tx < 0) {
-+ xoffs = -tx;
-+ tw -= xoffs;
-+ tx = 0;
++ if (deviceBox.x1 < 0) {
++ xoffs = -deviceBox.x1;
++ deviceBox.x1 = 0;
+ }
+
-+ if (ty < 0) {
-+ yoffs = -ty;
-+ th -= yoffs;
-+ ty = 0;
++ if (deviceBox.y1 < 0) {
++ yoffs = -deviceBox.y1;
++ deviceBox.y1 = 0;
+ }
-+
-+ hpos.f.cur_h_start = graphic_hdisp.f.graphic_h_start + tx;
-+ hpos.f.cur_h_end = hpos.f.cur_h_start + tw;
++
++ hpos.f.cur_h_start = graphic_hdisp.f.graphic_h_start + deviceBox.x1;
++ hpos.f.cur_h_end = graphic_hdisp.f.graphic_h_start + deviceBox.x2 + 1;
+ hpos.f.cur_en = 1;
-+ vpos.f.cur_v_start = graphic_vdisp.f.graphic_v_start + ty;
-+ vpos.f.cur_v_end = vpos.f.cur_v_start + th;
++ vpos.f.cur_v_start = graphic_vdisp.f.graphic_v_start + deviceBox.y1;
++ vpos.f.cur_v_end = graphic_vdisp.f.graphic_v_start + deviceBox.y2 + 1;
++
+ cursor_offset.f.cur_x_offset = xoffs;
+ cursor_offset.f.cur_y_offset = yoffs;
+ cursor_offset.f.cur_offset = (CARD32)
@@ -1255,7 +1254,7 @@
+ + pCurPriv->area->offset);
+ DBG_IMAGEON(("W100MoveCursor dst(x:%d,y:%d),"
+ "mapped(x:%d,y:%d,xoffs:%d,yoffs:%d)\n",
-+ x, y, tx, ty, xoffs, yoffs));
++ x, y, deviceBox.x1, deviceBox.y1, xoffs, yoffs));
+
+ W100DisableDisplayUpdate(w100c);
+ MMIO_OUT32(mmCURSOR1_OFFSET, cursor_offset.val);
@@ -1471,7 +1470,7 @@
+}
--- /dev/null
+++ xorg-server-X11R7.1-1.1.0.work/hw/kdrive/imageon/imageon_draw.c
-@@ -0,0 +1,237 @@
+@@ -0,0 +1,238 @@
+/*
+ * Copyright © 2007 Manuel Teira
+ *
@@ -1520,6 +1519,7 @@
+ KdScreenPriv(pPix->drawable.pScreen);
+ W100ScreenInfo(pScreenPriv);
+ W100CardInfo(pScreenPriv);
++ W100PortPrivPtr pPortPriv = w100s->pAdaptor->pPortPrivates[0].ptr;
+ int fifoEntries = 4;
+
+ DBG_IMAGEON(("W100PrepareSolid(alu:%d, pm:0x%08x, fg:%d)\n",
@@ -1711,7 +1711,7 @@
+}
--- /dev/null
+++ xorg-server-X11R7.1-1.1.0.work/hw/kdrive/imageon/imageon.h
-@@ -0,0 +1,261 @@
+@@ -0,0 +1,284 @@
+/*
+ * Copyright © 2007 Manuel Teira
+ *
@@ -1822,6 +1822,13 @@
+ Bool supported;
+} W100ModeSpec;
+
++typedef struct _W100BoxRec {
++ CARD16 x;
++ CARD16 y;
++ CARD16 w;
++ CARD16 h;
++} W100BoxRec, *W100BoxPtr;
++
+typedef struct _W100Mode {
+ CARD16 width;
+ CARD16 height;
@@ -1929,23 +1936,39 @@
+ CARD32 videoStatus;
+ CARD32 videoCtrl;
+ RegionRec clip;
-+ KdOffscreenArea *offSurface;
-+ CARD32 offSize;
-+ KdOffscreenArea *ovlSurface;
-+ CARD32 ovlSize;
-+ CARD32 YPlaneOffset;
-+ CARD32 UPlaneOffset;
-+ CARD32 VPlaneOffset;
-+ CARD32 colorKey;
-+ CARD8 brightness;
-+ CARD32 maxOverlaySize;
-+ CARD16 ovlX;
-+ CARD16 ovlY;
-+ CARD16 ovlWidth;
-+ CARD16 ovlHeight;
-+ CARD8 videoHorExp;
-+ CARD8 videoVerExp;
-+ int id;
++ struct {
++ int width; /* Source width */
++ int height; /* Source height */
++ unsigned char *buffer; /* Source buffer */
++ int id; /* Source FOURCC */
++ int size; /* Size of source rect (bytes) */
++ KdOffscreenArea *surface; /* Source surface (on card memory) */
++ BoxRec box; /* Source rect boundaries */
++ } src;
++ struct {
++ BoxRec box; /* Screen rectangle */
++ } dst;
++ struct {
++ int size; /* Size of the overlay surface (bytes) */
++ KdOffscreenArea *surface; /* Overlay surface (on card memory) */
++ BoxRec box; /* Overlay box (util size) */
++ BoxRec frame; /* Overlay box (plus corrections) */
++ Bool changed; /* To avoid recalculations */
++ int horExp; /* Horizontal expansion */
++ int verExp; /* Vertical expansion */
++ int maxSize; /* Maximum allowed surface size (bytes) */
++ int colorKey; /* Colour to replace with overlay */
++ int brightness; /* Brigthness */
++ } ovl;
++ struct {
++ int size; /* Number of planes */
++ int bpp; /* bpp of the planes */
++ int offset[3]; /* Planes offsets */
++ CARD32 yplane; /* Offset (card) of Y plane */
++ CARD32 uplane; /* Offset (card) of U plane */
++ CARD32 vplane; /* Offset (card) of V plane */
++ } planes;
++ Bool changed; /* To track changes and avoid recalculations */
+} W100PortPrivRec, *W100PortPrivPtr;
+
+extern KdCardFuncs W100Funcs;
@@ -6231,7 +6254,7 @@
+}
--- /dev/null
+++ xorg-server-X11R7.1-1.1.0.work/hw/kdrive/imageon/imageon_support.c
-@@ -0,0 +1,1438 @@
+@@ -0,0 +1,1474 @@
+/*
+ * Copyright © 2007 Manuel Teira
+ *
@@ -6856,7 +6879,6 @@
+ } else {
+ w100c->ctx.mask.enable = FALSE;
+ }
-+
+}
+
+Bool W100SetSource(KdScreenInfo *screen,
@@ -6962,184 +6984,140 @@
+ pPix->drawable.bitsPerPixel);
+}
+
-+int W100MapToHWX(W100CardInfo *w100c,
-+ int x, int y, int w, int h)
++void W100MapToDevice(W100CardInfo *w100c, BoxPtr src, BoxPtr dst)
+{
-+ int tx;
+ switch (w100c->hw_window.randr & RR_Rotate_All) {
+ case RR_Rotate_0:
-+ tx = x;
++ dst->x1 = src->x1;
++ dst->y1 = src->y1;
++ dst->x2 = src->x2;
++ dst->y2 = src->y2;
+ break;
+ case RR_Rotate_90:
-+ tx = w100c->hw_window.height - (y + h);
++ dst->x1 = w100c->hw_window.height - src->y2 - 1;
++ dst->y1 = src->x1;
++ dst->x2 = w100c->hw_window.height - src->y1 - 1;
++ dst->y2 = src->x2;
+ break;
+ case RR_Rotate_180:
-+ tx = w100c->hw_window.width - (x + w);
++ dst->x1 = w100c->hw_window.width - src->x2 - 1;
++ dst->y1 = w100c->hw_window.height - src->y2 - 1;
++ dst->x2 = w100c->hw_window.width - src->x1 - 1;
++ dst->y2 = w100c->hw_window.height - src->y1 - 1;
+ break;
+ case RR_Rotate_270:
-+ tx = y;
++ dst->x1 = src->y1;
++ dst->y1 = w100c->hw_window.width - src->x2 - 1;
++ dst->x2 = src->y2;
++ dst->y2 = w100c->hw_window.height - src->x1 - 1;
+ break;
-+ default:
-+ tx = x;
+ }
-+ return tx;
++ DBG_IMAGEON(("MapToDevice (x1:%d,y1:%d,x2:%d,y2:%d)->(x1:%d,y1:%d,x2:%d,y2:%d)\n",
++ src->x1, src->y1, src->x2, src->y2,
++ dst->x1, dst->y1, dst->x2, dst->y2));
+}
+
-+int W100MapToHWY(W100CardInfo *w100c,
-+ int x, int y, int w, int h)
++void W100MapFromDevice(W100CardInfo *w100c, BoxPtr src, BoxPtr dst)
+{
-+ int ty;
+ switch (w100c->hw_window.randr & RR_Rotate_All) {
+ case RR_Rotate_0:
-+ ty = y;
++ dst->x1 = src->x1;
++ dst->y1 = src->y1;
++ dst->x2 = src->x2;
++ dst->y2 = src->y2;
+ break;
+ case RR_Rotate_90:
-+ ty = x;
++ dst->x1 = src->y1;
++ dst->y1 = w100c->hw_window.height - src->x2 - 1;
++ dst->x2 = src->y2;
++ dst->y2 = w100c->hw_window.height - src->x1 - 1;
+ break;
+ case RR_Rotate_180:
-+ ty = w100c->hw_window.height - (y + h);
++ dst->x1 = w100c->hw_window.width - src->x2 - 1;
++ dst->y1 = w100c->hw_window.height - src->y2 - 1;
++ dst->x2 = w100c->hw_window.width - src->x1 - 1;
++ dst->y2 = w100c->hw_window.height - src->y1 - 1;
+ break;
+ case RR_Rotate_270:
-+ ty = w100c->hw_window.width - (x + w);
++ dst->x1 = w100c->hw_window.height - src->y2 - 1;
++ dst->y1 = src->x1;
++ dst->x2 = w100c->hw_window.width - src->y1 - 1;
++ dst->y2 = src->x2;
+ break;
-+ default:
-+ ty = y;
+ }
-+ return ty;
++ DBG_IMAGEON(("MapFromDevice (x1:%d,y1:%d,x2:%d,y2:%d)->(x1:%d,y1:%d,x2:%d,y2:%d)\n",
++ src->x1, src->y1, src->x2, src->y2,
++ dst->x1, dst->y1, dst->x2, dst->y2));
+}
+
-+int W100MapToHWW(W100CardInfo *w100c,
-+ int x, int y, int w, int h)
++void W100MoveTo(BoxPtr src, int x, int y)
+{
-+ int tw;
-+ switch (w100c->hw_window.randr & RR_Rotate_All) {
-+ case RR_Rotate_0:
-+ case RR_Rotate_180:
-+ tw = w;
-+ break;
-+ case RR_Rotate_90:
-+ case RR_Rotate_270:
-+ tw = h;
-+ break;
-+ }
-+ return tw;
++ src->x1 += x;
++ src->y1 += y;
++ src->x2 += x;
++ src->y2 += y;
+}
+
-+int W100MapToHWH(W100CardInfo *w100c,
-+ int x, int y, int w, int h)
++void W100ChangeOrigin(BoxPtr src, int x, int y)
+{
-+ int th;
-+ switch (w100c->hw_window.randr & RR_Rotate_All) {
-+ case RR_Rotate_0:
-+ case RR_Rotate_180:
-+ th = h;
-+ break;
-+ case RR_Rotate_90:
-+ case RR_Rotate_270:
-+ th = w;
-+ break;
++ src->x1 -= x;
++ src->y1 -= y;
++ src->x2 -= x;
++ src->y2 -= y;
++}
++
++void W100ScaleBox(BoxPtr src, BoxPtr dst, int scale)
++{
++ if (scale >= 0) {
++ dst->x1 = src->x1 << scale;
++ dst->x2 = src->x2 << scale;
++ dst->y1 = src->y1 << scale;
++ dst->y2 = src->y2 << scale;
++ } else {
++ dst->x1 = src->x1 >> -scale;
++ dst->x2 = src->x2 >> -scale;
++ dst->y1 = src->y1 >> -scale;
++ dst->y2 = src->y2 >> -scale;
+ }
-+ return th;
+}
+
-+CARD16 W100XformX(W100CardInfo *w100c,
-+ CARD16 x, CARD16 y, CARD16 w, CARD16 h)
++void W100TrajectoryOrigin(W100CardInfo *w100c, BoxPtr box, short *x, short *y)
+{
-+ CARD16 tx;
+ switch (w100c->ctx.xform.randr & RR_Rotate_All) {
+ case RR_Rotate_0:
+ if (w100c->ctx.xform.mirror) {
-+ tx = x + w - 1;
++ *x = box->x2;
+ } else {
-+ tx = x;
++ *x = box->x1;
+ }
++ *y = box->y1;
+ break;
+ case RR_Rotate_90:
-+ tx = x + h - 1;
-+ break;
-+ case RR_Rotate_180:
++ *x = box->x2;
+ if (w100c->ctx.xform.mirror) {
-+ tx = x;
++ *y = box->y2;
+ } else {
-+ tx = x + w - 1;
++ *y = box->y1;
+ }
+ break;
-+ case RR_Rotate_270:
-+ default:
-+ tx = x;
-+ break;
-+ }
-+ return tx;
-+}
-+
-+CARD16 W100XformY(W100CardInfo *w100c,
-+ CARD16 x, CARD16 y, CARD16 w, CARD16 h)
-+{
-+ CARD16 ty;
-+ switch (w100c->ctx.xform.randr & RR_Rotate_All) {
-+ case RR_Rotate_0:
-+ ty = y;
-+ break;
-+ case RR_Rotate_90:
++ case RR_Rotate_180:
+ if (w100c->ctx.xform.mirror) {
-+ ty = y + w - 1;
++ *x = box->x1;
+ } else {
-+ ty = y;
++ *x = box->x2;
+ }
-+ break;
-+ case RR_Rotate_180:
-+ ty = y + h - 1;
++ *y = box->y2;
+ break;
+ case RR_Rotate_270:
-+ default:
++ *x = box->x1;
+ if (w100c->ctx.xform.mirror) {
-+ ty = y;
++ *y = box->y1;
+ } else {
-+ ty = y + w - 1;
++ *y = box->y2;
+ }
-+ break;
+ }
-+ return ty;
+}
-+
-+CARD16 W100XformW(W100CardInfo *w100c,
-+ CARD16 x, CARD16 y, CARD16 w, CARD16 h)
-+{
-+ CARD16 tw;
-+
-+ switch (w100c->ctx.xform.randr & RR_Rotate_All) {
-+ case RR_Rotate_0:
-+ case RR_Rotate_180:
-+ default:
-+ tw = w;
-+ break;
-+ case RR_Rotate_90:
-+ case RR_Rotate_270:
-+ tw = h;
-+ break;
-+ }
-+ return tw;
-+}
-+
-+CARD16 W100XformH(W100CardInfo *w100c,
-+ CARD16 x, CARD16 y, CARD16 w, CARD16 h)
-+{
-+ CARD16 th;
-+
-+ switch (w100c->ctx.xform.randr & RR_Rotate_All) {
-+ case RR_Rotate_0:
-+ case RR_Rotate_180:
-+ default:
-+ th = h;
-+ break;
-+ case RR_Rotate_90:
-+ case RR_Rotate_270:
-+ th = w;
-+ break;
-+ }
-+ return th;
-+}
-+
++
+CARD8 W100GetScaler(CARD16 dstsize, CARD16 srcsize)
+{
+ return W100_MAX(1, W100_MIN(31, ((16 * srcsize) + dstsize - 1) / dstsize));
@@ -7152,22 +7130,18 @@
+}
+
+
-+static void W100Blt(KdScreenInfo *screen,
-+ int randr,
-+ int bpp,
++static void W100Blt(KdScreenInfo *screen,
++ int randr, int bpp,
+ CARD32 srcOffset,
-+ CARD16 srcW,
-+ CARD16 srcH,
+ CARD16 srcPitch,
++ BoxPtr srcBox,
+ CARD32 dstOffset,
+ CARD16 dstPitch,
-+ CARD16 dstX,
-+ CARD16 dstY)
++ BoxPtr dstBox)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ W100CardInfo(pScreenPriv);
-+ CARD16 x, y, w, h;
+ int fifoEntries = 9;
+ Bool hasXForm = FALSE;
+ eng_cntl_u eng_cntl;
@@ -7176,12 +7150,8 @@
+ src_width_u src_width;
+ src_height_u src_height;
+ dst_width_height_u dst_width_height;
-+
-+ DBG_IMAGEON(("W100Blt(randr:%d,bpp:%d,srcOffset:0x%08x,"
-+ "srcW:%d,srcH:%d,srcPitch:%d,dstOffset:0x%08x,"
-+ "dstPitch:%d,dstX:%d,dstY:%d)\n",
-+ randr, bpp, srcOffset, srcW, srcH,
-+ srcPitch, dstOffset, dstPitch, dstX, dstY));
++ CARD16 dstX;
++ CARD16 dstY;
+
+ if (randr & (RR_Rotate_90|RR_Rotate_270)) {
+ hasXForm = TRUE;
@@ -7195,21 +7165,28 @@
+ W100SetRotation(w100c, randr, FALSE);
+ W100SetSource(screen, srcPitch, srcOffset, bpp);
+ W100SetDestination(screen, dstPitch, dstOffset, bpp);
-+
-+ x = W100XformX(w100c, dstX, dstY, srcW, srcH);
-+ y = W100XformY(w100c, dstX, dstY, srcW, srcH);
-+ w = W100XformW(w100c, dstX, dstY, srcW, srcH);
-+ h = W100XformH(w100c, dstX, dstY, srcW, srcH);
-+
-+ src_x_y.f.src_y = 0;
-+ src_x_y.f.src_x = 0;
-+ dst_x_y.f.dst_x = x;
-+ dst_x_y.f.dst_y = y;
-+ src_width.f.src_width = srcW;
-+ src_height.f.src_height = srcH;
-+ dst_width_height.f.dst_height = h;
-+ dst_width_height.f.dst_width_b0 = w & 0xff;
-+ dst_width_height.f.dst_width_b1 = (w >> 8) & 0x3f;
++ W100TrajectoryOrigin(w100c, dstBox, &dstX, &dstY);
++
++ src_x_y.f.src_x = srcBox->x1;
++ src_x_y.f.src_y = srcBox->y1;
++ dst_x_y.f.dst_x = dstX;
++ dst_x_y.f.dst_y = dstY;
++ src_width.f.src_width = srcBox->x2 - srcBox->x1 + 1;
++ src_height.f.src_height = srcBox->y2 - srcBox->y1 + 1;
++ dst_width_height.f.dst_height = dstBox->y2 - dstBox->y1 + 1;
++ dst_width_height.f.dst_width_b0 = (dstBox->x2 - dstBox->x1 + 1) & 0xff;
++ dst_width_height.f.dst_width_b1 = ((dstBox->x2 - dstBox->x1 + 1) >> 8) & 0x3f;
++
++ DBG_IMAGEON(("W100Blt src(x:%d,y:%d,w:%d,h:%d) dst(x:%d,y:%d,w:%d,h:%d)\n",
++ src_x_y.f.src_x,
++ src_x_y.f.src_y,
++ src_width.f.src_width,
++ src_height.f.src_height,
++ dst_x_y.f.dst_x,
++ dst_x_y.f.dst_y,
++ dst_width_height.f.dst_width_b0 |
++ dst_width_height.f.dst_width_b1 << 8,
++ dst_width_height.f.dst_height));
+
+ if (W100WaitCmdFifoEntries(w100c, fifoEntries)) {
+ MMIO_OUT32(mmDST_PITCH, w100c->ctx.dst.pitch);
@@ -7239,20 +7216,17 @@
+ int randr,
+ int bpp,
+ CARD32 srcOffset,
-+ CARD16 srcW,
-+ CARD16 srcH,
+ CARD16 srcPitch,
++ BoxPtr srcBox,
+ CARD32 dstOffset,
+ CARD16 dstPitch,
-+ CARD16 dstX,
-+ CARD16 dstY,
++ BoxPtr dstBox,
+ CARD8 xscaler,
+ CARD8 yscaler)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ W100CardInfo(pScreenPriv);
-+ CARD16 x, y, w, h, sw, sh;
+ Bool hasXForm = FALSE;
+ dp_datatype_u dp_datatype;
+ dp_mix_u dp_mix;
@@ -7266,13 +7240,22 @@
+ dst_width_height_u dst_width_height;
+ int firstStage = 10;
+ int secondStage = 10;
-+
-+ DBG_IMAGEON(("W100StretchBlt(randr:%d,bpp:%d,srcOffset:0x%08x,"
-+ "srcW:%d,srcH:%d,srcPitch:%d,dstOffset:0x%08x,"
-+ "dstPitch:%d,dstX:%d,dstY:%d,xscaler:%d,yscaler:%d)\n",
-+ randr, bpp, srcOffset, srcW, srcH,
-+ srcPitch, dstOffset, dstPitch,
-+ dstX, dstY, xscaler, yscaler));
++ CARD16 dx, dy, sw, sh, dw, dh;
++ BoxRec dst;
++
++ DBG_IMAGEON(("W100StretchBlt(randr:%d,bpp:%d,"
++ "src(x1:%d,y1:%d,x2:%d,y2:%d,pitch:%d,offset:%d),"
++ "dst(x1:%d,y1:%d,x2:%d,y2:%d,pitch:%d,offset:%d),"
++ "xscaler:%d,yscaler:%d)\n",
++ randr, bpp,
++ srcBox->x1, srcBox->y1, srcBox->x2, srcBox->y2,
++ srcPitch, srcOffset,
++ dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2,
++ dstPitch, dstOffset,
++ xscaler, yscaler));
++
++ sw = W100ApplyScaler(srcBox->x2 - srcBox->x1 + 1, xscaler);
++ sh = W100ApplyScaler(srcBox->y2 - srcBox->y1 + 1, yscaler);
+
+ if (randr & (RR_Rotate_90|RR_Rotate_270)) {
+ hasXForm = TRUE;
@@ -7281,12 +7264,23 @@
+ eng_cntl.f.dis_src_uses_dst_dirmaj = 1;
+ ++firstStage;
+ ++secondStage;
++ dh = sw;
++ dw = sh;
++ } else {
++ dh = sh;
++ dw = sw;
+ }
+
++ dst.x1 = dstBox->x1;
++ dst.y1 = dstBox->y1;
++ dst.x2 = dst.x1 + dw - 1;
++ dst.y2 = dst.y1 + dh - 1;
++
+ W100ResetContext(w100c);
+ W100SetRotation(w100c, randr, FALSE);
+ W100SetSource(screen, srcPitch, srcOffset, bpp);
+ W100SetDestination(screen, dstPitch, dstOffset, bpp);
++ W100TrajectoryOrigin(w100c, &dst, &dx, &dy);
+
+ src_inc.val = 0;
+ src_inc.f.src_xinc = xscaler;
@@ -7308,23 +7302,15 @@
+ e2.f.srcblend = E2_SRCBLEND_ZERO;
+ e2.f.dstblend = E2_DSTBLEND_ZERO;
+
-+ sw = W100ApplyScaler(srcW, xscaler);
-+ sh = W100ApplyScaler(srcH, yscaler);
-+
-+ x = W100XformX(w100c, dstX, dstY, sw, sh);
-+ y = W100XformY(w100c, dstX, dstY, sw, sh);
-+ w = W100XformW(w100c, dstX, dstY, sw, sh);
-+ h = W100XformH(w100c, dstX, dstY, sw, sh);
-+
-+ src_x_y.f.src_y = 0;
-+ src_x_y.f.src_x = 0;
-+ dst_x_y.f.dst_x = x;
-+ dst_x_y.f.dst_y = y;
++ src_x_y.f.src_x = srcBox->x1;
++ src_x_y.f.src_y = srcBox->y1;
++ dst_x_y.f.dst_x = dx;
++ dst_x_y.f.dst_y = dy;
+ src_width.f.src_width = sw + 1;
+ src_height.f.src_height = sh;
-+ dst_width_height.f.dst_height = h;
-+ dst_width_height.f.dst_width_b0 = w & 0xff;
-+ dst_width_height.f.dst_width_b1 = (w >> 8) & 0x3f;
++ dst_width_height.f.dst_height = dh;
++ dst_width_height.f.dst_width_b0 = dw & 0xff;
++ dst_width_height.f.dst_width_b1 = (dw >> 8) & 0x3f;
+
+
+ if (W100WaitCmdFifoEntries(w100c, firstStage)) {
@@ -7373,20 +7359,17 @@
+ int randr,
+ int bpp,
+ CARD32 srcOffset,
-+ CARD16 srcW,
-+ CARD16 srcH,
+ CARD16 srcPitch,
++ BoxPtr srcBox,
+ CARD32 dstOffset,
+ CARD16 dstPitch,
-+ CARD16 dstX,
-+ CARD16 dstY,
++ BoxPtr dstBox,
+ CARD8 xscaler,
+ CARD8 yscaler)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ W100CardInfo(pScreenPriv);
-+ CARD16 x, y, w, h, sw, sh;
+ Bool hasXForm = FALSE;
+ dp_datatype_u dp_datatype;
+ dp_mix_u dp_mix;
@@ -7401,14 +7384,23 @@
+ dst_width_height_u dst_width_height;
+ int firstStage = 11;
+ int secondStage = 11;
-+
-+ DBG_IMAGEON(("W100ScaledBlt(randr:%d,bpp:%d,srcOffset:0x%08x,"
-+ "srcW:%d,srcH:%d,srcPitch:%d,dstOffset:0x%08x,"
-+ "dstPitch:%d,dstX:%d,dstY:%d,xscaler:%d,yscaler:%d)\n",
-+ randr, bpp, srcOffset, srcW, srcH,
-+ srcPitch, dstOffset, dstPitch,
-+ dstX, dstY, xscaler, yscaler));
-+
++ CARD16 dx, dy, sw, sh, dw, dh;
++ BoxRec dst;
++
++ DBG_IMAGEON(("W100ScaledBlt(randr:%d,bpp:%d,"
++ "src(x1:%d,y1:%d,x2:%d,y2:%d,pitch:%d,offset:%d),"
++ "dst(x1:%d,y1:%d,x2:%d,y2:%d,pitch:%d,offset:%d),"
++ "xscaler:%d,yscaler:%d)\n",
++ randr, bpp,
++ srcBox->x1, srcBox->y1, srcBox->x2, srcBox->y2,
++ srcPitch, srcOffset,
++ dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2,
++ dstPitch, dstOffset,
++ xscaler, yscaler));
++
++ sw = W100ApplyScaler(srcBox->x2 - srcBox->x1 + 1, xscaler);
++ sh = W100ApplyScaler(srcBox->y2 - srcBox->y1 + 1, yscaler);
++
+ if (randr & (RR_Rotate_90|RR_Rotate_270)) {
+ hasXForm = TRUE;
+ eng_cntl.val = w100c->regs.ENG_CNTL;
@@ -7416,12 +7408,27 @@
+ eng_cntl.f.dis_src_uses_dst_dirmaj = 1;
+ ++firstStage;
+ ++secondStage;
++ dh = sw;
++ dw = sh;
++ } else {
++ dh = sh;
++ dw = sw;
+ }
+
++ dst.x1 = dstBox->x1;
++ dst.y1 = dstBox->y1;
++ dst.x2 = dst.x1 + dw - 1;
++ dst.y2 = dst.y1 + dh - 1;
++
+ W100ResetContext(w100c);
+ W100SetRotation(w100c, randr, FALSE);
+ W100SetSource(screen, srcPitch, srcOffset, bpp);
+ W100SetDestination(screen, dstPitch, dstOffset, bpp);
++ W100TrajectoryOrigin(w100c, &dst, &dx, &dy);
++
++ DBG_IMAGEON(("Corrected dst(x1:%d,y1:%d,x2:%d,y2:%d). Origin(%d,%d)\n",
++ dst.x1, dst.y1, dst.x2, dst.y2,
++ dx, dy));
+
+ src_inc.val = 0;
+ src_inc.f.src_xinc = xscaler;
@@ -7446,25 +7453,18 @@
+ e2.f.srcblend = E2_SRCBLEND_ZERO;
+ e2.f.dstblend = E2_DSTBLEND_ZERO;
+
-+ sw = W100ApplyScaler(srcW, xscaler);
-+ sh = W100ApplyScaler(srcH, yscaler);
-+
-+ x = W100XformX(w100c, dstX, dstY, sw, sh);
-+ y = W100XformY(w100c, dstX, dstY, sw, sh);
-+ w = W100XformW(w100c, dstX, dstY, sw, sh);
-+ h = W100XformH(w100c, dstX, dstY, sw, sh);
+
-+ src_x_y.f.src_y = 0;
-+ src_x_y.f.src_x = 0;
-+ src2_x_y.f.src_y = 0 + 4;
-+ src2_x_y.f.src_x = 0;
-+ dst_x_y.f.dst_x = x;
-+ dst_x_y.f.dst_y = y;
++ src_x_y.f.src_x = srcBox->x1;
++ src_x_y.f.src_y = srcBox->y1;
++ src2_x_y.f.src_x = srcBox->x1;
++ src2_x_y.f.src_y = srcBox->y1 + 4;
++ dst_x_y.f.dst_x = dx;
++ dst_x_y.f.dst_y = dy;
+ src_width.f.src_width = sw + 1;
+ src_height.f.src_height = sh;
-+ dst_width_height.f.dst_height = h;
-+ dst_width_height.f.dst_width_b0 = w & 0xff;
-+ dst_width_height.f.dst_width_b1 = (w >> 8) & 0x3f;
++ dst_width_height.f.dst_height = dh;
++ dst_width_height.f.dst_width_b0 = dw & 0xff;
++ dst_width_height.f.dst_width_b1 = (dw >> 8) & 0x3f;
+
+ if (W100WaitCmdFifoEntries(w100c, firstStage)) {
+ /* Set Source */
@@ -7517,82 +7517,93 @@
+}
+
+void W100PlanarBlt(KdScreenInfo *screen,
-+ int planes,
-+ int bpp,
-+ int randr,
++ int planes, int planeOffsets[],
++ int bpp, int randr,
+ KdOffscreenArea *src,
+ int srcW,
-+ int srcPitch,
+ int srcH,
++ BoxPtr srcBox,
+ KdOffscreenArea *dst,
-+ int planeOffsets[],
+ int dstW,
-+ int dstPitch,
+ int dstH,
-+ int dstX,
-+ int dstY)
++ BoxPtr dstBox)
+{
+ ScreenPtr pScreen = screen->pScreen;
+ KdScreenPriv(pScreen);
+ W100CardInfo(pScreenPriv);
+ W100ScreenInfo(pScreenPriv);
++
++ CARD16 dstBoxW, dstBoxH, srcBoxW, srcBoxH;
+ CARD8 *srcOffset, *dstBase, *dstOffset;
-+ int xoffs, yoffs;
++ int xerror, yerror;
+ unsigned int subsampling[] = {0, 1, 1};
+ int plane;
-+ int stretch = ((srcW != dstW) || (srcH != dstH));
++ srcBoxW = srcBox->x2 - srcBox->x1 + 1;
++ srcBoxH = srcBox->y2 - srcBox->y1 + 1;
++ if (randr & (RR_Rotate_90 | RR_Rotate_270)) {
++ dstBoxW = dstBox->y2 - dstBox->y1 + 1;
++ dstBoxH = dstBox->x2 - dstBox->x1 + 1;
++ } else {
++ dstBoxW = dstBox->x2 - dstBox->x1 + 1;
++ dstBoxH = dstBox->y2 - dstBox->y1 + 1;
++ }
++
++ Bool stretch = ((srcBoxW != dstBoxW) || (srcBoxH != dstBoxH));
+ CARD8 xscaler, yscaler;
++ BoxRec dstb = *dstBox;
+
+ DBG_IMAGEON(("W100PlanarBlt(planes:%d,bpp:%d,randr:%d,"
-+ "src(w:%d,pitch:%d,h:%d),"
-+ "dst(w:%d,pitch:%d,h:%d,x:%d,y:%d)\n",
++ "src(x1:%d,y1:%d,x2:%d,y2:%d,w:%d,h:%d),"
++ "dst(x1:%d,y1:%d,x2:%d,y2:%d,w:%d,h:%d)\n",
+ planes, bpp, randr,
-+ srcW, srcPitch, srcH,
-+ dstW, dstPitch, dstH, dstX, dstY));
++ srcBox->x1, srcBox->y1, srcBox->x2, srcBox->y2, srcW, srcH,
++ dstBox->x1, dstBox->y1, dstBox->x2, dstBox->y2, dstW, dstH));
+
++ xerror = yerror = 0;
+ if (stretch) {
-+ xscaler = W100GetScaler(dstW, srcW);
-+ yscaler = W100GetScaler(dstH, srcH);
-+ xoffs = yoffs = 0;
++ xscaler = W100GetScaler(dstBoxW, srcBoxW);
++ yscaler = W100GetScaler(dstBoxH, srcBoxH);
+ if (xscaler != 16 || yscaler != 16) {
-+ xoffs = (dstW - W100ApplyScaler(srcW, xscaler)) / 2;
-+ yoffs = (dstH - W100ApplyScaler(srcH, yscaler)) / 2;
++ xerror = (dstBoxW - W100ApplyScaler(srcBoxW, xscaler)) / 2;
++ yerror = (dstBoxH - W100ApplyScaler(srcBoxH, yscaler)) / 2;
+ DBG_IMAGEON(("Stretching with xscaler:%d,yscaler:%d,"
-+ "xoffs:%d,yoffs:%d\n",
-+ xscaler, yscaler, xoffs, yoffs));
++ "xerror:%d,yerror:%d\n",
++ xscaler, yscaler, xerror, yerror));
+ } else {
-+ xoffs = yoffs = 0;
++ xerror = yerror = 0;
+ stretch = FALSE;
+ }
+ }
+
++ W100MoveTo(&dstb, xerror, yerror);
++
+ srcOffset = src->vidmem->base + src->offset;
+ dstBase = dst->vidmem->base + dst->offset;
+ for (plane = 0; plane < planes; plane++) {
++ BoxRec srcCBox;
++ BoxRec dstCBox;
+ dstOffset = dstBase + planeOffsets[plane];
++ W100ScaleBox(srcBox, &srcCBox, -subsampling[plane]);
++ W100ScaleBox(&dstb, &dstCBox, -subsampling[plane]);
+ if (stretch) {
+ W100ScaledBlt(screen, randr, bpp,
+ (CARD32) srcOffset,
+ srcW >> subsampling[plane],
-+ srcH >> subsampling[plane],
-+ srcPitch >> subsampling[plane],
++ &srcCBox,
+ (CARD32) dstOffset,
-+ dstPitch >> subsampling[plane],
-+ (dstX + xoffs) >> subsampling[plane],
-+ (dstY + yoffs) >> subsampling[plane],
++ dstW >> subsampling[plane],
++ &dstCBox,
+ xscaler, yscaler);
+ } else {
+ W100Blt(screen, randr, bpp,
+ (CARD32) srcOffset,
+ srcW >> subsampling[plane],
-+ srcH >> subsampling[plane],
-+ srcPitch >> subsampling[plane],
++ &srcCBox,
+ (CARD32) dstOffset,
-+ dstPitch >> subsampling[plane],
-+ dstX >> subsampling[plane],
-+ dstY >> subsampling[plane]);
++ dstW >> subsampling[plane],
++ &dstCBox);
+ }
-+ srcOffset += (srcPitch * srcH) >> (subsampling[plane] * 2);
++ srcOffset += (srcW * srcH) >> (subsampling[plane] * 2);
+ }
+}
+
@@ -7668,11 +7679,59 @@
+ *y >>= 1;
+ }
+}
-+
++
++void W100VSync(W100CardInfo *w100c)
++{
++ int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */
++ active_v_disp_u active_v_disp;
++ disp_int_cntl_u disp_int_cntl;
++ gen_int_cntl_u gen_int_cntl;
++ gen_int_status_wr_u gen_int_status;
++
++ active_v_disp.val = MMIO_IN32(mmACTIVE_V_DISP);
++
++ /*set vline pos */
++ disp_int_cntl.val = 0;
++ disp_int_cntl.f.vline_int_pos = active_v_disp.f.active_v_end;
++ MMIO_OUT32(mmDISP_INT_CNTL, disp_int_cntl.val);
++
++ /* disable vline irq */
++ gen_int_cntl.val = MMIO_IN32(mmGEN_INT_CNTL);
++ gen_int_cntl.f.crtc_vline_mask = 0;
++ MMIO_OUT32(mmGEN_INT_CNTL, gen_int_cntl.val);
++
++ /* clear vline irq status */
++ gen_int_status.val = 0;
++ gen_int_status.f.crtc_vline_stat_ak = 1;
++ MMIO_OUT32(mmGEN_INT_STATUS, gen_int_status.val);
++
++ /* enable vline irq */
++ gen_int_cntl.f.crtc_vline_mask = 1;
++ MMIO_OUT32(gen_int_cntl.val, mmGEN_INT_CNTL);
++
++ /* clear vline irq status */
++ MMIO_OUT32(mmGEN_INT_STATUS, gen_int_status.val);
++
++ while (timeout > 0) {
++ if (MMIO_IN32(mmGEN_INT_STATUS) & 0x00000002) {
++ break;
++ }
++ usleep(1);
++ timeout--;
++ }
++
++ /* disable vline irq */
++ gen_int_cntl.f.crtc_vline_mask = 0;
++ MMIO_OUT32(mmGEN_INT_CNTL, gen_int_cntl.val);
++
++ /* clear vline irq status */
++ MMIO_OUT32(mmGEN_INT_STATUS, gen_int_status.val);
++}
++
+
--- /dev/null
+++ xorg-server-X11R7.1-1.1.0.work/hw/kdrive/imageon/imageon_video.c
-@@ -0,0 +1,1051 @@
+@@ -0,0 +1,1170 @@
+/*
+ * Copyright © 2007 Manuel Teira
+ *
@@ -7754,19 +7813,32 @@
+static struct {
+ CARD8 xfactor;
+ CARD8 yfactor;
-+} ovlResizers[10] = {
-+ { 0, 0 },
-+ { 1, 0 },
-+ { 0, 1 },
-+ { 1, 1 },
-+ { 2, 1 },
-+ { 1, 2 },
-+ { 2, 2 },
-+ { 3, 2 },
-+ { 2, 3 },
-+ { 3, 3 }
++} ovlResizers[NUM_OVL_RESIZERS] = {
++ { 0, 0 },
++ { 0, 1 }, { 1, 0 }, { 1, 1 },
++ { 1, 2 }, { 2, 1 }, { 2, 2 },
++ { 2, 3 }, { 3, 2 }, { 3, 3 }
+};
+
++static int W100SurfaceSize(W100PortPrivPtr port, short w, short h)
++{
++ int size = 0;
++ DBG_IMAGEON(("W100SurfaceSize for id=%08x, w=%d, h=%d\n",
++ port->src.id, w, h));
++
++ switch (port->src.id) {
++ case FOURCC_YV12:
++ case FOURCC_I420:
++ size = (3 * w * h) / 2;
++ break;
++ case FOURCC_UYVY:
++ case FOURCC_YUY2:
++ size = w * h * 2;
++ break;
++ }
++ return size;
++}
++
+static void W100ClearSurface(KdScreenInfo *screen,
+ KdOffscreenArea *area,
+ CARD16 x,
@@ -7825,8 +7897,8 @@
+{
+ W100ScreenInfo *w100s = screen->driver;
+ W100CardInfo(screen);
-+ W100PortPrivPtr pPortPriv = w100s->pAdaptor->pPortPrivates[0].ptr;
-+
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
++ CARD16 w, h, pitch;
+ video_ctrl_u video_ctrl;
+ video_y_offset_u video_y_offset;
+ video_y_pitch_u video_y_pitch;
@@ -7840,56 +7912,56 @@
+ graphic_h_disp_u graphic_h_disp;
+ graphic_v_disp_u graphic_v_disp;
+
-+ CARD16 w, h;
++ w = pitch = port->ovl.frame.x2 - port->ovl.frame.x1 + 1;
++ h = port->ovl.frame.y2 - port->ovl.frame.y1 + 1;
+
-+ DBG_IMAGEON(("W100OverlaySetup(ovlX:%d,ovlY:%d,ovlWidth:%d,ovlHeight:%d,"
-+ "videoHorExp:%d,videoVerExp:%d,YPlane:0x%08x,UPlane:0x%08x,"
-+ "VPlane:0x%08x)\n",
-+ pPortPriv->ovlX, pPortPriv->ovlY,
-+ pPortPriv->ovlWidth, pPortPriv->ovlHeight,
-+ pPortPriv->videoHorExp, pPortPriv->videoVerExp,
-+ pPortPriv->YPlaneOffset, pPortPriv->UPlaneOffset,
-+ pPortPriv->VPlaneOffset));
++ ErrorF("W100OverlaySetup(ovlX:%d,ovlY:%d,ovlWidth:%d,ovlHeight:%d,"
++ "videoHorExp:%d,videoVerExp:%d,YPlane:0x%08x,UPlane:0x%08x,"
++ "VPlane:0x%08x)\n",
++ port->ovl.frame.x1, port->ovl.frame.y1, w, h,
++ port->ovl.horExp,
++ port->ovl.verExp,
++ port->planes.yplane,
++ port->planes.uplane,
++ port->planes.vplane);
+
-+ if (pPortPriv->videoStatus & W100_OVERLAY_CONFIGURED) {
++ if (port->videoStatus & W100_OVERLAY_CONFIGURED) {
+ return;
+ }
+
-+ w = pPortPriv->ovlWidth << pPortPriv->videoHorExp;
-+ h = pPortPriv->ovlHeight << pPortPriv->videoVerExp;
++ w <<= port->ovl.horExp;
++ h <<= port->ovl.verExp;
+
+ video_ctrl.val = w100c->regs.VIDEO_CTRL;
+
+ video_ctrl.f.video_inv_hor = 0;
+ video_ctrl.f.video_inv_ver = 0;
+ video_ctrl.f.yuv2rgb_option = 0;
-+ video_ctrl.f.video_hor_exp = pPortPriv->videoHorExp;
-+ video_ctrl.f.video_ver_exp = pPortPriv->videoVerExp;
++ video_ctrl.f.video_hor_exp = port->ovl.horExp;
++ video_ctrl.f.video_ver_exp = port->ovl.verExp;
+ video_ctrl.f.video_ch_sel = 0;
+
+ video_ctrl.f.yuv2rgb_en = 1;
+ //Only support this, by the moment
+ video_ctrl.f.video_mode = OVLFORMAT_YUV420;
+
-+ video_y_pitch.f.y_pitch = pPortPriv->ovlWidth;
-+ video_u_pitch.f.u_pitch = pPortPriv->ovlWidth >> 1;
-+ video_v_pitch.f.v_pitch = pPortPriv->ovlWidth >> 1;
+
-+ /*
-+ video_y_offset.f.y_offset = pPortPriv->YPlaneOffset +
-+ video_y_pitch.f.y_pitch * pPortPriv->ovlY + pPortPriv->ovlX;
-+ video_u_offset.f.u_offset = pPortPriv->UPlaneOffset +
-+ video_u_pitch.f.u_pitch * pPortPriv->ovlY + (pPortPriv->ovlX / 2);
-+ video_v_offset.f.v_offset = pPortPriv->VPlaneOffset +
-+ video_v_pitch.f.v_pitch * pPortPriv->ovlY + (pPortPriv->ovlX / 2);
-+ */
++ video_y_pitch.val = 0;
++ video_u_pitch.val = 0;
++ video_v_pitch.val = 0;
++ video_y_pitch.f.y_pitch = pitch;
++ video_u_pitch.f.u_pitch = pitch >> 1;
++ video_v_pitch.f.v_pitch = pitch >> 1;
+
-+ video_y_offset.f.y_offset = pPortPriv->YPlaneOffset;
-+ video_u_offset.f.u_offset = pPortPriv->UPlaneOffset;
-+ video_v_offset.f.v_offset = pPortPriv->VPlaneOffset;
++ video_y_offset.val = 0;
++ video_u_offset.val = 0;
++ video_v_offset.val = 0;
++ video_y_offset.f.y_offset = port->planes.yplane;
++ video_u_offset.f.u_offset = port->planes.uplane;
++ video_v_offset.f.v_offset = port->planes.vplane;
+
+ graphic_key.val = 0;
-+ graphic_key.f.keyer_color = pPortPriv->colorKey;
++ graphic_key.f.keyer_color = port->ovl.colorKey;
+ graphic_key.f.keyer_mask = 0xffffUL;
+ video_ctrl.f.keyer_en = 1;
+
@@ -7897,10 +7969,11 @@
+ graphic_v_disp.val = w100c->regs.GRAPHIC_V_DISP;
+
+ video_hpos.f.video_h_start = graphic_h_disp.f.graphic_h_start
-+ + pPortPriv->ovlX;
++ + port->ovl.frame.x1;
+ video_hpos.f.video_h_end = video_hpos.f.video_h_start + w;
++
+ video_vpos.f.video_v_start = graphic_v_disp.f.graphic_v_start
-+ + pPortPriv->ovlY;
++ + port->ovl.frame.y1;
+ video_vpos.f.video_v_end = video_vpos.f.video_v_start + h;
+ if (video_hpos.f.video_h_end > graphic_h_disp.f.graphic_h_end) {
+ w = graphic_h_disp.f.graphic_h_end - video_hpos.f.video_h_start;
@@ -7911,9 +7984,11 @@
+
+ W100DisableDisplayUpdate(w100c);
+ //This need to be tuned deeply, to get an stable
-+ //overlay image
++ //overlay image:
++ //Best results seems to be present with 0x40xxxxxx
++ //But overlay surface must be located in a 8 dot multiple
+ MMIO_OUT32(mmDISP_DEBUG2,
-+ (w100c->regs.DISP_DEBUG2 & ~0xff000000) | 0x80000000 );
++ (w100c->regs.DISP_DEBUG2 & ~0xff000000) | 0x40000000 );
+ MMIO_OUT32(mmGRAPHIC_KEY, graphic_key.val);
+ MMIO_OUT32(mmVIDEO_Y_OFFSET, video_y_offset.val);
+ MMIO_OUT32(mmVIDEO_Y_PITCH, video_y_pitch.val);
@@ -7926,52 +8001,56 @@
+ MMIO_OUT32(mmVIDEO_V_POS, video_vpos.val);
+ W100EnableDisplayUpdate(w100c);
+
-+ pPortPriv->videoCtrl = video_ctrl.val;
-+ pPortPriv->videoStatus |= W100_OVERLAY_CONFIGURED;
++ port->videoCtrl = video_ctrl.val;
++ port->videoStatus |= W100_OVERLAY_CONFIGURED;
+}
+
+static void W100OverlayEnable(KdScreenInfo *screen)
+{
+ W100ScreenInfo *w100s = screen->driver;
+ W100CardInfo(screen);
-+ W100PortPrivPtr pPortPriv = w100s->pAdaptor->pPortPrivates[0].ptr;
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
+ video_ctrl_u video_ctrl;
+
-+ DBG_IMAGEON(("W100OverlayEnable()\n"));
-+
-+ if (!(pPortPriv->videoStatus & W100_OVERLAY_CONFIGURED)) {
++ if (!(port->videoStatus & W100_OVERLAY_CONFIGURED)) {
+ W100OverlaySetup(screen);
+ }
+
-+ video_ctrl.val = pPortPriv->videoCtrl;
-+ video_ctrl.f.en_video_req = 1;
-+ video_ctrl.f.en_video_crtc = 1;
-+ video_ctrl.f.en_graphic_req_video = 1;
-+ W100DisableDisplayUpdate(w100c);
-+ MMIO_OUT32(mmVIDEO_CTRL, video_ctrl.val);
-+ W100EnableDisplayUpdate(w100c);
-+ pPortPriv->videoCtrl = video_ctrl.val;
-+ pPortPriv->videoStatus |= W100_OVERLAY_ON;
++ if (!(port->videoStatus & W100_OVERLAY_ON)) {
++ ErrorF("W100OverlayEnable()\n");
++ video_ctrl.val = port->videoCtrl;
++ video_ctrl.f.en_video_req = 1;
++ video_ctrl.f.en_video_crtc = 1;
++ video_ctrl.f.en_graphic_req_video = 1;
++ W100DisableDisplayUpdate(w100c);
++ MMIO_OUT32(mmVIDEO_CTRL, video_ctrl.val);
++ W100EnableDisplayUpdate(w100c);
++ port->videoCtrl = video_ctrl.val;
++ port->videoStatus |= W100_OVERLAY_ON;
++ }
+}
+
+static void W100OverlayDisable(KdScreenInfo *screen)
+{
-+ DBG_IMAGEON(("W100OverlayDisable()\n"));
++
+ W100ScreenInfo *w100s = screen->driver;
+ W100CardInfo(screen);
-+ W100PortPrivPtr pPortPriv = w100s->pAdaptor->pPortPrivates[0].ptr;
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
+
+ video_ctrl_u video_ctrl;
+
-+ video_ctrl.val = pPortPriv->videoCtrl;
-+ video_ctrl.f.en_video_req = 0;
-+ video_ctrl.f.en_video_crtc = 0;
-+ video_ctrl.f.en_graphic_req_video = 0;
-+ W100DisableDisplayUpdate(w100c);
-+ MMIO_OUT32(mmVIDEO_CTRL, video_ctrl.val);
-+ W100EnableDisplayUpdate(w100c);
-+ pPortPriv->videoCtrl = video_ctrl.val;
-+ pPortPriv->videoStatus &= ~W100_OVERLAY_ON;
++ if ((port->videoStatus & W100_OVERLAY_ON)) {
++ ErrorF("W100OverlayDisable()\n");
++ video_ctrl.val = port->videoCtrl;
++ video_ctrl.f.en_video_req = 0;
++ video_ctrl.f.en_video_crtc = 0;
++ video_ctrl.f.en_graphic_req_video = 0;
++ W100DisableDisplayUpdate(w100c);
++ MMIO_OUT32(mmVIDEO_CTRL, video_ctrl.val);
++ W100EnableDisplayUpdate(w100c);
++ port->videoCtrl = video_ctrl.val;
++ port->videoStatus &= ~W100_OVERLAY_ON;
++ }
+}
+
+static void W100VideoSave(ScreenPtr pScreen, KdOffscreenArea *area)
@@ -7979,28 +8058,44 @@
+ KdScreenPriv(pScreen);
+ W100CardInfo(pScreenPriv);
+ W100ScreenInfo(pScreenPriv);
-+ W100PortPrivPtr pPortPriv = w100s->pAdaptor->pPortPrivates[0].ptr;
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
+
-+ if (pPortPriv->offSurface == area) {
-+ pPortPriv->offSurface = NULL;
-+ pPortPriv->offSize = 0;
++ if (port->src.surface == area) {
++ port->src.surface = NULL;
+ }
-+ if (pPortPriv->ovlSurface == area) {
-+ pPortPriv->ovlSurface = NULL;
-+ pPortPriv->ovlSize = 0;
++
++ if (port->ovl.surface == area) {
++ port->ovl.surface = NULL;
+ }
+}
+
-+static void W100HostPlanarData(KdScreenInfo *screen,
-+ int id,
-+ CARD8 *src,
-+ KdOffscreenArea *dst,
-+ CARD32 srcPitch, CARD32 srcHeight,
-+ CARD32 dstPitch, CARD32 dstHeight,
-+ CARD16 srcX, CARD16 srcY,
-+ CARD16 dstX, CARD16 dstY,
-+ CARD16 w, CARD16 h)
++static void W100SaveSurface(CARD8 *src, int size, const char *file)
+{
++ int fd;
++ if (fd = open(file, O_WRONLY | O_CREAT | O_TRUNC,
++ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
++ write(fd, (void*) src, size);
++ close(fd);
++ }
++}
++
++static void W100HostPlanarData(KdScreenInfo *screen)
++{
++ W100ScreenInfo *w100s = screen->driver;
++ W100CardInfo(screen);
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
++ KdOffscreenArea *dst = port->src.surface;
++ CARD8 *src = port->src.buffer;
++ CARD16 srcPitch = port->src.width; //WARN: padding?
++ CARD16 srcHeight = port->src.height;
++ CARD16 dstPitch = port->src.box.x2 - port->src.box.x1 + 1; //WARN: padding?
++ CARD16 dstHeight = port->src.box.y2 - port->src.box.y1 + 1;
++ CARD16 srcX = port->src.box.x1;
++ CARD16 srcY = port->src.box.y1;
++ CARD16 dstX = 0;
++ CARD16 dstY = 0;
++ CARD16 w = dstPitch;
++ CARD16 h = dstHeight;
+ CARD8 *dstBase = dst->vidmem->base + dst->offset;
+ CARD8 *dstPtr;
+ CARD8 *srcPtr;
@@ -8025,7 +8120,7 @@
+ dstPtr = dstBase + (dstHeight * dstPitch) //Start of U Plane
+ + (dstX >> 1) //X Offset
+ + ((dstY * dstPitch) >> 2); //Y Offset
-+ if (id == FOURCC_I420) {
++ if (port->src.id == FOURCC_I420) {
+ srcPtr = src + (srcHeight * srcPitch) //Start of U Plane
+ + (srcX >> 1) //X Offset
+ + ((srcY * srcPitch) >> 2); //Y Offset
@@ -8044,7 +8139,7 @@
+ dstPtr = dstBase + ((5 * dstHeight * dstPitch) / 4) //Start of V Plane
+ + (dstX >> 1) //X Offset
+ + ((dstY * dstPitch) >> 2); //Y Offset
-+ if (id == FOURCC_I420) {
++ if (port->src.id == FOURCC_I420) {
+ srcPtr = src + ((5 * srcHeight * srcPitch) / 4) //Start of V Plane
+ + (srcX >> 1) //X Offset
+ + ((srcY * srcPitch) >> 2); //Y Offset
@@ -8060,16 +8155,22 @@
+ }
+}
+
-+static void W100HostPackedData(KdScreenInfo *screen,
-+ int id,
-+ CARD8 *src,
-+ KdOffscreenArea *dst,
-+ CARD32 srcPitch,
-+ CARD32 dstPitch,
-+ CARD16 srcX, CARD16 srcY,
-+ CARD16 dstX, CARD16 dstY,
-+ CARD16 w, CARD16 h)
++static void W100HostPackedData(KdScreenInfo *screen)
+{
++ W100ScreenInfo *w100s = screen->driver;
++ W100CardInfo(screen);
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
++ KdOffscreenArea *dst = port->src.surface;
++ CARD8 *src = port->src.buffer;
++ CARD16 srcPitch = port->src.width << 1; //WARN: padding?
++ CARD16 dstPitch = (port->src.box.x2 - port->src.box.x1 + 1) << 1;
++ CARD16 srcX = port->src.box.x1;
++ CARD16 srcY = port->src.box.y1;
++ CARD16 dstX = 0;
++ CARD16 dstY = 0;
++ CARD16 w = port->src.box.x2 - port->src.box.x1 + 1;
++ CARD16 h = port->src.box.y2 - port->src.box.y1 + 1;
++
+ CARD8 *dstBase = dst->vidmem->base + dst->offset;
+ CARD8 *dstPtr = dstBase + (dstY * dstPitch) + (dstX << 1);
+ CARD8 *srcPtr = src + (srcY + srcPitch) + (srcX << 1);
@@ -8079,7 +8180,7 @@
+ srcPitch, srcPtr, srcX, srcY,
+ dstPitch, dstPtr, dstX, dstY,
+ w, h));
-+ while(h--) {
++ while (h--) {
+ memcpy(dstPtr, srcPtr, (w << 1)); /* 16bpp assumed */
+ srcPtr += srcPitch;
+ dstPtr += dstPitch;
@@ -8090,31 +8191,29 @@
+static void W100StopVideo(KdScreenInfo *screen, pointer data, Bool exit)
+{
+ W100CardInfo(screen);
-+ W100PortPrivPtr pPriv = (W100PortPrivPtr)data;
++ W100PortPrivPtr port = (W100PortPrivPtr)data;
+
+ DBG_IMAGEON(("W100StopVideo(exit:%d)\n", exit));
+
-+ REGION_EMPTY(screen->pScreen, &pPriv->clip);
++ REGION_EMPTY(screen->pScreen, &port->clip);
+
+ if (exit) {
-+ if (pPriv->videoStatus & W100_OVERLAY_ON) {
++ if (port->videoStatus & W100_OVERLAY_ON) {
+ W100OverlayDisable(screen);
+ }
-+ if (pPriv->offSurface) {
-+ KdOffscreenFree(screen->pScreen, pPriv->offSurface);
-+ pPriv->offSurface = NULL;
-+ pPriv->offSize = 0;
++ if (port->src.surface) {
++ KdOffscreenFree(screen->pScreen, port->src.surface);
++ port->src.surface = NULL;
+ }
-+ if (pPriv->ovlSurface) {
-+ KdOffscreenFree(screen->pScreen, pPriv->ovlSurface);
-+ pPriv->ovlSurface = NULL;
-+ pPriv->ovlSize = 0;
++
++ if (port->ovl.surface) {
++ KdOffscreenFree(screen->pScreen, port->ovl.surface);
++ port->ovl.surface = NULL;
+ }
-+ pPriv->videoStatus &= ~W100_OVERLAY_ON;
++ port->src.id = -1; // Just to avoid cached values.
+ } else {
-+ if (pPriv->videoStatus & W100_OVERLAY_ON) {
++ if (port->videoStatus & W100_OVERLAY_ON) {
+ W100OverlayDisable(screen);
-+ pPriv->videoStatus &= ~W100_OVERLAY_ON;
+ }
+ }
+}
@@ -8125,18 +8224,18 @@
+ pointer data)
+{
+ W100CardInfo(screen);
-+ W100PortPrivPtr pPriv = (W100PortPrivPtr)data;
++ W100PortPrivPtr port = (W100PortPrivPtr)data;
+
+ if (attribute == xvBrightness) {
+ DBG_IMAGEON(("Setting Brightness attribute to %d\n", value));
+ W100SetBrightness(w100c, value);
-+ pPriv->brightness = value;
++ port->ovl.brightness = value;
+ } else if (attribute == xvMaxOverlaySize) {
+ DBG_IMAGEON(("Setting MaxOverlaySize to %d\n", value));
-+ pPriv->maxOverlaySize = value;
++ port->ovl.maxSize = value;
+ } else if (attribute == xvColorKey) {
+ DBG_IMAGEON(("Setting ColorKey attribute to %d\n", value));
-+ pPriv->colorKey = value;
++ port->ovl.colorKey = value;
+ }
+ return Success;
+}
@@ -8147,17 +8246,17 @@
+ pointer data)
+{
+ W100CardInfo(screen);
-+ W100PortPrivPtr pPriv = (W100PortPrivPtr)data;
++ W100PortPrivPtr port = (W100PortPrivPtr)data;
+
+ if (attribute == xvBrightness) {
+ DBG_IMAGEON(("Getting Brightness attribute\n"));
-+ *value = pPriv->brightness;
++ *value = port->ovl.brightness;
+ } else if (attribute == xvMaxOverlaySize) {
-+ *value = pPriv->maxOverlaySize;
++ *value = port->ovl.maxSize;
+ DBG_IMAGEON(("Getting Contrast attribute\n"));
+ } else if (attribute == xvColorKey) {
+ DBG_IMAGEON(("Getting ColorKey attribute\n"));
-+ *value = pPriv->colorKey;
++ *value = port->ovl.colorKey;
+ }
+ return Success;
+}
@@ -8166,7 +8265,8 @@
+ Bool motion,
+ short vid_w, short vid_h, /*Video dimensions */
+ short drw_w, short drw_h, /*Drawable dimensions */
-+ unsigned int *p_w, unsigned int *p_h,
++ unsigned int *p_w,
++ unsigned int *p_h,
+ pointer data)
+{
+ DBG_IMAGEON(("W100QueryBestSize(vid_w:%d,vid_h:%d,drw_w:%d,drw_h:%d)\n",
@@ -8184,6 +8284,8 @@
+{
+ int size, tmp;
+
++ DBG_IMAGEON(("W100QueryImageAttributes(id:%d,w:%d,h:%d)\n", id, *w, *h));
++
+ if (*w > IMAGE_MAX_WIDTH) {
+ *w = IMAGE_MAX_WIDTH;
+ }
@@ -8215,7 +8317,7 @@
+ if (pitches) pitches[1] = pitches[2] = tmp;
+ tmp *= (*h >> 1);
+ size += tmp;
-+ if(offsets) offsets[2] = size;
++ if (offsets) offsets[2] = size;
+ size += tmp;
+ break;
+ /* Packed Formats */
@@ -8230,376 +8332,452 @@
+ return size;
+}
+
-+
-+static void W100ClipVideo(BoxPtr dst,
-+ INT32 *x1,
-+ INT32 *x2,
-+ INT32 *y1,
-+ INT32 *y2,
-+ BoxPtr extents,
-+ INT32 width,
-+ INT32 height)
++static void W100ClipVideo(BoxPtr src, BoxPtr dst, BoxPtr extents,
++ short width, short height)
+{
+ INT32 vscale, hscale, delta;
-+ int diff;
++ INT32 diff, x1, x2, y1, y2;
+
-+ hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
-+ vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
++ hscale = ((src->x2 - src->x1) << 16) / (dst->x2 - dst->x1);
++ vscale = ((src->y2 - src->y1) << 16) / (dst->y2 - dst->y1);
+
-+ *x1 <<= 16; *x2 <<= 16;
-+ *y1 <<= 16; *y2 <<= 16;
++ x1 = src->x1 << 16;
++ x2 = src->x2 << 16;
++ y1 = src->y1 << 16;
++ y2 = src->y2 << 16;
+
+ diff = extents->x1 - dst->x1;
-+ if(diff > 0) {
-+ dst->x1 = extents->x1;
-+ *x1 += diff * hscale;
++ if (diff > 0) {
++ dst->x1 = extents->x1;
++ x1 += diff * hscale;
+ }
++
+ diff = dst->x2 - extents->x2;
-+ if(diff > 0) {
-+ dst->x2 = extents->x2;
-+ *x2 -= diff * hscale;
++ if (diff > 0) {
++ dst->x2 = extents->x2;
++ x2 -= diff * hscale;
+ }
++
+ diff = extents->y1 - dst->y1;
-+ if(diff > 0) {
-+ dst->y1 = extents->y1;
-+ *y1 += diff * vscale;
++ if (diff > 0) {
++ dst->y1 = extents->y1;
++ y1 += diff * vscale;
+ }
++
+ diff = dst->y2 - extents->y2;
-+ if(diff > 0) {
-+ dst->y2 = extents->y2;
-+ *y2 -= diff * vscale;
++ if (diff > 0) {
++ dst->y2 = extents->y2;
++ y2 -= diff * vscale;
+ }
+
-+ if(*x1 < 0) {
-+ diff = (- *x1 + hscale - 1)/ hscale;
-+ dst->x1 += diff;
-+ *x1 += diff * hscale;
++ if (x1 < 0) {
++ diff = (- x1 + hscale - 1) / hscale;
++ dst->x1 += diff;
++ x1 += diff * hscale;
+ }
-+ delta = *x2 - (width << 16);
-+ if(delta > 0) {
-+ diff = (delta + hscale - 1)/ hscale;
-+ dst->x2 -= diff;
-+ *x2 -= diff * hscale;
++
++ delta = x2 - (width << 16);
++ if (delta > 0) {
++ diff = (delta + hscale - 1) / hscale;
++ dst->x2 -= diff;
++ x2 -= diff * hscale;
+ }
-+ if(*y1 < 0) {
-+ diff = (- *y1 + vscale - 1)/ vscale;
-+ dst->y1 += diff;
-+ *y1 += diff * vscale;
++
++ if (y1 < 0) {
++ diff = (- y1 + vscale - 1) / vscale;
++ dst->y1 += diff;
++ y1 += diff * vscale;
+ }
-+ delta = *y2 - (height << 16);
-+ if(delta > 0) {
-+ diff = (delta + vscale - 1)/ vscale;
-+ dst->y2 -= diff;
-+ *y2 -= diff * vscale;
++ delta = y2 - (height << 16);
++ if (delta > 0) {
++ diff = (delta + vscale - 1) / vscale;
++ dst->y2 -= diff;
++ y2 -= diff * vscale;
+ }
-+}
++
++ src->x1 = x1 >> 16;
++ src->x2 = x2 >> 16;
++ src->y1 = y1 >> 16;
++ src->y2 = y2 >> 16;
++}
+
-+static int W100PutImage(KdScreenInfo *screen,
-+ DrawablePtr pDraw, /* Destination drawable */
-+ short src_x, short src_y, /* Source coordinates */
-+ short drw_x, short drw_y, /* Destination coordinates */
-+ short src_w, short src_h, /* Source rectangle to put */
-+ short drw_w, short drw_h, /* Destination size */
-+ int id, /* FOURCC id */
-+ unsigned char *buf, /* Source data */
-+ short width, /* Source width */
-+ short height, /* Source height */
-+ Bool sync, /* Sync before returning */
-+ RegionPtr clipBoxes,
-+ pointer data)
++static Bool W100SetOverlaySource(W100PortPrivPtr port,
++ unsigned char *buffer,
++ int id,
++ short src_x, short src_y,
++ short src_w, short src_h,
++ short width, short height,
++ short drw_x, short drw_y,
++ short drw_w, short drw_h,
++ RegionPtr clipBoxes)
+{
-+ ScreenPtr pScreen = screen->pScreen;
-+ KdScreenPriv(pScreen);
-+ W100CardInfo(pScreenPriv);
-+ W100ScreenInfo(pScreenPriv);
-+ W100PortPrivPtr pPortPriv = (W100PortPrivPtr)data;
-+ CARD32 baseAddr;
-+ int randr = w100c->hw_window.randr;
-+ int offWidth, offHeight;
-+ int ovlWidth, ovlHeight;
-+ int ovlX, ovlY;
-+ int dstX, dstY;
-+ int offSize;
-+ int ovlSize;
-+ int planes;
-+ int bpp;
-+ int i;
-+ INT32 x1, x2, y1, y2;
-+ BoxRec dstBox;
-+ int planeOffsets[3];
+
++ BoxRec srcBox, dstBox;
++ Bool changed = FALSE;
+
-+ DBG_IMAGEON(("W100PutImage(src(x:%d,y:%d,w:%d,h:%d),"
-+ "drw(x:%d,y:%d,w:%d,h:%d),"
-+ "width:%d,height:%d)\n",
-+ src_x,src_y,src_w,src_h,
-+ drw_x,drw_y,drw_w,drw_h,
-+ width, height));
-+
-+ /* Clip */
-+ x1 = src_x;
-+ x2 = src_x + src_w;
-+ y1 = src_y;
-+ y2 = src_y + src_h;
++ srcBox.x1 = src_x;
++ srcBox.x2 = src_x + src_w - 1;
++ srcBox.y1 = src_y;
++ srcBox.y2 = src_y + src_h - 1;
+
+ dstBox.x1 = drw_x;
-+ dstBox.x2 = drw_x + drw_w;
++ dstBox.x2 = drw_x + drw_w - 1;
+ dstBox.y1 = drw_y;
-+ dstBox.y2 = drw_y + drw_h;
++ dstBox.y2 = drw_y + drw_h - 1;
+
-+ W100ClipVideo(&dstBox, &x1, &x2, &y1, &y2,
-+ REGION_EXTENTS(pScreen, clipBoxes),
++ W100ClipVideo(&srcBox, &dstBox,
++ REGION_EXTENTS(pScreen, clipBoxes),
+ width, height);
+
-+ if ((x1 >= x2) || (y1 >= y2)) {
-+ return Success;
++ port->src.buffer = buffer;
++ port->ovl.changed = FALSE;
++
++ if (port->src.id != id) {
++ port->src.id = id;
++ changed = TRUE;
++ port->ovl.changed = TRUE;
++ }
++ if (port->src.box.x1 != srcBox.x1) {
++ port->src.box.x1 = srcBox.x1;
++ changed = TRUE;
++ }
++ if (port->src.box.x2 != srcBox.x2) {
++ port->src.box.x2 = srcBox.x2;
++ changed = TRUE;
++ }
++ if (port->src.box.y1 != srcBox.y1) {
++ port->src.box.y1 = srcBox.y1;
++ changed = TRUE;
++ }
++ if (port->src.box.y2 != srcBox.y2) {
++ port->src.box.y2 = srcBox.y2;
++ changed = TRUE;
++ }
++ if (port->src.width != width) {
++ port->src.width = width;
++ changed = TRUE;
++ }
++ if (port->src.height != height) {
++ port->src.height = height;
++ changed = TRUE;
+ }
+
-+ src_w = (x2 - x1) >> 16;
-+ src_h = (y2 - y1) >> 16;
-+ drw_w = dstBox.x2 - dstBox.x1;
-+ drw_h = dstBox.y2 - dstBox.y1;
-+ drw_x = dstBox.x1;
-+ drw_y = dstBox.y1;
-+ src_x = x1 >> 16;
-+ src_y = y1 >> 16;
-+
-+ /* Calculate dimensions for offscren and overlay surfaces */
-+ offWidth = src_w;
-+ offHeight = src_h;
++ if (port->dst.box.x1 != dstBox.x1) {
++ port->dst.box.x1 = dstBox.x1;
++ changed = TRUE;
++ }
++ if (port->dst.box.x2 != dstBox.x2) {
++ port->dst.box.x2 = dstBox.x2;
++ changed = TRUE;
++ }
++ if (port->dst.box.y1 != dstBox.y1) {
++ port->dst.box.y1 = dstBox.y1;
++ changed = TRUE;
++ }
++ if (port->dst.box.y2 != dstBox.y2) {
++ port->dst.box.y2 = dstBox.y2;
++ changed = TRUE;
++ }
+
-+ ovlX = W100MapToHWX(w100c, drw_x, drw_y, drw_w, drw_h);
-+ ovlY = W100MapToHWY(w100c, drw_x, drw_y, drw_w, drw_h);
++ if (changed) {
++ port->src.size = W100SurfaceSize(port,
++ srcBox.x2 - srcBox.x1 + 1,
++ srcBox.y2 - srcBox.y1 + 1);
++ }
++ port->changed = changed;
++ return changed;
++}
+
-+ for (i = 0; i < NUM_OVL_RESIZERS; i++) {
-+ CARD16 candidate_w = drw_w >> ovlResizers[i].xfactor;
-+ CARD16 candidate_h = drw_h >> ovlResizers[i].yfactor;
-+
-+ switch (randr & RR_Rotate_All) {
-+ case RR_Rotate_0:
-+ ovlWidth = W100_ALIGN(candidate_w, OVL_W_ALIGN);
-+ ovlHeight = W100_ALIGN(candidate_h, OVL_H_ALIGN);
-+ dstX = 0;
-+ dstY = 0;
-+ pPortPriv->videoHorExp = ovlResizers[i].xfactor;
-+ pPortPriv->videoVerExp = ovlResizers[i].yfactor;
-+ break;
-+ case RR_Rotate_180:
-+ ovlWidth = W100_ALIGN(candidate_w, OVL_W_ALIGN);
-+ ovlHeight = W100_ALIGN(candidate_h, OVL_H_ALIGN);
-+ dstX = ovlWidth - candidate_w;
-+ dstY = ovlHeight - candidate_h;
-+ pPortPriv->videoHorExp = ovlResizers[i].xfactor;
-+ pPortPriv->videoVerExp = ovlResizers[i].yfactor;
-+ break;
-+ case RR_Rotate_90:
-+ ovlWidth = W100_ALIGN(candidate_h, OVL_W_ALIGN);
-+ ovlHeight = W100_ALIGN(candidate_w, OVL_H_ALIGN);
-+ dstX = (ovlWidth - candidate_h) / 2;
-+ dstY = (ovlHeight - candidate_w) / 2;
-+ pPortPriv->videoHorExp = ovlResizers[i].yfactor;
-+ pPortPriv->videoVerExp = ovlResizers[i].xfactor;
-+ break;
-+ case RR_Rotate_270:
-+ ovlWidth = W100_ALIGN(candidate_h, OVL_W_ALIGN);
-+ ovlHeight = W100_ALIGN(candidate_w, OVL_H_ALIGN);
-+ dstX = 0;
-+ dstY = ovlHeight - candidate_w;
-+ pPortPriv->videoHorExp = ovlResizers[i].yfactor;
-+ pPortPriv->videoVerExp = ovlResizers[i].xfactor;
-+ break;
-+ }
+
-+ /* Calculate sizes for the surfaces */
-+ switch (id) {
-+ case FOURCC_YV12:
-+ case FOURCC_I420:
-+ offSize = (3 * offWidth * offHeight) / 2;
-+ ovlSize = (3 * ovlWidth * ovlHeight) / 2;
-+ planes = 3;
-+ planeOffsets[0] = 0;
-+ planeOffsets[1] = ovlWidth * ovlHeight;
-+ planeOffsets[2] = (5 * (ovlWidth * ovlHeight)) / 4;
-+ bpp = 8;
-+ break;
-+ case FOURCC_UYVY:
-+ case FOURCC_YUY2:
-+ offSize = offWidth * offHeight * 2;
-+ ovlSize = ovlWidth * ovlHeight * 2;
-+ planes = 1;
-+ planeOffsets[0] = 0;
-+ bpp = 16;
-+ break;
-+ }
-+ if (ovlSize <= pPortPriv->maxOverlaySize) {
-+ DBG_IMAGEON(("Using %dx%d overlay surface (%d bytes). "
-+ "Resizer(xfactor:%d,yfactor:%d)\n",
-+ ovlWidth, ovlHeight, ovlSize,
-+ ovlResizers[i].xfactor, ovlResizers[i].yfactor));
-+ drw_w = candidate_w;
-+ drw_h = candidate_h;
-+ break;
-+ }
++
++static int W100SetOverlaySurfaces(KdScreenInfo *screen,
++ short x, short y, short w, short h)
++{
++ W100ScreenInfo *w100s = screen->driver;
++ W100CardInfo(screen);
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
++
++ if (port->ovl.changed ||
++ (port->ovl.frame.x1 != x) ||
++ (port->ovl.frame.y1 != y) ||
++ (port->ovl.frame.x2 != (x + w - 1)) ||
++ (port->ovl.frame.y2 != (y + h - 1))) {
++
++ port->ovl.changed = TRUE;
++ port->ovl.frame.x1 = x;
++ port->ovl.frame.x2 = x + w - 1;
++ port->ovl.frame.y1 = y;
++ port->ovl.frame.y2 = y + h - 1;
++
++ W100MapToDevice(w100c, &port->dst.box, &port->ovl.box);
++ W100ChangeOrigin(&port->ovl.box,
++ port->ovl.frame.x1, port->ovl.frame.y1);
++ port->ovl.box.x2 >>= port->ovl.horExp;
++ port->ovl.box.y2 >>= port->ovl.verExp;
++ DBG_IMAGEON(("Translated ovl.box(x1:%d,y1:%d,x2:%d,y2:%d)\n",
++ port->ovl.box.x1, port->ovl.box.y1,
++ port->ovl.box.x2, port->ovl.box.y2));
+ }
+
-+ /* Reallocate the surfaces, if existing ones are not valid.
-+ * If overlay surface is not valid, dump both ones, to give
-+ * ovlSurface more chances to get internal memory
-+ */
-+ if (pPortPriv->ovlSurface && ovlSize != pPortPriv->ovlSize) {
-+ DBG_IMAGEON(("Freeing overlay and offscreen surfaces\n"));
-+ KdOffscreenFree(screen->pScreen, pPortPriv->ovlSurface);
-+ KdOffscreenFree(screen->pScreen, pPortPriv->offSurface);
-+ pPortPriv->ovlSurface = NULL;
-+ pPortPriv->offSurface = NULL;
-+ }
-+
-+ if (pPortPriv->offSurface && offSize != pPortPriv->offSize) {
-+ DBG_IMAGEON(("Freeing offscreen surface\n"));
-+ KdOffscreenFree(screen->pScreen, pPortPriv->offSurface);
-+ pPortPriv->offSurface = NULL;
-+ }
-+
-+ if (!pPortPriv->ovlSurface) {
-+ pPortPriv->ovlSurface = KdOffscreenAllocPrio(screen->pScreen,
-+ ovlSize, 0, TRUE,
-+ W100VideoSave,
-+ pPortPriv,
-+ KD_VIDMEM_MAXPRIO,
-+ KD_VIDMEM_MAXPRIO,
-+ TRUE);
-+ if (!pPortPriv->ovlSurface) {
-+ ErrorF("Using non internal memory to overlay. "
-+ "Expected bad performance\n");
-+ pPortPriv->ovlSurface = KdOffscreenAlloc(screen->pScreen,
-+ ovlSize, 0, TRUE,
-+ W100VideoSave,
-+ pPortPriv);
++ switch (port->src.id) {
++ case FOURCC_YV12:
++ case FOURCC_I420:
++ port->planes.size = 3;
++ port->planes.offset[0] = 0;
++ port->planes.offset[1] = w * h;
++ port->planes.offset[2] = (5 * (w * h)) / 4;
++ port->planes.bpp = 8;
++ break;
++ case FOURCC_UYVY:
++ case FOURCC_YUY2:
++ port->planes.size = 1;
++ port->planes.offset[0] = 0;
++ port->planes.bpp = 16;
++ break;
++ }
++
++ if (port->ovl.surface && port->ovl.size != port->ovl.surface->size) {
++ KdOffscreenFree(screen->pScreen, port->ovl.surface);
++ KdOffscreenFree(screen->pScreen, port->src.surface);
++ port->ovl.surface = NULL;
++ port->src.surface = NULL;
++ }
++ if (port->src.surface && port->src.size != port->src.surface->size) {
++ KdOffscreenFree(screen->pScreen, port->src.surface);
++ port->src.surface = NULL;
++ }
++
++ if (!port->ovl.surface) {
++ port->ovl.surface = KdOffscreenAllocPrio(screen->pScreen,
++ port->ovl.size, 0, TRUE,
++ W100VideoSave,
++ port,
++ KD_VIDMEM_MAXPRIO,
++ KD_VIDMEM_MAXPRIO,
++ TRUE);
++ if (!port->ovl.surface) {
++ ErrorF("Using external memory for overlay surface. "
++ "Expect bad performance\n");
++ port->ovl.surface = KdOffscreenAlloc(screen->pScreen,
++ port->ovl.size, 0, TRUE,
++ W100VideoSave,
++ port);
+ }
-+ if (!pPortPriv->ovlSurface) {
++ if (!port->ovl.surface) {
+ ErrorF("Unable to allocate %d bytes for overlay surface\n",
-+ ovlSize);
++ port->ovl.size);
+ return BadAlloc;
+ }
-+
-+ pPortPriv->ovlSize = ovlSize;
-+ W100ClearSurface(screen, pPortPriv->ovlSurface,
-+ 0, 0, (ovlWidth * bpp / 8),
-+ ovlWidth, ovlHeight, id);
-+ }
-+
-+ if (!pPortPriv->offSurface) {
-+ pPortPriv->offSurface = KdOffscreenAlloc(screen->pScreen,
-+ offSize, 0, TRUE,
-+ W100VideoSave,
-+ pPortPriv);
-+ if (!pPortPriv->offSurface) {
++
++ W100ClearSurface(screen, port->ovl.surface,
++ 0, 0,
++ (w * port->planes.bpp / 8),
++ w, h, port->src.id);
++ }
++ if (!port->src.surface) {
++ port->src.surface = KdOffscreenAlloc(screen->pScreen,
++ port->src.size, 0, TRUE,
++ W100VideoSave,
++ port);
++ if (!port->src.surface) {
+ ErrorF("Unable to allocate %d bytes for offscreen surface\n",
-+ offSize);
++ port->src.size);
+ return BadAlloc;
+ }
-+ pPortPriv->offSize = offSize;
+ }
+
-+ /* Copy the data into the offscreen surface */
-+ W100WaitIdle(w100c);
++ CARD32 baseAddr = (CARD32) W100_HOST2CARD(port->ovl.surface->vidmem->base +
++ port->ovl.surface->offset);
+
-+ switch (id) {
++
++ switch (port->src.id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
-+ W100HostPlanarData(screen, //screen
-+ id, //id
-+ buf, //src
-+ pPortPriv->offSurface, //dst
-+ width, //srcPitch
-+ height, //srcHeight
-+ offWidth, //dstPitch
-+ offHeight, //dstHeight
-+ src_x, //srcX
-+ src_y, //srcY
-+ 0, //dstX
-+ 0, //dstY
-+ src_w, //w
-+ src_h); //h
++ port->planes.yplane = baseAddr + port->planes.offset[0];
++ port->planes.uplane = baseAddr + port->planes.offset[1];
++ port->planes.vplane = baseAddr + port->planes.offset[2];
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
-+ W100HostPackedData(screen, //screen
-+ id, //id
-+ buf, //src
-+ pPortPriv->offSurface, //dst
-+ width << 1, //srcPitch
-+ offWidth << 1, //dstPitch
-+ src_x, //srcX
-+ src_y, //srcY
-+ 0, //dstX
-+ 0, //dstY
-+ src_w, //w
-+ src_h); //h
++ port->planes.yplane = baseAddr + port->planes.offset[0];
++ port->planes.uplane = 0;
++ port->planes.vplane = 0;
+ break;
+ }
+
-+ /* Update cliplist */
-+ if(!REGION_EQUAL(screen->pScreen, &pPortPriv->clip, clipBoxes)) {
-+ REGION_COPY(screen->pScreen, &pPortPriv->clip, clipBoxes);
-+ KXVPaintRegion(pDraw, &pPortPriv->clip, pPortPriv->colorKey);
++ return Success;
++}
++
++static int W100OvlSetup(KdScreenInfo *screen)
++{
++ W100ScreenInfo *w100s = screen->driver;
++ W100CardInfo(screen);
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
++ BoxRec ovlBox;
++ short x, y, w, h;
++ int i;
++
++ W100MapToDevice(w100c, &port->dst.box, &ovlBox);
++
++ x = ovlBox.x1 & ~7;
++ y = ovlBox.y1;
++
++ for (i = 0; i < NUM_OVL_RESIZERS; i++) {
++ w = (ovlBox.x2 - x + 1) >> ovlResizers[i].xfactor;
++ h = (ovlBox.y2 - y + 1) >> ovlResizers[i].yfactor;
++ DBG_IMAGEON(("Before aligning w=%d, h=%d\n", w, h));
++ w = W100_ALIGN(w, OVL_W_ALIGN);
++ h = W100_ALIGN(h, OVL_H_ALIGN);
++ DBG_IMAGEON(("Trying overlay surface (%d,%d,%d,%d)\n",
++ x, y, w, h));
++ port->ovl.size = W100SurfaceSize(port, w, h);
++ if (port->ovl.size <= port->ovl.maxSize) {
++ ErrorF("Using (x=%d,y=%d,w=%d,h=%d) overlay surface (%d bytes). "
++ "Resizer(xfactor:%d,yfactor:%d)\n",
++ x, y, w, h, port->ovl.size,
++ ovlResizers[i].xfactor, ovlResizers[i].yfactor);
++ port->ovl.horExp = ovlResizers[i].xfactor;
++ port->ovl.verExp = ovlResizers[i].yfactor;
++ return W100SetOverlaySurfaces(screen, x, y, w, h);
++ }
+ }
++ return BadAlloc;
++}
++
++static void W100OvlHostData(KdScreenInfo *screen)
++{
++ W100ScreenInfo *w100s = screen->driver;
++ W100CardInfo(screen);
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
+
-+ /* Calculate the incard offsets for the different planes */
-+ baseAddr = (CARD32) W100_HOST2CARD(pPortPriv->ovlSurface->vidmem->base +
-+ pPortPriv->ovlSurface->offset);
-+ switch (id) {
++ W100WaitIdle(w100c);
++ switch (port->src.id) {
+ case FOURCC_YV12:
+ case FOURCC_I420:
-+ pPortPriv->YPlaneOffset = baseAddr + planeOffsets[0];
-+ pPortPriv->UPlaneOffset = baseAddr + planeOffsets[1];
-+ pPortPriv->VPlaneOffset = baseAddr + planeOffsets[2];
++ W100HostPlanarData(screen);
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
-+ pPortPriv->YPlaneOffset = baseAddr + planeOffsets[0];
-+ pPortPriv->UPlaneOffset = 0;
-+ pPortPriv->VPlaneOffset = 0;
++ W100HostPackedData(screen);
++ break;
+ }
++}
+
-+ DBG_IMAGEON(("Offsets(Y:0x%08x,U:0x%08x,V:0x%08x)\n",
-+ pPortPriv->YPlaneOffset,
-+ pPortPriv->UPlaneOffset,
-+ pPortPriv->VPlaneOffset));
-+
-+
-+ /* Blit from offSurface to ovlSurface taking into account
-+ * the randr needed transformation
-+ */
-+ W100DisableDisplayUpdate(w100c);
-+ W100PlanarBlt(screen, planes, bpp, randr,
-+ pPortPriv->offSurface,
-+ src_w, offWidth * bpp / 8, src_h,
-+ pPortPriv->ovlSurface, planeOffsets,
-+ drw_w, ovlWidth * bpp / 8, drw_h,
-+ dstX, dstY);
-+ W100EnableDisplayUpdate(w100c);
++static void W100OvlBlt(KdScreenInfo *screen)
++{
++ W100ScreenInfo *w100s = screen->driver;
++ W100CardInfo(screen);
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
++ static int frame = 0;
++ int srcW = port->src.box.x2 - port->src.box.x1 + 1;
++ int srcH = port->src.box.y2 - port->src.box.y1 + 1;
++ int dstW = port->ovl.frame.x2 - port->ovl.frame.x1 + 1;
++ int dstH = port->ovl.frame.y2 - port->ovl.frame.y1 + 1;
++
++ DBG_IMAGEON(("ovl.box(x1:%d,y1:%d,x2:%d,y2:%d),"
++ "src.box(x1:%d,y1:%d,x2:%d,y2:%d),"
++ "dstW:%d, dstH:%d\n",
++ port->ovl.box.x1, port->ovl.box.y1,
++ port->ovl.box.x2, port->ovl.box.y2,
++ port->src.box.x1, port->src.box.y1,
++ port->src.box.x2, port->src.box.y2,
++ dstW, dstH));
++
++ W100PlanarBlt(screen, //KdScreenInfo* screen
++ port->planes.size, //int planes
++ port->planes.offset, //int planeOffsets[]
++ port->planes.bpp, //int bpp
++ w100c->hw_window.randr, //int randr
++ port->src.surface, //KdOffscrenArea *src
++ srcW, //int srcW
++ srcH, //int srcH
++ &port->src.box, //BoxPtr srcBox
++ port->ovl.surface, //KdOffscreenArea *dst
++ dstW, //int dstW
++ dstH, //int dstH
++ &port->ovl.box); //BoxPtr dstBox
++
++#if 0
++ if (++frame == 10) {
++ W100SaveSurface(port->src.surface->vidmem->base +
++ port->src.surface->offset,
++ port->src.surface->size,
++ "/media/card/kdrive/source.yuv");
++ W100SaveSurface(port->ovl.surface->vidmem->base +
++ port->ovl.surface->offset,
++ port->ovl.surface->size,
++ "/media/card/kdrive/ovl.yuv");
++ exit(1);
++ }
++#endif
++}
+
++static void W100OvlUpdate(KdScreenInfo *screen)
++{
++ W100ScreenInfo *w100s = screen->driver;
++ W100PortPrivPtr port = w100s->pAdaptor->pPortPrivates[0].ptr;
+
-+ if ((pPortPriv->ovlWidth != ovlWidth) ||
-+ (pPortPriv->ovlHeight != ovlHeight) ||
-+ (pPortPriv->ovlX != ovlX) ||
-+ (pPortPriv->ovlY != ovlY) ||
-+ (pPortPriv->id != id)) {
-+ pPortPriv->videoStatus &= ~W100_OVERLAY_CONFIGURED;
++ if (port->videoStatus & W100_OVERLAY_ON) {
+ W100OverlayDisable(screen);
+ }
-+ /* Enable overlay */
-+ pPortPriv->ovlWidth = ovlWidth;
-+ pPortPriv->ovlHeight = ovlHeight;
-+ pPortPriv->ovlX = ovlX;
-+ pPortPriv->ovlY = ovlY;
-+ pPortPriv->id = id;
++ port->videoStatus &= ~W100_OVERLAY_CONFIGURED;
++
+ W100OverlayEnable(screen);
++}
++
++static int W100PutImage(KdScreenInfo *screen,
++ DrawablePtr pDraw, /* Destination drawable */
++ short src_x, short src_y, /* Source coordinates */
++ short drw_x, short drw_y, /* Destination coordinates */
++ short src_w, short src_h, /* Source rectangle to put */
++ short drw_w, short drw_h, /* Destination size */
++ int id, /* FOURCC id */
++ unsigned char *buffer, /* Source data */
++ short width, /* Source width */
++ short height, /* Source height */
++ Bool sync, /* Sync before returning */
++ RegionPtr clipBoxes,
++ pointer data)
++{
++ ScreenPtr pScreen = screen->pScreen;
++ KdScreenPriv(pScreen);
++ W100CardInfo(pScreenPriv);
++ W100ScreenInfo(pScreenPriv);
++ W100PortPrivPtr port = (W100PortPrivPtr) data;
++ int errCode;
++
++ DBG_IMAGEON(("W100PutImage(src(x:%d,y:%d,w:%d,h:%d),"
++ "drw(x:%d,y:%d,w:%d,h:%d),"
++ "width:%d,height:%d), buffer:%p)\n",
++ src_x,src_y,src_w,src_h,
++ drw_x,drw_y,drw_w,drw_h,
++ width, height,
++ buffer));
++
++ if (W100SetOverlaySource(port, buffer, id,
++ src_x, src_y, src_w, src_h,
++ width, height,
++ drw_x, drw_y, drw_w, drw_h,
++ clipBoxes)) {
++ if ((errCode = W100OvlSetup(screen)) != Success) {
++ return errCode;
++ }
++ }
++ W100OvlHostData(screen);
++ /* Update cliplist */
++ if(!REGION_EQUAL(screen->pScreen, &port->clip, clipBoxes)) {
++ REGION_COPY(screen->pScreen, &port->clip, clipBoxes);
++ KXVPaintRegion(pDraw, &port->clip, port->ovl.colorKey);
++ }
+
++ W100OvlBlt(screen);
++
++ if (port->ovl.changed) {
++ W100OvlUpdate(screen);
++ }
+ return Success;
+}
-+
++
+static KdVideoAdaptorPtr
+W100SetupImageVideo(ScreenPtr pScreen)
+{
@@ -8607,7 +8785,7 @@
+ W100ScreenInfo(pScreenPriv);
+ W100CardInfo(pScreenPriv);
+ KdVideoAdaptorPtr adaptor;
-+ W100PortPrivPtr pPortPriv;
++ W100PortPrivPtr port;
+
+ adaptor = xcalloc(1, sizeof(KdVideoAdaptorRec)
+ + sizeof(W100PortPrivRec)
@@ -8626,9 +8804,9 @@
+ adaptor->nPorts = 1;
+ adaptor->pPortPrivates = (DevUnion*)(&adaptor[1]);
+
-+ pPortPriv = (W100PortPrivPtr)(&adaptor->pPortPrivates[1]);
++ port = (W100PortPrivPtr)(&adaptor->pPortPrivates[1]);
+
-+ adaptor->pPortPrivates[0].ptr = (pointer)(pPortPriv);
++ adaptor->pPortPrivates[0].ptr = (pointer)(port);
+
+ adaptor->nAttributes = NUM_ATTRIBUTES;
+ adaptor->pAttributes = Attributes;
@@ -8646,7 +8824,7 @@
+ adaptor->ReputImage = NULL;
+ adaptor->QueryImageAttributes = W100QueryImageAttributes;
+
-+ REGION_INIT(pScreen, &pPortPriv->clip, NullBox, 0);
++ REGION_INIT(pScreen, &port->clip, NullBox, 0);
+
+ w100s->pAdaptor = adaptor;
+
@@ -8654,9 +8832,9 @@
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvMaxOverlaySize = MAKE_ATOM("XV_MAXOVERLAYSIZE");
+
-+ pPortPriv->maxOverlaySize = OVL_MAX_SIZE;
-+ pPortPriv->colorKey = 0xff00;
-+ pPortPriv->brightness = W100GetBrightness(w100c);
++ port->ovl.maxSize = OVL_MAX_SIZE;
++ port->ovl.colorKey = 0xff00;
++ port->ovl.brightness = W100GetBrightness(w100c);
+ return adaptor;
+}
+
@@ -8711,14 +8889,14 @@
+ KdScreenPriv(pScreen);
+ W100ScreenInfo(pScreenPriv);
+ KdVideoAdaptorPtr adaptor = w100s->pAdaptor;
-+ W100PortPrivPtr pPortPriv;
++ W100PortPrivPtr port;
+ int i;
+
+ if (!adaptor)
+ return;
+
-+ pPortPriv = (W100PortPrivPtr)(&adaptor->pPortPrivates[0].ptr);
-+ REGION_UNINIT(pScreen, &pPortPriv->clip);
++ port = (W100PortPrivPtr)(&adaptor->pPortPrivates[0].ptr);
++ REGION_UNINIT(pScreen, &port->clip);
+
+ xfree(adaptor);
+ w100s->pAdaptor = NULL;
@@ -8726,7 +8904,7 @@
+
--- /dev/null
+++ xorg-server-X11R7.1-1.1.0.work/hw/kdrive/imageon/imageon_support.h
-@@ -0,0 +1,98 @@
+@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2007 Manuel Teira
+ *
@@ -8757,6 +8935,7 @@
+extern CARD8 W100SolidRop[16];
+extern CARD8 W100BltRop[16];
+
++/* Card control */
+void W100DisableDisplayUpdate(W100CardInfo *w100c);
+void W100EnableDisplayUpdate(W100CardInfo *w100c);
+void W100SetupGraphicEngine(W100CardInfo *w100c);
@@ -8764,8 +8943,13 @@
+void W100SetupGraphicWindow(W100CardInfo *w100c);
+void W100EnableGraphicWindow(W100CardInfo *w100c);
+void W100DisableGraphicWindow(W100CardInfo *w100c);
-+inline Bool W100WaitCmdFifoEntries(W100CardInfo *w100c, int entries);
++void W100VSync(W100CardInfo *w100c);
++
++/* Wait for card slots */
++__inline__ Bool W100WaitCmdFifoEntries(W100CardInfo *w100c, int entries);
+Bool W100WaitIdle(W100CardInfo *w100c);
++
++/* Set context of the current operation */
+void W100ResetContext(W100CardInfo *w100c);
+CARD32 W100ComputeSolidGmc(W100CardInfo *w100c, CARD8 alu);
+CARD32 W100ComputeCopyGmc(W100CardInfo *w100c, CARD8 alu);
@@ -8779,51 +8963,55 @@
+ CARD32 dstOffset, CARD8 bpp);
+Bool W100SetSourcePixmap(PixmapPtr pPix);
+Bool W100SetDestinationPixmap(PixmapPtr pPix);
-+int W100MapToHWX(W100CardInfo *w100c,
-+ int x, int y, int w, int h);
-+int W100MapToHWY(W100CardInfo *w100c,
-+ int x, int y, int w, int h);
-+int W100MapToHWW(W100CardInfo *w100c,
-+ int x, int y, int w, int h);
-+int W100MapToHWH(W100CardInfo *w100c,
-+ int x, int y, int w, int h);
-+CARD16 W100XformX(W100CardInfo *w100c, CARD16 x, CARD16 y, CARD16 w, CARD16 h);
-+CARD16 W100XformY(W100CardInfo *w100c, CARD16 x, CARD16 y, CARD16 w, CARD16 h);
-+CARD16 W100XformW(W100CardInfo *w100c, CARD16 x, CARD16 y, CARD16 w, CARD16 h);
-+CARD16 W100XformH(W100CardInfo *w100c, CARD16 x, CARD16 y, CARD16 w, CARD16 h);
++
++/* Scaler related functions */
+CARD8 W100GetScaler(CARD16 dstsize, CARD16 srcsize);
+CARD16 W100ApplyScaler(CARD16 srcsize, CARD8 scaler);
-+static void W100Blt(KdScreenInfo *screen, int randr, int bpp,
-+ CARD32 srcOffset, CARD16 srcW, CARD16 srcH, CARD16 srcPitch,
-+ CARD32 dstOffset, CARD16 dstPitch,
-+ CARD16 dstX, CARD16 dstY);
-+static void W100StretchBlt(KdScreenInfo *screen, int randr, int bpp,
-+ CARD32 srcOffset, CARD16 srcW, CARD16 srcH,
-+ CARD16 srcPitch,
-+ CARD32 dstOffset, CARD16 dstPitch,
-+ CARD16 dstX, CARD16 dstY,
-+ CARD8 xscaler, CARD8 yscaler);
++
++/* Blitting functions */
++void W100PlanarBlt(KdScreenInfo *screen, int planes, int planeOffsets[],
++ int bpp, int randr,
++ KdOffscreenArea *src, int srcW, int srcH, BoxPtr srcBox,
++ KdOffscreenArea *dst, int dstW, int dstH, BoxPtr dstBox);
+static void W100ScaledBlt(KdScreenInfo *screen, int randr, int bpp,
-+ CARD32 srcOffset, CARD16 srcW, CARD16 srcH,
-+ CARD16 srcPitch,
-+ CARD32 dstOffset, CARD16 dstPitch,
-+ CARD16 dstX, CARD16 dstY,
++ CARD32 srcOffset, CARD16 srcPitch, BoxPtr srcBox,
++ CARD32 dstOffset, CARD16 dstPitch, BoxPtr dstBox,
++ CARD8 xscaler, CARD8 yscaler);
++static void W100StretchBlt(KdScreenInfo *screen, int randr, int bpp,
++ CARD32 srcOffset, CARD16 srcPitch, BoxPtr srcBox,
++ CARD32 dstOffset, CARD16 dstPitch, BoxPtr dstBox,
+ CARD8 xscaler, CARD8 yscaler);
-+void W100PlanarBlt(KdScreenInfo *screen, int planes, int bpp, int randr,
-+ KdOffscreenArea *src, int srcW, int srcPitch, int srcH,
-+ KdOffscreenArea *dst, int planeOffsets[],
-+ int dstW, int dstPitch, int dstH,
-+ int dstX, int dstY);
++static void W100Blt(KdScreenInfo *screen, int randr, int bpp,
++ CARD32 srcOffset, CARD16 srcPitch, BoxPtr srcBox,
++ CARD32 dstOffset, CARD16 dstPitch, BoxPtr dstBox);
++
++/* Brightness functions */
+CARD8 W100GetBrightness(W100CardInfo *w100c);
+void W100SetBrightness(W100CardInfo *w100c, CARD8 value);
++
++
++/* Get and set mode and rotation info */
+int W100GetRotation(W100CardInfo *w100c);
+W100ModeSpec *W100GetModeSpec(W100CardInfo *w100c, W100Mode *mode);
+Bool W100GetFbMode(W100CardInfo *w100c, W100Mode *mode);
+Bool W100CheckFbMode(W100CardInfo *w100c, W100ModeSpec *modes);
+W100ModeSpec *W100GetBestMode(W100CardInfo *w100c, int width, int height);
-+void W100TransformTsLibCoordinates(long *x, long *y, void *closure);
++
++/* SysFS helpers */
+Bool W100SysFsGet(W100CardInfo *w100c, const char *path, char *value);
+Bool W100SysFsSet(W100CardInfo *w100c, const char *path, const char *value);
++
++/* Coordinate transformations */
++void W100TransformTsLibCoordinates(long *x, long *y, void *closure);
++void W100MapToDevice(W100CardInfo *w100c, BoxPtr src, BoxPtr dst);
++void W100MapFromDevice(W100CardInfo *w100c, BoxPtr src, BoxPtr dst);
++void W100ChangeOrigin(BoxPtr src, int x, int y);
++void W100TrajectoryOrigin(W100CardInfo *w100c, BoxPtr box, short *x, short *y);
++void W100ScaleBox(BoxPtr src, BoxPtr dst, int scale);
++void W100MoveTo(BoxPtr src, int x, int y);
++
++
++
+#endif
--- xorg-server-X11R7.1-1.1.0.work/hw/kdrive/linux/tslib.c~kdrive-imageon
+++ xorg-server-X11R7.1-1.1.0.work/hw/kdrive/linux/tslib.c