From 42a0261cb3065200887f81816b1bc3850593da4c Mon Sep 17 00:00:00 2001 From: Zhigang Gong Date: Mon, 9 Jan 2012 05:03:08 +0800 Subject: [PATCH] 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 --- glamor/glamor_getimage.c | 81 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c index 7a9280b43..086ec4b6d 100644 --- a/glamor/glamor_getimage.c +++ b/glamor/glamor_getimage.c @@ -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; }