Track curent transform down in the mode setting code so that it may be set
separately from RandR.
---
 hw/xfree86/modes/xf86Crtc.c    |   56 ++++++++++++++++++++++++++++-----------
 hw/xfree86/modes/xf86Crtc.h    |   11 +++++++-
 hw/xfree86/modes/xf86RandR12.c |   36 +++++++++++++++++--------
 hw/xfree86/modes/xf86RandR12.h |    2 +-
 hw/xfree86/modes/xf86Rename.h  |    1 +
 hw/xfree86/modes/xf86Rotate.c  |   50 +++++++++++++++++++++++++++--------
 randr/randrstr.h               |    4 +-
 randr/rrcrtc.c                 |   56 ++++++++++++++++++++++++---------------
 8 files changed, 150 insertions(+), 66 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index f33a228..e3a852e 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -237,8 +237,8 @@ xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
  * Sets the given video mode on the given crtc
  */
 _X_EXPORT Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
-                int x, int y)
+xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation 
rotation,
+                         RRTransformPtr transform, int x, int y)
 {
     ScrnInfoPtr                scrn = crtc->scrn;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -249,6 +249,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation,
     DisplayModeRec     saved_mode;
     int                        saved_x, saved_y;
     Rotation           saved_rotation;
+    RRTransformRec     saved_transform;
+    Bool               saved_transform_present;
 
     if (crtc->funcs->set_mode_major)
        return crtc->funcs->set_mode_major(crtc, mode, rotation, x, y);
@@ -269,6 +271,9 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation,
     saved_x = crtc->x;
     saved_y = crtc->y;
     saved_rotation = crtc->rotation;
+    saved_transform = crtc->transform;
+    saved_transform_present = crtc->transformPresent;
+
     /* Update crtc values up front so the driver can rely on them for mode
      * setting.
      */
@@ -276,6 +281,11 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation,
     crtc->x = x;
     crtc->y = y;
     crtc->rotation = rotation;
+    if (transform) {
+       crtc->transform = *transform;
+       crtc->transformPresent = TRUE;
+    } else
+       crtc->transformPresent = FALSE;
 
     /* Shift offsets that move us out of virtual size */
     if (x + mode->HDisplay > xf86_config->maxWidth ||
@@ -322,9 +332,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation,
        goto done;
     }
 
-    if (!xf86CrtcRotate (crtc, mode, rotation)) {
+    if (!xf86CrtcRotate (crtc))
        goto done;
-    }
 
     /* Prepare the outputs and CRTCs before setting the mode. */
     for (i = 0; i < xf86_config->num_output; i++) {
@@ -356,17 +365,11 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation,
     {
        xf86OutputPtr output = xf86_config->output[i];
        if (output->crtc == crtc)
-       {
            output->funcs->commit(output);
-#ifdef RANDR_12_INTERFACE
-           if (output->randr_output)
-               RRPostPendingProperties (output->randr_output);
-#endif
-       }
     }
 #ifdef RANDR_12_INTERFACE
     if (crtc->randr_crtc)
-       RRCrtcPostPendingTransform (crtc->randr_crtc);
+       RRCrtcSetTransform (crtc->randr_crtc, transform);
 #endif
 
     /* XXX free adjustedmode */
@@ -380,6 +383,8 @@ done:
        crtc->y = saved_y;
        crtc->rotation = saved_rotation;
        crtc->mode = saved_mode;
+       crtc->transform = saved_transform;
+       crtc->transformPresent = saved_transform_present;
     }
 
     if (didLock)
@@ -388,6 +393,17 @@ done:
     return ret;
 }
 
+/**
+ * Sets the given video mode on the given crtc, but without providing
+ * a transform
+ */
+_X_EXPORT Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+                int x, int y)
+{
+    return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
+}
+
 /*
  * Output functions
  */
