[PATCH 18/21] glamor: Add glamor_transfer based glamor_get_image and glamor_put_image

Keith Packard keithp at keithp.com
Tue Apr 1 17:29:17 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        |   5 +-
 glamor/glamor.c           |   4 -
 glamor/glamor_fill.c      | 361 ----------------------------------------------
 glamor/glamor_getimage.c  |  96 ------------
 glamor/glamor_image.c     | 181 +++++++++++++++++++++++
 glamor/glamor_priv.h      |  51 +++----
 glamor/glamor_putimage.c  | 161 ---------------------
 glamor/glamor_trapezoid.c |   9 +-
 glamor/glamor_utils.c     |  82 +++++++++++
 9 files changed, 289 insertions(+), 661 deletions(-)
 delete mode 100644 glamor/glamor_fill.c
 delete mode 100644 glamor/glamor_getimage.c
 create mode 100644 glamor/glamor_image.c
 delete mode 100644 glamor/glamor_putimage.c
 create mode 100644 glamor/glamor_utils.c

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 9a2b949..61107bd 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -10,13 +10,12 @@ libglamor_la_SOURCES = \
 	glamor_copy.c \
 	glamor_core.c \
 	glamor_debug.h \
-	glamor_fill.c \
 	glamor_font.c \
 	glamor_glx.c \
 	glamor_glyphs.c \
-	glamor_putimage.c \
 	glamor_lines.c \
 	glamor_segs.c \
+	glamor_image.c \
 	glamor_render.c \
 	glamor_gradient.c \
 	glamor_prepare.c \
@@ -32,7 +31,6 @@ libglamor_la_SOURCES = \
 	glamor_tile.c \
 	glamor_triangles.c\
 	glamor_addtraps.c\
-	glamor_getimage.c\
 	glamor_glyphblt.c\
 	glamor_points.c\
 	glamor_priv.h\
@@ -43,6 +41,7 @@ libglamor_la_SOURCES = \
 	glamor_window.c\
 	glamor_fbo.c\
 	glamor_compositerects.c\
+	glamor_utils.c\
 	glamor_utils.h\
 	glamor.h
 
diff --git a/glamor/glamor.c b/glamor/glamor.c
index e9d3f47..1de25d9 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -487,12 +487,10 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 
     glamor_init_vbo(screen);
     glamor_init_pixmap_fbo(screen);
-    glamor_init_solid_shader(screen);
     glamor_init_tile_shader(screen);
 #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);
@@ -521,12 +519,10 @@ glamor_release_screen_priv(ScreenPtr screen)
 #endif
     glamor_fini_vbo(screen);
     glamor_fini_pixmap_fbo(screen);
