summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorBin Jin <bjin@ctrl-d.org>2019-03-12 02:24:51 +0000
committersfan5 <sfan5@live.de>2019-06-06 20:01:56 +0200
commitae1c489b319eab1fe200200c39f58246de75a6f3 (patch)
tree28a9e74588a36b3163fb81443f62e5fa3db6f786 /video/out
parent4d001bb30db6786a44658b0625dc31027767a393 (diff)
downloadmpv-ae1c489b319eab1fe200200c39f58246de75a6f3.tar.bz2
mpv-ae1c489b319eab1fe200200c39f58246de75a6f3.tar.xz
vo_gpu: allow user shader to fix texture offset
This commit essentially makes user shader able to fix offset (produced by other prescaler, for example) like builtin `--scale`.
Diffstat (limited to 'video/out')
-rw-r--r--video/out/gpu/user_shaders.c18
-rw-r--r--video/out/gpu/user_shaders.h1
-rw-r--r--video/out/gpu/video.c35
3 files changed, 45 insertions, 9 deletions
diff --git a/video/out/gpu/user_shaders.c b/video/out/gpu/user_shaders.c
index 0613eb93f6..f0c8a9d19a 100644
--- a/video/out/gpu/user_shaders.c
+++ b/video/out/gpu/user_shaders.c
@@ -170,6 +170,7 @@ static bool parse_hook(struct mp_log *log, struct bstr *body,
*out = (struct gl_user_shader_hook){
.pass_desc = bstr0("(unknown)"),
.offset = identity_trans,
+ .align_offset = false,
.width = {{ SZEXP_VAR_W, { .varname = bstr0("HOOKED") }}},
.height = {{ SZEXP_VAR_H, { .varname = bstr0("HOOKED") }}},
.cond = {{ SZEXP_CONST, { .cval = 1.0 }}},
@@ -221,13 +222,18 @@ static bool parse_hook(struct mp_log *log, struct bstr *body,
}
if (bstr_eatstart0(&line, "OFFSET")) {
- float ox, oy;
- if (bstr_sscanf(line, "%f %f", &ox, &oy) != 2) {
- mp_err(log, "Error while parsing OFFSET!\n");
- return false;
+ line = bstr_strip(line);
+ if (bstr_equals0(line, "ALIGN")) {
+ out->align_offset = true;
+ } else {
+ float ox, oy;
+ if (bstr_sscanf(line, "%f %f", &ox, &oy) != 2) {
+ mp_err(log, "Error while parsing OFFSET!\n");
+ return false;
+ }
+ out->offset.t[0] = ox;
+ out->offset.t[1] = oy;
}
- out->offset.t[0] = ox;
- out->offset.t[1] = oy;
continue;
}
diff --git a/video/out/gpu/user_shaders.h b/video/out/gpu/user_shaders.h
index a477e3ce3d..4bb7c2250f 100644
--- a/video/out/gpu/user_shaders.h
+++ b/video/out/gpu/user_shaders.h
@@ -69,6 +69,7 @@ struct gl_user_shader_hook {
struct bstr save_tex;
struct bstr pass_body;
struct gl_transform offset;
+ bool align_offset;
struct szexp width[MAX_SZEXP_SIZE];
struct szexp height[MAX_SZEXP_SIZE];
struct szexp cond[MAX_SZEXP_SIZE];
diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index fd35d3a2af..c1e4b8c48f 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -121,6 +121,7 @@ struct tex_hook {
const char *hook_tex[SHADER_MAX_HOOKS];
const char *bind_tex[SHADER_MAX_BINDS];
int components; // how many components are relevant (0 = same as input)
+ bool align_offset; // whether to align hooked tex with reference.
void *priv; // this gets talloc_freed when the tex_hook is removed
void (*hook)(struct gl_video *p, struct image img, // generates GLSL
struct gl_transform *trans, void *priv);
@@ -1482,6 +1483,25 @@ found:
continue;
}
+ const char *store_name = hook->save_tex ? hook->save_tex : name;
+ bool is_overwrite = strcmp(store_name, name) == 0;
+
+ // If user shader is set to align HOOKED with reference and fix its
+ // offset, it requires HOOKED to be resizable and overwrited.
+ if (is_overwrite && hook->align_offset) {
+ if (!trans) {
+ MP_ERR(p, "Hook tried to align unresizable texture %s!\n",
+ name);
+ return img;
+ }
+
+ struct gl_transform align_off = identity_trans;
+ align_off.t[0] = trans->t[0];
+ align_off.t[1] = trans->t[1];
+
+ gl_transform_trans(align_off, &img.transform);
+ }
+
if (!pass_hook_setup_binds(p, name, img, hook))
continue;
@@ -1501,13 +1521,12 @@ found:
struct ra_tex **tex = next_hook_tex(p);
finish_pass_tex(p, tex, w, h);
- const char *store_name = hook->save_tex ? hook->save_tex : name;
struct image saved_img = image_wrap(*tex, img.type, comps);
// If the texture we're saving overwrites the "current" texture, also
// update the tex parameter so that the future loop cycles will use the
// updated values, and export the offset
- if (strcmp(store_name, name) == 0) {
+ if (is_overwrite) {
if (!trans && !gl_transform_eq(hook_off, identity_trans)) {
MP_ERR(p, "Hook tried changing size of unscalable texture %s!\n",
name);
@@ -1515,8 +1534,17 @@ found:
}
img = saved_img;
- if (trans)
+ if (trans) {
gl_transform_trans(hook_off, trans);
+
+ // If user shader is set to align HOOKED, the offset it produces
+ // is dynamic (with static resizing factor though).
+ // Align it with reference manually to get offset fixed.
+ if (hook->align_offset) {
+ trans->t[0] = 0.0;
+ trans->t[1] = 0.0;
+ }
+ }
}
saved_img_store(p, store_name, saved_img);
@@ -1955,6 +1983,7 @@ static bool add_user_hook(void *priv, struct gl_user_shader_hook hook)
struct tex_hook texhook = {
.save_tex = bstrdup0(copy, hook.save_tex),
.components = hook.components,
+ .align_offset = hook.align_offset,
.hook = user_hook,
.cond = user_hook_cond,
.priv = copy,