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