Home | History | Annotate | Line # | Download | only in src
      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 "xorg-server.h"
     31 
     32 #include "xf86.h"
     33 #include "shadow.h"
     34 #include "geode.h"
     35 
     36 static void *
     37 GXWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
     38                CARD32 *size, void *closure)
     39 {
     40     ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen);
     41     GeodeRec *pGeode = GEODEPTR(pScrni);
     42 
     43     *size = pGeode->displayPitch;
     44 
     45     return (pGeode->FBBase + pGeode->displayOffset) +
     46         row * pGeode->displayPitch + offset;
     47 }
     48 
     49 static void
     50 GXUpdate(ScreenPtr pScreen, shadowBufPtr pBuf)
     51 {
     52     ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen);
     53     GeodeRec *pGeode = GEODEPTR(pScrni);
     54     int rotate = pGeode->rotation;
     55 
     56     switch (rotate) {
     57     case RR_Rotate_90:
     58 
     59         if (pScrni->bitsPerPixel == 8)
     60             shadowUpdateRotate8_90(pScreen, pBuf);
     61         else if (pScrni->bitsPerPixel == 16)
     62             shadowUpdateRotate16_90(pScreen, pBuf);
     63         else
     64             shadowUpdateRotate32_90(pScreen, pBuf);
     65 
     66         break;
     67 
     68     case RR_Rotate_180:
     69 
     70         if (pScrni->bitsPerPixel == 8)
     71             shadowUpdateRotate8_180(pScreen, pBuf);
     72         else if (pScrni->bitsPerPixel == 16)
     73             shadowUpdateRotate16_180(pScreen, pBuf);
     74         else
     75             shadowUpdateRotate32_180(pScreen, pBuf);
     76 
     77         break;
     78 
     79     case RR_Rotate_270:
     80         if (pScrni->bitsPerPixel == 8)
     81             shadowUpdateRotate8_270(pScreen, pBuf);
     82         else if (pScrni->bitsPerPixel == 16)
     83             shadowUpdateRotate16_270(pScreen, pBuf);
     84         else
     85             shadowUpdateRotate32_270(pScreen, pBuf);
     86 
     87         break;
     88     }
     89 }
     90 
     91 Bool
     92 GXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode)
     93 {
     94     GeodeRec *pGeode = GEODEPTR(pScrni);
     95     Rotation curr = pGeode->rotation;
     96     unsigned int curdw = pScrni->displayWidth;
     97     PixmapPtr pPixmap;
     98     BOOL ret;
     99 
    100     pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen);
    101     pGeode->rotation = GXGetRotation(pScrni->pScreen);
    102 
    103     /* Leave if we have nothing to do */
    104 
    105     if (pGeode->rotation == curr && pGeode->curMode == mode) {
    106         return TRUE;
    107     }
    108 
    109     shadowRemove(pScrni->pScreen, NULL);
    110 
    111     switch (pGeode->rotation) {
    112     case RR_Rotate_0:
    113         ErrorF("Rotate to 0 degrees\n");
    114         pScrni->displayWidth = pGeode->displayWidth;
    115         pGeode->Pitch = pGeode->displayPitch;
    116         break;
    117 
    118     case RR_Rotate_90:
    119         ErrorF("Rotate to 90 degrees\n");
    120         pScrni->displayWidth = pScrni->pScreen->width;
    121         break;
    122 
    123     case RR_Rotate_180:
    124         ErrorF("Rotate to 180 degrees\n");
    125         pScrni->displayWidth = pGeode->displayWidth;
    126         break;
    127 
    128     case RR_Rotate_270:
    129         ErrorF("Rotate to 270 degrees\n");
    130         pScrni->displayWidth = pScrni->pScreen->width;
    131         break;
    132     }
    133 
    134     if (pGeode->rotation != RR_Rotate_0) {
    135 
    136         ret =
    137             shadowAdd(pScrni->pScreen, pPixmap, GXUpdate, GXWindowLinear,
    138                       pGeode->rotation, NULL);
    139 
    140         if (!ret) {
    141             ErrorF("shadowAdd failed\n");
    142             goto error;
    143         }
    144     }
    145 
    146     if (pGeode->rotation == RR_Rotate_0)
    147         pScrni->fbOffset = pGeode->displayOffset;
    148     else
    149         pScrni->fbOffset = pGeode->shadowOffset;
    150 
    151     pScrni->pScreen->ModifyPixmapHeader(pPixmap,
    152                                         pScrni->pScreen->width,
    153                                         pScrni->pScreen->height,
    154                                         pScrni->pScreen->rootDepth,
    155                                         pScrni->bitsPerPixel,
    156                                         PixmapBytePad(pScrni->displayWidth,
    157                                                       pScrni->
    158                                                       pScreen->rootDepth),
    159                                         (pointer) (pGeode->FBBase +
    160                                                    pScrni->fbOffset));
    161 
    162     /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */
    163 #if XF86XAA
    164     if (pGeode->AccelInfoRec) {
    165         if (pGeode->rotation == RR_Rotate_0) {
    166             pGeode->AccelInfoRec->Flags =
    167                 LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE;
    168             pGeode->AccelInfoRec->UsingPixmapCache = TRUE;
    169             pGeode->AccelInfoRec->maxOffPixWidth = 0;
    170             pGeode->AccelInfoRec->maxOffPixHeight = 0;
    171         }
    172         else {
    173             pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER;
    174             pGeode->AccelInfoRec->UsingPixmapCache = FALSE;
    175             pGeode->AccelInfoRec->maxOffPixWidth = 1;
    176             pGeode->AccelInfoRec->maxOffPixHeight = 1;
    177         }
    178     }
    179 #endif
    180 
    181     return TRUE;
    182 
    183  error:
    184     /* Restore the old rotation */
    185     pScrni->displayWidth = curdw;
    186 
    187     if (curr & (RR_Rotate_0 | RR_Rotate_180)) {
    188         pScrni->pScreen->width = pScrni->virtualX;
    189         pScrni->pScreen->height = pScrni->virtualY;
    190     }
    191     else {
    192         pScrni->pScreen->width = pScrni->virtualY;
    193         pScrni->pScreen->height = pScrni->virtualX;
    194     }
    195 
    196     pGeode->rotation = curr;
    197     return FALSE;
    198 }
    199