summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-10 09:39:44 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-10 10:36:14 +0100
commitf52b6e832292c02c0010b19882e38e1097beeda0 (patch)
tree9da0d96b7d8a1917f0506095928bf5158d9e5e2f
parent848ab66384508c3ad3e5fb4884e4527f3ebd3bde (diff)
uxa: Rearrange checking and preparing of composite textures.
x11perf regression caused by 2D driver https://bugs.freedesktop.org/show_bug.cgi?id=28047 caused by commit a7b800513fcc94e063dfd68d2f63b6bab7fae47d uxa: Extract sub-region from in-memory buffers. The issue is that as we extract the region prior to checking whether the composite can in fact be accelerated, we perform expensive surplus operations. This is particularly noticeable for ComponentAlpha text, such as rgb10text. The solution here is to rearrange the check_composite() prior to acquiring the sources, and only extracting the subregion if the render path can not actually handle the texture. Performance (on PineView): a7b800513^: aa=68600 glyphs/s, rgb=29900 glyphs/s a7b800513: aa=65700 glyphs/s, rgb=13200 glyphs/s now: aa=66800 glyph/s, rgb=28800 glyphs/s The residual lossage seems to be from the extra function call and dixPrivate lookups. Hmm. More warning is the extremely low performance, however the results are consistent so the improvement looks real... Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/i830.h5
-rw-r--r--src/i830_render.c104
-rw-r--r--src/i830_uxa.c3
-rw-r--r--src/i915_render.c170
-rw-r--r--src/i965_render.c108
-rw-r--r--uxa/uxa-render.c130
-rw-r--r--uxa/uxa.h13
7 files changed, 271 insertions, 262 deletions
diff --git a/src/i830.h b/src/i830.h
index 88949f6f..fc26f3a2 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -447,8 +447,9 @@ void i830_set_gem_max_sizes(ScrnInfoPtr scrn);
drm_intel_bo *i830_allocate_framebuffer(ScrnInfoPtr scrn);
/* i830_render.c */
-Bool i830_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
+Bool i830_check_composite(int op, PicturePtr source, PicturePtr mask,
PicturePtr dest);
+Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture);
Bool i830_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest, PixmapPtr sourcecPixmap,
PixmapPtr maskPixmap, PixmapPtr destPixmap);
@@ -460,6 +461,7 @@ void i830_done_composite(PixmapPtr dest);
/* i915_render.c */
Bool i915_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest);
+Bool i915_check_composite_texture(ScreenPtr screen, PicturePtr picture);
Bool i915_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest, PixmapPtr sourcecPixmap,
PixmapPtr maskPixmap, PixmapPtr destPixmap);
@@ -473,6 +475,7 @@ void gen4_render_state_init(ScrnInfoPtr scrn);
void gen4_render_state_cleanup(ScrnInfoPtr scrn);
Bool i965_check_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest);
+Bool i965_check_composite_texture(ScreenPtr screen, PicturePtr picture);
Bool i965_prepare_composite(int op, PicturePtr sourcec, PicturePtr mask,
PicturePtr dest, PixmapPtr sourcecPixmap,
PixmapPtr maskPixmap, PixmapPtr destPixmap);
diff --git a/src/i830_render.c b/src/i830_render.c
index 8e559c99..e7f55ce7 100644
--- a/src/i830_render.c
+++ b/src/i830_render.c
@@ -221,52 +221,6 @@ static Bool i830_get_blend_cntl(ScrnInfoPtr scrn, int op, PicturePtr mask,
return TRUE;
}
-static Bool i830_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
- int unit)
-{
- if (picture->repeatType > RepeatReflect) {
- intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
- picture->repeatType);
- return FALSE;
- }
-
- if (picture->filter != PictFilterNearest &&
- picture->filter != PictFilterBilinear) {
- intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
- picture->filter);
- return FALSE;
- }
-
- if (picture->pDrawable) {
- int w, h, i;
-
- w = picture->pDrawable->width;
- h = picture->pDrawable->height;
- if ((w > 2048) || (h > 2048)) {
- intel_debug_fallback(scrn,
- "Picture w/h too large (%dx%d)\n",
- w, h);
- return FALSE;
- }
-
- for (i = 0;
- i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
- i++) {
- if (i830_tex_formats[i].fmt == picture->format)
- break;
- }
- if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]))
- {
- intel_debug_fallback(scrn, "Unsupported picture format "
- "0x%x\n",
- (int)picture->format);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
static uint32_t i8xx_get_card_format(PicturePtr picture)
{
int i;
@@ -413,22 +367,64 @@ i830_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
}
}
- if (!i830_check_composite_texture(scrn, source_picture, 0)) {
- intel_debug_fallback(scrn, "Check Src picture texture\n");
+ if (!i830_get_dest_format(dest_picture, &tmp1)) {
+ intel_debug_fallback(scrn, "Get Color buffer format\n");
return FALSE;
}
- if (mask_picture != NULL
- && !i830_check_composite_texture(scrn, mask_picture, 1)) {
- intel_debug_fallback(scrn, "Check Mask picture texture\n");
+
+ return TRUE;
+}
+
+Bool
+i830_check_composite_texture(ScreenPtr screen, PicturePtr picture)
+{
+ if (picture->repeatType > RepeatReflect) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
+ picture->repeatType);
return FALSE;
}
- if (!i830_get_dest_format(dest_picture, &tmp1)) {
- intel_debug_fallback(scrn, "Get Color buffer format\n");
+ if (picture->filter != PictFilterNearest &&
+ picture->filter != PictFilterBilinear) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
+ picture->filter);
return FALSE;
}
- return TRUE;
+ if (picture->pDrawable) {
+ int w, h, i;
+
+ w = picture->pDrawable->width;
+ h = picture->pDrawable->height;
+ if ((w > 2048) || (h > 2048)) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn,
+ "Picture w/h too large (%dx%d)\n",
+ w, h);
+ return FALSE;
+ }
+
+ for (i = 0;
+ i < sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]);
+ i++) {
+ if (i830_tex_formats[i].fmt == picture->format)
+ break;
+ }
+ if (i == sizeof(i830_tex_formats) / sizeof(i830_tex_formats[0]))
+ {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn, "Unsupported picture format "
+ "0x%x\n",
+ (int)picture->format);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
}
Bool
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 4a13eb0b..8b81e0c0 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -1078,17 +1078,20 @@ Bool i830_uxa_init(ScreenPtr screen)
/* Composite */
if (!IS_I9XX(intel)) {
intel->uxa_driver->check_composite = i830_check_composite;
+ intel->uxa_driver->check_composite_texture = i830_check_composite_texture;
intel->uxa_driver->prepare_composite = i830_prepare_composite;
intel->uxa_driver->composite = i830_composite;
intel->uxa_driver->done_composite = i830_done_composite;
} else if (IS_I915G(intel) || IS_I915GM(intel) ||
IS_I945G(intel) || IS_I945GM(intel) || IS_G33CLASS(intel)) {
intel->uxa_driver->check_composite = i915_check_composite;
+ intel->uxa_driver->check_composite_texture = i915_check_composite_texture;
intel->uxa_driver->prepare_composite = i915_prepare_composite;
intel->uxa_driver->composite = i915_composite;
intel->uxa_driver->done_composite = i830_done_composite;
} else {
intel->uxa_driver->check_composite = i965_check_composite;
+ intel->uxa_driver->check_composite_texture = i965_check_composite_texture;
intel->uxa_driver->prepare_composite = i965_prepare_composite;
intel->uxa_driver->composite = i965_composite;
intel->uxa_driver->done_composite = i830_done_composite;
diff --git a/src/i915_render.c b/src/i915_render.c
index 98b5b88a..36f50d47 100644
--- a/src/i915_render.c
+++ b/src/i915_render.c
@@ -176,10 +176,50 @@ static Bool i915_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
return TRUE;
}
-static Bool i915_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
- int unit)
+Bool
+i915_check_composite(int op,
+ PicturePtr source_picture,
+ PicturePtr mask_picture,
+ PicturePtr dest_picture)
+{
+ ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
+ uint32_t tmp1;
+
+ /* Check for unsupported compositing operations. */
+ if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0])) {
+ intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
+ op);
+ return FALSE;
+ }
+ if (mask_picture != NULL && mask_picture->componentAlpha &&
+ PICT_FORMAT_RGB(mask_picture->format)) {
+ /* Check if it's component alpha that relies on a source alpha
+ * and on the source value. We can only get one of those
+ * into the single source value that we get to blend with.
+ */
+ if (i915_blend_op[op].src_alpha &&
+ (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
+ intel_debug_fallback(scrn,
+ "Component alpha not supported "
+ "with source alpha and source "
+ "value blending.\n");
+ return FALSE;
+ }
+ }
+
+ if (!i915_get_dest_format(dest_picture, &tmp1)) {
+ intel_debug_fallback(scrn, "Get Color buffer format\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+i915_check_composite_texture(ScreenPtr screen, PicturePtr picture)
{
if (picture->repeatType > RepeatReflect) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported picture repeat %d\n",
picture->repeatType);
return FALSE;
@@ -187,17 +227,25 @@ static Bool i915_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
if (picture->filter != PictFilterNearest &&
picture->filter != PictFilterBilinear) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
picture->filter);
return FALSE;
}
+ if (picture->pSourcePict) {
+ SourcePict *source = picture->pSourcePict;
+ if (source->type == SourcePictTypeSolidFill)
+ return TRUE;
+ }
+
if (picture->pDrawable) {
int w, h, i;
w = picture->pDrawable->width;
h = picture->pDrawable->height;
if ((w > 2048) || (h > 2048)) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn,
"Picture w/h too large (%dx%d)\n",
w, h);
@@ -212,61 +260,17 @@ static Bool i915_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
}
if (i == sizeof(i915_tex_formats) / sizeof(i915_tex_formats[0]))
{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
intel_debug_fallback(scrn, "Unsupported picture format "
"0x%x\n",
(int)picture->format);
return FALSE;
}
- }
- return TRUE;
-}
-
-Bool
-i915_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
- PicturePtr dest_picture)
-{
- ScrnInfoPtr scrn = xf86Screens[dest_picture->pDrawable->pScreen->myNum];
- uint32_t tmp1;
-
- /* Check for unsupported compositing operations. */
- if (op >= sizeof(i915_blend_op) / sizeof(i915_blend_op[0])) {
- intel_debug_fallback(scrn, "Unsupported Composite op 0x%x\n",
- op);
- return FALSE;
- }
- if (mask_picture != NULL && mask_picture->componentAlpha &&
- PICT_FORMAT_RGB(mask_picture->format)) {
- /* Check if it's component alpha that relies on a source alpha
- * and on the source value. We can only get one of those
- * into the single source value that we get to blend with.
- */
- if (i915_blend_op[op].src_alpha &&
- (i915_blend_op[op].src_blend != BLENDFACT_ZERO)) {
- intel_debug_fallback(scrn,
- "Component alpha not supported "
- "with source alpha and source "
- "value blending.\n");
- return FALSE;
- }
- }
-
- if (!i915_check_composite_texture(scrn, source_picture, 0)) {
- intel_debug_fallback(scrn, "Check Src picture texture\n");
- return FALSE;
- }
- if (mask_picture != NULL
- && !i915_check_composite_texture(scrn, mask_picture, 1)) {
- intel_debug_fallback(scrn, "Check Mask picture texture\n");
- return FALSE;
- }
-
- if (!i915_get_dest_format(dest_picture, &tmp1)) {
- intel_debug_fallback(scrn, "Get Color buffer format\n");
- return FALSE;
+ return TRUE;
}
- return TRUE;
+ return FALSE;
}
static Bool i915_texture_setup(PicturePtr picture, PixmapPtr pixmap, int unit)
@@ -382,39 +386,53 @@ i915_prepare_composite(int op, PicturePtr source_picture,
intel->render_dest_picture = dest_picture;
intel->render_dest = dest;
- intel->render_source_is_solid =
- source_picture->pDrawable &&
- source_picture->pDrawable->width == 1 &&
- source_picture->pDrawable->height == 1 &&
- source_picture->repeat;
-
- if (intel->render_source_is_solid) {
- if (! uxa_get_color_for_pixmap (source,
- source_picture->format,
- PICT_a8r8g8b8,
- &intel->render_source_solid))
- intel->render_source_is_solid = FALSE;
+ 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;
+ }
+ } else if (source_picture->pDrawable) {
+ intel->render_source_is_solid =
+ source_picture->pDrawable->width == 1 &&
+ source_picture->pDrawable->height == 1 &&
+ source_picture->repeat;
+
+ if (intel->render_source_is_solid) {
+ if (! uxa_get_color_for_pixmap (source,
+ source_picture->format,
+ PICT_a8r8g8b8,
+ &intel->render_source_solid))
+ intel->render_source_is_solid = FALSE;
+ }
}
if (!intel->render_source_is_solid && !intel_check_pitch_3d(source))
return FALSE;
-
intel->render_mask_is_solid = TRUE; /* mask == NULL => opaque */
if (mask) {
- intel->render_mask_is_solid =
- mask_picture->pDrawable &&
- mask_picture->pDrawable->width == 1 &&
- mask_picture->pDrawable->height == 1 &&
- mask_picture->repeat;
- if (intel->render_mask_is_solid) {
- if (! uxa_get_color_for_pixmap (mask,
- mask_picture->format,
- PICT_a8r8g8b8,
- &intel->render_mask_solid))
- intel->render_mask_is_solid = FALSE;
- }
- if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
- return FALSE;
+ 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;
+ }
+ } else if (mask_picture->pDrawable) {
+ intel->render_mask_is_solid =
+ mask_picture->pDrawable->width == 1 &&
+ mask_picture->pDrawable->height == 1 &&
+ mask_picture->repeat;
+ if (intel->render_mask_is_solid) {
+ if (! uxa_get_color_for_pixmap (mask,
+ mask_picture->format,
+ PICT_a8r8g8b8,
+ &intel->render_mask_solid))
+ intel->render_mask_is_solid = FALSE;
+ }
+ }
+ if (!intel->render_mask_is_solid && !intel_check_pitch_3d(mask))
+ return FALSE;
}
if (!intel_check_pitch_3d(dest))
diff --git a/src/i965_render.c b/src/i965_render.c
index 36235499..c38bbfc3 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -183,54 +183,6 @@ static Bool i965_get_dest_format(PicturePtr dest_picture, uint32_t * dst_format)
return TRUE;
}
-static Bool i965_check_composite_texture(ScrnInfoPtr scrn, PicturePtr picture,
- int unit)
-{
- if (picture->repeatType > RepeatReflect) {
- intel_debug_fallback(scrn,
- "extended repeat (%d) not supported\n",
- picture->repeatType);
- return FALSE;
- }
-
- if (picture->filter != PictFilterNearest &&
- picture->filter != PictFilterBilinear) {
- intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
- picture->filter);
- return FALSE;
- }
-
- if (picture->pDrawable) {
- int w, h, i;
-
- w = picture->pDrawable->width;
- h = picture->pDrawable->height;
- if ((w > 8192) || (h > 8192)) {
- intel_debug_fallback(scrn,
- "Picture w/h too large (%dx%d)\n",
- w, h);
- return FALSE;
- }
-
- for (i = 0;
- i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
- i++) {
- if (i965_tex_formats[i].fmt == picture->format)
- break;
- }
- if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
- {
- intel_debug_fallback(scrn,
- "Unsupported picture format "
- "0x%x\n",
- (int)picture->format);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
Bool
i965_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
PicturePtr dest_picture)
@@ -267,25 +219,69 @@ i965_check_composite(int op, PicturePtr source_picture, PicturePtr mask_picture,
}
}
- if (!i965_check_composite_texture(scrn, source_picture, 0)) {
- intel_debug_fallback(scrn, "Check Src picture texture\n");
+ if (!i965_get_dest_format(dest_picture, &tmp1)) {
+ intel_debug_fallback(scrn, "Get Color buffer format\n");
return FALSE;
}
- if (mask_picture != NULL
- && !i965_check_composite_texture(scrn, mask_picture, 1)) {
- intel_debug_fallback(scrn, "Check Mask picture texture\n");
+
+ return TRUE;
+}
+
+Bool
+i965_check_composite_texture(ScreenPtr screen, PicturePtr picture)
+{
+ if (picture->repeatType > RepeatReflect) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn,
+ "extended repeat (%d) not supported\n",
+ picture->repeatType);
return FALSE;
}
- if (!i965_get_dest_format(dest_picture, &tmp1)) {
- intel_debug_fallback(scrn, "Get Color buffer format\n");
+ if (picture->filter != PictFilterNearest &&
+ picture->filter != PictFilterBilinear) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn, "Unsupported filter 0x%x\n",
+ picture->filter);
return FALSE;
}
- return TRUE;
+ if (picture->pDrawable) {
+ int w, h, i;
+ w = picture->pDrawable->width;
+ h = picture->pDrawable->height;
+ if ((w > 8192) || (h > 8192)) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn,
+ "Picture w/h too large (%dx%d)\n",
+ w, h);
+ return FALSE;
+ }
+
+ for (i = 0;
+ i < sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]);
+ i++) {
+ if (i965_tex_formats[i].fmt == picture->format)
+ break;
+ }
+ if (i == sizeof(i965_tex_formats) / sizeof(i965_tex_formats[0]))
+ {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ intel_debug_fallback(scrn,
+ "Unsupported picture format "
+ "0x%x\n",
+ (int)picture->format);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
}
+
#define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1)
/* Set up a default static partitioning of the URB, which is supposed to
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index 31126770..ddee1725 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -642,8 +642,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
PicturePtr pSrc,
INT16 x, INT16 y,
CARD16 width, CARD16 height,
- INT16 * out_x, INT16 * out_y,
- Bool force)
+ INT16 * out_x, INT16 * out_y)
{
PixmapPtr pPixmap;
PicturePtr pDst;
@@ -651,17 +650,17 @@ uxa_acquire_drawable(ScreenPtr pScreen,
int depth, error;
int tx, ty;
- if (!force && uxa_drawable_is_offscreen(pSrc->pDrawable)) {
- *out_x = x + pSrc->pDrawable->x;
- *out_y = y + pSrc->pDrawable->y;
- return pSrc;
- }
-
depth = pSrc->pDrawable->depth;
if (depth == 1 || !transform_is_integer_translation(pSrc->transform, &tx, &ty)) {
/* XXX extract the sample extents and do the transformation on the GPU */
pDst = uxa_render_picture(pScreen, pSrc, x, y, width, height);
goto done;
+ } else {
+ if (width == pSrc->pDrawable->width && height == pSrc->pDrawable->depth) {
+ *out_x = x + pSrc->pDrawable->x;
+ *out_y = y + pSrc->pDrawable->y;
+ return pSrc;
+ }
}
pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, 0);
@@ -671,9 +670,7 @@ uxa_acquire_drawable(ScreenPtr pScreen,
/* Skip the copy if the result remains in memory and not a bo */
if (!uxa_drawable_is_offscreen(&pPixmap->drawable)) {
pScreen->DestroyPixmap(pPixmap);
- *out_x = x + pSrc->pDrawable->x;
- *out_y = y + pSrc->pDrawable->y;
- return pSrc;
+ return 0;
}
pGC = GetScratchGC(depth, pScreen);
@@ -705,14 +702,21 @@ uxa_acquire_source(ScreenPtr pScreen,
PicturePtr pPict,
INT16 x, INT16 y,
CARD16 width, CARD16 height,
- INT16 * out_x, INT16 * out_y,
- Bool force)
+ INT16 * out_x, INT16 * out_y)
{
+ uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
+
+ if (uxa_screen->info->check_composite_texture &&
+ uxa_screen->info->check_composite_texture(pScreen, pPict)) {
+ *out_x = x + pPict->pDrawable->x;
+ *out_y = y + pPict->pDrawable->y;
+ return pPict;
+ }
+
if (pPict->pDrawable)
return uxa_acquire_drawable(pScreen, pPict,
x, y, width, height,
- out_x, out_y,
- force);
+ out_x, out_y);
*out_x = 0;
*out_y = 0;
@@ -725,14 +729,21 @@ uxa_acquire_mask(ScreenPtr pScreen,
PicturePtr pPict,
INT16 x, INT16 y,
INT16 width, INT16 height,
- INT16 * out_x, INT16 * out_y,
- Bool force)
+ INT16 * out_x, INT16 * out_y)
{
+ uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
+
+ if (uxa_screen->info->check_composite_texture &&
+ uxa_screen->info->check_composite_texture(pScreen, pPict)) {
+ *out_x = x + pPict->pDrawable->x;
+ *out_y = y + pPict->pDrawable->y;
+ return pPict;
+ }
+
if (pPict->pDrawable)
return uxa_acquire_drawable(pScreen, pPict,
x, y, width, height,
- out_x, out_y,
- force);
+ out_x, out_y);
*out_x = 0;
*out_y = 0;
@@ -872,12 +883,14 @@ uxa_try_driver_composite(CARD8 op,
RegionRec region;
BoxPtr pbox;
int nbox;
- INT16 _xSrc = xSrc, _ySrc = ySrc;
- INT16 _xMask = xMask, _yMask = yMask;
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
PicturePtr localSrc, localMask = NULL;
+ if (uxa_screen->info->check_composite &&
+ !(*uxa_screen->info->check_composite) (op, pSrc, pMask, pDst))
+ return -1;
+
pDstPix =
uxa_get_offscreen_pixmap(pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix)
@@ -886,18 +899,18 @@ uxa_try_driver_composite(CARD8 op,
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
- localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
- pSrc, xSrc, ySrc, width, height,
- &xSrc, &ySrc,
- FALSE);
+ localSrc = uxa_acquire_source(pDst->pDrawable->pScreen, pSrc,
+ xSrc, ySrc,
+ width, height,
+ &xSrc, &ySrc);
if (!localSrc)
return 0;
if (pMask) {
- localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
- pMask, xMask, yMask, width, height,
- &xMask, &yMask,
- FALSE);
+ localMask = uxa_acquire_mask(pDst->pDrawable->pScreen, pMask,
+ xMask, yMask,
+ width, height,
+ &xMask, &yMask);
if (!localMask) {
if (localSrc != pSrc)
FreePicture(localSrc, 0);
@@ -906,45 +919,6 @@ uxa_try_driver_composite(CARD8 op,
}
}
-recheck:
- if (uxa_screen->info->check_composite &&
- !(*uxa_screen->info->check_composite) (op, localSrc, localMask,
- pDst)) {
- if (localSrc == pSrc || (localMask && localMask == pMask)) {
- if (localSrc == pSrc) {
- localSrc = uxa_acquire_source(pDst->pDrawable->pScreen,
- pSrc, _xSrc, _ySrc, width, height,
- &xSrc, &ySrc, TRUE);
- if (!localSrc || localSrc == pSrc) {
- if (localMask && localMask != pMask)
- FreePicture(localMask, 0);
- return -(localSrc == pSrc);
- }
- }
-
- if (localMask && localMask == pMask) {
- localMask = uxa_acquire_mask(pDst->pDrawable->pScreen,
- pMask, _xMask, _yMask, width, height,
- &xMask, &yMask, TRUE);
- if (!localMask || localMask == pMask) {
- if (localSrc != pSrc)
- FreePicture(localSrc, 0);
-
- return -(localMask == pMask);
- }
- }
-
- goto recheck;
- }
-
- if (localSrc != pSrc)
- FreePicture(localSrc, 0);
- if (localMask && localMask != pMask)
- FreePicture(localMask, 0);
-
- return -1;
- }
-
if (!miComputeCompositeRegion(&region, localSrc, localMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height)) {
@@ -1306,9 +1280,15 @@ uxa_composite(CARD8 op,
/* For generic masks and solid src pictures, mach64 can do
* Over in two passes, similar to the component-alpha case.
*/
- isSrcSolid = pSrc->pDrawable &&
- pSrc->pDrawable->width == 1 &&
- pSrc->pDrawable->height == 1 && pSrc->repeat;
+
+ isSrcSolid =
+ pSrc->pDrawable ?
+ pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1 &&
+ pSrc->repeat :
+ pSrc->pSourcePict ?
+ pSrc->pSourcePict->type == SourcePictTypeSolidFill :
+ 0;
/* If we couldn't do the Composite in a single pass, and it
* was a component-alpha Over, see if we can do it in two
@@ -1320,13 +1300,13 @@ uxa_composite(CARD8 op,
uxa_try_magic_two_pass_composite_helper(op, pSrc,
pMask, pDst,
xSrc, ySrc,
- xMask,
- yMask, xDst,
- yDst, width,
- height);
+ xMask, yMask,
+ xDst, yDst,
+ width, height);
if (ret == 1)
goto done;
}
+
}
fallback:
diff --git a/uxa/uxa.h b/uxa/uxa.h
index c7e5566a..32a86a96 100644
--- a/uxa/uxa.h
+++ b/uxa/uxa.h
@@ -252,6 +252,19 @@ typedef struct _UxaDriver {
PicturePtr pDstPicture);
/**
+ * check_composite_texture() checks to see if a source to the composite
+ * operation can be used without midification.
+ *
+ * @param pScreen Screen
+ * @param pPicture Picture
+ *
+ * The check_composite_texture() call is recommended if prepare_composite() is
+ * implemented, but is not required.
+ */
+ Bool(*check_composite_texture) (ScreenPtr pScreen,
+ PicturePtr pPicture);
+
+ /**
* prepare_composite() sets up the driver for doing a composite
* operation described in the Render extension protocol spec.
*