largepixmap: Support self composite for large pixmap.

The simplest way to support large pixmap's self compositing
is to just clone a pixmap private data structure, and change
the fbo and box to point to the correct postions. Don't need
to copy a new box.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2012-06-11 11:42:46 +08:00 committed by Eric Anholt
parent 1d2d858b8d
commit 5325c800f7
3 changed files with 57 additions and 45 deletions

View File

@ -22,8 +22,7 @@ __glamor_compute_clipped_regions(int block_w,
int x, int y, int x, int y,
int w, int h, int w, int h,
RegionPtr region, RegionPtr region,
int *n_region, int *n_region)
int repeat)
{ {
glamor_pixmap_clipped_regions * clipped_regions; glamor_pixmap_clipped_regions * clipped_regions;
BoxPtr extent; BoxPtr extent;
@ -157,7 +156,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
0, 0, 0, 0,
priv->base.pixmap->drawable.width, priv->base.pixmap->drawable.width,
priv->base.pixmap->drawable.height, priv->base.pixmap->drawable.height,
region, n_region, 0 region, n_region
); );
if (clipped_regions == NULL) { if (clipped_regions == NULL) {
@ -185,7 +184,7 @@ glamor_compute_clipped_regions_ext(glamor_pixmap_private *pixmap_priv,
width, width,
height, height,
clipped_regions[i].region, clipped_regions[i].region,
&inner_n_regions, 0); &inner_n_regions);
for(j = 0; j < inner_n_regions; j++) for(j = 0; j < inner_n_regions; j++)
{ {
result_regions[k].region = inner_regions[j].region; result_regions[k].region = inner_regions[j].region;
@ -339,7 +338,7 @@ _glamor_compute_clipped_regions(glamor_pixmap_private *pixmap_priv,
0, 0, 0, 0,
priv->base.pixmap->drawable.width, priv->base.pixmap->drawable.width,
priv->base.pixmap->drawable.height, priv->base.pixmap->drawable.height,
region, n_region, 0 region, n_region
); );
if (saved_region) if (saved_region)
RegionDestroy(region); RegionDestroy(region);
@ -1044,14 +1043,17 @@ glamor_composite_largepixmap_region(CARD8 op,
&n_dest_regions, &n_dest_regions,
0); 0);
DEBUGF("dest clipped result %d region: \n", n_dest_regions); DEBUGF("dest clipped result %d region: \n", n_dest_regions);
if (source_pixmap_priv == dest_pixmap_priv if (source_pixmap_priv
&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) { && (source_pixmap_priv == dest_pixmap_priv || source_pixmap_priv == mask_pixmap_priv)
&& source_pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
/* XXX self-copy...*/ /* XXX self-copy...*/
need_free_source_pixmap_priv = source_pixmap_priv; need_free_source_pixmap_priv = source_pixmap_priv;
source_pixmap_priv = malloc(sizeof(*source_pixmap_priv)); source_pixmap_priv = malloc(sizeof(*source_pixmap_priv));
*source_pixmap_priv = *need_free_source_pixmap_priv; *source_pixmap_priv = *need_free_source_pixmap_priv;
need_free_source_pixmap_priv = source_pixmap_priv; need_free_source_pixmap_priv = source_pixmap_priv;
} }
assert(mask_pixmap_priv != dest_pixmap_priv);
for(i = 0; i < n_dest_regions; i++) for(i = 0; i < n_dest_regions; i++)
{ {
DEBUGF("dest region %d idx %d\n", i, clipped_dest_regions[i].block_idx); DEBUGF("dest region %d idx %d\n", i, clipped_dest_regions[i].block_idx);
@ -1149,7 +1151,10 @@ glamor_composite_largepixmap_region(CARD8 op,
#define COMPOSITE_REGION(region) do { \ #define COMPOSITE_REGION(region) do { \
if (!glamor_composite_clipped_region(op, \ if (!glamor_composite_clipped_region(op, \
null_source ? NULL : source, \ null_source ? NULL : source, \
null_mask ? NULL : mask, dest, region, \ null_mask ? NULL : mask, dest, \
null_source ? NULL : source_pixmap_priv, \
null_mask ? NULL : mask_pixmap_priv, \
dest_pixmap_priv, region, \
x_source, y_source, x_mask, y_mask, \ x_source, y_source, x_mask, y_mask, \
x_dest, y_dest)) { \ x_dest, y_dest)) { \
assert(0); \ assert(0); \

View File

@ -667,6 +667,9 @@ glamor_composite_clipped_region(CARD8 op,
PicturePtr source, PicturePtr source,
PicturePtr mask, PicturePtr mask,
PicturePtr dest, PicturePtr dest,
glamor_pixmap_private *soruce_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
RegionPtr region, RegionPtr region,
int x_source, int x_source,
int y_source, int y_source,

View File

@ -968,22 +968,19 @@ glamor_composite_with_shader(CARD8 op,
PicturePtr source, PicturePtr source,
PicturePtr mask, PicturePtr mask,
PicturePtr dest, PicturePtr dest,
glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
int nrect, int nrect,
glamor_composite_rect_t * rects) glamor_composite_rect_t * rects)
{ {
ScreenPtr screen = dest->pDrawable->pScreen; ScreenPtr screen = dest->pDrawable->pScreen;
glamor_screen_private *glamor_priv = glamor_screen_private *glamor_priv = dest_pixmap_priv->base.glamor_priv;
glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch; glamor_gl_dispatch *dispatch;
PixmapPtr dest_pixmap = PixmapPtr dest_pixmap = dest_pixmap_priv->base.pixmap;
glamor_get_drawable_pixmap(dest->pDrawable);
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
glamor_pixmap_private *source_pixmap_priv = NULL;
glamor_pixmap_private *mask_pixmap_priv = NULL;
glamor_pixmap_private *dest_pixmap_priv = NULL;
GLfloat dst_xscale, dst_yscale; GLfloat dst_xscale, dst_yscale;
GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = GLfloat mask_xscale = 1, mask_yscale = 1, src_xscale = 1, src_yscale = 1;
1, src_yscale = 1;
struct shader_key key; struct shader_key key;
glamor_composite_shader *shader; glamor_composite_shader *shader;
float vertices[8], source_texcoords[8], mask_texcoords[8]; float vertices[8], source_texcoords[8], mask_texcoords[8];
@ -1000,7 +997,6 @@ glamor_composite_with_shader(CARD8 op,
int nrect_max; int nrect_max;
Bool ret = FALSE; Bool ret = FALSE;
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
glamor_fallback("dest has no fbo.\n"); glamor_fallback("dest has no fbo.\n");
goto fail; goto fail;
@ -1075,10 +1071,7 @@ glamor_composite_with_shader(CARD8 op,
} }
if (key.source == SHADER_SOURCE_TEXTURE || if (key.source == SHADER_SOURCE_TEXTURE ||
key.source == SHADER_SOURCE_TEXTURE_ALPHA) { key.source == SHADER_SOURCE_TEXTURE_ALPHA) {
source_pixmap = source_pixmap = source_pixmap_priv->base.pixmap;
glamor_get_drawable_pixmap(source->pDrawable);
source_pixmap_priv =
glamor_get_pixmap_private(source_pixmap);
if (source_pixmap == dest_pixmap) { if (source_pixmap == dest_pixmap) {
/* XXX source and the dest share the same texture. /* XXX source and the dest share the same texture.
* Does it need special handle? */ * Does it need special handle? */
@ -1099,8 +1092,7 @@ glamor_composite_with_shader(CARD8 op,
} }
if (key.mask == SHADER_MASK_TEXTURE || if (key.mask == SHADER_MASK_TEXTURE ||
key.mask == SHADER_MASK_TEXTURE_ALPHA) { key.mask == SHADER_MASK_TEXTURE_ALPHA) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); mask_pixmap = mask_pixmap_priv->base.pixmap;
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
if (mask_pixmap == dest_pixmap) { if (mask_pixmap == dest_pixmap) {
glamor_fallback("mask == dest\n"); glamor_fallback("mask == dest\n");
goto fail; goto fail;
@ -1432,6 +1424,9 @@ glamor_composite_clipped_region(CARD8 op,
PicturePtr source, PicturePtr source,
PicturePtr mask, PicturePtr mask,
PicturePtr dest, PicturePtr dest,
glamor_pixmap_private *source_pixmap_priv,
glamor_pixmap_private *mask_pixmap_priv,
glamor_pixmap_private *dest_pixmap_priv,
RegionPtr region, RegionPtr region,
int x_source, int x_source,
int y_source, int y_source,
@ -1441,13 +1436,10 @@ glamor_composite_clipped_region(CARD8 op,
int y_dest) int y_dest)
{ {
ScreenPtr screen = dest->pDrawable->pScreen; ScreenPtr screen = dest->pDrawable->pScreen;
glamor_pixmap_private *dest_pixmap_priv;
glamor_pixmap_private *source_pixmap_priv =
NULL, *mask_pixmap_priv = NULL;
PixmapPtr dest_pixmap =
glamor_get_drawable_pixmap(dest->pDrawable);
PixmapPtr source_pixmap = NULL, mask_pixmap = NULL; PixmapPtr source_pixmap = NULL, mask_pixmap = NULL;
PicturePtr temp_src = source, temp_mask = mask; PicturePtr temp_src = source, temp_mask = mask;
glamor_pixmap_private *temp_src_priv = source_pixmap_priv;
glamor_pixmap_private *temp_mask_priv = mask_pixmap_priv;
int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask; int x_temp_src, y_temp_src, x_temp_mask, y_temp_mask;
BoxPtr extent; BoxPtr extent;
@ -1472,20 +1464,12 @@ glamor_composite_clipped_region(CARD8 op,
y_temp_mask = y_mask; y_temp_mask = y_mask;
DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n", DEBUGF("clipped (%d %d) (%d %d) (%d %d) width %d height %d \n",
x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height); x_source, y_source, x_mask, y_mask, x_dest, y_dest, width, height);
DEBUGF("dest pixmap %p ", dest_pixmap);
dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); if (source_pixmap_priv)
/* Currently. Always fallback to cpu if destination is in CPU memory. */ source_pixmap = source_pixmap_priv->base.pixmap;
if (source && source->pDrawable) { if (mask_pixmap_priv)
source_pixmap = glamor_get_drawable_pixmap(source->pDrawable); mask_pixmap = mask_pixmap_priv->base.pixmap;
source_pixmap_priv = glamor_get_pixmap_private(source_pixmap);
}
if (mask && mask->pDrawable) {
mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable);
mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap);
}
/* XXX is it possible source mask have non-zero drawable.x/y? */ /* XXX is it possible source mask have non-zero drawable.x/y? */
if (source if (source
@ -1504,6 +1488,7 @@ glamor_composite_clipped_region(CARD8 op,
temp_src = source; temp_src = source;
goto out; goto out;
} }
temp_src_priv = glamor_get_pixmap_private((PixmapPtr)(temp_src->pDrawable));
x_temp_src = - extent->x1 + x_dest; x_temp_src = - extent->x1 + x_dest;
y_temp_src = - extent->y1 + y_dest; y_temp_src = - extent->y1 + y_dest;
} }
@ -1527,6 +1512,7 @@ glamor_composite_clipped_region(CARD8 op,
temp_mask = mask; temp_mask = mask;
goto out; goto out;
} }
temp_mask_priv = glamor_get_pixmap_private((PixmapPtr)(temp_mask->pDrawable));
x_temp_mask = - extent->x1 + x_dest; x_temp_mask = - extent->x1 + x_dest;
y_temp_mask = - extent->y1 + y_dest; y_temp_mask = - extent->y1 + y_dest;
} }
@ -1538,6 +1524,7 @@ glamor_composite_clipped_region(CARD8 op,
if (op == PictOpOver) { if (op == PictOpOver) {
glamor_composite_clipped_region(PictOpOutReverse, glamor_composite_clipped_region(PictOpOutReverse,
temp_src, temp_mask, dest, temp_src, temp_mask, dest,
temp_src_priv, temp_mask_priv, dest_pixmap_priv,
region, region,
x_temp_src, y_temp_src, x_temp_src, y_temp_src,
x_temp_mask, y_temp_mask, x_temp_mask, y_temp_mask,
@ -1545,6 +1532,7 @@ glamor_composite_clipped_region(CARD8 op,
glamor_composite_clipped_region(PictOpAdd, glamor_composite_clipped_region(PictOpAdd,
temp_src, temp_mask, dest, temp_src, temp_mask, dest,
temp_src_priv, temp_mask_priv, dest_pixmap_priv,
region, region,
x_temp_src, y_temp_src, x_temp_src, y_temp_src,
x_temp_mask, y_temp_mask, x_temp_mask, y_temp_mask,
@ -1598,8 +1586,10 @@ glamor_composite_clipped_region(CARD8 op,
prect[i].width = box[i].x2 - box[i].x1; prect[i].width = box[i].x2 - box[i].x1;
prect[i].height = box[i].y2 - box[i].y1; prect[i].height = box[i].y2 - box[i].y1;
} }
ok = glamor_composite_with_shader(op, temp_src, temp_mask, ok = glamor_composite_with_shader(op, temp_src, temp_mask, dest,
dest, box_cnt, prect); temp_src_priv, temp_mask_priv,
dest_pixmap_priv,
box_cnt, prect);
if (!ok) if (!ok)
break; break;
nbox -= box_cnt; nbox -= box_cnt;
@ -1749,7 +1739,11 @@ _glamor_composite(CARD8 op,
width, height); width, height);
else else
ok = glamor_composite_clipped_region(op, source, ok = glamor_composite_clipped_region(op, source,
mask, dest, &region, mask, dest,
source_pixmap_priv,
mask_pixmap_priv,
dest_pixmap_priv,
&region,
x_source, y_source, x_source, y_source,
x_mask, y_mask, x_mask, y_mask,
x_dest, y_dest); x_dest, y_dest);
@ -2045,7 +2039,17 @@ glamor_composite_glyph_rects(CARD8 op,
if (!(glamor_is_large_picture(src) if (!(glamor_is_large_picture(src)
|| (mask && glamor_is_large_picture(mask)) || (mask && glamor_is_large_picture(mask))
|| glamor_is_large_picture(dst))) { || glamor_is_large_picture(dst))) {
if (glamor_composite_with_shader(op, src, mask, dst, nrect, rects)) glamor_pixmap_private *src_pixmap_priv = NULL;
glamor_pixmap_private *mask_pixmap_priv = NULL;
glamor_pixmap_private *dst_pixmap_priv;
dst_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(dst->pDrawable));
if (mask && mask->pDrawable)
mask_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(mask->pDrawable));
if (src->pDrawable)
src_pixmap_priv = glamor_get_pixmap_private(glamor_get_drawable_pixmap(src->pDrawable));
if (glamor_composite_with_shader(op, src, mask, dst, src_pixmap_priv,
mask_pixmap_priv, dst_pixmap_priv, nrect, rects))
return; return;
} }