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 
35 Bool
saa_hw_copy_nton(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,BoxPtr pbox,int nbox,int dx,int dy,Bool reverse,Bool upsidedown)36 saa_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 
115 static void
saa_copy_nton(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,BoxPtr pbox,int nbox,int dx,int dy,Bool reverse,Bool upsidedown,Pixel bitplane,void * closure)116 saa_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 
133 RegionPtr
saa_copy_area(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,int srcx,int srcy,int width,int height,int dstx,int dsty)134 saa_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