| 1 | From: Chris Wilson <chris@chris-wilson.co.uk> |
| 2 | To: xorg-devel@lists.x.org |
| 3 | Subject: [PATCH 2/3] randr: Consider rotation of slaved crtcs when computing bounds |
| 4 | Date: Wed, 23 Jul 2014 12:35:14 +0100 |
| 5 | |
| 6 | When creating a pixmap to cover a rotated slaved CRTC, we need to |
| 7 | consider its rotated size as that is the area that it occupies in the |
| 8 | framebuffer. The slave is then responsible for mapping the copy of the |
| 9 | framebuffer onto the rotated scanout - which can be the usual RandR |
| 10 | shadow composite method. |
| 11 | |
| 12 | Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> |
| 13 | Cc: Dave Airlie <airlied@redhat.com> |
| 14 | Cc: Maarten Lankhorst <maarten.lankhorst@canonical.com> |
| 15 | --- |
| 16 | randr/rrcrtc.c | 56 ++++++++++++++++++++++++++++++++++++-------------------- |
| 17 | 1 file changed, 36 insertions(+), 20 deletions(-) |
| 18 | |
| 19 | --- a/randr/rrcrtc.c |
| 20 | +++ b/randr/rrcrtc.c |
| 21 | @@ -273,27 +273,43 @@ RRCrtcPendingProperties(RRCrtcPtr crtc) |
| 22 | return FALSE; |
| 23 | } |
| 24 | |
| 25 | -static void |
| 26 | -crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom) |
| 27 | +static int mode_height(const RRModeRec *mode, Rotation rotation) |
| 28 | { |
| 29 | - *left = crtc->x; |
| 30 | - *top = crtc->y; |
| 31 | - |
| 32 | - switch (crtc->rotation) { |
| 33 | + switch (rotation & 0xf) { |
| 34 | case RR_Rotate_0: |
| 35 | case RR_Rotate_180: |
| 36 | + return mode->mode.height; |
| 37 | + case RR_Rotate_90: |
| 38 | + case RR_Rotate_270: |
| 39 | + return mode->mode.width; |
| 40 | default: |
| 41 | - *right = crtc->x + crtc->mode->mode.width; |
| 42 | - *bottom = crtc->y + crtc->mode->mode.height; |
| 43 | - return; |
| 44 | + return 0; |
| 45 | + } |
| 46 | +} |
| 47 | + |
| 48 | +static int mode_width(const RRModeRec *mode, Rotation rotation) |
| 49 | +{ |
| 50 | + switch (rotation & 0xf) { |
| 51 | + case RR_Rotate_0: |
| 52 | + case RR_Rotate_180: |
| 53 | + return mode->mode.width; |
| 54 | case RR_Rotate_90: |
| 55 | case RR_Rotate_270: |
| 56 | - *right = crtc->x + crtc->mode->mode.height; |
| 57 | - *bottom = crtc->y + crtc->mode->mode.width; |
| 58 | - return; |
| 59 | + return mode->mode.height; |
| 60 | + default: |
| 61 | + return 0; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | +static void |
| 66 | +crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom) |
| 67 | +{ |
| 68 | + *left = crtc->x; |
| 69 | + *top = crtc->y; |
| 70 | + *right = crtc->x + mode_width(crtc->mode, crtc->rotation); |
| 71 | + *bottom = crtc->y + mode_height(crtc->mode, crtc->rotation); |
| 72 | +} |
| 73 | + |
| 74 | /* overlapping counts as adjacent */ |
| 75 | static Bool |
| 76 | crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b) |
| 77 | @@ -466,9 +482,9 @@ rrCheckPixmapBounding(ScreenPtr pScreen, |
| 78 | if (!pScrPriv->crtcs[c]->mode) |
| 79 | continue; |
| 80 | newbox.x1 = pScrPriv->crtcs[c]->x; |
| 81 | - newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width; |
| 82 | + newbox.x2 = pScrPriv->crtcs[c]->x + mode_width(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); |
| 83 | newbox.y1 = pScrPriv->crtcs[c]->y; |
| 84 | - newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height; |
| 85 | + newbox.y2 = pScrPriv->crtcs[c]->y + mode_height(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); |
| 86 | } |
| 87 | RegionInit(&new_crtc_region, &newbox, 1); |
| 88 | RegionUnion(&total_region, &total_region, &new_crtc_region); |
| 89 | @@ -487,9 +503,9 @@ rrCheckPixmapBounding(ScreenPtr pScreen, |
| 90 | if (!pScrPriv->crtcs[c]->mode) |
| 91 | continue; |
| 92 | newbox.x1 = pScrPriv->crtcs[c]->x; |
| 93 | - newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width; |
| 94 | + newbox.x2 = pScrPriv->crtcs[c]->x + mode_width(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); |
| 95 | newbox.y1 = pScrPriv->crtcs[c]->y; |
| 96 | - newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height; |
| 97 | + newbox.y2 = pScrPriv->crtcs[c]->y + mode_height(pScrPriv->crtcs[c]->mode, pScrPriv->crtcs[c]->rotation); |
| 98 | } |
| 99 | RegionInit(&new_crtc_region, &newbox, 1); |
| 100 | RegionUnion(&total_region, &total_region, &new_crtc_region); |
| 101 | @@ -544,8 +560,8 @@ RRCrtcSet(RRCrtcPtr crtc, |
| 102 | int width = 0, height = 0; |
| 103 | |
| 104 | if (mode) { |
| 105 | - width = mode->mode.width; |
| 106 | - height = mode->mode.height; |
| 107 | + width = mode_width(mode, rotation); |
| 108 | + height = mode_height(mode, rotation); |
| 109 | } |
| 110 | ErrorF("have a master to look out for\n"); |
| 111 | ret = rrCheckPixmapBounding(master, crtc, |
| 112 | @@ -1672,8 +1688,8 @@ RRReplaceScanoutPixmap(DrawablePtr pDraw |
| 113 | changed = FALSE; |
| 114 | if (crtc->mode && crtc->x == pDrawable->x && |
| 115 | crtc->y == pDrawable->y && |
| 116 | - crtc->mode->mode.width == pDrawable->width && |
| 117 | - crtc->mode->mode.height == pDrawable->height) |
| 118 | + mode_width(crtc->mode, crtc->rotation) == pDrawable->width && |
| 119 | + mode_height(crtc->mode, crtc->rotation) == pDrawable->height) |
| 120 | size_fits = TRUE; |
| 121 | |
| 122 | /* is the pixmap already set? */ |