Wed Jul 22 06:10:52 2009 UTC ()
apply the patch from http://bugs.freedesktop.org/attachment.cgi?id=27568.
it fixes various issues picked up by newer pixman.


(mrg)
diff -r1.1.1.3 -r1.2 xsrc/external/mit/xorg-server/dist/exa/exa_accel.c

cvs diff -r1.1.1.3 -r1.2 xsrc/external/mit/xorg-server/dist/exa/exa_accel.c (switch to unified diff)

--- xsrc/external/mit/xorg-server/dist/exa/exa_accel.c 2009/07/09 07:04:33 1.1.1.3
+++ xsrc/external/mit/xorg-server/dist/exa/exa_accel.c 2009/07/22 06:10:52 1.2
@@ -1,1232 +1,1242 @@ @@ -1,1232 +1,1242 @@
1/* 1/*
2 * Copyright © 2001 Keith Packard 2 * Copyright © 2001 Keith Packard
3 * 3 *
4 * Partly based on code that is Copyright © The XFree86 Project Inc. 4 * Partly based on code that is Copyright © The XFree86 Project Inc.
5 * 5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its 6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that 7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that 8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting 9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of Keith Packard not be used in 10 * documentation, and that the name of Keith Packard not be used in
11 * advertising or publicity pertaining to distribution of the software without 11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission. Keith Packard makes no 12 * specific, written prior permission. Keith Packard makes no
13 * representations about the suitability of this software for any purpose. It 13 * representations about the suitability of this software for any purpose. It
14 * is provided "as is" without express or implied warranty. 14 * is provided "as is" without express or implied warranty.
15 * 15 *
16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE. 22 * PERFORMANCE OF THIS SOFTWARE.
23 * 23 *
24 * Authors: 24 * Authors:
25 * Eric Anholt <eric@anholt.net> 25 * Eric Anholt <eric@anholt.net>
26 * Michel Dänzer <michel@tungstengraphics.com> 26 * Michel Dänzer <michel@tungstengraphics.com>
27 * 27 *
28 */ 28 */
29 29
30#ifdef HAVE_DIX_CONFIG_H 30#ifdef HAVE_DIX_CONFIG_H
31#include <dix-config.h> 31#include <dix-config.h>
32#endif 32#endif
33#include "exa_priv.h" 33#include "exa_priv.h"
34#include <X11/fonts/fontstruct.h> 34#include <X11/fonts/fontstruct.h>
35#include "dixfontstr.h" 35#include "dixfontstr.h"
36#include "exa.h" 36#include "exa.h"
37 37
38static void 38static void
39exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, 39exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
40 DDXPointPtr ppt, int *pwidth, int fSorted) 40 DDXPointPtr ppt, int *pwidth, int fSorted)
41{ 41{
42 ScreenPtr pScreen = pDrawable->pScreen; 42 ScreenPtr pScreen = pDrawable->pScreen;
43 ExaScreenPriv (pScreen); 43 ExaScreenPriv (pScreen);
44 RegionPtr pClip = fbGetCompositeClip(pGC); 44 RegionPtr pClip = fbGetCompositeClip(pGC);
45 PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); 45 PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
46 ExaPixmapPriv (pPixmap); 46 ExaPixmapPriv (pPixmap);
47 BoxPtr pextent, pbox; 47 BoxPtr pextent, pbox;
48 int nbox; 48 int nbox;
49 int extentX1, extentX2, extentY1, extentY2; 49 int extentX1, extentX2, extentY1, extentY2;
50 int fullX1, fullX2, fullY1; 50 int fullX1, fullX2, fullY1;
51 int partX1, partX2; 51 int partX1, partX2;
52 int off_x, off_y; 52 int off_x, off_y;
53 ExaMigrationRec pixmaps[1]; 53 ExaMigrationRec pixmaps[1];
54 54
55 pixmaps[0].as_dst = TRUE; 55 pixmaps[0].as_dst = TRUE;
56 pixmaps[0].as_src = FALSE; 56 pixmaps[0].as_src = FALSE;
57 pixmaps[0].pPix = pPixmap; 57 pixmaps[0].pPix = pPixmap;
58 pixmaps[0].pReg = NULL; 58 pixmaps[0].pReg = NULL;
59 59
60 if (pExaScr->swappedOut || 60 if (pExaScr->swappedOut ||
61 pGC->fillStyle != FillSolid || 61 pGC->fillStyle != FillSolid ||
62 pExaPixmap->accel_blocked) 62 pExaPixmap->accel_blocked)
63 { 63 {
64 ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); 64 ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
65 return; 65 return;
66 } else { 66 } else {
67 exaDoMigration (pixmaps, 1, TRUE); 67 exaDoMigration (pixmaps, 1, TRUE);
68 } 68 }
69 69
70 if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || 70 if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
71 !(*pExaScr->info->PrepareSolid) (pPixmap, 71 !(*pExaScr->info->PrepareSolid) (pPixmap,
72 pGC->alu, 72 pGC->alu,
73 pGC->planemask, 73 pGC->planemask,
74 pGC->fgPixel)) 74 pGC->fgPixel))
75 { 75 {
76 ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); 76 ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
77 return; 77 return;
78 } 78 }
79 79
80 pextent = REGION_EXTENTS(pGC->pScreen, pClip); 80 pextent = REGION_EXTENTS(pGC->pScreen, pClip);
81 extentX1 = pextent->x1; 81 extentX1 = pextent->x1;
82 extentY1 = pextent->y1; 82 extentY1 = pextent->y1;
83 extentX2 = pextent->x2; 83 extentX2 = pextent->x2;
84 extentY2 = pextent->y2; 84 extentY2 = pextent->y2;
85 while (n--) 85 while (n--)
86 { 86 {
87 fullX1 = ppt->x; 87 fullX1 = ppt->x;
88 fullY1 = ppt->y; 88 fullY1 = ppt->y;
89 fullX2 = fullX1 + (int) *pwidth; 89 fullX2 = fullX1 + (int) *pwidth;
90 ppt++; 90 ppt++;
91 pwidth++; 91 pwidth++;
92 92
93 if (fullY1 < extentY1 || extentY2 <= fullY1) 93 if (fullY1 < extentY1 || extentY2 <= fullY1)
94 continue; 94 continue;
95 95
96 if (fullX1 < extentX1) 96 if (fullX1 < extentX1)
97 fullX1 = extentX1; 97 fullX1 = extentX1;
98 98
99 if (fullX2 > extentX2) 99 if (fullX2 > extentX2)
100 fullX2 = extentX2; 100 fullX2 = extentX2;
101 101
102 if (fullX1 >= fullX2) 102 if (fullX1 >= fullX2)
103 continue; 103 continue;
104 104
105 nbox = REGION_NUM_RECTS (pClip); 105 nbox = REGION_NUM_RECTS (pClip);
106 if (nbox == 1) 106 if (nbox == 1)
107 { 107 {
108 (*pExaScr->info->Solid) (pPixmap, 108 (*pExaScr->info->Solid) (pPixmap,
109 fullX1 + off_x, fullY1 + off_y, 109 fullX1 + off_x, fullY1 + off_y,
110 fullX2 + off_x, fullY1 + 1 + off_y); 110 fullX2 + off_x, fullY1 + 1 + off_y);
111 } 111 }
112 else 112 else
113 { 113 {
114 pbox = REGION_RECTS(pClip); 114 pbox = REGION_RECTS(pClip);
115 while(nbox--) 115 while(nbox--)
116 { 116 {
117 if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) 117 if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
118 { 118 {
119 partX1 = pbox->x1; 119 partX1 = pbox->x1;
120 if (partX1 < fullX1) 120 if (partX1 < fullX1)
121 partX1 = fullX1; 121 partX1 = fullX1;
122 partX2 = pbox->x2; 122 partX2 = pbox->x2;
123 if (partX2 > fullX2) 123 if (partX2 > fullX2)
124 partX2 = fullX2; 124 partX2 = fullX2;
125 if (partX2 > partX1) { 125 if (partX2 > partX1) {
126 (*pExaScr->info->Solid) (pPixmap, 126 (*pExaScr->info->Solid) (pPixmap,
127 partX1 + off_x, fullY1 + off_y, 127 partX1 + off_x, fullY1 + off_y,
128 partX2 + off_x, fullY1 + 1 + off_y); 128 partX2 + off_x, fullY1 + 1 + off_y);
129 } 129 }
130 } 130 }
131 pbox++; 131 pbox++;
132 } 132 }
133 } 133 }
134 } 134 }
135 (*pExaScr->info->DoneSolid) (pPixmap); 135 (*pExaScr->info->DoneSolid) (pPixmap);
136 exaMarkSync(pScreen); 136 exaMarkSync(pScreen);
137} 137}
138 138
139static Bool 139static Bool
140exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, 140exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
141 int w, int h, int format, char *bits, int src_stride) 141 int w, int h, int format, char *bits, int src_stride)
142{ 142{
143 ExaScreenPriv (pDrawable->pScreen); 143 ExaScreenPriv (pDrawable->pScreen);
144 PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); 144 PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
145 ExaPixmapPriv(pPix); 145 ExaPixmapPriv(pPix);
146 RegionPtr pClip; 146 RegionPtr pClip;
147 BoxPtr pbox; 147 BoxPtr pbox;
148 int nbox; 148 int nbox;
149 int xoff, yoff; 149 int xoff, yoff;
150 int bpp = pDrawable->bitsPerPixel; 150 int bpp = pDrawable->bitsPerPixel;
151 Bool access_prepared = FALSE; 151 Bool access_prepared = FALSE;
152 152
153 if (pExaPixmap->accel_blocked) 153 if (pExaPixmap->accel_blocked)
154 return FALSE; 154 return FALSE;
155 155
156 /* Don't bother with under 8bpp, XYPixmaps. */ 156 /* Don't bother with under 8bpp, XYPixmaps. */
157 if (format != ZPixmap || bpp < 8) 157 if (format != ZPixmap || bpp < 8)
158 return FALSE; 158 return FALSE;
159 159
160 /* Only accelerate copies: no rop or planemask. */ 160 /* Only accelerate copies: no rop or planemask. */
161 if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy) 161 if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
162 return FALSE; 162 return FALSE;
163 163
164 if (pExaScr->swappedOut) 164 if (pExaScr->swappedOut)
165 return FALSE; 165 return FALSE;
166 166
167 if (pExaPixmap->pDamage) { 167 if (pExaPixmap->pDamage) {
168 ExaMigrationRec pixmaps[1]; 168 ExaMigrationRec pixmaps[1];
169 169
170 pixmaps[0].as_dst = TRUE; 170 pixmaps[0].as_dst = TRUE;
171 pixmaps[0].as_src = FALSE; 171 pixmaps[0].as_src = FALSE;
172 pixmaps[0].pPix = pPix; 172 pixmaps[0].pPix = pPix;
173 pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); 173 pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
174 174
175 exaDoMigration (pixmaps, 1, TRUE); 175 exaDoMigration (pixmaps, 1, TRUE);
176 } 176 }
177 177
178 pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); 178 pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
179 179
180 if (!pPix || !pExaScr->info->UploadToScreen) 180 if (!pPix || !pExaScr->info->UploadToScreen)
181 return FALSE; 181 return FALSE;
182 182
183 x += pDrawable->x; 183 x += pDrawable->x;
184 y += pDrawable->y; 184 y += pDrawable->y;
185 185
186 pClip = fbGetCompositeClip(pGC); 186 pClip = fbGetCompositeClip(pGC);
187 for (nbox = REGION_NUM_RECTS(pClip), 187 for (nbox = REGION_NUM_RECTS(pClip),
188 pbox = REGION_RECTS(pClip); 188 pbox = REGION_RECTS(pClip);
189 nbox--; 189 nbox--;
190 pbox++) 190 pbox++)
191 { 191 {
192 int x1 = x; 192 int x1 = x;
193 int y1 = y; 193 int y1 = y;
194 int x2 = x + w; 194 int x2 = x + w;
195 int y2 = y + h; 195 int y2 = y + h;
196 char *src; 196 char *src;
197 Bool ok; 197 Bool ok;
198 198
199 if (x1 < pbox->x1) 199 if (x1 < pbox->x1)
200 x1 = pbox->x1; 200 x1 = pbox->x1;
201 if (y1 < pbox->y1) 201 if (y1 < pbox->y1)
202 y1 = pbox->y1; 202 y1 = pbox->y1;
203 if (x2 > pbox->x2) 203 if (x2 > pbox->x2)
204 x2 = pbox->x2; 204 x2 = pbox->x2;
205 if (y2 > pbox->y2) 205 if (y2 > pbox->y2)
206 y2 = pbox->y2; 206 y2 = pbox->y2;
207 if (x1 >= x2 || y1 >= y2) 207 if (x1 >= x2 || y1 >= y2)
208 continue; 208 continue;
209 209
210 src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); 210 src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
211 ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff, 211 ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
212 x2 - x1, y2 - y1, src, src_stride); 212 x2 - x1, y2 - y1, src, src_stride);
213 /* If we fail to accelerate the upload, fall back to using unaccelerated 213 /* If we fail to accelerate the upload, fall back to using unaccelerated
214 * fb calls. 214 * fb calls.
215 */ 215 */
216 if (!ok) { 216 if (!ok) {
217 FbStip *dst; 217 FbStip *dst;
218 FbStride dst_stride; 218 FbStride dst_stride;
219 int dstBpp; 219 int dstBpp;
220 int dstXoff, dstYoff; 220 int dstXoff, dstYoff;
221 221
222 if (!access_prepared) { 222 if (!access_prepared) {
223 ExaDoPrepareAccess(pDrawable, EXA_PREPARE_DEST); 223 ExaDoPrepareAccess(pDrawable, EXA_PREPARE_DEST);
224 224
225 access_prepared = TRUE; 225 access_prepared = TRUE;
226 } 226 }
227 227
228 fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp, 228 fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
229 dstXoff, dstYoff); 229 dstXoff, dstYoff);
230 230
231 fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)), 231 fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)),
232 src_stride / sizeof(FbStip), 232 src_stride / sizeof(FbStip),
233 (x1 - x) * dstBpp, 233 (x1 - x) * dstBpp,
234 dst + (y1 + dstYoff) * dst_stride, 234 dst + (y1 + dstYoff) * dst_stride,
235 dst_stride, 235 dst_stride,
236 (x1 + dstXoff) * dstBpp, 236 (x1 + dstXoff) * dstBpp,
237 (x2 - x1) * dstBpp, 237 (x2 - x1) * dstBpp,
238 y2 - y1, 238 y2 - y1,
239 GXcopy, FB_ALLONES, dstBpp); 239 GXcopy, FB_ALLONES, dstBpp);
240 } 240 }
241 } 241 }
242 242
243 if (access_prepared) 243 if (access_prepared)
244 exaFinishAccess(pDrawable, EXA_PREPARE_DEST); 244 exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
245 else 245 else
246 exaMarkSync(pDrawable->pScreen); 246 exaMarkSync(pDrawable->pScreen);
247 247
248 return TRUE; 248 return TRUE;
249} 249}
250 250
251static void 251static void
252exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, 252exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
253 int w, int h, int leftPad, int format, char *bits) 253 int w, int h, int leftPad, int format, char *bits)
254{ 254{
255 if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits, 255 if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits,
256 PixmapBytePad(w, pDrawable->depth))) 256 PixmapBytePad(w, pDrawable->depth)))
257 ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, 257 ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
258 bits); 258 bits);
259} 259}
260 260
261static Bool inline 261static Bool inline
262exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, 262exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
263 GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) 263 GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
264{ 264{
265 ExaScreenPriv (pDstDrawable->pScreen); 265 ExaScreenPriv (pDstDrawable->pScreen);
266 PixmapPtr pSrcPixmap, pDstPixmap; 266 PixmapPtr pSrcPixmap, pDstPixmap;
267 int src_off_x, src_off_y, dst_off_x, dst_off_y; 267 int src_off_x, src_off_y, dst_off_x, dst_off_y;
268 int dirsetup; 268 int dirsetup;
269 269
270 /* Need to get both pixmaps to call the driver routines */ 270 /* Need to get both pixmaps to call the driver routines */
271 pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y); 271 pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y);
272 pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y); 272 pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y);
273 if (!pSrcPixmap || !pDstPixmap) 273 if (!pSrcPixmap || !pDstPixmap)
274 return FALSE; 274 return FALSE;
275 275
276 /* 276 /*
277 * Now the case of a chip that only supports xdir = ydir = 1 or 277 * Now the case of a chip that only supports xdir = ydir = 1 or
278 * xdir = ydir = -1, but we have xdir != ydir. 278 * xdir = ydir = -1, but we have xdir != ydir.
279 */ 279 */
280 dirsetup = 0; /* No direction set up yet. */ 280 dirsetup = 0; /* No direction set up yet. */
281 for (; nbox; pbox++, nbox--) { 281 for (; nbox; pbox++, nbox--) {
282 if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { 282 if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
283 /* Do a xdir = ydir = -1 blit instead. */ 283 /* Do a xdir = ydir = -1 blit instead. */
284 if (dirsetup != -1) { 284 if (dirsetup != -1) {
285 if (dirsetup != 0) 285 if (dirsetup != 0)
286 pExaScr->info->DoneCopy(pDstPixmap); 286 pExaScr->info->DoneCopy(pDstPixmap);
287 dirsetup = -1; 287 dirsetup = -1;
288 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, 288 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
289 pDstPixmap, 289 pDstPixmap,
290 -1, -1, 290 -1, -1,
291 pGC ? pGC->alu : GXcopy, 291 pGC ? pGC->alu : GXcopy,
292 pGC ? pGC->planemask : 292 pGC ? pGC->planemask :
293 FB_ALLONES)) 293 FB_ALLONES))
294 return FALSE; 294 return FALSE;
295 } 295 }
296 (*pExaScr->info->Copy)(pDstPixmap, 296 (*pExaScr->info->Copy)(pDstPixmap,
297 src_off_x + pbox->x1 + dx, 297 src_off_x + pbox->x1 + dx,
298 src_off_y + pbox->y1 + dy, 298 src_off_y + pbox->y1 + dy,
299 dst_off_x + pbox->x1, 299 dst_off_x + pbox->x1,
300 dst_off_y + pbox->y1, 300 dst_off_y + pbox->y1,
301 pbox->x2 - pbox->x1, 301 pbox->x2 - pbox->x1,
302 pbox->y2 - pbox->y1); 302 pbox->y2 - pbox->y1);
303 } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { 303 } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
304 /* Do a xdir = ydir = 1 blit instead. */ 304 /* Do a xdir = ydir = 1 blit instead. */
305 if (dirsetup != 1) { 305 if (dirsetup != 1) {
306 if (dirsetup != 0) 306 if (dirsetup != 0)
307 pExaScr->info->DoneCopy(pDstPixmap); 307 pExaScr->info->DoneCopy(pDstPixmap);
308 dirsetup = 1; 308 dirsetup = 1;
309 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, 309 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
310 pDstPixmap, 310 pDstPixmap,
311 1, 1, 311 1, 1,
312 pGC ? pGC->alu : GXcopy, 312 pGC ? pGC->alu : GXcopy,
313 pGC ? pGC->planemask : 313 pGC ? pGC->planemask :
314 FB_ALLONES)) 314 FB_ALLONES))
315 return FALSE; 315 return FALSE;
316 } 316 }
317 (*pExaScr->info->Copy)(pDstPixmap, 317 (*pExaScr->info->Copy)(pDstPixmap,
318 src_off_x + pbox->x1 + dx, 318 src_off_x + pbox->x1 + dx,
319 src_off_y + pbox->y1 + dy, 319 src_off_y + pbox->y1 + dy,
320 dst_off_x + pbox->x1, 320 dst_off_x + pbox->x1,
321 dst_off_y + pbox->y1, 321 dst_off_y + pbox->y1,
322 pbox->x2 - pbox->x1, 322 pbox->x2 - pbox->x1,
323 pbox->y2 - pbox->y1); 323 pbox->y2 - pbox->y1);
324 } else if (dx >= 0) { 324 } else if (dx >= 0) {
325 /* 325 /*
326 * xdir = 1, ydir = -1. 326 * xdir = 1, ydir = -1.
327 * Perform line-by-line xdir = ydir = 1 blits, going up. 327 * Perform line-by-line xdir = ydir = 1 blits, going up.
328 */ 328 */
329 int i; 329 int i;
330 if (dirsetup != 1) { 330 if (dirsetup != 1) {
331 if (dirsetup != 0) 331 if (dirsetup != 0)
332 pExaScr->info->DoneCopy(pDstPixmap); 332 pExaScr->info->DoneCopy(pDstPixmap);
333 dirsetup = 1; 333 dirsetup = 1;
334 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, 334 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
335 pDstPixmap, 335 pDstPixmap,
336 1, 1, 336 1, 1,
337 pGC ? pGC->alu : GXcopy, 337 pGC ? pGC->alu : GXcopy,
338 pGC ? pGC->planemask : 338 pGC ? pGC->planemask :
339 FB_ALLONES)) 339 FB_ALLONES))
340 return FALSE; 340 return FALSE;
341 } 341 }
342 for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--) 342 for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
343 (*pExaScr->info->Copy)(pDstPixmap, 343 (*pExaScr->info->Copy)(pDstPixmap,
344 src_off_x + pbox->x1 + dx, 344 src_off_x + pbox->x1 + dx,
345 src_off_y + pbox->y1 + dy + i, 345 src_off_y + pbox->y1 + dy + i,
346 dst_off_x + pbox->x1, 346 dst_off_x + pbox->x1,
347 dst_off_y + pbox->y1 + i, 347 dst_off_y + pbox->y1 + i,
348 pbox->x2 - pbox->x1, 1); 348 pbox->x2 - pbox->x1, 1);
349 } else { 349 } else {
350 /* 350 /*
351 * xdir = -1, ydir = 1. 351 * xdir = -1, ydir = 1.
352 * Perform line-by-line xdir = ydir = -1 blits, going down. 352 * Perform line-by-line xdir = ydir = -1 blits, going down.
353 */ 353 */
354 int i; 354 int i;
355 if (dirsetup != -1) { 355 if (dirsetup != -1) {
356 if (dirsetup != 0) 356 if (dirsetup != 0)
357 pExaScr->info->DoneCopy(pDstPixmap); 357 pExaScr->info->DoneCopy(pDstPixmap);
358 dirsetup = -1; 358 dirsetup = -1;
359 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, 359 if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
360 pDstPixmap, 360 pDstPixmap,
361 -1, -1, 361 -1, -1,
362 pGC ? pGC->alu : GXcopy, 362 pGC ? pGC->alu : GXcopy,
363 pGC ? pGC->planemask : 363 pGC ? pGC->planemask :
364 FB_ALLONES)) 364 FB_ALLONES))
365 return FALSE; 365 return FALSE;
366 } 366 }
367 for (i = 0; i < pbox->y2 - pbox->y1; i++) 367 for (i = 0; i < pbox->y2 - pbox->y1; i++)
368 (*pExaScr->info->Copy)(pDstPixmap, 368 (*pExaScr->info->Copy)(pDstPixmap,
369 src_off_x + pbox->x1 + dx, 369 src_off_x + pbox->x1 + dx,
370 src_off_y + pbox->y1 + dy + i, 370 src_off_y + pbox->y1 + dy + i,
371 dst_off_x + pbox->x1, 371 dst_off_x + pbox->x1,
372 dst_off_y + pbox->y1 + i, 372 dst_off_y + pbox->y1 + i,
373 pbox->x2 - pbox->x1, 1); 373 pbox->x2 - pbox->x1, 1);
374 } 374 }
375 } 375 }
376 if (dirsetup != 0) 376 if (dirsetup != 0)
377 pExaScr->info->DoneCopy(pDstPixmap); 377 pExaScr->info->DoneCopy(pDstPixmap);
378 exaMarkSync(pDstDrawable->pScreen); 378 exaMarkSync(pDstDrawable->pScreen);
379 return TRUE; 379 return TRUE;
380} 380}
381 381
382void 382void
383exaCopyNtoN (DrawablePtr pSrcDrawable, 383exaCopyNtoN (DrawablePtr pSrcDrawable,
384 DrawablePtr pDstDrawable, 384 DrawablePtr pDstDrawable,
385 GCPtr pGC, 385 GCPtr pGC,
386 BoxPtr pbox, 386 BoxPtr pbox,
387 int nbox, 387 int nbox,
388 int dx, 388 int dx,
389 int dy, 389 int dy,
390 Bool reverse, 390 Bool reverse,
391 Bool upsidedown, 391 Bool upsidedown,
392 Pixel bitplane, 392 Pixel bitplane,
393 void *closure) 393 void *closure)
394{ 394{
395 ExaScreenPriv (pDstDrawable->pScreen); 395 ExaScreenPriv (pDstDrawable->pScreen);
396 PixmapPtr pSrcPixmap, pDstPixmap; 396 PixmapPtr pSrcPixmap, pDstPixmap;
397 ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; 397 ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
398 int src_off_x, src_off_y; 398 int src_off_x, src_off_y;
399 int dst_off_x, dst_off_y; 399 int dst_off_x, dst_off_y;
400 ExaMigrationRec pixmaps[2]; 400 ExaMigrationRec pixmaps[2];
401 RegionPtr srcregion = NULL, dstregion = NULL; 401 RegionPtr srcregion = NULL, dstregion = NULL;
402 xRectangle *rects; 402 xRectangle *rects;
403 403
404 /* avoid doing copy operations if no boxes */ 404 /* avoid doing copy operations if no boxes */
405 if (nbox == 0) 405 if (nbox == 0)
406 return; 406 return;
407 407
408 pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable); 408 pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
409 pDstPixmap = exaGetDrawablePixmap (pDstDrawable); 409 pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
410 410
411 exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); 411 exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
412 exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); 412 exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
413 413
414 rects = xalloc(nbox * sizeof(xRectangle)); 414 rects = xalloc(nbox * sizeof(xRectangle));
415 415
416 if (rects) { 416 if (rects) {
417 int i; 417 int i;
 418 int ordering;
418 419
419 for (i = 0; i < nbox; i++) { 420 for (i = 0; i < nbox; i++) {
420 rects[i].x = pbox[i].x1 + dx + src_off_x; 421 rects[i].x = pbox[i].x1 + dx + src_off_x;
421 rects[i].y = pbox[i].y1 + dy + src_off_y; 422 rects[i].y = pbox[i].y1 + dy + src_off_y;
422 rects[i].width = pbox[i].x2 - pbox[i].x1; 423 rects[i].width = pbox[i].x2 - pbox[i].x1;
423 rects[i].height = pbox[i].y2 - pbox[i].y1; 424 rects[i].height = pbox[i].y2 - pbox[i].y1;
424 } 425 }
425 426
426 srcregion = RECTS_TO_REGION(pScreen, nbox, rects, CT_YXBANDED); 427 /* This must match the miRegionCopy() logic for reversing rect order */
 428 if (nbox == 1 || (dx > 0 && dy > 0) ||
 429 (pDstDrawable != pSrcDrawable &&
 430 (pDstDrawable->type != DRAWABLE_WINDOW ||
 431 pSrcDrawable->type != DRAWABLE_WINDOW)))
 432 ordering = CT_YXBANDED;
 433 else
 434 ordering = CT_UNSORTED;
 435
 436 srcregion = RECTS_TO_REGION(pScreen, nbox, rects, ordering);
427 xfree(rects); 437 xfree(rects);
428 438
429 if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask, 439 if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
430 pGC->fillStyle, pGC->alu, 440 pGC->fillStyle, pGC->alu,
431 pGC->clientClipType)) { 441 pGC->clientClipType)) {
432 dstregion = REGION_CREATE(pScreen, NullBox, 0); 442 dstregion = REGION_CREATE(pScreen, NullBox, 0);
433 REGION_COPY(pScreen, dstregion, srcregion); 443 REGION_COPY(pScreen, dstregion, srcregion);
434 REGION_TRANSLATE(pScreen, dstregion, dst_off_x - dx - src_off_x, 444 REGION_TRANSLATE(pScreen, dstregion, dst_off_x - dx - src_off_x,
435 dst_off_y - dy - src_off_y); 445 dst_off_y - dy - src_off_y);
436 } 446 }
437 } 447 }
438 448
439 pixmaps[0].as_dst = TRUE; 449 pixmaps[0].as_dst = TRUE;
440 pixmaps[0].as_src = FALSE; 450 pixmaps[0].as_src = FALSE;
441 pixmaps[0].pPix = pDstPixmap; 451 pixmaps[0].pPix = pDstPixmap;
442 pixmaps[0].pReg = dstregion; 452 pixmaps[0].pReg = dstregion;
443 pixmaps[1].as_dst = FALSE; 453 pixmaps[1].as_dst = FALSE;
444 pixmaps[1].as_src = TRUE; 454 pixmaps[1].as_src = TRUE;
445 pixmaps[1].pPix = pSrcPixmap; 455 pixmaps[1].pPix = pSrcPixmap;
446 pixmaps[1].pReg = srcregion; 456 pixmaps[1].pReg = srcregion;
447 457
448 pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap); 458 pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap);
449 pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap); 459 pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap);
450 460
451 /* Check whether the accelerator can use this pixmap. 461 /* Check whether the accelerator can use this pixmap.
452 * If the pitch of the pixmaps is out of range, there's nothing 462 * If the pitch of the pixmaps is out of range, there's nothing
453 * we can do but fall back to software rendering. 463 * we can do but fall back to software rendering.
454 */ 464 */
455 if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || 465 if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH ||
456 pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) 466 pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH)
457 goto fallback; 467 goto fallback;
458 468
459 /* If the width or the height of either of the pixmaps 469 /* If the width or the height of either of the pixmaps
460 * is out of range, check whether the boxes are actually out of the 470 * is out of range, check whether the boxes are actually out of the
461 * addressable range as well. If they aren't, we can still do 471 * addressable range as well. If they aren't, we can still do
462 * the copying in hardware. 472 * the copying in hardware.
463 */ 473 */
464 if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { 474 if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) {
465 int i; 475 int i;
466 476
467 for (i = 0; i < nbox; i++) { 477 for (i = 0; i < nbox; i++) {
468 /* src */ 478 /* src */
469 if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || 479 if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX ||
470 (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) 480 (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY)
471 goto fallback; 481 goto fallback;
472 482
473 /* dst */ 483 /* dst */
474 if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || 484 if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX ||
475 (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) 485 (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY)
476 goto fallback; 486 goto fallback;
477 } 487 }
478 } 488 }
479 489
480 exaDoMigration (pixmaps, 2, TRUE); 490 exaDoMigration (pixmaps, 2, TRUE);
481 491
482 /* Mixed directions must be handled specially if the card is lame */ 492 /* Mixed directions must be handled specially if the card is lame */
483 if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && 493 if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
484 reverse != upsidedown) { 494 reverse != upsidedown) {
485 if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, 495 if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
486 dx, dy)) 496 dx, dy))
487 goto out; 497 goto out;
488 goto fallback; 498 goto fallback;
489 } 499 }
490 500
491 if (!exaPixmapIsOffscreen(pSrcPixmap) || 501 if (!exaPixmapIsOffscreen(pSrcPixmap) ||
492 !exaPixmapIsOffscreen(pDstPixmap) || 502 !exaPixmapIsOffscreen(pDstPixmap) ||
493 !(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, 503 !(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
494 upsidedown ? -1 : 1, 504 upsidedown ? -1 : 1,
495 pGC ? pGC->alu : GXcopy, 505 pGC ? pGC->alu : GXcopy,
496 pGC ? pGC->planemask : FB_ALLONES)) { 506 pGC ? pGC->planemask : FB_ALLONES)) {
497 goto fallback; 507 goto fallback;
498 } 508 }
499 509
500 while (nbox--) 510 while (nbox--)
501 { 511 {
502 (*pExaScr->info->Copy) (pDstPixmap, 512 (*pExaScr->info->Copy) (pDstPixmap,
503 pbox->x1 + dx + src_off_x, 513 pbox->x1 + dx + src_off_x,
504 pbox->y1 + dy + src_off_y, 514 pbox->y1 + dy + src_off_y,
505 pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, 515 pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
506 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); 516 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
507 pbox++; 517 pbox++;
508 } 518 }
509 519
510 (*pExaScr->info->DoneCopy) (pDstPixmap); 520 (*pExaScr->info->DoneCopy) (pDstPixmap);
511 exaMarkSync (pDstDrawable->pScreen); 521 exaMarkSync (pDstDrawable->pScreen);
512 522
513 goto out; 523 goto out;
514 524
515fallback: 525fallback:
516 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable, 526 EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
517 exaDrawableLocation(pSrcDrawable), 527 exaDrawableLocation(pSrcDrawable),
518 exaDrawableLocation(pDstDrawable))); 528 exaDrawableLocation(pDstDrawable)));
519 exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, dstregion); 529 exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, dstregion);
520 exaPrepareAccessReg (pSrcDrawable, EXA_PREPARE_SRC, srcregion); 530 exaPrepareAccessReg (pSrcDrawable, EXA_PREPARE_SRC, srcregion);
521 fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, 531 fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
522 upsidedown, bitplane, closure); 532 upsidedown, bitplane, closure);
523 exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC); 533 exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
524 exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST); 534 exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
525 535
526out: 536out:
527 if (dstregion) { 537 if (dstregion) {
528 REGION_UNINIT(pScreen, dstregion); 538 REGION_UNINIT(pScreen, dstregion);
529 REGION_DESTROY(pScreen, dstregion); 539 REGION_DESTROY(pScreen, dstregion);
530 } 540 }
531 if (srcregion) { 541 if (srcregion) {
532 REGION_UNINIT(pScreen, srcregion); 542 REGION_UNINIT(pScreen, srcregion);
533 REGION_DESTROY(pScreen, srcregion); 543 REGION_DESTROY(pScreen, srcregion);
534 } 544 }
535} 545}
536 546
537RegionPtr 547RegionPtr
538exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, 548exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
539 int srcx, int srcy, int width, int height, int dstx, int dsty) 549 int srcx, int srcy, int width, int height, int dstx, int dsty)
540{ 550{
541 ExaScreenPriv (pDstDrawable->pScreen); 551 ExaScreenPriv (pDstDrawable->pScreen);
542 552
543 if (pExaScr->swappedOut) { 553 if (pExaScr->swappedOut) {
544 return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC, 554 return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
545 srcx, srcy, width, height, dstx, dsty); 555 srcx, srcy, width, height, dstx, dsty);
546 } 556 }
547 557
548 return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, 558 return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
549 srcx, srcy, width, height, 559 srcx, srcy, width, height,
550 dstx, dsty, exaCopyNtoN, 0, NULL); 560 dstx, dsty, exaCopyNtoN, 0, NULL);
551} 561}
552 562
553static void 563static void
554exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, 564exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
555 DDXPointPtr ppt) 565 DDXPointPtr ppt)
556{ 566{
557 int i; 567 int i;
558 xRectangle *prect; 568 xRectangle *prect;
559 569
560 /* If we can't reuse the current GC as is, don't bother accelerating the 570 /* If we can't reuse the current GC as is, don't bother accelerating the
561 * points. 571 * points.
562 */ 572 */
563 if (pGC->fillStyle != FillSolid) { 573 if (pGC->fillStyle != FillSolid) {
564 ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt); 574 ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
565 return; 575 return;
566 } 576 }
567 577
568 prect = xalloc(sizeof(xRectangle) * npt); 578 prect = xalloc(sizeof(xRectangle) * npt);
569 for (i = 0; i < npt; i++) { 579 for (i = 0; i < npt; i++) {
570 prect[i].x = ppt[i].x; 580 prect[i].x = ppt[i].x;
571 prect[i].y = ppt[i].y; 581 prect[i].y = ppt[i].y;
572 if (i > 0 && mode == CoordModePrevious) { 582 if (i > 0 && mode == CoordModePrevious) {
573 prect[i].x += prect[i - 1].x; 583 prect[i].x += prect[i - 1].x;
574 prect[i].y += prect[i - 1].y; 584 prect[i].y += prect[i - 1].y;
575 } 585 }
576 prect[i].width = 1; 586 prect[i].width = 1;
577 prect[i].height = 1; 587 prect[i].height = 1;
578 } 588 }
579 pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect); 589 pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect);
580 xfree(prect); 590 xfree(prect);
581} 591}
582 592
583/** 593/**
584 * exaPolylines() checks if it can accelerate the lines as a group of 594 * exaPolylines() checks if it can accelerate the lines as a group of
585 * horizontal or vertical lines (rectangles), and uses existing rectangle fill 595 * horizontal or vertical lines (rectangles), and uses existing rectangle fill
586 * acceleration if so. 596 * acceleration if so.
587 */ 597 */
588static void 598static void
589exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, 599exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
590 DDXPointPtr ppt) 600 DDXPointPtr ppt)
591{ 601{
592 xRectangle *prect; 602 xRectangle *prect;
593 int x1, x2, y1, y2; 603 int x1, x2, y1, y2;
594 int i; 604 int i;
595 605
596 /* Don't try to do wide lines or non-solid fill style. */ 606 /* Don't try to do wide lines or non-solid fill style. */
597 if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || 607 if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
598 pGC->fillStyle != FillSolid) { 608 pGC->fillStyle != FillSolid) {
599 ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); 609 ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
600 return; 610 return;
601 } 611 }
602 612
603 prect = xalloc(sizeof(xRectangle) * (npt - 1)); 613 prect = xalloc(sizeof(xRectangle) * (npt - 1));
604 x1 = ppt[0].x; 614 x1 = ppt[0].x;
605 y1 = ppt[0].y; 615 y1 = ppt[0].y;
606 /* If we have any non-horizontal/vertical, fall back. */ 616 /* If we have any non-horizontal/vertical, fall back. */
607 for (i = 0; i < npt - 1; i++) { 617 for (i = 0; i < npt - 1; i++) {
608 if (mode == CoordModePrevious) { 618 if (mode == CoordModePrevious) {
609 x2 = x1 + ppt[i + 1].x; 619 x2 = x1 + ppt[i + 1].x;
610 y2 = y1 + ppt[i + 1].y; 620 y2 = y1 + ppt[i + 1].y;
611 } else { 621 } else {
612 x2 = ppt[i + 1].x; 622 x2 = ppt[i + 1].x;
613 y2 = ppt[i + 1].y; 623 y2 = ppt[i + 1].y;
614 } 624 }
615 625
616 if (x1 != x2 && y1 != y2) { 626 if (x1 != x2 && y1 != y2) {
617 xfree(prect); 627 xfree(prect);
618 ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); 628 ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
619 return; 629 return;
620 } 630 }
621 631
622 if (x1 < x2) { 632 if (x1 < x2) {
623 prect[i].x = x1; 633 prect[i].x = x1;
624 prect[i].width = x2 - x1 + 1; 634 prect[i].width = x2 - x1 + 1;
625 } else { 635 } else {
626 prect[i].x = x2; 636 prect[i].x = x2;
627 prect[i].width = x1 - x2 + 1; 637 prect[i].width = x1 - x2 + 1;
628 } 638 }
629 if (y1 < y2) { 639 if (y1 < y2) {
630 prect[i].y = y1; 640 prect[i].y = y1;
631 prect[i].height = y2 - y1 + 1; 641 prect[i].height = y2 - y1 + 1;
632 } else { 642 } else {
633 prect[i].y = y2; 643 prect[i].y = y2;
634 prect[i].height = y1 - y2 + 1; 644 prect[i].height = y1 - y2 + 1;
635 } 645 }
636 646
637 x1 = x2; 647 x1 = x2;
638 y1 = y2; 648 y1 = y2;
639 } 649 }
640 pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect); 650 pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect);
641 xfree(prect); 651 xfree(prect);
642} 652}
643 653
644/** 654/**
645 * exaPolySegment() checks if it can accelerate the lines as a group of 655 * exaPolySegment() checks if it can accelerate the lines as a group of
646 * horizontal or vertical lines (rectangles), and uses existing rectangle fill 656 * horizontal or vertical lines (rectangles), and uses existing rectangle fill
647 * acceleration if so. 657 * acceleration if so.
648 */ 658 */
649static void 659static void
650exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg, 660exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
651 xSegment *pSeg) 661 xSegment *pSeg)
652{ 662{
653 xRectangle *prect; 663 xRectangle *prect;
654 int i; 664 int i;
655 665
656 /* Don't try to do wide lines or non-solid fill style. */ 666 /* Don't try to do wide lines or non-solid fill style. */
657 if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || 667 if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
658 pGC->fillStyle != FillSolid) 668 pGC->fillStyle != FillSolid)
659 { 669 {
660 ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); 670 ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
661 return; 671 return;
662 } 672 }
663 673
664 /* If we have any non-horizontal/vertical, fall back. */ 674 /* If we have any non-horizontal/vertical, fall back. */
665 for (i = 0; i < nseg; i++) { 675 for (i = 0; i < nseg; i++) {
666 if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) { 676 if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
667 ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); 677 ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
668 return; 678 return;
669 } 679 }
670 } 680 }
671 681
672 prect = xalloc(sizeof(xRectangle) * nseg); 682 prect = xalloc(sizeof(xRectangle) * nseg);
673 for (i = 0; i < nseg; i++) { 683 for (i = 0; i < nseg; i++) {
674 if (pSeg[i].x1 < pSeg[i].x2) { 684 if (pSeg[i].x1 < pSeg[i].x2) {
675 prect[i].x = pSeg[i].x1; 685 prect[i].x = pSeg[i].x1;
676 prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1; 686 prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
677 } else { 687 } else {
678 prect[i].x = pSeg[i].x2; 688 prect[i].x = pSeg[i].x2;
679 prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1; 689 prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
680 } 690 }
681 if (pSeg[i].y1 < pSeg[i].y2) { 691 if (pSeg[i].y1 < pSeg[i].y2) {
682 prect[i].y = pSeg[i].y1; 692 prect[i].y = pSeg[i].y1;
683 prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1; 693 prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
684 } else { 694 } else {
685 prect[i].y = pSeg[i].y2; 695 prect[i].y = pSeg[i].y2;
686 prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1; 696 prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
687 } 697 }
688 698
689 /* don't paint last pixel */ 699 /* don't paint last pixel */
690 if (pGC->capStyle == CapNotLast) { 700 if (pGC->capStyle == CapNotLast) {
691 if (prect[i].width == 1) 701 if (prect[i].width == 1)
692 prect[i].height--; 702 prect[i].height--;
693 else 703 else
694 prect[i].width--; 704 prect[i].width--;
695 } 705 }
696 } 706 }
697 pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect); 707 pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect);
698 xfree(prect); 708 xfree(prect);
699} 709}
700 710
701static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, 711static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
702 Pixel pixel, CARD32 planemask, CARD32 alu, 712 Pixel pixel, CARD32 planemask, CARD32 alu,
703 unsigned int clientClipType); 713 unsigned int clientClipType);
704 714
705static void 715static void
706exaPolyFillRect(DrawablePtr pDrawable, 716exaPolyFillRect(DrawablePtr pDrawable,
707 GCPtr pGC, 717 GCPtr pGC,
708 int nrect, 718 int nrect,
709 xRectangle *prect) 719 xRectangle *prect)
710{ 720{
711 ExaScreenPriv (pDrawable->pScreen); 721 ExaScreenPriv (pDrawable->pScreen);
712 RegionPtr pClip = fbGetCompositeClip(pGC); 722 RegionPtr pClip = fbGetCompositeClip(pGC);
713 PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); 723 PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
714 ExaPixmapPriv (pPixmap); 724 ExaPixmapPriv (pPixmap);
715 register BoxPtr pbox; 725 register BoxPtr pbox;
716 BoxPtr pextent; 726 BoxPtr pextent;
717 int extentX1, extentX2, extentY1, extentY2; 727 int extentX1, extentX2, extentY1, extentY2;
718 int fullX1, fullX2, fullY1, fullY2; 728 int fullX1, fullX2, fullY1, fullY2;
719 int partX1, partX2, partY1, partY2; 729 int partX1, partX2, partY1, partY2;
720 int xoff, yoff; 730 int xoff, yoff;
721 int xorg, yorg; 731 int xorg, yorg;
722 int n; 732 int n;
723 ExaMigrationRec pixmaps[2]; 733 ExaMigrationRec pixmaps[2];
724 RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); 734 RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
725 735
726 /* Compute intersection of rects and clip region */ 736 /* Compute intersection of rects and clip region */
727 REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y); 737 REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
728 REGION_INTERSECT(pScreen, pReg, pClip, pReg); 738 REGION_INTERSECT(pScreen, pReg, pClip, pReg);
729 739
730 if (!REGION_NUM_RECTS(pReg)) { 740 if (!REGION_NUM_RECTS(pReg)) {
731 goto out; 741 goto out;
732 } 742 }
733 743
734 pixmaps[0].as_dst = TRUE; 744 pixmaps[0].as_dst = TRUE;
735 pixmaps[0].as_src = FALSE; 745 pixmaps[0].as_src = FALSE;
736 pixmaps[0].pPix = pPixmap; 746 pixmaps[0].pPix = pPixmap;
737 pixmaps[0].pReg = NULL; 747 pixmaps[0].pReg = NULL;
738 748
739 exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); 749 exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
740 750
741 if (pExaScr->swappedOut || pExaPixmap->accel_blocked) 751 if (pExaScr->swappedOut || pExaPixmap->accel_blocked)
742 { 752 {
743 goto fallback; 753 goto fallback;
744 } 754 }
745 755
746 /* For ROPs where overlaps don't matter, convert rectangles to region and 756 /* For ROPs where overlaps don't matter, convert rectangles to region and
747 * call exaFillRegion{Solid,Tiled}. 757 * call exaFillRegion{Solid,Tiled}.
748 */ 758 */
749 if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) && 759 if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
750 (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear || 760 (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
751 pGC->alu == GXnoop || pGC->alu == GXcopyInverted || 761 pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
752 pGC->alu == GXset)) { 762 pGC->alu == GXset)) {
753 if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) && 763 if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
754 exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ? 764 exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
755 pGC->fgPixel : pGC->tile.pixel, pGC->planemask, 765 pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
756 pGC->alu, pGC->clientClipType)) || 766 pGC->alu, pGC->clientClipType)) ||
757 (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && 767 (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
758 exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, 768 exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
759 pGC->planemask, pGC->alu, 769 pGC->planemask, pGC->alu,
760 pGC->clientClipType))) { 770 pGC->clientClipType))) {
761 goto out; 771 goto out;
762 } 772 }
763 } 773 }
764 774
765 if (pGC->fillStyle != FillSolid && 775 if (pGC->fillStyle != FillSolid &&
766 !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) 776 !(pGC->tileIsPixel && pGC->fillStyle == FillTiled))
767 { 777 {
768 goto fallback; 778 goto fallback;
769 } 779 }
770 780
771 exaDoMigration (pixmaps, 1, TRUE); 781 exaDoMigration (pixmaps, 1, TRUE);
772 782
773 if (!exaPixmapIsOffscreen (pPixmap) || 783 if (!exaPixmapIsOffscreen (pPixmap) ||
774 !(*pExaScr->info->PrepareSolid) (pPixmap, 784 !(*pExaScr->info->PrepareSolid) (pPixmap,
775 pGC->alu, 785 pGC->alu,
776 pGC->planemask, 786 pGC->planemask,
777 pGC->fgPixel)) 787 pGC->fgPixel))
778 { 788 {
779fallback: 789fallback:
780 ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect); 790 ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
781 goto out; 791 goto out;
782 } 792 }
783 793
784 xorg = pDrawable->x; 794 xorg = pDrawable->x;
785 yorg = pDrawable->y; 795 yorg = pDrawable->y;
786 796
787 pextent = REGION_EXTENTS(pGC->pScreen, pClip); 797 pextent = REGION_EXTENTS(pGC->pScreen, pClip);
788 extentX1 = pextent->x1; 798 extentX1 = pextent->x1;
789 extentY1 = pextent->y1; 799 extentY1 = pextent->y1;
790 extentX2 = pextent->x2; 800 extentX2 = pextent->x2;
791 extentY2 = pextent->y2; 801 extentY2 = pextent->y2;
792 while (nrect--) 802 while (nrect--)
793 { 803 {
794 fullX1 = prect->x + xorg; 804 fullX1 = prect->x + xorg;
795 fullY1 = prect->y + yorg; 805 fullY1 = prect->y + yorg;
796 fullX2 = fullX1 + (int) prect->width; 806 fullX2 = fullX1 + (int) prect->width;
797 fullY2 = fullY1 + (int) prect->height; 807 fullY2 = fullY1 + (int) prect->height;
798 prect++; 808 prect++;
799 809
800 if (fullX1 < extentX1) 810 if (fullX1 < extentX1)
801 fullX1 = extentX1; 811 fullX1 = extentX1;
802 812
803 if (fullY1 < extentY1) 813 if (fullY1 < extentY1)
804 fullY1 = extentY1; 814 fullY1 = extentY1;
805 815
806 if (fullX2 > extentX2) 816 if (fullX2 > extentX2)
807 fullX2 = extentX2; 817 fullX2 = extentX2;
808 818
809 if (fullY2 > extentY2) 819 if (fullY2 > extentY2)
810 fullY2 = extentY2; 820 fullY2 = extentY2;
811 821
812 if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) 822 if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
813 continue; 823 continue;
814 n = REGION_NUM_RECTS (pClip); 824 n = REGION_NUM_RECTS (pClip);
815 if (n == 1) 825 if (n == 1)
816 { 826 {
817 (*pExaScr->info->Solid) (pPixmap, 827 (*pExaScr->info->Solid) (pPixmap,
818 fullX1 + xoff, fullY1 + yoff, 828 fullX1 + xoff, fullY1 + yoff,
819 fullX2 + xoff, fullY2 + yoff); 829 fullX2 + xoff, fullY2 + yoff);
820 } 830 }
821 else 831 else
822 { 832 {
823 pbox = REGION_RECTS(pClip); 833 pbox = REGION_RECTS(pClip);
824 /* 834 /*
825 * clip the rectangle to each box in the clip region 835 * clip the rectangle to each box in the clip region
826 * this is logically equivalent to calling Intersect(), 836 * this is logically equivalent to calling Intersect(),
827 * but rectangles may overlap each other here. 837 * but rectangles may overlap each other here.
828 */ 838 */
829 while(n--) 839 while(n--)
830 { 840 {
831 partX1 = pbox->x1; 841 partX1 = pbox->x1;
832 if (partX1 < fullX1) 842 if (partX1 < fullX1)
833 partX1 = fullX1; 843 partX1 = fullX1;
834 partY1 = pbox->y1; 844 partY1 = pbox->y1;
835 if (partY1 < fullY1) 845 if (partY1 < fullY1)
836 partY1 = fullY1; 846 partY1 = fullY1;
837 partX2 = pbox->x2; 847 partX2 = pbox->x2;
838 if (partX2 > fullX2) 848 if (partX2 > fullX2)
839 partX2 = fullX2; 849 partX2 = fullX2;
840 partY2 = pbox->y2; 850 partY2 = pbox->y2;
841 if (partY2 > fullY2) 851 if (partY2 > fullY2)
842 partY2 = fullY2; 852 partY2 = fullY2;
843 853
844 pbox++; 854 pbox++;
845 855
846 if (partX1 < partX2 && partY1 < partY2) { 856 if (partX1 < partX2 && partY1 < partY2) {
847 (*pExaScr->info->Solid) (pPixmap, 857 (*pExaScr->info->Solid) (pPixmap,
848 partX1 + xoff, partY1 + yoff, 858 partX1 + xoff, partY1 + yoff,
849 partX2 + xoff, partY2 + yoff); 859 partX2 + xoff, partY2 + yoff);
850 } 860 }
851 } 861 }
852 } 862 }
853 } 863 }
854 (*pExaScr->info->DoneSolid) (pPixmap); 864 (*pExaScr->info->DoneSolid) (pPixmap);
855 exaMarkSync(pDrawable->pScreen); 865 exaMarkSync(pDrawable->pScreen);
856 866
857out: 867out:
858 REGION_UNINIT(pScreen, pReg); 868 REGION_UNINIT(pScreen, pReg);
859 REGION_DESTROY(pScreen, pReg); 869 REGION_DESTROY(pScreen, pReg);
860} 870}
861 871
862const GCOps exaOps = { 872const GCOps exaOps = {
863 exaFillSpans, 873 exaFillSpans,
864 ExaCheckSetSpans, 874 ExaCheckSetSpans,
865 exaPutImage, 875 exaPutImage,
866 exaCopyArea, 876 exaCopyArea,
867 ExaCheckCopyPlane, 877 ExaCheckCopyPlane,
868 exaPolyPoint, 878 exaPolyPoint,
869 exaPolylines, 879 exaPolylines,
870 exaPolySegment, 880 exaPolySegment,
871 miPolyRectangle, 881 miPolyRectangle,
872 ExaCheckPolyArc, 882 ExaCheckPolyArc,
873 miFillPolygon, 883 miFillPolygon,
874 exaPolyFillRect, 884 exaPolyFillRect,
875 miPolyFillArc, 885 miPolyFillArc,
876 miPolyText8, 886 miPolyText8,
877 miPolyText16, 887 miPolyText16,
878 miImageText8, 888 miImageText8,
879 miImageText16, 889 miImageText16,
880 ExaCheckImageGlyphBlt, 890 ExaCheckImageGlyphBlt,
881 ExaCheckPolyGlyphBlt, 891 ExaCheckPolyGlyphBlt,
882 ExaCheckPushPixels, 892 ExaCheckPushPixels,
883}; 893};
884 894
885void 895void
886exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 896exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
887{ 897{
888 RegionRec rgnDst; 898 RegionRec rgnDst;
889 int dx, dy; 899 int dx, dy;
890 PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); 900 PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
891 901
892 dx = ptOldOrg.x - pWin->drawable.x; 902 dx = ptOldOrg.x - pWin->drawable.x;
893 dy = ptOldOrg.y - pWin->drawable.y; 903 dy = ptOldOrg.y - pWin->drawable.y;
894 REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); 904 REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
895 905
896 REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0); 906 REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
897 907
898 REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); 908 REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
899#ifdef COMPOSITE 909#ifdef COMPOSITE
900 if (pPixmap->screen_x || pPixmap->screen_y) 910 if (pPixmap->screen_x || pPixmap->screen_y)
901 REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst, 911 REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
902 -pPixmap->screen_x, -pPixmap->screen_y); 912 -pPixmap->screen_x, -pPixmap->screen_y);
903#endif 913#endif
904 914
905 fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable, 915 fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
906 NULL, 916 NULL,
907 &rgnDst, dx, dy, exaCopyNtoN, 0, NULL); 917 &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
908 918
909 REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); 919 REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
910} 920}
911 921
912static Bool 922static Bool
913exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, 923exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
914 CARD32 planemask, CARD32 alu, unsigned int clientClipType) 924 CARD32 planemask, CARD32 alu, unsigned int clientClipType)
915{ 925{
916 ExaScreenPriv(pDrawable->pScreen); 926 ExaScreenPriv(pDrawable->pScreen);
917 PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); 927 PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
918 ExaPixmapPriv (pPixmap); 928 ExaPixmapPriv (pPixmap);
919 int xoff, yoff; 929 int xoff, yoff;
920 ExaMigrationRec pixmaps[1]; 930 ExaMigrationRec pixmaps[1];
921 Bool ret = FALSE; 931 Bool ret = FALSE;
922 932
923 pixmaps[0].as_dst = TRUE; 933 pixmaps[0].as_dst = TRUE;
924 pixmaps[0].as_src = FALSE; 934 pixmaps[0].as_src = FALSE;
925 pixmaps[0].pPix = pPixmap; 935 pixmaps[0].pPix = pPixmap;
926 pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid, 936 pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
927 alu, clientClipType) 937 alu, clientClipType)
928 ? NULL : pRegion; 938 ? NULL : pRegion;
929 939
930 exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); 940 exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
931 REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); 941 REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
932 942
933 if (pExaPixmap->accel_blocked) 943 if (pExaPixmap->accel_blocked)
934 { 944 {
935 goto out; 945 goto out;
936 } else { 946 } else {
937 exaDoMigration (pixmaps, 1, TRUE); 947 exaDoMigration (pixmaps, 1, TRUE);
938 } 948 }
939 949
940 if (exaPixmapIsOffscreen (pPixmap) && 950 if (exaPixmapIsOffscreen (pPixmap) &&
941 (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) 951 (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
942 { 952 {
943 int nbox; 953 int nbox;
944 BoxPtr pBox; 954 BoxPtr pBox;
945 955
946 nbox = REGION_NUM_RECTS (pRegion); 956 nbox = REGION_NUM_RECTS (pRegion);
947 pBox = REGION_RECTS (pRegion); 957 pBox = REGION_RECTS (pRegion);
948 958
949 while (nbox--) 959 while (nbox--)
950 { 960 {
951 (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2, 961 (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
952 pBox->y2); 962 pBox->y2);
953 pBox++; 963 pBox++;
954 } 964 }
955 (*pExaScr->info->DoneSolid) (pPixmap); 965 (*pExaScr->info->DoneSolid) (pPixmap);
956 exaMarkSync(pDrawable->pScreen); 966 exaMarkSync(pDrawable->pScreen);
957 967
958 if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) && 968 if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
959 pDrawable->width == 1 && pDrawable->height == 1 && 969 pDrawable->width == 1 && pDrawable->height == 1 &&
960 pDrawable->bitsPerPixel != 24) { 970 pDrawable->bitsPerPixel != 24) {
961 ExaPixmapPriv(pPixmap); 971 ExaPixmapPriv(pPixmap);
962 972
963 switch (pDrawable->bitsPerPixel) { 973 switch (pDrawable->bitsPerPixel) {
964 case 32: 974 case 32:
965 *(CARD32*)pExaPixmap->sys_ptr = pixel; 975 *(CARD32*)pExaPixmap->sys_ptr = pixel;
966 break; 976 break;
967 case 16: 977 case 16:
968 *(CARD16*)pExaPixmap->sys_ptr = pixel; 978 *(CARD16*)pExaPixmap->sys_ptr = pixel;
969 break; 979 break;
970 case 8: 980 case 8:
971 *(CARD8*)pExaPixmap->sys_ptr = pixel; 981 *(CARD8*)pExaPixmap->sys_ptr = pixel;
972 } 982 }
973 983
974 REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, 984 REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
975 pRegion); 985 pRegion);
976 } 986 }
977 987
978 ret = TRUE; 988 ret = TRUE;
979 } 989 }
980 990
981out: 991out:
982 REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); 992 REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
983 993
984 return ret; 994 return ret;
985} 995}
986 996
987/* Try to do an accelerated tile of the pTile into pRegion of pDrawable. 997/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
988 * Based on fbFillRegionTiled(), fbTile(). 998 * Based on fbFillRegionTiled(), fbTile().
989 */ 999 */
990Bool 1000Bool
991exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, 1001exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
992 DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu, 1002 DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
993 unsigned int clientClipType) 1003 unsigned int clientClipType)
994{ 1004{
995 ExaScreenPriv(pDrawable->pScreen); 1005 ExaScreenPriv(pDrawable->pScreen);
996 PixmapPtr pPixmap; 1006 PixmapPtr pPixmap;
997 ExaPixmapPrivPtr pExaPixmap; 1007 ExaPixmapPrivPtr pExaPixmap;
998 ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile); 1008 ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
999 int xoff, yoff; 1009 int xoff, yoff;
1000 int tileWidth, tileHeight; 1010 int tileWidth, tileHeight;
1001 ExaMigrationRec pixmaps[2]; 1011 ExaMigrationRec pixmaps[2];
1002 int nbox = REGION_NUM_RECTS (pRegion); 1012 int nbox = REGION_NUM_RECTS (pRegion);
1003 BoxPtr pBox = REGION_RECTS (pRegion); 1013 BoxPtr pBox = REGION_RECTS (pRegion);
1004 Bool ret = FALSE; 1014 Bool ret = FALSE;
1005 int i; 1015 int i;
1006 1016
1007 tileWidth = pTile->drawable.width; 1017 tileWidth = pTile->drawable.width;
1008 tileHeight = pTile->drawable.height; 1018 tileHeight = pTile->drawable.height;
1009 1019
1010 /* If we're filling with a solid color, grab it out and go to 1020 /* If we're filling with a solid color, grab it out and go to
1011 * FillRegionSolid, saving numerous copies. 1021 * FillRegionSolid, saving numerous copies.
1012 */ 1022 */
1013 if (tileWidth == 1 && tileHeight == 1) 1023 if (tileWidth == 1 && tileHeight == 1)
1014 return exaFillRegionSolid(pDrawable, pRegion, 1024 return exaFillRegionSolid(pDrawable, pRegion,
1015 exaGetPixmapFirstPixel (pTile), planemask, 1025 exaGetPixmapFirstPixel (pTile), planemask,
1016 alu, clientClipType); 1026 alu, clientClipType);
1017 1027
1018 pixmaps[0].as_dst = TRUE; 1028 pixmaps[0].as_dst = TRUE;
1019 pixmaps[0].as_src = FALSE; 1029 pixmaps[0].as_src = FALSE;
1020 pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable); 1030 pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
1021 pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled, 1031 pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
1022 alu, clientClipType) 1032 alu, clientClipType)
1023 ? NULL : pRegion; 1033 ? NULL : pRegion;
1024 pixmaps[1].as_dst = FALSE; 1034 pixmaps[1].as_dst = FALSE;
1025 pixmaps[1].as_src = TRUE; 1035 pixmaps[1].as_src = TRUE;
1026 pixmaps[1].pPix = pTile; 1036 pixmaps[1].pPix = pTile;
1027 pixmaps[1].pReg = NULL; 1037 pixmaps[1].pReg = NULL;
1028 1038
1029 pExaPixmap = ExaGetPixmapPriv (pPixmap); 1039 pExaPixmap = ExaGetPixmapPriv (pPixmap);
1030 1040
1031 if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) 1041 if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
1032 { 1042 {
1033 return FALSE; 1043 return FALSE;
1034 } else { 1044 } else {
1035 exaDoMigration (pixmaps, 2, TRUE); 1045 exaDoMigration (pixmaps, 2, TRUE);
1036 } 1046 }
1037 1047
1038 pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); 1048 pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
1039 1049
1040 if (!pPixmap || !exaPixmapIsOffscreen(pTile)) 1050 if (!pPixmap || !exaPixmapIsOffscreen(pTile))
1041 return FALSE; 1051 return FALSE;
1042 1052
1043 if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) 1053 if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
1044 { 1054 {
1045 if (xoff || yoff) 1055 if (xoff || yoff)
1046 REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); 1056 REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
1047 1057
1048 for (i = 0; i < nbox; i++) 1058 for (i = 0; i < nbox; i++)
1049 { 1059 {
1050 int height = pBox[i].y2 - pBox[i].y1; 1060 int height = pBox[i].y2 - pBox[i].y1;
1051 int dstY = pBox[i].y1; 1061 int dstY = pBox[i].y1;
1052 int tileY; 1062 int tileY;
1053 1063
1054 if (alu == GXcopy) 1064 if (alu == GXcopy)
1055 height = min(height, tileHeight); 1065 height = min(height, tileHeight);
1056 1066
1057 modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY); 1067 modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);
1058 1068
1059 while (height > 0) { 1069 while (height > 0) {
1060 int width = pBox[i].x2 - pBox[i].x1; 1070 int width = pBox[i].x2 - pBox[i].x1;
1061 int dstX = pBox[i].x1; 1071 int dstX = pBox[i].x1;
1062 int tileX; 1072 int tileX;
1063 int h = tileHeight - tileY; 1073 int h = tileHeight - tileY;
1064 1074
1065 if (alu == GXcopy) 1075 if (alu == GXcopy)
1066 width = min(width, tileWidth); 1076 width = min(width, tileWidth);
1067 1077
1068 if (h > height) 1078 if (h > height)
1069 h = height; 1079 h = height;
1070 height -= h; 1080 height -= h;
1071 1081
1072 modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth, 1082 modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
1073 tileX); 1083 tileX);
1074 1084
1075 while (width > 0) { 1085 while (width > 0) {
1076 int w = tileWidth - tileX; 1086 int w = tileWidth - tileX;
1077 if (w > width) 1087 if (w > width)
1078 w = width; 1088 w = width;
1079 width -= w; 1089 width -= w;
1080 1090
1081 (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY, 1091 (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
1082 w, h); 1092 w, h);
1083 dstX += w; 1093 dstX += w;
1084 tileX = 0; 1094 tileX = 0;
1085 } 1095 }
1086 dstY += h; 1096 dstY += h;
1087 tileY = 0; 1097 tileY = 0;
1088 } 1098 }
1089 } 1099 }
1090 (*pExaScr->info->DoneCopy) (pPixmap); 1100 (*pExaScr->info->DoneCopy) (pPixmap);
1091 1101
1092 /* With GXcopy, we only need to do the basic algorithm up to the tile 1102 /* With GXcopy, we only need to do the basic algorithm up to the tile
1093 * size; then, we can just keep doubling the destination in each 1103 * size; then, we can just keep doubling the destination in each
1094 * direction until it fills the box. This way, the number of copy 1104 * direction until it fills the box. This way, the number of copy
1095 * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where 1105 * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where
1096 * rx/ry is the ratio between box and tile width/height. This can make 1106 * rx/ry is the ratio between box and tile width/height. This can make
1097 * a big difference if each driver copy incurs a significant constant 1107 * a big difference if each driver copy incurs a significant constant
1098 * overhead. 1108 * overhead.
1099 */ 1109 */
1100 if (alu != GXcopy) 1110 if (alu != GXcopy)
1101 ret = TRUE; 1111 ret = TRUE;
1102 else { 1112 else {
1103 Bool more_copy = FALSE; 1113 Bool more_copy = FALSE;
1104 1114
1105 for (i = 0; i < nbox; i++) { 1115 for (i = 0; i < nbox; i++) {
1106 int dstX = pBox[i].x1 + tileWidth; 1116 int dstX = pBox[i].x1 + tileWidth;
1107 int dstY = pBox[i].y1 + tileHeight; 1117 int dstY = pBox[i].y1 + tileHeight;
1108 1118
1109 if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) { 1119 if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) {
1110 more_copy = TRUE; 1120 more_copy = TRUE;
1111 break; 1121 break;
1112 } 1122 }
1113 } 1123 }
1114 1124
1115 if (more_copy == FALSE) 1125 if (more_copy == FALSE)
1116 ret = TRUE; 1126 ret = TRUE;
1117 1127
1118 if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap, 1128 if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap,
1119 1, 1, alu, planemask)) { 1129 1, 1, alu, planemask)) {
1120 for (i = 0; i < nbox; i++) 1130 for (i = 0; i < nbox; i++)
1121 { 1131 {
1122 int dstX = pBox[i].x1 + tileWidth; 1132 int dstX = pBox[i].x1 + tileWidth;
1123 int dstY = pBox[i].y1 + tileHeight; 1133 int dstY = pBox[i].y1 + tileHeight;
1124 int width = min(pBox[i].x2 - dstX, tileWidth); 1134 int width = min(pBox[i].x2 - dstX, tileWidth);
1125 int height = min(pBox[i].y2 - pBox[i].y1, tileHeight); 1135 int height = min(pBox[i].y2 - pBox[i].y1, tileHeight);
1126 1136
1127 while (dstX < pBox[i].x2) { 1137 while (dstX < pBox[i].x2) {
1128 (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, 1138 (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
1129 dstX, pBox[i].y1, width, height); 1139 dstX, pBox[i].y1, width, height);
1130 dstX += width; 1140 dstX += width;
1131 width = min(pBox[i].x2 - dstX, width * 2); 1141 width = min(pBox[i].x2 - dstX, width * 2);
1132 } 1142 }
1133 1143
1134 width = pBox[i].x2 - pBox[i].x1; 1144 width = pBox[i].x2 - pBox[i].x1;
1135 height = min(pBox[i].y2 - dstY, tileHeight); 1145 height = min(pBox[i].y2 - dstY, tileHeight);
1136 1146
1137 while (dstY < pBox[i].y2) { 1147 while (dstY < pBox[i].y2) {
1138 (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, 1148 (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
1139 pBox[i].x1, dstY, width, height); 1149 pBox[i].x1, dstY, width, height);
1140 dstY += height; 1150 dstY += height;
1141 height = min(pBox[i].y2 - dstY, height * 2); 1151 height = min(pBox[i].y2 - dstY, height * 2);
1142 } 1152 }
1143 } 1153 }
1144 1154
1145 (*pExaScr->info->DoneCopy) (pPixmap); 1155 (*pExaScr->info->DoneCopy) (pPixmap);
1146 1156
1147 ret = TRUE; 1157 ret = TRUE;
1148 } 1158 }
1149 } 1159 }
1150 1160
1151 exaMarkSync(pDrawable->pScreen); 1161 exaMarkSync(pDrawable->pScreen);
1152 1162
1153 if (xoff || yoff) 1163 if (xoff || yoff)
1154 REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); 1164 REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
1155 } 1165 }
1156 1166
1157 return ret; 1167 return ret;
1158} 1168}
1159 1169
1160 1170
1161/** 1171/**
1162 * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. 1172 * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
1163 * 1173 *
1164 * This is probably the only case we actually care about. The rest fall through 1174 * This is probably the only case we actually care about. The rest fall through
1165 * to migration and fbGetImage, which hopefully will result in migration pushing 1175 * to migration and fbGetImage, which hopefully will result in migration pushing
1166 * the pixmap out of framebuffer. 1176 * the pixmap out of framebuffer.
1167 */ 1177 */
1168void 1178void
1169exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, 1179exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
1170 unsigned int format, unsigned long planeMask, char *d) 1180 unsigned int format, unsigned long planeMask, char *d)
1171{ 1181{
1172 ExaScreenPriv (pDrawable->pScreen); 1182 ExaScreenPriv (pDrawable->pScreen);
1173 ExaMigrationRec pixmaps[1]; 1183 ExaMigrationRec pixmaps[1];
1174 BoxRec Box; 1184 BoxRec Box;
1175 RegionRec Reg; 1185 RegionRec Reg;
1176 PixmapPtr pPix; 1186 PixmapPtr pPix;
1177 int xoff, yoff; 1187 int xoff, yoff;
1178 Bool ok; 1188 Bool ok;
1179 1189
1180 pixmaps[0].as_dst = FALSE; 1190 pixmaps[0].as_dst = FALSE;
1181 pixmaps[0].as_src = TRUE; 1191 pixmaps[0].as_src = TRUE;
1182 pixmaps[0].pPix = pPix = exaGetDrawablePixmap (pDrawable); 1192 pixmaps[0].pPix = pPix = exaGetDrawablePixmap (pDrawable);
1183 pixmaps[0].pReg = &Reg; 1193 pixmaps[0].pReg = &Reg;
1184 1194
1185 exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff); 1195 exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
1186 1196
1187 Box.x1 = pDrawable->y + x + xoff; 1197 Box.x1 = pDrawable->y + x + xoff;
1188 Box.y1 = pDrawable->y + y + yoff; 1198 Box.y1 = pDrawable->y + y + yoff;
1189 Box.x2 = Box.x1 + w; 1199 Box.x2 = Box.x1 + w;
1190 Box.y2 = Box.y1 + h; 1200 Box.y2 = Box.y1 + h;
1191 1201
1192 REGION_INIT(pScreen, &Reg, &Box, 1); 1202 REGION_INIT(pScreen, &Reg, &Box, 1);
1193 1203
1194 if (pExaScr->swappedOut) 1204 if (pExaScr->swappedOut)
1195 goto fallback; 1205 goto fallback;
1196 1206
1197 exaDoMigration(pixmaps, 1, FALSE); 1207 exaDoMigration(pixmaps, 1, FALSE);
1198 1208
1199 pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); 1209 pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
1200 1210
1201 if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL) 1211 if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL)
1202 goto fallback; 1212 goto fallback;
1203 1213
1204 /* Only cover the ZPixmap, solid copy case. */ 1214 /* Only cover the ZPixmap, solid copy case. */
1205 if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask)) 1215 if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
1206 goto fallback; 1216 goto fallback;
1207 1217
1208 /* Only try to handle the 8bpp and up cases, since we don't want to think 1218 /* Only try to handle the 8bpp and up cases, since we don't want to think
1209 * about <8bpp. 1219 * about <8bpp.
1210 */ 1220 */
1211 if (pDrawable->bitsPerPixel < 8) 1221 if (pDrawable->bitsPerPixel < 8)
1212 goto fallback; 1222 goto fallback;
1213 1223
1214 ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff, 1224 ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff,
1215 pDrawable->y + y + yoff, w, h, d, 1225 pDrawable->y + y + yoff, w, h, d,
1216 PixmapBytePad(w, pDrawable->depth)); 1226 PixmapBytePad(w, pDrawable->depth));
1217 if (ok) { 1227 if (ok) {
1218 exaWaitSync(pDrawable->pScreen); 1228 exaWaitSync(pDrawable->pScreen);
1219 goto out; 1229 goto out;
1220 } 1230 }
1221 1231
1222fallback: 1232fallback:
1223 EXA_FALLBACK(("from %p (%c)\n", pDrawable, 1233 EXA_FALLBACK(("from %p (%c)\n", pDrawable,
1224 exaDrawableLocation(pDrawable))); 1234 exaDrawableLocation(pDrawable)));
1225 1235
1226 exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg); 1236 exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg);
1227 fbGetImage (pDrawable, x, y, w, h, format, planeMask, d); 1237 fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
1228 exaFinishAccess (pDrawable, EXA_PREPARE_SRC); 1238 exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
1229 1239
1230out: 1240out:
1231 REGION_UNINIT(pScreen, &Reg); 1241 REGION_UNINIT(pScreen, &Reg);
1232} 1242}