[PATCH 1/5] drm: Add struct drm_region and assorted utility functions

2012-05-24 Thread ville.syrj...@linux.intel.com
From: Ville Syrj?l? 

struct drm_region represents a two dimensional region. The utility
functions are there to help driver writers.

Signed-off-by: Ville Syrj?l? 
---
 drivers/gpu/drm/drm_crtc.c |  155 
 include/drm/drm_crtc.h |   24 +++
 2 files changed, 179 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5fc198d..a14b786 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3837,3 +3837,158 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
}
 }
 EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
+
+/**
+ * drm_region_adjust_size - adjust the size of the region
+ * @r: region to be adjusted
+ * @x: horizontal adjustment
+ * @y: vertical adjustment
+ *
+ * Change the size of region @r by @x in the horizontal direction,
+ * and by @y in the vertical direction, while keeping the center
+ * of @r stationary.
+ *
+ * Positive @x and @y increase the size, negative values decrease it.
+ */
+void drm_region_adjust_size(struct drm_region *r, int x, int y)
+{
+   r->x1 -= x >> 1;
+   r->y1 -= y >> 1;
+   r->x2 += (x + 1) >> 1;
+   r->y2 += (y + 1) >> 1;
+}
+EXPORT_SYMBOL(drm_region_adjust_size);
+
+/**
+ * drm_region_translate - translate the region
+ * @r: region to be tranlated
+ * @x: horizontal translation
+ * @y: vertical translation
+ *
+ * Move region @r by @x in the horizontal direction,
+ * and by @y in the vertical direction.
+ */
+void drm_region_translate(struct drm_region *r, int x, int y)
+{
+   r->x1 += x;
+   r->y1 += y;
+   r->x2 += x;
+   r->y2 += y;
+}
+EXPORT_SYMBOL(drm_region_translate);
+
+/**
+ * drm_region_subsample - subsample a region
+ * @r: region to be subsampled
+ * @hsub: horizontal subsampling factor
+ * @vsub: vertical subsampling factor
+ *
+ * Divide the coordinates of region @r by @hsub and @vsub.
+ */
+void drm_region_subsample(struct drm_region *r, int hsub, int vsub)
+{
+   r->x1 /= hsub;
+   r->y1 /= vsub;
+   r->x2 /= hsub;
+   r->y2 /= vsub;
+}
+EXPORT_SYMBOL(drm_region_subsample);
+
+/**
+ * drm_region_width - determine the region width
+ * @r: region whose width is returned
+ *
+ * RETURNS:
+ * The width of the region.
+ */
+int drm_region_width(const struct drm_region *r)
+{
+   return r->x2 - r->x1;
+}
+EXPORT_SYMBOL(drm_region_width);
+
+/**
+ * drm_region_height - determine the region height
+ * @r: region whose height is returned
+ *
+ * RETURNS:
+ * The height of the region.
+ */
+int drm_region_height(const struct drm_region *r)
+{
+   return r->y2 - r->y1;
+}
+EXPORT_SYMBOL(drm_region_height);
+
+/**
+ * drm_region_visible - determine if the the region is visible
+ * @r: region whose visibility is returned
+ *
+ * RETURNS:
+ * @true if the region is visible, @false otherwise.
+ */
+bool drm_region_visible(const struct drm_region *r)
+{
+   return drm_region_width(r) > 0 && drm_region_height(r) > 0;
+}
+EXPORT_SYMBOL(drm_region_visible);
+
+/**
+ * drm_region_clip - clip one region by another region
+ * @r: region to be clipped
+ * @clip: clip region
+ *
+ * Clip region @r by region @clip.
+ *
+ * RETURNS:
+ * @true if the region is still visible after being clipped,
+ * @false otherwise.
+ */
+bool drm_region_clip(struct drm_region *r, const struct drm_region *clip)
+{
+   r->x1 = max(r->x1, clip->x1);
+   r->y1 = max(r->y1, clip->y1);
+   r->x2 = min(r->x2, clip->x2);
+   r->y2 = min(r->y2, clip->y2);
+
+   return drm_region_visible(r);
+}
+EXPORT_SYMBOL(drm_region_clip);
+
+/**
+ * drm_region_clip_scaled - perform a scaled clip operation
+ * @src: source window region
+ * @dst: destination window region
+ * @clip: clip region
+ * @hscale: horizontal scaling factor
+ * @vscale: vertical scaling factor
+ *
+ * Clip region @dst by region @clip. Clip region @src by the same
+ * amounts multiplied by @hscale and @vscale.
+ *
+ * RETUTRNS:
+ * @true if region @dst is still visible after being clipped,
+ * @false otherwise
+ */
+bool drm_region_clip_scaled(struct drm_region *src, struct drm_region *dst,
+   const struct drm_region *clip,
+   int hscale, int vscale)
+{
+   int diff;
+
+   diff = clip->x1 - dst->x1;
+   if (diff > 0)
+   src->x1 += diff * hscale;
+   diff = clip->y1 - dst->y1;
+   if (diff > 0)
+   src->y1 += diff * vscale;
+   diff = dst->x2 - clip->x2;
+   if (diff > 0)
+   src->x2 -= diff * hscale;
+   diff = dst->y2 - clip->y2;
+   if (diff > 0)
+   src->y2 -= diff * vscale;
+
+   return drm_region_clip(dst, clip);
+}
+EXPORT_SYMBOL(drm_region_clip_scaled);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 73e4560..c735520 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1062,4 +1062,28 @@ extern int 

