]> git.pld-linux.org Git - packages/xorg-xserver-server.git/blame - xorg-xserver-server-exa.patch
- up to 1.6.1
[packages/xorg-xserver-server.git] / xorg-xserver-server-exa.patch
CommitLineData
055b6688
AM
1--- xorg/exa/exa_render.c~ 2009-02-25 20:12:11.000000000 +0100
2+++ xorg/exa/exa_render.c 2009-02-28 18:09:52.562970685 +0100
3@@ -342,7 +342,6 @@
4 int src_off_x, src_off_y, dst_off_x, dst_off_y;
5 PixmapPtr pSrcPix, pDstPix;
6 ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
7- struct _Pixmap scratch;
8 ExaMigrationRec pixmaps[2];
9
10 if (!pExaScr->info->PrepareComposite)
11@@ -386,13 +385,6 @@
12 if (!exaPixmapIsOffscreen(pDstPix))
13 return 0;
14
15- if (!pSrcPix && pExaScr->info->UploadToScratch)
16- {
17- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
18- if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
19- pSrcPix = &scratch;
20- }
21-
22 if (!pSrcPix)
23 return 0;
24
25@@ -573,7 +565,6 @@
26 int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
27 PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
28 ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
29- struct _Pixmap scratch;
30 ExaMigrationRec pixmaps[3];
31
32 pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
33@@ -652,16 +643,6 @@
34 return 0;
35 }
36
37- if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->UploadToScratch) {
38- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
39- if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
40- pSrcPix = &scratch;
41- } else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->UploadToScratch) {
42- pMaskPix = exaGetDrawablePixmap (pMask->pDrawable);
43- if ((*pExaScr->info->UploadToScratch) (pMaskPix, &scratch))
44- pMaskPix = &scratch;
45- }
46-
47 if (!pSrcPix || (pMask && !pMaskPix)) {
48 REGION_UNINIT(pDst->pDrawable->pScreen, &region);
49 return 0;
50commit f07f18231a921d3ae9dd9b75881c9e58e9e2e235
51Author: Michel Dänzer <daenzer@vmware.com>
52Date: Thu Feb 26 10:35:44 2009 +0100
453260b6 53
055b6688
AM
54 EXA: Allow using exaCompositeRects also when we can't use a mask in exaGlyphs.
55
56 This should give the full benefits of the glyph cache even when we can't use a
57 mask.
58
59 This also means we no longer need to scan the glyphs to see if they overlap,
60 we can just use a mask or not as the client asks.
61
62 Signed-off-by: Michel Dänzer <daenzer@vmware.com>
453260b6 63
055b6688
AM
64diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
65index 688081d..918fd85 100644
66--- a/exa/exa_glyphs.c
67+++ b/exa/exa_glyphs.c
68@@ -68,7 +68,7 @@
69 #define GLYPH_BUFFER_SIZE 256
33d29f3f 70
055b6688
AM
71 typedef struct {
72- PicturePtr source;
73+ PicturePtr mask;
74 ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE];
75 int count;
76 } ExaGlyphBuffer, *ExaGlyphBufferPtr;
77@@ -144,7 +144,7 @@ exaUnrealizeGlyphCaches(ScreenPtr pScreen,
78
79 /* All caches for a single format share a single pixmap for glyph storage,
80 * allowing mixing glyphs of different sizes without paying a penalty
81- * for switching between source pixmaps. (Note that for a size of font
82+ * for switching between mask pixmaps. (Note that for a size of font
83 * right at the border between two sizes, we might be switching for almost
84 * every glyph.)
85 *
86@@ -417,13 +417,19 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
87 ExaGlyphCachePtr cache,
88 ExaGlyphBufferPtr buffer,
89 GlyphPtr pGlyph,
90- int xGlyph,
91- int yGlyph)
92+ PicturePtr pSrc,
93+ PicturePtr pDst,
94+ INT16 xSrc,
95+ INT16 ySrc,
96+ INT16 xMask,
97+ INT16 yMask,
98+ INT16 xDst,
99+ INT16 yDst)
100 {
101 ExaCompositeRectPtr rect;
102 int pos;
103
104- if (buffer->source && buffer->source != cache->picture)
105+ if (buffer->mask && buffer->mask != cache->picture)
106 return ExaGlyphNeedFlush;
33d29f3f 107
055b6688
AM
108 if (!cache->picture) {
109@@ -497,13 +503,28 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
33d29f3f 110
055b6688 111 }
33d29f3f 112
055b6688
AM
113- buffer->source = cache->picture;
114+ buffer->mask = cache->picture;
115
116 rect = &buffer->rects[buffer->count];
117- rect->xSrc = CACHE_X(pos);
118- rect->ySrc = CACHE_Y(pos);
119- rect->xDst = xGlyph - pGlyph->info.x;
120- rect->yDst = yGlyph - pGlyph->info.y;
33d29f3f 121+
055b6688
AM
122+ if (pSrc)
123+ {
124+ rect->xSrc = xSrc;
125+ rect->ySrc = ySrc;
126+ rect->xMask = CACHE_X(pos);
127+ rect->yMask = CACHE_Y(pos);
33d29f3f 128+ }
055b6688
AM
129+ else
130+ {
131+ rect->xSrc = CACHE_X(pos);
132+ rect->ySrc = CACHE_Y(pos);
133+ rect->xMask = 0;
134+ rect->yMask = 0;
33d29f3f 135+ }
055b6688
AM
136+
137+ rect->pDst = pDst;
138+ rect->xDst = xDst - pGlyph->info.x;
139+ rect->yDst = yDst - pGlyph->info.y;
140 rect->width = pGlyph->info.width;
141 rect->height = pGlyph->info.height;
142
143@@ -519,15 +540,21 @@ static ExaGlyphCacheResult
144 exaBufferGlyph(ScreenPtr pScreen,
145 ExaGlyphBufferPtr buffer,
146 GlyphPtr pGlyph,
147- int xGlyph,
148- int yGlyph)
149+ PicturePtr pSrc,
150+ PicturePtr pDst,
151+ INT16 xSrc,
152+ INT16 ySrc,
153+ INT16 xMask,
154+ INT16 yMask,
155+ INT16 xDst,
156+ INT16 yDst)
157 {
158 ExaScreenPriv(pScreen);
159 unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format;
160 int width = pGlyph->info.width;
161 int height = pGlyph->info.height;
162 ExaCompositeRectPtr rect;
163- PicturePtr source;
164+ PicturePtr mask;
165 int i;
166
167 if (buffer->count == GLYPH_BUFFER_SIZE)
168@@ -542,9 +569,15 @@ exaBufferGlyph(ScreenPtr pScreen,
169 if (format == cache->format &&
170 width <= cache->glyphWidth &&
171 height <= cache->glyphHeight) {
172- ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen, &pExaScr->glyphCaches[i],
173+ ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen,
174+ &pExaScr->glyphCaches[i],
175 buffer,
176- pGlyph, xGlyph, yGlyph);
177+ pGlyph,
178+ pSrc,
179+ pDst,
180+ xSrc, ySrc,
181+ xMask, yMask,
182+ xDst, yDst);
183 switch (result) {
184 case ExaGlyphFail:
185 break;
186@@ -557,19 +590,21 @@ exaBufferGlyph(ScreenPtr pScreen,
187
188 /* Couldn't find the glyph in the cache, use the glyph picture directly */
189
190- source = GlyphPicture(pGlyph)[pScreen->myNum];
191- if (buffer->source && buffer->source != source)
192+ mask = GlyphPicture(pGlyph)[pScreen->myNum];
193+ if (buffer->mask && buffer->mask != mask)
194 return ExaGlyphNeedFlush;
195
196- buffer->source = source;
197-
198+ buffer->mask = mask;
199+
200 rect = &buffer->rects[buffer->count];
201- rect->xSrc = 0;
202- rect->ySrc = 0;
203- rect->xDst = xGlyph - pGlyph->info.x;
204- rect->yDst = yGlyph - pGlyph->info.y;
205- rect->width = pGlyph->info.width;
206- rect->height = pGlyph->info.height;
207+ rect->xSrc = xSrc;
208+ rect->ySrc = ySrc;
209+ rect->xMask = xMask;
210+ rect->yMask = yMask;
211+ rect->xDst = xDst - pGlyph->info.x;
212+ rect->yDst = yDst - pGlyph->info.y;
213+ rect->width = width;
214+ rect->height = height;
215
216 buffer->count++;
217
218@@ -580,44 +615,23 @@ static void
219 exaGlyphsToMask(PicturePtr pMask,
220 ExaGlyphBufferPtr buffer)
221 {
222- exaCompositeRects(PictOpAdd, buffer->source, pMask,
223+ exaCompositeRects(PictOpAdd, buffer->mask, NULL, pMask,
224 buffer->count, buffer->rects);
225
226 buffer->count = 0;
227- buffer->source = NULL;
228+ buffer->mask = NULL;
33d29f3f
AM
229 }
230
055b6688
AM
231 static void
232-exaGlyphsToDst(CARD8 op,
233- PicturePtr pSrc,
234+exaGlyphsToDst(PicturePtr pSrc,
235 PicturePtr pDst,
236- ExaGlyphBufferPtr buffer,
237- INT16 xSrc,
238- INT16 ySrc,
239- INT16 xDst,
240- INT16 yDst)
241+ ExaGlyphBufferPtr buffer)
33d29f3f 242 {
055b6688
AM
243- int i;
244-
245- for (i = 0; i < buffer->count; i++) {
246- ExaCompositeRectPtr rect = &buffer->rects[i];
247-
248- CompositePicture (op,
249- pSrc,
250- buffer->source,
251- pDst,
252- xSrc + rect->xDst - xDst,
253- ySrc + rect->yDst - yDst,
254- rect->xSrc,
255- rect->ySrc,
256- rect->xDst,
257- rect->yDst,
258- rect->width,
259- rect->height);
260- }
261+ exaCompositeRects(PictOpOver, pSrc, buffer->mask, pDst, buffer->count,
262+ buffer->rects);
263
264 buffer->count = 0;
265- buffer->source = NULL;
266+ buffer->mask = NULL;
33d29f3f
AM
267 }
268
055b6688
AM
269 /* Cut and paste from render/glyph.c - probably should export it instead */
270@@ -673,79 +687,6 @@ GlyphExtents (int nlist,
453260b6 271 }
055b6688 272 }
453260b6 273
055b6688
AM
274-/**
275- * Returns TRUE if the glyphs in the lists intersect. Only checks based on
276- * bounding box, which appears to be good enough to catch most cases at least.
277- */
278-static Bool
279-exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
280-{
281- int x1, x2, y1, y2;
282- int n;
283- GlyphPtr glyph;
284- int x, y;
285- BoxRec extents;
286- Bool first = TRUE;
33d29f3f 287-
055b6688
AM
288- x = 0;
289- y = 0;
290- while (nlist--) {
291- x += list->xOff;
292- y += list->yOff;
293- n = list->len;
294- list++;
295- while (n--) {
296- glyph = *glyphs++;
33d29f3f 297-
055b6688
AM
298- if (glyph->info.width == 0 || glyph->info.height == 0) {
299- x += glyph->info.xOff;
300- y += glyph->info.yOff;
301- continue;
302- }
33d29f3f 303-
055b6688
AM
304- x1 = x - glyph->info.x;
305- if (x1 < MINSHORT)
306- x1 = MINSHORT;
307- y1 = y - glyph->info.y;
308- if (y1 < MINSHORT)
309- y1 = MINSHORT;
310- x2 = x1 + glyph->info.width;
311- if (x2 > MAXSHORT)
312- x2 = MAXSHORT;
313- y2 = y1 + glyph->info.height;
314- if (y2 > MAXSHORT)
315- y2 = MAXSHORT;
316-
317- if (first) {
318- extents.x1 = x1;
319- extents.y1 = y1;
320- extents.x2 = x2;
321- extents.y2 = y2;
322- first = FALSE;
323- } else {
324- if (x1 < extents.x2 && x2 > extents.x1 &&
325- y1 < extents.y2 && y2 > extents.y1)
326- {
327- return TRUE;
328- }
329-
330- if (x1 < extents.x1)
331- extents.x1 = x1;
332- if (x2 > extents.x2)
333- extents.x2 = x2;
334- if (y1 < extents.y1)
335- extents.y1 = y1;
336- if (y2 > extents.y2)
337- extents.y2 = y2;
338- }
339- x += glyph->info.xOff;
340- y += glyph->info.yOff;
341- }
342- }
343-
344- return FALSE;
345-}
33d29f3f
AM
346-
347 void
055b6688
AM
348 exaGlyphs (CARD8 op,
349 PicturePtr pSrc,
350@@ -759,7 +700,7 @@ exaGlyphs (CARD8 op,
351 {
352 PicturePtr pPicture;
353 PixmapPtr pMaskPixmap = 0;
354- PicturePtr pMask;
355+ PicturePtr pMask = NULL;
356 ScreenPtr pScreen = pDst->pDrawable->pScreen;
357 int width = 0, height = 0;
358 int x, y;
359@@ -771,29 +712,6 @@ exaGlyphs (CARD8 op,
360 CARD32 component_alpha;
361 ExaGlyphBuffer buffer;
362
363- /* If we don't have a mask format but all the glyphs have the same format
364- * and don't intersect, use the glyph format as mask format for the full
365- * benefits of the glyph cache.
366- */
367- if (!maskFormat) {
368- Bool sameFormat = TRUE;
369- int i;
361c468e 370-
055b6688 371- maskFormat = list[0].format;
33d29f3f 372-
055b6688
AM
373- for (i = 0; i < nlist; i++) {
374- if (maskFormat->format != list[i].format->format) {
375- sameFormat = FALSE;
376- break;
377- }
378- }
379-
380- if (!sameFormat || (maskFormat->depth != 1 &&
381- exaGlyphsIntersect(nlist, list, glyphs))) {
382- maskFormat = NULL;
383- }
384- }
385-
386 if (maskFormat)
33d29f3f 387 {
055b6688
AM
388 GCPtr pGC;
389@@ -840,12 +758,11 @@ exaGlyphs (CARD8 op,
33d29f3f 390 }
055b6688 391 else
33d29f3f 392 {
055b6688
AM
393- pMask = pDst;
394 x = 0;
395 y = 0;
33d29f3f 396 }
055b6688
AM
397 buffer.count = 0;
398- buffer.source = NULL;
399+ buffer.mask = NULL;
400 while (nlist--)
401 {
402 x += list->xOff;
403@@ -856,16 +773,31 @@ exaGlyphs (CARD8 op,
404 glyph = *glyphs++;
405 pPicture = GlyphPicture (glyph)[pScreen->myNum];
406
407- if (glyph->info.width > 0 && glyph->info.height > 0 &&
408- exaBufferGlyph(pScreen, &buffer, glyph, x, y) == ExaGlyphNeedFlush)
409+ if (glyph->info.width > 0 && glyph->info.height > 0)
410 {
411 if (maskFormat)
412- exaGlyphsToMask(pMask, &buffer);
413+ {
414+ if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
415+ 0, 0, 0, 0, x, y) == ExaGlyphNeedFlush)
416+ {
417+ exaGlyphsToMask(pMask, &buffer);
418+ exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
419+ 0, 0, 0, 0, x, y);
420+ }
421+ }
422 else
423- exaGlyphsToDst(op, pSrc, pDst, &buffer,
424- xSrc, ySrc, xDst, yDst);
33d29f3f 425-
055b6688
AM
426- exaBufferGlyph(pScreen, &buffer, glyph, x, y);
427+ {
428+ if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
429+ xSrc + x - xDst, ySrc + y - yDst,
430+ x, y, x + extents.x1, y + extents.y1)
431+ == ExaGlyphNeedFlush)
432+ {
433+ exaGlyphsToDst(pSrc, pDst, &buffer);
434+ exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
435+ xSrc + x - xDst, ySrc + y - yDst,
436+ x, y, x + extents.x1, y + extents.y1);
453260b6
AM
437+ }
438+ }
055b6688 439 }
33d29f3f 440
055b6688
AM
441 x += glyph->info.xOff;
442@@ -878,8 +810,7 @@ exaGlyphs (CARD8 op,
443 if (maskFormat)
444 exaGlyphsToMask(pMask, &buffer);
445 else
446- exaGlyphsToDst(op, pSrc, pDst, &buffer,
447- xSrc, ySrc, xDst, yDst);
448+ exaGlyphsToDst(pSrc, pDst, &buffer);
449 }
33d29f3f 450
055b6688 451 if (maskFormat)
453260b6 452diff --git a/exa/exa_priv.h b/exa/exa_priv.h
055b6688 453index ea8c3da..8f83701 100644
453260b6
AM
454--- a/exa/exa_priv.h
455+++ b/exa/exa_priv.h
055b6688 456@@ -287,8 +287,11 @@ typedef struct _ExaMigrationRec {
453260b6
AM
457 } ExaMigrationRec, *ExaMigrationPtr;
458
055b6688
AM
459 typedef struct {
460+ PicturePtr pDst;
461 INT16 xSrc;
462 INT16 ySrc;
463+ INT16 xMask;
464+ INT16 yMask;
465 INT16 xDst;
466 INT16 yDst;
467 INT16 width;
468@@ -519,6 +522,7 @@ exaComposite(CARD8 op,
33d29f3f 469 void
055b6688
AM
470 exaCompositeRects(CARD8 op,
471 PicturePtr Src,
472+ PicturePtr pMask,
473 PicturePtr pDst,
474 int nrect,
475 ExaCompositeRectPtr rects);
453260b6 476diff --git a/exa/exa_render.c b/exa/exa_render.c
055b6688 477index bdc1ed1..d53f13b 100644
453260b6
AM
478--- a/exa/exa_render.c
479+++ b/exa/exa_render.c
055b6688 480@@ -334,15 +334,16 @@ exaTryDriverSolidFill(PicturePtr pSrc,
453260b6 481 static int
055b6688
AM
482 exaTryDriverCompositeRects(CARD8 op,
483 PicturePtr pSrc,
484+ PicturePtr pMask,
485 PicturePtr pDst,
486 int nrect,
487 ExaCompositeRectPtr rects)
488 {
489 ExaScreenPriv (pDst->pDrawable->pScreen);
490- int src_off_x, src_off_y, dst_off_x, dst_off_y;
491- PixmapPtr pSrcPix, pDstPix;
492- ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
493- ExaMigrationRec pixmaps[2];
494+ int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
495+ PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
496+ ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
497+ ExaMigrationRec pixmaps[3];
498
499 if (!pExaScr->info->PrepareComposite)
500 return -1;
501@@ -350,6 +351,11 @@ exaTryDriverCompositeRects(CARD8 op,
502 pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
503 pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
504
505+ if (pMask) {
506+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
507+ pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
33d29f3f 508+ }
453260b6 509+
055b6688
AM
510 pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
511 pDstExaPix = ExaGetPixmapPriv(pDstPix);
453260b6 512
055b6688
AM
513@@ -357,20 +363,18 @@ exaTryDriverCompositeRects(CARD8 op,
514 * FIXME: If it cannot, use temporary pixmaps so that the drawing
515 * happens within limits.
516 */
517- if (pSrcExaPix->accel_blocked ||
518- pDstExaPix->accel_blocked)
519+ if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked ||
520+ (pMask && pMaskExaPix->accel_blocked))
521 {
522 return -1;
453260b6 523 }
055b6688
AM
524
525 if (pExaScr->info->CheckComposite &&
526- !(*pExaScr->info->CheckComposite) (op, pSrc, NULL, pDst))
527+ !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
33d29f3f 528 {
055b6688
AM
529 return -1;
530 }
531
532- exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
33d29f3f 533-
055b6688
AM
534 pixmaps[0].as_dst = TRUE;
535 pixmaps[0].as_src = exaOpReadsDestination(op);
536 pixmaps[0].pPix = pDstPix;
537@@ -379,32 +383,49 @@ exaTryDriverCompositeRects(CARD8 op,
538 pixmaps[1].as_src = TRUE;
539 pixmaps[1].pPix = pSrcPix;
540 pixmaps[1].pReg = NULL;
541- exaDoMigration(pixmaps, 2, TRUE);
542+ if (pMask) {
543+ pixmaps[2].as_dst = FALSE;
544+ pixmaps[2].as_src = TRUE;
545+ pixmaps[2].pPix = pMaskPix;
546+ pixmaps[2].pReg = NULL;
547+ exaDoMigration(pixmaps, 3, TRUE);
548+ } else
549+ exaDoMigration(pixmaps, 2, TRUE);
550
551- pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
552- if (!exaPixmapIsOffscreen(pDstPix))
553+ pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
554+ if (!pDstPix)
555 return 0;
556
557+ pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
558 if (!pSrcPix)
559 return 0;
453260b6 560
055b6688
AM
561- if (!(*pExaScr->info->PrepareComposite) (op, pSrc, NULL, pDst, pSrcPix,
562- NULL, pDstPix))
563+ if (pMask) {
564+ pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, &mask_off_y);
33d29f3f 565+
055b6688
AM
566+ if (!pMaskPix)
567+ return 0;
568+ }
453260b6 569+
055b6688
AM
570+ if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
571+ pMaskPix, pDstPix))
572 return -1;
33d29f3f 573
055b6688
AM
574 while (nrect--)
575 {
576 INT16 xDst = rects->xDst + pDst->pDrawable->x;
577 INT16 yDst = rects->yDst + pDst->pDrawable->y;
578+ INT16 xMask = pMask ? rects->xMask + pMask->pDrawable->x : 0;
579+ INT16 yMask = pMask ? rects->yMask + pMask->pDrawable->y : 0;
580 INT16 xSrc = rects->xSrc + pSrc->pDrawable->x;
581 INT16 ySrc = rects->ySrc + pSrc->pDrawable->y;
582
583 RegionRec region;
584 BoxPtr pbox;
585 int nbox;
33d29f3f 586-
055b6688
AM
587- if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
588- xSrc, ySrc, 0, 0, xDst, yDst,
589+
590+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
591+ xSrc, ySrc, xMask, yMask, xDst, yDst,
592 rects->width, rects->height))
593 goto next_rect;
594
595@@ -413,6 +434,8 @@ exaTryDriverCompositeRects(CARD8 op,
596 nbox = REGION_NUM_RECTS(&region);
597 pbox = REGION_RECTS(&region);
598
599+ xMask = xMask + mask_off_x - xDst - dst_off_x;
600+ yMask = yMask + mask_off_y - yDst - dst_off_y;
601 xSrc = xSrc + src_off_x - xDst - dst_off_x;
602 ySrc = ySrc + src_off_y - yDst - dst_off_y;
603
604@@ -421,7 +444,8 @@ exaTryDriverCompositeRects(CARD8 op,
605 (*pExaScr->info->Composite) (pDstPix,
606 pbox->x1 + xSrc,
607 pbox->y1 + ySrc,
608- 0, 0,
609+ pbox->x1 + xMask,
610+ pbox->y1 + yMask,
611 pbox->x1,
612 pbox->y1,
613 pbox->x2 - pbox->x1,
614@@ -443,25 +467,30 @@ exaTryDriverCompositeRects(CARD8 op,
615
33d29f3f 616 /**
055b6688
AM
617 * Copy a number of rectangles from source to destination in a single
618- * operation. This is specialized for building a glyph mask: we don'y
619- * have a mask argument because we don't need it for that, and we
620- * don't have he special-case fallbacks found in exaComposite() - if the
621- * driver can support it, we use the driver functionality, otherwise we
622- * fallback straight to software.
623+ * operation. This is specialized for glyph rendering: we don't have the
624+ * special-case fallbacks found in exaComposite() - if the driver can support
625+ * it, we use the driver functionality, otherwise we fall back straight to
626+ * software.
627 */
628 void
629 exaCompositeRects(CARD8 op,
630 PicturePtr pSrc,
631+ PicturePtr pMask,
632 PicturePtr pDst,
633 int nrect,
634 ExaCompositeRectPtr rects)
33d29f3f 635 {
055b6688
AM
636+ ExaScreenPriv (pDst->pDrawable->pScreen);
637 PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable);
638 ExaPixmapPriv(pPixmap);
639 int n;
640 ExaCompositeRectPtr r;
641-
642- if (pExaPixmap->pDamage) {
643+ int ret;
644+
645+ /* If we get a mask, that means we're rendering to the exaGlyphs
646+ * destination directly, so the damage layer takes care of this.
647+ */
648+ if (!pMask && pExaPixmap->pDamage) {
649 RegionRec region;
650 int x1 = MAXSHORT;
651 int y1 = MAXSHORT;
652@@ -518,24 +547,44 @@ exaCompositeRects(CARD8 op,
653 /************************************************************/
33d29f3f 654
055b6688
AM
655 ValidatePicture (pSrc);
656+ if (pMask)
657+ ValidatePicture (pMask);
658 ValidatePicture (pDst);
659-
660- if (exaTryDriverCompositeRects(op, pSrc, pDst, nrect, rects) != 1) {
661- n = nrect;
662- r = rects;
663- while (n--) {
664- ExaCheckComposite (op, pSrc, NULL, pDst,
665- r->xSrc, r->ySrc,
666- 0, 0,
667- r->xDst, r->yDst,
668- r->width, r->height);
669- r++;
670+
671+ ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects);
672+
673+ if (ret != 1) {
674+ if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha &&
675+ (!pExaScr->info->CheckComposite ||
676+ ((*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
677+ pDst) &&
678+ (*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))) {
679+ ret = exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask,
680+ pDst, nrect, rects);
681+ if (ret == 1) {
682+ op = PictOpAdd;
683+ ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect,
684+ rects);
685+ }
686+ }
687+
688+ if (ret != 1) {
689+ n = nrect;
690+ r = rects;
691+ while (n--) {
692+ ExaCheckComposite (op, pSrc, pMask, pDst,
693+ r->xSrc, r->ySrc,
694+ r->xMask, r->yMask,
695+ r->xDst, r->yDst,
696+ r->width, r->height);
697+ r++;
698+ }
699 }
33d29f3f 700 }
453260b6 701
055b6688
AM
702 /************************************************************/
703
704- if (pExaPixmap->pDamage) {
705+ if (!pMask && pExaPixmap->pDamage) {
706 /* Now we have to flush the damage out from pendingDamage => damage
707 * Calling DamageRegionProcessPending has that effect.
708 */
709commit 265d20068af5434489752b6dba0bf0065b3cc3ec
710Author: Michel Dänzer <daenzer@vmware.com>
711Date: Fri Feb 27 16:41:39 2009 +0100
1de84ad0 712
055b6688
AM
713 EXA: Fix check for whether the glyph we're evicting from the cache is in use.
714
715 Since commit f07f18231a921d3ae9dd9b75881c9e58e9e2e235 ('EXA: Allow using
716 exaCompositeRects also when we can't use a mask in exaGlyphs.') we were
717 checking the wrong set of coordinates in the buffer where glyphs to be rendered
718 are accumulated when no mask is used in exaGlyphs.
719
720 This fixes occasional glyph corruption which can be corrected with redraws, in
721 particular with Qt4.
1de84ad0 722
055b6688
AM
723 Thanks to Maarten Maathuis for asking the right question: 'where do we protect
724 against evicting glyphs that are still needed?'
1de84ad0 725
055b6688 726 Signed-off-by: Michel Dänzer <daenzer@vmware.com>
1de84ad0 727
055b6688
AM
728diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
729index 918fd85..d55839c 100644
730--- a/exa/exa_glyphs.c
731+++ b/exa/exa_glyphs.c
732@@ -469,7 +469,9 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
733 y = CACHE_Y(pos);
734
735 for (i = 0; i < buffer->count; i++) {
736- if (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y) {
737+ if (pSrc ?
738+ (buffer->rects[i].xMask == x && buffer->rects[i].yMask == y) :
739+ (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y)) {
740 DBG_GLYPH_CACHE((" must flush buffer\n"));
741 return ExaGlyphNeedFlush;
742 }
This page took 0.214189 seconds and 4 git commands to generate.