[PATCH 17/20] glamor: Add glamor_getimage and glamor_putimage

Keith Packard keithp at keithp.com
Tue Mar 18 22:09:51 PDT 2014


These use the upload_boxes and download_boxes helpers to provide
reasonably efficient image transfer.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 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(&region, &box, 1);
+    RegionIntersect(&region, &region, gc->pCompositeClip);
+
+    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+    if (off_x || off_y) {
+        x += off_x;
+        y += off_y;
+        RegionTranslate(&region, off_x, off_y);
+    }
+
+    glamor_get_context(glamor_priv);
+
+    glamor_upload_region(pixmap, &region, x, y, (uint8_t *) bits, byte_stride);
+
+    glamor_put_context(glamor_priv);
+
+    RegionUninit(&region);
+    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



More information about the xorg-devel mailing list