-    glamor_fini_solid_shader(screen);
     glamor_fini_tile_shader(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_fill.c b/glamor/glamor_fill.c
deleted file mode 100644
index 2fa726e..0000000
--- a/glamor/glamor_fill.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright © 2008 Intel Corporation
- * Copyright © 1998 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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.
- *
- * Authors:
- *    Eric Anholt <eric at anholt.net>
- *    Zhigang Gong <zhigang.gong at linux.intel.com>
- */
-
-#include "glamor_priv.h"
-
-/** @file glamor_fill.c
- *
- * GC fill implementation, based loosely on fb_fill.c
- */
-
-/**
- * Fills the given rectangle of a drawable with the GC's fill style.
- */
-Bool
-glamor_fill(DrawablePtr drawable,
-            GCPtr gc, int x, int y, int width, int height, Bool fallback)
-{
-    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(drawable);
-    int off_x, off_y;
-    PixmapPtr sub_pixmap = NULL;
-    glamor_access_t sub_pixmap_access;
-    DrawablePtr saved_drawable = NULL;
-    int saved_x = x, saved_y = y;
-
-    glamor_get_drawable_deltas(drawable, dst_pixmap, &off_x, &off_y);
-
-    switch (gc->fillStyle) {
-    case FillSolid:
-        if (!glamor_solid(dst_pixmap,
-                          x + off_x,
-                          y + off_y,
-                          width, height, gc->alu, gc->planemask, gc->fgPixel))
-            goto fail;
-        break;
-    case FillStippled:
-    case FillOpaqueStippled:
-        if (!glamor_stipple(dst_pixmap,
-                            gc->stipple,
-                            x + off_x,
-                            y + off_y,
-                            width,
-                            height,
-                            gc->alu,
-                            gc->planemask,
-                            gc->fgPixel,
-                            gc->bgPixel, gc->patOrg.x, gc->patOrg.y))
-            goto fail;
-        break;
-    case FillTiled:
-        if (!glamor_tile(dst_pixmap,
-                         gc->tile.pixmap,
-                         x + off_x,
-                         y + off_y,
-                         width,
-                         height,
-                         gc->alu,
-                         gc->planemask,
-                         x - drawable->x - gc->patOrg.x,
-                         y - drawable->y - gc->patOrg.y))
-            goto fail;
-        break;
-    }
-    return TRUE;
-
- fail:
-    if (!fallback) {
-        if (glamor_ddx_fallback_check_pixmap(&dst_pixmap->drawable)
-            && glamor_ddx_fallback_check_gc(gc))
-            return FALSE;
-    }
-    /* Is it possible to set the access as WO? */
-
-    sub_pixmap_access = GLAMOR_ACCESS_RW;
-
-    sub_pixmap = glamor_get_sub_pixmap(dst_pixmap, x + off_x,
-                                       y + off_y, width, height,
-                                       sub_pixmap_access);
-
-    if (sub_pixmap != NULL) {
-        if (gc->fillStyle != FillSolid) {
-            gc->patOrg.x += (drawable->x - x);
-            gc->patOrg.y += (drawable->y - y);
-        }
-        saved_drawable = drawable;
-        drawable = &sub_pixmap->drawable;
-        saved_x = x;
-        saved_y = y;
-        x = 0;
-        y = 0;
-    }
-    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
-        glamor_prepare_access_gc(gc)) {
-        fbFill(drawable, gc, x, y, width, height);
-    }
-    glamor_finish_access_gc(gc);
-    glamor_finish_access(drawable);
-
-    if (sub_pixmap != NULL) {
-        if (gc->fillStyle != FillSolid) {
-            gc->patOrg.x -= (saved_drawable->x - saved_x);
-            gc->patOrg.y -= (saved_drawable->y - saved_y);
-        }
-
-        x = saved_x;
-        y = saved_y;
-
-        glamor_put_sub_pixmap(sub_pixmap, dst_pixmap,
-                              x + off_x, y + off_y,
-                              width, height, sub_pixmap_access);
-    }
-
-    return TRUE;
-}
-
-void
-glamor_init_solid_shader(ScreenPtr screen)
-{
-    glamor_screen_private *glamor_priv;
-    const char *solid_vs =
-        "attribute vec4 v_position;"
-        "void main()\n"
-        "{\n"
-        "       gl_Position = v_position;\n"
-        "}\n";
-    const char *solid_fs =
-        GLAMOR_DEFAULT_PRECISION
-        "uniform vec4 color;\n"
-        "void main()\n"
-        "{\n"
-        "	gl_FragColor = color;\n"
-        "}\n";
-    GLint fs_prog, vs_prog;
-
-    glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
-    glamor_priv->solid_prog = glCreateProgram();
-    vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
-    fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
-    glAttachShader(glamor_priv->solid_prog, vs_prog);
-    glAttachShader(glamor_priv->solid_prog, fs_prog);
-
-    glBindAttribLocation(glamor_priv->solid_prog,
-                         GLAMOR_VERTEX_POS, "v_position");
-    glamor_link_glsl_prog(screen, glamor_priv->solid_prog, "solid");
-
-    glamor_priv->solid_color_uniform_location =
-        glGetUniformLocation(glamor_priv->solid_prog, "color");
-    glamor_put_context(glamor_priv);
-}
-
-void
-glamor_fini_solid_shader(ScreenPtr screen)
-{
-    glamor_screen_private *glamor_priv;
-
-    glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
-    glDeleteProgram(glamor_priv->solid_prog);
-    glamor_put_context(glamor_priv);
-}
-
-static void
-_glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    GLfloat xscale, yscale;
-    float stack_vertices[32];
-    float *vertices = stack_vertices;
-    int valid_nbox = ARRAY_SIZE(stack_vertices) / (4 * 2);
-
-    glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-
-    glamor_get_context(glamor_priv);
-    glUseProgram(glamor_priv->solid_prog);
-
-    glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
-
-    pixmap_priv_get_dest_scale(pixmap_priv, &xscale, &yscale);
-
-    if (nbox > valid_nbox) {
-        int allocated_nbox;
-        float *new_vertices;
-
-        if (nbox > GLAMOR_COMPOSITE_VBO_VERT_CNT / 6)
-            allocated_nbox = GLAMOR_COMPOSITE_VBO_VERT_CNT / 6;
-        else
-            allocated_nbox = nbox;
-        new_vertices = malloc(allocated_nbox * 4 * 2 * sizeof(float));
-        if (new_vertices) {
-            vertices = new_vertices;
-            valid_nbox = allocated_nbox;
-        }
-    }
-
-    glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
-                          GL_FALSE, 2 * sizeof(float), vertices);
-    glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
-    while (nbox) {
-        int box_cnt, i;
-        float *next_box;
-
-        next_box = vertices;
-        box_cnt = nbox > valid_nbox ? valid_nbox : nbox;
-        for (i = 0; i < box_cnt; i++) {
-            glamor_set_normalize_vcoords(pixmap_priv, xscale, yscale,
-                                         box[i].x1, box[i].y1,
-                                         box[i].x2, box[i].y2,
-                                         glamor_priv->yInverted,
-                                         next_box);
-            next_box += 4 * 2;
-        }
-        if (box_cnt == 1)
-            glDrawArrays(GL_TRIANGLE_FAN, 0, box_cnt * 4);
-        else {
-            if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
-                glDrawRangeElements(GL_TRIANGLES, 0, box_cnt * 4, box_cnt * 6,
-                                    GL_UNSIGNED_SHORT, NULL);
-            } else {
-                glDrawElements(GL_TRIANGLES, box_cnt * 6, GL_UNSIGNED_SHORT,
-                               NULL);
-            }
-        }
-        nbox -= box_cnt;
-        box += box_cnt;
-    }
-
-    if (vertices != stack_vertices)
-        free(vertices);
-
-    glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glamor_put_context(glamor_priv);
-    glamor_priv->state = RENDER_STATE;
-    glamor_priv->render_idle_cnt = 0;
-}
-
-/**
- * Fills the given rectangles of pixmap with an X pixel value.
- *
- * This is a helper used by other code after clipping and translation
- * of coordinates to a glamor backing pixmap.
- */
-Bool
-glamor_solid_boxes(PixmapPtr pixmap,
-                   BoxPtr box, int nbox, unsigned long fg_pixel)
-{
-    glamor_pixmap_private *pixmap_priv;
-    GLfloat color[4];
-
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-        return FALSE;
-
-    glamor_get_rgba_from_pixel(fg_pixel,
-                               &color[0],
-                               &color[1],
-                               &color[2], &color[3], format_for_pixmap(pixmap));
-
-    if (pixmap_priv->type == GLAMOR_TEXTURE_LARGE) {
-        RegionRec region;
-        int n_region;
-        glamor_pixmap_clipped_regions *clipped_regions;
-        int i;
-
-        RegionInitBoxes(&region, box, nbox);
-        clipped_regions =
-            glamor_compute_clipped_regions(pixmap_priv, &region, &n_region, 0,
-                                           0, 0);
-        for (i = 0; i < n_region; i++) {
-            BoxPtr inner_box;
-            int inner_nbox;
-
-            SET_PIXMAP_FBO_CURRENT(pixmap_priv, clipped_regions[i].block_idx);
-
-            inner_box = RegionRects(clipped_regions[i].region);
-            inner_nbox = RegionNumRects(clipped_regions[i].region);
-            _glamor_solid_boxes(pixmap, inner_box, inner_nbox, color);
-            RegionDestroy(clipped_regions[i].region);
-        }
-        free(clipped_regions);
-        RegionUninit(&region);
-    }
-    else
-        _glamor_solid_boxes(pixmap, box, nbox, color);
-
-    return TRUE;
-}
-
-/**
- * Fills a rectangle of a pixmap with an X pixel value.
- *
- * This is a helper used by other glamor code mostly for clearing of
- * buffers to 0.
- */
-Bool
-glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-             unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
-{
-    ScreenPtr screen = pixmap->drawable.pScreen;
-    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_pixmap_private *pixmap_priv;
-    BoxRec box;
-
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-        return FALSE;
-
-    if (!glamor_set_planemask(pixmap, planemask)) {
-        glamor_fallback("Failedto set planemask  in glamor_solid.\n");
-        return FALSE;
-    }
-
-    glamor_get_context(glamor_priv);
-    if (!glamor_set_alu(screen, alu)) {
-        if (alu == GXclear)
-            fg_pixel = 0;
-        else {
-            glamor_fallback("unsupported alu %x\n", alu);
-            glamor_put_context(glamor_priv);
-            return FALSE;
-        }
-    }
-    box.x1 = x;
-    box.y1 = y;
-    box.x2 = x + width;
-    box.y2 = y + height;
-    glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
-
-    glamor_set_alu(screen, GXcopy);
-    glamor_put_context(glamor_priv);
-
-    return TRUE;
-}
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
deleted file mode 100644
index a932473..0000000
--- 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 at 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 0000000..d73201e
--- /dev/null
+++ b/glamor/glamor_image.c
@@ -0,0 +1,181 @@
+/*
+ * 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
+ */
+
+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(&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 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))
+        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))
+        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 a72a74f..2c0becd 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -216,10 +216,6 @@ typedef struct glamor_screen_private {
         fbo_cache[CACHE_FORMAT_COUNT][CACHE_BUCKET_WCOUNT][CACHE_BUCKET_HCOUNT];
     unsigned long fbo_cache_watermark;
 
-    /* glamor_solid */
-    GLint solid_prog;
-    GLint solid_color_uniform_location;
-
     /* glamor point shader */
     glamor_program point_prog;
 
@@ -286,11 +282,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;
@@ -674,18 +665,6 @@ Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask);
 Bool glamor_change_window_attributes(WindowPtr pWin, unsigned long mask);
 RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap);
 
