xf86-video-intel: 2 commits - src/sna/sna_accel.c src/sna/sna_glyphs.c src/sna/sna_render.h
Chris Wilson
ickle at kemper.freedesktop.org
Thu May 31 05:22:10 PDT 2012
src/sna/sna_accel.c | 10 +---
src/sna/sna_glyphs.c | 109 ++++++++++++++++++++++++++++++++++++---------------
src/sna/sna_render.h | 2
3 files changed, 84 insertions(+), 37 deletions(-)
New commits:
commit 660c89e9742bac5ce7cbd480e08b4667e37dee8c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu May 31 13:18:21 2012 +0100
sna: Use full 16-bit unsigned values for absolute differences
Beware the overflow implicit in:
adx = x2 >= x1 ? x2 - x1 : x1 - x2;
when both x2 and x1 may be large signed 16-bit values
Reported-by: Zdenek Kabelac <zdenek.kabelac at gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50532
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ee2f69a..cebfc7e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5881,9 +5881,8 @@ sna_poly_zero_line_blt(DrawablePtr drawable,
while (--n) {
int16_t sdx, sdy;
- int16_t adx, ady;
- int16_t e, e1, e2, e3;
- int16_t length;
+ uint16_t adx, ady, length;
+ int e, e1, e2, e3;
int x1 = x2, x;
int y1 = y2, y;
int oc1 = oc2;
@@ -7080,9 +7079,8 @@ sna_poly_zero_segment_blt(DrawablePtr drawable,
const xSegment *s = _s;
do {
int16_t sdx, sdy;
- int16_t adx, ady;
- int16_t e, e1, e2, e3;
- int16_t length;
+ uint16_t adx, ady, length;
+ int e, e1, e2, e3;
int x1, x2;
int y1, y2;
int oc1, oc2;
commit 035c2953751f58225bd6b1fcb4c1275ccb5526cb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu May 31 09:29:40 2012 +0100
sna/glyphs: use add(WHITE, glyph, mask) for channel expansion
If the glyph format does not match the mask format we can not simply add
the two together, but must first perform a channel expansion (or
contraction) by multiplying the glyph against a WHITE source.
Normally the glyph and the mask are equivalent formats and so we hit the
fast path.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 0a2e042..81e833e 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -130,6 +130,15 @@ static void unrealize_glyph_caches(struct sna *sna)
free(cache->glyphs);
}
memset(render->glyph, 0, sizeof(render->glyph));
+
+ if (render->white_image) {
+ pixman_image_unref(render->white_image);
+ render->white_image = NULL;
+ }
+ if (render->white_picture) {
+ FreePicture(render->white_picture, 0);
+ render->white_picture = NULL;
+ }
}
/* All caches for a single format share a single pixmap for glyph storage,
@@ -144,11 +153,13 @@ static void unrealize_glyph_caches(struct sna *sna)
static Bool realize_glyph_caches(struct sna *sna)
{
ScreenPtr screen = sna->scrn->pScreen;
+ pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
unsigned int formats[] = {
PIXMAN_a8,
PIXMAN_a8r8g8b8,
};
unsigned int i;
+ int error;
DBG(("%s\n", __FUNCTION__));
@@ -163,7 +174,6 @@ static Bool realize_glyph_caches(struct sna *sna)
PictFormatPtr pPictFormat;
CARD32 component_alpha;
int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
- int error;
pPictFormat = PictureMatchFormat(screen, depth, formats[i]);
if (!pPictFormat)
@@ -205,7 +215,10 @@ static Bool realize_glyph_caches(struct sna *sna)
cache->evict = rand() % GLYPH_CACHE_SIZE;
}
- return TRUE;
+ sna->render.white_image = pixman_image_create_solid_fill(&white);
+ sna->render.white_picture =
+ CreateSolidPicture(0, (xRenderColor *)&white, &error);
+ return sna->render.white_image && sna->render.white_picture;
bail:
unrealize_glyph_caches(sna);
@@ -412,7 +425,6 @@ glyphs_to_dst(struct sna *sna,
{
struct sna_composite_op tmp;
ScreenPtr screen = dst->pDrawable->pScreen;
- int index = screen->myNum;
PicturePtr glyph_atlas;
BoxPtr rects;
int nrect;
@@ -566,7 +578,6 @@ glyphs_slow(struct sna *sna,
{
struct sna_composite_op tmp;
ScreenPtr screen = dst->pDrawable->pScreen;
- int index = screen->myNum;
int16_t x, y;
if (NO_GLYPHS_SLOW)
@@ -705,7 +716,6 @@ glyphs_via_mask(struct sna *sna,
{
ScreenPtr screen = dst->pDrawable->pScreen;
struct sna_composite_op tmp;
- int index = screen->myNum;
CARD32 component_alpha;
PixmapPtr pixmap;
PicturePtr glyph_atlas, mask;
@@ -759,7 +769,6 @@ glyphs_via_mask(struct sna *sna,
((uint32_t)width * height * format->depth < 8 * 4096 ||
too_large(sna, width, height))) {
pixman_image_t *mask_image;
- int s;
DBG(("%s: small mask [format=%lx, depth=%d, size=%d], rendering glyphs to upload buffer\n",
__FUNCTION__, (unsigned long)format->format,
@@ -784,7 +793,6 @@ upload:
}
memset(pixmap->devPrivate.ptr, 0, pixmap->devKind*height);
- s = dst->pDrawable->pScreen->myNum;
do {
int n = list->len;
x += list->xOff;
@@ -833,15 +841,28 @@ upload:
g->info.width,
g->info.height));
- pixman_image_composite(PictOpAdd,
- glyph_image,
- NULL,
- mask_image,
- 0, 0,
- 0, 0,
- xi, yi,
- g->info.width,
- g->info.height);
+ if (list->format == format) {
+ assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image));
+ pixman_image_composite(PictOpAdd,
+ glyph_image,
+ NULL,
+ mask_image,
+ 0, 0,
+ 0, 0,
+ xi, yi,
+ g->info.width,
+ g->info.height);
+ } else {
+ pixman_image_composite(PictOpAdd,
+ sna->render.white_image,
+ glyph_image,
+ mask_image,
+ 0, 0,
+ 0, 0,
+ xi, yi,
+ g->info.width,
+ g->info.height);
+ }
next_image:
x += g->info.xOff;
@@ -914,14 +935,25 @@ next_image:
}
if (this_atlas != glyph_atlas) {
+ bool ok;
+
if (glyph_atlas)
tmp.done(sna, &tmp);
- if (!sna->render.composite(sna, PictOpAdd,
- this_atlas, NULL, mask,
- 0, 0, 0, 0, 0, 0,
- width, height,
- &tmp)) {
+ if (this_atlas->format == format->format) {
+ ok = sna->render.composite(sna, PictOpAdd,
+ this_atlas, NULL, mask,
+ 0, 0, 0, 0, 0, 0,
+ width, height,
+ &tmp);
+ } else {
+ ok = sna->render.composite(sna, PictOpAdd,
+ sna->render.white_picture, this_atlas, mask,
+ 0, 0, 0, 0, 0, 0,
+ width, height,
+ &tmp);
+ }
+ if (!ok) {
FreePicture(mask, 0);
return FALSE;
}
@@ -1046,6 +1078,7 @@ glyphs_fallback(CARD8 op,
GlyphListPtr list,
GlyphPtr *glyphs)
{
+ struct sna *sna = to_sna_from_drawable(dst->pDrawable);
pixman_image_t *dst_image, *mask_image, *src_image;
int dx, dy, x, y;
BoxRec box;
@@ -1178,16 +1211,30 @@ glyphs_fallback(CARD8 op,
g->info.width,
g->info.height));
- pixman_image_composite(PictOpAdd,
- glyph_image,
- NULL,
- mask_image,
- dx, dy,
- 0, 0,
- x - g->info.x,
- y - g->info.y,
- g->info.width,
- g->info.height);
+ if (list->format == mask_format) {
+ assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image));
+ pixman_image_composite(PictOpAdd,
+ glyph_image,
+ NULL,
+ mask_image,
+ dx, dy,
+ 0, 0,
+ x - g->info.x,
+ y - g->info.y,
+ g->info.width,
+ g->info.height);
+ } else {
+ pixman_image_composite(PictOpAdd,
+ sna->render.white_image,
+ glyph_image,
+ mask_image,
+ dx, dy,
+ 0, 0,
+ x - g->info.x,
+ y - g->info.y,
+ g->info.width,
+ g->info.height);
+ }
} else {
int xi = x - g->info.x;
int yi = y - g->info.y;
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 8764796..b9360c3 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -274,6 +274,8 @@ struct sna_render {
uint16_t count;
uint16_t evict;
} glyph[2];
+ pixman_image_t *white_image;
+ PicturePtr white_picture;
uint16_t vertex_start;
uint16_t vertex_index;
More information about the xorg-commit
mailing list