xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

exa_driver.c (6913B)


      1 /*
      2  * Copyright © 2009 Maarten Maathuis
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21  * SOFTWARE.
     22  *
     23  */
     24 
     25 #ifdef HAVE_DIX_CONFIG_H
     26 #include <dix-config.h>
     27 #endif
     28 
     29 #include <string.h>
     30 
     31 #include "exa_priv.h"
     32 #include "exa.h"
     33 
     34 /* This file holds the driver allocated pixmaps specific implementation. */
     35 
     36 static _X_INLINE void *
     37 ExaGetPixmapAddress(PixmapPtr p)
     38 {
     39     ExaPixmapPriv(p);
     40 
     41     return pExaPixmap->sys_ptr;
     42 }
     43 
     44 /**
     45  * exaCreatePixmap() creates a new pixmap.
     46  *
     47  * Pixmaps are always marked as pinned, because exa has no control over them.
     48  */
     49 PixmapPtr
     50 exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
     51                        unsigned usage_hint)
     52 {
     53     PixmapPtr pPixmap;
     54     ExaPixmapPrivPtr pExaPixmap;
     55     int bpp;
     56     size_t paddedWidth, datasize;
     57 
     58     ExaScreenPriv(pScreen);
     59 
     60     if (w > 32767 || h > 32767)
     61         return NullPixmap;
     62 
     63     swap(pExaScr, pScreen, CreatePixmap);
     64     pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint);
     65     swap(pExaScr, pScreen, CreatePixmap);
     66 
     67     if (!pPixmap)
     68         return NULL;
     69 
     70     pExaPixmap = ExaGetPixmapPriv(pPixmap);
     71     pExaPixmap->driverPriv = NULL;
     72 
     73     bpp = pPixmap->drawable.bitsPerPixel;
     74 
     75     /* Set this before driver hooks, to allow for driver pixmaps without gpu
     76      * memory to back it. These pixmaps have a valid pointer at all times.
     77      */
     78     pPixmap->devPrivate.ptr = NULL;
     79 
     80     if (pExaScr->info->CreatePixmap2) {
     81         int new_pitch = 0;
     82 
     83         pExaPixmap->driverPriv =
     84             pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp,
     85                                          &new_pitch);
     86         paddedWidth = pExaPixmap->fb_pitch = new_pitch;
     87     }
     88     else {
     89         paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
     90         if (paddedWidth / 4 > 32767 || h > 32767)
     91             return NullPixmap;
     92 
     93         exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
     94 
     95         if (paddedWidth < pExaPixmap->fb_pitch)
     96             paddedWidth = pExaPixmap->fb_pitch;
     97         datasize = h * paddedWidth;
     98         pExaPixmap->driverPriv =
     99             pExaScr->info->CreatePixmap(pScreen, datasize, 0);
    100     }
    101 
    102     if (!pExaPixmap->driverPriv) {
    103         swap(pExaScr, pScreen, DestroyPixmap);
    104         pScreen->DestroyPixmap(pPixmap);
    105         swap(pExaScr, pScreen, DestroyPixmap);
    106         return NULL;
    107     }
    108 
    109     /* Allow ModifyPixmapHeader to set sys_ptr appropriately. */
    110     pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
    111     pExaPixmap->fb_ptr = NULL;
    112     pExaPixmap->pDamage = NULL;
    113     pExaPixmap->sys_ptr = NULL;
    114 
    115     (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
    116 
    117     pExaPixmap->area = NULL;
    118 
    119     exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
    120 
    121     pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
    122 
    123     /* During a fallback we must prepare access. */
    124     if (pExaScr->fallback_counter)
    125         exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
    126 
    127     return pPixmap;
    128 }
    129 
    130 Bool
    131 exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
    132                              int depth, int bitsPerPixel, int devKind,
    133                              void *pPixData)
    134 {
    135     ScreenPtr pScreen;
    136     ExaScreenPrivPtr pExaScr;
    137     ExaPixmapPrivPtr pExaPixmap;
    138     Bool ret;
    139 
    140     if (!pPixmap)
    141         return FALSE;
    142 
    143     pScreen = pPixmap->drawable.pScreen;
    144     pExaScr = ExaGetScreenPriv(pScreen);
    145     pExaPixmap = ExaGetPixmapPriv(pPixmap);
    146 
    147     if (pExaPixmap) {
    148         if (pPixData)
    149             pExaPixmap->sys_ptr = pPixData;
    150 
    151         if (devKind > 0)
    152             pExaPixmap->sys_pitch = devKind;
    153 
    154         if (width > 0 && height > 0 && bitsPerPixel > 0) {
    155             exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
    156 
    157             exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
    158         }
    159     }
    160 
    161     if (pExaScr->info->ModifyPixmapHeader) {
    162         ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
    163                                                 bitsPerPixel, devKind,
    164                                                 pPixData);
    165         /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL.
    166          * If pPixmap->devPrivate.ptr is non-NULL, then we've got a
    167          * !has_gpu_copy pixmap. We need to store the pointer,
    168          * because PrepareAccess won't be called.
    169          */
    170         if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
    171             pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
    172             pExaPixmap->sys_pitch = pPixmap->devKind;
    173         }
    174         if (ret == TRUE)
    175             goto out;
    176     }
    177 
    178     swap(pExaScr, pScreen, ModifyPixmapHeader);
    179     ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
    180                                       bitsPerPixel, devKind, pPixData);
    181     swap(pExaScr, pScreen, ModifyPixmapHeader);
    182 
    183  out:
    184     /* Always NULL this, we don't want lingering pointers. */
    185     pPixmap->devPrivate.ptr = NULL;
    186 
    187     return ret;
    188 }
    189 
    190 Bool
    191 exaDestroyPixmap_driver(PixmapPtr pPixmap)
    192 {
    193     ScreenPtr pScreen = pPixmap->drawable.pScreen;
    194 
    195     ExaScreenPriv(pScreen);
    196     Bool ret;
    197 
    198     if (pPixmap->refcnt == 1) {
    199         ExaPixmapPriv(pPixmap);
    200 
    201         exaDestroyPixmap(pPixmap);
    202 
    203         if (pExaPixmap->driverPriv)
    204             pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
    205         pExaPixmap->driverPriv = NULL;
    206     }
    207 
    208     swap(pExaScr, pScreen, DestroyPixmap);
    209     ret = pScreen->DestroyPixmap(pPixmap);
    210     swap(pExaScr, pScreen, DestroyPixmap);
    211 
    212     return ret;
    213 }
    214 
    215 Bool
    216 exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap)
    217 {
    218     ScreenPtr pScreen = pPixmap->drawable.pScreen;
    219 
    220     ExaScreenPriv(pScreen);
    221     void *saved_ptr;
    222     Bool ret;
    223 
    224     saved_ptr = pPixmap->devPrivate.ptr;
    225     pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
    226     ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
    227     pPixmap->devPrivate.ptr = saved_ptr;
    228 
    229     return ret;
    230 }