-/* glamor_fill.c */
-Bool glamor_fill(DrawablePtr drawable,
-                 GCPtr gc, int x, int y, int width, int height, Bool fallback);
-Bool glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
-                  unsigned char alu, unsigned long planemask,
-                  unsigned long fg_pixel);
-Bool glamor_solid_boxes(PixmapPtr pixmap,
-                        BoxPtr box, int nbox, unsigned long fg_pixel);
-
-void glamor_init_solid_shader(ScreenPtr screen);
-void glamor_fini_solid_shader(ScreenPtr screen);
-
 /* glamor_glyphs.c */
 Bool glamor_realize_glyph_caches(ScreenPtr screen);
 void glamor_glyphs_fini(ScreenPtr screen);
@@ -696,12 +675,6 @@ void glamor_glyphs(CARD8 op,
                    INT16 xSrc,
                    INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs);
 
-/* 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,
@@ -939,9 +912,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);
 
@@ -1013,6 +983,15 @@ glamor_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 void
 glamor_copy_window(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
 
+/* 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,
@@ -1036,6 +1015,18 @@ void glamor_composite_rectangles(CARD8 op,
 extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
                                              struct glamor_context *glamor_ctx);
 
+/* glamor_util.c */
+
+void
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+             unsigned char alu, unsigned long planemask,
+             unsigned long fg_pixel);
+
+void
+glamor_solid_boxes(PixmapPtr pixmap,
+                   BoxPtr box, int nbox, unsigned long fg_pixel);
+
+
 /* glamor_xv */
 typedef struct {
     uint32_t transform_index;
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
deleted file mode 100644
index cf7197b..0000000
--- 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 at anholt.net>
- *    Zhigang Gong <zhigang.gong at 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);
-}
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index c76b8bb..1c8eddd 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -1399,12 +1399,9 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
     }
 
     /* First, clear all to zero */