@@ -740,12 +756,12 @@ xf86CrtcScreenInit (ScreenPtr screen)
        xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 |
                                 RR_Rotate_180 | RR_Rotate_270 |
                                 RR_Reflect_X | RR_Reflect_Y);
-       xf86RandR12SetTransform (screen, TRUE);
+       xf86RandR12SetTransformSupport (screen, TRUE);
     }
     else
     {
        xf86RandR12SetRotations (screen, RR_Rotate_0);
-       xf86RandR12SetTransform (screen, FALSE);
+       xf86RandR12SetTransformSupport (screen, FALSE);
     }
     
     /* Wrap CreateScreenResources so we can initialize the RandR code */
@@ -2200,6 +2216,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
            crtc->desiredRotation = output->initial_rotation;
            crtc->desiredX = output->initial_x;
            crtc->desiredY = output->initial_y;
+           crtc->desiredTransformPresent = FALSE;
            crtc->enabled = TRUE;
            crtc->x = output->initial_x;
            crtc->y = output->initial_y;
@@ -2331,6 +2348,7 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
        xf86CrtcPtr     crtc = config->crtc[c];
        xf86OutputPtr   output = NULL;
        int             o;
+       RRTransformPtr  transform;
 
        /* Skip disabled CRTCs */
        if (!crtc->enabled)
@@ -2361,12 +2379,17 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
                return FALSE;
            crtc->desiredMode = *mode;
            crtc->desiredRotation = RR_Rotate_0;
+           crtc->desiredTransformPresent = FALSE;
            crtc->desiredX = 0;
            crtc->desiredY = 0;
        }
 
-       if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
-                             crtc->desiredX, crtc->desiredY))
+       if (crtc->desiredTransformPresent)
+           transform = &crtc->desiredTransform;
+       else
+           transform = NULL;
+       if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, 
crtc->desiredRotation,
+                                      transform, crtc->desiredX, 
crtc->desiredY))
            return FALSE;
     }
 
@@ -2495,12 +2518,13 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr 
desired, Rotation rotation)
            crtc->enabled = FALSE;
            continue;
        }
-       if (!xf86CrtcSetMode (crtc, crtc_mode, rotation, 0, 0))
+       if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0))
            ok = FALSE;
        else
        {
            crtc->desiredMode = *crtc_mode;
            crtc->desiredRotation = rotation;
+           crtc->desiredTransformPresent = FALSE;
            crtc->desiredX = 0;
            crtc->desiredY = 0;
        }
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 026ec78..4b6f7d2 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -313,6 +313,10 @@ struct _xf86Crtc {
     int                    filter_width;
     int                    filter_height;
     Bool           transform_in_use;
+    RRTransformRec  transform;
+    Bool           transformPresent;
+    RRTransformRec  desiredTransform;
+    Bool           desiredTransformPresent;
     /**
      * Bounding box in screen space
      */
@@ -665,6 +669,11 @@ xf86CrtcDestroy (xf86CrtcPtr               crtc);
 /**
  * Sets the given video mode on the given crtc
  */
+
+Bool
+xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation 
rotation,
+                         RRTransformPtr transform, int x, int y);
+
 Bool
 xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
                 int x, int y);
@@ -673,7 +682,7 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation,
  * Assign crtc rotation during mode set
  */
 Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
