162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (C) 2011-2013 Intel Corporation
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * The above copyright notice and this permission notice (including the next
1262306a36Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
1362306a36Sopenharmony_ci * Software.
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1662306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1762306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1862306a36Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1962306a36Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2062306a36Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2162306a36Sopenharmony_ci * SOFTWARE.
2262306a36Sopenharmony_ci */
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include <linux/errno.h>
2562306a36Sopenharmony_ci#include <linux/export.h>
2662306a36Sopenharmony_ci#include <linux/kernel.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include <drm/drm_mode.h>
2962306a36Sopenharmony_ci#include <drm/drm_print.h>
3062306a36Sopenharmony_ci#include <drm/drm_rect.h>
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/**
3362306a36Sopenharmony_ci * drm_rect_intersect - intersect two rectangles
3462306a36Sopenharmony_ci * @r1: first rectangle
3562306a36Sopenharmony_ci * @r2: second rectangle
3662306a36Sopenharmony_ci *
3762306a36Sopenharmony_ci * Calculate the intersection of rectangles @r1 and @r2.
3862306a36Sopenharmony_ci * @r1 will be overwritten with the intersection.
3962306a36Sopenharmony_ci *
4062306a36Sopenharmony_ci * RETURNS:
4162306a36Sopenharmony_ci * %true if rectangle @r1 is still visible after the operation,
4262306a36Sopenharmony_ci * %false otherwise.
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_cibool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	r1->x1 = max(r1->x1, r2->x1);
4762306a36Sopenharmony_ci	r1->y1 = max(r1->y1, r2->y1);
4862306a36Sopenharmony_ci	r1->x2 = min(r1->x2, r2->x2);
4962306a36Sopenharmony_ci	r1->y2 = min(r1->y2, r2->y2);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	return drm_rect_visible(r1);
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ciEXPORT_SYMBOL(drm_rect_intersect);
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic u32 clip_scaled(int src, int dst, int *clip)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	u64 tmp;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	if (dst == 0)
6062306a36Sopenharmony_ci		return 0;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	/* Only clip what we have. Keeps the result bounded. */
6362306a36Sopenharmony_ci	*clip = min(*clip, dst);
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	tmp = mul_u32_u32(src, dst - *clip);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	/*
6862306a36Sopenharmony_ci	 * Round toward 1.0 when clipping so that we don't accidentally
6962306a36Sopenharmony_ci	 * change upscaling to downscaling or vice versa.
7062306a36Sopenharmony_ci	 */
7162306a36Sopenharmony_ci	if (src < (dst << 16))
7262306a36Sopenharmony_ci		return DIV_ROUND_UP_ULL(tmp, dst);
7362306a36Sopenharmony_ci	else
7462306a36Sopenharmony_ci		return DIV_ROUND_DOWN_ULL(tmp, dst);
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci/**
7862306a36Sopenharmony_ci * drm_rect_clip_scaled - perform a scaled clip operation
7962306a36Sopenharmony_ci * @src: source window rectangle
8062306a36Sopenharmony_ci * @dst: destination window rectangle
8162306a36Sopenharmony_ci * @clip: clip rectangle
8262306a36Sopenharmony_ci *
8362306a36Sopenharmony_ci * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by
8462306a36Sopenharmony_ci * the corresponding amounts, retaining the vertical and horizontal scaling
8562306a36Sopenharmony_ci * factors from @src to @dst.
8662306a36Sopenharmony_ci *
8762306a36Sopenharmony_ci * RETURNS:
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * %true if rectangle @dst is still visible after being clipped,
9062306a36Sopenharmony_ci * %false otherwise.
9162306a36Sopenharmony_ci */
9262306a36Sopenharmony_cibool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst,
9362306a36Sopenharmony_ci			  const struct drm_rect *clip)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	int diff;
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	diff = clip->x1 - dst->x1;
9862306a36Sopenharmony_ci	if (diff > 0) {
9962306a36Sopenharmony_ci		u32 new_src_w = clip_scaled(drm_rect_width(src),
10062306a36Sopenharmony_ci					    drm_rect_width(dst), &diff);
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci		src->x1 = src->x2 - new_src_w;
10362306a36Sopenharmony_ci		dst->x1 += diff;
10462306a36Sopenharmony_ci	}
10562306a36Sopenharmony_ci	diff = clip->y1 - dst->y1;
10662306a36Sopenharmony_ci	if (diff > 0) {
10762306a36Sopenharmony_ci		u32 new_src_h = clip_scaled(drm_rect_height(src),
10862306a36Sopenharmony_ci					    drm_rect_height(dst), &diff);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci		src->y1 = src->y2 - new_src_h;
11162306a36Sopenharmony_ci		dst->y1 += diff;
11262306a36Sopenharmony_ci	}
11362306a36Sopenharmony_ci	diff = dst->x2 - clip->x2;
11462306a36Sopenharmony_ci	if (diff > 0) {
11562306a36Sopenharmony_ci		u32 new_src_w = clip_scaled(drm_rect_width(src),
11662306a36Sopenharmony_ci					    drm_rect_width(dst), &diff);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci		src->x2 = src->x1 + new_src_w;
11962306a36Sopenharmony_ci		dst->x2 -= diff;
12062306a36Sopenharmony_ci	}
12162306a36Sopenharmony_ci	diff = dst->y2 - clip->y2;
12262306a36Sopenharmony_ci	if (diff > 0) {
12362306a36Sopenharmony_ci		u32 new_src_h = clip_scaled(drm_rect_height(src),
12462306a36Sopenharmony_ci					    drm_rect_height(dst), &diff);
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci		src->y2 = src->y1 + new_src_h;
12762306a36Sopenharmony_ci		dst->y2 -= diff;
12862306a36Sopenharmony_ci	}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	return drm_rect_visible(dst);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ciEXPORT_SYMBOL(drm_rect_clip_scaled);
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic int drm_calc_scale(int src, int dst)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	int scale = 0;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	if (WARN_ON(src < 0 || dst < 0))
13962306a36Sopenharmony_ci		return -EINVAL;
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	if (dst == 0)
14262306a36Sopenharmony_ci		return 0;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	if (src > (dst << 16))
14562306a36Sopenharmony_ci		return DIV_ROUND_UP(src, dst);
14662306a36Sopenharmony_ci	else
14762306a36Sopenharmony_ci		scale = src / dst;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	return scale;
15062306a36Sopenharmony_ci}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci/**
15362306a36Sopenharmony_ci * drm_rect_calc_hscale - calculate the horizontal scaling factor
15462306a36Sopenharmony_ci * @src: source window rectangle
15562306a36Sopenharmony_ci * @dst: destination window rectangle
15662306a36Sopenharmony_ci * @min_hscale: minimum allowed horizontal scaling factor
15762306a36Sopenharmony_ci * @max_hscale: maximum allowed horizontal scaling factor
15862306a36Sopenharmony_ci *
15962306a36Sopenharmony_ci * Calculate the horizontal scaling factor as
16062306a36Sopenharmony_ci * (@src width) / (@dst width).
16162306a36Sopenharmony_ci *
16262306a36Sopenharmony_ci * If the scale is below 1 << 16, round down. If the scale is above
16362306a36Sopenharmony_ci * 1 << 16, round up. This will calculate the scale with the most
16462306a36Sopenharmony_ci * pessimistic limit calculation.
16562306a36Sopenharmony_ci *
16662306a36Sopenharmony_ci * RETURNS:
16762306a36Sopenharmony_ci * The horizontal scaling factor, or errno of out of limits.
16862306a36Sopenharmony_ci */
16962306a36Sopenharmony_ciint drm_rect_calc_hscale(const struct drm_rect *src,
17062306a36Sopenharmony_ci			 const struct drm_rect *dst,
17162306a36Sopenharmony_ci			 int min_hscale, int max_hscale)
17262306a36Sopenharmony_ci{
17362306a36Sopenharmony_ci	int src_w = drm_rect_width(src);
17462306a36Sopenharmony_ci	int dst_w = drm_rect_width(dst);
17562306a36Sopenharmony_ci	int hscale = drm_calc_scale(src_w, dst_w);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	if (hscale < 0 || dst_w == 0)
17862306a36Sopenharmony_ci		return hscale;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	if (hscale < min_hscale || hscale > max_hscale)
18162306a36Sopenharmony_ci		return -ERANGE;
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	return hscale;
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ciEXPORT_SYMBOL(drm_rect_calc_hscale);
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci/**
18862306a36Sopenharmony_ci * drm_rect_calc_vscale - calculate the vertical scaling factor
18962306a36Sopenharmony_ci * @src: source window rectangle
19062306a36Sopenharmony_ci * @dst: destination window rectangle
19162306a36Sopenharmony_ci * @min_vscale: minimum allowed vertical scaling factor
19262306a36Sopenharmony_ci * @max_vscale: maximum allowed vertical scaling factor
19362306a36Sopenharmony_ci *
19462306a36Sopenharmony_ci * Calculate the vertical scaling factor as
19562306a36Sopenharmony_ci * (@src height) / (@dst height).
19662306a36Sopenharmony_ci *
19762306a36Sopenharmony_ci * If the scale is below 1 << 16, round down. If the scale is above
19862306a36Sopenharmony_ci * 1 << 16, round up. This will calculate the scale with the most
19962306a36Sopenharmony_ci * pessimistic limit calculation.
20062306a36Sopenharmony_ci *
20162306a36Sopenharmony_ci * RETURNS:
20262306a36Sopenharmony_ci * The vertical scaling factor, or errno of out of limits.
20362306a36Sopenharmony_ci */
20462306a36Sopenharmony_ciint drm_rect_calc_vscale(const struct drm_rect *src,
20562306a36Sopenharmony_ci			 const struct drm_rect *dst,
20662306a36Sopenharmony_ci			 int min_vscale, int max_vscale)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	int src_h = drm_rect_height(src);
20962306a36Sopenharmony_ci	int dst_h = drm_rect_height(dst);
21062306a36Sopenharmony_ci	int vscale = drm_calc_scale(src_h, dst_h);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	if (vscale < 0 || dst_h == 0)
21362306a36Sopenharmony_ci		return vscale;
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	if (vscale < min_vscale || vscale > max_vscale)
21662306a36Sopenharmony_ci		return -ERANGE;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	return vscale;
21962306a36Sopenharmony_ci}
22062306a36Sopenharmony_ciEXPORT_SYMBOL(drm_rect_calc_vscale);
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci/**
22362306a36Sopenharmony_ci * drm_rect_debug_print - print the rectangle information
22462306a36Sopenharmony_ci * @prefix: prefix string
22562306a36Sopenharmony_ci * @r: rectangle to print
22662306a36Sopenharmony_ci * @fixed_point: rectangle is in 16.16 fixed point format
22762306a36Sopenharmony_ci */
22862306a36Sopenharmony_civoid drm_rect_debug_print(const char *prefix, const struct drm_rect *r, bool fixed_point)
22962306a36Sopenharmony_ci{
23062306a36Sopenharmony_ci	if (fixed_point)
23162306a36Sopenharmony_ci		DRM_DEBUG_KMS("%s" DRM_RECT_FP_FMT "\n", prefix, DRM_RECT_FP_ARG(r));
23262306a36Sopenharmony_ci	else
23362306a36Sopenharmony_ci		DRM_DEBUG_KMS("%s" DRM_RECT_FMT "\n", prefix, DRM_RECT_ARG(r));
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ciEXPORT_SYMBOL(drm_rect_debug_print);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci/**
23862306a36Sopenharmony_ci * drm_rect_rotate - Rotate the rectangle
23962306a36Sopenharmony_ci * @r: rectangle to be rotated
24062306a36Sopenharmony_ci * @width: Width of the coordinate space
24162306a36Sopenharmony_ci * @height: Height of the coordinate space
24262306a36Sopenharmony_ci * @rotation: Transformation to be applied
24362306a36Sopenharmony_ci *
24462306a36Sopenharmony_ci * Apply @rotation to the coordinates of rectangle @r.
24562306a36Sopenharmony_ci *
24662306a36Sopenharmony_ci * @width and @height combined with @rotation define
24762306a36Sopenharmony_ci * the location of the new origin.
24862306a36Sopenharmony_ci *
24962306a36Sopenharmony_ci * @width correcsponds to the horizontal and @height
25062306a36Sopenharmony_ci * to the vertical axis of the untransformed coordinate
25162306a36Sopenharmony_ci * space.
25262306a36Sopenharmony_ci */
25362306a36Sopenharmony_civoid drm_rect_rotate(struct drm_rect *r,
25462306a36Sopenharmony_ci		     int width, int height,
25562306a36Sopenharmony_ci		     unsigned int rotation)
25662306a36Sopenharmony_ci{
25762306a36Sopenharmony_ci	struct drm_rect tmp;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	if (rotation & (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)) {
26062306a36Sopenharmony_ci		tmp = *r;
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci		if (rotation & DRM_MODE_REFLECT_X) {
26362306a36Sopenharmony_ci			r->x1 = width - tmp.x2;
26462306a36Sopenharmony_ci			r->x2 = width - tmp.x1;
26562306a36Sopenharmony_ci		}
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci		if (rotation & DRM_MODE_REFLECT_Y) {
26862306a36Sopenharmony_ci			r->y1 = height - tmp.y2;
26962306a36Sopenharmony_ci			r->y2 = height - tmp.y1;
27062306a36Sopenharmony_ci		}
27162306a36Sopenharmony_ci	}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	switch (rotation & DRM_MODE_ROTATE_MASK) {
27462306a36Sopenharmony_ci	case DRM_MODE_ROTATE_0:
27562306a36Sopenharmony_ci		break;
27662306a36Sopenharmony_ci	case DRM_MODE_ROTATE_90:
27762306a36Sopenharmony_ci		tmp = *r;
27862306a36Sopenharmony_ci		r->x1 = tmp.y1;
27962306a36Sopenharmony_ci		r->x2 = tmp.y2;
28062306a36Sopenharmony_ci		r->y1 = width - tmp.x2;
28162306a36Sopenharmony_ci		r->y2 = width - tmp.x1;
28262306a36Sopenharmony_ci		break;
28362306a36Sopenharmony_ci	case DRM_MODE_ROTATE_180:
28462306a36Sopenharmony_ci		tmp = *r;
28562306a36Sopenharmony_ci		r->x1 = width - tmp.x2;
28662306a36Sopenharmony_ci		r->x2 = width - tmp.x1;
28762306a36Sopenharmony_ci		r->y1 = height - tmp.y2;
28862306a36Sopenharmony_ci		r->y2 = height - tmp.y1;
28962306a36Sopenharmony_ci		break;
29062306a36Sopenharmony_ci	case DRM_MODE_ROTATE_270:
29162306a36Sopenharmony_ci		tmp = *r;
29262306a36Sopenharmony_ci		r->x1 = height - tmp.y2;
29362306a36Sopenharmony_ci		r->x2 = height - tmp.y1;
29462306a36Sopenharmony_ci		r->y1 = tmp.x1;
29562306a36Sopenharmony_ci		r->y2 = tmp.x2;
29662306a36Sopenharmony_ci		break;
29762306a36Sopenharmony_ci	default:
29862306a36Sopenharmony_ci		break;
29962306a36Sopenharmony_ci	}
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ciEXPORT_SYMBOL(drm_rect_rotate);
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci/**
30462306a36Sopenharmony_ci * drm_rect_rotate_inv - Inverse rotate the rectangle
30562306a36Sopenharmony_ci * @r: rectangle to be rotated
30662306a36Sopenharmony_ci * @width: Width of the coordinate space
30762306a36Sopenharmony_ci * @height: Height of the coordinate space
30862306a36Sopenharmony_ci * @rotation: Transformation whose inverse is to be applied
30962306a36Sopenharmony_ci *
31062306a36Sopenharmony_ci * Apply the inverse of @rotation to the coordinates
31162306a36Sopenharmony_ci * of rectangle @r.
31262306a36Sopenharmony_ci *
31362306a36Sopenharmony_ci * @width and @height combined with @rotation define
31462306a36Sopenharmony_ci * the location of the new origin.
31562306a36Sopenharmony_ci *
31662306a36Sopenharmony_ci * @width correcsponds to the horizontal and @height
31762306a36Sopenharmony_ci * to the vertical axis of the original untransformed
31862306a36Sopenharmony_ci * coordinate space, so that you never have to flip
31962306a36Sopenharmony_ci * them when doing a rotatation and its inverse.
32062306a36Sopenharmony_ci * That is, if you do ::
32162306a36Sopenharmony_ci *
32262306a36Sopenharmony_ci *     drm_rect_rotate(&r, width, height, rotation);
32362306a36Sopenharmony_ci *     drm_rect_rotate_inv(&r, width, height, rotation);
32462306a36Sopenharmony_ci *
32562306a36Sopenharmony_ci * you will always get back the original rectangle.
32662306a36Sopenharmony_ci */
32762306a36Sopenharmony_civoid drm_rect_rotate_inv(struct drm_rect *r,
32862306a36Sopenharmony_ci			 int width, int height,
32962306a36Sopenharmony_ci			 unsigned int rotation)
33062306a36Sopenharmony_ci{
33162306a36Sopenharmony_ci	struct drm_rect tmp;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	switch (rotation & DRM_MODE_ROTATE_MASK) {
33462306a36Sopenharmony_ci	case DRM_MODE_ROTATE_0:
33562306a36Sopenharmony_ci		break;
33662306a36Sopenharmony_ci	case DRM_MODE_ROTATE_90:
33762306a36Sopenharmony_ci		tmp = *r;
33862306a36Sopenharmony_ci		r->x1 = width - tmp.y2;
33962306a36Sopenharmony_ci		r->x2 = width - tmp.y1;
34062306a36Sopenharmony_ci		r->y1 = tmp.x1;
34162306a36Sopenharmony_ci		r->y2 = tmp.x2;
34262306a36Sopenharmony_ci		break;
34362306a36Sopenharmony_ci	case DRM_MODE_ROTATE_180:
34462306a36Sopenharmony_ci		tmp = *r;
34562306a36Sopenharmony_ci		r->x1 = width - tmp.x2;
34662306a36Sopenharmony_ci		r->x2 = width - tmp.x1;
34762306a36Sopenharmony_ci		r->y1 = height - tmp.y2;
34862306a36Sopenharmony_ci		r->y2 = height - tmp.y1;
34962306a36Sopenharmony_ci		break;
35062306a36Sopenharmony_ci	case DRM_MODE_ROTATE_270:
35162306a36Sopenharmony_ci		tmp = *r;
35262306a36Sopenharmony_ci		r->x1 = tmp.y1;
35362306a36Sopenharmony_ci		r->x2 = tmp.y2;
35462306a36Sopenharmony_ci		r->y1 = height - tmp.x2;
35562306a36Sopenharmony_ci		r->y2 = height - tmp.x1;
35662306a36Sopenharmony_ci		break;
35762306a36Sopenharmony_ci	default:
35862306a36Sopenharmony_ci		break;
35962306a36Sopenharmony_ci	}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	if (rotation & (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)) {
36262306a36Sopenharmony_ci		tmp = *r;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci		if (rotation & DRM_MODE_REFLECT_X) {
36562306a36Sopenharmony_ci			r->x1 = width - tmp.x2;
36662306a36Sopenharmony_ci			r->x2 = width - tmp.x1;
36762306a36Sopenharmony_ci		}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci		if (rotation & DRM_MODE_REFLECT_Y) {
37062306a36Sopenharmony_ci			r->y1 = height - tmp.y2;
37162306a36Sopenharmony_ci			r->y2 = height - tmp.y1;
37262306a36Sopenharmony_ci		}
37362306a36Sopenharmony_ci	}
37462306a36Sopenharmony_ci}
37562306a36Sopenharmony_ciEXPORT_SYMBOL(drm_rect_rotate_inv);
376