These use the upload_boxes and download_boxes helpers to provide reasonably efficient image transfer.
Signed-off-by: Keith Packard <[email protected]> --- glamor/Makefile.am | 1 + glamor/glamor.c | 2 +- glamor/glamor_core.c | 2 +- glamor/glamor_image.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++ glamor/glamor_priv.h | 7 +++ 5 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 glamor/glamor_image.c diff --git a/glamor/Makefile.am b/glamor/Makefile.am index 7f756dc..bf2e326 100644 --- a/glamor/Makefile.am +++ b/glamor/Makefile.am @@ -18,6 +18,7 @@ libglamor_la_SOURCES = \ glamor_getspans.c \ glamor_glx.c \ glamor_glyphs.c \ + glamor_image.c \ glamor_polyfillrect.c \ glamor_polylines.c \ glamor_putimage.c \ diff --git a/glamor/glamor.c b/glamor/glamor.c index 3117013..cb509ee 100644 --- a/glamor/glamor.c +++ b/glamor/glamor.c @@ -432,7 +432,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) screen->GetSpans = glamor_getspans; glamor_priv->saved_procs.get_image = screen->GetImage; - screen->GetImage = glamor_get_image; + screen->GetImage = glamor_getimage; glamor_priv->saved_procs.change_window_attributes = screen->ChangeWindowAttributes; diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c index dc316d4..162e47e 100644 --- a/glamor/glamor_core.c +++ b/glamor/glamor_core.c @@ -434,7 +434,7 @@ glamor_fallback_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, D GCOps glamor_gc_ops = { .FillSpans = glamor_fillspans, .SetSpans = glamor_setspans, - .PutImage = glamor_put_image, + .PutImage = glamor_putimage, .CopyArea = glamor_copyarea, .CopyPlane = glamor_copyplane, .PolyPoint = glamor_poly_point, diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c new file mode 100644 index 0000000..ca98f07 --- /dev/null +++ b/glamor/glamor_image.c @@ -0,0 +1,125 @@ +/* + * 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" +#include "glamor_prepare.h" + +/* + * PutImage. Only does ZPixmap right now as other formats are quite a bit harder + */ + +void glamor_putimage(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)) { + fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); + return; + } + + 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_get_context(glamor_priv); + + glamor_upload_region(pixmap, ®ion, x, y, (uint8_t *) bits, byte_stride); + + glamor_put_context(glamor_priv); + + RegionUninit(®ion); + return; +bail: + if (glamor_prep_drawable(drawable, TRUE)) + fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); + glamor_fini_drawable(drawable); +} + +void glamor_getimage(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)) { + fbGetImage(drawable, x, y, w, h, format, plane_mask, d); + return; + } + + 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; +bail: + if (glamor_prep_drawable(drawable, FALSE)) + fbGetImage(drawable, x, y, w, h, format, plane_mask, d); + glamor_fini_drawable(drawable); +} diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index 727a3f6..79b7f01 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -1054,6 +1054,13 @@ void glamor_pushpixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable, int w, int h, int x, int y); +/* glamor_image.c */ +void glamor_putimage(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits); + +void glamor_getimage(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, -- 1.9.0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
