diff options
Diffstat (limited to 'packages/xorg-xserver/xserver-kdrive')
-rw-r--r-- | packages/xorg-xserver/xserver-kdrive/kdrive-imageon.patch | 1700 |
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 |