+xf86CrtcRotate (xf86CrtcPtr crtc);
 
 /*
  * free shadow memory allocated for all crtcs
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index f247a88..49add63 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -569,7 +569,7 @@ xf86RandR12SetRotations (ScreenPtr pScreen, Rotation 
rotations)
 }
 
 _X_EXPORT void
-xf86RandR12SetTransform (ScreenPtr pScreen, Bool transforms)
+xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
 {
     XF86RandRInfoPtr   randrp;
 #if RANDR_13_INTERFACE
@@ -588,7 +588,7 @@ xf86RandR12SetTransform (ScreenPtr pScreen, Bool transforms)
     for (c = 0; c < config->num_crtc; c++) {
        xf86CrtcPtr    crtc = config->crtc[c];
 
-       RRCrtcSetTransform (crtc->randr_crtc, transforms);
+       RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
     }
 #endif
 }
@@ -751,18 +751,19 @@ xf86RandRModeConvert (ScrnInfoPtr scrn,
 }
 
 static Bool
-xf86RandR12CrtcSet (ScreenPtr  pScreen,
-                 RRCrtcPtr     randr_crtc,
-                 RRModePtr     randr_mode,
-                 int           x,
-                 int           y,
-                 Rotation      rotation,
-                 int           num_randr_outputs,
-                 RROutputPtr   *randr_outputs)
+xf86RandR12CrtcSet (ScreenPtr      pScreen,
+                   RRCrtcPtr       randr_crtc,
+                   RRModePtr       randr_mode,
+                   int             x,
+                   int             y,
+                   Rotation        rotation,
+                   int             num_randr_outputs,
+                   RROutputPtr     *randr_outputs)
 {
     ScrnInfoPtr                pScrn = xf86Screens[pScreen->myNum];
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
     xf86CrtcPtr                crtc = randr_crtc->devPrivate;
+    RRTransformPtr     transform;
     Bool               changed = FALSE;
     int                        o, ro;
     xf86CrtcPtr                *save_crtcs;
@@ -780,7 +781,11 @@ xf86RandR12CrtcSet (ScreenPtr      pScreen,
     if (rotation != crtc->rotation)
        changed = TRUE;
 
-    if (RRCrtcPendingTransform (randr_crtc))
+    transform = RRCrtcGetTransform (randr_crtc);
+    if ((transform != NULL) != crtc->transformPresent)
+       changed = TRUE;
+    else if (transform && memcmp (&transform->transform, 
&crtc->transform.transform,
+                                 sizeof (transform->transform)) != 0)
        changed = TRUE;
 
     if (x != crtc->x || y != crtc->y)
@@ -820,9 +825,10 @@ xf86RandR12CrtcSet (ScreenPtr      pScreen,
        if (randr_mode)
        {
            DisplayModeRec  mode;
+           RRTransformPtr  transform = RRCrtcGetTransform (randr_crtc);
 
            xf86RandRModeConvert (pScrn, randr_mode, &mode);
-           if (!xf86CrtcSetMode (crtc, &mode, rotation, x, y))
+           if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, 
y))
            {
                crtc->enabled = save_enabled;
                for (o = 0; o < config->num_output; o++)
@@ -838,6 +844,12 @@ xf86RandR12CrtcSet (ScreenPtr      pScreen,
             */
            crtc->desiredMode = mode;
            crtc->desiredRotation = rotation;
+           if (transform) {
+               crtc->desiredTransform = *transform;
+               crtc->desiredTransformPresent = TRUE;
+           } else
+               crtc->desiredTransformPresent = FALSE;
+
            crtc->desiredX = x;
            crtc->desiredY = y;
        }
diff --git a/hw/xfree86/modes/xf86RandR12.h b/hw/xfree86/modes/xf86RandR12.h
index c361b47..17a2dcc 100644
--- a/hw/xfree86/modes/xf86RandR12.h
+++ b/hw/xfree86/modes/xf86RandR12.h
@@ -31,7 +31,7 @@
 Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen);
 Bool xf86RandR12Init(ScreenPtr pScreen);
 void xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotation);
-void xf86RandR12SetTransform (ScreenPtr pScreen, Bool transforms);
+void xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms);
 Bool xf86RandR12SetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
                        RRScreenSizePtr pSize);
 Rotation xf86RandR12GetRotation(ScreenPtr pScreen);
diff --git a/hw/xfree86/modes/xf86Rename.h b/hw/xfree86/modes/xf86Rename.h
index b8c1d70..e3418ca 100644
--- a/hw/xfree86/modes/xf86Rename.h
+++ b/hw/xfree86/modes/xf86Rename.h
@@ -38,6 +38,7 @@
 #define xf86CrtcInUse XF86NAME(xf86CrtcInUse)
 #define xf86CrtcRotate XF86NAME(xf86CrtcRotate)
 #define xf86CrtcScreenInit XF86NAME(xf86CrtcScreenInit)
