Subversion Repositories Kolibri OS

Rev

Rev 5060 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2011-2013 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21.  * SOFTWARE.
  22.  */
  23.  
  24. #include <linux/errno.h>
  25. #include <linux/export.h>
  26. #include <linux/kernel.h>
  27. #include <drm/drmP.h>
  28. #include <drm/drm_rect.h>
  29.  
  30. /**
  31.  * drm_rect_intersect - intersect two rectangles
  32.  * @r1: first rectangle
  33.  * @r2: second rectangle
  34.  *
  35.  * Calculate the intersection of rectangles @r1 and @r2.
  36.  * @r1 will be overwritten with the intersection.
  37.  *
  38.  * RETURNS:
  39.  * %true if rectangle @r1 is still visible after the operation,
  40.  * %false otherwise.
  41.  */
  42. bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2)
  43. {
  44.         r1->x1 = max(r1->x1, r2->x1);
  45.         r1->y1 = max(r1->y1, r2->y1);
  46.         r1->x2 = min(r1->x2, r2->x2);
  47.         r1->y2 = min(r1->y2, r2->y2);
  48.  
  49.         return drm_rect_visible(r1);
  50. }
  51. EXPORT_SYMBOL(drm_rect_intersect);
  52.  
  53. /**
  54.  * drm_rect_clip_scaled - perform a scaled clip operation
  55.  * @src: source window rectangle
  56.  * @dst: destination window rectangle
  57.  * @clip: clip rectangle
  58.  * @hscale: horizontal scaling factor
  59.  * @vscale: vertical scaling factor
  60.  *
  61.  * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the
  62.  * same amounts multiplied by @hscale and @vscale.
  63.  *
  64.  * RETURNS:
  65.  * %true if rectangle @dst is still visible after being clipped,
  66.  * %false otherwise
  67.  */
  68. bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst,
  69.                           const struct drm_rect *clip,
  70.                           int hscale, int vscale)
  71. {
  72.         int diff;
  73.  
  74.         diff = clip->x1 - dst->x1;
  75.         if (diff > 0) {
  76.                 int64_t tmp = src->x1 + (int64_t) diff * hscale;
  77.                 src->x1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
  78.         }
  79.         diff = clip->y1 - dst->y1;
  80.         if (diff > 0) {
  81.                 int64_t tmp = src->y1 + (int64_t) diff * vscale;
  82.                 src->y1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
  83.         }
  84.         diff = dst->x2 - clip->x2;
  85.         if (diff > 0) {
  86.                 int64_t tmp = src->x2 - (int64_t) diff * hscale;
  87.                 src->x2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
  88.         }
  89.         diff = dst->y2 - clip->y2;
  90.         if (diff > 0) {
  91.                 int64_t tmp = src->y2 - (int64_t) diff * vscale;
  92.                 src->y2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
  93.         }
  94.  
  95.         return drm_rect_intersect(dst, clip);
  96. }
  97. EXPORT_SYMBOL(drm_rect_clip_scaled);
  98.  
  99. static int drm_calc_scale(int src, int dst)
  100. {
  101.         int scale = 0;
  102.  
  103.         if (src < 0 || dst < 0)
  104.                 return -EINVAL;
  105.  
  106.         if (dst == 0)
  107.                 return 0;
  108.  
  109.         scale = src / dst;
  110.  
  111.         return scale;
  112. }
  113.  
  114. /**
  115.  * drm_rect_calc_hscale - calculate the horizontal scaling factor
  116.  * @src: source window rectangle
  117.  * @dst: destination window rectangle
  118.  * @min_hscale: minimum allowed horizontal scaling factor
  119.  * @max_hscale: maximum allowed horizontal scaling factor
  120.  *
  121.  * Calculate the horizontal scaling factor as
  122.  * (@src width) / (@dst width).
  123.  *
  124.  * RETURNS:
  125.  * The horizontal scaling factor, or errno of out of limits.
  126.  */
  127. int drm_rect_calc_hscale(const struct drm_rect *src,
  128.                          const struct drm_rect *dst,
  129.                          int min_hscale, int max_hscale)
  130. {
  131.         int src_w = drm_rect_width(src);
  132.         int dst_w = drm_rect_width(dst);
  133.         int hscale = drm_calc_scale(src_w, dst_w);
  134.  
  135.         if (hscale < 0 || dst_w == 0)
  136.                 return hscale;
  137.  
  138.         if (hscale < min_hscale || hscale > max_hscale)
  139.                 return -ERANGE;
  140.  
  141.         return hscale;
  142. }
  143. EXPORT_SYMBOL(drm_rect_calc_hscale);
  144.  
  145. /**
  146.  * drm_rect_calc_vscale - calculate the vertical scaling factor
  147.  * @src: source window rectangle
  148.  * @dst: destination window rectangle
  149.  * @min_vscale: minimum allowed vertical scaling factor
  150.  * @max_vscale: maximum allowed vertical scaling factor
  151.  *
  152.  * Calculate the vertical scaling factor as
  153.  * (@src height) / (@dst height).
  154.  *
  155.  * RETURNS:
  156.  * The vertical scaling factor, or errno of out of limits.
  157.  */
  158. int drm_rect_calc_vscale(const struct drm_rect *src,
  159.                          const struct drm_rect *dst,
  160.                          int min_vscale, int max_vscale)
  161. {
  162.         int src_h = drm_rect_height(src);
  163.         int dst_h = drm_rect_height(dst);
  164.         int vscale = drm_calc_scale(src_h, dst_h);
  165.  
  166.         if (vscale < 0 || dst_h == 0)
  167.                 return vscale;
  168.  
  169.         if (vscale < min_vscale || vscale > max_vscale)
  170.                 return -ERANGE;
  171.  
  172.         return vscale;
  173. }
  174. EXPORT_SYMBOL(drm_rect_calc_vscale);
  175.  
  176. /**
  177.  * drm_calc_hscale_relaxed - calculate the horizontal scaling factor
  178.  * @src: source window rectangle
  179.  * @dst: destination window rectangle
  180.  * @min_hscale: minimum allowed horizontal scaling factor
  181.  * @max_hscale: maximum allowed horizontal scaling factor
  182.  *
  183.  * Calculate the horizontal scaling factor as
  184.  * (@src width) / (@dst width).
  185.  *
  186.  * If the calculated scaling factor is below @min_vscale,
  187.  * decrease the height of rectangle @dst to compensate.
  188.  *
  189.  * If the calculated scaling factor is above @max_vscale,
  190.  * decrease the height of rectangle @src to compensate.
  191.  *
  192.  * RETURNS:
  193.  * The horizontal scaling factor.
  194.  */
  195. int drm_rect_calc_hscale_relaxed(struct drm_rect *src,
  196.                                  struct drm_rect *dst,
  197.                                  int min_hscale, int max_hscale)
  198. {
  199.         int src_w = drm_rect_width(src);
  200.         int dst_w = drm_rect_width(dst);
  201.         int hscale = drm_calc_scale(src_w, dst_w);
  202.  
  203.         if (hscale < 0 || dst_w == 0)
  204.                 return hscale;
  205.  
  206.         if (hscale < min_hscale) {
  207.                 int max_dst_w = src_w / min_hscale;
  208.  
  209.                 drm_rect_adjust_size(dst, max_dst_w - dst_w, 0);
  210.  
  211.                 return min_hscale;
  212.         }
  213.  
  214.         if (hscale > max_hscale) {
  215.                 int max_src_w = dst_w * max_hscale;
  216.  
  217.                 drm_rect_adjust_size(src, max_src_w - src_w, 0);
  218.  
  219.                 return max_hscale;
  220.         }
  221.  
  222.         return hscale;
  223. }
  224. EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed);
  225.  
  226. /**
  227.  * drm_rect_calc_vscale_relaxed - calculate the vertical scaling factor
  228.  * @src: source window rectangle
  229.  * @dst: destination window rectangle
  230.  * @min_vscale: minimum allowed vertical scaling factor
  231.  * @max_vscale: maximum allowed vertical scaling factor
  232.  *
  233.  * Calculate the vertical scaling factor as
  234.  * (@src height) / (@dst height).
  235.  *
  236.  * If the calculated scaling factor is below @min_vscale,
  237.  * decrease the height of rectangle @dst to compensate.
  238.  *
  239.  * If the calculated scaling factor is above @max_vscale,
  240.  * decrease the height of rectangle @src to compensate.
  241.  *
  242.  * RETURNS:
  243.  * The vertical scaling factor.
  244.  */
  245. int drm_rect_calc_vscale_relaxed(struct drm_rect *src,
  246.                                  struct drm_rect *dst,
  247.                                  int min_vscale, int max_vscale)
  248. {
  249.         int src_h = drm_rect_height(src);
  250.         int dst_h = drm_rect_height(dst);
  251.         int vscale = drm_calc_scale(src_h, dst_h);
  252.  
  253.         if (vscale < 0 || dst_h == 0)
  254.                 return vscale;
  255.  
  256.         if (vscale < min_vscale) {
  257.                 int max_dst_h = src_h / min_vscale;
  258.  
  259.                 drm_rect_adjust_size(dst, 0, max_dst_h - dst_h);
  260.  
  261.                 return min_vscale;
  262.         }
  263.  
  264.         if (vscale > max_vscale) {
  265.                 int max_src_h = dst_h * max_vscale;
  266.  
  267.                 drm_rect_adjust_size(src, 0, max_src_h - src_h);
  268.  
  269.                 return max_vscale;
  270.         }
  271.  
  272.         return vscale;
  273. }
  274. EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed);
  275.  
  276. /**
  277.  * drm_rect_debug_print - print the rectangle information
  278.  * @r: rectangle to print
  279.  * @fixed_point: rectangle is in 16.16 fixed point format
  280.  */
  281. void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point)
  282. {
  283.         int w = drm_rect_width(r);
  284.         int h = drm_rect_height(r);
  285.  
  286.         if (fixed_point)
  287.                 DRM_DEBUG_KMS("%d.%06ux%d.%06u%+d.%06u%+d.%06u\n",
  288.                               w >> 16, ((w & 0xffff) * 15625) >> 10,
  289.                               h >> 16, ((h & 0xffff) * 15625) >> 10,
  290.                               r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10,
  291.                               r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10);
  292.         else
  293.                 DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1);
  294. }
  295. EXPORT_SYMBOL(drm_rect_debug_print);
  296.