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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
