[PATCH 1/2] render: Add protocol support for floating-point transforms (Version 0.12)

Keith Packard keithp at keithp.com
Sun Aug 17 14:16:25 PDT 2014


This adds the protocol side support for the SetPictureTransformFloat,
which takes a matrix of 32-bit IEEE 754 single precision floating
point values in place of the 16.16 fixed point values used in the
SetPictureTransform request.

SetPictureTransform and SetPictureTransformFloat save both fixed and
double (to match pixman) versions of their arguments; a new boolean
value in the picture indicates whether the original data was float or
fixed, in case some implementation cares.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 render/picture.c    |  70 +++++++++++++++--
 render/picturestr.h |  14 +++-
 render/render.c     | 216 ++++++++++++++++++++++++++++++++++------------------
 3 files changed, 220 insertions(+), 80 deletions(-)

diff --git a/render/picture.c b/render/picture.c
index 58535d4..cb1afa3 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1299,6 +1299,30 @@ transformIsIdentity(PictTransform * t)
             (t->matrix[2][0] == 0) && (t->matrix[2][1] == 0));
 }
 
+static Bool
+transformFloatIsIdentity(PictTransformFloat * t)
+{
+    return ((t->m[0][0] == t->m[1][1]) &&
+            (t->m[0][0] == t->m[2][2]) &&
+            (t->m[0][0] != 0) &&
+            (t->m[0][1] == 0) &&
+            (t->m[0][2] == 0) &&
+            (t->m[1][0] == 0) &&
+            (t->m[1][2] == 0) &&
+            (t->m[2][0] == 0) && (t->m[2][1] == 0));
+}
+
+static Bool
+AllocPictureTransform(PicturePtr pPicture)
+{
+    if (!pPicture->transform) {
+        pPicture->transform = malloc(sizeof(PictTransform) + sizeof (PictTransformFloat));
+        if (!pPicture->transform)
+            return FALSE;
+    }
+    return TRUE;
+}
+
 int
 SetPictureTransform(PicturePtr pPicture, PictTransform * transform)
 {
@@ -1306,13 +1330,45 @@ SetPictureTransform(PicturePtr pPicture, PictTransform * transform)
         transform = 0;
 
     if (transform) {
-        if (!pPicture->transform) {
-            pPicture->transform =
-                (PictTransform *) malloc(sizeof(PictTransform));
-            if (!pPicture->transform)
-                return BadAlloc;
-        }
+        if (!AllocPictureTransform(pPicture))
+            return BadAlloc;
         *pPicture->transform = *transform;
+        pPicture->floatTransform = FALSE;
+        pixman_f_transform_from_pixman_transform(PictureTransformFloat(pPicture),
+                                                 pPicture->transform);
+    }
+    else {
+        free(pPicture->transform);
+        pPicture->transform = NULL;
+    }
+
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+    if (pPicture->pDrawable != NULL) {
+        int result;
+        PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+        result = (*ps->ChangePictureTransform) (pPicture, pPicture->transform);
+
+        return result;
+    }
+
+    return Success;
+}
+
+int
+SetPictureTransformFloat(PicturePtr pPicture, PictTransformFloat * transform)
+{
+    if (transform && transformFloatIsIdentity(transform))
+        transform = 0;
+
+    if (transform) {
+        if (!AllocPictureTransform(pPicture))
+            return BadAlloc;
+        *PictureTransformFloat(pPicture) = *transform;
+        pPicture->floatTransform = TRUE;
+        pixman_transform_from_pixman_f_transform(pPicture->transform,
+                                                 PictureTransformFloat(pPicture));
     }
     else {
         free(pPicture->transform);
@@ -1324,7 +1380,7 @@ SetPictureTransform(PicturePtr pPicture, PictTransform * transform)
         int result;
         PictureScreenPtr ps = GetPictureScreen(pPicture->pDrawable->pScreen);
 
-        result = (*ps->ChangePictureTransform) (pPicture, transform);
+        result = (*ps->ChangePictureTransform) (pPicture, pPicture->transform);
 
         return result;
     }
diff --git a/render/picturestr.h b/render/picturestr.h
index 1278f62..eaf5fb9 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -55,6 +55,7 @@ typedef struct _PictFormat {
 
 typedef struct pixman_vector PictVector, *PictVectorPtr;
 typedef struct pixman_transform PictTransform, *PictTransformPtr;
+typedef struct pixman_f_transform PictTransformFloat, *PictTransformFloatPtr;
 
 #define pict_f_vector pixman_f_vector
 #define pict_f_transform pixman_f_transform
@@ -136,8 +137,9 @@ typedef struct _Picture {
     unsigned int componentAlpha:1;
     unsigned int repeatType:2;
     unsigned int filter:3;
+    unsigned int floatTransform:1;
     unsigned int stateChanges:CPLastBit;
-    unsigned int unused:18 - CPLastBit;
+    unsigned int unused:17 - CPLastBit;
 
     PicturePtr pNext;           /* chain on same drawable */
 
@@ -160,6 +162,13 @@ typedef struct _Picture {
     int filter_nparams;
 } PictureRec;
 
+static inline PictTransformFloatPtr
+PictureTransformFloat(PicturePtr picture) {
+    if (picture->transform)
+        return (PictTransformFloatPtr) (picture->transform + 1);
+    return NULL;
+}
+
 typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id,
                                                  xFixed * params, int nparams,
                                                  int *width, int *height);
@@ -475,6 +484,9 @@ SetPictureClipRegion(PicturePtr pPicture,
 extern _X_EXPORT int
  SetPictureTransform(PicturePtr pPicture, PictTransform * transform);
 
+extern _X_EXPORT int
+SetPictureTransformFloat(PicturePtr pPicture, PictTransformFloat *transform);
+
 extern _X_EXPORT void
  ValidatePicture(PicturePtr pPicture);
 
diff --git a/render/render.c b/render/render.c
index 9ac4a98..23d15fd 100644
--- a/render/render.c
+++ b/render/render.c
@@ -90,6 +90,7 @@ static int ProcRenderCreateSolidFill(ClientPtr pClient);
 static int ProcRenderCreateLinearGradient(ClientPtr pClient);
 static int ProcRenderCreateRadialGradient(ClientPtr pClient);
 static int ProcRenderCreateConicalGradient(ClientPtr pClient);
+static int ProcRenderSetPictureTransformFloat(ClientPtr pClient);
 
 static int ProcRenderDispatch(ClientPtr pClient);
 
@@ -128,84 +129,91 @@ static int SProcRenderCreateSolidFill(ClientPtr pClient);
 static int SProcRenderCreateLinearGradient(ClientPtr pClient);
 static int SProcRenderCreateRadialGradient(ClientPtr pClient);
 static int SProcRenderCreateConicalGradient(ClientPtr pClient);
+static int SProcRenderSetPictureTransformFloat(ClientPtr pClient);
 
 static int SProcRenderDispatch(ClientPtr pClient);
 
 int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
-ProcRenderQueryVersion,
-        ProcRenderQueryPictFormats,
-        ProcRenderQueryPictIndexValues,
-        ProcRenderQueryDithers,
-        ProcRenderCreatePicture,
-        ProcRenderChangePicture,
-        ProcRenderSetPictureClipRectangles,
-        ProcRenderFreePicture,
-        ProcRenderComposite,
-        ProcRenderScale,
-        ProcRenderTrapezoids,
-        ProcRenderTriangles,
-        ProcRenderTriStrip,
-        ProcRenderTriFan,
-        ProcRenderColorTrapezoids,
-        ProcRenderColorTriangles,
-        ProcRenderTransform,
-        ProcRenderCreateGlyphSet,
-        ProcRenderReferenceGlyphSet,
-        ProcRenderFreeGlyphSet,
-        ProcRenderAddGlyphs,
-        ProcRenderAddGlyphsFromPicture,
-        ProcRenderFreeGlyphs,
-        ProcRenderCompositeGlyphs,
-        ProcRenderCompositeGlyphs,
-        ProcRenderCompositeGlyphs,
-        ProcRenderFillRectangles,
-        ProcRenderCreateCursor,
-        ProcRenderSetPictureTransform,
-        ProcRenderQueryFilters,
-        ProcRenderSetPictureFilter,
-        ProcRenderCreateAnimCursor,
-        ProcRenderAddTraps,
-        ProcRenderCreateSolidFill,
-        ProcRenderCreateLinearGradient,
-        ProcRenderCreateRadialGradient, ProcRenderCreateConicalGradient};
+    ProcRenderQueryVersion,
+    ProcRenderQueryPictFormats,
+    ProcRenderQueryPictIndexValues,
+    ProcRenderQueryDithers,
+    ProcRenderCreatePicture,
+    ProcRenderChangePicture,
+    ProcRenderSetPictureClipRectangles,
+    ProcRenderFreePicture,
+    ProcRenderComposite,
+    ProcRenderScale,
+    ProcRenderTrapezoids,
+    ProcRenderTriangles,
+    ProcRenderTriStrip,
+    ProcRenderTriFan,
+    ProcRenderColorTrapezoids,
+    ProcRenderColorTriangles,
+    ProcRenderTransform,
+    ProcRenderCreateGlyphSet,
+    ProcRenderReferenceGlyphSet,
+    ProcRenderFreeGlyphSet,
+    ProcRenderAddGlyphs,
+    ProcRenderAddGlyphsFromPicture,
+    ProcRenderFreeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderFillRectangles,
+    ProcRenderCreateCursor,
+    ProcRenderSetPictureTransform,
+    ProcRenderQueryFilters,
+    ProcRenderSetPictureFilter,
+    ProcRenderCreateAnimCursor,
+    ProcRenderAddTraps,
+    ProcRenderCreateSolidFill,
+    ProcRenderCreateLinearGradient,
+    ProcRenderCreateRadialGradient,
+    ProcRenderCreateConicalGradient,
+    ProcRenderSetPictureTransformFloat,
+};
 
 int (*SProcRenderVector[RenderNumberRequests]) (ClientPtr) = {
-SProcRenderQueryVersion,
-        SProcRenderQueryPictFormats,
-        SProcRenderQueryPictIndexValues,
-        SProcRenderQueryDithers,
-        SProcRenderCreatePicture,
-        SProcRenderChangePicture,
-        SProcRenderSetPictureClipRectangles,
-        SProcRenderFreePicture,
-        SProcRenderComposite,
-        SProcRenderScale,
-        SProcRenderTrapezoids,
-        SProcRenderTriangles,
-        SProcRenderTriStrip,
-        SProcRenderTriFan,
-        SProcRenderColorTrapezoids,
-        SProcRenderColorTriangles,
-        SProcRenderTransform,
-        SProcRenderCreateGlyphSet,
-        SProcRenderReferenceGlyphSet,
-        SProcRenderFreeGlyphSet,
-        SProcRenderAddGlyphs,
-        SProcRenderAddGlyphsFromPicture,
-        SProcRenderFreeGlyphs,
-        SProcRenderCompositeGlyphs,
-        SProcRenderCompositeGlyphs,
-        SProcRenderCompositeGlyphs,
-        SProcRenderFillRectangles,
-        SProcRenderCreateCursor,
-        SProcRenderSetPictureTransform,
-        SProcRenderQueryFilters,
-        SProcRenderSetPictureFilter,
-        SProcRenderCreateAnimCursor,
-        SProcRenderAddTraps,
-        SProcRenderCreateSolidFill,
-        SProcRenderCreateLinearGradient,
-        SProcRenderCreateRadialGradient, SProcRenderCreateConicalGradient};
+    SProcRenderQueryVersion,
+    SProcRenderQueryPictFormats,
+    SProcRenderQueryPictIndexValues,
+    SProcRenderQueryDithers,
+    SProcRenderCreatePicture,
+    SProcRenderChangePicture,
+    SProcRenderSetPictureClipRectangles,
+    SProcRenderFreePicture,
+    SProcRenderComposite,
+    SProcRenderScale,
+    SProcRenderTrapezoids,
+    SProcRenderTriangles,
+    SProcRenderTriStrip,
+    SProcRenderTriFan,
+    SProcRenderColorTrapezoids,
+    SProcRenderColorTriangles,
+    SProcRenderTransform,
+    SProcRenderCreateGlyphSet,
+    SProcRenderReferenceGlyphSet,
+    SProcRenderFreeGlyphSet,
+    SProcRenderAddGlyphs,
+    SProcRenderAddGlyphsFromPicture,
+    SProcRenderFreeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderFillRectangles,
+    SProcRenderCreateCursor,
+    SProcRenderSetPictureTransform,
+    SProcRenderQueryFilters,
+    SProcRenderSetPictureFilter,
+    SProcRenderCreateAnimCursor,
+    SProcRenderAddTraps,
+    SProcRenderCreateSolidFill,
+    SProcRenderCreateLinearGradient,
+    SProcRenderCreateRadialGradient,
+    SProcRenderCreateConicalGradient,
+    SProcRenderSetPictureTransformFloat,
+};
 
 int RenderErrBase;
 static DevPrivateKeyRec RenderClientPrivateKeyRec;