-    if (!glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
-                      pixmap_priv->base.pixmap->drawable.height,
-                      GXclear, 0xFFFFFFFF, 0)) {
-        DEBUGF("glamor_solid failed, fallback\n");
-        return FALSE;
-    }
+    glamor_solid(pixmap, 0, 0, pixmap_priv->base.pixmap->drawable.width,
+                 pixmap_priv->base.pixmap->drawable.height,
+                 GXclear, 0xFFFFFFFF, 0);
 
     glamor_get_context(glamor_priv);
 
diff --git a/glamor/glamor_utils.c b/glamor/glamor_utils.c
new file mode 100644
index 0000000..5459d79
--- /dev/null
+++ b/glamor/glamor_utils.c
@@ -0,0 +1,82 @@
+/*
+ * 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"
+
+void
+glamor_solid_boxes(PixmapPtr pixmap,
+                   BoxPtr box, int nbox, unsigned long fg_pixel)
+{
+    DrawablePtr drawable = &pixmap->drawable;
+    GCPtr gc;
+    xRectangle *rect;
+    int n;
+
+    rect = malloc(nbox * sizeof (xRectangle));
+    if (!rect)
+        return;
+    for (n = 0; n < nbox; n++) {
+        rect[n].x = box[n].x1;
+        rect[n].y = box[n].y1;
+        rect[n].width = box[n].x2 - box[n].x1;
+        rect[n].height = box[n].y2 - box[n].y1;
+    }
+
+    gc = GetScratchGC(drawable->depth, drawable->pScreen);
+    if (gc) {
+        ChangeGCVal vals[1];
+
+        vals[0].val = fg_pixel;
+        ChangeGC(NullClient, gc, GCForeground, vals);
+        ValidateGC(drawable, gc);
+        gc->ops->PolyFillRect(drawable, gc, nbox, rect);
+        FreeScratchGC(gc);
+    }
+    free(rect);
+}
+
+void
+glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
+             unsigned char alu, unsigned long planemask,
+             unsigned long fg_pixel)
+{
+    DrawablePtr drawable = &pixmap->drawable;
+    GCPtr gc;
+    ChangeGCVal vals[3];
+    xRectangle rect;
+
+    vals[0].val = alu;
+    vals[1].val = planemask;
+    vals[2].val = fg_pixel;
+    gc = GetScratchGC(drawable->depth, drawable->pScreen);
+    if (!gc)
+        return;
+    ChangeGC(NullClient, gc, GCFunction|GCPlaneMask|GCForeground, vals);
+    ValidateGC(drawable, gc);
+    rect.x = x;
+    rect.y = y;
+    rect.width = width;
+    rect.height = height;
+    gc->ops->PolyFillRect(drawable, gc, 1, &rect);
+    FreeScratchGC(gc);
+}
+
-- 
1.9.0




More information about the xorg-devel mailing list