]> git.pld-linux.org Git - packages/xorg-xserver-server.git/blame_incremental - xorg-xserver-server-exa.patch
- up to 1.6.1
[packages/xorg-xserver-server.git] / xorg-xserver-server-exa.patch
... / ...
CommitLineData
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
53
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>
63
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
70
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;
107
108 if (!cache->picture) {
109@@ -497,13 +503,28 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
110
111 }
112
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;
121+
122+ if (pSrc)
123+ {
124+ rect->xSrc = xSrc;
125+ rect->ySrc = ySrc;
126+ rect->xMask = CACHE_X(pos);
127+ rect->yMask = CACHE_Y(pos);
128+ }
129+ else
130+ {
131+ rect->xSrc = CACHE_X(pos);
132+ rect->ySrc = CACHE_Y(pos);
133+ rect->xMask = 0;
134+ rect->yMask = 0;
135+ }
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;
229 }
230
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)
242 {
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;
267 }
268
269 /* Cut and paste from render/glyph.c - probably should export it instead */
270@@ -673,79 +687,6 @@ GlyphExtents (int nlist,
271 }
272 }
273
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;
287-
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++;
297-
298- if (glyph->info.width == 0 || glyph->info.height == 0) {
299- x += glyph->info.xOff;
300- y += glyph->info.yOff;
301- continue;
302- }
303-
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-}
346-
347 void
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;
370-
371- maskFormat = list[0].format;
372-
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)
387 {
388 GCPtr pGC;
389@@ -840,12 +758,11 @@ exaGlyphs (CARD8 op,
390 }
391 else
392 {
393- pMask = pDst;
394 x = 0;
395 y = 0;
396 }
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);
425-
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);
437+ }
438+ }
439 }
440
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 }
450
451 if (maskFormat)
452diff --git a/exa/exa_priv.h b/exa/exa_priv.h
453index ea8c3da..8f83701 100644
454--- a/exa/exa_priv.h
455+++ b/exa/exa_priv.h
456@@ -287,8 +287,11 @@ typedef struct _ExaMigrationRec {
457 } ExaMigrationRec, *ExaMigrationPtr;
458
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,
469 void
470 exaCompositeRects(CARD8 op,
471 PicturePtr Src,
472+ PicturePtr pMask,
473 PicturePtr pDst,
474 int nrect,
475 ExaCompositeRectPtr rects);
476diff --git a/exa/exa_render.c b/exa/exa_render.c
477index bdc1ed1..d53f13b 100644
478--- a/exa/exa_render.c
479+++ b/exa/exa_render.c
480@@ -334,15 +334,16 @@ exaTryDriverSolidFill(PicturePtr pSrc,
481 static int
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);
508+ }
509+
510 pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
511 pDstExaPix = ExaGetPixmapPriv(pDstPix);
512
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;
523 }
524
525 if (pExaScr->info->CheckComposite &&
526- !(*pExaScr->info->CheckComposite) (op, pSrc, NULL, pDst))
527+ !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
528 {
529 return -1;
530 }
531
532- exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
533-
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;
560
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);
565+
566+ if (!pMaskPix)
567+ return 0;
568+ }
569+
570+ if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
571+ pMaskPix, pDstPix))
572 return -1;
573
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;
586-
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
616 /**
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)
635 {
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 /************************************************************/
654
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 }
700 }
701
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
712
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.
722
723 Thanks to Maarten Maathuis for asking the right question: 'where do we protect
724 against evicting glyphs that are still needed?'
725
726 Signed-off-by: Michel Dänzer <daenzer@vmware.com>
727
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.041238 seconds and 4 git commands to generate.