Add patches for driver to handle the transform
authorXavier Boudet <x-boudet@ti.com>
Wed, 21 Mar 2012 15:16:16 +0000 (16:16 +0100)
committerXavier Boudet <x-boudet@ti.com>
Wed, 21 Mar 2012 15:22:55 +0000 (15:22 +0000)
Signed-off-by: Xavier Boudet <x-boudet@ti.com>
debian/patches/1001-xfree86-modes-Let-the-driver-handle-the-transform.patch [new file with mode: 0644]
debian/patches/1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/1001-xfree86-modes-Let-the-driver-handle-the-transform.patch b/debian/patches/1001-xfree86-modes-Let-the-driver-handle-the-transform.patch
new file mode 100644 (file)
index 0000000..3f3fb6d
--- /dev/null
@@ -0,0 +1,333 @@
+From 245cb8e94fd15990e1b7d6622added460f104dba Mon Sep 17 00:00:00 2001
+From: Aaron Plattner <aplattner@nvidia.com>
+Date: Thu, 25 Aug 2011 10:19:48 -0700
+Subject: [PATCH 1/2] xfree86/modes: Let the driver handle the transform
+
+If a driver can use hardware to handle the crtc transform, then
+there's no need for the server's shadow layer to do it.  Add a crtc
+flag that lets the driver indicate that it is handling the transform.
+If it's set, consider the transformed size of the screen but don't
+actually enable the shadow layer.  Also stop adjusting the cursor
+image and position.
+
+Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
+---
+ hw/xfree86/modes/xf86Crtc.h    |   16 +++++-
+ hw/xfree86/modes/xf86Cursors.c |   31 +++++++---
+ hw/xfree86/modes/xf86Rotate.c  |  131 +++++++++++++++++++++-------------------
+ 3 files changed, 107 insertions(+), 71 deletions(-)
+
+diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
+index 68a968c..0d7a6a6 100644
+--- a/hw/xfree86/modes/xf86Crtc.h
++++ b/hw/xfree86/modes/xf86Crtc.h
+@@ -1,5 +1,6 @@
+ /*
+  * Copyright © 2006 Keith Packard
++ * Copyright © 2011 Aaron Plattner
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+@@ -223,7 +224,7 @@ typedef struct _xf86CrtcFuncs {
+ } xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
+-#define XF86_CRTC_VERSION 3
++#define XF86_CRTC_VERSION 4
+ struct _xf86Crtc {
+     /**
+@@ -361,6 +362,19 @@ struct _xf86Crtc {
+      * Clear the shadow
+      */
+     Bool          shadowClear;
++
++    /**
++     * Indicates that the driver is handling the transform, so the shadow
++     * surface should be disabled.  The driver writes this field before calling
++     * xf86CrtcRotate to indicate that it is handling the transform (including
++     * rotation and reflection).
++     *
++     * Setting this flag also causes the server to stop adjusting the cursor
++     * image and position.
++     *
++     * Added in ABI version 4
++     */
++    Bool          driverIsPerformingTransform;
+ };
+ typedef struct _xf86OutputFuncs {
+diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
+index 23c48eb..02dea5c 100644
+--- a/hw/xfree86/modes/xf86Cursors.c
++++ b/hw/xfree86/modes/xf86Cursors.c
+@@ -1,6 +1,6 @@
+ /*
+  * Copyright © 2007 Keith Packard
+- * Copyright © 2010 Aaron Plattner
++ * Copyright © 2010-2011 Aaron Plattner
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+@@ -47,6 +47,18 @@
+ #include "inputstr.h"
+ /*
++ * Returns the rotation being performed by the server.  If the driver indicates
++ * that it's handling the screen transform, then this returns RR_Rotate_0.
++ */
++static Rotation
++xf86_crtc_cursor_rotation (xf86CrtcPtr crtc)
++{
++    if (crtc->driverIsPerformingTransform)
++      return RR_Rotate_0;
++    return crtc->rotation;
++}
++
++/*
+  * Given a screen coordinate, rotate back to a cursor source coordinate
+  */
+ static void
+@@ -214,6 +226,7 @@ xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
+     int                       xin, yin;
+     int                       flags = cursor_info->Flags;
+     CARD32            bits;
++    const Rotation    rotation = xf86_crtc_cursor_rotation(crtc);
+ #ifdef ARGB_CURSOR
+     crtc->cursor_argb = FALSE;
+@@ -222,7 +235,7 @@ xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
+     for (y = 0; y < cursor_info->MaxHeight; y++)
+       for (x = 0; x < cursor_info->MaxWidth; x++) 
+       {
+-          xf86_crtc_rotate_coord (crtc->rotation,
++          xf86_crtc_rotate_coord (rotation,
+                                   cursor_info->MaxWidth,
+                                   cursor_info->MaxHeight,
+                                   x, y, &xin, &yin);
+@@ -338,7 +351,7 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+     /*
+      * Transform position of cursor on screen
+      */
+-    if (crtc->transform_in_use)
++    if (crtc->transform_in_use && !crtc->driverIsPerformingTransform)
+     {
+       ScreenPtr       screen = scrn->pScreen;
+       xf86CursorScreenPtr ScreenPriv =
+@@ -420,12 +433,13 @@ xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
+     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+     xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+     CARD8             *cursor_image;
++    const Rotation    rotation = xf86_crtc_cursor_rotation(crtc);
+ #ifdef ARGB_CURSOR
+     crtc->cursor_argb = FALSE;
+ #endif
+-    if (crtc->rotation == RR_Rotate_0)
++    if (rotation == RR_Rotate_0)
+       cursor_image = src;
+     else
+     {
+@@ -439,7 +453,7 @@ xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
+         for (y = 0; y < cursor_info->MaxHeight; y++)
+           for (x = 0; x < cursor_info->MaxWidth; x++) 
+           {
+-              xf86_crtc_rotate_coord (crtc->rotation,
++              xf86_crtc_rotate_coord (rotation,
+                                       cursor_info->MaxWidth,
+                                       cursor_info->MaxHeight,
+                                       x, y, &xin, &yin);
+@@ -532,12 +546,13 @@ xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
+     int                       source_height = cursor->bits->height;
+     int                       image_width = cursor_info->MaxWidth;
+     int                       image_height = cursor_info->MaxHeight;
+-    
++    const Rotation    rotation = xf86_crtc_cursor_rotation(crtc);
++
+     for (y = 0; y < image_height; y++)
+       for (x = 0; x < image_width; x++)
+       {
+-          xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
+-                                  x, y, &xin, &yin);
++          xf86_crtc_rotate_coord (rotation, image_width, image_height, x, y,
++                                  &xin, &yin);
+           if (xin < source_width && yin < source_height)
+               bits = cursor_source[yin * source_width + xin];
+           else
+diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
+index 57c3499..45aabf0 100644
+--- a/hw/xfree86/modes/xf86Rotate.c
++++ b/hw/xfree86/modes/xf86Rotate.c
+@@ -1,5 +1,6 @@
+ /*
+  * Copyright © 2006 Keith Packard
++ * Copyright © 2011 Aaron Plattner
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+@@ -84,7 +85,10 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
+     int                       n = RegionNumRects(region);
+     BoxPtr            b = RegionRects(region);
+     XID                       include_inferiors = IncludeInferiors;
+-    
++
++    if (crtc->driverIsPerformingTransform)
++      return;
++
+     src = CreatePicture (None,
+                        &root->drawable,
+                        format,
+@@ -290,7 +294,7 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
+     }
+     for (c = 0; c < xf86_config->num_crtc; c++)
+-      if (xf86_config->crtc[c]->transform_in_use)
++      if (xf86_config->crtc[c]->rotatedData)
+           return;
+     /*
+@@ -414,52 +418,73 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
+     }
+     else
+     {
+-      /*
+-       * these are the size of the shadow pixmap, which
+-       * matches the mode, not the pre-rotated copy in the
+-       * frame buffer
+-       */
+-      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;
+-      int         old_height = shadow ? shadow->drawable.height : 0;
+-
+-      /* Allocate memory for rotation */
+-      if (old_width != width || old_height != height)
+-      {
+-          if (shadow || shadowData)
++      if (crtc->driverIsPerformingTransform) {
++          xf86RotateDestroy(crtc);
++      } else {
++          /*
++           * these are the size of the shadow pixmap, which
++           * matches the mode, not the pre-rotated copy in the
++           * frame buffer
++           */
++          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;
++          int         old_height = shadow ? shadow->drawable.height : 0;
++
++          /* Allocate memory for rotation */
++          if (old_width != width || old_height != height)
+           {
+-              crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+-              crtc->rotatedPixmap = NULL;
+-              crtc->rotatedData = NULL;
++              if (shadow || shadowData)
++              {
++                  crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
++                  crtc->rotatedPixmap = NULL;
++                  crtc->rotatedData = NULL;
++              }
++              shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
++              if (!shadowData)
++                  goto bail1;
++              crtc->rotatedData = shadowData;
++              /* shadow will be damaged in xf86RotatePrepare */
++          }
++          else
++          {
++              /* mark shadowed area as damaged so it will be repainted */
++              damage = TRUE;
+           }
+-          shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
+-          if (!shadowData)
+-              goto bail1;
+-          crtc->rotatedData = shadowData;
+-          /* shadow will be damaged in xf86RotatePrepare */
+-      }
+-      else
+-      {
+-          /* mark shadowed area as damaged so it will be repainted */
+-          damage = TRUE;
+-      }
+-      if (!xf86_config->rotation_damage)
+-      {
+-          /* Create damage structure */
+-          xf86_config->rotation_damage = DamageCreate (NULL, NULL,
+-                                              DamageReportNone,
+-                                              TRUE, pScreen, pScreen);
+           if (!xf86_config->rotation_damage)
+-              goto bail2;
+-          
+-          /* Wrap block handler */
+-          if (!xf86_config->BlockHandler) {
+-              xf86_config->BlockHandler = pScreen->BlockHandler;
+-              pScreen->BlockHandler = xf86RotateBlockHandler;
++          {
++              /* Create damage structure */
++              xf86_config->rotation_damage = DamageCreate (NULL, NULL,
++                                                  DamageReportNone,
++                                                  TRUE, pScreen, pScreen);
++              if (!xf86_config->rotation_damage)
++                  goto bail2;
++
++              /* Wrap block handler */
++              if (!xf86_config->BlockHandler) {
++                  xf86_config->BlockHandler = pScreen->BlockHandler;
++                  pScreen->BlockHandler = xf86RotateBlockHandler;
++              }
++          }
++
++          if (0)
++          {
++      bail2:
++              if (shadow || shadowData)
++              {
++                  crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
++                  crtc->rotatedPixmap = NULL;
++                  crtc->rotatedData = NULL;
++              }
++      bail1:
++              if (old_width && old_height)
++                  crtc->rotatedPixmap =
++                      crtc->funcs->shadow_create (crtc, NULL, old_width,
++                                                  old_height);
++              return FALSE;
+           }
+       }
+ #ifdef RANDR_12_INTERFACE
+@@ -482,24 +507,6 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
+           }
+       }
+ #endif
+-
+-      if (0)
+-      {
+-    bail2:
+-          if (shadow || shadowData)
+-          {
+-              crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+-              crtc->rotatedPixmap = NULL;
+-              crtc->rotatedData = NULL;
+-          }
+-    bail1:
+-          if (old_width && old_height)
+-              crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
+-                                                                NULL,
+-                                                                old_width,
+-                                                                old_height);
+-          return FALSE;
+-      }
+       crtc->transform_in_use = TRUE;
+     }
+     crtc->crtc_to_framebuffer = crtc_to_fb;
+-- 
+1.7.4.1
+
diff --git a/debian/patches/1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch b/debian/patches/1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch
new file mode 100644 (file)
index 0000000..bbb3d07
--- /dev/null
@@ -0,0 +1,117 @@
+From 57cd32e93425597317b4b7722859155419836e4c Mon Sep 17 00:00:00 2001
+From: Aaron Plattner <aplattner@nvidia.com>
+Date: Thu, 25 Aug 2011 15:41:55 -0700
+Subject: [PATCH 2/2] xfree86/modes: Make cursor position transform a helper function
+
+When the driver can handle the crtc transform in hardware, it sets
+crtc->driverIsPerformingTransform, which turns off both the shadow
+layer and the cursor's position-transforming code.  However, some
+drivers actually do require the cursor position to still be
+transformed in these cases.  Move the cursor position transform into a
+helper function that can be called by such drivers.
+
+Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
+---
+ hw/xfree86/modes/xf86Crtc.h    |    8 +++++
+ hw/xfree86/modes/xf86Cursors.c |   57 +++++++++++++++++++++------------------
+ 2 files changed, 39 insertions(+), 26 deletions(-)
+
+Index: xserver/hw/xfree86/modes/xf86Crtc.h
+===================================================================
+--- xserver.orig/hw/xfree86/modes/xf86Crtc.h   2012-03-21 16:16:55.085740513 +0100
++++ xserver/hw/xfree86/modes/xf86Crtc.h        2012-03-21 16:16:55.121740513 +0100
+@@ -903,6 +903,14 @@
+ extern _X_EXPORT char *
+ xf86ConnectorGetName(xf86ConnectorType connector);
++/**
++ * Transform the cursor's coordinates based on the crtc transform.  Normally
++ * this is done by the server, but if crtc->driverIsPerformingTransform is TRUE,
++ * then the server does not transform the cursor position automatically.
++ */
++extern _X_EXPORT void
++xf86CrtcTransformCursorPos (xf86CrtcPtr crtc, int *x, int *y);
++
+ /*
+  * Using the desired mode information in each crtc, set
+  * modes (used in EnterVT functions, or at server startup)
+Index: xserver/hw/xfree86/modes/xf86Cursors.c
+===================================================================
+--- xserver.orig/hw/xfree86/modes/xf86Cursors.c        2012-03-21 16:16:55.089740513 +0100
++++ xserver/hw/xfree86/modes/xf86Cursors.c     2012-03-21 16:16:55.121740513 +0100
+@@ -337,7 +337,36 @@
+           xf86_crtc_show_cursor (crtc);
+     }
+ }
+-    
++
++void xf86CrtcTransformCursorPos (xf86CrtcPtr crtc, int *x, int *y)
++{
++    ScrnInfoPtr scrn = crtc->scrn;
++    ScreenPtr screen = scrn->pScreen;
++    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
++    xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
++    xf86CursorScreenPtr ScreenPriv =
++      (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
++                                            xf86CursorScreenKey);
++    struct pict_f_vector v;
++    int dx, dy;
++
++    v.v[0] = (*x + ScreenPriv->HotX) + 0.5;
++    v.v[1] = (*y + ScreenPriv->HotY) + 0.5;
++    v.v[2] = 1;
++    pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
++    /* cursor will have 0.5 added to it already so floor is sufficent */
++    *x = floor (v.v[0]);
++    *y = floor (v.v[1]);
++    /*
++     * Transform position of cursor upper left corner
++     */
++    xf86_crtc_rotate_coord_back (crtc->rotation, cursor_info->MaxWidth,
++                               cursor_info->MaxHeight, ScreenPriv->HotX,
++                               ScreenPriv->HotY, &dx, &dy);
++    *x -= dx;
++    *y -= dy;
++}
++
+ static void
+ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
+ {
+@@ -346,36 +375,12 @@
+     xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
+     DisplayModePtr    mode = &crtc->mode;
+     Bool              in_range;
+-    int                       dx, dy;
+     /*
+      * Transform position of cursor on screen
+      */
+     if (crtc->transform_in_use && !crtc->driverIsPerformingTransform)
+-    {
+-      ScreenPtr       screen = scrn->pScreen;
+-      xf86CursorScreenPtr ScreenPriv =
+-          (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
+-                                                xf86CursorScreenKey);
+-      struct pict_f_vector   v;
+-
+-      v.v[0] = (x + ScreenPriv->HotX) + 0.5;
+-      v.v[1] = (y + ScreenPriv->HotY) + 0.5;
+-      v.v[2] = 1;
+-      pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
+-      /* cursor will have 0.5 added to it already so floor is sufficent */
+-      x = floor (v.v[0]);
+-      y = floor (v.v[1]);
+-      /*
+-       * Transform position of cursor upper left corner
+-       */
+-      xf86_crtc_rotate_coord_back (crtc->rotation,
+-                                   cursor_info->MaxWidth,
+-                                   cursor_info->MaxHeight,
+-                                   ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy);
+-      x -= dx;
+-      y -= dy;
+-   }
++      xf86CrtcTransformCursorPos(crtc, &x, &y);
+     else
+     {
+       x -= crtc->x;
index 920503d167f25ef5549f9374db6fb986e6e60022..3c3119f63fb6620787b13dd86cce678be3dd3133 100644 (file)
@@ -35,3 +35,5 @@
 500_pointer_barrier_thresholds.diff
 501_touch_accept_end.patch
 502_indirect_touch_window_set.patch
+1001-xfree86-modes-Let-the-driver-handle-the-transform.patch
+1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch