glamor: Reduce source pixmap's size.
If the dest pixmap is in texture memory, but source pixmap is not. Then we need to upload the source pixmap to texture memory. Previous version will upload the whole source pixmap. This commit preprocess the source pixmap, and reduce it to a smaller tempory pixmap only contains the required region. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
33c6c78ae9
commit
1dca5d7b91
|
@ -308,6 +308,23 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
Pixel bitplane,
|
||||
void *closure)
|
||||
{
|
||||
glamor_access_t dst_access;
|
||||
PixmapPtr dst_pixmap, src_pixmap, temp_pixmap;
|
||||
DrawablePtr temp_src = src;
|
||||
glamor_pixmap_private *dst_pixmap_priv, *src_pixmap_priv;
|
||||
BoxRec bound;
|
||||
ScreenPtr screen;
|
||||
int temp_dx = dx;
|
||||
int temp_dy = dy;
|
||||
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
screen = dst_pixmap->drawable.pScreen;
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
|
||||
glamor_fallback("dest pixmap %p has no fbo. \n", dst_pixmap);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
|
||||
goto done;
|
||||
return;
|
||||
|
@ -318,17 +335,50 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
return;
|
||||
}
|
||||
|
||||
if (glamor_copy_n_to_n_textured(src, dst, gc, box, nbox, dx, dy)) {
|
||||
goto done;
|
||||
return;
|
||||
src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
src_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
|
||||
glamor_calculate_boxes_bound(&bound, box, nbox);
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_pixmap_priv)
|
||||
&& ((bound.x2 - bound.x1) * (bound.y2 - bound.y1)
|
||||
* 4 > src_pixmap->drawable.width * src_pixmap->drawable.height)) {
|
||||
|
||||
temp_pixmap = (*screen->CreatePixmap)(screen,
|
||||
bound.x2 - bound.x1,
|
||||
bound.y2 - bound.y1,
|
||||
src_pixmap->drawable.depth,
|
||||
GLAMOR_CREATE_PIXMAP_CPU);
|
||||
if (!temp_src)
|
||||
goto fail;
|
||||
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
|
||||
fbCopyNtoN(src, temp_src, gc, box, nbox,
|
||||
temp_dx + bound.x1, temp_dy + bound.y1,
|
||||
reverse, upsidedown, bitplane,
|
||||
closure);
|
||||
glamor_transform_boxes(box, nbox, bound.x1, bound.y1);
|
||||
temp_dx = -bound.x1;
|
||||
temp_dy = -bound.y1;
|
||||
temp_src = &temp_pixmap->drawable;
|
||||
}
|
||||
|
||||
if (glamor_copy_n_to_n_textured(temp_src, dst, gc, box, nbox, temp_dx, temp_dy)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
fail:
|
||||
glamor_report_delayed_fallbacks(src->pScreen);
|
||||
glamor_report_delayed_fallbacks(dst->pScreen);
|
||||
|
||||
glamor_fallback("from %p to %p (%c,%c)\n", src, dst,
|
||||
glamor_get_drawable_location(src),
|
||||
glamor_get_drawable_location(dst));
|
||||
|
||||
if (gc && gc->alu != GXcopy)
|
||||
dst_access = GLAMOR_ACCESS_RW;
|
||||
else
|
||||
dst_access = GLAMOR_ACCESS_WO;
|
||||
|
||||
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
|
||||
if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
|
||||
fbCopyNtoN(src, dst, gc, box, nbox,
|
||||
|
@ -339,11 +389,13 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
}
|
||||
glamor_finish_access(dst);
|
||||
}
|
||||
return;
|
||||
|
||||
done:
|
||||
glamor_clear_delayed_fallbacks(src->pScreen);
|
||||
glamor_clear_delayed_fallbacks(dst->pScreen);
|
||||
if (temp_src != src) {
|
||||
(*screen->DestroyPixmap)(temp_pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
|
|
|
@ -121,4 +121,42 @@
|
|||
} while(0)
|
||||
|
||||
|
||||
inline static void
|
||||
glamor_calculate_boxes_bound(BoxPtr bound, BoxPtr boxes, int nbox)
|
||||
{
|
||||
int x_min, y_min;
|
||||
int x_max, y_max;
|
||||
int i;
|
||||
x_min = y_min = MAXSHORT;
|
||||
x_max = y_max = MINSHORT;
|
||||
for(i = 0; i < nbox; i++)
|
||||
{
|
||||
if (x_min > boxes[i].x1)
|
||||
x_min = boxes[i].x1;
|
||||
if (y_min > boxes[i].y1)
|
||||
x_min = boxes[i].y1;
|
||||
|
||||
if (x_max < boxes[i].x2)
|
||||
x_max = boxes[i].x2;
|
||||
if (y_max > boxes[i].y2)
|
||||
y_max = boxes[i].y2;
|
||||
}
|
||||
bound->x1 = x_min;
|
||||
bound->y1 = y_min;
|
||||
bound->x2 = x_max;
|
||||
bound->y2 = y_max;
|
||||
}
|
||||
|
||||
inline static void
|
||||
glamor_transform_boxes(BoxPtr boxes, int nbox, int dx, int dy)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nbox; i++)
|
||||
{
|
||||
boxes[i].x1 += dx;
|
||||
boxes[i].y1 += dy;
|
||||
boxes[i].x2 += dx;
|
||||
boxes[i].y2 += dy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user