[PATCH 13/20] glamor: Add glamor_program based copy acceleration

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


Uses glCopyPixels for self-copies, otherwise paints with textures.
Performs CPU to GPU transfers for pixmaps in memory.
Accelerates copy plane when both objects are in memory
Includes copy_window acceleration too.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 glamor/Makefile.am      |   1 +
 glamor/glamor.c         |   2 +-
 glamor/glamor_copy.c    | 510 ++++++++++++++++++++++++++++++++++++++++++++++++
 glamor/glamor_core.c    |   4 +-
 glamor/glamor_priv.h    |  30 +++
 glamor/glamor_program.c |  10 +-
 glamor/glamor_program.h |   3 +
 7 files changed, 556 insertions(+), 4 deletions(-)
 create mode 100644 glamor/glamor_copy.c

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index f859155..7f756dc 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -7,6 +7,7 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
 libglamor_la_SOURCES = \
 	glamor.c \
 	glamor_context.h \
+	glamor_copy.c \
 	glamor_copyarea.c \
 	glamor_copywindow.c \
 	glamor_core.c \
diff --git a/glamor/glamor.c b/glamor/glamor.c
index dd18386..3117013 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -439,7 +439,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
         screen->ChangeWindowAttributes = glamor_change_window_attributes;
 
         glamor_priv->saved_procs.copy_window = screen->CopyWindow;
-        screen->CopyWindow = glamor_copy_window;
+        screen->CopyWindow = glamor_copywindow;
 
         glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
         screen->BitmapToRegion = glamor_bitmap_to_region;
diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c
new file mode 100644
index 0000000..a26c4a7
--- /dev/null
+++ b/glamor/glamor_copy.c
@@ -0,0 +1,510 @@
+/*
+ * 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_prepare.h"
+#include "glamor_transform.h"
+
+struct copy_args {
+    PixmapPtr           src_pixmap;
+    glamor_pixmap_fbo   *src;
+    uint32_t            bitplane;
+    int                 dx, dy;
+};
+
+static Bool
+use_copyarea(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
+{
+    struct copy_args *args = arg;
+    glamor_pixmap_fbo *src = args->src;
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, src->tex);
+
+    glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
+    glUniform2f(prog->fill_size_uniform, src->width, src->height);
+
+    return TRUE;
+}
+
+static const glamor_facet glamor_facet_copyarea = {
+    "copy_area",
+    .version = 130,
+    .vs_vars = "attribute vec4 primitive;\n",
+    .vs_exec = ("       vec2 pos = (primitive.zw - primitive.xy) * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+                GLAMOR_POS(gl_Position, (primitive.xy + pos))
+                "       fill_pos = fill_offset + primitive.xy + pos;\n"),
+    .fs_exec = "       gl_FragColor = texelFetch(sampler, ivec2(fill_pos), 0);\n",
+    .locations = glamor_program_location_fill,
+    .use = use_copyarea,
+};
+
+static Bool
+use_copyplane(PixmapPtr dst, GCPtr gc, glamor_program *prog, void *arg)
+{
+    struct copy_args *args = arg;
+    glamor_pixmap_fbo *src = args->src;
+
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, src->tex);
+
+    glUniform2f(prog->fill_offset_uniform, args->dx, args->dy);
+    glUniform2f(prog->fill_size_uniform, src->width, src->height);
+
+    glamor_set_color(dst, gc->fgPixel, prog->fg_uniform);
+    glamor_set_color(dst, gc->bgPixel, prog->bg_uniform);
+
+    /* XXX handle 2 10 10 10 and 1555 formats; presumably the pixmap private knows this? */
+    switch (args->src_pixmap->drawable.depth) {
+    case 24:
+        glUniform4ui(prog->bitplane_uniform,
+                     (args->bitplane >> 16) & 0xff,
+                     (args->bitplane >>  8) & 0xff,
+                     (args->bitplane      ) & 0xff,
+                     0);
+
+        glUniform4ui(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0);
+        break;
+    case 32:
+        glUniform4ui(prog->bitplane_uniform,
+                     (args->bitplane >> 16) & 0xff,
+                     (args->bitplane >>  8) & 0xff,
+                     (args->bitplane      ) & 0xff,
+                     (args->bitplane >> 24) & 0xff);
+
+        glUniform4ui(prog->bitmul_uniform, 0xff, 0xff, 0xff, 0xff);
+        break;
+    case 16:
+        glUniform4ui(prog->bitplane_uniform,
+                     (args->bitplane >> 11) & 0x1f,
+                     (args->bitplane >>  5) & 0x3f,
+                     (args->bitplane      ) & 0x1f,
+                     0);
+
+        glUniform4ui(prog->bitmul_uniform, 0x1f, 0x3f, 0x1f, 0);
+        break;
+    case 15:
+        glUniform4ui(prog->bitplane_uniform,
+                     (args->bitplane >> 10) & 0x1f,
+                     (args->bitplane >>  5) & 0x1f,
+                     (args->bitplane      ) & 0x1f,
+                     0);
+
+        glUniform4ui(prog->bitmul_uniform, 0x1f, 0x1f, 0x1f, 0);
+        break;
+    case 8:
+        glUniform4ui(prog->bitplane_uniform,
+                     0, 0, 0, args->bitplane);
+        glUniform4ui(prog->bitmul_uniform, 0, 0, 0, 0xff);
+        break;
+    case 1:
+        glUniform4ui(prog->bitplane_uniform,
+                     0, 0, 0, args->bitplane);
+        glUniform4ui(prog->bitmul_uniform, 0, 0, 0, 0xff);
+        break;
+    }
+
+    return TRUE;
+}
+
+static const glamor_facet glamor_facet_copyplane = {
+    "copy_plane",
+    .version = 130,
+    .vs_vars = "attribute vec4 primitive;\n",
+    .vs_exec = ("       vec2 pos = (primitive.zw - primitive.xy) * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n"
+                GLAMOR_POS(gl_Position, (primitive.xy + pos))
+                "       fill_pos = fill_offset + primitive.xy + pos;\n"),
+    .fs_exec = ("       uvec4 bits = uvec4(texelFetch(sampler, ivec2(fill_pos), 0) * bitmul + vec4(0.5,0.5,0.5,0.5));\n"
+                "       if ((bits & bitplane) != uvec4(0,0,0,0))\n"
+                "               gl_FragColor = fg;\n"
+                "       else\n"
+                "               gl_FragColor = bg;\n"),
+    .locations = glamor_program_location_fill|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
+    .use = use_copyplane,
+};
+
+static void
+glamor_copy_bail(DrawablePtr src,
+                 DrawablePtr dst,
+                 GCPtr gc,
+                 BoxPtr box,
+                 int nbox,
+                 int dx,
+                 int dy,
+                 Bool reverse,
+                 Bool upsidedown,
+                 Pixel bitplane,
+                 void *closure)
+{
+    if (glamor_prep_drawable(dst, TRUE) && glamor_prep_drawable(src, FALSE)) {
+        if (bitplane) {
+            if (src->bitsPerPixel > 1)
+                fbCopyNto1(src, dst, gc, box, nbox, dx, dy,
+                           reverse, upsidedown, bitplane, closure);
+            else
+                fbCopy1toN(src, dst, gc, box, nbox, dx, dy,
+                           reverse, upsidedown, bitplane, closure);
+        } else {
+            fbCopyNtoN(src, dst, gc, box, nbox, dx, dy,
+                       reverse, upsidedown, bitplane, closure);
+        }
+    }
+    glamor_fini_drawable(dst);
+    glamor_fini_drawable(src);
+}
+
+static void
+glamor_copy_cpu_fbo(DrawablePtr src,
+                    DrawablePtr dst,
+                    GCPtr gc,
+                    BoxPtr box,
+                    int nbox,
+                    int dx,
+                    int dy,
+                    Bool reverse,
+                    Bool upsidedown,
+                    Pixel bitplane,
+                    void *closure)
+{
+    ScreenPtr screen = dst->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
+    FbBits *src_bits;
+    FbStride src_stride;
+    int src_bpp;
+    int src_xoff, src_yoff;
+    int dst_xoff, dst_yoff;
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv))
+        goto bail;
+
+    if (gc && gc->alu != GXcopy)
+        goto bail;
+
+    if (gc && !glamor_pm_is_solid(dst, gc->planemask))
+        goto bail;
+
+    glamor_get_context(glamor_priv);
+    glamor_prep_drawable(src, FALSE);
+
+    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff);
+
+    fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff);
+
+    glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy,
+                        dst->x + dst_xoff, dst->y + dst_yoff,
+                        (uint8_t *) src_bits, src_stride * sizeof (FbBits));
+    glamor_fini_drawable(src);
+    glamor_put_context(glamor_priv);
+
+    return;
+
+bail:
+    glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
+}
+
+static void
+glamor_copy_fbo_fbo(DrawablePtr src,
+                    DrawablePtr dst,
+                    GCPtr gc,
+                    BoxPtr box,
+                    int nbox,
+                    int dx,
+                    int dy,
+                    Bool reverse,
+                    Bool upsidedown,
+                    Pixel bitplane,
+                    void *closure)
+{
+    ScreenPtr screen = dst->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
+    glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
+    int src_box_x, src_box_y, dst_box_x, dst_box_y;
+    int b;
+    Bool use_copy_pixels = FALSE;
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv) || !GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv))
+        goto bail;
+
+    glamor_get_context(glamor_priv);
+
+    if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask))
+        goto bail_ctx;
+
+    if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy))
+        goto bail_ctx;
+
+    if (src_pixmap == dst_pixmap) {
+        if (bitplane)
+            goto bail_ctx;
+        use_copy_pixels = TRUE;
+    }
+
+    if (use_copy_pixels) {
+        static float modelview[16] = {
+            1, 0, 0, 0,
+            0, 1, 0, 0,
+            0, 0, 1, 0,
+            -1, -1, 0, 1,
+        };
+
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
+
+        glamor_pixmap_loop(src_priv, src_box_x, src_box_y) {
+            BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y);
+            glBindFramebuffer(GL_READ_FRAMEBUFFER, glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y)->fb);
+
+            glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) {
+                BoxPtr dst_box = glamor_pixmap_box_at(dst_priv, dst_box_x, dst_box_y);
+
+                glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glamor_pixmap_fbo_at(dst_priv, dst_box_x, dst_box_y)->fb);
+                glViewport(0, 0, dst_box->x2 - dst_box->x1, dst_box->y2 - dst_box->y1);
+
+                glMatrixMode(GL_MODELVIEW);
+
+                modelview[0] = 2.0f / (dst_box->x2 - dst_box->x1);
+                modelview[5] = 2.0f / (dst_box->y2 - dst_box->y1);
+
+                glLoadMatrixf(modelview);
+
+                for (b = 0; b < nbox; b++) {
+                    int     dx1, dx2, dy1, dy2;
+
+                    dx1 = box[b].x1;
+                    dx2 = box[b].x2;
+
+                    dy1 = box[b].y1;
+                    dy2 = box[b].y2;
+
+                    /* clip to the destination box */
+                    if (dx1 < dst_box->x1)
+                        dx1 = dst_box->x1;
+                    if (dst_box->x2 < dx2)
+                        dx2 = dst_box->x2;
+
+                    if (dy1 < dst_box->y1)
+                        dy1 = dst_box->y1;
+                    if (dst_box->y2 < dy2)
+                        dy2 = dst_box->y2;
+
+                    /* clip to the source box */
+
+                    if (dx1 < src_box->x1 - dx)
+                        dx1 = src_box->x1 - dx;
+                    if (src_box->x2 - dx < dx2)
+                        dx2 = src_box->x2 - dx;
+
+                    if (dy1 < src_box->y1 - dy)
+                        dy1 = src_box->y1 - dy;
+                    if (src_box->y2 - dy < dy2)
+                        dy2 = src_box->y2 - dy;
+
+                    if (dx1 >= dx2)
+                        continue;
+                    if (dy1 >= dy2)
+                        continue;
+
+
+                    glRasterPos2i(dx1 - dst_box->x1, dy1 - dst_box->y1);
+                    glCopyPixels (dx1 + dx - src_box->x1,
+                                  dy1 + dy - src_box->y1,
+                                  dx2 - dx1, dy2 - dy1, GL_COLOR);
+                }
+            }
+        }
+    } else {
+
+        int dst_off_x, dst_off_y;
+        int src_off_x, src_off_y;
+        GLshort *v;
+        char *vbo_offset;
+        struct copy_args args;
+        glamor_program *prog;
+        const glamor_facet *copy_facet;
+        Bool set_scissor;
+
+        if (bitplane) {
+            prog = &glamor_priv->copy_plane_prog;
+            copy_facet = &glamor_facet_copyplane;
+        } else {
+            prog = &glamor_priv->copy_area_prog;
+            copy_facet = &glamor_facet_copyarea;
+        }
+
+        if (prog->failed)
+            goto bail_ctx;
+
+        if (!prog->prog) {
+            if (!glamor_build_program(screen, prog,
+                                      copy_facet, NULL))
+                goto bail_ctx;
+        }
+
+        args.src_pixmap = src_pixmap;
+        args.bitplane = bitplane;
+
+        /* Set up the vertex buffers for the points */
+
+        v = glamor_get_vbo_space(dst->pScreen, nbox * (4 * sizeof (GLshort)), &vbo_offset);
+
+        glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+        glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1);
+        glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE,
+                              4 * sizeof (GLshort), vbo_offset);
+
+        memcpy(v, box, nbox * sizeof (BoxRec));
+
+        glamor_get_drawable_deltas(src, src_pixmap, &src_off_x, &src_off_y);
+
+        glamor_put_vbo_space(screen);
+
+        set_scissor = src_priv->type == GLAMOR_TEXTURE_LARGE;
+        if (set_scissor)
+            glEnable(GL_SCISSOR_TEST);
+
+        glamor_pixmap_loop(src_priv, src_box_x, src_box_y) {
+            BoxPtr src_box = glamor_pixmap_box_at(src_priv, src_box_x, src_box_y);
+
+            args.dx = dx + src_off_x - src_box->x1;
+            args.dy = dy + src_off_y - src_box->y1;
+            args.src = glamor_pixmap_fbo_at(src_priv, src_box_x, src_box_y);
+
+            if (!glamor_use_program(dst_pixmap, gc, prog, &args))
+                goto bail_ctx;
+
+            glamor_pixmap_loop(dst_priv, dst_box_x, dst_box_y) {
+                glamor_set_destination_drawable(dst, dst_box_x, dst_box_y, FALSE, FALSE,
+                                                prog->matrix_uniform, &dst_off_x, &dst_off_y);
+
+                if (set_scissor)
+                    glScissor(dst_off_x - args.dx,
+                              dst_off_y - args.dy,
+                              src_box->x2 - src_box->x1,
+                              src_box->y2 - src_box->y1);
+
+                glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nbox);
+            }
+        }
+        if (set_scissor)
+            glDisable(GL_SCISSOR_TEST);
+        glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
+        glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+    }
+
+    glDisable(GL_COLOR_LOGIC_OP);
+    glamor_put_context(glamor_priv);
+    return;
+
+bail_ctx:
+    glDisable(GL_COLOR_LOGIC_OP);
+    glamor_put_context(glamor_priv);
+bail:
+    glamor_copy_bail(src, dst, gc, box, nbox, dx, dy,
+                     reverse, upsidedown, bitplane, closure);
+}
+
+void
+glamor_copy(DrawablePtr src,
+            DrawablePtr dst,
+            GCPtr gc,
+            BoxPtr box,
+            int nbox,
+            int dx,
+            int dy,
+            Bool reverse,
+            Bool upsidedown,
+            Pixel bitplane,
+            void *closure)
+{
+    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
+    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
+    glamor_pixmap_private *src_priv = glamor_get_pixmap_private(src_pixmap);
+    glamor_pixmap_private *dst_priv = glamor_get_pixmap_private(dst_pixmap);
+
+    if (GLAMOR_PIXMAP_PRIV_HAS_FBO(dst_priv)) {
+        if (GLAMOR_PIXMAP_PRIV_HAS_FBO(src_priv)) {
+            glamor_copy_fbo_fbo(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
+            return;
+        }
+        if (bitplane == 0) {
+            glamor_copy_cpu_fbo(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
+            return;
+        }
+    }
+    glamor_copy_bail(src, dst, gc, box, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
+}
+
+RegionPtr
+glamor_copyarea(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+                int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+    return miDoCopy(src, dst, gc,
+                    srcx, srcy, width, height,
+                    dstx, dsty, glamor_copy, 0, NULL);
+}
+
+RegionPtr
+glamor_copyplane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+                 int srcx, int srcy, int width, int height, int dstx, int dsty,
+                 unsigned long bitplane)
+{
+    if ((bitplane & FbFullMask(src->depth)) == 0)
+        return miHandleExposures(src, dst, gc,
+                                 srcx, srcy, width, height, dstx, dsty,
+                                 bitplane);
+    return miDoCopy(src, dst, gc,
+                    srcx, srcy, width, height,
+                    dstx, dsty, glamor_copy, bitplane, NULL);
+}
+
+void
+glamor_copywindow(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region)
+{
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(&window->drawable);
+    DrawablePtr drawable = &pixmap->drawable;
+    RegionRec dst_region;
+    int dx, dy;
+
+    dx = old_origin.x - window->drawable.x;
+    dy = old_origin.y - window->drawable.y;
+    RegionTranslate(src_region, -dx, -dy);
+
+    RegionNull(&dst_region);
+
+    RegionIntersect(&dst_region, &window->borderClip, src_region);
+
+#ifdef COMPOSITE
+    if (pixmap->screen_x || pixmap->screen_y)
+        RegionTranslate(&dst_region, -pixmap->screen_x, -pixmap->screen_y);
+#endif
+
+    miCopyRegion(drawable, drawable,
+                 0, &dst_region, dx, dy, glamor_copy, 0, 0);
+
+    RegionUninit(&dst_region);
+}
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 23ac1b2..f350746 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -416,8 +416,8 @@ GCOps glamor_gc_ops = {
     .FillSpans = glamor_fillspans,
     .SetSpans = glamor_setspans,
     .PutImage = glamor_put_image,
-    .CopyArea = glamor_copy_area,
-    .CopyPlane = glamor_copy_plane,
+    .CopyArea = glamor_copyarea,
+    .CopyPlane = glamor_copyplane,
     .PolyPoint = glamor_poly_point,
     .Polylines = glamor_poly_lines,
     .PolySegment = glamor_poly_segment,
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 5df60ac..c0fd096 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -233,6 +233,10 @@ typedef struct glamor_screen_private {
     glamor_program      te_text_prog;
     glamor_program      image_text_prog;
 
+    /* glamor copy shaders */
+    glamor_program      copy_area_prog;
+    glamor_program      copy_plane_prog;
+
     /* vertext/elment_index buffer object for render */
     GLuint vbo, ebo;
     /** Next offset within the VBO that glamor_get_vbo_space() will use. */
@@ -1017,6 +1021,32 @@ void
 glamor_polyfillrect(DrawablePtr drawable,
                     GCPtr gc, int nrect, xRectangle *prect);
 
+/* glamor_copy.c */
+void
+glamor_copy(DrawablePtr src,
+            DrawablePtr dst,
+            GCPtr gc,
+            BoxPtr box,
+            int nbox,
+            int dx,
+            int dy,
+            Bool reverse,
+            Bool upsidedown,
+            Pixel bitplane,
+            void *closure);
+
+RegionPtr
+glamor_copyarea(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+                int srcx, int srcy, int width, int height, int dstx, int dsty);
+
+RegionPtr
+glamor_copyplane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+                 int srcx, int srcy, int width, int height, int dstx, int dsty,
+                 unsigned long bitplane);
+
+void
+glamor_copywindow(WindowPtr window, DDXPointRec old_origin, RegionPtr src_region);
+
 /* glamor_glyphblt.c */
 void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                             int x, int y, unsigned int nglyph,
diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
index 0f9b248..f7d795f 100644
--- a/glamor/glamor_program.c
+++ b/glamor/glamor_program.c
@@ -117,6 +117,11 @@ static glamor_location_var location_vars[] = {
         .location = glamor_program_location_font,
         .fs_vars = "uniform usampler2D font;\n",
     },
+    {
+        .location = glamor_program_location_bitplane,
+        .fs_vars = ("uniform uvec4 bitplane;\n"
+                    "uniform uvec4 bitmul;\n"),
+    },
 };
 
 #define NUM_LOCATION_VARS       (sizeof location_vars / sizeof location_vars[0])
@@ -196,6 +201,8 @@ static const glamor_facet facet_null_fill = {
     .name = ""
 };
 
+#define DBG 0
+
 static GLint
 glamor_get_uniform(glamor_program               *prog,
                    glamor_program_location      location,
@@ -289,7 +296,6 @@ glamor_build_program(ScreenPtr          screen,
     if (!vs_prog_string || !fs_prog_string)
         goto fail;
 
-#define DBG 0
 #if DBG
     ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s",
            prim->name, fill->name, vs_prog_string, fs_prog_string);
@@ -326,6 +332,8 @@ glamor_build_program(ScreenPtr          screen,
     prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset");
     prog->fill_size_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size");
     prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font");
+    prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane");
+    prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul");
 
     if (glGetError() != GL_NO_ERROR)
         goto fail;
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
index 88efc35..118f978 100644
--- a/glamor/glamor_program.h
+++ b/glamor/glamor_program.h
@@ -29,6 +29,7 @@ typedef enum {
     glamor_program_location_bg = 2,
     glamor_program_location_fill = 4,
     glamor_program_location_font = 8,
+    glamor_program_location_bitplane = 16,
 } glamor_program_location;
 
 typedef enum {
@@ -61,6 +62,8 @@ struct _glamor_program {
     GLint                       fill_size_uniform;
     GLint                       fill_offset_uniform;
     GLint                       font_uniform;
+    GLint                       bitplane_uniform;
+    GLint                       bitmul_uniform;
     glamor_program_location     locations;
     glamor_program_flag         flags;
     glamor_use                  prim_use;
-- 
1.9.0



More information about the xorg-devel mailing list