xserver

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

exa_mixed.c (9739B)


      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 + better initial placement code.
     35  */
     36 
     37 static _X_INLINE void *
     38 ExaGetPixmapAddress(PixmapPtr p)
     39 {
     40     ExaPixmapPriv(p);
     41 
     42     return pExaPixmap->sys_ptr;
     43 }
     44 
     45 /**
     46  * exaCreatePixmap() creates a new pixmap.
     47  */
     48 PixmapPtr
     49 exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     50                       unsigned usage_hint)
     51 {
     52     PixmapPtr pPixmap;
     53     ExaPixmapPrivPtr pExaPixmap;
     54     int bpp;
     55     size_t paddedWidth;
     56 
     57     ExaScreenPriv(pScreen);
     58 
     59     if (w > 32767 || h > 32767)
     60         return NullPixmap;
     61 
     62     swap(pExaScr, pScreen, CreatePixmap);
     63     pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint);
     64     swap(pExaScr, pScreen, CreatePixmap);
     65 
     66     if (!pPixmap)
     67         return NULL;
     68 
     69     pExaPixmap = ExaGetPixmapPriv(pPixmap);
     70     pExaPixmap->driverPriv = NULL;
     71 
     72     bpp = pPixmap->drawable.bitsPerPixel;
     73 
     74     paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
     75     if (paddedWidth / 4 > 32767 || h > 32767)
     76         return NullPixmap;
     77 
     78     /* We will allocate the system pixmap later if needed. */
     79     pPixmap->devPrivate.ptr = NULL;
     80     pExaPixmap->sys_ptr = NULL;
     81     pExaPixmap->sys_pitch = paddedWidth;
     82 
     83     pExaPixmap->area = NULL;
     84     pExaPixmap->fb_ptr = NULL;
     85     pExaPixmap->pDamage = NULL;
     86 
     87     exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
     88     exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
     89 
     90     (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
     91 
     92     /* A scratch pixmap will become a driver pixmap right away. */
     93     if (!w || !h) {
     94         exaCreateDriverPixmap_mixed(pPixmap);
     95         pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
     96     }
     97     else {
     98         pExaPixmap->use_gpu_copy = FALSE;
     99 
    100         if (w == 1 && h == 1) {
    101             pExaPixmap->sys_ptr = malloc(paddedWidth);
    102 
    103             /* Set up damage tracking */
    104             pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
    105                                                DamageReportNonEmpty, TRUE,
    106                                                pPixmap->drawable.pScreen,
    107                                                pPixmap);
    108 
    109             if (pExaPixmap->pDamage) {
    110                 DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
    111                 /* This ensures that pending damage reflects the current
    112                  * operation. This is used by exa to optimize migration.
    113                  */
    114                 DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
    115             }
    116         }
    117     }
    118 
    119     /* During a fallback we must prepare access. */
    120     if (pExaScr->fallback_counter)
    121         exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
    122 
    123     return pPixmap;
    124 }
    125 
    126 Bool
    127 exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
    128                             int bitsPerPixel, int devKind, void *pPixData)
    129 {
    130     ScreenPtr pScreen;
    131     ExaScreenPrivPtr pExaScr;
    132     ExaPixmapPrivPtr pExaPixmap;
    133     Bool ret, has_gpu_copy;
    134 
    135     if (!pPixmap)
    136         return FALSE;
    137 
    138     pScreen = pPixmap->drawable.pScreen;
    139     pExaScr = ExaGetScreenPriv(pScreen);
    140     pExaPixmap = ExaGetPixmapPriv(pPixmap);
    141 
    142     if (pPixData) {
    143         if (pExaPixmap->driverPriv) {
    144             if (pExaPixmap->pDamage) {
    145                 DamageDestroy(pExaPixmap->pDamage);
    146                 pExaPixmap->pDamage = NULL;
    147             }
    148 
    149             pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
    150             pExaPixmap->driverPriv = NULL;
    151         }
    152 
    153         pExaPixmap->use_gpu_copy = FALSE;
    154         pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
    155     }
    156 
    157     has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
    158 
    159     if (width <= 0)
    160         width = pPixmap->drawable.width;
    161 
    162     if (height <= 0)
    163         height = pPixmap->drawable.height;
    164 
    165     if (bitsPerPixel <= 0) {
    166         if (depth <= 0)
    167             bitsPerPixel = pPixmap->drawable.bitsPerPixel;
    168         else
    169             bitsPerPixel = BitsPerPixel(depth);
    170     }
    171 
    172     if (depth <= 0)
    173         depth = pPixmap->drawable.depth;
    174 
    175     if (width != pPixmap->drawable.width ||
    176         height != pPixmap->drawable.height ||
    177         depth != pPixmap->drawable.depth ||
    178         bitsPerPixel != pPixmap->drawable.bitsPerPixel) {
    179         if (pExaPixmap->driverPriv) {
    180             if (devKind > 0)
    181                 pExaPixmap->fb_pitch = devKind;
    182             else
    183                 exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
    184 
    185             exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
    186             RegionEmpty(&pExaPixmap->validFB);
    187         }
    188 
    189         /* Need to re-create system copy if there's also a GPU copy */
    190         if (has_gpu_copy) {
    191             if (pExaPixmap->sys_ptr) {
    192                 free(pExaPixmap->sys_ptr);
    193                 pExaPixmap->sys_ptr = NULL;
    194                 DamageDestroy(pExaPixmap->pDamage);
    195                 pExaPixmap->pDamage = NULL;
    196                 RegionEmpty(&pExaPixmap->validSys);
    197 
    198                 if (pExaScr->deferred_mixed_pixmap == pPixmap)
    199                     pExaScr->deferred_mixed_pixmap = NULL;
    200             }
    201 
    202             pExaPixmap->sys_pitch = PixmapBytePad(width, depth);
    203         }
    204     }
    205 
    206     if (has_gpu_copy) {
    207         pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
    208         pPixmap->devKind = pExaPixmap->fb_pitch;
    209     }
    210     else {
    211         pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
    212         pPixmap->devKind = pExaPixmap->sys_pitch;
    213     }
    214 
    215     /* Only pass driver pixmaps to the driver. */
    216     if (pExaScr->info->ModifyPixmapHeader && pExaPixmap->driverPriv) {
    217         ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
    218                                                 bitsPerPixel, devKind,
    219                                                 pPixData);
    220         if (ret == TRUE)
    221             goto out;
    222     }
    223 
    224     swap(pExaScr, pScreen, ModifyPixmapHeader);
    225     ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
    226                                       bitsPerPixel, devKind, pPixData);
    227     swap(pExaScr, pScreen, ModifyPixmapHeader);
    228 
    229  out:
    230     if (has_gpu_copy) {
    231         pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr;
    232         pExaPixmap->fb_pitch = pPixmap->devKind;
    233     }
    234     else {
    235         pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
    236         pExaPixmap->sys_pitch = pPixmap->devKind;
    237     }
    238     /* Always NULL this, we don't want lingering pointers. */
    239     pPixmap->devPrivate.ptr = NULL;
    240 
    241     return ret;
    242 }
    243 
    244 Bool
    245 exaDestroyPixmap_mixed(PixmapPtr pPixmap)
    246 {
    247     ScreenPtr pScreen = pPixmap->drawable.pScreen;
    248 
    249     ExaScreenPriv(pScreen);
    250     Bool ret;
    251 
    252     if (pPixmap->refcnt == 1) {
    253         ExaPixmapPriv(pPixmap);
    254 
    255         exaDestroyPixmap(pPixmap);
    256 
    257         if (pExaScr->deferred_mixed_pixmap == pPixmap)
    258             pExaScr->deferred_mixed_pixmap = NULL;
    259 
    260         if (pExaPixmap->driverPriv)
    261             pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
    262         pExaPixmap->driverPriv = NULL;
    263 
    264         if (pExaPixmap->pDamage) {
    265             free(pExaPixmap->sys_ptr);
    266             pExaPixmap->sys_ptr = NULL;
    267             pExaPixmap->pDamage = NULL;
    268         }
    269     }
    270 
    271     swap(pExaScr, pScreen, DestroyPixmap);
    272     ret = pScreen->DestroyPixmap(pPixmap);
    273     swap(pExaScr, pScreen, DestroyPixmap);
    274 
    275     return ret;
    276 }
    277 
    278 Bool
    279 exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap)
    280 {
    281     ScreenPtr pScreen = pPixmap->drawable.pScreen;
    282 
    283     ExaScreenPriv(pScreen);
    284     ExaPixmapPriv(pPixmap);
    285     void *saved_ptr;
    286     Bool ret;
    287 
    288     if (!pExaPixmap->driverPriv)
    289         return FALSE;
    290 
    291     saved_ptr = pPixmap->devPrivate.ptr;
    292     pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
    293     ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
    294     pPixmap->devPrivate.ptr = saved_ptr;
    295 
    296     return ret;
    297 }
    298 
    299 Bool
    300 exaSharePixmapBacking_mixed(PixmapPtr pPixmap, ScreenPtr secondary, void **handle_p)
    301 {
    302     ScreenPtr pScreen = pPixmap->drawable.pScreen;
    303     ExaScreenPriv(pScreen);
    304     Bool ret = FALSE;
    305 
    306     exaMoveInPixmap(pPixmap);
    307     /* get the driver to give us a handle */
    308     if (pExaScr->info->SharePixmapBacking)
    309         ret = pExaScr->info->SharePixmapBacking(pPixmap, secondary, handle_p);
    310 
    311     return ret;
    312 }
    313 
    314 Bool
    315 exaSetSharedPixmapBacking_mixed(PixmapPtr pPixmap, void *handle)
    316 {
    317     ScreenPtr pScreen = pPixmap->drawable.pScreen;
    318     ExaScreenPriv(pScreen);
    319     Bool ret = FALSE;
    320 
    321     if (pExaScr->info->SetSharedPixmapBacking)
    322         ret = pExaScr->info->SetSharedPixmapBacking(pPixmap, handle);
    323 
    324     if (ret == TRUE)
    325         exaMoveInPixmap(pPixmap);
    326 
    327     return ret;
    328 }
    329 
    330