Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: Add drm_rect_calc_{hscale, vscale}() utility functions

These functions calculate the scaling factor based on the source and
destination rectangles.

There are two version of the functions, the strict ones that will
return an error if the min/max scaling factor is exceeded, and the
relaxed versions that will adjust the src/dst rectangles in order to
keep the scaling factor withing the limits.

v2: Return error instead of adjusting regions, refactor common parts
into one function, and split into strict and relaxed versions.
v3: Renamed drm_region to drm_rect, add "_rect_" to the function
names.
v4: Fix "calculcate" typos

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Acked-by: Dave Airlie <airlied@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Ville Syrjälä and committed by
Daniel Vetter
4954c428 3512f976

+189
+177
drivers/gpu/drm/drm_rect.c
··· 94 94 return drm_rect_intersect(dst, clip); 95 95 } 96 96 EXPORT_SYMBOL(drm_rect_clip_scaled); 97 + 98 + static int drm_calc_scale(int src, int dst) 99 + { 100 + int scale = 0; 101 + 102 + if (src < 0 || dst < 0) 103 + return -EINVAL; 104 + 105 + if (dst == 0) 106 + return 0; 107 + 108 + scale = src / dst; 109 + 110 + return scale; 111 + } 112 + 113 + /** 114 + * drm_rect_calc_hscale - calculate the horizontal scaling factor 115 + * @src: source window rectangle 116 + * @dst: destination window rectangle 117 + * @min_hscale: minimum allowed horizontal scaling factor 118 + * @max_hscale: maximum allowed horizontal scaling factor 119 + * 120 + * Calculate the horizontal scaling factor as 121 + * (@src width) / (@dst width). 122 + * 123 + * RETURNS: 124 + * The horizontal scaling factor, or errno of out of limits. 125 + */ 126 + int drm_rect_calc_hscale(const struct drm_rect *src, 127 + const struct drm_rect *dst, 128 + int min_hscale, int max_hscale) 129 + { 130 + int src_w = drm_rect_width(src); 131 + int dst_w = drm_rect_width(dst); 132 + int hscale = drm_calc_scale(src_w, dst_w); 133 + 134 + if (hscale < 0 || dst_w == 0) 135 + return hscale; 136 + 137 + if (hscale < min_hscale || hscale > max_hscale) 138 + return -ERANGE; 139 + 140 + return hscale; 141 + } 142 + EXPORT_SYMBOL(drm_rect_calc_hscale); 143 + 144 + /** 145 + * drm_rect_calc_vscale - calculate the vertical scaling factor 146 + * @src: source window rectangle 147 + * @dst: destination window rectangle 148 + * @min_vscale: minimum allowed vertical scaling factor 149 + * @max_vscale: maximum allowed vertical scaling factor 150 + * 151 + * Calculate the vertical scaling factor as 152 + * (@src height) / (@dst height). 153 + * 154 + * RETURNS: 155 + * The vertical scaling factor, or errno of out of limits. 156 + */ 157 + int drm_rect_calc_vscale(const struct drm_rect *src, 158 + const struct drm_rect *dst, 159 + int min_vscale, int max_vscale) 160 + { 161 + int src_h = drm_rect_height(src); 162 + int dst_h = drm_rect_height(dst); 163 + int vscale = drm_calc_scale(src_h, dst_h); 164 + 165 + if (vscale < 0 || dst_h == 0) 166 + return vscale; 167 + 168 + if (vscale < min_vscale || vscale > max_vscale) 169 + return -ERANGE; 170 + 171 + return vscale; 172 + } 173 + EXPORT_SYMBOL(drm_rect_calc_vscale); 174 + 175 + /** 176 + * drm_calc_hscale_relaxed - calculate the horizontal scaling factor 177 + * @src: source window rectangle 178 + * @dst: destination window rectangle 179 + * @min_hscale: minimum allowed horizontal scaling factor 180 + * @max_hscale: maximum allowed horizontal scaling factor 181 + * 182 + * Calculate the horizontal scaling factor as 183 + * (@src width) / (@dst width). 184 + * 185 + * If the calculated scaling factor is below @min_vscale, 186 + * decrease the height of rectangle @dst to compensate. 187 + * 188 + * If the calculated scaling factor is above @max_vscale, 189 + * decrease the height of rectangle @src to compensate. 190 + * 191 + * RETURNS: 192 + * The horizontal scaling factor. 193 + */ 194 + int drm_rect_calc_hscale_relaxed(struct drm_rect *src, 195 + struct drm_rect *dst, 196 + int min_hscale, int max_hscale) 197 + { 198 + int src_w = drm_rect_width(src); 199 + int dst_w = drm_rect_width(dst); 200 + int hscale = drm_calc_scale(src_w, dst_w); 201 + 202 + if (hscale < 0 || dst_w == 0) 203 + return hscale; 204 + 205 + if (hscale < min_hscale) { 206 + int max_dst_w = src_w / min_hscale; 207 + 208 + drm_rect_adjust_size(dst, max_dst_w - dst_w, 0); 209 + 210 + return min_hscale; 211 + } 212 + 213 + if (hscale > max_hscale) { 214 + int max_src_w = dst_w * max_hscale; 215 + 216 + drm_rect_adjust_size(src, max_src_w - src_w, 0); 217 + 218 + return max_hscale; 219 + } 220 + 221 + return hscale; 222 + } 223 + EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed); 224 + 225 + /** 226 + * drm_rect_calc_vscale_relaxed - calculate the vertical scaling factor 227 + * @src: source window rectangle 228 + * @dst: destination window rectangle 229 + * @min_vscale: minimum allowed vertical scaling factor 230 + * @max_vscale: maximum allowed vertical scaling factor 231 + * 232 + * Calculate the vertical scaling factor as 233 + * (@src height) / (@dst height). 234 + * 235 + * If the calculated scaling factor is below @min_vscale, 236 + * decrease the height of rectangle @dst to compensate. 237 + * 238 + * If the calculated scaling factor is above @max_vscale, 239 + * decrease the height of rectangle @src to compensate. 240 + * 241 + * RETURNS: 242 + * The vertical scaling factor. 243 + */ 244 + int drm_rect_calc_vscale_relaxed(struct drm_rect *src, 245 + struct drm_rect *dst, 246 + int min_vscale, int max_vscale) 247 + { 248 + int src_h = drm_rect_height(src); 249 + int dst_h = drm_rect_height(dst); 250 + int vscale = drm_calc_scale(src_h, dst_h); 251 + 252 + if (vscale < 0 || dst_h == 0) 253 + return vscale; 254 + 255 + if (vscale < min_vscale) { 256 + int max_dst_h = src_h / min_vscale; 257 + 258 + drm_rect_adjust_size(dst, 0, max_dst_h - dst_h); 259 + 260 + return min_vscale; 261 + } 262 + 263 + if (vscale > max_vscale) { 264 + int max_src_h = dst_h * max_vscale; 265 + 266 + drm_rect_adjust_size(src, 0, max_src_h - src_h); 267 + 268 + return max_vscale; 269 + } 270 + 271 + return vscale; 272 + } 273 + EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed);
+12
include/drm/drm_rect.h
··· 128 128 bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, 129 129 const struct drm_rect *clip, 130 130 int hscale, int vscale); 131 + int drm_rect_calc_hscale(const struct drm_rect *src, 132 + const struct drm_rect *dst, 133 + int min_hscale, int max_hscale); 134 + int drm_rect_calc_vscale(const struct drm_rect *src, 135 + const struct drm_rect *dst, 136 + int min_vscale, int max_vscale); 137 + int drm_rect_calc_hscale_relaxed(struct drm_rect *src, 138 + struct drm_rect *dst, 139 + int min_hscale, int max_hscale); 140 + int drm_rect_calc_vscale_relaxed(struct drm_rect *src, 141 + struct drm_rect *dst, 142 + int min_vscale, int max_vscale); 131 143 132 144 #endif