glamor_getimage: Add the optimization path of getImage.

This optimization will only call glReadPixels once. It should get
some performance gain. But it seems it even get worse performance
at SNB, disable it by default.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
Zhigang Gong 2012-01-09 05:03:08 +08:00 committed by Eric Anholt
parent 96085017c8
commit 42a0261cb3

View File

@ -34,11 +34,88 @@
static Bool
_glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
_glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d,
Bool fallback)
{
miGetImage(pDrawable, x, y, w, h, format, planeMask, d);
PixmapPtr pixmap;
struct glamor_pixmap_private *pixmap_priv;
struct glamor_screen_private *glamor_priv;
int x_off, y_off;
GLenum tex_format, tex_type;
int no_alpha, no_revert;
PixmapPtr temp_pixmap = NULL;
glamor_gl_dispatch * dispatch;
goto fall_back;
if (format != ZPixmap)
goto fall_back;
pixmap = glamor_get_drawable_pixmap(drawable);
if (!glamor_set_planemask(pixmap, planeMask)) {
glamor_fallback
("Failedto set planemask in glamor_solid.\n");
goto fall_back;
}
glamor_priv = glamor_get_screen_private(drawable->pScreen);
pixmap_priv = glamor_get_pixmap_private(pixmap);
dispatch = &glamor_priv->dispatch;
if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
goto fall_back;
glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
if (glamor_get_tex_format_type_from_pixmap(pixmap,
&tex_format,
&tex_type,
&no_alpha,
&no_revert)) {
glamor_fallback("unknown depth. %d \n", drawable->depth);
goto fall_back;
}
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_validate_pixmap(pixmap);
if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) {
/* XXX prepare whole pixmap is not efficient. */
temp_pixmap =
glamor_es2_pixmap_read_prepare(pixmap, &tex_format,
&tex_type, no_alpha,
no_revert);
pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
}
int row_length = PixmapBytePad(w, drawable->depth);
row_length = (row_length * 8) / drawable->bitsPerPixel;
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 1);
dispatch->glPixelStorei(GL_PACK_ROW_LENGTH, row_length);
} else {
dispatch->glPixelStorei(GL_PACK_ALIGNMENT, 4);
}
if (glamor_priv->yInverted)
dispatch->glReadPixels(x + x_off,
y + y_off,
w, h,
tex_format,
tex_type, d);
else
dispatch->glReadPixels(x + x_off,
pixmap->drawable.height - 1 - (y + y_off),
w,
h,
tex_format,
tex_type, d);
if (temp_pixmap)
glamor_destroy_pixmap(temp_pixmap);
return TRUE;
fall_back:
miGetImage(drawable, x, y, w, h, format, planeMask, d);
return TRUE;
}