[PATCH 1/5] drm: Add struct drm_region and assorted utility functions

2012-05-24 Thread ville . syrjala
From: Ville Syrjälä ville.syrj...@linux.intel.com

struct drm_region represents a two dimensional region. The utility
functions are there to help driver writers.

Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
---
 drivers/gpu/drm/drm_crtc.c |  155 
 include/drm/drm_crtc.h |   24 +++
 2 files changed, 179 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5fc198d..a14b786 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3837,3 +3837,158 @@ int drm_format_vert_chroma_subsampling(uint32_t format)
}
 }
 EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
+
+/**
+ * drm_region_adjust_size - adjust the size of the region
+ * @r: region to be adjusted
+ * @x: horizontal adjustment
+ * @y: vertical adjustment
+ *
+ * Change the size of region @r by @x in the horizontal direction,
+ * and by @y in the vertical direction, while keeping the center
+ * of @r stationary.
+ *
+ * Positive @x and @y increase the size, negative values decrease it.
+ */
+void drm_region_adjust_size(struct drm_region *r, int x, int y)
+{
+   r-x1 -= x  1;
+   r-y1 -= y  1;
+   r-x2 += (x + 1)  1;
+   r-y2 += (y + 1)  1;
+}
+EXPORT_SYMBOL(drm_region_adjust_size);
+
+/**
+ * drm_region_translate - translate the region
+ * @r: region to be tranlated
+ * @x: horizontal translation
+ * @y: vertical translation
+ *
+ * Move region @r by @x in the horizontal direction,
+ * and by @y in the vertical direction.
+ */
+void drm_region_translate(struct drm_region *r, int x, int y)
+{
+   r-x1 += x;
+   r-y1 += y;
+   r-x2 += x;
+   r-y2 += y;
+}
+EXPORT_SYMBOL(drm_region_translate);
+
+/**
+ * drm_region_subsample - subsample a region
+ * @r: region to be subsampled
+ * @hsub: horizontal subsampling factor
+ * @vsub: vertical subsampling factor
+ *
+ * Divide the coordinates of region @r by @hsub and @vsub.
+ */
+void drm_region_subsample(struct drm_region *r, int hsub, int vsub)
+{
+   r-x1 /= hsub;
+   r-y1 /= vsub;
+   r-x2 /= hsub;
+   r-y2 /= vsub;
+}
+EXPORT_SYMBOL(drm_region_subsample);
+
+/**
+ * drm_region_width - determine the region width
+ * @r: region whose width is returned
+ *
+ * RETURNS:
+ * The width of the region.
+ */
+int drm_region_width(const struct drm_region *r)
+{
+   return r-x2 - r-x1;
+}
+EXPORT_SYMBOL(drm_region_width);
+
+/**
+ * drm_region_height - determine the region height
+ * @r: region whose height is returned
+ *
+ * RETURNS:
+ * The height of the region.
+ */
+int drm_region_height(const struct drm_region *r)
+{
+   return r-y2 - r-y1;
+}
+EXPORT_SYMBOL(drm_region_height);
+
+/**
+ * drm_region_visible - determine if the the region is visible
+ * @r: region whose visibility is returned
+ *
+ * RETURNS:
+ * @true if the region is visible, @false otherwise.
+ */
+bool drm_region_visible(const struct drm_region *r)
+{
+   return drm_region_width(r)  0  drm_region_height(r)  0;
+}
+EXPORT_SYMBOL(drm_region_visible);
+
+/**
+ * drm_region_clip - clip one region by another region
+ * @r: region to be clipped
+ * @clip: clip region
+ *
+ * Clip region @r by region @clip.
+ *
+ * RETURNS:
+ * @true if the region is still visible after being clipped,
+ * @false otherwise.
+ */
+bool drm_region_clip(struct drm_region *r, const struct drm_region *clip)
+{
+   r-x1 = max(r-x1, clip-x1);
+   r-y1 = max(r-y1, clip-y1);
+   r-x2 = min(r-x2, clip-x2);
+   r-y2 = min(r-y2, clip-y2);
+
+   return drm_region_visible(r);
+}
+EXPORT_SYMBOL(drm_region_clip);
+
+/**
+ * drm_region_clip_scaled - perform a scaled clip operation
+ * @src: source window region
+ * @dst: destination window region
+ * @clip: clip region
+ * @hscale: horizontal scaling factor
+ * @vscale: vertical scaling factor
+ *
+ * Clip region @dst by region @clip. Clip region @src by the same
+ * amounts multiplied by @hscale and @vscale.
+ *
+ * RETUTRNS:
+ * @true if region @dst is still visible after being clipped,
+ * @false otherwise
+ */
+bool drm_region_clip_scaled(struct drm_region *src, struct drm_region *dst,
+   const struct drm_region *clip,
+   int hscale, int vscale)
+{
+   int diff;
+
+   diff = clip-x1 - dst-x1;
+   if (diff  0)
+   src-x1 += diff * hscale;
+   diff = clip-y1 - dst-y1;
+   if (diff  0)
+   src-y1 += diff * vscale;
+   diff = dst-x2 - clip-x2;
+   if (diff  0)
+   src-x2 -= diff * hscale;
+   diff = dst-y2 - clip-y2;
+   if (diff  0)
+   src-y2 -= diff * vscale;
+
+   return drm_region_clip(dst, clip);
+}
+EXPORT_SYMBOL(drm_region_clip_scaled);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 73e4560..c735520 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1062,4 +1062,28 @@ extern int drm_format_plane_cpp(uint32_t format, int 
plane);