glamor: Avoid 2D bitblit if possible.
It turns out that the use of fbo blit is one of the root cause which lead to slow drawing, especially slow filling rects. We guess there should be a performance bug in the mesa driver or even in the kernel drm driver. Currently, the only thing glamor can do is to avoid calling those functions. We check whether the copy source and destination has overlapped region, if it has, we have to call fbo blit function. If it has not, we can load the source texture directly and draw it to the target texture. We totally don't need the glCopyPixels here, so remove it. By apply this patch, the rendering time of firefox-planet-gnome decrease to 10.4 seconds. At the same platform, uxa driver get 13 seconds. This is the first time we get better performance than uxa driver. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
5c4d53c512
commit
1f3f3baf14
|
@ -47,15 +47,10 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
|||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||
int dst_x_off, dst_y_off, src_x_off, src_y_off, i;
|
||||
|
||||
if (src == dst) {
|
||||
glamor_delayed_fallback(screen,"src == dest\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GLEW_EXT_framebuffer_blit) {
|
||||
glamor_delayed_fallback(screen,"no EXT_framebuffer_blit\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
|
||||
|
@ -121,78 +116,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
glamor_copy_n_to_n_copypixels(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
GCPtr gc,
|
||||
BoxPtr box,
|
||||
int nbox,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
glamor_screen_private *glamor_priv =
|
||||
glamor_get_screen_private(screen);
|
||||
glamor_pixmap_private *pixmap_priv;
|
||||
int x_off, y_off, i;
|
||||
if (src != dst) {
|
||||
glamor_delayed_fallback(screen, "src != dest\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gc) {
|
||||
if (gc->alu != GXcopy) {
|
||||
glamor_delayed_fallback(screen,"non-copy ALU\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (!glamor_pm_is_solid(dst, gc->planemask)) {
|
||||
glamor_delayed_fallback(screen,"non-solid planemask\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
if (pixmap_priv->pending_op.type == GLAMOR_PENDING_FILL)
|
||||
return TRUE;
|
||||
if (glamor_set_destination_pixmap(dst_pixmap)) {
|
||||
glamor_delayed_fallback(screen, "dst has no fbo.\n");
|
||||
return FALSE;
|
||||
}
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, dst_pixmap->drawable.width,
|
||||
0, dst_pixmap->drawable.height,
|
||||
-1, 1);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &x_off, &y_off);
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
if(glamor_priv->yInverted) {
|
||||
glRasterPos2i(box[i].x1 + x_off,
|
||||
box[i].y1 + y_off);
|
||||
glCopyPixels(box[i].x1 + dx + x_off,
|
||||
box[i].y1 + dy + y_off,
|
||||
box[i].x2 - box[i].x1,
|
||||
box[i].y2 - box[i].y1,
|
||||
GL_COLOR);
|
||||
} else {
|
||||
int flip_y1 = dst_pixmap->drawable.height - box[i].y2 + y_off;
|
||||
glRasterPos2i(box[i].x1 + x_off,
|
||||
flip_y1);
|
||||
glCopyPixels(box[i].x1 + dx + x_off,
|
||||
flip_y1 - dy,
|
||||
box[i].x2 - box[i].x1,
|
||||
box[i].y2 - box[i].y1,
|
||||
GL_COLOR);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
glamor_copy_n_to_n_textured(DrawablePtr src,
|
||||
DrawablePtr dst,
|
||||
|
@ -213,21 +136,17 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
||||
enum glamor_pixmap_status src_status = GLAMOR_NONE;
|
||||
GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale;
|
||||
int flush_needed = 0;
|
||||
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
|
||||
if (src == dst) {
|
||||
glamor_delayed_fallback(dst->pScreen, "same src/dst\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
|
||||
glamor_delayed_fallback(dst->pScreen, "dst has no fbo.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!src_pixmap_priv->gl_tex) {
|
||||
if (!src_pixmap_priv->gl_fbo) {
|
||||
#ifndef GLAMOR_PIXMAP_DYNAMIC_UPLOAD
|
||||
glamor_delayed_fallback(dst->pScreen, "src has no fbo.\n");
|
||||
goto fail;
|
||||
|
@ -237,6 +156,8 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
goto fail;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
flush_needed = 1;
|
||||
|
||||
if (gc) {
|
||||
glamor_set_alu(gc->alu);
|
||||
|
@ -246,7 +167,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
glamor_set_destination_pixmap_priv_nc(src_pixmap_priv);
|
||||
glamor_validate_pixmap(src_pixmap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
|
||||
|
@ -283,6 +203,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
}
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
|
||||
glamor_set_normalize_vcoords(dst_xscale, dst_yscale,
|
||||
box[i].x1 + dst_x_off,
|
||||
box[i].y1 + dst_y_off,
|
||||
|
@ -308,6 +229,9 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
|
|||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
/* The source texture is bound to a fbo, we have to flush it here. */
|
||||
if (flush_needed)
|
||||
glFlush();
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
|
@ -337,8 +261,14 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
ScreenPtr screen;
|
||||
int temp_dx = dx;
|
||||
int temp_dy = dy;
|
||||
int src_x_off, src_y_off, dst_x_off, dst_y_off;
|
||||
int i;
|
||||
int overlaped = 0;
|
||||
|
||||
dst_pixmap = glamor_get_drawable_pixmap(dst);
|
||||
dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap);
|
||||
src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
src_pixmap_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
screen = dst_pixmap->drawable.pScreen;
|
||||
|
||||
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_pixmap_priv)) {
|
||||
|
@ -346,19 +276,29 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
|
||||
glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
|
||||
glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
|
||||
|
||||
if (src_pixmap_priv->fb == dst_pixmap_priv->fb) {
|
||||
int x_shift = abs(src_x_off - dx - dst_x_off);
|
||||
int y_shift = abs(src_y_off - dy - dst_y_off);
|
||||
for ( i = 0; i < nbox; i++)
|
||||
{
|
||||
if (x_shift < abs(box[i].x2 - box[i].x1)
|
||||
&& y_shift < abs(box[i].y2 - box[i].y1)) {
|
||||
overlaped = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* XXX need revisit to handle overlapped area copying. */
|
||||
|
||||
if ( overlaped
|
||||
&& glamor_copy_n_to_n_fbo_blit(src, dst, gc, box, nbox, dx, dy)) {
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
if (glamor_copy_n_to_n_copypixels(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)
|
||||
|
@ -370,7 +310,7 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
bound.y2 - bound.y1,
|
||||
src_pixmap->drawable.depth,
|
||||
GLAMOR_CREATE_PIXMAP_CPU);
|
||||
if (!temp_src)
|
||||
if (!temp_pixmap)
|
||||
goto fail;
|
||||
glamor_transform_boxes(box, nbox, -bound.x1, -bound.y1);
|
||||
temp_src = &temp_pixmap->drawable;
|
||||
|
@ -391,6 +331,7 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
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);
|
||||
|
@ -406,7 +347,8 @@ glamor_copy_n_to_n(DrawablePtr src,
|
|||
dst_access = GLAMOR_ACCESS_WO;
|
||||
|
||||
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
|
||||
if (dst == src || glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
|
||||
if (dst == src
|
||||
|| glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
|
||||
fbCopyNtoN(src, dst, gc, box, nbox,
|
||||
dx, dy, reverse, upsidedown, bitplane,
|
||||
closure);
|
||||
|
@ -428,34 +370,10 @@ RegionPtr
|
|||
glamor_copy_area(DrawablePtr src, DrawablePtr dst, GCPtr gc,
|
||||
int srcx, int srcy, int width, int height, int dstx, int dsty)
|
||||
{
|
||||
#if 0
|
||||
ScreenPtr screen = dst->pScreen;
|
||||
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
|
||||
PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
|
||||
glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
|
||||
#endif
|
||||
RegionPtr region;
|
||||
|
||||
region = miDoCopy(src, dst, gc,
|
||||
srcx, srcy, width, height,
|
||||
dstx, dsty, glamor_copy_n_to_n, 0, NULL);
|
||||
|
||||
return region;
|
||||
|
||||
#if 0
|
||||
fail:
|
||||
glamor_fallback("glamor_copy_area from %p to %p (%c,%c)\n", src, dst,
|
||||
glamor_get_drawable_location(src),
|
||||
glamor_get_drawable_location(dst));
|
||||
region = NULL;
|
||||
if (glamor_prepare_access(dst, GLAMOR_ACCESS_RW)) {
|
||||
if (glamor_prepare_access(src, GLAMOR_ACCESS_RO)) {
|
||||
region = fbCopyArea(src, dst, gc, srcx, srcy, width, height,
|
||||
dstx, dsty);
|
||||
glamor_finish_access(src);
|
||||
}
|
||||
glamor_finish_access(dst);
|
||||
}
|
||||
return region;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user