diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c
new file mode 100644
index 0000000..b0d4ff0
--- /dev/null
+++ b/glamor/glamor_program.c
@@ -0,0 +1,422 @@
+/*
+ * 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_transform.h"
+#include "glamor_program.h"
+
+static Bool
+use_solid (PixmapPtr pixmap, GCPtr gc, glamor_program *prog)
+{
+ return glamor_set_solid(pixmap, gc, TRUE, prog->fg_uniform);
+}
+
+const glamor_facet glamor_fill_solid = {
+ .name = "solid",
+ .fs_exec = " gl_FragColor = fg;\n",
+ .locations = glamor_program_location_fg,
+ .use = use_solid,
+};
+
+static Bool
+use_tile (PixmapPtr pixmap, GCPtr gc, glamor_program *prog)
+{
+ return glamor_set_tiled(pixmap, gc, prog->fill_offset_uniform,
prog->fill_size_uniform);
+}
+
+static const glamor_facet glamor_fill_tile = {
+ .name = "tile",
+ .version = 130,
+ .vs_exec = " fill_pos = fill_offset + primitive.xy +
pos;\n",
+ .fs_exec = " gl_FragColor = texelFetch(sampler,
ivec2(mod(fill_pos,fill_size)), 0);\n",
+ .locations = glamor_program_location_fill,
+ .use = use_tile,
+};
+
+#if 0
+static Bool
+use_stipple (PixmapPtr pixmap, GCPtr gc, glamor_program *prog)
+{
+ return glamor_set_stippled(pixmap, gc, prog->fg_uniform,
prog->fill_offset_uniform, prog->fill_size_uniform);
+}
+
+static const glamor_facet glamor_fill_stipple = {
+ .name = "stipple",
+ .version = 130,
+ .vs_exec = " fill_pos = fill_offset + primitive.xy +
pos;\n";
+ .fs_exec = (" if (texelFetch(sampler,
ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
+ " discard;\n"
+ " gl_FragColor = fg;\n")
+ .locations = glamor_program_location_fg |
glamor_program_location_fill
+ .use = use_stipple,
+};
+
+static const glamor_facet glamor_fill_opaque_stipple = {
+ .name = "opaque_stipple",
+ .version = 130,
+ .vs_exec = " fill_pos = fill_offset + primitive.xy +
pos;\n";
+ .fs_exec = (" if (texelFetch(sampler,
ivec2(mod(fill_pos,fill_size)), 0).x == 0)\n"
+ " gl_FragColor = bg;\n"
+ " else\n"
+ " gl_FragColor = fg;\n"),
+ .locations = glamor_program_location_fg |
glamor_program_location_bg | glamor_program_location_fill
+ .use = use_opaque_stipple
+};
+#endif
+
+static const glamor_facet *glamor_facet_fill[4] = {
+ &glamor_fill_solid,
+ &glamor_fill_tile,
+ NULL,
+ NULL,
+};
+
+typedef struct {
+ glamor_program_location location;
+ const char *vs_vars;
+ const char *fs_vars;
+} glamor_location_var;
+
+static glamor_location_var location_vars[] = {
+ {
+ .location = glamor_program_location_fg,
+ .fs_vars = "uniform vec4 fg;\n"
+ },
+ {
+ .location = glamor_program_location_bg,
+ .fs_vars = "uniform vec4 bg;\n"
+ },
+ {
+ .location = glamor_program_location_fill,
+ .vs_vars = ("uniform vec2 fill_offset;\n"
+ "varying vec2 fill_pos;\n"),
+ .fs_vars = ("uniform sampler2D sampler;\n"
+ "uniform vec2 fill_size;\n"
+ "varying vec2 fill_pos;\n")
+ },
+ {
+ .location = glamor_program_location_font,
+ .fs_vars = "uniform usampler2D font;\n",
+ },
+};
+
+#define NUM_LOCATION_VARS (sizeof location_vars / sizeof
location_vars[0])
+
+static char *
+add_var(char *cur, const char *add)
+{
+ char *new;
+
+ if (!add)
+ return cur;
+
+ new = realloc(cur, strlen(cur) + strlen(add) + 1);
+ if (!new) {
+ free(cur);
+ return NULL;
+ }
+ strcat(new, add);
+ return new;
+}
+
+static char *
+vs_location_vars(glamor_program_location locations)
+{
+ int l;
+ char *vars = strdup("");
+
+ for (l = 0; vars && l < NUM_LOCATION_VARS; l++)
+ if (locations & location_vars[l].location)
+ vars = add_var(vars, location_vars[l].vs_vars);
+ return vars;
+}
+
+static char *
+fs_location_vars(glamor_program_location locations)
+{
+ int l;
+ char *vars = strdup("");
+
+ for (l = 0; vars && l < NUM_LOCATION_VARS; l++)
+ if (locations & location_vars[l].location)
+ vars = add_var(vars, location_vars[l].fs_vars);
+ return vars;
+}
+
+static const char vs_template[] =
+ "%s" /* version */
+ "%s" /* prim vs_vars */
+ "%s" /* fill vs_vars */
+ "%s" /* location vs_vars */
+ GLAMOR_DECLARE_MATRIX
+ "void main() {\n"
+ "%s" /* prim vs_exec, outputs
'pos' and gl_Position */
+ "%s" /* fill vs_exec */
+ "}\n";
+
+static const char fs_template[] =
+ "%s" /* version */
+ GLAMOR_DEFAULT_PRECISION
+ "%s" /* prim fs_vars */
+ "%s" /* fill fs_vars */
+ "%s" /* location fs_vars */
+ "void main() {\n"
+ "%s" /* prim fs_exec */
+ "%s" /* fill fs_exec */
+ "}\n";
+
+static const char *
+str(const char *s)
+{
+ if (!s)
+ return "";
+ return s;
+}
+
+Bool
+glamor_build_program(ScreenPtr screen,
+ glamor_program *prog,
+ const glamor_facet *prim,
+ const glamor_facet *fill)
+{
+ glamor_program_location locations = prim->locations;
+ glamor_program_flag flags = prim->flags;
+
+ int version = prim->version;
+ char *version_string = NULL;
+
+ char *fs_vars = NULL;
+ char *vs_vars = NULL;
+
+ char *vs_prog_string;
+ char *fs_prog_string;
+
+ GLint fs_prog, vs_prog;
+
+ locations |= fill->locations;
+ flags |= fill->flags;
+ if (fill->version > version)
+ version = fill->version;
+
+ vs_vars = vs_location_vars(locations);
+ fs_vars = fs_location_vars(locations);
+
+ if (!vs_vars)
+ goto fail;
+ if (!fs_vars)
+ goto fail;
+
+
+ if (version) {
+ if (asprintf(&version_string, "#version %d\n", version) < 0)
+ version_string = NULL;
+ if (!version_string)
+ goto fail;
+ }
+
+ if (asprintf(&vs_prog_string,
+ vs_template,
+ str(version_string),
+ str(prim->vs_vars),
+ str(fill->vs_vars),
+ vs_vars,
+ str(prim->vs_exec),
+ str(fill->vs_exec)) < 0)
+ vs_prog_string = NULL;
+
+ if (asprintf(&fs_prog_string,
+ fs_template,
+ str(version_string),
+ str(prim->fs_vars),
+ str(fill->fs_vars),
+ fs_vars,
+ str(prim->fs_exec),
+ str(fill->fs_exec)) < 0)
+ fs_prog_string = NULL;
+
+ 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);
+#endif
+
+ (void) glGetError();
+
+ prog->prog = glCreateProgram();
+ vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER,
vs_prog_string);
+ fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER,
fs_prog_string);
+ free(vs_prog_string);
+ free(fs_prog_string);
+ glAttachShader(prog->prog, vs_prog);
+ glAttachShader(prog->prog, fs_prog);
+ glBindAttribLocation(prog->prog, GLAMOR_VERTEX_POS, "primitive");
+
+ if (prim->source_name) {
+#if DBG
+ ErrorF("Bind GLAMOR_VERTEX_SOURCE to %s\n",
prim->source_name);
+#endif
+ glBindAttribLocation(prog->prog, GLAMOR_VERTEX_SOURCE,
prim->source_name);
+ }
+
+ glamor_link_glsl_prog(screen, prog->prog, "%s_%s", prim->name,
fill->name);
+
+ prog->matrix_uniform = glGetUniformLocation(prog->prog,
"v_matrix");
+#if DBG
+ ErrorF("matrix uniform %d\n", prog->matrix_uniform);
+#endif
+
+ if (locations & glamor_program_location_fg) {
+ prog->fg_uniform = glGetUniformLocation(prog->prog, "fg");
+#if DBG
+ ErrorF("fg uniform %d\n", prog->fg_uniform);
+#endif
+ }
+
+ if (locations & glamor_program_location_bg) {
+ prog->bg_uniform = glGetUniformLocation(prog->prog, "bg");
+#if DBG
+ ErrorF("bg uniform %d\n", prog->bg_uniform);
+#endif
+ }
+
+ if (locations & glamor_program_location_fill) {
+ prog->fill_offset_uniform = glGetUniformLocation(prog->prog,
"fill_offset");
+ prog->fill_size_uniform = glGetUniformLocation(prog->prog,
"fill_size");
+#if DBG
+ ErrorF("fill offset uniform %d fill size uniform %d\n",
+ prog->fill_offset_uniform, prog->fill_size_uniform);
+#endif
+ }
+
+ if (locations & glamor_program_location_font) {
+ prog->font_uniform = glGetUniformLocation(prog->prog, "font");
+#if DBG
+ ErrorF("font uniform %d\n", prog->font_uniform);
+#endif
+ }
+
+ if (glGetError() != GL_NO_ERROR)
+ goto fail;
+
+ prog->prim_use = prim->use;
+ prog->fill_use = fill->use;
+
+ prog->flags = flags;
+ prog->locations = locations;
+
+ free(version_string);
+ free(fs_vars);
+ free(vs_vars);
+ return TRUE;
+fail:
+ prog->failed = 1;
+ if (prog->prog) {
+ glDeleteProgram(prog->prog);
+ prog->prog = 0;
+ }
+ free(version_string);
+ free(fs_vars);
+ free(vs_vars);
+ return FALSE;
+}
+
+Bool
+glamor_use_program(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program *prog)
+{
+ glUseProgram(prog->prog);
+
+ if (prog->prim_use && !prog->prim_use(pixmap, gc, prog))
+ return FALSE;
+
+ if (prog->fill_use && !prog->fill_use(pixmap, gc, prog))
+ return FALSE;
+
+ return TRUE;
+}
+
+glamor_program *
+glamor_use_program_fill(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program_fill *program_fill,
+ const glamor_facet *prim)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_program *prog =
&program_fill->progs[gc->fillStyle];
+
+ int fill_style = gc->fillStyle;
+ const glamor_facet *fill;
+
+ if (prog->failed)
+ return FALSE;
+
+ if (!prog->prog) {
+ fill = glamor_facet_fill[fill_style];
+ if (!fill)
+ return NULL;
+
+ if (!glamor_build_program(screen, prog, prim, fill))
+ return NULL;
+ }
+
+ if (!glamor_use_program(pixmap, gc, prog))
+ return NULL;
+
+ return prog;
+}
+
+static void
+glamor_delete_programs(ScreenPtr screen,
+ glamor_program *programs,
+ int n)
+{
+ glamor_screen_private *glamor_priv;
+ int i;
+
+ glamor_priv = glamor_get_screen_private(screen);
+ glamor_get_context(glamor_priv);
+ for (i = 0; i < n; i++) {
+ glamor_program *prog = &programs[i];
+ if (prog->prog)
+ glDeleteProgram(prog->prog);
+ memset(prog, '\0', sizeof (*prog));
+ }
+ glamor_put_context(glamor_priv);
+}
+
+void
+glamor_delete_program(ScreenPtr screen,
+ glamor_program *program)
+{
+ glamor_delete_programs(screen, program, 1);
+}
+
+void
+glamor_delete_program_fill(ScreenPtr screen,
+ glamor_program_fill *program_fill)
+{
+ glamor_delete_programs(screen, program_fill->progs, sizeof
(program_fill->progs) / sizeof (program_fill->progs[0]));
+}
diff --git a/glamor/glamor_program.h b/glamor/glamor_program.h
new file mode 100644
index 0000000..6f920b4
--- /dev/null
+++ b/glamor/glamor_program.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#ifndef _GLAMOR_PROGRAM_H_
+#define _GLAMOR_PROGRAM_H_
+
+typedef enum {
+ glamor_program_location_none = 0,
+ glamor_program_location_fg = 1,
+ glamor_program_location_bg = 2,
+ glamor_program_location_fill = 4,
+ glamor_program_location_font = 8,
+} glamor_program_location;
+
+typedef enum {
+ glamor_program_flag_none = 0,
+} glamor_program_flag;
+
+typedef struct _glamor_program glamor_program;
+
+typedef Bool (*glamor_use) (PixmapPtr pixmap, GCPtr gc, glamor_program
*prog);
+
+typedef struct {
+ const char *name;
+ const int version;
+ const char *vs_vars;
+ const char *vs_exec;
+ const char *fs_vars;
+ const char *fs_exec;
+ const glamor_program_location locations;
+ const glamor_program_flag flags;
+ const char *source_name;
+ glamor_use use;
+} glamor_facet;
+
+struct _glamor_program {
+ GLint prog;
+ GLint failed;
+ GLint matrix_uniform;
+ GLint fg_uniform;
+ GLint bg_uniform;
+ GLint fill_size_uniform;
+ GLint fill_offset_uniform;
+ GLint font_uniform;
+ glamor_program_location locations;
+ glamor_program_flag flags;
+ glamor_use prim_use;
+ glamor_use fill_use;
+};
+
+typedef struct {
+ glamor_program progs[4];
+} glamor_program_fill;
+
+extern const glamor_facet glamor_fill_solid;
+
+Bool
+glamor_build_program(ScreenPtr screen,
+ glamor_program *prog,
+ const glamor_facet *prim,
+ const glamor_facet *fill);
+
+Bool
+glamor_use_program(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program *prog);
+
+glamor_program *
+glamor_use_program_fill(PixmapPtr pixmap,
+ GCPtr gc,
+ glamor_program_fill *program_fill,
+ const glamor_facet *prim);
+
+void
+glamor_delete_program(ScreenPtr screen,
+ glamor_program *program);
+
+void
+glamor_delete_program_fill(ScreenPtr screen,
+ glamor_program_fill *program_fill);
+
+#endif /* _GLAMOR_PROGRAM_H_ */
diff --git a/glamor/glamor_transform.c b/glamor/glamor_transform.c
new file mode 100644
index 0000000..7ad6d8e
--- /dev/null
+++ b/glamor/glamor_transform.c
@@ -0,0 +1,206 @@
+/*
+ * 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_transform.h"
+
+
+/*
+ * Set up rendering to target the specified drawable, computing an
+ * appropriate transform for the vertex shader to convert
+ * drawable-relative coordinates into pixmap-relative coordinates. If
+ * requested, the offset from pixmap origin coordinates back to window
+ * system coordinates will be returned in *p_off_x, *p_off_y so that
+ * clipping computations can be adjusted as appropriate
+ */
+
+void
+glamor_set_destination_drawable(DrawablePtr drawable,
+ int box_x,
+ int box_y,
+ Bool do_drawable_translate,
+ GLint
matrix_uniform_location,
+ int *p_off_x,
+ int *p_off_y)
+{
+ PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+ glamor_pixmap_private *pixmap_priv =
glamor_get_pixmap_private(pixmap);
+ int off_x, off_y;
+ BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
+ int w = box->x2 - box->x1;
+ int h = box->y2 - box->y1;
+ float scale_x = 2.0f / (float) w;
+ float scale_y = 2.0f / (float) h;
+
+ glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+
+ off_x -= box->x1;
+ off_y -= box->y1;
+
+ if (p_off_x) {
+ *p_off_x = off_x;
+ *p_off_y = off_y;
+ }
+
+ /* A tricky computation to find the right value for the two
linear functions
+ * that transform rendering coordinates to pixmap coordinates
+ *
+ * pixmap_x = render_x + drawable->x + off_x
+ * pixmap_y = render_y + drawable->y + off_y
+ *
+ * gl_x = pixmap_x * 2 / width - 1
+ * gl_y = pixmap_y * 2 / height - 1
+ *
+ * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1
+ *
+ * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 /
width - 1
+ *
+ * To get GL_POINTS drawn in the right spot, we need to adjust the
+ * coordinates by 1/2 a pixel. This doesn't hurt rectangles at
+ * all, so we just always do it. If we need to change someday, we
+ * can add a parameter to this function
+ *
+ * I'll think about yInverted later, when I have some way to test
+ */
+
+ if (do_drawable_translate) {
+ off_x += drawable->x;
+ off_y += drawable->y;
+ }
+
+ glUniform4f(matrix_uniform_location,
+ scale_x, (off_x + 0.5f) * scale_x -1.0f,
+ scale_y, (off_y + 0.5f) * scale_y -1.0f);
+
+
glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo_at(pixmap_priv,
box_x, box_y),
+ 0, 0, w, h);
+}
+
+/*
+ * Set up for solid rendering to the specified pixmap using alu, fg
and planemask
+ * from the specified GC. Load the target color into the specified
uniform
+ */
+
+void
+glamor_set_color(PixmapPtr pixmap,
+ CARD32 pixel,
+ GLint uniform)
+{
+ float color[4];
+
+ glamor_get_rgba_from_pixel(pixel,
+ &color[0], &color[1], &color[2],
&color[3],
+ format_for_pixmap(pixmap));
+
+ glUniform4fv(uniform, 1, color);
+}
+
+Bool
+glamor_set_solid(PixmapPtr pixmap,
+ GCPtr gc,
+ Bool use_alu,
+ GLint uniform)
+{
+ CARD32 pixel;
+ int alu = use_alu ? gc->alu : GXcopy;
+
+ if (!glamor_set_planemask(pixmap, gc->planemask))
+ return FALSE;
+
+ pixel = gc->fgPixel;
+
+ if (!glamor_set_alu(pixmap->drawable.pScreen, alu)) {
+ switch (gc->alu) {
+ case GXclear:
+ pixel = 0;
+ break;
+ case GXcopyInverted:
+ pixel = ~pixel;
+ break;
+ case GXset:
+ pixel = ~0 & gc->planemask;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ glamor_set_color(pixmap, gc->fgPixel, uniform);
+
+ return TRUE;
+}
+
+static Bool
+glamor_set_texture(PixmapPtr pixmap,
+ GCPtr gc,
+ PixmapPtr texture,
+ GLint offset_uniform,
+ GLint size_uniform)
+{
+ glamor_pixmap_private *texture_priv;
+ int off_x, off_y;
+
+ texture_priv = glamor_get_pixmap_private(texture);
+
+ if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(texture_priv))
+ return FALSE;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture_priv->base.fbo->tex);
+
+ off_x = gc->patOrg.x;
+ off_y = gc->patOrg.y;
+ glUniform2f(offset_uniform, off_x, off_y);
+ glUniform2f(size_uniform, texture->drawable.width,
texture->drawable.height);
+ return TRUE;
+}
+
+Bool
+glamor_set_tiled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint offset_uniform,
+ GLint size_uniform)
+{
+ if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu))
+ return FALSE;
+
+ if (!glamor_set_planemask(pixmap, gc->planemask))
+ return FALSE;
+
+ return glamor_set_texture(pixmap, gc, gc->tile.pixmap,
offset_uniform, size_uniform);
+}
+
+Bool
+glamor_set_stippled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint fg_uniform,
+ GLint offset_uniform,
+ GLint size_uniform)
+{
+ if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform))
+ return FALSE;
+
+ if (!glamor_set_texture(pixmap, gc, gc->stipple, offset_uniform,
size_uniform))
+ return FALSE;
+
+ return TRUE;
+}
+
diff --git a/glamor/glamor_transform.h b/glamor/glamor_transform.h
new file mode 100644
index 0000000..d1cfbf9
--- /dev/null
+++ b/glamor/glamor_transform.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef _GLAMOR_TRANSFORM_H_
+#define _GLAMOR_TRANSFORM_H_
+
+void
+glamor_set_destination_drawable(DrawablePtr drawable,
+ int box_x,
+ int box_y,
+ Bool do_drawable_translate,
+ GLint
matrix_uniform_location,
+ int *p_off_x,
+ int *p_off_y);
+
+void
+glamor_set_color(PixmapPtr pixmap,
+ CARD32 pixel,
+ GLint uniform);
+
+Bool
+glamor_set_solid(PixmapPtr pixmap,
+ GCPtr gc,
+ Bool use_alu,
+ GLint uniform);
+
+Bool
+glamor_set_tiled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint offset_uniform,
+ GLint size_uniform);
+
+Bool
+glamor_set_stippled(PixmapPtr pixmap,
+ GCPtr gc,
+ GLint fg_uniform,
+ GLint offset_uniform,
+ GLint size_uniform);
+
+/*
+ * Vertex shader bits that transform X coordinates to pixmap
+ * coordinates using the matrix computed above
+ */
+
+#define GLAMOR_DECLARE_MATRIX "uniform vec4 v_matrix;\n"
+#define GLAMOR_X_POS(x) #x " *v_matrix.x + v_matrix.y"
+#define GLAMOR_Y_POS(y) #y " *v_matrix.z + v_matrix.w"
+#if 0
+#define GLAMOR_POS(dst,src) \
+ " " #dst ".x = " #src ".x * v_matrix.x + v_matrix.y;\n" \
+ " " #dst ".y = " #src ".y * v_matrix.z + v_matrix.w;\n" \
+ " " #dst ".z = 0.0;\n" \
+ " " #dst ".w = 1.0;\n"
+#endif
+#define GLAMOR_POS(dst,src) \
+ " " #dst ".xy = " #src ".xy * v_matrix.xz + v_matrix.yw;\n"
\
+ " " #dst ".zw = vec2(0.0,1.0);\n"
+
+#endif /* _GLAMOR_TRANSFORM_H_ */