1/* 2 * Copyright © 2001 Keith Packard 3 * Copyright 2011 VMWare, Inc. All Rights Reserved. 4 * May partly be based on code that is Copyright © The XFree86 Project Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Author: Eric Anholt <eric@anholt.net> 27 * Author: Michel Dänzer <michel@tungstengraphics.com> 28 * Author: Thomas Hellstrom <thellstrom@vmware.com> 29 */ 30 31#include "saa.h" 32#include "saa_priv.h" 33#include <mi.h> 34 35Bool 36saa_hw_copy_nton(DrawablePtr pSrcDrawable, 37 DrawablePtr pDstDrawable, 38 GCPtr pGC, 39 BoxPtr pbox, 40 int nbox, int dx, int dy, Bool reverse, Bool upsidedown) 41{ 42 ScreenPtr pScreen = pDstDrawable->pScreen; 43 struct saa_screen_priv *sscreen = saa_screen(pDstDrawable->pScreen); 44 struct saa_driver *driver = sscreen->driver; 45 PixmapPtr pSrcPixmap, pDstPixmap; 46 struct saa_pixmap *src_spix, *dst_spix; 47 int src_off_x, src_off_y; 48 int dst_off_x, dst_off_y; 49 RegionRec dst_reg, *src_reg; 50 int ordering; 51 Bool ret = TRUE; 52 53 (void)pScreen; 54 55 /* avoid doing copy operations if no boxes */ 56 if (nbox == 0) 57 return TRUE; 58 59 pSrcPixmap = saa_get_pixmap(pSrcDrawable, &src_off_x, &src_off_y); 60 pDstPixmap = saa_get_pixmap(pDstDrawable, &dst_off_x, &dst_off_y); 61 src_spix = saa_pixmap(pSrcPixmap); 62 dst_spix = saa_pixmap(pDstPixmap); 63 64 if (src_spix->auth_loc != saa_loc_driver || 65 dst_spix->auth_loc != saa_loc_driver) 66 return FALSE; 67 68 69 ordering = (nbox == 1 || (dx > 0 && dy > 0) || 70 (pDstDrawable != pSrcDrawable && 71 (pDstDrawable->type != DRAWABLE_WINDOW || 72 pSrcDrawable->type != DRAWABLE_WINDOW))) ? 73 CT_YXBANDED : CT_UNSORTED; 74 75 src_reg = saa_boxes_to_region(pScreen, nbox, pbox, ordering); 76 if (!src_reg) 77 return FALSE; 78 79 REGION_NULL(pScreen, &dst_reg); 80 REGION_COPY(pScreen, &dst_reg, src_reg); 81 REGION_TRANSLATE(pScreen, src_reg, dx + src_off_x, dy + src_off_y); 82 REGION_TRANSLATE(pScreen, &dst_reg, dst_off_x, dst_off_y); 83 84 if (!(driver->copy_prepare) (driver, pSrcPixmap, pDstPixmap, 85 reverse ? -1 : 1, 86 upsidedown ? -1 : 1, 87 pGC ? pGC->alu : GXcopy, 88 src_reg, pGC ? pGC->planemask : FB_ALLONES)) { 89 goto fallback; 90 } 91 92 while (nbox--) { 93 (driver->copy) (driver, 94 pbox->x1 + dx + src_off_x, 95 pbox->y1 + dy + src_off_y, 96 pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, 97 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 98 pbox++; 99 } 100 101 (driver->copy_done) (driver); 102 saa_pixmap_dirty(pDstPixmap, TRUE, &dst_reg); 103 goto out; 104 105 fallback: 106 ret = FALSE; 107 108 out: 109 REGION_UNINIT(pScreen, &dst_reg); 110 REGION_DESTROY(pScreen, src_reg); 111 112 return ret; 113} 114 115static void 116saa_copy_nton(DrawablePtr pSrcDrawable, 117 DrawablePtr pDstDrawable, 118 GCPtr pGC, 119 BoxPtr pbox, 120 int nbox, 121 int dx, 122 int dy, 123 Bool reverse, Bool upsidedown, Pixel bitplane, void *closure) 124{ 125 if (saa_hw_copy_nton(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, 126 reverse, upsidedown)) 127 return; 128 129 saa_check_copy_nton(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, 130 reverse, upsidedown, bitplane, closure); 131} 132 133RegionPtr 134saa_copy_area(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, 135 int srcx, int srcy, int width, int height, int dstx, int dsty) 136{ 137 struct saa_screen_priv *sscreen = saa_screen(pDstDrawable->pScreen); 138 139 if (sscreen->fallback_count) { 140 return saa_check_copy_area(pSrcDrawable, pDstDrawable, pGC, 141 srcx, srcy, width, height, dstx, dsty); 142 } 143 144#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 6) 145 return miDoCopy(pSrcDrawable, pDstDrawable, pGC, 146 srcx, srcy, width, height, 147 dstx, dsty, saa_copy_nton, 0, NULL); 148#else 149 return fbDoCopy(pSrcDrawable, pDstDrawable, pGC, 150 srcx, srcy, width, height, 151 dstx, dsty, saa_copy_nton, 0, NULL); 152#endif 153} 154