+#define xf86CrtcSetModeTransform XF86NAME(xf86CrtcSetModeTransform)
 #define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
 #define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
 #define xf86CVTMode XF86NAME(xf86CVTMode)
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index efbacec..7d35c34 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -349,8 +349,35 @@ xf86RotateCloseScreen (ScreenPtr screen)
        xf86RotateDestroy (xf86_config->crtc[c]);
 }
 
+static Bool
+xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb)
+{
+    ScrnInfoPtr                pScrn = crtc->scrn;
+    /* if this is called during ScreenInit() we don't have pScrn->pScreen yet 
*/
+    ScreenPtr          pScreen = screenInfo.screens[pScrn->scrnIndex];
+    BoxRec             b;
+
+    if (!pScreen)
+       return TRUE;
+    b.x1 = 0;
+    b.y1 = 0;
+    b.x2 = crtc->mode.HDisplay;
+    b.y2 = crtc->mode.VDisplay;
+    if (crtc_to_fb)
+       pict_f_transform_bounds (crtc_to_fb, &b);
+    else {
+       b.x1 += crtc->x;
+       b.y1 += crtc->y;
+       b.x2 += crtc->x;
+       b.y2 += crtc->y;
+    }
+
+    return (0 <= b.x1 && b.x2 <= pScreen->width &&
+           0 <= b.y1 && b.y2 <= pScreen->height);
+}
+
 _X_EXPORT Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+xf86CrtcRotate (xf86CrtcPtr crtc)
 {
     ScrnInfoPtr                pScrn = crtc->scrn;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -364,20 +391,19 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation)
     int                        new_width = 0;
     int                        new_height = 0;
     RRTransformPtr     transform = NULL;
-    
-#ifdef RANDR_12_INTERFACE
-    if (crtc->randr_crtc)
-       transform = RRCrtcGetTransform (crtc->randr_crtc);
-#endif
-    if (!transform ||
-       !RRComputeTransform (crtc->x, crtc->y,
+
+    if (crtc->transformPresent)
+       transform = &crtc->transform;
+
+    if (!RRComputeTransform (crtc->x, crtc->y,
                             crtc->mode.HDisplay, crtc->mode.VDisplay,
-                            rotation,
+                            crtc->rotation,
                             transform,
 
                             &crtc_to_fb,
                             &f_crtc_to_fb,
-                            &f_fb_to_crtc))
+                            &f_fb_to_crtc) &&
+       xf86CrtcFitsScreen (crtc, &f_crtc_to_fb))
     {
        /*
         * If the untranslated transformation is the identity,
@@ -400,8 +426,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, 
Rotation rotation)
         * matches the mode, not the pre-rotated copy in the
         * frame buffer
         */
-       int         width = mode->HDisplay;
-       int         height = mode->VDisplay;
+       int         width = crtc->mode.HDisplay;
+       int         height = crtc->mode.VDisplay;
        void        *shadowData = crtc->rotatedData;
        PixmapPtr   shadow = crtc->rotatedPixmap;
        int         old_width = shadow ? shadow->drawable.width : 0;
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 5ac983d..d4cfa67 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -545,7 +545,7 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
  * Set whether transforms are allowed on a CRTC
  */
 void
-RRCrtcSetTransform (RRCrtcPtr crtc, Bool transforms);
+RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms);
 
 /*
  * Notify the extension that the Crtc has been reconfigured,
@@ -639,7 +639,7 @@ RRCrtcGetTransform (RRCrtcPtr crtc);
  * Mark the pending transform as current
  */
 void
