LCOV - code coverage report
Current view: top level - drivers/gpu/drm - drm_rect.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 130 0.0 %
Date: 2022-04-01 14:58:12 Functions: 0 8 0.0 %
Branches: 0 82 0.0 %

           Branch data     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                 :            : #include <linux/errno.h>
      25                 :            : #include <linux/export.h>
      26                 :            : #include <linux/kernel.h>
      27                 :            : 
      28                 :            : #include <drm/drm_mode.h>
      29                 :            : #include <drm/drm_print.h>
      30                 :            : #include <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                 :          0 : static u32 clip_scaled(int src, int dst, int *clip)
      56                 :            : {
      57                 :          0 :         u64 tmp;
      58                 :            : 
      59   [ #  #  #  #  :          0 :         if (dst == 0)
             #  #  #  # ]
      60                 :            :                 return 0;
      61                 :            : 
      62                 :            :         /* Only clip what we have. Keeps the result bounded. */
      63                 :          0 :         *clip = min(*clip, dst);
      64                 :            : 
      65   [ #  #  #  #  :          0 :         tmp = mul_u32_u32(src, dst - *clip);
             #  #  #  # ]
      66                 :            : 
      67                 :            :         /*
      68                 :            :          * Round toward 1.0 when clipping so that we don't accidentally
      69                 :            :          * change upscaling to downscaling or vice versa.
      70                 :            :          */
      71   [ #  #  #  #  :          0 :         if (src < (dst << 16))
             #  #  #  # ]
      72                 :          0 :                 return DIV_ROUND_UP_ULL(tmp, dst);
      73                 :            :         else
      74                 :          0 :                 return DIV_ROUND_DOWN_ULL(tmp, dst);
      75                 :            : }
      76                 :            : 
      77                 :            : /**
      78                 :            :  * drm_rect_clip_scaled - perform a scaled clip operation
      79                 :            :  * @src: source window rectangle
      80                 :            :  * @dst: destination window rectangle
      81                 :            :  * @clip: clip rectangle
      82                 :            :  *
      83                 :            :  * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the
      84                 :            :  * the corresponding amounts, retaining the vertical and horizontal scaling
      85                 :            :  * factors from @src to @dst.
      86                 :            :  *
      87                 :            :  * RETURNS:
      88                 :            :  *
      89                 :            :  * %true if rectangle @dst is still visible after being clipped,
      90                 :            :  * %false otherwise.
      91                 :            :  */
      92                 :          0 : bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst,
      93                 :            :                           const struct drm_rect *clip)
      94                 :            : {
      95                 :          0 :         int diff;
      96                 :            : 
      97                 :          0 :         diff = clip->x1 - dst->x1;
      98         [ #  # ]:          0 :         if (diff > 0) {
      99         [ #  # ]:          0 :                 u32 new_src_w = clip_scaled(drm_rect_width(src),
     100                 :            :                                             drm_rect_width(dst), &diff);
     101                 :            : 
     102                 :          0 :                 src->x1 = src->x2 - new_src_w;
     103                 :          0 :                 dst->x1 += diff;
     104                 :            :         }
     105                 :          0 :         diff = clip->y1 - dst->y1;
     106         [ #  # ]:          0 :         if (diff > 0) {
     107         [ #  # ]:          0 :                 u32 new_src_h = clip_scaled(drm_rect_height(src),
     108                 :            :                                             drm_rect_height(dst), &diff);
     109                 :            : 
     110                 :          0 :                 src->y1 = src->y2 - new_src_h;
     111                 :          0 :                 dst->y1 += diff;
     112                 :            :         }
     113                 :          0 :         diff = dst->x2 - clip->x2;
     114         [ #  # ]:          0 :         if (diff > 0) {
     115         [ #  # ]:          0 :                 u32 new_src_w = clip_scaled(drm_rect_width(src),
     116                 :            :                                             drm_rect_width(dst), &diff);
     117                 :            : 
     118                 :          0 :                 src->x2 = src->x1 + new_src_w;
     119                 :          0 :                 dst->x2 -= diff;
     120                 :            :         }
     121                 :          0 :         diff = dst->y2 - clip->y2;
     122         [ #  # ]:          0 :         if (diff > 0) {
     123         [ #  # ]:          0 :                 u32 new_src_h = clip_scaled(drm_rect_height(src),
     124                 :            :                                             drm_rect_height(dst), &diff);
     125                 :            : 
     126                 :          0 :                 src->y2 = src->y1 + new_src_h;
     127                 :          0 :                 dst->y2 -= diff;
     128                 :            :         }
     129                 :            : 
     130         [ #  # ]:          0 :         return drm_rect_visible(dst);
     131                 :            : }
     132                 :            : EXPORT_SYMBOL(drm_rect_clip_scaled);
     133                 :            : 
     134                 :          0 : static int drm_calc_scale(int src, int dst)
     135                 :            : {
     136                 :          0 :         int scale = 0;
     137                 :            : 
     138   [ #  #  #  # ]:          0 :         if (WARN_ON(src < 0 || dst < 0))
     139                 :            :                 return -EINVAL;
     140                 :            : 
     141         [ #  # ]:          0 :         if (dst == 0)
     142                 :            :                 return 0;
     143                 :            : 
     144         [ #  # ]:          0 :         if (src > (dst << 16))
     145                 :          0 :                 return DIV_ROUND_UP(src, dst);
     146                 :            :         else
     147                 :          0 :                 scale = src / dst;
     148                 :            : 
     149                 :          0 :         return scale;
     150                 :            : }
     151                 :            : 
     152                 :            : /**
     153                 :            :  * drm_rect_calc_hscale - calculate the horizontal scaling factor
     154                 :            :  * @src: source window rectangle
     155                 :            :  * @dst: destination window rectangle
     156                 :            :  * @min_hscale: minimum allowed horizontal scaling factor
     157                 :            :  * @max_hscale: maximum allowed horizontal scaling factor
     158                 :            :  *
     159                 :            :  * Calculate the horizontal scaling factor as
     160                 :            :  * (@src width) / (@dst width).
     161                 :            :  *
     162                 :            :  * If the scale is below 1 << 16, round down. If the scale is above
     163                 :            :  * 1 << 16, round up. This will calculate the scale with the most
     164                 :            :  * pessimistic limit calculation.
     165                 :            :  *
     166                 :            :  * RETURNS:
     167                 :            :  * The horizontal scaling factor, or errno of out of limits.
     168                 :            :  */
     169                 :          0 : int drm_rect_calc_hscale(const struct drm_rect *src,
     170                 :            :                          const struct drm_rect *dst,
     171                 :            :                          int min_hscale, int max_hscale)
     172                 :            : {
     173                 :          0 :         int src_w = drm_rect_width(src);
     174                 :          0 :         int dst_w = drm_rect_width(dst);
     175                 :          0 :         int hscale = drm_calc_scale(src_w, dst_w);
     176                 :            : 
     177         [ #  # ]:          0 :         if (hscale < 0 || dst_w == 0)
     178                 :            :                 return hscale;
     179                 :            : 
     180         [ #  # ]:          0 :         if (hscale < min_hscale || hscale > max_hscale)
     181                 :          0 :                 return -ERANGE;
     182                 :            : 
     183                 :            :         return hscale;
     184                 :            : }
     185                 :            : EXPORT_SYMBOL(drm_rect_calc_hscale);
     186                 :            : 
     187                 :            : /**
     188                 :            :  * drm_rect_calc_vscale - calculate the vertical scaling factor
     189                 :            :  * @src: source window rectangle
     190                 :            :  * @dst: destination window rectangle
     191                 :            :  * @min_vscale: minimum allowed vertical scaling factor
     192                 :            :  * @max_vscale: maximum allowed vertical scaling factor
     193                 :            :  *
     194                 :            :  * Calculate the vertical scaling factor as
     195                 :            :  * (@src height) / (@dst height).
     196                 :            :  *
     197                 :            :  * If the scale is below 1 << 16, round down. If the scale is above
     198                 :            :  * 1 << 16, round up. This will calculate the scale with the most
     199                 :            :  * pessimistic limit calculation.
     200                 :            :  *
     201                 :            :  * RETURNS:
     202                 :            :  * The vertical scaling factor, or errno of out of limits.
     203                 :            :  */
     204                 :          0 : int drm_rect_calc_vscale(const struct drm_rect *src,
     205                 :            :                          const struct drm_rect *dst,
     206                 :            :                          int min_vscale, int max_vscale)
     207                 :            : {
     208                 :          0 :         int src_h = drm_rect_height(src);
     209                 :          0 :         int dst_h = drm_rect_height(dst);
     210                 :          0 :         int vscale = drm_calc_scale(src_h, dst_h);
     211                 :            : 
     212         [ #  # ]:          0 :         if (vscale < 0 || dst_h == 0)
     213                 :            :                 return vscale;
     214                 :            : 
     215         [ #  # ]:          0 :         if (vscale < min_vscale || vscale > max_vscale)
     216                 :          0 :                 return -ERANGE;
     217                 :            : 
     218                 :            :         return vscale;
     219                 :            : }
     220                 :            : EXPORT_SYMBOL(drm_rect_calc_vscale);
     221                 :            : 
     222                 :            : /**
     223                 :            :  * drm_rect_debug_print - print the rectangle information
     224                 :            :  * @prefix: prefix string
     225                 :            :  * @r: rectangle to print
     226                 :            :  * @fixed_point: rectangle is in 16.16 fixed point format
     227                 :            :  */
     228                 :          0 : void drm_rect_debug_print(const char *prefix, const struct drm_rect *r, bool fixed_point)
     229                 :            : {
     230         [ #  # ]:          0 :         if (fixed_point)
     231                 :          0 :                 DRM_DEBUG_KMS("%s" DRM_RECT_FP_FMT "\n", prefix, DRM_RECT_FP_ARG(r));
     232                 :            :         else
     233                 :          0 :                 DRM_DEBUG_KMS("%s" DRM_RECT_FMT "\n", prefix, DRM_RECT_ARG(r));
     234                 :          0 : }
     235                 :            : EXPORT_SYMBOL(drm_rect_debug_print);
     236                 :            : 
     237                 :            : /**
     238                 :            :  * drm_rect_rotate - Rotate the rectangle
     239                 :            :  * @r: rectangle to be rotated
     240                 :            :  * @width: Width of the coordinate space
     241                 :            :  * @height: Height of the coordinate space
     242                 :            :  * @rotation: Transformation to be applied
     243                 :            :  *
     244                 :            :  * Apply @rotation to the coordinates of rectangle @r.
     245                 :            :  *
     246                 :            :  * @width and @height combined with @rotation define
     247                 :            :  * the location of the new origin.
     248                 :            :  *
     249                 :            :  * @width correcsponds to the horizontal and @height
     250                 :            :  * to the vertical axis of the untransformed coordinate
     251                 :            :  * space.
     252                 :            :  */
     253                 :          0 : void drm_rect_rotate(struct drm_rect *r,
     254                 :            :                      int width, int height,
     255                 :            :                      unsigned int rotation)
     256                 :            : {
     257                 :          0 :         struct drm_rect tmp;
     258                 :            : 
     259         [ #  # ]:          0 :         if (rotation & (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)) {
     260                 :          0 :                 tmp = *r;
     261                 :            : 
     262         [ #  # ]:          0 :                 if (rotation & DRM_MODE_REFLECT_X) {
     263                 :          0 :                         r->x1 = width - tmp.x2;
     264                 :          0 :                         r->x2 = width - tmp.x1;
     265                 :            :                 }
     266                 :            : 
     267         [ #  # ]:          0 :                 if (rotation & DRM_MODE_REFLECT_Y) {
     268                 :          0 :                         r->y1 = height - tmp.y2;
     269                 :          0 :                         r->y2 = height - tmp.y1;
     270                 :            :                 }
     271                 :            :         }
     272                 :            : 
     273   [ #  #  #  # ]:          0 :         switch (rotation & DRM_MODE_ROTATE_MASK) {
     274                 :            :         case DRM_MODE_ROTATE_0:
     275                 :            :                 break;
     276                 :          0 :         case DRM_MODE_ROTATE_90:
     277                 :          0 :                 tmp = *r;
     278                 :          0 :                 r->x1 = tmp.y1;
     279                 :          0 :                 r->x2 = tmp.y2;
     280                 :          0 :                 r->y1 = width - tmp.x2;
     281                 :          0 :                 r->y2 = width - tmp.x1;
     282                 :          0 :                 break;
     283                 :          0 :         case DRM_MODE_ROTATE_180:
     284                 :          0 :                 tmp = *r;
     285                 :          0 :                 r->x1 = width - tmp.x2;
     286                 :          0 :                 r->x2 = width - tmp.x1;
     287                 :          0 :                 r->y1 = height - tmp.y2;
     288                 :          0 :                 r->y2 = height - tmp.y1;
     289                 :          0 :                 break;
     290                 :          0 :         case DRM_MODE_ROTATE_270:
     291                 :          0 :                 tmp = *r;
     292                 :          0 :                 r->x1 = height - tmp.y2;
     293                 :          0 :                 r->x2 = height - tmp.y1;
     294                 :          0 :                 r->y1 = tmp.x1;
     295                 :          0 :                 r->y2 = tmp.x2;
     296                 :          0 :                 break;
     297                 :            :         default:
     298                 :            :                 break;
     299                 :            :         }
     300                 :          0 : }
     301                 :            : EXPORT_SYMBOL(drm_rect_rotate);
     302                 :            : 
     303                 :            : /**
     304                 :            :  * drm_rect_rotate_inv - Inverse rotate the rectangle
     305                 :            :  * @r: rectangle to be rotated
     306                 :            :  * @width: Width of the coordinate space
     307                 :            :  * @height: Height of the coordinate space
     308                 :            :  * @rotation: Transformation whose inverse is to be applied
     309                 :            :  *
     310                 :            :  * Apply the inverse of @rotation to the coordinates
     311                 :            :  * of rectangle @r.
     312                 :            :  *
     313                 :            :  * @width and @height combined with @rotation define
     314                 :            :  * the location of the new origin.
     315                 :            :  *
     316                 :            :  * @width correcsponds to the horizontal and @height
     317                 :            :  * to the vertical axis of the original untransformed
     318                 :            :  * coordinate space, so that you never have to flip
     319                 :            :  * them when doing a rotatation and its inverse.
     320                 :            :  * That is, if you do ::
     321                 :            :  *
     322                 :            :  *     drm_rect_rotate(&r, width, height, rotation);
     323                 :            :  *     drm_rect_rotate_inv(&r, width, height, rotation);
     324                 :            :  *
     325                 :            :  * you will always get back the original rectangle.
     326                 :            :  */
     327                 :          0 : void drm_rect_rotate_inv(struct drm_rect *r,
     328                 :            :                          int width, int height,
     329                 :            :                          unsigned int rotation)
     330                 :            : {
     331                 :          0 :         struct drm_rect tmp;
     332                 :            : 
     333   [ #  #  #  # ]:          0 :         switch (rotation & DRM_MODE_ROTATE_MASK) {
     334                 :            :         case DRM_MODE_ROTATE_0:
     335                 :            :                 break;
     336                 :          0 :         case DRM_MODE_ROTATE_90:
     337                 :          0 :                 tmp = *r;
     338                 :          0 :                 r->x1 = width - tmp.y2;
     339                 :          0 :                 r->x2 = width - tmp.y1;
     340                 :          0 :                 r->y1 = tmp.x1;
     341                 :          0 :                 r->y2 = tmp.x2;
     342                 :          0 :                 break;
     343                 :          0 :         case DRM_MODE_ROTATE_180:
     344                 :          0 :                 tmp = *r;
     345                 :          0 :                 r->x1 = width - tmp.x2;
     346                 :          0 :                 r->x2 = width - tmp.x1;
     347                 :          0 :                 r->y1 = height - tmp.y2;
     348                 :          0 :                 r->y2 = height - tmp.y1;
     349                 :          0 :                 break;
     350                 :          0 :         case DRM_MODE_ROTATE_270:
     351                 :          0 :                 tmp = *r;
     352                 :          0 :                 r->x1 = tmp.y1;
     353                 :          0 :                 r->x2 = tmp.y2;
     354                 :          0 :                 r->y1 = height - tmp.x2;
     355                 :          0 :                 r->y2 = height - tmp.x1;
     356                 :          0 :                 break;
     357                 :            :         default:
     358                 :            :                 break;
     359                 :            :         }
     360                 :            : 
     361         [ #  # ]:          0 :         if (rotation & (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)) {
     362                 :          0 :                 tmp = *r;
     363                 :            : 
     364         [ #  # ]:          0 :                 if (rotation & DRM_MODE_REFLECT_X) {
     365                 :          0 :                         r->x1 = width - tmp.x2;
     366                 :          0 :                         r->x2 = width - tmp.x1;
     367                 :            :                 }
     368                 :            : 
     369         [ #  # ]:          0 :                 if (rotation & DRM_MODE_REFLECT_Y) {
     370                 :          0 :                         r->y1 = height - tmp.y2;
     371                 :          0 :                         r->y2 = height - tmp.y1;
     372                 :            :                 }
     373                 :            :         }
     374                 :          0 : }
     375                 :            : EXPORT_SYMBOL(drm_rect_rotate_inv);

Generated by: LCOV version 1.14