@@ -1981,6 +1989,25 @@ ProcRenderCreateConicalGradient(ClientPtr client)
 }
 
 static int
+ProcRenderSetPictureTransformFloat(ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformFloatReq);
+    PicturePtr pPicture;
+    PictTransformFloat t;
+    float *f;
+    double *d;
+    int i;
+
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformFloatReq);
+    VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess);
+    f = (float *) &stuff->transform;
+    d = &t.m[0][0];
+    for (i = 0; i < 9; i++)
+        d[i] = f[i];
+    return SetPictureTransformFloat(pPicture, &t);
+}
+
+static int
 ProcRenderDispatch(ClientPtr client)
 {
     REQUEST(xReq);
@@ -2554,6 +2581,26 @@ SProcRenderCreateConicalGradient(ClientPtr client)
 }
 
 static int
+SProcRenderSetPictureTransformFloat(ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformFloatReq);
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformFloatReq);
+
+    swaps(&stuff->length);
+    swapl(&stuff->picture);
+    swapl(&stuff->transform.matrix11);
+    swapl(&stuff->transform.matrix12);
+    swapl(&stuff->transform.matrix13);
+    swapl(&stuff->transform.matrix21);
+    swapl(&stuff->transform.matrix22);
+    swapl(&stuff->transform.matrix23);
+    swapl(&stuff->transform.matrix31);
+    swapl(&stuff->transform.matrix32);
+    swapl(&stuff->transform.matrix33);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
 SProcRenderDispatch(ClientPtr client)
 {
     REQUEST(xReq);
@@ -3256,6 +3303,28 @@ PanoramiXRenderCreateConicalGradient(ClientPtr client)
     return result;
 }
 
+static int
+PanoramiXRenderSetPictureTransformFloat(ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformFloatReq);
+    int result = Success, j;
+    PanoramiXRes *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformFloatReq);
+
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess);
+
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result =
+            (*PanoramiXSaveRenderVector[X_RenderSetPictureTransformFloat]) (client);
+        if (result != Success)
+            break;
+    }
+
+    return result;
+}
+
 void
 PanoramiXRenderInit(void)
 {
@@ -3300,6 +3369,9 @@ PanoramiXRenderInit(void)
         PanoramiXRenderCreateRadialGradient;
     ProcRenderVector[X_RenderCreateConicalGradient] =
         PanoramiXRenderCreateConicalGradient;
+
+    ProcRenderVector[X_RenderSetPictureTransformFloat] =
+        PanoramiXRenderSetPictureTransformFloat;
 }
 
 void
-- 
2.0.1



More information about the xorg-devel mailing list