diff options
-rw-r--r-- | libvo/gl_common.c | 340 |
1 files changed, 188 insertions, 152 deletions
diff --git a/libvo/gl_common.c b/libvo/gl_common.c index f433f5642d..47b0429ccf 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -751,6 +751,58 @@ static void glSetupYUVFragmentATI(GL *gl, struct mp_csp_params *csp_params, } } +// Replace all occurances of variables named "$"+name (e.g. $foo) in *text with +// replace, and return the result. *text must have been allocated with talloc. +static void replace_var_str(char **text, const char *name, const char *replace) +{ + size_t namelen = strlen(name); + char *nextvar = *text; + void *parent = talloc_parent(*text); + for (;;) { + nextvar = strchr(nextvar, '$'); + if (!nextvar) + break; + char *until = nextvar; + nextvar++; + if (strncmp(nextvar, name, namelen) != 0) + continue; + nextvar += namelen; + // try not to replace prefixes of other vars (e.g. $foo vs. $foo_bar) + char term = nextvar[0]; + if (isalnum(term) || term == '_') + continue; + int prelength = until - *text; + int postlength = nextvar - *text; + char *n = talloc_asprintf(parent, "%.*s%s%s", prelength, *text, replace, + nextvar); + talloc_free(*text); + *text = n; + nextvar = *text + postlength; + } +} + +static void replace_var_float(char **text, const char *name, float replace) +{ + char *s = talloc_asprintf(NULL, "%e", replace); + replace_var_str(text, name, s); + talloc_free(s); +} + +static void replace_var_char(char **text, const char *name, char replace) +{ + char s[2] = { replace, '\0' }; + replace_var_str(text, name, s); +} + +// Append template to *text. Possibly initialize *text if it's NULL. +static void append_template(char **text, const char* template) +{ + if (!text) + *text = talloc_strdup(NULL, template); + else + *text = talloc_strdup_append(*text, template); +} + /** * \brief helper function for gen_spline_lookup_tex * \param x subpixel-position ((0,1) range) to calculate weights for @@ -800,38 +852,41 @@ static void gen_spline_lookup_tex(GL *gl, GLenum unit) free(tex); } +#define SAMPLE(dest, coord, texture) \ + "TEX dest, " coord ", " texture ", $tex_type;\n" + static const char *bilin_filt_template = - "TEX yuv.%c, fragment.texcoord[%c], texture[%c], %s;\n"; + SAMPLE("yuv.$out_comp","fragment.texcoord[$in_tex]","texture[$in_tex]"); -#define BICUB_FILT_MAIN(textype) \ +#define BICUB_FILT_MAIN \ /* first y-interpolation */ \ - "ADD coord, fragment.texcoord[%c].xyxy, cdelta.xyxw;\n" \ - "ADD coord2, fragment.texcoord[%c].xyxy, cdelta.zyzw;\n" \ - "TEX a.r, coord.xyxy, texture[%c], "textype ";\n" \ - "TEX a.g, coord.zwzw, texture[%c], "textype ";\n" \ + "ADD coord, fragment.texcoord[$in_tex].xyxy, cdelta.xyxw;\n" \ + "ADD coord2, fragment.texcoord[$in_tex].xyxy, cdelta.zyzw;\n" \ + SAMPLE("a.r","coord.xyxy","texture[$in_tex]") \ + SAMPLE("a.g","coord.zwzw","texture[$in_tex]") \ /* second y-interpolation */ \ - "TEX b.r, coord2.xyxy, texture[%c], "textype ";\n" \ - "TEX b.g, coord2.zwzw, texture[%c], "textype ";\n" \ + SAMPLE("b.r","coord2.xyxy","texture[$in_tex]") \ + SAMPLE("b.g","coord2.zwzw","texture[$in_tex]") \ "LRP a.b, parmy.b, a.rrrr, a.gggg;\n" \ "LRP a.a, parmy.b, b.rrrr, b.gggg;\n" \ /* x-interpolation */ \ - "LRP yuv.%c, parmx.b, a.bbbb, a.aaaa;\n" + "LRP yuv.$out_comp, parmx.b, a.bbbb, a.aaaa;\n" static const char *bicub_filt_template_2D = - "MAD coord.xy, fragment.texcoord[%c], {%e, %e}, {0.5, 0.5};\n" - "TEX parmx, coord.x, texture[%c], 1D;\n" - "MUL cdelta.xz, parmx.rrgg, {-%e, 0, %e, 0};\n" - "TEX parmy, coord.y, texture[%c], 1D;\n" - "MUL cdelta.yw, parmy.rrgg, {0, -%e, 0, %e};\n" - BICUB_FILT_MAIN("2D"); + "MAD coord.xy, fragment.texcoord[$in_tex], {$texw, $texh}, {0.5, 0.5};\n" + "TEX parmx, coord.x, texture[$texs], 1D;\n" + "MUL cdelta.xz, parmx.rrgg, {-$ptw, 0, $ptw, 0};\n" + "TEX parmy, coord.y, texture[$texs], 1D;\n" + "MUL cdelta.yw, parmy.rrgg, {0, -$pth, 0, $pth};\n" + BICUB_FILT_MAIN; static const char *bicub_filt_template_RECT = - "ADD coord, fragment.texcoord[%c], {0.5, 0.5};\n" - "TEX parmx, coord.x, texture[%c], 1D;\n" + "ADD coord, fragment.texcoord[$in_tex], {0.5, 0.5};\n" + "TEX parmx, coord.x, texture[$texs], 1D;\n" "MUL cdelta.xz, parmx.rrgg, {-1, 0, 1, 0};\n" - "TEX parmy, coord.y, texture[%c], 1D;\n" + "TEX parmy, coord.y, texture[$texs], 1D;\n" "MUL cdelta.yw, parmy.rrgg, {0, -1, 0, 1};\n" - BICUB_FILT_MAIN("RECT"); + BICUB_FILT_MAIN; #define CALCWEIGHTS(t, s) \ "MAD "t ", {-0.5, 0.1666, 0.3333, -0.3333}, "s ", {1, 0, -0.5, 0.5};\n" \ @@ -844,86 +899,86 @@ static const char *bicub_filt_template_RECT = "SUB "t ".y, "t ".yyyy, "s ";\n" static const char *bicub_notex_filt_template_2D = - "MAD coord.xy, fragment.texcoord[%c], {%e, %e}, {0.5, 0.5};\n" + "MAD coord.xy, fragment.texcoord[$in_tex], {$texw, $texh}, {0.5, 0.5};\n" "FRC coord.xy, coord.xyxy;\n" CALCWEIGHTS("parmx", "coord.xxxx") - "MUL cdelta.xz, parmx.rrgg, {-%e, 0, %e, 0};\n" + "MUL cdelta.xz, parmx.rrgg, {-$ptw, 0, $ptw, 0};\n" CALCWEIGHTS("parmy", "coord.yyyy") - "MUL cdelta.yw, parmy.rrgg, {0, -%e, 0, %e};\n" - BICUB_FILT_MAIN("2D"); + "MUL cdelta.yw, parmy.rrgg, {0, -$pth, 0, $pth};\n" + BICUB_FILT_MAIN; static const char *bicub_notex_filt_template_RECT = - "ADD coord, fragment.texcoord[%c], {0.5, 0.5};\n" + "ADD coord, fragment.texcoord[$in_tex], {0.5, 0.5};\n" "FRC coord.xy, coord.xyxy;\n" CALCWEIGHTS("parmx", "coord.xxxx") "MUL cdelta.xz, parmx.rrgg, {-1, 0, 1, 0};\n" CALCWEIGHTS("parmy", "coord.yyyy") "MUL cdelta.yw, parmy.rrgg, {0, -1, 0, 1};\n" - BICUB_FILT_MAIN("RECT"); + BICUB_FILT_MAIN; -#define BICUB_X_FILT_MAIN(textype) \ - "ADD coord.xy, fragment.texcoord[%c].xyxy, cdelta.xyxy;\n" \ - "ADD coord2.xy, fragment.texcoord[%c].xyxy, cdelta.zyzy;\n" \ - "TEX a.r, coord, texture[%c], "textype ";\n" \ - "TEX b.r, coord2, texture[%c], "textype ";\n" \ +#define BICUB_X_FILT_MAIN \ + "ADD coord.xy, fragment.texcoord[$in_tex].xyxy, cdelta.xyxy;\n" \ + "ADD coord2.xy, fragment.texcoord[$in_tex].xyxy, cdelta.zyzy;\n" \ + SAMPLE("a.r","coord","texture[$in_tex]") \ + SAMPLE("b.r","coord2","texture[$in_tex]") \ /* x-interpolation */ \ - "LRP yuv.%c, parmx.b, a.rrrr, b.rrrr;\n" + "LRP yuv.$out_comp, parmx.b, a.rrrr, b.rrrr;\n" static const char *bicub_x_filt_template_2D = - "MAD coord.x, fragment.texcoord[%c], {%e}, {0.5};\n" - "TEX parmx, coord, texture[%c], 1D;\n" - "MUL cdelta.xyz, parmx.rrgg, {-%e, 0, %e};\n" - BICUB_X_FILT_MAIN("2D"); + "MAD coord.x, fragment.texcoord[$in_tex], {$texw}, {0.5};\n" + "TEX parmx, coord, texture[$texs], 1D;\n" + "MUL cdelta.xyz, parmx.rrgg, {-$ptw, 0, $ptw};\n" + BICUB_X_FILT_MAIN; static const char *bicub_x_filt_template_RECT = - "ADD coord.x, fragment.texcoord[%c], {0.5};\n" - "TEX parmx, coord, texture[%c], 1D;\n" + "ADD coord.x, fragment.texcoord[$in_tex], {0.5};\n" + "TEX parmx, coord, texture[$texs], 1D;\n" "MUL cdelta.xyz, parmx.rrgg, {-1, 0, 1};\n" - BICUB_X_FILT_MAIN("RECT"); + BICUB_X_FILT_MAIN; static const char *unsharp_filt_template = - "PARAM dcoord%c = {%e, %e, %e, %e};\n" - "ADD coord, fragment.texcoord[%c].xyxy, dcoord%c;\n" - "SUB coord2, fragment.texcoord[%c].xyxy, dcoord%c;\n" - "TEX a.r, fragment.texcoord[%c], texture[%c], %s;\n" - "TEX b.r, coord.xyxy, texture[%c], %s;\n" - "TEX b.g, coord.zwzw, texture[%c], %s;\n" + "PARAM dcoord$out_comp = {$ptw_05, $pth_05, $ptw_05, -$pth_05};\n" + "ADD coord, fragment.texcoord[$in_tex].xyxy, dcoord$out_comp;\n" + "SUB coord2, fragment.texcoord[$in_tex].xyxy, dcoord$out_comp;\n" + SAMPLE("a.r","fragment.texcoord[$in_tex]","texture[$in_tex]") + SAMPLE("b.r","coord.xyxy","texture[$in_tex]") + SAMPLE("b.g","coord.zwzw","texture[$in_tex]") "ADD b.r, b.r, b.g;\n" - "TEX b.b, coord2.xyxy, texture[%c], %s;\n" - "TEX b.g, coord2.zwzw, texture[%c], %s;\n" + SAMPLE("b.b","coord2.xyxy","texture[$in_tex]") + SAMPLE("b.g","coord2.zwzw","texture[$in_tex]") "DP3 b, b, {0.25, 0.25, 0.25};\n" "SUB b.r, a.r, b.r;\n" - "MAD yuv.%c, b.r, {%e}, a.r;\n"; + "MAD yuv.$out_comp, b.r, {$strength}, a.r;\n"; static const char *unsharp_filt_template2 = - "PARAM dcoord%c = {%e, %e, %e, %e};\n" - "PARAM dcoord2%c = {%e, 0, 0, %e};\n" - "ADD coord, fragment.texcoord[%c].xyxy, dcoord%c;\n" - "SUB coord2, fragment.texcoord[%c].xyxy, dcoord%c;\n" - "TEX a.r, fragment.texcoord[%c], texture[%c], %s;\n" - "TEX b.r, coord.xyxy, texture[%c], %s;\n" - "TEX b.g, coord.zwzw, texture[%c], %s;\n" + "PARAM dcoord$out_comp = {$ptw_12, $pth_12, $ptw_12, -$pth_12};\n" + "PARAM dcoord2$out_comp = {$ptw_15, 0, 0, $pth_15};\n" + "ADD coord, fragment.texcoord[$in_tex].xyxy, dcoord$out_comp;\n" + "SUB coord2, fragment.texcoord[$in_tex].xyxy, dcoord$out_comp;\n" + SAMPLE("a.r","fragment.texcoord[$in_tex]","texture[$in_tex]") + SAMPLE("b.r","coord.xyxy","texture[$in_tex]") + SAMPLE("b.g","coord.zwzw","texture[$in_tex]") "ADD b.r, b.r, b.g;\n" - "TEX b.b, coord2.xyxy, texture[%c], %s;\n" - "TEX b.g, coord2.zwzw, texture[%c], %s;\n" + SAMPLE("b.b","coord2.xyxy","texture[$in_tex]") + SAMPLE("b.g","coord2.zwzw","texture[$in_tex]") "ADD b.r, b.r, b.b;\n" "ADD b.a, b.r, b.g;\n" - "ADD coord, fragment.texcoord[%c].xyxy, dcoord2%c;\n" - "SUB coord2, fragment.texcoord[%c].xyxy, dcoord2%c;\n" - "TEX b.r, coord.xyxy, texture[%c], %s;\n" - "TEX b.g, coord.zwzw, texture[%c], %s;\n" + "ADD coord, fragment.texcoord[$in_tex].xyxy, dcoord2$out_comp;\n" + "SUB coord2, fragment.texcoord[$in_tex].xyxy, dcoord2$out_comp;\n" + SAMPLE("b.r","coord.xyxy","texture[$in_tex]") + SAMPLE("b.g","coord.zwzw","texture[$in_tex]") "ADD b.r, b.r, b.g;\n" - "TEX b.b, coord2.xyxy, texture[%c], %s;\n" - "TEX b.g, coord2.zwzw, texture[%c], %s;\n" + SAMPLE("b.b","coord2.xyxy","texture[$in_tex]") + SAMPLE("b.g","coord2.zwzw","texture[$in_tex]") "DP4 b.r, b, {-0.1171875, -0.1171875, -0.1171875, -0.09765625};\n" "MAD b.r, a.r, {0.859375}, b.r;\n" - "MAD yuv.%c, b.r, {%e}, a.r;\n"; + "MAD yuv.$out_comp, b.r, {$strength}, a.r;\n"; static const char *yuv_prog_template = - "PARAM ycoef = {%e, %e, %e};\n" - "PARAM ucoef = {%e, %e, %e};\n" - "PARAM vcoef = {%e, %e, %e};\n" - "PARAM offsets = {%e, %e, %e};\n" + "PARAM ycoef = {$cm11, $cm21, $cm31};\n" + "PARAM ucoef = {$cm12, $cm22, $cm32};\n" + "PARAM vcoef = {$cm13, $cm23, $cm33};\n" + "PARAM offsets = {$cm14, $cm24, $cm34};\n" "TEMP res;\n" "MAD res.rgb, yuv.rrrr, ycoef, offsets;\n" "MAD res.rgb, yuv.gggg, ucoef, res;\n" @@ -931,11 +986,11 @@ static const char *yuv_prog_template = "END"; static const char *yuv_pow_prog_template = - "PARAM ycoef = {%e, %e, %e};\n" - "PARAM ucoef = {%e, %e, %e};\n" - "PARAM vcoef = {%e, %e, %e};\n" - "PARAM offsets = {%e, %e, %e};\n" - "PARAM gamma = {%e, %e, %e};\n" + "PARAM ycoef = {$cm11, $cm21, $cm31};\n" + "PARAM ucoef = {$cm12, $cm22, $cm32};\n" + "PARAM vcoef = {$cm13, $cm23, $cm33};\n" + "PARAM offsets = {$cm14, $cm24, $cm34};\n" + "PARAM gamma = {$gamma_r, $gamma_g, $gamma_b};\n" "TEMP res;\n" "MAD res.rgb, yuv.rrrr, ycoef, offsets;\n" "MAD res.rgb, yuv.gggg, ucoef, res;\n" @@ -946,23 +1001,23 @@ static const char *yuv_pow_prog_template = "END"; static const char *yuv_lookup_prog_template = - "PARAM ycoef = {%e, %e, %e, 0};\n" - "PARAM ucoef = {%e, %e, %e, 0};\n" - "PARAM vcoef = {%e, %e, %e, 0};\n" - "PARAM offsets = {%e, %e, %e, 0.125};\n" + "PARAM ycoef = {$cm11, $cm21, $cm31, 0};\n" + "PARAM ucoef = {$cm12, $cm22, $cm32, 0};\n" + "PARAM vcoef = {$cm13, $cm23, $cm33, 0};\n" + "PARAM offsets = {$cm14, $cm24, $cm34, 0.125};\n" "TEMP res;\n" "MAD res, yuv.rrrr, ycoef, offsets;\n" "MAD res.rgb, yuv.gggg, ucoef, res;\n" "MAD res.rgb, yuv.bbbb, vcoef, res;\n" - "TEX result.color.r, res.raaa, texture[%c], 2D;\n" + "TEX result.color.r, res.raaa, texture[$conv_tex0], 2D;\n" "ADD res.a, res.a, 0.25;\n" - "TEX result.color.g, res.gaaa, texture[%c], 2D;\n" + "TEX result.color.g, res.gaaa, texture[$conv_tex0], 2D;\n" "ADD res.a, res.a, 0.25;\n" - "TEX result.color.b, res.baaa, texture[%c], 2D;\n" + "TEX result.color.b, res.baaa, texture[$conv_tex0], 2D;\n" "END"; static const char *yuv_lookup3d_prog_template = - "TEX result.color, yuv, texture[%c], 3D;\n" + "TEX result.color, yuv, texture[$conv_tex0], 3D;\n" "END"; /** @@ -1059,8 +1114,7 @@ static void create_conv_textures(GL *gl, gl_conversion_params_t *params, /** * \brief adds a scaling texture read at the current fragment program position * \param scaler type of scaler to insert - * \param prog_pos current position in fragment program - * \param remain how many bytes remain in the buffer given by prog_pos + * \param prog pointer to fragment program so far * \param texs array containing the texture unit identifiers for this scaler * \param in_tex texture unit the scaler should read from * \param out_comp component of the yuv variable the scaler stores the result in @@ -1069,7 +1123,7 @@ static void create_conv_textures(GL *gl, gl_conversion_params_t *params, * \param texh height of the in_tex texture * \param strength strength of filter effect if the scaler does some kind of filtering */ -static void add_scaler(int scaler, char **prog_pos, int *remain, char *texs, +static void add_scaler(int scaler, char **prog, char *texs, char in_tex, char out_comp, int rect, int texw, int texh, double strength) { @@ -1078,61 +1132,52 @@ static void add_scaler(int scaler, char **prog_pos, int *remain, char *texs, const float pth = rect ? 1.0 : 1.0 / texh; switch (scaler) { case YUV_SCALER_BILIN: - snprintf(*prog_pos, *remain, bilin_filt_template, out_comp, in_tex, - in_tex, ttype); + append_template(prog, bilin_filt_template); break; case YUV_SCALER_BICUB: if (rect) - snprintf(*prog_pos, *remain, bicub_filt_template_RECT, - in_tex, texs[0], texs[0], - in_tex, in_tex, in_tex, in_tex, in_tex, in_tex, out_comp); + append_template(prog, bicub_filt_template_RECT); else - snprintf(*prog_pos, *remain, bicub_filt_template_2D, - in_tex, (float)texw, (float)texh, - texs[0], ptw, ptw, texs[0], pth, pth, - in_tex, in_tex, in_tex, in_tex, in_tex, in_tex, out_comp); + append_template(prog, bicub_filt_template_2D); break; case YUV_SCALER_BICUB_X: if (rect) - snprintf(*prog_pos, *remain, bicub_x_filt_template_RECT, - in_tex, texs[0], - in_tex, in_tex, in_tex, in_tex, out_comp); + append_template(prog, bicub_x_filt_template_RECT); else - snprintf(*prog_pos, *remain, bicub_x_filt_template_2D, - in_tex, (float)texw, - texs[0], ptw, ptw, - in_tex, in_tex, in_tex, in_tex, out_comp); + append_template(prog, bicub_x_filt_template_2D); break; case YUV_SCALER_BICUB_NOTEX: if (rect) - snprintf(*prog_pos, *remain, bicub_notex_filt_template_RECT, - in_tex, - in_tex, in_tex, in_tex, in_tex, in_tex, in_tex, out_comp); + append_template(prog, bicub_notex_filt_template_RECT); else - snprintf(*prog_pos, *remain, bicub_notex_filt_template_2D, - in_tex, (float)texw, (float)texh, ptw, ptw, pth, pth, - in_tex, in_tex, in_tex, in_tex, in_tex, in_tex, out_comp); + append_template(prog, bicub_notex_filt_template_2D); break; case YUV_SCALER_UNSHARP: - snprintf(*prog_pos, *remain, unsharp_filt_template, - out_comp, 0.5 * ptw, 0.5 * pth, 0.5 * ptw, -0.5 * pth, - in_tex, out_comp, in_tex, out_comp, in_tex, - in_tex, ttype, in_tex, ttype, in_tex, ttype, in_tex, ttype, - in_tex, ttype, out_comp, strength); + append_template(prog, unsharp_filt_template); break; case YUV_SCALER_UNSHARP2: - snprintf(*prog_pos, *remain, unsharp_filt_template2, - out_comp, 1.2 * ptw, 1.2 * pth, 1.2 * ptw, -1.2 * pth, - out_comp, 1.5 * ptw, 1.5 * pth, - in_tex, out_comp, in_tex, out_comp, in_tex, - in_tex, ttype, in_tex, ttype, in_tex, ttype, in_tex, ttype, - in_tex, ttype, in_tex, out_comp, in_tex, out_comp, - in_tex, ttype, in_tex, ttype, in_tex, ttype, - in_tex, ttype, out_comp, strength); + append_template(prog, unsharp_filt_template2); break; } - *remain -= strlen(*prog_pos); - *prog_pos += strlen(*prog_pos); + + replace_var_char(prog, "texs", texs[0]); + replace_var_char(prog, "in_tex", in_tex); + replace_var_char(prog, "out_comp", out_comp); + replace_var_str(prog, "tex_type", ttype); + replace_var_float(prog, "texw", texw); + replace_var_float(prog, "texh", texh); + replace_var_float(prog, "ptw", ptw); + replace_var_float(prog, "pth", pth); + + // this is silly, not sure if that couldn't be in the shader source instead + replace_var_float(prog, "ptw_05", ptw * 0.5); + replace_var_float(prog, "pth_05", pth * 0.5); + replace_var_float(prog, "ptw_15", ptw * 1.5); + replace_var_float(prog, "pth_15", pth * 1.5); + replace_var_float(prog, "ptw_12", ptw * 1.2); + replace_var_float(prog, "pth_12", pth * 1.2); + + replace_var_float(prog, "strength", strength); } static const struct { @@ -1211,9 +1256,9 @@ static void glSetupYUVFragprog(GL *gl, gl_conversion_params_t *params) "OPTION ARB_precision_hint_fastest;\n" // all scaler variables must go here so they aren't defined // multiple times when the same scaler is used more than once - "TEMP coord, coord2, cdelta, parmx, parmy, a, b, yuv;\n"; - int prog_remain; - char *yuv_prog, *prog_pos; + "TEMP coord, coord2, cdelta, parmx, parmy, a, b, yuv, textemp;\n"; + char *yuv_prog = NULL; + char **prog = &yuv_prog; int cur_texu = 3; char lum_scale_texs[1]; char chrom_scale_texs[1]; @@ -1238,58 +1283,49 @@ static void glSetupYUVFragprog(GL *gl, gl_conversion_params_t *params) mp_msg(MSGT_VO, MSGL_FATAL, "[gl] ProgramString function missing!\n"); return; } - yuv_prog = malloc(MAX_PROGSZ); - strcpy(yuv_prog, prog_hdr); - prog_pos = yuv_prog + sizeof(prog_hdr) - 1; - prog_remain = MAX_PROGSZ - sizeof(prog_hdr); - add_scaler(YUV_LUM_SCALER(type), &prog_pos, &prog_remain, lum_scale_texs, + append_template(prog, prog_hdr); + add_scaler(YUV_LUM_SCALER(type), prog, lum_scale_texs, '0', 'r', rect, texw, texh, params->filter_strength); - add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, + add_scaler(YUV_CHROM_SCALER(type), prog, chrom_scale_texs, '1', 'g', rect, params->chrom_texw, params->chrom_texh, params->filter_strength); - add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, + add_scaler(YUV_CHROM_SCALER(type), prog, chrom_scale_texs, '2', 'b', rect, params->chrom_texw, params->chrom_texh, params->filter_strength); mp_get_yuv2rgb_coeffs(¶ms->csp_params, yuv2rgb); switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_FRAGMENT: - snprintf(prog_pos, prog_remain, yuv_prog_template, - yuv2rgb[ROW_R][COL_Y], yuv2rgb[ROW_G][COL_Y], yuv2rgb[ROW_B][COL_Y], - yuv2rgb[ROW_R][COL_U], yuv2rgb[ROW_G][COL_U], yuv2rgb[ROW_B][COL_U], - yuv2rgb[ROW_R][COL_V], yuv2rgb[ROW_G][COL_V], yuv2rgb[ROW_B][COL_V], - yuv2rgb[ROW_R][COL_C], yuv2rgb[ROW_G][COL_C], yuv2rgb[ROW_B][COL_C]); + append_template(prog, yuv_prog_template); break; case YUV_CONVERSION_FRAGMENT_POW: - snprintf(prog_pos, prog_remain, yuv_pow_prog_template, - yuv2rgb[ROW_R][COL_Y], yuv2rgb[ROW_G][COL_Y], yuv2rgb[ROW_B][COL_Y], - yuv2rgb[ROW_R][COL_U], yuv2rgb[ROW_G][COL_U], yuv2rgb[ROW_B][COL_U], - yuv2rgb[ROW_R][COL_V], yuv2rgb[ROW_G][COL_V], yuv2rgb[ROW_B][COL_V], - yuv2rgb[ROW_R][COL_C], yuv2rgb[ROW_G][COL_C], yuv2rgb[ROW_B][COL_C], - (float)1.0 / params->csp_params.rgamma, - (float)1.0 / params->csp_params.bgamma, - (float)1.0 / params->csp_params.bgamma); + append_template(prog, yuv_pow_prog_template); break; case YUV_CONVERSION_FRAGMENT_LOOKUP: - snprintf(prog_pos, prog_remain, yuv_lookup_prog_template, - yuv2rgb[ROW_R][COL_Y], yuv2rgb[ROW_G][COL_Y], yuv2rgb[ROW_B][COL_Y], - yuv2rgb[ROW_R][COL_U], yuv2rgb[ROW_G][COL_U], yuv2rgb[ROW_B][COL_U], - yuv2rgb[ROW_R][COL_V], yuv2rgb[ROW_G][COL_V], yuv2rgb[ROW_B][COL_V], - yuv2rgb[ROW_R][COL_C], yuv2rgb[ROW_G][COL_C], yuv2rgb[ROW_B][COL_C], - conv_texs[0], conv_texs[0], conv_texs[0]); + append_template(prog, yuv_lookup_prog_template); break; case YUV_CONVERSION_FRAGMENT_LOOKUP3D: - snprintf(prog_pos, prog_remain, yuv_lookup3d_prog_template, - conv_texs[0]); + append_template(prog, yuv_lookup3d_prog_template); break; default: mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type)); break; } + for (int r = 0; r < 3; r++) { + for (int c = 0; c < 4; c++) { + // "cmRC" + char var[] = { 'c', 'm', '1' + r, '1' + c, '\0' }; + replace_var_float(prog, var, yuv2rgb[r][c]); + } + } + replace_var_float(prog, "gamma_r", (float)1.0 / params->csp_params.rgamma); + replace_var_float(prog, "gamma_g", (float)1.0 / params->csp_params.ggamma); + replace_var_float(prog, "gamma_b", (float)1.0 / params->csp_params.bgamma); + replace_var_char(prog, "conv_tex0", conv_texs[0]); mp_msg(MSGT_VO, MSGL_DBG2, "[gl] generated fragment program:\n%s\n", yuv_prog); loadGPUProgram(gl, GL_FRAGMENT_PROGRAM, yuv_prog); - free(yuv_prog); + talloc_free(yuv_prog); } /** |