Summary: Tiny nitpicks, one functional concern. Keith Packard <[email protected]> writes: > This extends the existing API to support options needed for render > accleratoin, including an additional fragment, 'combine', (which
acceleration > provides a place to perform the source IN mask operation before the > final OP dest state) and an addtional 'defines' parameter which additional > provides a way to add target-dependent values without using a uniform. > > Signed-off-by: Keith Packard <[email protected]> > --- > glamor/glamor_copy.c | 2 +- > glamor/glamor_dash.c | 2 +- > glamor/glamor_points.c | 3 +- > glamor/glamor_program.c | 230 > ++++++++++++++++++++++++++++++++++++++++++++++-- > glamor/glamor_program.h | 51 ++++++++++- > glamor/glamor_text.c | 2 +- > 6 files changed, 279 insertions(+), 11 deletions(-) > > diff --git a/glamor/glamor_copy.c b/glamor/glamor_copy.c > index 921e80e..2ffe645 100644 > --- a/glamor/glamor_copy.c > +++ b/glamor/glamor_copy.c > @@ -338,7 +338,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src, > > if (!prog->prog) { > if (!glamor_build_program(screen, prog, > - copy_facet, NULL)) > + copy_facet, NULL, NULL, NULL)) > goto bail_ctx; > } > > diff --git a/glamor/glamor_dash.c b/glamor/glamor_dash.c > index 4281ff0..101228e 100644 > --- a/glamor/glamor_dash.c > +++ b/glamor/glamor_dash.c > @@ -170,7 +170,7 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc) > if (!prog->prog) { > if (!glamor_build_program(screen, prog, > &glamor_facet_double_dash_lines, > - NULL)) > + NULL, NULL, NULL)) > goto bail; > } > > diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c > index df7e5a2..3ba4a69 100644 > --- a/glamor/glamor_points.c > +++ b/glamor/glamor_points.c > @@ -60,7 +60,8 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int > mode, int npt, DDXPoint > if (!prog->prog) { > if (!glamor_build_program(screen, prog, > &glamor_facet_point, > - &glamor_fill_solid)) > + &glamor_fill_solid, > + NULL, NULL)) > goto bail; > } > > diff --git a/glamor/glamor_program.c b/glamor/glamor_program.c > index 8aab53f..857256d 100644 > --- a/glamor/glamor_program.c > +++ b/glamor/glamor_program.c > @@ -183,6 +183,7 @@ fs_location_vars(glamor_program_location locations) > > static const char vs_template[] = > "%s" /* version */ > + "%s" /* defines */ > "%s" /* prim vs_vars */ > "%s" /* fill vs_vars */ > "%s" /* location vs_vars */ > @@ -195,12 +196,14 @@ static const char vs_template[] = > static const char fs_template[] = > "%s" /* version */ > GLAMOR_DEFAULT_PRECISION > + "%s" /* defines */ > "%s" /* prim fs_vars */ > "%s" /* fill fs_vars */ > "%s" /* location fs_vars */ > "void main() {\n" > "%s" /* prim fs_exec */ > "%s" /* fill fs_exec */ > + "%s" /* combine */ > "}\n"; > > static const char * > @@ -236,7 +239,9 @@ Bool > glamor_build_program(ScreenPtr screen, > glamor_program *prog, > const glamor_facet *prim, > - const glamor_facet *fill) > + const glamor_facet *fill, > + const char *combine, > + const char *defines) > { > glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); > > @@ -282,6 +287,7 @@ glamor_build_program(ScreenPtr screen, > if (asprintf(&vs_prog_string, > vs_template, > str(version_string), > + str(defines), > str(prim->vs_vars), > str(fill->vs_vars), > vs_vars, > @@ -292,26 +298,30 @@ glamor_build_program(ScreenPtr screen, > if (asprintf(&fs_prog_string, > fs_template, > str(version_string), > + str(defines), > str(prim->fs_vars), > str(fill->fs_vars), > fs_vars, > str(prim->fs_exec), > - str(fill->fs_exec)) < 0) > + str(fill->fs_exec), > + str(combine)) < 0) > fs_prog_string = NULL; > > if (!vs_prog_string || !fs_prog_string) > goto fail; > > + prog->prog = glCreateProgram(); > #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); > + ErrorF("\n\tProgram %d for %s %s\n\tVertex > shader:\n\n\t================\n%s\n\n\tFragment > Shader:\n\n%s\t================\n", > + prog->prog, prim->name, fill->name, vs_prog_string, > fs_prog_string); > #endif > > - prog->prog = glCreateProgram(); > prog->flags = flags; > prog->locations = locations; > prog->prim_use = prim->use; > + prog->prim_use_render = prim->use_render; > prog->fill_use = fill->use; > + prog->fill_use_render = fill->use_render; > > vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_prog_string); > fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_prog_string); > @@ -396,7 +406,7 @@ glamor_use_program_fill(PixmapPtr pixmap, > if (!fill) > return NULL; > > - if (!glamor_build_program(screen, prog, prim, fill)) > + if (!glamor_build_program(screen, prog, prim, fill, NULL, NULL)) > return NULL; > } > > @@ -405,3 +415,211 @@ glamor_use_program_fill(PixmapPtr pixmap, > > return prog; > } > + > +static struct blendinfo composite_op_info[] = { > + [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, > + [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, > + [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, > + [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, > + [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, > + [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, > + [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, > + [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, > + [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, > + [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, > + [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, > + [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, > + [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, > +}; > + > +static void > +glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) > +{ > + GLenum src_blend, dst_blend; > + struct blendinfo *op_info; > + > + switch (alpha) { > + case glamor_program_alpha_ca_first: > + op = PictOpOutReverse; > + break; > + case glamor_program_alpha_ca_second: > + op = PictOpAdd; > + break; > + default: > + break; > + } > + > + if (op == PictOpSrc) > + return; > + op_info = &composite_op_info[op]; > + > + src_blend = op_info->source_blend; > + dst_blend = op_info->dest_blend; > + > + /* If there's no dst alpha channel, adjust the blend op so that we'll > treat > + * it as always 1. > + */ > + if (PICT_FORMAT_A(dst->format) == 0 && op_info->dest_alpha) { > + if (src_blend == GL_DST_ALPHA) > + src_blend = GL_ONE; > + else if (src_blend == GL_ONE_MINUS_DST_ALPHA) > + src_blend = GL_ZERO; > + } > + > + /* Set up the source alpha value for blending in component alpha mode. */ > + if (alpha != glamor_program_alpha_normal && op_info->source_alpha) { > + if (dst_blend == GL_SRC_ALPHA) > + dst_blend = GL_SRC_COLOR; > + else if (dst_blend == GL_ONE_MINUS_SRC_ALPHA) > + dst_blend = GL_ONE_MINUS_SRC_COLOR; > + } > + > + glEnable(GL_BLEND); > + glBlendFunc(src_blend, dst_blend); > +} > + > +static Bool > +use_source_solid(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program > *prog) > +{ > + > + glamor_set_blend(op, prog->alpha, dst); > + > + glamor_set_color(glamor_get_drawable_pixmap(dst->pDrawable), > + src->pSourcePict->solidFill.color, > + prog->fg_uniform); > + return TRUE; > +} > + > +const glamor_facet glamor_source_solid = { > + .name = "render_solid", > + .fs_exec = " vec4 source = fg;\n", > + .locations = glamor_program_location_fg, > + .use_render = use_source_solid, > +}; > + > +static Bool > +use_source_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program > *prog) > +{ > + glamor_set_blend(op, prog->alpha, dst); > + > + return glamor_set_texture((PixmapPtr) src->pDrawable, > + 0, 0, > + prog->fill_offset_uniform, > + prog->fill_size_inv_uniform); > + > + return TRUE; > +} > + > +const glamor_facet glamor_source_picture = { > + .name = "render_picture", > + .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) / > fill_size;\n", > + .fs_exec = " vec4 source = texture2D(sampler, fill_pos);\n", > + .locations = glamor_program_location_fill, > + .use_render = use_source_picture, > +}; > + > +const glamor_facet *glamor_facet_source[glamor_program_source_count] = { > + [glamor_program_source_solid] = &glamor_source_solid, > + [glamor_program_source_picture] = &glamor_source_picture, > +}; > + > +static const char *glamor_combine[] = { > + " gl_FragColor = source * mask.a;\n", > + " gl_FragColor = source.a * mask;\n", > + " gl_FragColor = source * mask;\n" > +}; This would be nice as: [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n", [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n", [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n" > + > +static Bool > +glamor_setup_one_program_render(ScreenPtr screen, > + glamor_program *prog, > + glamor_program_source source_type, > + glamor_program_alpha alpha, > + const glamor_facet *prim, > + const char *defines) > +{ > + if(prog->failed) > + return FALSE; missing space > + > + if (!prog->prog) { > + const glamor_facet *fill = glamor_facet_source[source_type]; > + > + if (!fill) > + return FALSE; > + > + if (!glamor_build_program(screen, prog, prim, fill, > glamor_combine[alpha], defines)) > + return FALSE; > + prog->alpha = alpha; > + } > + > + return TRUE; > +} > + > +glamor_program * > +glamor_setup_program_render(CARD8 op, > + PicturePtr src, > + PicturePtr mask, > + PicturePtr dst, > + glamor_program_render *program_render, > + const glamor_facet *prim, > + const char *defines) > +{ > + ScreenPtr screen = dst->pDrawable->pScreen; > + glamor_program_alpha alpha; > + glamor_program_source source_type; > + glamor_program *prog, *ret; > + > + if (op > sizeof (composite_op_info)/sizeof (composite_op_info[0])) if (op > ARRAY_SIZE(composite_op_info)) > + return NULL; > + > + if (glamor_is_component_alpha(mask)) { > + /* This only works for PictOpOver */ > + if (op != PictOpOver) > + return NULL; > + alpha = glamor_program_alpha_ca_first; > + } else > + alpha = glamor_program_alpha_normal; > + > + if (src->pDrawable) > + source_type = glamor_program_source_picture; > + else { > + SourcePictPtr sp = src->pSourcePict; > + if (!sp) > + return NULL; > + switch (sp->type) { > + case SourcePictTypeSolidFill: > + source_type = glamor_program_source_solid; > + break; > + default: > + return NULL; > + } > + } I don't think the glamor_program_source_picture path is complete -- what about src->transform and src->alphaMap? I'd be just fine with the text path only doing solids, and glyph-masking a texture being something we fall back to the slow path for. If so, and we need to do 1x1 repeating src (I think that's how a lot of text is drawn still, right?), we might want to drop fill_pos in the facet and just texture2D(sampler, vec2(0.5)). > + > + ret = &program_render->progs[source_type][alpha]; > + for (;;) { > + prog = &program_render->progs[source_type][alpha]; > + > + if (!glamor_setup_one_program_render(screen, prog, source_type, > alpha, prim, defines)) > + return NULL; > + > + if (alpha != glamor_program_alpha_ca_first) > + break; > + alpha++; > + } This was hard to read, and I think explicit might be nicer: prog = &program_render->progs[source_type][alpha]; if (!glamor_setup_one_program_render(screen, prog, source_type, alpha, prim, defines)) return NULL; if (alpha == glamor_program_alpha_ca_first) { /* Make sure we can also build the second program before deciding * to use this path. */ if (!glamor_setup_one_program_render(screen, &program_render->progs[source_type][glamor_program_alpha_ca_second], source_type, glamor_program_alpha_ca_second, prim, defines)) { return NULL; } }
signature.asc
Description: PGP signature
_______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
