LCOV - code coverage report
Current view: top level - dev/pci/drm - drm_rect.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 148 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifdef __linux__
      25             : #include <linux/errno.h>
      26             : #include <linux/export.h>
      27             : #include <linux/kernel.h>
      28             : #endif
      29             : #include <dev/pci/drm/drmP.h>
      30             : #include <dev/pci/drm/drm_rect.h>
      31             : 
      32             : /**
      33             :  * drm_rect_intersect - intersect two rectangles
      34             :  * @r1: first rectangle
      35             :  * @r2: second rectangle
      36             :  *
      37             :  * Calculate the intersection of rectangles @r1 and @r2.
      38             :  * @r1 will be overwritten with the intersection.
      39             :  *
      40             :  * RETURNS:
      41             :  * %true if rectangle @r1 is still visible after the operation,
      42             :  * %false otherwise.
      43             :  */
      44           0 : bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2)
      45             : {
      46           0 :         r1->x1 = max(r1->x1, r2->x1);
      47           0 :         r1->y1 = max(r1->y1, r2->y1);
      48           0 :         r1->x2 = min(r1->x2, r2->x2);
      49           0 :         r1->y2 = min(r1->y2, r2->y2);
      50             : 
      51           0 :         return drm_rect_visible(r1);
      52             : }
      53             : EXPORT_SYMBOL(drm_rect_intersect);
      54             : 
      55             : /**
      56             :  * drm_rect_clip_scaled - perform a scaled clip operation
      57             :  * @src: source window rectangle
      58             :  * @dst: destination window rectangle
      59             :  * @clip: clip rectangle
      60             :  * @hscale: horizontal scaling factor
      61             :  * @vscale: vertical scaling factor
      62             :  *
      63             :  * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the
      64             :  * same amounts multiplied by @hscale and @vscale.
      65             :  *
      66             :  * RETURNS:
      67             :  * %true if rectangle @dst is still visible after being clipped,
      68             :  * %false otherwise
      69             :  */
      70           0 : bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst,
      71             :                           const struct drm_rect *clip,
      72             :                           int hscale, int vscale)
      73             : {
      74             :         int diff;
      75             : 
      76           0 :         diff = clip->x1 - dst->x1;
      77           0 :         if (diff > 0) {
      78           0 :                 int64_t tmp = src->x1 + (int64_t) diff * hscale;
      79           0 :                 src->x1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
      80           0 :         }
      81           0 :         diff = clip->y1 - dst->y1;
      82           0 :         if (diff > 0) {
      83           0 :                 int64_t tmp = src->y1 + (int64_t) diff * vscale;
      84           0 :                 src->y1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
      85           0 :         }
      86           0 :         diff = dst->x2 - clip->x2;
      87           0 :         if (diff > 0) {
      88           0 :                 int64_t tmp = src->x2 - (int64_t) diff * hscale;
      89           0 :                 src->x2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
      90           0 :         }
      91           0 :         diff = dst->y2 - clip->y2;
      92           0 :         if (diff > 0) {
      93           0 :                 int64_t tmp = src->y2 - (int64_t) diff * vscale;
      94           0 :                 src->y2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX);
      95           0 :         }
      96             : 
      97           0 :         return drm_rect_intersect(dst, clip);
      98             : }
      99             : EXPORT_SYMBOL(drm_rect_clip_scaled);
     100             : 
     101           0 : static int drm_calc_scale(int src, int dst)
     102             : {
     103             :         int scale = 0;
     104             : 
     105           0 :         if (src < 0 || dst < 0)
     106           0 :                 return -EINVAL;
     107             : 
     108           0 :         if (dst == 0)
     109           0 :                 return 0;
     110             : 
     111           0 :         scale = src / dst;
     112             : 
     113           0 :         return scale;
     114           0 : }
     115             : 
     116             : /**
     117             :  * drm_rect_calc_hscale - calculate the horizontal scaling factor
     118             :  * @src: source window rectangle
     119             :  * @dst: destination window rectangle
     120             :  * @min_hscale: minimum allowed horizontal scaling factor
     121             :  * @max_hscale: maximum allowed horizontal scaling factor
     122             :  *
     123             :  * Calculate the horizontal scaling factor as
     124             :  * (@src width) / (@dst width).
     125             :  *
     126             :  * RETURNS:
     127             :  * The horizontal scaling factor, or errno of out of limits.
     128             :  */
     129           0 : int drm_rect_calc_hscale(const struct drm_rect *src,
     130             :                          const struct drm_rect *dst,
     131             :                          int min_hscale, int max_hscale)
     132             : {
     133           0 :         int src_w = drm_rect_width(src);
     134           0 :         int dst_w = drm_rect_width(dst);
     135           0 :         int hscale = drm_calc_scale(src_w, dst_w);
     136             : 
     137           0 :         if (hscale < 0 || dst_w == 0)
     138           0 :                 return hscale;
     139             : 
     140           0 :         if (hscale < min_hscale || hscale > max_hscale)
     141           0 :                 return -ERANGE;
     142             : 
     143           0 :         return hscale;
     144           0 : }
     145             : EXPORT_SYMBOL(drm_rect_calc_hscale);
     146             : 
     147             : /**
     148             :  * drm_rect_calc_vscale - calculate the vertical scaling factor
     149             :  * @src: source window rectangle
     150             :  * @dst: destination window rectangle
     151             :  * @min_vscale: minimum allowed vertical scaling factor
     152             :  * @max_vscale: maximum allowed vertical scaling factor
     153             :  *
     154             :  * Calculate the vertical scaling factor as
     155             :  * (@src height) / (@dst height).
     156             :  *
     157             :  * RETURNS:
     158             :  * The vertical scaling factor, or errno of out of limits.
     159             :  */
     160           0 : int drm_rect_calc_vscale(const struct drm_rect *src,
     161             :                          const struct drm_rect *dst,
     162             :                          int min_vscale, int max_vscale)
     163             : {
     164           0 :         int src_h = drm_rect_height(src);
     165           0 :         int dst_h = drm_rect_height(dst);
     166           0 :         int vscale = drm_calc_scale(src_h, dst_h);
     167             : 
     168           0 :         if (vscale < 0 || dst_h == 0)
     169           0 :                 return vscale;
     170             : 
     171           0 :         if (vscale < min_vscale || vscale > max_vscale)
     172           0 :                 return -ERANGE;
     173             : 
     174           0 :         return vscale;
     175           0 : }
     176             : EXPORT_SYMBOL(drm_rect_calc_vscale);
     177             : 
     178             : /**
     179             :  * drm_calc_hscale_relaxed - calculate the horizontal scaling factor
     180             :  * @src: source window rectangle
     181             :  * @dst: destination window rectangle
     182             :  * @min_hscale: minimum allowed horizontal scaling factor
     183             :  * @max_hscale: maximum allowed horizontal scaling factor
     184             :  *
     185             :  * Calculate the horizontal scaling factor as
     186             :  * (@src width) / (@dst width).
     187             :  *
     188             :  * If the calculated scaling factor is below @min_vscale,
     189             :  * decrease the height of rectangle @dst to compensate.
     190             :  *
     191             :  * If the calculated scaling factor is above @max_vscale,
     192             :  * decrease the height of rectangle @src to compensate.
     193             :  *
     194             :  * RETURNS:
     195             :  * The horizontal scaling factor.
     196             :  */
     197           0 : int drm_rect_calc_hscale_relaxed(struct drm_rect *src,
     198             :                                  struct drm_rect *dst,
     199             :                                  int min_hscale, int max_hscale)
     200             : {
     201           0 :         int src_w = drm_rect_width(src);
     202           0 :         int dst_w = drm_rect_width(dst);
     203           0 :         int hscale = drm_calc_scale(src_w, dst_w);
     204             : 
     205           0 :         if (hscale < 0 || dst_w == 0)
     206           0 :                 return hscale;
     207             : 
     208           0 :         if (hscale < min_hscale) {
     209           0 :                 int max_dst_w = src_w / min_hscale;
     210             : 
     211           0 :                 drm_rect_adjust_size(dst, max_dst_w - dst_w, 0);
     212             : 
     213             :                 return min_hscale;
     214             :         }
     215             : 
     216           0 :         if (hscale > max_hscale) {
     217           0 :                 int max_src_w = dst_w * max_hscale;
     218             : 
     219           0 :                 drm_rect_adjust_size(src, max_src_w - src_w, 0);
     220             : 
     221             :                 return max_hscale;
     222             :         }
     223             : 
     224           0 :         return hscale;
     225           0 : }
     226             : EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed);
     227             : 
     228             : /**
     229             :  * drm_rect_calc_vscale_relaxed - calculate the vertical scaling factor
     230             :  * @src: source window rectangle
     231             :  * @dst: destination window rectangle
     232             :  * @min_vscale: minimum allowed vertical scaling factor
     233             :  * @max_vscale: maximum allowed vertical scaling factor
     234             :  *
     235             :  * Calculate the vertical scaling factor as
     236             :  * (@src height) / (@dst height).
     237             :  *
     238             :  * If the calculated scaling factor is below @min_vscale,
     239             :  * decrease the height of rectangle @dst to compensate.
     240             :  *
     241             :  * If the calculated scaling factor is above @max_vscale,
     242             :  * decrease the height of rectangle @src to compensate.
     243             :  *
     244             :  * RETURNS:
     245             :  * The vertical scaling factor.
     246             :  */
     247           0 : int drm_rect_calc_vscale_relaxed(struct drm_rect *src,
     248             :                                  struct drm_rect *dst,
     249             :                                  int min_vscale, int max_vscale)
     250             : {
     251           0 :         int src_h = drm_rect_height(src);
     252           0 :         int dst_h = drm_rect_height(dst);
     253           0 :         int vscale = drm_calc_scale(src_h, dst_h);
     254             : 
     255           0 :         if (vscale < 0 || dst_h == 0)
     256           0 :                 return vscale;
     257             : 
     258           0 :         if (vscale < min_vscale) {
     259           0 :                 int max_dst_h = src_h / min_vscale;
     260             : 
     261           0 :                 drm_rect_adjust_size(dst, 0, max_dst_h - dst_h);
     262             : 
     263             :                 return min_vscale;
     264             :         }
     265             : 
     266           0 :         if (vscale > max_vscale) {
     267           0 :                 int max_src_h = dst_h * max_vscale;
     268             : 
     269           0 :                 drm_rect_adjust_size(src, 0, max_src_h - src_h);
     270             : 
     271             :                 return max_vscale;
     272             :         }
     273             : 
     274           0 :         return vscale;
     275           0 : }
     276             : EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed);
     277             : 
     278             : /**
     279             :  * drm_rect_debug_print - print the rectangle information
     280             :  * @r: rectangle to print
     281             :  * @fixed_point: rectangle is in 16.16 fixed point format
     282             :  */
     283           0 : void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point)
     284             : {
     285             : #ifdef DRMDEBUG
     286             :         int w = drm_rect_width(r);
     287             :         int h = drm_rect_height(r);
     288             : 
     289             :         if (fixed_point)
     290             :                 DRM_DEBUG_KMS("%d.%06ux%d.%06u%+d.%06u%+d.%06u\n",
     291             :                               w >> 16, ((w & 0xffff) * 15625) >> 10,
     292             :                               h >> 16, ((h & 0xffff) * 15625) >> 10,
     293             :                               r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10,
     294             :                               r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10);
     295             :         else
     296             :                 DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1);
     297             : #endif
     298           0 : }
     299             : EXPORT_SYMBOL(drm_rect_debug_print);
     300             : 
     301             : /**
     302             :  * drm_rect_rotate - Rotate the rectangle
     303             :  * @r: rectangle to be rotated
     304             :  * @width: Width of the coordinate space
     305             :  * @height: Height of the coordinate space
     306             :  * @rotation: Transformation to be applied
     307             :  *
     308             :  * Apply @rotation to the coordinates of rectangle @r.
     309             :  *
     310             :  * @width and @height combined with @rotation define
     311             :  * the location of the new origin.
     312             :  *
     313             :  * @width correcsponds to the horizontal and @height
     314             :  * to the vertical axis of the untransformed coordinate
     315             :  * space.
     316             :  */
     317           0 : void drm_rect_rotate(struct drm_rect *r,
     318             :                      int width, int height,
     319             :                      unsigned int rotation)
     320             : {
     321             :         struct drm_rect tmp;
     322             : 
     323           0 :         if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) {
     324           0 :                 tmp = *r;
     325             : 
     326           0 :                 if (rotation & BIT(DRM_REFLECT_X)) {
     327           0 :                         r->x1 = width - tmp.x2;
     328           0 :                         r->x2 = width - tmp.x1;
     329           0 :                 }
     330             : 
     331           0 :                 if (rotation & BIT(DRM_REFLECT_Y)) {
     332           0 :                         r->y1 = height - tmp.y2;
     333           0 :                         r->y2 = height - tmp.y1;
     334           0 :                 }
     335             :         }
     336             : 
     337           0 :         switch (rotation & DRM_ROTATE_MASK) {
     338             :         case BIT(DRM_ROTATE_0):
     339             :                 break;
     340             :         case BIT(DRM_ROTATE_90):
     341           0 :                 tmp = *r;
     342           0 :                 r->x1 = tmp.y1;
     343           0 :                 r->x2 = tmp.y2;
     344           0 :                 r->y1 = width - tmp.x2;
     345           0 :                 r->y2 = width - tmp.x1;
     346           0 :                 break;
     347             :         case BIT(DRM_ROTATE_180):
     348           0 :                 tmp = *r;
     349           0 :                 r->x1 = width - tmp.x2;
     350           0 :                 r->x2 = width - tmp.x1;
     351           0 :                 r->y1 = height - tmp.y2;
     352           0 :                 r->y2 = height - tmp.y1;
     353           0 :                 break;
     354             :         case BIT(DRM_ROTATE_270):
     355           0 :                 tmp = *r;
     356           0 :                 r->x1 = height - tmp.y2;
     357           0 :                 r->x2 = height - tmp.y1;
     358           0 :                 r->y1 = tmp.x1;
     359           0 :                 r->y2 = tmp.x2;
     360           0 :                 break;
     361             :         default:
     362             :                 break;
     363             :         }
     364           0 : }
     365             : EXPORT_SYMBOL(drm_rect_rotate);
     366             : 
     367             : /**
     368             :  * drm_rect_rotate_inv - Inverse rotate the rectangle
     369             :  * @r: rectangle to be rotated
     370             :  * @width: Width of the coordinate space
     371             :  * @height: Height of the coordinate space
     372             :  * @rotation: Transformation whose inverse is to be applied
     373             :  *
     374             :  * Apply the inverse of @rotation to the coordinates
     375             :  * of rectangle @r.
     376             :  *
     377             :  * @width and @height combined with @rotation define
     378             :  * the location of the new origin.
     379             :  *
     380             :  * @width correcsponds to the horizontal and @height
     381             :  * to the vertical axis of the original untransformed
     382             :  * coordinate space, so that you never have to flip
     383             :  * them when doing a rotatation and its inverse.
     384             :  * That is, if you do:
     385             :  *
     386             :  * drm_rotate(&r, width, height, rotation);
     387             :  * drm_rotate_inv(&r, width, height, rotation);
     388             :  *
     389             :  * you will always get back the original rectangle.
     390             :  */
     391           0 : void drm_rect_rotate_inv(struct drm_rect *r,
     392             :                          int width, int height,
     393             :                          unsigned int rotation)
     394             : {
     395             :         struct drm_rect tmp;
     396             : 
     397           0 :         switch (rotation & DRM_ROTATE_MASK) {
     398             :         case BIT(DRM_ROTATE_0):
     399             :                 break;
     400             :         case BIT(DRM_ROTATE_90):
     401           0 :                 tmp = *r;
     402           0 :                 r->x1 = width - tmp.y2;
     403           0 :                 r->x2 = width - tmp.y1;
     404           0 :                 r->y1 = tmp.x1;
     405           0 :                 r->y2 = tmp.x2;
     406           0 :                 break;
     407             :         case BIT(DRM_ROTATE_180):
     408           0 :                 tmp = *r;
     409           0 :                 r->x1 = width - tmp.x2;
     410           0 :                 r->x2 = width - tmp.x1;
     411           0 :                 r->y1 = height - tmp.y2;
     412           0 :                 r->y2 = height - tmp.y1;
     413           0 :                 break;
     414             :         case BIT(DRM_ROTATE_270):
     415           0 :                 tmp = *r;
     416           0 :                 r->x1 = tmp.y1;
     417           0 :                 r->x2 = tmp.y2;
     418           0 :                 r->y1 = height - tmp.x2;
     419           0 :                 r->y2 = height - tmp.x1;
     420           0 :                 break;
     421             :         default:
     422             :                 break;
     423             :         }
     424             : 
     425           0 :         if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) {
     426           0 :                 tmp = *r;
     427             : 
     428           0 :                 if (rotation & BIT(DRM_REFLECT_X)) {
     429           0 :                         r->x1 = width - tmp.x2;
     430           0 :                         r->x2 = width - tmp.x1;
     431           0 :                 }
     432             : 
     433           0 :                 if (rotation & BIT(DRM_REFLECT_Y)) {
     434           0 :                         r->y1 = height - tmp.y2;
     435           0 :                         r->y2 = height - tmp.y1;
     436           0 :                 }
     437             :         }
     438           0 : }
     439             : EXPORT_SYMBOL(drm_rect_rotate_inv);

Generated by: LCOV version 1.13