[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