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

drm: Add drm_rect rotation functions

Add some helper functions to move drm_rects between different rotated
coordinate spaces. One function does the forward transform and
another does the inverse.

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Acked-by: Dave Airlie <airlied@linux.ie>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

authored by

Ville Syrjälä and committed by
Daniel Vetter
07074006 a4969dd7

+146
+140
drivers/gpu/drm/drm_rect.c
··· 293 293 DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1); 294 294 } 295 295 EXPORT_SYMBOL(drm_rect_debug_print); 296 + 297 + /** 298 + * drm_rect_rotate - Rotate the rectangle 299 + * @r: rectangle to be rotated 300 + * @width: Width of the coordinate space 301 + * @height: Height of the coordinate space 302 + * @rotation: Transformation to be applied 303 + * 304 + * Apply @rotation to the coordinates of rectangle @r. 305 + * 306 + * @width and @height combined with @rotation define 307 + * the location of the new origin. 308 + * 309 + * @width correcsponds to the horizontal and @height 310 + * to the vertical axis of the untransformed coordinate 311 + * space. 312 + */ 313 + void drm_rect_rotate(struct drm_rect *r, 314 + int width, int height, 315 + unsigned int rotation) 316 + { 317 + struct drm_rect tmp; 318 + 319 + if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) { 320 + tmp = *r; 321 + 322 + if (rotation & BIT(DRM_REFLECT_X)) { 323 + r->x1 = width - tmp.x2; 324 + r->x2 = width - tmp.x1; 325 + } 326 + 327 + if (rotation & BIT(DRM_REFLECT_Y)) { 328 + r->y1 = height - tmp.y2; 329 + r->y2 = height - tmp.y1; 330 + } 331 + } 332 + 333 + switch (rotation & 0xf) { 334 + case BIT(DRM_ROTATE_0): 335 + break; 336 + case BIT(DRM_ROTATE_90): 337 + tmp = *r; 338 + r->x1 = tmp.y1; 339 + r->x2 = tmp.y2; 340 + r->y1 = width - tmp.x2; 341 + r->y2 = width - tmp.x1; 342 + break; 343 + case BIT(DRM_ROTATE_180): 344 + tmp = *r; 345 + r->x1 = width - tmp.x2; 346 + r->x2 = width - tmp.x1; 347 + r->y1 = height - tmp.y2; 348 + r->y2 = height - tmp.y1; 349 + break; 350 + case BIT(DRM_ROTATE_270): 351 + tmp = *r; 352 + r->x1 = height - tmp.y2; 353 + r->x2 = height - tmp.y1; 354 + r->y1 = tmp.x1; 355 + r->y2 = tmp.x2; 356 + break; 357 + default: 358 + break; 359 + } 360 + } 361 + EXPORT_SYMBOL(drm_rect_rotate); 362 + 363 + /** 364 + * drm_rect_rotate_inv - Inverse rotate the rectangle 365 + * @r: rectangle to be rotated 366 + * @width: Width of the coordinate space 367 + * @height: Height of the coordinate space 368 + * @rotation: Transformation whose inverse is to be applied 369 + * 370 + * Apply the inverse of @rotation to the coordinates 371 + * of rectangle @r. 372 + * 373 + * @width and @height combined with @rotation define 374 + * the location of the new origin. 375 + * 376 + * @width correcsponds to the horizontal and @height 377 + * to the vertical axis of the original untransformed 378 + * coordinate space, so that you never have to flip 379 + * them when doing a rotatation and its inverse. 380 + * That is, if you do: 381 + * 382 + * drm_rotate(&r, width, height, rotation); 383 + * drm_rotate_inv(&r, width, height, rotation); 384 + * 385 + * you will always get back the original rectangle. 386 + */ 387 + void drm_rect_rotate_inv(struct drm_rect *r, 388 + int width, int height, 389 + unsigned int rotation) 390 + { 391 + struct drm_rect tmp; 392 + 393 + switch (rotation & 0xf) { 394 + case BIT(DRM_ROTATE_0): 395 + break; 396 + case BIT(DRM_ROTATE_90): 397 + tmp = *r; 398 + r->x1 = width - tmp.y2; 399 + r->x2 = width - tmp.y1; 400 + r->y1 = tmp.x1; 401 + r->y2 = tmp.x2; 402 + break; 403 + case BIT(DRM_ROTATE_180): 404 + tmp = *r; 405 + r->x1 = width - tmp.x2; 406 + r->x2 = width - tmp.x1; 407 + r->y1 = height - tmp.y2; 408 + r->y2 = height - tmp.y1; 409 + break; 410 + case BIT(DRM_ROTATE_270): 411 + tmp = *r; 412 + r->x1 = tmp.y1; 413 + r->x2 = tmp.y2; 414 + r->y1 = height - tmp.x2; 415 + r->y2 = height - tmp.x1; 416 + break; 417 + default: 418 + break; 419 + } 420 + 421 + if (rotation & (BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y))) { 422 + tmp = *r; 423 + 424 + if (rotation & BIT(DRM_REFLECT_X)) { 425 + r->x1 = width - tmp.x2; 426 + r->x2 = width - tmp.x1; 427 + } 428 + 429 + if (rotation & BIT(DRM_REFLECT_Y)) { 430 + r->y1 = height - tmp.y2; 431 + r->y2 = height - tmp.y1; 432 + } 433 + } 434 + } 435 + EXPORT_SYMBOL(drm_rect_rotate_inv);
+6
include/drm/drm_rect.h
··· 163 163 struct drm_rect *dst, 164 164 int min_vscale, int max_vscale); 165 165 void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point); 166 + void drm_rect_rotate(struct drm_rect *r, 167 + int width, int height, 168 + unsigned int rotation); 169 + void drm_rect_rotate_inv(struct drm_rect *r, 170 + int width, int height, 171 + unsigned int rotation); 166 172 167 173 #endif