xf86-video-intel: add patches from upstream to fix UXA corruption with cairo-1.12.

This commit is contained in:
Juan RP 2012-04-20 16:15:56 +02:00
parent ede03a8486
commit 02363bf5a2
6 changed files with 1266 additions and 1 deletions

View File

@ -0,0 +1,532 @@
From fbee314a4194671bfc6dfaa90141498a2f45de4e Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Mon, 27 Feb 2012 16:29:38 +0000
Subject: [PATCH 1/5] uxa/gen3: Remove special casing of solid pictures
Fixes use of alpha-groups and opacity masks in cairo.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
src/i915_render.c | 366 ++++++++++++++++++-----------------------------------
1 file changed, 122 insertions(+), 244 deletions(-)
diff --git a/src/i915_render.c b/src/i915_render.c
index 87d2336..6210035 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -257,11 +257,8 @@ i915_check_composite_texture(ScreenPtr screen, PicturePtr picture)
return FALSE;
}
- if (picture->pSourcePict) {
- SourcePict *source = picture->pSourcePict;
- if (source->type == SourcePictTypeSolidFill)
- return TRUE;
- }
+ if (picture->pSourcePict)
+ return FALSE;
if (picture->pDrawable) {
int w, h, i;
@@ -387,23 +384,6 @@ static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
}
static void
-i915_emit_composite_primitive_constant(intel_screen_private *intel,
- int srcX, int srcY,
- int maskX, int maskY,
- int dstX, int dstY,
- int w, int h)
-{
- OUT_VERTEX(dstX + w);
- OUT_VERTEX(dstY + h);
-
- OUT_VERTEX(dstX);
- OUT_VERTEX(dstY + h);
-
- OUT_VERTEX(dstX);
- OUT_VERTEX(dstY);
-}
-
-static void
i915_emit_composite_primitive_identity_source(intel_screen_private *intel,
int srcX, int srcY,
int maskX, int maskY,
@@ -470,29 +450,6 @@ i915_emit_composite_primitive_affine_source(intel_screen_private *intel,
}
static void
-i915_emit_composite_primitive_constant_identity_mask(intel_screen_private *intel,
- int srcX, int srcY,
- int maskX, int maskY,
- int dstX, int dstY,
- int w, int h)
-{
- OUT_VERTEX(dstX + w);
- OUT_VERTEX(dstY + h);
- OUT_VERTEX((maskX + w) * intel->scale_units[0][0]);
- OUT_VERTEX((maskY + h) * intel->scale_units[0][1]);
-
- OUT_VERTEX(dstX);
- OUT_VERTEX(dstY + h);
- OUT_VERTEX(maskX * intel->scale_units[0][0]);
- OUT_VERTEX((maskY + h) * intel->scale_units[0][1]);
-
- OUT_VERTEX(dstX);
- OUT_VERTEX(dstY);
- OUT_VERTEX(maskX * intel->scale_units[0][0]);
- OUT_VERTEX(maskY * intel->scale_units[0][1]);
-}
-
-static void
i915_emit_composite_primitive_identity_source_mask(intel_screen_private *intel,
int srcX, int srcY,
int maskX, int maskY,
@@ -536,63 +493,61 @@ i915_emit_composite_primitive(intel_screen_private *intel,
per_vertex = 2; /* dest x/y */
- if (! intel->render_source_is_solid) {
- src_unit = tex_unit++;
-
- is_affine_src = intel_transform_is_affine(intel->transform[src_unit]);
- if (is_affine_src) {
- if (!intel_get_transformed_coordinates(srcX, srcY,
- intel->
- transform[src_unit],
- &src_x[0],
- &src_y[0]))
- return;
-
- if (!intel_get_transformed_coordinates(srcX, srcY + h,
- intel->
- transform[src_unit],
- &src_x[1],
- &src_y[1]))
- return;
-
- if (!intel_get_transformed_coordinates(srcX + w, srcY + h,
- intel->
- transform[src_unit],
- &src_x[2],
- &src_y[2]))
- return;
-
- per_vertex += 2; /* src x/y */
- } else {
- if (!intel_get_transformed_coordinates_3d(srcX, srcY,
- intel->
- transform[src_unit],
- &src_x[0],
- &src_y[0],
- &src_w[0]))
- return;
-
- if (!intel_get_transformed_coordinates_3d(srcX, srcY + h,
- intel->
- transform[src_unit],
- &src_x[1],
- &src_y[1],
- &src_w[1]))
- return;
-
- if (!intel_get_transformed_coordinates_3d(srcX + w, srcY + h,
- intel->
- transform[src_unit],
- &src_x[2],
- &src_y[2],
- &src_w[2]))
- return;
-
- per_vertex += 4; /* src x/y/z/w */
- }
+ src_unit = tex_unit++;
+
+ is_affine_src = intel_transform_is_affine(intel->transform[src_unit]);
+ if (is_affine_src) {
+ if (!intel_get_transformed_coordinates(srcX, srcY,
+ intel->
+ transform[src_unit],
+ &src_x[0],
+ &src_y[0]))
+ return;
+
+ if (!intel_get_transformed_coordinates(srcX, srcY + h,
+ intel->
+ transform[src_unit],
+ &src_x[1],
+ &src_y[1]))
+ return;
+
+ if (!intel_get_transformed_coordinates(srcX + w, srcY + h,
+ intel->
+ transform[src_unit],
+ &src_x[2],
+ &src_y[2]))
+ return;
+
+ per_vertex += 2; /* src x/y */
+ } else {
+ if (!intel_get_transformed_coordinates_3d(srcX, srcY,
+ intel->
+ transform[src_unit],
+ &src_x[0],
+ &src_y[0],
+ &src_w[0]))
+ return;
+
+ if (!intel_get_transformed_coordinates_3d(srcX, srcY + h,
+ intel->
+ transform[src_unit],
+ &src_x[1],
+ &src_y[1],
+ &src_w[1]))
+ return;
+
+ if (!intel_get_transformed_coordinates_3d(srcX + w, srcY + h,
+ intel->
+ transform[src_unit],
+ &src_x[2],
+ &src_y[2],
+ &src_w[2]))
+ return;
+
+ per_vertex += 4; /* src x/y/z/w */
}
- if (intel->render_mask && ! intel->render_mask_is_solid) {
+ if (intel->render_mask) {
mask_unit = tex_unit++;
is_affine_mask = intel_transform_is_affine(intel->transform[mask_unit]);
@@ -650,15 +605,13 @@ i915_emit_composite_primitive(intel_screen_private *intel,
OUT_VERTEX(dstX + w);
OUT_VERTEX(dstY + h);
- if (! intel->render_source_is_solid) {
- OUT_VERTEX(src_x[2] * intel->scale_units[src_unit][0]);
- OUT_VERTEX(src_y[2] * intel->scale_units[src_unit][1]);
- if (!is_affine_src) {
+ OUT_VERTEX(src_x[2] * intel->scale_units[src_unit][0]);
+ OUT_VERTEX(src_y[2] * intel->scale_units[src_unit][1]);
+ if (!is_affine_src) {
OUT_VERTEX(0.0);
OUT_VERTEX(src_w[2]);
- }
}
- if (intel->render_mask && ! intel->render_mask_is_solid) {
+ if (intel->render_mask) {
OUT_VERTEX(mask_x[2] * intel->scale_units[mask_unit][0]);
OUT_VERTEX(mask_y[2] * intel->scale_units[mask_unit][1]);
if (!is_affine_mask) {
@@ -669,15 +622,13 @@ i915_emit_composite_primitive(intel_screen_private *intel,
OUT_VERTEX(dstX);
OUT_VERTEX(dstY + h);
- if (! intel->render_source_is_solid) {
- OUT_VERTEX(src_x[1] * intel->scale_units[src_unit][0]);
- OUT_VERTEX(src_y[1] * intel->scale_units[src_unit][1]);
- if (!is_affine_src) {
+ OUT_VERTEX(src_x[1] * intel->scale_units[src_unit][0]);
+ OUT_VERTEX(src_y[1] * intel->scale_units[src_unit][1]);
+ if (!is_affine_src) {
OUT_VERTEX(0.0);
OUT_VERTEX(src_w[1]);
- }
}
- if (intel->render_mask && ! intel->render_mask_is_solid) {
+ if (intel->render_mask) {
OUT_VERTEX(mask_x[1] * intel->scale_units[mask_unit][0]);
OUT_VERTEX(mask_y[1] * intel->scale_units[mask_unit][1]);
if (!is_affine_mask) {
@@ -688,15 +639,13 @@ i915_emit_composite_primitive(intel_screen_private *intel,
OUT_VERTEX(dstX);
OUT_VERTEX(dstY);
- if (! intel->render_source_is_solid) {
- OUT_VERTEX(src_x[0] * intel->scale_units[src_unit][0]);
- OUT_VERTEX(src_y[0] * intel->scale_units[src_unit][1]);
- if (!is_affine_src) {
+ OUT_VERTEX(src_x[0] * intel->scale_units[src_unit][0]);
+ OUT_VERTEX(src_y[0] * intel->scale_units[src_unit][1]);
+ if (!is_affine_src) {
OUT_VERTEX(0.0);
OUT_VERTEX(src_w[0]);
- }
}
- if (intel->render_mask && ! intel->render_mask_is_solid) {
+ if (intel->render_mask) {
OUT_VERTEX(mask_x[0] * intel->scale_units[mask_unit][0]);
OUT_VERTEX(mask_y[0] * intel->scale_units[mask_unit][1]);
if (!is_affine_mask) {
@@ -729,29 +678,11 @@ i915_prepare_composite(int op, PicturePtr source_picture,
intel->render_dest_picture = dest_picture;
intel->render_dest = dest;
- intel->render_source_is_solid = FALSE;
- if (source_picture->pSourcePict) {
- SourcePict *source = source_picture->pSourcePict;
- if (source->type == SourcePictTypeSolidFill) {
- intel->render_source_is_solid = TRUE;
- intel->render_source_solid = source->solidFill.color;
- }
- }
- if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
+ if (!intel_check_pitch_3d(source))
return FALSE;
- intel->render_mask_is_solid = FALSE;
- if (mask) {
- if (mask_picture->pSourcePict) {
- SourcePict *source = mask_picture->pSourcePict;
- if (source->type == SourcePictTypeSolidFill) {
- intel->render_mask_is_solid = TRUE;
- intel->render_mask_solid = source->solidFill.color;
- }
- }
- if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
- return FALSE;
- }
+ if (mask && !intel_check_pitch_3d(mask))
+ return FALSE;
if (!intel_check_pitch_3d(dest))
return FALSE;
@@ -787,31 +718,27 @@ i915_prepare_composite(int op, PicturePtr source_picture,
intel->scale_units[1][1] = -1;
floats_per_vertex = 2; /* dest x/y */
- if (! intel->render_source_is_solid) {
- if (!i915_texture_setup(source_picture, source, tex_unit++)) {
- intel_debug_fallback(scrn, "fail to setup src texture\n");
- return FALSE;
- }
-
- if (intel_transform_is_affine(source_picture->transform))
- floats_per_vertex += 2; /* src x/y */
- else
- floats_per_vertex += 4; /* src x/y/z/w */
+ if (!i915_texture_setup(source_picture, source, tex_unit++)) {
+ intel_debug_fallback(scrn, "fail to setup src texture\n");
+ return FALSE;
}
- if (mask != NULL) {
- if (! intel->render_mask_is_solid) {
- if (!i915_texture_setup(mask_picture, mask, tex_unit++)) {
- intel_debug_fallback(scrn,
- "fail to setup mask texture\n");
- return FALSE;
- }
+ if (intel_transform_is_affine(source_picture->transform))
+ floats_per_vertex += 2; /* src x/y */
+ else
+ floats_per_vertex += 4; /* src x/y/z/w */
- if (intel_transform_is_affine(mask_picture->transform))
- floats_per_vertex += 2; /* mask x/y */
- else
- floats_per_vertex += 4; /* mask x/y/z/w */
+ if (mask != NULL) {
+ if (!i915_texture_setup(mask_picture, mask, tex_unit++)) {
+ intel_debug_fallback(scrn,
+ "fail to setup mask texture\n");
+ return FALSE;
}
+
+ if (intel_transform_is_affine(mask_picture->transform))
+ floats_per_vertex += 2; /* mask x/y */
+ else
+ floats_per_vertex += 4; /* mask x/y/z/w */
}
intel->i915_render_state.op = op;
@@ -827,17 +754,13 @@ i915_prepare_composite(int op, PicturePtr source_picture,
intel->prim_emit = i915_emit_composite_primitive;
if (!mask) {
- if (intel->render_source_is_solid)
- intel->prim_emit = i915_emit_composite_primitive_constant;
- else if (intel->transform[0] == NULL)
+ if (intel->transform[0] == NULL)
intel->prim_emit = i915_emit_composite_primitive_identity_source;
else if (intel_transform_is_affine(intel->transform[0]))
intel->prim_emit = i915_emit_composite_primitive_affine_source;
} else {
if (intel->transform[0] == NULL) {
- if (intel->render_source_is_solid)
- intel->prim_emit = i915_emit_composite_primitive_constant_identity_mask;
- else if (intel->transform[1] == NULL)
+ if (intel->transform[1] == NULL)
intel->prim_emit = i915_emit_composite_primitive_identity_source_mask;
}
}
@@ -856,39 +779,25 @@ i915_composite_emit_shader(intel_screen_private *intel, CARD8 op)
PicturePtr mask_picture = intel->render_mask_picture;
PixmapPtr mask = intel->render_mask;
int src_reg, mask_reg;
- Bool is_solid_src, is_solid_mask;
Bool dest_is_alpha = PIXMAN_FORMAT_RGB(intel->render_dest_picture->format) == 0;
- int tex_unit, t;
FS_LOCALS();
- is_solid_src = intel->render_source_is_solid;
- is_solid_mask = intel->render_mask_is_solid;
-
FS_BEGIN();
/* Declare the registers necessary for our program. */
- t = 0;
- if (is_solid_src) {
- i915_fs_dcl(FS_T8);
- src_reg = FS_T8;
- } else {
- i915_fs_dcl(FS_T0);
- i915_fs_dcl(FS_S0);
- t++;
- }
+ i915_fs_dcl(FS_T0);
+ i915_fs_dcl(FS_S0);
if (!mask) {
/* No mask, so load directly to output color */
- if (! is_solid_src) {
- if (dest_is_alpha)
- src_reg = FS_R0;
- else
- src_reg = FS_OC;
+ if (dest_is_alpha)
+ src_reg = FS_R0;
+ else
+ src_reg = FS_OC;
- if (intel_transform_is_affine(intel->transform[0]))
- i915_fs_texld(src_reg, FS_S0, FS_T0);
- else
- i915_fs_texldp(src_reg, FS_S0, FS_T0);
- }
+ if (intel_transform_is_affine(intel->transform[0]))
+ i915_fs_texld(src_reg, FS_S0, FS_T0);
+ else
+ i915_fs_texldp(src_reg, FS_S0, FS_T0);
if (src_reg != FS_OC) {
if (dest_is_alpha)
@@ -897,35 +806,24 @@ i915_composite_emit_shader(intel_screen_private *intel, CARD8 op)
i915_fs_mov(FS_OC, i915_fs_operand_reg(src_reg));
}
} else {
- if (is_solid_mask) {
- i915_fs_dcl(FS_T9);
- mask_reg = FS_T9;
- } else {
- i915_fs_dcl(FS_T0 + t);
- i915_fs_dcl(FS_S0 + t);
- }
+ i915_fs_dcl(FS_T1);
+ i915_fs_dcl(FS_S1);
- tex_unit = 0;
- if (! is_solid_src) {
- /* Load the source_picture texel */
- if (intel_transform_is_affine(intel->transform[tex_unit]))
- i915_fs_texld(FS_R0, FS_S0, FS_T0);
- else
- i915_fs_texldp(FS_R0, FS_S0, FS_T0);
+ /* Load the source_picture texel */
+ if (intel_transform_is_affine(intel->transform[0]))
+ i915_fs_texld(FS_R0, FS_S0, FS_T0);
+ else
+ i915_fs_texldp(FS_R0, FS_S0, FS_T0);
- src_reg = FS_R0;
- tex_unit++;
- }
+ src_reg = FS_R0;
- if (! is_solid_mask) {
- /* Load the mask_picture texel */
- if (intel_transform_is_affine(intel->transform[tex_unit]))
- i915_fs_texld(FS_R1, FS_S0 + t, FS_T0 + t);
- else
- i915_fs_texldp(FS_R1, FS_S0 + t, FS_T0 + t);
+ /* Load the mask_picture texel */
+ if (intel_transform_is_affine(intel->transform[1]))
+ i915_fs_texld(FS_R1, FS_S1, FS_T1);
+ else
+ i915_fs_texldp(FS_R1, FS_S1, FS_T1);
- mask_reg = FS_R1;
- }
+ mask_reg = FS_R1;
if (dest_is_alpha) {
i915_fs_mul(FS_OC,
@@ -972,7 +870,6 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
PicturePtr dest_picture = intel->render_dest_picture;
PixmapPtr mask = intel->render_mask;
PixmapPtr dest = intel->render_dest;
- Bool is_solid_src, is_solid_mask;
int tex_count, t;
intel->needs_render_state_emit = FALSE;
@@ -980,12 +877,7 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
IntelEmitInvarientState(scrn);
intel->last_3d = LAST_3D_RENDER;
- is_solid_src = intel->render_source_is_solid;
- is_solid_mask = intel->render_mask_is_solid;
-
- tex_count = 0;
- tex_count += ! is_solid_src;
- tex_count += mask && ! is_solid_mask;
+ tex_count = 1 + (mask != NULL);
assert(intel->in_batch_atomic);
@@ -1007,15 +899,6 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
}
}
- if (is_solid_src) {
- OUT_BATCH (_3DSTATE_DFLT_DIFFUSE_CMD);
- OUT_BATCH (intel->render_source_solid);
- }
- if (mask && is_solid_mask) {
- OUT_BATCH (_3DSTATE_DFLT_SPEC_CMD);
- OUT_BATCH (intel->render_mask_solid);
- }
-
/* BUF_INFO is an implicit flush, so avoid if the target has not changed.
* XXX However for reasons unfathomed, correct rendering in KDE requires
* at least a MI_FLUSH | INHIBIT_RENDER_CACHE_FLUSH here.
@@ -1058,20 +941,15 @@ static void i915_emit_composite_setup(ScrnInfoPtr scrn)
uint32_t ss2;
ss2 = ~0;
- t = 0;
- if (! is_solid_src) {
- ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT);
- ss2 |= S2_TEXCOORD_FMT(t,
- intel_transform_is_affine(intel->transform[t]) ?
- TEXCOORDFMT_2D : TEXCOORDFMT_4D);
- t++;
- }
- if (mask && ! is_solid_mask) {
- ss2 &= ~S2_TEXCOORD_FMT(t, TEXCOORDFMT_NOT_PRESENT);
- ss2 |= S2_TEXCOORD_FMT(t,
- intel_transform_is_affine(intel->transform[t]) ?
+ ss2 &= ~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(0,
+ intel_transform_is_affine(intel->transform[0]) ?
+ TEXCOORDFMT_2D : TEXCOORDFMT_4D);
+ if (mask) {
+ ss2 &= ~S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT);
+ ss2 |= S2_TEXCOORD_FMT(1,
+ intel_transform_is_affine(intel->transform[1]) ?
TEXCOORDFMT_2D : TEXCOORDFMT_4D);
- t++;
}
if (intel->needs_render_ca_pass) {
--
1.7.10

View File

@ -0,0 +1,49 @@
From fd25a4586b0667b1591d85b23daaa99464e9b0d8 Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Mon, 19 Mar 2012 15:51:43 +0000
Subject: [PATCH 2/5] uxa: Defer the call to EnterVT till after outputs are
initialised
We need to do this apparently or else we never perform the VT switch.
However, we can not do it too early, especially not before we have
finished intialising the outputs.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=47395
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
src/intel_driver.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/src/intel_driver.c b/src/intel_driver.c
index e2e43fa..ff29754 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -1013,13 +1013,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr screen, int argc, char **argv)
"Hardware cursor initialization failed\n");
}
- /* Must force it before EnterVT, so we are in control of VT and
- * later memory should be bound when allocating, e.g rotate_mem */
- scrn->vtSema = TRUE;
-
- if (!I830EnterVT(scrnIndex, 0))
- return FALSE;
-
intel->BlockHandler = screen->BlockHandler;
screen->BlockHandler = I830BlockHandler;
@@ -1092,7 +1085,11 @@ I830ScreenInit(int scrnIndex, ScreenPtr screen, int argc, char **argv)
I830UeventInit(scrn);
#endif
- return TRUE;
+ /* Must force it before EnterVT, so we are in control of VT and
+ * later memory should be bound when allocating, e.g rotate_mem */
+ scrn->vtSema = TRUE;
+
+ return I830EnterVT(scrnIndex, 0);
}
static void i830AdjustFrame(int scrnIndex, int x, int y, int flags)
--
1.7.10

View File

@ -0,0 +1,254 @@
From b669f171adece9df7f0c340c664b70e94118a55e Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri, 23 Mar 2012 14:56:06 +0000
Subject: [PATCH 3/5] uxa: Remove hook for CompositeRectangles
It was broken and not flushing damage correctly. With the
improvements made to the kernel, it is no longer a significant advantage
per se and not worth its additional complexity.
Reported-by: Tilman Sauerbeck <tilman@code-monkey.de>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32547
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
uxa/uxa-priv.h | 1 -
uxa/uxa-render.c | 189 ------------------------------------------------------
uxa/uxa.c | 4 --
3 files changed, 194 deletions(-)
diff --git a/uxa/uxa-priv.h b/uxa/uxa-priv.h
index 0de45f5..b24ec4f 100644
--- a/uxa/uxa-priv.h
+++ b/uxa/uxa-priv.h
@@ -123,7 +123,6 @@ typedef struct {
BitmapToRegionProcPtr SavedBitmapToRegion;
#ifdef RENDER
CompositeProcPtr SavedComposite;
- CompositeRectsProcPtr SavedCompositeRects;
TrianglesProcPtr SavedTriangles;
GlyphsProcPtr SavedGlyphs;
TrapezoidsProcPtr SavedTrapezoids;
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index 877b286..1e88c5d 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -947,195 +947,6 @@ uxa_acquire_mask(ScreenPtr screen,
out_x, out_y);
}
-static Bool
-_pixman_region_init_rectangles(pixman_region16_t *region,
- int num_rects,
- xRectangle *rects,
- int tx, int ty)
-{
- pixman_box16_t stack_boxes[64], *boxes = stack_boxes;
- pixman_bool_t ret;
- int i;
-
- if (num_rects > sizeof(stack_boxes) / sizeof(stack_boxes[0])) {
- boxes = malloc(sizeof(pixman_box16_t) * num_rects);
- if (boxes == NULL)
- return FALSE;
- }
-
- for (i = 0; i < num_rects; i++) {
- boxes[i].x1 = rects[i].x + tx;
- boxes[i].y1 = rects[i].y + ty;
- boxes[i].x2 = rects[i].x + tx + rects[i].width;
- boxes[i].y2 = rects[i].y + ty + rects[i].height;
- }
-
- ret = pixman_region_init_rects(region, boxes, num_rects);
-
- if (boxes != stack_boxes)
- free(boxes);
-
- return ret;
-}
-
-void
-uxa_solid_rects (CARD8 op,
- PicturePtr dst,
- xRenderColor *color,
- int num_rects,
- xRectangle *rects)
-{
- ScreenPtr screen = dst->pDrawable->pScreen;
- uxa_screen_t *uxa_screen = uxa_get_screen(screen);
- PixmapPtr dst_pixmap, src_pixmap = NULL;
- pixman_region16_t region;
- pixman_box16_t *boxes, *extents;
- PicturePtr src;
- int dst_x, dst_y;
- int num_boxes;
-
- if (!pixman_region_not_empty(dst->pCompositeClip))
- return;
-
- if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
- int ok;
-
- uxa_picture_prepare_access(dst, UXA_GLAMOR_ACCESS_RW);
- ok = glamor_composite_rects_nf(op, dst, color,
- num_rects, rects);
- uxa_picture_finish_access(dst, UXA_GLAMOR_ACCESS_RW);
-
- if (!ok)
- goto fallback;
-
- return;
- }
-
- if (dst->alphaMap)
- goto fallback;
-
- dst_pixmap = uxa_get_offscreen_pixmap(dst->pDrawable, &dst_x, &dst_y);
- if (!dst_pixmap)
- goto fallback;
-
- if (!_pixman_region_init_rectangles(&region,
- num_rects, rects,
- dst->pDrawable->x, dst->pDrawable->y))
- goto fallback;
-
- if (!pixman_region_intersect(&region, &region, dst->pCompositeClip)) {
- pixman_region_fini(&region);
- return;
- }
-
- pixman_region_translate(&region, dst_x, dst_y);
- boxes = pixman_region_rectangles(&region, &num_boxes);
- extents = pixman_region_extents (&region);
-
- if (op == PictOpClear)
- color->red = color->green = color->blue = color->alpha = 0;
- if (color->alpha >= 0xff00 && op == PictOpOver) {
- color->alpha = 0xffff;
- op = PictOpSrc;
- }
-
- /* Using GEM, the relocation costs outweigh the advantages of the blitter */
- if (num_boxes == 1 && (op == PictOpSrc || op == PictOpClear)) {
- CARD32 pixel;
-
-try_solid:
- if (uxa_screen->info->check_solid &&
- !uxa_screen->info->check_solid(&dst_pixmap->drawable, GXcopy, FB_ALLONES))
- goto err_region;
-
- if (!uxa_get_pixel_from_rgba(&pixel,
- color->red,
- color->green,
- color->blue,
- color->alpha,
- dst->format))
- goto err_region;
-
- if (!uxa_screen->info->prepare_solid(dst_pixmap, GXcopy, FB_ALLONES, pixel))
- goto err_region;
-
- while (num_boxes--) {
- uxa_screen->info->solid(dst_pixmap,
- boxes->x1, boxes->y1,
- boxes->x2, boxes->y2);
- boxes++;
- }
-
- uxa_screen->info->done_solid(dst_pixmap);
- } else {
- int error;
-
- src = CreateSolidPicture(0, color, &error);
- if (!src)
- goto err_region;
-
- if (!uxa_screen->info->check_composite(op, src, NULL, dst,
- extents->x2 - extents->x1,
- extents->y2 - extents->y1)) {
- if (op == PictOpSrc || op == PictOpClear) {
- FreePicture(src, 0);
- goto try_solid;
- }
-
- goto err_src;
- }
-
- if (!uxa_screen->info->check_composite_texture ||
- !uxa_screen->info->check_composite_texture(screen, src)) {
- PicturePtr solid;
- int src_off_x, src_off_y;
-
- solid = uxa_acquire_solid(screen, src->pSourcePict);
- if (!solid)
- goto err_src;
- FreePicture(src, 0);
-
- src = solid;
- src_pixmap = uxa_get_offscreen_pixmap(src->pDrawable,
- &src_off_x, &src_off_y);
- if (!src_pixmap)
- goto err_src;
- }
-
- if (!uxa_screen->info->prepare_composite(op, src, NULL, dst, src_pixmap, NULL, dst_pixmap))
- goto err_src;
-
- while (num_boxes--) {
- uxa_screen->info->composite(dst_pixmap,
- 0, 0, 0, 0,
- boxes->x1,
- boxes->y1,
- boxes->x2 - boxes->x1,
- boxes->y2 - boxes->y1);
- boxes++;
- }
-
- uxa_screen->info->done_composite(dst_pixmap);
- FreePicture(src, 0);
- }
-
- /* XXX xserver-1.8: CompositeRects is not tracked by Damage, so we must
- * manually append the damaged regions ourselves.
- */
- pixman_region_translate(&region, -dst_x, -dst_y);
- DamageRegionAppend(dst->pDrawable, &region);
-
- pixman_region_fini(&region);
- return;
-
-err_src:
- FreePicture(src, 0);
-err_region:
- pixman_region_fini(&region);
-fallback:
- uxa_screen->SavedCompositeRects(op, dst, color, num_rects, rects);
-}
-
static int
uxa_try_driver_composite(CARD8 op,
PicturePtr pSrc,
diff --git a/uxa/uxa.c b/uxa/uxa.c
index eb2ae03..b4a1da6 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -407,7 +407,6 @@ static Bool uxa_close_screen(int i, ScreenPtr pScreen)
#ifdef RENDER
if (ps) {
ps->Composite = uxa_screen->SavedComposite;
- ps->CompositeRects = uxa_screen->SavedCompositeRects;
ps->Glyphs = uxa_screen->SavedGlyphs;
ps->Trapezoids = uxa_screen->SavedTrapezoids;
ps->AddTraps = uxa_screen->SavedAddTraps;
@@ -536,9 +535,6 @@ Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver)
uxa_screen->SavedComposite = ps->Composite;
ps->Composite = uxa_composite;
- uxa_screen->SavedCompositeRects = ps->CompositeRects;
- ps->CompositeRects = uxa_solid_rects;
-
uxa_screen->SavedGlyphs = ps->Glyphs;
ps->Glyphs = uxa_glyphs;
--
1.7.10

View File

@ -0,0 +1,390 @@
From 1aee0af6d8296c108b6b4eb1bcf583aae385d22d Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri, 30 Mar 2012 12:47:21 +0100
Subject: [PATCH 4/5] uxa: Remove broken render glyphs-to-dst
Reported-by: Vincent Untz <vuntz@gnome.org>
Reported-by: Robert Bradford <robert.bradford@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=48045
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
uxa/uxa-glyphs.c | 330 +++---------------------------------------------------
1 file changed, 17 insertions(+), 313 deletions(-)
diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index 6172f2f..b754f4e 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -663,190 +663,6 @@ uxa_glyph_cache(ScreenPtr screen, GlyphPtr glyph, int *out_x, int *out_y)
return cache->picture;
}
-static int
-uxa_glyphs_to_dst(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- INT16 src_x, INT16 src_y,
- INT16 xDst, INT16 yDst,
- int nlist, GlyphListPtr list, GlyphPtr * glyphs,
- BoxPtr extents)
-{
- ScreenPtr screen = pDst->pDrawable->pScreen;
- uxa_screen_t *uxa_screen = uxa_get_screen(screen);
- PixmapPtr src_pixmap, dst_pixmap;
- PicturePtr localSrc, glyph_atlas;
- int x, y, n;
- BoxRec box;
-
- if (uxa_screen->info->check_composite_texture &&
- uxa_screen->info->check_composite_texture(screen, pSrc)) {
- if (pSrc->pDrawable) {
- int src_off_x, src_off_y;
-
- src_pixmap = uxa_get_offscreen_pixmap(pSrc->pDrawable, &src_off_x, &src_off_y);
- if (src_pixmap == NULL)
- return -1;
-
- src_x += pSrc->pDrawable->x + src_off_x;
- src_y += pSrc->pDrawable->y + src_off_y;
- } else {
- src_pixmap = NULL;
- }
- localSrc = pSrc;
- } else {
- int width, height;
-
- if (extents == NULL) {
- uxa_glyph_extents(nlist, list, glyphs, &box);
- extents = &box;
- }
-
- width = extents->x2 - extents->x1;
- height = extents->y2 - extents->y1;
- if (width == 0 || height == 0)
- return 0;
-
- if (pSrc->pDrawable) {
- int src_off_x, src_off_y;
-
- src_off_x = extents->x1 - xDst;
- src_off_y = extents->y1 - yDst;
- localSrc = uxa_acquire_drawable(screen, pSrc,
- src_x + src_off_x, src_y + src_off_y,
- width, height,
- &src_x, &src_y);
- if (uxa_screen->info->check_composite_texture &&
- !uxa_screen->info->check_composite_texture(screen, localSrc)) {
- if (localSrc != pSrc)
- FreePicture(localSrc, 0);
- return -1;
- }
-
- src_pixmap = uxa_get_offscreen_pixmap(localSrc->pDrawable, &src_off_x, &src_off_y);
- if (src_pixmap == NULL) {
- if (localSrc != pSrc)
- FreePicture(localSrc, 0);
- return -1;
- }
-
- src_x += localSrc->pDrawable->x + src_off_x;
- src_y += localSrc->pDrawable->y + src_off_y;
- } else {
- localSrc = uxa_acquire_pattern(screen, pSrc,
- PICT_a8r8g8b8, x, y, width, height);
- if (!localSrc)
- return 1;
-
- src_pixmap = uxa_get_drawable_pixmap(localSrc->pDrawable);
- if (src_pixmap == NULL) {
- FreePicture(localSrc, 0);
- return -1;
- }
-
- src_x = src_y = 0;
- }
- }
-
- dst_pixmap = uxa_get_offscreen_pixmap(pDst->pDrawable, &x, &y);
- x += xDst + pDst->pDrawable->x - list->xOff;
- y += yDst + pDst->pDrawable->y - list->yOff;
-
- glyph_atlas = NULL;
- while (nlist--) {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- while (n--) {
- GlyphPtr glyph = *glyphs++;
- PicturePtr this_atlas;
- int mask_x, mask_y, nrect;
- struct uxa_glyph *priv;
- BoxPtr rects;
-
- if (glyph->info.width == 0 || glyph->info.height == 0)
- goto next_glyph;
-
- priv = uxa_glyph_get_private(glyph);
- if (priv != NULL) {
- mask_x = priv->x;
- mask_y = priv->y;
- this_atlas = priv->cache->picture;
- } else {
- if (glyph_atlas) {
- uxa_screen->info->done_composite(dst_pixmap);
- glyph_atlas = NULL;
- }
- this_atlas = uxa_glyph_cache(screen, glyph, &mask_x, &mask_y);
- if (this_atlas == NULL) {
- /* no cache for this glyph */
- this_atlas = GlyphPicture(glyph)[screen->myNum];
- mask_x = mask_y = 0;
- }
- }
-
- if (this_atlas != glyph_atlas) {
- PixmapPtr mask_pixmap;
-
- if (glyph_atlas)
- uxa_screen->info->done_composite(dst_pixmap);
-
- mask_pixmap =
- uxa_get_drawable_pixmap(this_atlas->pDrawable);
- if (!uxa_pixmap_is_offscreen(mask_pixmap) ||
- !uxa_screen->info->prepare_composite(op,
- localSrc, this_atlas, pDst,
- src_pixmap, mask_pixmap, dst_pixmap))
- return -1;
-
- glyph_atlas = this_atlas;
- }
-
- rects = REGION_RECTS(pDst->pCompositeClip);
- nrect = REGION_NUM_RECTS(pDst->pCompositeClip);
- while (nrect--) {
- int x1 = x - glyph->info.x, dx = 0;
- int y1 = y - glyph->info.y, dy = 0;
- int x2 = x1 + glyph->info.width;
- int y2 = y1 + glyph->info.height;
-
- if (rects->y1 >= y2)
- break;
-
- if (x1 < rects->x1)
- dx = rects->x1 - x1, x1 = rects->x1;
- if (x2 > rects->x2)
- x2 = rects->x2;
- if (y1 < rects->y1)
- dy = rects->y1 - y1, y1 = rects->y1;
- if (y2 > rects->y2)
- y2 = rects->y2;
-
- if (x1 < x2 && y1 < y2) {
- uxa_screen->info->composite(dst_pixmap,
- x1 + src_x, y1 + src_y,
- dx + mask_x, dy + mask_y,
- x1, y1,
- x2 - x1, y2 - y1);
- }
- rects++;
- }
-
-next_glyph:
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- list++;
- }
- if (glyph_atlas)
- uxa_screen->info->done_composite(dst_pixmap);
-
- if (localSrc != pSrc)
- FreePicture(localSrc, 0);
-
- return 0;
-}
-
static void
uxa_clear_pixmap(ScreenPtr screen,
uxa_screen_t *uxa_screen,
@@ -894,37 +710,30 @@ uxa_glyphs_via_mask(CARD8 op,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
- INT16 xDst, INT16 yDst,
- int nlist, GlyphListPtr list, GlyphPtr * glyphs,
- BoxPtr extents)
+ int nlist, GlyphListPtr list, GlyphPtr * glyphs)
{
ScreenPtr screen = pDst->pDrawable->pScreen;
uxa_screen_t *uxa_screen = uxa_get_screen(screen);
CARD32 component_alpha;
PixmapPtr pixmap;
PicturePtr glyph_atlas, mask;
+ int xDst = list->xOff, yDst = list->yOff;
int x, y, width, height;
int dst_off_x, dst_off_y;
int n, error;
BoxRec box;
- if (!extents) {
- uxa_glyph_extents(nlist, list, glyphs, &box);
+ uxa_glyph_extents(nlist, list, glyphs, &box);
+ if (box.x2 <= box.x1 || box.y2 <= box.y1)
+ return 0;
- if (box.x2 <= box.x1 || box.y2 <= box.y1)
- return 0;
+ dst_off_x = box.x1;
+ dst_off_y = box.y1;
- extents = &box;
- dst_off_x = box.x1;
- dst_off_y = box.y1;
- } else {
- dst_off_x = dst_off_y = 0;
- }
-
- width = extents->x2 - extents->x1;
- height = extents->y2 - extents->y1;
- x = -extents->x1;
- y = -extents->y1;
+ width = box.x2 - box.x1;
+ height = box.y2 - box.y1;
+ x = -box.x1;
+ y = -box.y1;
if (maskFormat->depth == 1) {
PictFormatPtr a8Format =
@@ -1061,11 +870,6 @@ uxa_glyphs(CARD8 op,
{
ScreenPtr screen = pDst->pDrawable->pScreen;
uxa_screen_t *uxa_screen = uxa_get_screen(screen);
- int xDst = list->xOff, yDst = list->yOff;
- BoxRec extents = { 0, 0, 0, 0 };
- Bool have_extents = FALSE;
- int width, height, ret;
- PicturePtr localDst = pDst;
if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
int ok;
@@ -1128,112 +932,12 @@ fallback:
}
}
- if (!maskFormat &&
- uxa_screen->info->check_composite_target &&
- !uxa_screen->info->check_composite_target(uxa_get_drawable_pixmap(pDst->pDrawable))) {
- int depth = pDst->pDrawable->depth;
- PixmapPtr pixmap;
- int x, y, error;
- GCPtr gc;
-
- pixmap = uxa_get_drawable_pixmap(pDst->pDrawable);
- if (uxa_screen->info->check_copy &&
- !uxa_screen->info->check_copy(pixmap, pixmap, GXcopy, FB_ALLONES))
- goto fallback;
-
- uxa_glyph_extents(nlist, list, glyphs, &extents);
-
- /* clip against dst bounds */
- if (extents.x1 < 0)
- extents.x1 = 0;
- if (extents.y1 < 0)
- extents.y1 = 0;
- if (extents.x2 > pDst->pDrawable->width)
- extents.x2 = pDst->pDrawable->width;
- if (extents.y2 > pDst->pDrawable->height)
- extents.y2 = pDst->pDrawable->height;
-
- if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
- return;
- width = extents.x2 - extents.x1;
- height = extents.y2 - extents.y1;
- x = -extents.x1;
- y = -extents.y1;
- have_extents = TRUE;
-
- xDst += x;
- yDst += y;
-
- pixmap = screen->CreatePixmap(screen,
- width, height, depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pixmap)
- return;
-
- if (!uxa_pixmap_is_offscreen(pixmap)) {
- screen->DestroyPixmap(pixmap);
- goto fallback;
- }
-
- gc = GetScratchGC(depth, screen);
- if (!gc) {
- screen->DestroyPixmap(pixmap);
- return;
- }
-
- ValidateGC(&pixmap->drawable, gc);
- gc->ops->CopyArea(pDst->pDrawable, &pixmap->drawable, gc,
- extents.x1, extents.y1,
- width, height,
- 0, 0);
- FreeScratchGC(gc);
-
- localDst = CreatePicture(0, &pixmap->drawable,
- PictureMatchFormat(screen, depth, pDst->format),
- 0, 0, serverClient, &error);
- screen->DestroyPixmap(pixmap);
-
- if (!localDst)
- return;
-
- ValidatePicture(localDst);
- }
-
- if (maskFormat) {
- ret = uxa_glyphs_via_mask(op,
- pSrc, localDst, maskFormat,
- xSrc, ySrc,
- xDst, yDst,
- nlist, list, glyphs,
- have_extents ? &extents : NULL);
- } else {
- ret = uxa_glyphs_to_dst(op,
- pSrc, localDst,
- xSrc, ySrc,
- xDst, yDst,
- nlist, list, glyphs,
- have_extents ? &extents : NULL);
- }
- if (ret) {
- if (localDst != pDst)
- FreePicture(localDst, 0);
-
+ if (!maskFormat)
goto fallback;
- }
- if (localDst != pDst) {
- GCPtr gc;
-
- gc = GetScratchGC(pDst->pDrawable->depth, screen);
- if (gc) {
- ValidateGC(pDst->pDrawable, gc);
- gc->ops->CopyArea(localDst->pDrawable, pDst->pDrawable, gc,
- 0, 0,
- width, height,
- extents.x1, extents.y1);
- FreeScratchGC(gc);
- }
-
- FreePicture(localDst, 0);
- }
+ if (uxa_glyphs_via_mask(op,
+ pSrc, pDst, maskFormat,
+ xSrc, ySrc,
+ nlist, list, glyphs))
+ goto fallback;
}
--
1.7.10

View File

@ -0,0 +1,39 @@
From af5c698fd43308c3b799783b662b9cd871f90a62 Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Sat, 14 Apr 2012 19:03:25 +0100
Subject: [PATCH 5/5] uxa: Fix leak of glyph mask for unhandled glyph
composition
==1401== 7,344 bytes in 34 blocks are possibly lost in loss record 570 of 587
==1401== at 0x4027034: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1401== by 0x8BE5150: drm_intel_gem_bo_alloc_internal (intel_bufmgr_gem.c:689)
==1401== by 0x899FC04: intel_uxa_create_pixmap (intel_uxa.c:1077)
==1401== by 0x89C2C41: uxa_glyphs (uxa-glyphs.c:254)
==1401== by 0x21F05E: damageGlyphs (damage.c:647)
==1401== by 0x218E06: ProcRenderCompositeGlyphs (render.c:1434)
==1401== by 0x15AA40: Dispatch (dispatch.c:439)
==1401== by 0x1499E9: main (main.c:287)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
uxa/uxa-glyphs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index b754f4e..921b99c 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -812,8 +812,10 @@ uxa_glyphs_via_mask(CARD8 op,
if (!uxa_pixmap_is_offscreen(src_pixmap) ||
!uxa_screen->info->prepare_composite(PictOpAdd,
this_atlas, NULL, mask,
- src_pixmap, NULL, pixmap))
+ src_pixmap, NULL, pixmap)) {
+ FreePicture(mask, 0);
return -1;
+ }
glyph_atlas = this_atlas;
}
--
1.7.10

View File

@ -1,7 +1,8 @@
# Template build file for 'xf86-video-intel'.
pkgname=xf86-video-intel
version=2.18.0
revision=1
revision=2
patch_args="-Np1"
distfiles="${XORG_SITE}/driver/$pkgname-$version.tar.bz2"
build_style=gnu-configure
configure_args="--enable-sna"