13bfa90b6Smrg/* 23bfa90b6Smrg * Copyright © 2009 Maarten Maathuis 33bfa90b6Smrg * Copyright 2011 VMWare, Inc. All Rights Reserved. 43bfa90b6Smrg * 53bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 63bfa90b6Smrg * copy of this software and associated documentation files (the 73bfa90b6Smrg * "Software"), to deal in the Software without restriction, including 83bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish, 93bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to 103bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to 113bfa90b6Smrg * the following conditions: 123bfa90b6Smrg * 133bfa90b6Smrg * The above copyright notice and this permission notice (including the 143bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions 153bfa90b6Smrg * of the Software. 163bfa90b6Smrg * 173bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 183bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 193bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 203bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 213bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 223bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 233bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 243bfa90b6Smrg * 253bfa90b6Smrg * Author: Based on "exa_driver.c" 263bfa90b6Smrg * Author: Thomas Hellstrom <thellstrom@vmware.com> 273bfa90b6Smrg */ 283bfa90b6Smrg 293bfa90b6Smrg#include "saa_priv.h" 303bfa90b6Smrg#include "saa.h" 313bfa90b6Smrg 323bfa90b6SmrgPixmapPtr 333bfa90b6Smrgsaa_create_pixmap(ScreenPtr pScreen, int w, int h, int depth, 343bfa90b6Smrg unsigned usage_hint) 353bfa90b6Smrg{ 363bfa90b6Smrg PixmapPtr pPixmap; 373bfa90b6Smrg struct saa_pixmap *spix; 383bfa90b6Smrg int bpp; 393bfa90b6Smrg size_t paddedWidth; 403bfa90b6Smrg struct saa_screen_priv *sscreen = saa_screen(pScreen); 413bfa90b6Smrg int new_pitch = 0; 423bfa90b6Smrg struct saa_driver *driver = sscreen->driver; 433bfa90b6Smrg 443bfa90b6Smrg if (w > 32767 || h > 32767) 453bfa90b6Smrg return NullPixmap; 463bfa90b6Smrg 473bfa90b6Smrg /* 483bfa90b6Smrg * Create a scratch pixmap without backing storage (w and h are zero) 493bfa90b6Smrg */ 503bfa90b6Smrg 513bfa90b6Smrg saa_swap(sscreen, pScreen, CreatePixmap); 523bfa90b6Smrg pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); 533bfa90b6Smrg saa_swap(sscreen, pScreen, CreatePixmap); 543bfa90b6Smrg 553bfa90b6Smrg if (!pPixmap) 563bfa90b6Smrg goto out_no_pix; 573bfa90b6Smrg 583bfa90b6Smrg spix = saa_pixmap(pPixmap); 593bfa90b6Smrg memset(spix, 0, driver->pixmap_size); 603bfa90b6Smrg REGION_NULL(pScreen, &spix->dirty_shadow); 613bfa90b6Smrg REGION_NULL(pScreen, &spix->dirty_hw); 623bfa90b6Smrg REGION_NULL(pScreen, &spix->shadow_damage); 633bfa90b6Smrg spix->read_access = 0; 643bfa90b6Smrg spix->write_access = 0; 653bfa90b6Smrg spix->mapped_access = 0; 663bfa90b6Smrg spix->addr = NULL; 673bfa90b6Smrg spix->auth_loc = saa_loc_override; 683bfa90b6Smrg spix->override = SAA_INVALID_ADDRESS; 693bfa90b6Smrg spix->pixmap = pPixmap; 703bfa90b6Smrg bpp = pPixmap->drawable.bitsPerPixel; 713bfa90b6Smrg 723bfa90b6Smrg if (!driver->create_pixmap(driver, spix, w, h, depth, 733bfa90b6Smrg usage_hint, bpp, &new_pitch)) 743bfa90b6Smrg goto out_no_driver_priv; 753bfa90b6Smrg 763bfa90b6Smrg paddedWidth = new_pitch; 773bfa90b6Smrg spix->damage = NULL; 783bfa90b6Smrg 793bfa90b6Smrg /* 803bfa90b6Smrg * Now set w and h to the correct value. This might allocate 813bfa90b6Smrg * backing store if w and h are NON-NULL. 823bfa90b6Smrg */ 833bfa90b6Smrg 843bfa90b6Smrg if (!(*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, 853bfa90b6Smrg paddedWidth, NULL)) 863bfa90b6Smrg goto out_no_pixmap_header; 873bfa90b6Smrg 883bfa90b6Smrg /* 893bfa90b6Smrg * During a fallback we must prepare access. This hack is initially used 903bfa90b6Smrg * for pixmaps created during ValidateGC. 913bfa90b6Smrg */ 923bfa90b6Smrg 933bfa90b6Smrg spix->fallback_created = FALSE; 943bfa90b6Smrg if (sscreen->fallback_count) { 953bfa90b6Smrg if (!saa_prepare_access_pixmap(pPixmap, SAA_ACCESS_W, NULL)) 963bfa90b6Smrg goto out_no_access; 973bfa90b6Smrg 983bfa90b6Smrg spix->fallback_created = TRUE; 993bfa90b6Smrg } 1003bfa90b6Smrg 1013bfa90b6Smrg return pPixmap; 1023bfa90b6Smrg out_no_access: 1033bfa90b6Smrg out_no_pixmap_header: 1043bfa90b6Smrg driver->destroy_pixmap(driver, pPixmap); 1053bfa90b6Smrg out_no_driver_priv: 1063bfa90b6Smrg saa_swap(sscreen, pScreen, DestroyPixmap); 1073bfa90b6Smrg pScreen->DestroyPixmap(pPixmap); 1083bfa90b6Smrg saa_swap(sscreen, pScreen, DestroyPixmap); 1093bfa90b6Smrg out_no_pix: 1103bfa90b6Smrg LogMessage(X_ERROR, "Failing pixmap creation.\n"); 1113bfa90b6Smrg return NullPixmap; 1123bfa90b6Smrg} 1133bfa90b6Smrg 1143bfa90b6SmrgBool 1153bfa90b6Smrgsaa_destroy_pixmap(PixmapPtr pPixmap) 1163bfa90b6Smrg{ 1173bfa90b6Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 1183bfa90b6Smrg struct saa_screen_priv *sscreen = saa_screen(pScreen); 1193bfa90b6Smrg Bool ret; 1203bfa90b6Smrg struct saa_driver *driver = sscreen->driver; 1213bfa90b6Smrg 1223bfa90b6Smrg if (pPixmap->refcnt == 1) { 1233bfa90b6Smrg struct saa_pixmap *spix = saa_pixmap(pPixmap); 1243bfa90b6Smrg 1253bfa90b6Smrg if (spix->fallback_created) { 1263bfa90b6Smrg if (!sscreen->fallback_count) 1273bfa90b6Smrg LogMessage(X_ERROR, "Fallback pixmap destroyed outside " 1283bfa90b6Smrg "fallback.\n"); 1293bfa90b6Smrg 1303bfa90b6Smrg saa_finish_access_pixmap(pPixmap, SAA_ACCESS_W); 1313bfa90b6Smrg } 1323bfa90b6Smrg 1333bfa90b6Smrg driver->destroy_pixmap(driver, pPixmap); 1343bfa90b6Smrg 1353bfa90b6Smrg REGION_UNINIT(pScreen, &spix->dirty_hw); 1363bfa90b6Smrg REGION_UNINIT(pScreen, &spix->dirty_shadow); 13725dbecb6Smrg if (spix->damage) 13825dbecb6Smrg DamageDestroy(spix->damage); 1393bfa90b6Smrg } 1403bfa90b6Smrg 1413bfa90b6Smrg saa_swap(sscreen, pScreen, DestroyPixmap); 1423bfa90b6Smrg ret = pScreen->DestroyPixmap(pPixmap); 1433bfa90b6Smrg saa_swap(sscreen, pScreen, DestroyPixmap); 1443bfa90b6Smrg 1453bfa90b6Smrg return ret; 1463bfa90b6Smrg} 1473bfa90b6Smrg 1483bfa90b6SmrgBool 1493bfa90b6Smrgsaa_modify_pixmap_header(PixmapPtr pPixmap, int width, int height, int depth, 1503bfa90b6Smrg int bitsPerPixel, int devKind, pointer pPixData) 1513bfa90b6Smrg{ 1523bfa90b6Smrg ScreenPtr pScreen; 1533bfa90b6Smrg struct saa_screen_priv *sscreen; 1543bfa90b6Smrg struct saa_pixmap *spix; 1553bfa90b6Smrg struct saa_driver *driver; 1563bfa90b6Smrg Bool ret = TRUE; 1573bfa90b6Smrg 1583bfa90b6Smrg if (!pPixmap) 1593bfa90b6Smrg return FALSE; 1603bfa90b6Smrg 1613bfa90b6Smrg pScreen = pPixmap->drawable.pScreen; 1623bfa90b6Smrg sscreen = saa_screen(pScreen); 1633bfa90b6Smrg spix = saa_pixmap(pPixmap); 1643bfa90b6Smrg driver = sscreen->driver; 1653bfa90b6Smrg 1663bfa90b6Smrg if (spix && driver->modify_pixmap_header && 1673bfa90b6Smrg driver->modify_pixmap_header(pPixmap, width, height, depth, 1683bfa90b6Smrg bitsPerPixel, devKind, pPixData)) { 1693bfa90b6Smrg spix->auth_loc = saa_loc_driver; 1703bfa90b6Smrg spix->override = SAA_INVALID_ADDRESS; 1713bfa90b6Smrg goto out; 1723bfa90b6Smrg } 1733bfa90b6Smrg 1743bfa90b6Smrg saa_swap(sscreen, pScreen, ModifyPixmapHeader); 1753bfa90b6Smrg ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, 1763bfa90b6Smrg bitsPerPixel, devKind, pPixData); 1773bfa90b6Smrg saa_swap(sscreen, pScreen, ModifyPixmapHeader); 1783bfa90b6Smrg spix->override = pPixmap->devPrivate.ptr; 1793bfa90b6Smrg spix->auth_loc = saa_loc_override; 1803bfa90b6Smrg 1813bfa90b6Smrg out: 1823bfa90b6Smrg pPixmap->devPrivate.ptr = NULL; 1833bfa90b6Smrg return ret; 1843bfa90b6Smrg} 1853bfa90b6Smrg 1863bfa90b6Smrgstruct saa_pixmap * 1873bfa90b6Smrgsaa_get_saa_pixmap(PixmapPtr pPixmap) 1883bfa90b6Smrg{ 1893bfa90b6Smrg return saa_pixmap(pPixmap); 1903bfa90b6Smrg} 1913bfa90b6Smrg 1923bfa90b6Smrgvoid 1933bfa90b6Smrgsaa_pixmap_dirty(PixmapPtr pixmap, Bool hw, RegionPtr reg) 1943bfa90b6Smrg{ 1953bfa90b6Smrg struct saa_pixmap *spix = saa_pixmap(pixmap); 1963bfa90b6Smrg struct saa_screen_priv *sscreen = saa_screen(pixmap->drawable.pScreen); 1973bfa90b6Smrg 1983bfa90b6Smrg if (hw) { 1993bfa90b6Smrg REGION_UNION(pixmap->drawable.pScreen, &spix->dirty_hw, 2003bfa90b6Smrg &spix->dirty_hw, reg); 2013bfa90b6Smrg REGION_SUBTRACT(pixmap->drawable.pScreen, &spix->dirty_shadow, 2023bfa90b6Smrg &spix->dirty_shadow, reg); 2033bfa90b6Smrg } else { 2043bfa90b6Smrg REGION_UNION(pixmap->drawable.pScreen, &spix->dirty_shadow, 2053bfa90b6Smrg &spix->dirty_shadow, reg); 2063bfa90b6Smrg REGION_SUBTRACT(pixmap->drawable.pScreen, &spix->dirty_hw, 2073bfa90b6Smrg &spix->dirty_hw, reg); 2083bfa90b6Smrg } 2093bfa90b6Smrg 2103bfa90b6Smrg sscreen->driver->damage(sscreen->driver, pixmap, hw, reg); 2113bfa90b6Smrg} 2123bfa90b6Smrg 2133bfa90b6Smrgvoid 2143bfa90b6Smrgsaa_drawable_dirty(DrawablePtr draw, Bool hw, RegionPtr reg) 2153bfa90b6Smrg{ 2163bfa90b6Smrg PixmapPtr pixmap; 2173bfa90b6Smrg int x_offset, y_offset; 2183bfa90b6Smrg 2193bfa90b6Smrg pixmap = saa_get_pixmap(draw, &x_offset, &y_offset); 2203bfa90b6Smrg REGION_TRANSLATE(draw->pScreen, reg, x_offset, y_offset); 2213bfa90b6Smrg saa_pixmap_dirty(pixmap, hw, reg); 2223bfa90b6Smrg REGION_TRANSLATE(draw->pScreen, reg, -x_offset, -y_offset); 2233bfa90b6Smrg} 224