diff options
author | Keith Packard <keithp@keithp.com> | 2014-03-16 20:44:48 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2014-04-23 10:36:18 -0700 |
commit | 5062b4fadd977d044e54b53b7f3e02e466eac9a9 (patch) | |
tree | dff08cea6996d695e4a582da203b424bb4b23b12 /glamor | |
parent | 747160016ba2d0cd42ad6b174cbf927d67c01875 (diff) |
glamor: Add glamor_transfer based glamor_get_image and glamor_put_image
These use the upload_boxes and download_boxes helpers to provide
reasonably efficient image transfer.
Fixes segfaults in Xephyr with x11perf -reps 1.
Performance improvements:
Improves -putimage10 by 548.218% +/- 88.601% (n=10).
Improves -putimage500 by 3.71014% +/- 1.5049% (n=10).
Improves -getimage10 by 8.37004% +/- 4.58274% (n=10).
No statistically significant difference on -getimage500 (n=10).
v2: Fix rebase failures, don't forget to check/prepare the gc in
putimage fallbacks (changes by anholt).
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'glamor')
-rw-r--r-- | glamor/Makefile.am | 3 | ||||
-rw-r--r-- | glamor/glamor.c | 2 | ||||
-rw-r--r-- | glamor/glamor_getimage.c | 96 | ||||
-rw-r--r-- | glamor/glamor_image.c | 180 | ||||
-rw-r--r-- | glamor/glamor_priv.h | 23 | ||||
-rw-r--r-- | glamor/glamor_putimage.c | 161 |
6 files changed, 190 insertions, 275 deletions
diff --git a/glamor/Makefile.am b/glamor/Makefile.am index b7069e012..bde58b632 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -17,8 +17,8 @@ libglamor_la_SOURCES = \ glamor_glx.c \ glamor_glyphs.c \ glamor_polylines.c \ - glamor_putimage.c \ glamor_segment.c \ + glamor_image.c \ glamor_render.c \ glamor_gradient.c \ glamor_program.c \ @@ -34,7 +34,6 @@ libglamor_la_SOURCES = \ glamor_tile.c \ glamor_triangles.c\ glamor_addtraps.c\ - glamor_getimage.c\ glamor_copyplane.c\ glamor_glyphblt.c\ glamor_points.c\ diff --git a/glamor/glamor.c b/glamor/glamor.c index 29f887482..994e92358 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -507,7 +507,6 @@ glamor_init(ScreenPtr screen, unsigned int flags) #ifdef GLAMOR_TRAPEZOID_SHADER glamor_init_trapezoid_shader(screen); #endif - glamor_init_putimage_shaders(screen); glamor_init_finish_access_shaders(screen); #ifdef GLAMOR_GRADIENT_SHADER glamor_init_gradient_shader(screen); @@ -541,7 +540,6 @@ glamor_release_screen_priv(ScreenPtr screen) #ifdef GLAMOR_TRAPEZOID_SHADER glamor_fini_trapezoid_shader(screen); #endif - glamor_fini_putimage_shaders(screen); glamor_fini_finish_access_shaders(screen); #ifdef GLAMOR_GRADIENT_SHADER glamor_fini_gradient_shader(screen); diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c deleted file mode 100644 index a932473e8..000000000 --- a/glamor/glamor_getimage.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * Copyright © 1998 Keith Packard - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Zhigang Gong <zhigang.gong@gmail.com> - * - */ - -#include "glamor_priv.h" - -static Bool -_glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d, - Bool fallback) -{ - PixmapPtr pixmap, sub_pixmap; - struct glamor_pixmap_private *pixmap_priv; - int x_off, y_off; - int stride; - void *data; - - pixmap = glamor_get_drawable_pixmap(drawable); - glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - - if (format != ZPixmap) - goto fall_back; - - if (!glamor_set_planemask(pixmap, planeMask)) { - glamor_fallback("Failedto set planemask in glamor_solid.\n"); - goto fall_back; - } - pixmap_priv = glamor_get_pixmap_private(pixmap); - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) - goto fall_back; - stride = PixmapBytePad(w, drawable->depth); - - x += drawable->x + x_off; - y += drawable->y + y_off; - - data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride, - d, 0, GLAMOR_ACCESS_RO); - if (data != NULL) { - assert(data == d); - return TRUE; - } - fall_back: - sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, - y + y_off + drawable->y, w, h, - GLAMOR_ACCESS_RO); - if (sub_pixmap) { - fbGetImage(&sub_pixmap->drawable, 0, 0, w, h, format, planeMask, d); - glamor_put_sub_pixmap(sub_pixmap, pixmap, - x + x_off + drawable->x, - y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RO); - } - else - miGetImage(drawable, x, y, w, h, format, planeMask, d); - - return TRUE; -} - -void -glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d) -{ - _glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE); -} - -Bool -glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d) -{ - return _glamor_get_image(pDrawable, x, y, w, - h, format, planeMask, d, FALSE); -} diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c new file mode 100644 index 000000000..4791d089f --- /dev/null +++ b/glamor/glamor_image.c @@ -0,0 +1,180 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "glamor_priv.h" +#include "glamor_transfer.h" +#include "glamor_transform.h" + +/* + * PutImage. Only does ZPixmap right now as other formats are quite a bit harder + */ + +static Bool +glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + uint32_t byte_stride = PixmapBytePad(w, drawable->depth); + RegionRec region; + BoxRec box; + int off_x, off_y; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + return FALSE; + + if (gc->alu != GXcopy) + goto bail; + + if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask)) + goto bail; + + if (format == XYPixmap && drawable->depth == 1 && leftPad == 0) + format = ZPixmap; + + if (format != ZPixmap) + goto bail; + + x += drawable->x; + y += drawable->y; + box.x1 = x; + box.y1 = y; + box.x2 = box.x1 + w; + box.y2 = box.y1 + h; + RegionInit(®ion, &box, 1); + RegionIntersect(®ion, ®ion, gc->pCompositeClip); + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + if (off_x || off_y) { + x += off_x; + y += off_y; + RegionTranslate(®ion, off_x, off_y); + } + + glamor_make_current(glamor_priv); + + glamor_upload_region(pixmap, ®ion, x, y, (uint8_t *) bits, byte_stride); + + RegionUninit(®ion); + return TRUE; +bail: + return FALSE; +} + +static void +glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && + glamor_prepare_access_gc(gc)) + fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); + glamor_finish_access(drawable); +} + +void +glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ + if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits)) + return; + glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits); +} + +Bool +glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ + if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits)) + return TRUE; + if (glamor_ddx_fallback_check_pixmap(drawable) && + glamor_ddx_fallback_check_gc(gc)) + return FALSE; + glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits); + return TRUE; +} + +static Bool +glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h, + unsigned int format, unsigned long plane_mask, char *d) +{ + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv; + uint32_t byte_stride = PixmapBytePad(w, drawable->depth); + BoxRec box; + int off_x, off_y; + + pixmap_priv = glamor_get_pixmap_private(pixmap); + if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) + goto bail; + + if (format != ZPixmap || !glamor_pm_is_solid(drawable, plane_mask)) + goto bail; + + glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); + box.x1 = x; + box.x2 = x + w; + box.y1 = y; + box.y2 = y + h; + glamor_download_boxes(pixmap, &box, 1, + drawable->x + off_x, drawable->y + off_y, + -x, -y, + (uint8_t *) d, byte_stride); + return TRUE; +bail: + return FALSE; +} + +static void +glamor_get_image_bail(DrawablePtr drawable, int x, int y, int w, int h, + unsigned int format, unsigned long plane_mask, char *d) +{ + if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO)) + fbGetImage(drawable, x, y, w, h, format, plane_mask, d); + glamor_finish_access(drawable); +} + +void +glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, + unsigned int format, unsigned long plane_mask, char *d) +{ + if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d)) + return; + glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d); +} + +Bool +glamor_get_image_nf(DrawablePtr drawable, int x, int y, int w, int h, + unsigned int format, unsigned long plane_mask, char *d) +{ + if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d)) + return TRUE; + + if (glamor_ddx_fallback_check_pixmap(drawable)) + return FALSE; + + glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d); + return TRUE; +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 0cafac4b5..a2a21fca0 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -277,11 +277,6 @@ typedef struct glamor_screen_private { /* glamor trapezoid shader. */ GLint trapezoid_prog; - /* glamor_putimage */ - GLint put_image_xybitmap_prog; - GLint put_image_xybitmap_fg_uniform_location; - GLint put_image_xybitmap_bg_uniform_location; - PixmapPtr *back_pixmap; int screen_fbo; struct glamor_saved_procs saved_procs; @@ -704,12 +699,6 @@ void glamor_glyphs(CARD8 op, void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr points); -/* glamor_putimage.c */ -void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int leftPad, int format, char *bits); -void glamor_init_putimage_shaders(ScreenPtr screen); -void glamor_fini_putimage_shaders(ScreenPtr screen); - /* glamor_render.c */ Bool glamor_composite_clipped_region(CARD8 op, PicturePtr source, @@ -951,9 +940,6 @@ Bool glamor_fixup_pixmap_priv(ScreenPtr screen, void glamor_picture_format_fixup(PicturePtr picture, glamor_pixmap_private *pixmap_priv); -void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d); - void glamor_add_traps(PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntrap, xTrap *traps); @@ -994,6 +980,15 @@ void glamor_poly_fill_rect(DrawablePtr drawable, GCPtr gc, int nrect, xRectangle *prect); +/* glamor_image.c */ +void +glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits); + +void +glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, char *d); + /* glamor_glyphblt.c */ void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c deleted file mode 100644 index cf7197bfc..000000000 --- a/glamor/glamor_putimage.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Zhigang Gong <zhigang.gong@linux.intel.com> - * - */ - -/** @file glamor_putaimge.c - * - * XPutImage implementation - */ -#include "glamor_priv.h" - -void -glamor_init_putimage_shaders(ScreenPtr screen) -{ -} - -void -glamor_fini_putimage_shaders(ScreenPtr screen) -{ -} - -static Bool -_glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, int image_format, char *bits, - Bool fallback) -{ - PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); - glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - RegionPtr clip; - int x_off, y_off; - Bool ret = FALSE; - PixmapPtr temp_pixmap, sub_pixmap; - glamor_pixmap_private *temp_pixmap_priv; - BoxRec box; - - glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); - clip = fbGetCompositeClip(gc); - if (image_format == XYBitmap) { - assert(depth == 1); - goto fail; - } - - if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { - glamor_fallback("has no fbo.\n"); - goto fail; - } - - if (image_format != ZPixmap) { - glamor_fallback("non-ZPixmap\n"); - goto fail; - } - - if (!glamor_set_planemask(pixmap, gc->planemask)) { - goto fail; - } - /* create a temporary pixmap and upload the bits to that - * pixmap, then apply clip copy it to the destination pixmap.*/ - box.x1 = x + drawable->x; - box.y1 = y + drawable->y; - box.x2 = x + w + drawable->x; - box.y2 = y + h + drawable->y; - - if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN) - || gc->alu != GXcopy) { - temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0); - if (temp_pixmap == NULL) - goto fail; - - temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); - - if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) { - temp_pixmap_priv->base.picture = pixmap_priv->base.picture; - temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture; - } - - glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h, - pixmap->devKind, bits, 0); - - glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, - y); - glamor_destroy_pixmap(temp_pixmap); - } - else - glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, - y + drawable->y + y_off, w, h, - PixmapBytePad(w, depth), bits, 0); - ret = TRUE; - goto done; - - fail: - glamor_set_planemask(pixmap, ~0); - - if (!fallback && glamor_ddx_fallback_check_pixmap(&pixmap->drawable)) - goto done; - - glamor_fallback("to %p (%c)\n", - drawable, glamor_get_drawable_location(drawable)); - - sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, - y + y_off + drawable->y, w, h, - GLAMOR_ACCESS_RW); - if (sub_pixmap) { - if (clip != NULL) - pixman_region_translate(clip, -x - drawable->x, -y - drawable->y); - - fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h, - left_pad, image_format, bits); - - glamor_put_sub_pixmap(sub_pixmap, pixmap, - x + x_off + drawable->x, - y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW); - if (clip != NULL) - pixman_region_translate(clip, x + drawable->x, y + drawable->y); - } - else - fbPutImage(drawable, gc, depth, x, y, w, h, - left_pad, image_format, bits); - ret = TRUE; - - done: - return ret; -} - -void -glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, int image_format, char *bits) -{ - _glamor_put_image(drawable, gc, depth, x, y, w, h, - left_pad, image_format, bits, TRUE); -} - -Bool -glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, - int w, int h, int left_pad, int image_format, char *bits) -{ - return _glamor_put_image(drawable, gc, depth, x, y, w, h, - left_pad, image_format, bits, FALSE); -} |