gx_rotate.c revision 04007eba
1f29dbc25Smrg/* Copyrightg (c) 2006 Advanced Micro Devices, Inc.
2f29dbc25Smrg *
3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy
4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to
5f29dbc25Smrg * deal in the Software without restriction, including without limitation the
6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is
8f29dbc25Smrg * furnished to do so, subject to the following conditions:
9f29dbc25Smrg *
10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in
11f29dbc25Smrg * all copies or substantial portions of the Software.
12f29dbc25Smrg *
13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19f29dbc25Smrg * IN THE SOFTWARE.
20f29dbc25Smrg *
21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this
23f29dbc25Smrg * software without specific prior written permission.
24f29dbc25Smrg */
25f29dbc25Smrg
26f29dbc25Smrg#ifdef HAVE_CONFIG_H
27f29dbc25Smrg#include "config.h"
28f29dbc25Smrg#endif
29f29dbc25Smrg
30f29dbc25Smrg#include "xf86.h"
31f29dbc25Smrg#include "shadow.h"
32f29dbc25Smrg#include "geode.h"
33f29dbc25Smrg
34f29dbc25Smrgstatic void *
35f29dbc25SmrgGXWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
3604007ebaSmrg               CARD32 *size, void *closure)
37f29dbc25Smrg{
3804007ebaSmrg    ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen);
39f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
40f29dbc25Smrg
41f29dbc25Smrg    *size = pGeode->displayPitch;
42f29dbc25Smrg
43f29dbc25Smrg    return (pGeode->FBBase + pGeode->displayOffset) +
4404007ebaSmrg        row * pGeode->displayPitch + offset;
45f29dbc25Smrg}
46f29dbc25Smrg
47f29dbc25Smrgstatic void
48f29dbc25SmrgGXUpdate(ScreenPtr pScreen, shadowBufPtr pBuf)
49f29dbc25Smrg{
5004007ebaSmrg    ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen);
51f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
52f29dbc25Smrg    int rotate = pGeode->rotation;
53f29dbc25Smrg
54f29dbc25Smrg    switch (rotate) {
55f29dbc25Smrg    case RR_Rotate_90:
56f29dbc25Smrg
5704007ebaSmrg        if (pScrni->bitsPerPixel == 8)
5804007ebaSmrg            shadowUpdateRotate8_90(pScreen, pBuf);
5904007ebaSmrg        else if (pScrni->bitsPerPixel == 16)
6004007ebaSmrg            shadowUpdateRotate16_90(pScreen, pBuf);
6104007ebaSmrg        else
6204007ebaSmrg            shadowUpdateRotate32_90(pScreen, pBuf);
63f29dbc25Smrg
6404007ebaSmrg        break;
65f29dbc25Smrg
66f29dbc25Smrg    case RR_Rotate_180:
67f29dbc25Smrg
6804007ebaSmrg        if (pScrni->bitsPerPixel == 8)
6904007ebaSmrg            shadowUpdateRotate8_180(pScreen, pBuf);
7004007ebaSmrg        else if (pScrni->bitsPerPixel == 16)
7104007ebaSmrg            shadowUpdateRotate16_180(pScreen, pBuf);
7204007ebaSmrg        else
7304007ebaSmrg            shadowUpdateRotate32_180(pScreen, pBuf);
74f29dbc25Smrg
7504007ebaSmrg        break;
76f29dbc25Smrg
77f29dbc25Smrg    case RR_Rotate_270:
7804007ebaSmrg        if (pScrni->bitsPerPixel == 8)
7904007ebaSmrg            shadowUpdateRotate8_270(pScreen, pBuf);
8004007ebaSmrg        else if (pScrni->bitsPerPixel == 16)
8104007ebaSmrg            shadowUpdateRotate16_270(pScreen, pBuf);
8204007ebaSmrg        else
8304007ebaSmrg            shadowUpdateRotate32_270(pScreen, pBuf);
8404007ebaSmrg
8504007ebaSmrg        break;
86f29dbc25Smrg    }
87f29dbc25Smrg}
88f29dbc25Smrg
89f29dbc25SmrgBool
90f29dbc25SmrgGXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode)
91f29dbc25Smrg{
92f29dbc25Smrg    GeodeRec *pGeode = GEODEPTR(pScrni);
93f29dbc25Smrg    Rotation curr = pGeode->rotation;
94f29dbc25Smrg    unsigned int curdw = pScrni->displayWidth;
95f29dbc25Smrg    PixmapPtr pPixmap;
96f29dbc25Smrg    BOOL ret;
97f29dbc25Smrg
98f29dbc25Smrg    pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen);
99f29dbc25Smrg    pGeode->rotation = GXGetRotation(pScrni->pScreen);
100f29dbc25Smrg
101f29dbc25Smrg    /* Leave if we have nothing to do */
102f29dbc25Smrg
103f29dbc25Smrg    if (pGeode->rotation == curr && pGeode->curMode == mode) {
10404007ebaSmrg        return TRUE;
105f29dbc25Smrg    }
106f29dbc25Smrg
107f29dbc25Smrg    shadowRemove(pScrni->pScreen, NULL);
108f29dbc25Smrg
109f29dbc25Smrg    switch (pGeode->rotation) {
110f29dbc25Smrg    case RR_Rotate_0:
11104007ebaSmrg        ErrorF("Rotate to 0 degrees\n");
11204007ebaSmrg        pScrni->displayWidth = pGeode->displayWidth;
11304007ebaSmrg        pGeode->Pitch = pGeode->displayPitch;
11404007ebaSmrg        break;
115f29dbc25Smrg
116f29dbc25Smrg    case RR_Rotate_90:
11704007ebaSmrg        ErrorF("Rotate to 90 degrees\n");
11804007ebaSmrg        pScrni->displayWidth = pScrni->pScreen->width;
11904007ebaSmrg        break;
120f29dbc25Smrg
121f29dbc25Smrg    case RR_Rotate_180:
12204007ebaSmrg        ErrorF("Rotate to 180 degrees\n");
12304007ebaSmrg        pScrni->displayWidth = pGeode->displayWidth;
12404007ebaSmrg        break;
125f29dbc25Smrg
126f29dbc25Smrg    case RR_Rotate_270:
12704007ebaSmrg        ErrorF("Rotate to 270 degrees\n");
12804007ebaSmrg        pScrni->displayWidth = pScrni->pScreen->width;
12904007ebaSmrg        break;
130f29dbc25Smrg    }
131f29dbc25Smrg
132f29dbc25Smrg    if (pGeode->rotation != RR_Rotate_0) {
133f29dbc25Smrg
13404007ebaSmrg        ret =
13504007ebaSmrg            shadowAdd(pScrni->pScreen, pPixmap, GXUpdate, GXWindowLinear,
13604007ebaSmrg                      pGeode->rotation, NULL);
137f29dbc25Smrg
13804007ebaSmrg        if (!ret) {
13904007ebaSmrg            ErrorF("shadowAdd failed\n");
14004007ebaSmrg            goto error;
14104007ebaSmrg        }
142f29dbc25Smrg    }
143f29dbc25Smrg
144f29dbc25Smrg    if (pGeode->rotation == RR_Rotate_0)
14504007ebaSmrg        pScrni->fbOffset = pGeode->displayOffset;
146f29dbc25Smrg    else
14704007ebaSmrg        pScrni->fbOffset = pGeode->shadowOffset;
148f29dbc25Smrg
149f29dbc25Smrg    pScrni->pScreen->ModifyPixmapHeader(pPixmap,
15004007ebaSmrg                                        pScrni->pScreen->width,
15104007ebaSmrg                                        pScrni->pScreen->height,
15204007ebaSmrg                                        pScrni->pScreen->rootDepth,
15304007ebaSmrg                                        pScrni->bitsPerPixel,
15404007ebaSmrg                                        PixmapBytePad(pScrni->displayWidth,
15504007ebaSmrg                                                      pScrni->
15604007ebaSmrg                                                      pScreen->rootDepth),
15704007ebaSmrg                                        (pointer) (pGeode->FBBase +
15804007ebaSmrg                                                   pScrni->fbOffset));
159f29dbc25Smrg
160f29dbc25Smrg    /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */
16104007ebaSmrg#if XF86XAA
162f29dbc25Smrg    if (pGeode->AccelInfoRec) {
16304007ebaSmrg        if (pGeode->rotation == RR_Rotate_0) {
16404007ebaSmrg            pGeode->AccelInfoRec->Flags =
16504007ebaSmrg                LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
16604007ebaSmrg            pGeode->AccelInfoRec->UsingPixmapCache = TRUE;
16704007ebaSmrg            pGeode->AccelInfoRec->maxOffPixWidth = 0;
16804007ebaSmrg            pGeode->AccelInfoRec->maxOffPixHeight = 0;
16904007ebaSmrg        }
17004007ebaSmrg        else {
17104007ebaSmrg            pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
17204007ebaSmrg            pGeode->AccelInfoRec->UsingPixmapCache = FALSE;
17304007ebaSmrg            pGeode->AccelInfoRec->maxOffPixWidth = 1;
17404007ebaSmrg            pGeode->AccelInfoRec->maxOffPixHeight = 1;
17504007ebaSmrg        }
176f29dbc25Smrg    }
17704007ebaSmrg#endif
178f29dbc25Smrg
179f29dbc25Smrg    return TRUE;
180f29dbc25Smrg
18104007ebaSmrg error:
182f29dbc25Smrg    /* Restore the old rotation */
183f29dbc25Smrg    pScrni->displayWidth = curdw;
184f29dbc25Smrg
185f29dbc25Smrg    if (curr & (RR_Rotate_0 | RR_Rotate_180)) {
18604007ebaSmrg        pScrni->pScreen->width = pScrni->virtualX;
18704007ebaSmrg        pScrni->pScreen->height = pScrni->virtualY;
18804007ebaSmrg    }
18904007ebaSmrg    else {
19004007ebaSmrg        pScrni->pScreen->width = pScrni->virtualY;
19104007ebaSmrg        pScrni->pScreen->height = pScrni->virtualX;
192f29dbc25Smrg    }
193f29dbc25Smrg
194f29dbc25Smrg    pGeode->rotation = curr;
195f29dbc25Smrg    return FALSE;
196f29dbc25Smrg}
197