-RRCrtcPostPendingTransform (RRCrtcPtr crtc);
+RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform);
 
 /*
  * Check whether the pending and current transforms are the same
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index d7ea6f2..091517a 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -91,12 +91,23 @@ RRTransformSetFilter (RRTransformPtr        dst,
 static Bool
 RRTransformCopy (RRTransformPtr dst, RRTransformPtr src)
 {
-    if (!RRTransformSetFilter (dst, src->filter,
-                              src->params, src->nparams, src->width, 
src->height))
-       return FALSE;
-    dst->transform = src->transform;
-    dst->f_transform = src->f_transform;
-    dst->f_inverse = src->f_inverse;
+    if (src)
+    {
+       if (!RRTransformSetFilter (dst, src->filter,
+                                  src->params, src->nparams, src->width, 
src->height))
+           return FALSE;
+       dst->transform = src->transform;
+       dst->f_transform = src->f_transform;
+       dst->f_inverse = src->f_inverse;
+    }
+    else
+    {
+       if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0))
+           return FALSE;
+       PictureTransformInitIdentity (&dst->transform);
+       pict_f_transform_init_identity (&dst->f_transform);
+       pict_f_transform_init_identity (&dst->f_inverse);
+    }
     return TRUE;
 }
 
@@ -170,7 +181,7 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
  * Set whether transforms are allowed on a CRTC
  */
 void
-RRCrtcSetTransform (RRCrtcPtr crtc, Bool transforms)
+RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms)
 {
     crtc->transforms = transforms;
 }
@@ -439,21 +450,21 @@ RRCrtcGetTransform (RRCrtcPtr crtc)
 }
 
 /*
- * Mark the pending transform as current
+ * Called when driver applies a transform to a crtc
  */
 void
-RRCrtcPostPendingTransform (RRCrtcPtr crtc)
+RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform)
 {
     if (!crtc->mode)
        return;
 
-    RRTransformCopy (&crtc->client_current_transform,
-                    &crtc->client_pending_transform);
+    RRTransformCopy (&crtc->client_current_transform, transform);
+
     RRComputeTransform (crtc->x, crtc->y,
                        crtc->mode->mode.width,
                        crtc->mode->mode.height,
                        crtc->rotation,
-                       &crtc->client_current_transform,
+                       transform,
                        &crtc->transform,
                        &crtc->f_transform,
                        &crtc->f_inverse);
@@ -1091,23 +1102,25 @@ ProcRRSetCrtcConfig (ClientPtr client)
        }
     
 #ifdef RANDR_12_INTERFACE
-#if 0
        /*
         * Check screen size bounds if the DDX provides a 1.2 interface
         * for setting screen size. Else, assume the CrtcSet sets
-        * the size along with the mode
+        * the size along with the mode. If the driver supports transforms,
+        * then it must allow crtcs to display a subset of the screen, so
+        * only do this check for drivers without transform support.
         */
-       if (pScrPriv->rrScreenSetSize)
+       if (pScrPriv->rrScreenSetSize && !crtc->transforms)
        {
            int source_width;
            int source_height;
-           PictTransform transform, inverse;
+           PictTransform transform;
+           struct pict_f_transform f_transform, f_inverse;
 
-           RRComputeTransform (mode, stuff->rotation,
-                               stuff->x, stuff->y,
-                               &crtc->client_pending_transform.transform,
-                               &crtc->client_pending_transform.inverse,
-                               &transform, &inverse);
+           RRComputeTransform (stuff->x, stuff->y,
+                               mode->mode.width, mode->mode.height,
+                               rotation,
+                               &crtc->client_pending_transform,
+                               &transform, &f_transform, &f_inverse);
 
            RRModeGetScanoutSize (mode, &transform, &source_width, 
&source_height);
            if (stuff->x + source_width > pScreen->width)
@@ -1127,7 +1140,6 @@ ProcRRSetCrtcConfig (ClientPtr client)
            }
        }
 #endif
-#endif
     }
     
     /*
-- 
1.5.6.5

_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to