xserver: Branch 'transform-proposal' - 2 commits

Keith Packard keithp at kemper.freedesktop.org
Mon Mar 17 23:05:10 PDT 2008


 randr/rrcrtc.c      |    5 +--
 render/matrix.c     |   80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 render/picturestr.h |    3 +
 3 files changed, 85 insertions(+), 3 deletions(-)

New commits:
commit 4184a2db90045c10d56faa390042ebf062a285fa
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Mar 17 23:04:49 2008 -0700

    Compute matrix inversion instead of using wire version in RRCrtcTransformSet
    
    It doesn't make sense to have the client invert this matrix when the server
    can do so reasonably efficiently. This avoids weird fixed point rounding
    errors when testing the transform against its inverse. Now to fix the
    protocol.

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 9032b61..a3e2503 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -608,8 +608,6 @@ RRCrtcTransformSet (RRCrtcPtr		crtc,
     PictFilterPtr   filter = NULL;
     int		    width = 0, height = 0;
 
-    if (!PictureTransformIsInverse (transform, inverse))
-	return BadMatch;
     if (filter_len)
     {
 	filter = PictureFindFilter (crtc->pScreen,
@@ -1220,7 +1218,8 @@ ProcRRSetCrtcTransform (ClientPtr client)
 	return RRErrorBase + BadRRCrtc;
 
     PictTransform_from_xRenderTransform (&transform, &stuff->transform);
-    PictTransform_from_xRenderTransform (&inverse, &stuff->inverse);
+    if (!PictureTransformInvert (&inverse, &transform))
+	return BadMatch;
 
     filter = (char *) (stuff + 1);
     nbytes = stuff->nbytesFilter;
commit 47dcd54077b40889f604ac3ed491e2558a4587a5
Author: Keith Packard <keithp at keithp.com>
Date:   Mon Mar 17 23:03:56 2008 -0700

    Add matrix inversion function (uses doubles)
    
    The obvious matrix inversion function, coded using doubles to avoid fiddling
    with fixed point precision adventures.

diff --git a/render/matrix.c b/render/matrix.c
index a976304..6e50205 100644
--- a/render/matrix.c
+++ b/render/matrix.c
@@ -262,6 +262,86 @@ PictureTransformBounds (BoxPtr b, PictTransformPtr matrix)
     }
 }
 
+static const int	a[3] = { 3, 3, 2 };
+static const int	b[3] = { 2, 1, 1 };
+
+static void
+to_doubles (double m[3][3], const PictTransformPtr t)
+{
+    int	i, j;
+
+    for (j = 0; j < 3; j++)
+	for (i = 0; i < 3; i++)
+	    m[j][i] = pixman_fixed_to_double (t->matrix[j][i]);
+}
+
+static Bool
+from_doubles (PictTransformPtr t, double m[3][3])
+{
+    int	i, j;
+
+    for (j = 0; j < 3; j++)
+	for (i = 0; i < 3; i++)
+	{
+	    double  d = m[j][i];
+	    if (d < -32767.0 || d > 32767.0)
+		return FALSE;
+	    t->matrix[j][i] = pixman_double_to_fixed (d);
+	}
+    return TRUE;
+}
+
+static Bool
+invert (double r[3][3], double m[3][3])
+{
+    double  det, norm;
+    int	    i, j;
+    static int	a[3] = { 2, 2, 1 };
+    static int	b[3] = { 1, 0, 0 };
+
+    det = 0;
+    for (i = 0; i < 3; i++) {
+	double	p;
+	int	ai = a[i];
+	int	bi = b[i];
+	p = m[i][0] * (m[ai][2] * m[bi][1] - m[ai][1] * m[bi][2]);
+	if (i == 1)
+	    p = -p;
+	det += p;
+    }
+    if (det == 0)
+	return FALSE;
+    det = 1/det;
+    for (j = 0; j < 3; j++) {
+	for (i = 0; i < 3; i++) {
+	    double  p;
+	    int	    ai = a[i];
+	    int	    aj = a[j];
+	    int	    bi = b[i];
+	    int	    bj = b[j];
+
+	    p = m[ai][aj] * m[bi][bj] - m[ai][bj] * m[bi][aj];
+	    if (((i + j) & 1) != 0)
+		p = -p;
+	    r[j][i] = det * p;
+	}
+    }
+    return TRUE;
+}
+
+_X_EXPORT Bool
+PictureTransformInvert (PictTransformPtr dst, const PictTransformPtr src)
+{
+    double  m[3][3], r[3][3];
+
+    to_doubles (m, src);
+    if (!invert (r, m))
+	return FALSE;
+    if (!from_doubles (dst, r))
+	return FALSE;
+    return TRUE;
+}
+
 static Bool
 within_epsilon (xFixed a, xFixed b, xFixed epsilon)
 {
diff --git a/render/picturestr.h b/render/picturestr.h
index 4a07070..5db9a04 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -723,6 +723,9 @@ void
 PictureTransformBounds (BoxPtr b, PictTransformPtr matrix);
 
 Bool
+PictureTransformInvert (PictTransformPtr dst, const PictTransformPtr src);
+
+Bool
 PictureTransformIsIdentity(PictTransform *t);
 
 Bool


More information about the xorg-commit mailing list