gx_rotate.c revision 04007eba
1/* Copyrightg (c) 2006 Advanced Micro Devices, Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 * 21 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22 * contributors may be used to endorse or promote products derived from this 23 * software without specific prior written permission. 24 */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "xf86.h" 31#include "shadow.h" 32#include "geode.h" 33 34static void * 35GXWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, 36 CARD32 *size, void *closure) 37{ 38 ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen); 39 GeodeRec *pGeode = GEODEPTR(pScrni); 40 41 *size = pGeode->displayPitch; 42 43 return (pGeode->FBBase + pGeode->displayOffset) + 44 row * pGeode->displayPitch + offset; 45} 46 47static void 48GXUpdate(ScreenPtr pScreen, shadowBufPtr pBuf) 49{ 50 ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen); 51 GeodeRec *pGeode = GEODEPTR(pScrni); 52 int rotate = pGeode->rotation; 53 54 switch (rotate) { 55 case RR_Rotate_90: 56 57 if (pScrni->bitsPerPixel == 8) 58 shadowUpdateRotate8_90(pScreen, pBuf); 59 else if (pScrni->bitsPerPixel == 16) 60 shadowUpdateRotate16_90(pScreen, pBuf); 61 else 62 shadowUpdateRotate32_90(pScreen, pBuf); 63 64 break; 65 66 case RR_Rotate_180: 67 68 if (pScrni->bitsPerPixel == 8) 69 shadowUpdateRotate8_180(pScreen, pBuf); 70 else if (pScrni->bitsPerPixel == 16) 71 shadowUpdateRotate16_180(pScreen, pBuf); 72 else 73 shadowUpdateRotate32_180(pScreen, pBuf); 74 75 break; 76 77 case RR_Rotate_270: 78 if (pScrni->bitsPerPixel == 8) 79 shadowUpdateRotate8_270(pScreen, pBuf); 80 else if (pScrni->bitsPerPixel == 16) 81 shadowUpdateRotate16_270(pScreen, pBuf); 82 else 83 shadowUpdateRotate32_270(pScreen, pBuf); 84 85 break; 86 } 87} 88 89Bool 90GXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode) 91{ 92 GeodeRec *pGeode = GEODEPTR(pScrni); 93 Rotation curr = pGeode->rotation; 94 unsigned int curdw = pScrni->displayWidth; 95 PixmapPtr pPixmap; 96 BOOL ret; 97 98 pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen); 99 pGeode->rotation = GXGetRotation(pScrni->pScreen); 100 101 /* Leave if we have nothing to do */ 102 103 if (pGeode->rotation == curr && pGeode->curMode == mode) { 104 return TRUE; 105 } 106 107 shadowRemove(pScrni->pScreen, NULL); 108 109 switch (pGeode->rotation) { 110 case RR_Rotate_0: 111 ErrorF("Rotate to 0 degrees\n"); 112 pScrni->displayWidth = pGeode->displayWidth; 113 pGeode->Pitch = pGeode->displayPitch; 114 break; 115 116 case RR_Rotate_90: 117 ErrorF("Rotate to 90 degrees\n"); 118 pScrni->displayWidth = pScrni->pScreen->width; 119 break; 120 121 case RR_Rotate_180: 122 ErrorF("Rotate to 180 degrees\n"); 123 pScrni->displayWidth = pGeode->displayWidth; 124 break; 125 126 case RR_Rotate_270: 127 ErrorF("Rotate to 270 degrees\n"); 128 pScrni->displayWidth = pScrni->pScreen->width; 129 break; 130 } 131 132 if (pGeode->rotation != RR_Rotate_0) { 133 134 ret = 135 shadowAdd(pScrni->pScreen, pPixmap, GXUpdate, GXWindowLinear, 136 pGeode->rotation, NULL); 137 138 if (!ret) { 139 ErrorF("shadowAdd failed\n"); 140 goto error; 141 } 142 } 143 144 if (pGeode->rotation == RR_Rotate_0) 145 pScrni->fbOffset = pGeode->displayOffset; 146 else 147 pScrni->fbOffset = pGeode->shadowOffset; 148 149 pScrni->pScreen->ModifyPixmapHeader(pPixmap, 150 pScrni->pScreen->width, 151 pScrni->pScreen->height, 152 pScrni->pScreen->rootDepth, 153 pScrni->bitsPerPixel, 154 PixmapBytePad(pScrni->displayWidth, 155 pScrni-> 156 pScreen->rootDepth), 157 (pointer) (pGeode->FBBase + 158 pScrni->fbOffset)); 159 160 /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */ 161#if XF86XAA 162 if (pGeode->AccelInfoRec) { 163 if (pGeode->rotation == RR_Rotate_0) { 164 pGeode->AccelInfoRec->Flags = 165 LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; 166 pGeode->AccelInfoRec->UsingPixmapCache = TRUE; 167 pGeode->AccelInfoRec->maxOffPixWidth = 0; 168 pGeode->AccelInfoRec->maxOffPixHeight = 0; 169 } 170 else { 171 pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER; 172 pGeode->AccelInfoRec->UsingPixmapCache = FALSE; 173 pGeode->AccelInfoRec->maxOffPixWidth = 1; 174 pGeode->AccelInfoRec->maxOffPixHeight = 1; 175 } 176 } 177#endif 178 179 return TRUE; 180 181 error: 182 /* Restore the old rotation */ 183 pScrni->displayWidth = curdw; 184 185 if (curr & (RR_Rotate_0 | RR_Rotate_180)) { 186 pScrni->pScreen->width = pScrni->virtualX; 187 pScrni->pScreen->height = pScrni->virtualY; 188 } 189 else { 190 pScrni->pScreen->width = pScrni->virtualY; 191 pScrni->pScreen->height = pScrni->virtualX; 192 } 193 194 pGeode->rotation = curr; 195 return FALSE; 196} 197