diff options
author | Eric Anholt <eric@anholt.net> | 2007-01-30 16:34:50 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2007-01-30 16:34:50 -0800 |
commit | 4cd552e8f4851e029e43bf778cd8340f6c2c4881 (patch) | |
tree | 9a8a411ba11f4dcf6685dc64cce9a4415e0ea04a /src/i830_exa.c | |
parent | 6a628ae12b0568d656059891c5bca4415d8a735f (diff) |
Fix accelerated Render transformations.
Previously, we tried to use 2 points instead of 3 to describe the source
rectangles, which mostly just worked for scaling.
Diffstat (limited to 'src/i830_exa.c')
-rw-r--r-- | src/i830_exa.c | 137 |
1 files changed, 72 insertions, 65 deletions
diff --git a/src/i830_exa.c b/src/i830_exa.c index b976f548..b0d886b0 100644 --- a/src/i830_exa.c +++ b/src/i830_exa.c @@ -282,69 +282,76 @@ I830EXADoneCopy(PixmapPtr pDstPixmap) #endif } +#define xFixedToFloat(val) \ + ((float)xFixedToInt(val) + ((float)xFixedFrac(val) / 65536.0)) + +/** + * Returns the floating-point coordinates transformed by the given transform. + * + * transform may be null. + */ +void +i830_get_transformed_coordinates(int x, int y, PictTransformPtr transform, + float *x_out, float *y_out) +{ + if (transform == NULL) { + *x_out = x; + *y_out = y; + } else { + PictVector v; + + v.vector[0] = IntToxFixed(x); + v.vector[1] = IntToxFixed(y); + v.vector[2] = xFixed1; + PictureTransformPoint(transform, &v); + *x_out = xFixedToFloat(v.vector[0]); + *y_out = xFixedToFloat(v.vector[1]); + } +} + +/** + * Do a single rectangle composite operation. + * + * This function is shared between i830 and i915 generation code. + */ static void IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h) { ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - int srcXend, srcYend, maskXend, maskYend; - PictVector v; - int pMask = 1; - - DPRINTF(PFX, "Composite: srcX %d, srcY %d\n\t maskX %d, maskY %d\n\t" - "dstX %d, dstY %d\n\twidth %d, height %d\n\t" - "src_scale_x %f, src_scale_y %f, " - "mask_scale_x %f, mask_scale_y %f\n", - srcX, srcY, maskX, maskY, dstX, dstY, w, h, - pI830->scale_units[0][0], pI830->scale_units[0][1], - pI830->scale_units[1][0], pI830->scale_units[1][1]); + Bool has_mask; + float src_x[3], src_y[3], mask_x[3], mask_y[3]; + + i830_get_transformed_coordinates(srcX, srcY, + pI830->transform[0], + &src_x[0], &src_y[0]); + i830_get_transformed_coordinates(srcX, srcY + h, + pI830->transform[0], + &src_x[1], &src_y[1]); + i830_get_transformed_coordinates(srcX + w, srcY + h, + pI830->transform[0], + &src_x[2], &src_y[2]); if (pI830->scale_units[1][0] == -1 || pI830->scale_units[1][1] == -1) { - pMask = 0; - } - - srcXend = srcX + w; - srcYend = srcY + h; - maskXend = maskX + w; - maskYend = maskY + h; - if (pI830->transform[0] != NULL) { - v.vector[0] = IntToxFixed(srcX); - v.vector[1] = IntToxFixed(srcY); - v.vector[2] = xFixed1; - PictureTransformPoint(pI830->transform[0], &v); - srcX = xFixedToInt(v.vector[0]); - srcY = xFixedToInt(v.vector[1]); - v.vector[0] = IntToxFixed(srcXend); - v.vector[1] = IntToxFixed(srcYend); - v.vector[2] = xFixed1; - PictureTransformPoint(pI830->transform[0], &v); - srcXend = xFixedToInt(v.vector[0]); - srcYend = xFixedToInt(v.vector[1]); - } - if (pI830->transform[1] != NULL) { - v.vector[0] = IntToxFixed(maskX); - v.vector[1] = IntToxFixed(maskY); - v.vector[2] = xFixed1; - PictureTransformPoint(pI830->transform[1], &v); - maskX = xFixedToInt(v.vector[0]); - maskY = xFixedToInt(v.vector[1]); - v.vector[0] = IntToxFixed(maskXend); - v.vector[1] = IntToxFixed(maskYend); - v.vector[2] = xFixed1; - PictureTransformPoint(pI830->transform[1], &v); - maskXend = xFixedToInt(v.vector[0]); - maskYend = xFixedToInt(v.vector[1]); + has_mask = FALSE; + } else { + has_mask = TRUE; + i830_get_transformed_coordinates(maskX, maskY, + pI830->transform[1], + &mask_x[0], &mask_y[0]); + i830_get_transformed_coordinates(maskX, maskY + h, + pI830->transform[1], + &mask_x[1], &mask_y[1]); + i830_get_transformed_coordinates(maskX + w, maskY + h, + pI830->transform[1], + &mask_x[2], &mask_y[2]); } - DPRINTF(PFX, "After transform: srcX %d, srcY %d,srcXend %d, srcYend %d\n\t" - "maskX %d, maskY %d, maskXend %d, maskYend %d\n\t" - "dstX %d, dstY %d\n", srcX, srcY, srcXend, srcYend, - maskX, maskY, maskXend, maskYend, dstX, dstY); { int vertex_count; - if (pMask) + if (has_mask) vertex_count = 3*6; else vertex_count = 3*4; @@ -361,29 +368,29 @@ IntelEXAComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, OUT_RING_F(dstX); OUT_RING_F(dstY); - OUT_RING_F(srcX / pI830->scale_units[0][0]); - OUT_RING_F(srcY / pI830->scale_units[0][1]); - if (pMask) { - OUT_RING_F(maskX / pI830->scale_units[1][0]); - OUT_RING_F(maskY / pI830->scale_units[1][1]); + OUT_RING_F(src_x[0] / pI830->scale_units[0][0]); + OUT_RING_F(src_y[0] / pI830->scale_units[0][1]); + if (has_mask) { + OUT_RING_F(mask_x[0] / pI830->scale_units[1][0]); + OUT_RING_F(mask_y[0] / pI830->scale_units[1][1]); } OUT_RING_F(dstX); OUT_RING_F(dstY + h); - OUT_RING_F(srcX / pI830->scale_units[0][0]); - OUT_RING_F(srcYend / pI830->scale_units[0][1]); - if (pMask) { - OUT_RING_F(maskX / pI830->scale_units[1][0]); - OUT_RING_F(maskYend / pI830->scale_units[1][1]); + OUT_RING_F(src_x[1] / pI830->scale_units[0][0]); + OUT_RING_F(src_y[1] / pI830->scale_units[0][1]); + if (has_mask) { + OUT_RING_F(mask_x[1] / pI830->scale_units[1][0]); + OUT_RING_F(mask_y[1] / pI830->scale_units[1][1]); } OUT_RING_F(dstX + w); OUT_RING_F(dstY + h); - OUT_RING_F(srcXend / pI830->scale_units[0][0]); - OUT_RING_F(srcYend / pI830->scale_units[0][1]); - if (pMask) { - OUT_RING_F(maskXend / pI830->scale_units[1][0]); - OUT_RING_F(maskYend / pI830->scale_units[1][1]); + OUT_RING_F(src_x[2] / pI830->scale_units[0][0]); + OUT_RING_F(src_y[2] / pI830->scale_units[0][1]); + if (has_mask) { + OUT_RING_F(mask_x[2] / pI830->scale_units[1][0]); + OUT_RING_F(mask_y[2] / pI830->scale_units[1][1]); } ADVANCE_LP_RING(); } |