.. | .. |
---|
24 | 24 | #include <linux/errno.h> |
---|
25 | 25 | #include <linux/export.h> |
---|
26 | 26 | #include <linux/kernel.h> |
---|
27 | | -#include <drm/drmP.h> |
---|
| 27 | + |
---|
| 28 | +#include <drm/drm_mode.h> |
---|
| 29 | +#include <drm/drm_print.h> |
---|
28 | 30 | #include <drm/drm_rect.h> |
---|
29 | 31 | |
---|
30 | 32 | /** |
---|
.. | .. |
---|
50 | 52 | } |
---|
51 | 53 | EXPORT_SYMBOL(drm_rect_intersect); |
---|
52 | 54 | |
---|
53 | | -static u32 clip_scaled(u32 src, u32 dst, u32 clip) |
---|
| 55 | +static u32 clip_scaled(int src, int dst, int *clip) |
---|
54 | 56 | { |
---|
55 | 57 | u64 tmp; |
---|
56 | 58 | |
---|
57 | 59 | if (dst == 0) |
---|
58 | 60 | return 0; |
---|
59 | 61 | |
---|
60 | | - tmp = mul_u32_u32(src, dst - clip); |
---|
| 62 | + /* Only clip what we have. Keeps the result bounded. */ |
---|
| 63 | + *clip = min(*clip, dst); |
---|
| 64 | + |
---|
| 65 | + tmp = mul_u32_u32(src, dst - *clip); |
---|
61 | 66 | |
---|
62 | 67 | /* |
---|
63 | 68 | * Round toward 1.0 when clipping so that we don't accidentally |
---|
.. | .. |
---|
76 | 81 | * @clip: clip rectangle |
---|
77 | 82 | * |
---|
78 | 83 | * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the |
---|
79 | | - * same amounts multiplied by @hscale and @vscale. |
---|
| 84 | + * the corresponding amounts, retaining the vertical and horizontal scaling |
---|
| 85 | + * factors from @src to @dst. |
---|
80 | 86 | * |
---|
81 | 87 | * RETURNS: |
---|
| 88 | + * |
---|
82 | 89 | * %true if rectangle @dst is still visible after being clipped, |
---|
83 | | - * %false otherwise |
---|
| 90 | + * %false otherwise. |
---|
84 | 91 | */ |
---|
85 | 92 | bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, |
---|
86 | 93 | const struct drm_rect *clip) |
---|
.. | .. |
---|
90 | 97 | diff = clip->x1 - dst->x1; |
---|
91 | 98 | if (diff > 0) { |
---|
92 | 99 | u32 new_src_w = clip_scaled(drm_rect_width(src), |
---|
93 | | - drm_rect_width(dst), diff); |
---|
| 100 | + drm_rect_width(dst), &diff); |
---|
94 | 101 | |
---|
95 | | - src->x1 = clamp_t(int64_t, src->x2 - new_src_w, INT_MIN, INT_MAX); |
---|
96 | | - dst->x1 = clip->x1; |
---|
| 102 | + src->x1 = src->x2 - new_src_w; |
---|
| 103 | + dst->x1 += diff; |
---|
97 | 104 | } |
---|
98 | 105 | diff = clip->y1 - dst->y1; |
---|
99 | 106 | if (diff > 0) { |
---|
100 | 107 | u32 new_src_h = clip_scaled(drm_rect_height(src), |
---|
101 | | - drm_rect_height(dst), diff); |
---|
| 108 | + drm_rect_height(dst), &diff); |
---|
102 | 109 | |
---|
103 | | - src->y1 = clamp_t(int64_t, src->y2 - new_src_h, INT_MIN, INT_MAX); |
---|
104 | | - dst->y1 = clip->y1; |
---|
| 110 | + src->y1 = src->y2 - new_src_h; |
---|
| 111 | + dst->y1 += diff; |
---|
105 | 112 | } |
---|
106 | 113 | diff = dst->x2 - clip->x2; |
---|
107 | 114 | if (diff > 0) { |
---|
108 | 115 | u32 new_src_w = clip_scaled(drm_rect_width(src), |
---|
109 | | - drm_rect_width(dst), diff); |
---|
| 116 | + drm_rect_width(dst), &diff); |
---|
110 | 117 | |
---|
111 | | - src->x2 = clamp_t(int64_t, src->x1 + new_src_w, INT_MIN, INT_MAX); |
---|
112 | | - dst->x2 = clip->x2; |
---|
| 118 | + src->x2 = src->x1 + new_src_w; |
---|
| 119 | + dst->x2 -= diff; |
---|
113 | 120 | } |
---|
114 | 121 | diff = dst->y2 - clip->y2; |
---|
115 | 122 | if (diff > 0) { |
---|
116 | 123 | u32 new_src_h = clip_scaled(drm_rect_height(src), |
---|
117 | | - drm_rect_height(dst), diff); |
---|
| 124 | + drm_rect_height(dst), &diff); |
---|
118 | 125 | |
---|
119 | | - src->y2 = clamp_t(int64_t, src->y1 + new_src_h, INT_MIN, INT_MAX); |
---|
120 | | - dst->y2 = clip->y2; |
---|
| 126 | + src->y2 = src->y1 + new_src_h; |
---|
| 127 | + dst->y2 -= diff; |
---|
121 | 128 | } |
---|
122 | 129 | |
---|
123 | 130 | return drm_rect_visible(dst); |
---|
.. | .. |
---|
211 | 218 | return vscale; |
---|
212 | 219 | } |
---|
213 | 220 | EXPORT_SYMBOL(drm_rect_calc_vscale); |
---|
214 | | - |
---|
215 | | -/** |
---|
216 | | - * drm_calc_hscale_relaxed - calculate the horizontal scaling factor |
---|
217 | | - * @src: source window rectangle |
---|
218 | | - * @dst: destination window rectangle |
---|
219 | | - * @min_hscale: minimum allowed horizontal scaling factor |
---|
220 | | - * @max_hscale: maximum allowed horizontal scaling factor |
---|
221 | | - * |
---|
222 | | - * Calculate the horizontal scaling factor as |
---|
223 | | - * (@src width) / (@dst width). |
---|
224 | | - * |
---|
225 | | - * If the calculated scaling factor is below @min_vscale, |
---|
226 | | - * decrease the height of rectangle @dst to compensate. |
---|
227 | | - * |
---|
228 | | - * If the calculated scaling factor is above @max_vscale, |
---|
229 | | - * decrease the height of rectangle @src to compensate. |
---|
230 | | - * |
---|
231 | | - * If the scale is below 1 << 16, round down. If the scale is above |
---|
232 | | - * 1 << 16, round up. This will calculate the scale with the most |
---|
233 | | - * pessimistic limit calculation. |
---|
234 | | - * |
---|
235 | | - * RETURNS: |
---|
236 | | - * The horizontal scaling factor. |
---|
237 | | - */ |
---|
238 | | -int drm_rect_calc_hscale_relaxed(struct drm_rect *src, |
---|
239 | | - struct drm_rect *dst, |
---|
240 | | - int min_hscale, int max_hscale) |
---|
241 | | -{ |
---|
242 | | - int src_w = drm_rect_width(src); |
---|
243 | | - int dst_w = drm_rect_width(dst); |
---|
244 | | - int hscale = drm_calc_scale(src_w, dst_w); |
---|
245 | | - |
---|
246 | | - if (hscale < 0 || dst_w == 0) |
---|
247 | | - return hscale; |
---|
248 | | - |
---|
249 | | - if (hscale < min_hscale) { |
---|
250 | | - int max_dst_w = src_w / min_hscale; |
---|
251 | | - |
---|
252 | | - drm_rect_adjust_size(dst, max_dst_w - dst_w, 0); |
---|
253 | | - |
---|
254 | | - return min_hscale; |
---|
255 | | - } |
---|
256 | | - |
---|
257 | | - if (hscale > max_hscale) { |
---|
258 | | - int max_src_w = dst_w * max_hscale; |
---|
259 | | - |
---|
260 | | - drm_rect_adjust_size(src, max_src_w - src_w, 0); |
---|
261 | | - |
---|
262 | | - return max_hscale; |
---|
263 | | - } |
---|
264 | | - |
---|
265 | | - return hscale; |
---|
266 | | -} |
---|
267 | | -EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed); |
---|
268 | | - |
---|
269 | | -/** |
---|
270 | | - * drm_rect_calc_vscale_relaxed - calculate the vertical scaling factor |
---|
271 | | - * @src: source window rectangle |
---|
272 | | - * @dst: destination window rectangle |
---|
273 | | - * @min_vscale: minimum allowed vertical scaling factor |
---|
274 | | - * @max_vscale: maximum allowed vertical scaling factor |
---|
275 | | - * |
---|
276 | | - * Calculate the vertical scaling factor as |
---|
277 | | - * (@src height) / (@dst height). |
---|
278 | | - * |
---|
279 | | - * If the calculated scaling factor is below @min_vscale, |
---|
280 | | - * decrease the height of rectangle @dst to compensate. |
---|
281 | | - * |
---|
282 | | - * If the calculated scaling factor is above @max_vscale, |
---|
283 | | - * decrease the height of rectangle @src to compensate. |
---|
284 | | - * |
---|
285 | | - * If the scale is below 1 << 16, round down. If the scale is above |
---|
286 | | - * 1 << 16, round up. This will calculate the scale with the most |
---|
287 | | - * pessimistic limit calculation. |
---|
288 | | - * |
---|
289 | | - * RETURNS: |
---|
290 | | - * The vertical scaling factor. |
---|
291 | | - */ |
---|
292 | | -int drm_rect_calc_vscale_relaxed(struct drm_rect *src, |
---|
293 | | - struct drm_rect *dst, |
---|
294 | | - int min_vscale, int max_vscale) |
---|
295 | | -{ |
---|
296 | | - int src_h = drm_rect_height(src); |
---|
297 | | - int dst_h = drm_rect_height(dst); |
---|
298 | | - int vscale = drm_calc_scale(src_h, dst_h); |
---|
299 | | - |
---|
300 | | - if (vscale < 0 || dst_h == 0) |
---|
301 | | - return vscale; |
---|
302 | | - |
---|
303 | | - if (vscale < min_vscale) { |
---|
304 | | - int max_dst_h = src_h / min_vscale; |
---|
305 | | - |
---|
306 | | - drm_rect_adjust_size(dst, 0, max_dst_h - dst_h); |
---|
307 | | - |
---|
308 | | - return min_vscale; |
---|
309 | | - } |
---|
310 | | - |
---|
311 | | - if (vscale > max_vscale) { |
---|
312 | | - int max_src_h = dst_h * max_vscale; |
---|
313 | | - |
---|
314 | | - drm_rect_adjust_size(src, 0, max_src_h - src_h); |
---|
315 | | - |
---|
316 | | - return max_vscale; |
---|
317 | | - } |
---|
318 | | - |
---|
319 | | - return vscale; |
---|
320 | | -} |
---|
321 | | -EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed); |
---|
322 | 221 | |
---|
323 | 222 | /** |
---|
324 | 223 | * drm_rect_debug_print - print the rectangle information |
---|