exa_driver.c revision 6747b715
16747b715Smrg/* 26747b715Smrg * Copyright � 2009 Maarten Maathuis 36747b715Smrg * 46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a 56747b715Smrg * copy of this software and associated documentation files (the "Software"), 66747b715Smrg * to deal in the Software without restriction, including without limitation 76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 96747b715Smrg * Software is furnished to do so, subject to the following conditions: 106747b715Smrg * 116747b715Smrg * The above copyright notice and this permission notice (including the next 126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 136747b715Smrg * Software. 146747b715Smrg * 156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 206747b715Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 216747b715Smrg * SOFTWARE. 226747b715Smrg * 236747b715Smrg */ 246747b715Smrg 256747b715Smrg#ifdef HAVE_DIX_CONFIG_H 266747b715Smrg#include <dix-config.h> 276747b715Smrg#endif 286747b715Smrg 296747b715Smrg#include <string.h> 306747b715Smrg 316747b715Smrg#include "exa_priv.h" 326747b715Smrg#include "exa.h" 336747b715Smrg 346747b715Smrg/* This file holds the driver allocated pixmaps specific implementation. */ 356747b715Smrg 366747b715Smrgstatic _X_INLINE void* 376747b715SmrgExaGetPixmapAddress(PixmapPtr p) 386747b715Smrg{ 396747b715Smrg ExaPixmapPriv(p); 406747b715Smrg 416747b715Smrg return pExaPixmap->sys_ptr; 426747b715Smrg} 436747b715Smrg 446747b715Smrg/** 456747b715Smrg * exaCreatePixmap() creates a new pixmap. 466747b715Smrg * 476747b715Smrg * Pixmaps are always marked as pinned, because exa has no control over them. 486747b715Smrg */ 496747b715SmrgPixmapPtr 506747b715SmrgexaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, 516747b715Smrg unsigned usage_hint) 526747b715Smrg{ 536747b715Smrg PixmapPtr pPixmap; 546747b715Smrg ExaPixmapPrivPtr pExaPixmap; 556747b715Smrg int bpp; 566747b715Smrg size_t paddedWidth, datasize; 576747b715Smrg ExaScreenPriv(pScreen); 586747b715Smrg 596747b715Smrg if (w > 32767 || h > 32767) 606747b715Smrg return NullPixmap; 616747b715Smrg 626747b715Smrg swap(pExaScr, pScreen, CreatePixmap); 636747b715Smrg pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); 646747b715Smrg swap(pExaScr, pScreen, CreatePixmap); 656747b715Smrg 666747b715Smrg if (!pPixmap) 676747b715Smrg return NULL; 686747b715Smrg 696747b715Smrg pExaPixmap = ExaGetPixmapPriv(pPixmap); 706747b715Smrg pExaPixmap->driverPriv = NULL; 716747b715Smrg 726747b715Smrg bpp = pPixmap->drawable.bitsPerPixel; 736747b715Smrg 746747b715Smrg /* Set this before driver hooks, to allow for driver pixmaps without gpu 756747b715Smrg * memory to back it. These pixmaps have a valid pointer at all times. 766747b715Smrg */ 776747b715Smrg pPixmap->devPrivate.ptr = NULL; 786747b715Smrg 796747b715Smrg if (pExaScr->info->CreatePixmap2) { 806747b715Smrg int new_pitch = 0; 816747b715Smrg pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp, &new_pitch); 826747b715Smrg paddedWidth = pExaPixmap->fb_pitch = new_pitch; 836747b715Smrg } 846747b715Smrg else { 856747b715Smrg paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); 866747b715Smrg if (paddedWidth / 4 > 32767 || h > 32767) 876747b715Smrg return NullPixmap; 886747b715Smrg 896747b715Smrg exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); 906747b715Smrg 916747b715Smrg if (paddedWidth < pExaPixmap->fb_pitch) 926747b715Smrg paddedWidth = pExaPixmap->fb_pitch; 936747b715Smrg datasize = h * paddedWidth; 946747b715Smrg pExaPixmap->driverPriv = pExaScr->info->CreatePixmap(pScreen, datasize, 0); 956747b715Smrg } 966747b715Smrg 976747b715Smrg if (!pExaPixmap->driverPriv) { 986747b715Smrg swap(pExaScr, pScreen, DestroyPixmap); 996747b715Smrg pScreen->DestroyPixmap (pPixmap); 1006747b715Smrg swap(pExaScr, pScreen, DestroyPixmap); 1016747b715Smrg return NULL; 1026747b715Smrg } 1036747b715Smrg 1046747b715Smrg /* Allow ModifyPixmapHeader to set sys_ptr appropriately. */ 1056747b715Smrg pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; 1066747b715Smrg pExaPixmap->fb_ptr = NULL; 1076747b715Smrg pExaPixmap->pDamage = NULL; 1086747b715Smrg pExaPixmap->sys_ptr = NULL; 1096747b715Smrg 1106747b715Smrg (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0, 1116747b715Smrg paddedWidth, NULL); 1126747b715Smrg 1136747b715Smrg pExaPixmap->area = NULL; 1146747b715Smrg 1156747b715Smrg exaSetAccelBlock(pExaScr, pExaPixmap, 1166747b715Smrg w, h, bpp); 1176747b715Smrg 1186747b715Smrg /* During a fallback we must prepare access. */ 1196747b715Smrg if (pExaScr->fallback_counter) 1206747b715Smrg exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); 1216747b715Smrg 1226747b715Smrg return pPixmap; 1236747b715Smrg} 1246747b715Smrg 1256747b715SmrgBool 1266747b715SmrgexaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth, 1276747b715Smrg int bitsPerPixel, int devKind, pointer pPixData) 1286747b715Smrg{ 1296747b715Smrg ScreenPtr pScreen; 1306747b715Smrg ExaScreenPrivPtr pExaScr; 1316747b715Smrg ExaPixmapPrivPtr pExaPixmap; 1326747b715Smrg Bool ret; 1336747b715Smrg 1346747b715Smrg if (!pPixmap) 1356747b715Smrg return FALSE; 1366747b715Smrg 1376747b715Smrg pScreen = pPixmap->drawable.pScreen; 1386747b715Smrg pExaScr = ExaGetScreenPriv(pScreen); 1396747b715Smrg pExaPixmap = ExaGetPixmapPriv(pPixmap); 1406747b715Smrg 1416747b715Smrg if (pExaPixmap) { 1426747b715Smrg if (pPixData) 1436747b715Smrg pExaPixmap->sys_ptr = pPixData; 1446747b715Smrg 1456747b715Smrg if (devKind > 0) 1466747b715Smrg pExaPixmap->sys_pitch = devKind; 1476747b715Smrg 1486747b715Smrg if (width > 0 && height > 0 && bitsPerPixel > 0) { 1496747b715Smrg exaSetFbPitch(pExaScr, pExaPixmap, 1506747b715Smrg width, height, bitsPerPixel); 1516747b715Smrg 1526747b715Smrg exaSetAccelBlock(pExaScr, pExaPixmap, 1536747b715Smrg width, height, bitsPerPixel); 1546747b715Smrg } 1556747b715Smrg } 1566747b715Smrg 1576747b715Smrg if (pExaScr->info->ModifyPixmapHeader) { 1586747b715Smrg ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth, 1596747b715Smrg bitsPerPixel, devKind, pPixData); 1606747b715Smrg /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL. 1616747b715Smrg * If pPixmap->devPrivate.ptr is non-NULL, then we've got a 1626747b715Smrg * !has_gpu_copy pixmap. We need to store the pointer, 1636747b715Smrg * because PrepareAccess won't be called. 1646747b715Smrg */ 1656747b715Smrg if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) { 1666747b715Smrg pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; 1676747b715Smrg pExaPixmap->sys_pitch = pPixmap->devKind; 1686747b715Smrg } 1696747b715Smrg if (ret == TRUE) 1706747b715Smrg goto out; 1716747b715Smrg } 1726747b715Smrg 1736747b715Smrg swap(pExaScr, pScreen, ModifyPixmapHeader); 1746747b715Smrg ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, 1756747b715Smrg bitsPerPixel, devKind, pPixData); 1766747b715Smrg swap(pExaScr, pScreen, ModifyPixmapHeader); 1776747b715Smrg 1786747b715Smrgout: 1796747b715Smrg /* Always NULL this, we don't want lingering pointers. */ 1806747b715Smrg pPixmap->devPrivate.ptr = NULL; 1816747b715Smrg 1826747b715Smrg return ret; 1836747b715Smrg} 1846747b715Smrg 1856747b715SmrgBool 1866747b715SmrgexaDestroyPixmap_driver (PixmapPtr pPixmap) 1876747b715Smrg{ 1886747b715Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 1896747b715Smrg ExaScreenPriv(pScreen); 1906747b715Smrg Bool ret; 1916747b715Smrg 1926747b715Smrg if (pPixmap->refcnt == 1) 1936747b715Smrg { 1946747b715Smrg ExaPixmapPriv (pPixmap); 1956747b715Smrg 1966747b715Smrg exaDestroyPixmap(pPixmap); 1976747b715Smrg 1986747b715Smrg if (pExaPixmap->driverPriv) 1996747b715Smrg pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); 2006747b715Smrg pExaPixmap->driverPriv = NULL; 2016747b715Smrg } 2026747b715Smrg 2036747b715Smrg swap(pExaScr, pScreen, DestroyPixmap); 2046747b715Smrg ret = pScreen->DestroyPixmap (pPixmap); 2056747b715Smrg swap(pExaScr, pScreen, DestroyPixmap); 2066747b715Smrg 2076747b715Smrg return ret; 2086747b715Smrg} 2096747b715Smrg 2106747b715SmrgBool 2116747b715SmrgexaPixmapHasGpuCopy_driver(PixmapPtr pPixmap) 2126747b715Smrg{ 2136747b715Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 2146747b715Smrg ExaScreenPriv(pScreen); 2156747b715Smrg pointer saved_ptr; 2166747b715Smrg Bool ret; 2176747b715Smrg 2186747b715Smrg saved_ptr = pPixmap->devPrivate.ptr; 2196747b715Smrg pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap); 2206747b715Smrg ret = pExaScr->info->PixmapIsOffscreen(pPixmap); 2216747b715Smrg pPixmap->devPrivate.ptr = saved_ptr; 2226747b715Smrg 2236747b715Smrg return ret; 2246747b715Smrg} 225