summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/user_shaders.c
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2016-05-12 03:34:47 +0200
committerNiklas Haas <git@nand.wakku.to>2016-05-15 20:42:02 +0200
commit034faaa9d818bd8c1c52c879e383b8e7350d3df5 (patch)
tree18333dad4b120905363456479bafb14fff1db299 /video/out/opengl/user_shaders.c
parent7c3d78fd82d4d1e1a0b15284386d39b4014cb7d1 (diff)
downloadmpv-034faaa9d818bd8c1c52c879e383b8e7350d3df5.tar.bz2
mpv-034faaa9d818bd8c1c52c879e383b8e7350d3df5.tar.xz
vo_opengl: use RPN expressions for user hook sizes
This replaces the previous TRANSFORM by WIDTH, HEIGHT and OFFSET where WIDTH and HEIGHT are RPN expressions. This allows for more fine-grained control over the output size, and also makes sure that overwriting existing textures works more cleanly. (Also add some more useful bstr functions)
Diffstat (limited to 'video/out/opengl/user_shaders.c')
-rw-r--r--video/out/opengl/user_shaders.c84
1 files changed, 77 insertions, 7 deletions
diff --git a/video/out/opengl/user_shaders.c b/video/out/opengl/user_shaders.c
index 0c1b765400..0cf80af115 100644
--- a/video/out/opengl/user_shaders.c
+++ b/video/out/opengl/user_shaders.c
@@ -16,6 +16,54 @@
*/
#include "user_shaders.h"
+#include "ctype.h"
+
+static bool parse_rpn_szexpr(struct bstr line, struct szexp out[MAX_SZEXP_SIZE])
+{
+ int pos = 0;
+
+ while (line.len > 0) {
+ struct bstr word = bstr_strip(bstr_splitchar(line, &line, ' '));
+ if (word.len == 0)
+ continue;
+
+ if (pos >= MAX_SZEXP_SIZE)
+ return false;
+
+ struct szexp *exp = &out[pos++];
+
+ if (bstr_eatend0(&word, ".w") || bstr_eatend0(&word, ".width")) {
+ exp->tag = SZEXP_VAR_W;
+ exp->val.varname = word;
+ continue;
+ }
+
+ if (bstr_eatend0(&word, ".h") || bstr_eatend0(&word, ".height")) {
+ exp->tag = SZEXP_VAR_H;
+ exp->val.varname = word;
+ continue;
+ }
+
+ switch (word.start[0]) {
+ case '+': exp->tag = SZEXP_OP2; exp->val.op = SZEXP_OP_ADD; continue;
+ case '-': exp->tag = SZEXP_OP2; exp->val.op = SZEXP_OP_SUB; continue;
+ case '*': exp->tag = SZEXP_OP2; exp->val.op = SZEXP_OP_MUL; continue;
+ case '/': exp->tag = SZEXP_OP2; exp->val.op = SZEXP_OP_DIV; continue;
+ }
+
+ if (isdigit(word.start[0])) {
+ exp->tag = SZEXP_CONST;
+ if (bstr_sscanf(word, "%f", &exp->val.cval) != 1)
+ return false;
+ continue;
+ }
+
+ // Some sort of illegal expression
+ return false;
+ }
+
+ return true;
+}
// Returns false if no more shaders could be parsed
bool parse_user_shader_pass(struct mp_log *log, struct bstr *body,
@@ -24,14 +72,19 @@ bool parse_user_shader_pass(struct mp_log *log, struct bstr *body,
if (!body || !out || !body->start || body->len == 0)
return false;
- *out = (struct gl_user_shader){ .transform = identity_trans };
+ *out = (struct gl_user_shader){
+ .offset = identity_trans,
+ .width = {{ SZEXP_VAR_W, { .varname = bstr0("HOOKED") }}},
+ .height = {{ SZEXP_VAR_H, { .varname = bstr0("HOOKED") }}},
+ };
+
int hook_idx = 0;
int bind_idx = 0;
// First parse all the headers
while (true) {
struct bstr rest;
- struct bstr line = bstr_getline(*body, &rest);
+ struct bstr line = bstr_strip(bstr_getline(*body, &rest));
// Check for the presence of the magic line beginning
if (!bstr_eatstart0(&line, "//!"))
@@ -65,13 +118,30 @@ bool parse_user_shader_pass(struct mp_log *log, struct bstr *body,
continue;
}
- if (bstr_eatstart0(&line, "TRANSFORM")) {
- float sx, sy, ox, oy;
- if (bstr_sscanf(line, "%f %f %f %f", &sx, &sy, &ox, &oy) != 4) {
- mp_err(log, "Error while parsing TRANSFORM!\n");
+ 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;
+ }
+ out->offset.t[0] = ox;
+ out->offset.t[1] = oy;
+ continue;
+ }
+
+ if (bstr_eatstart0(&line, "WIDTH")) {
+ if (!parse_rpn_szexpr(line, out->width)) {
+ mp_err(log, "Error while parsing WIDTH!\n");
+ return false;
+ }
+ continue;
+ }
+
+ if (bstr_eatstart0(&line, "HEIGHT")) {
+ if (!parse_rpn_szexpr(line, out->height)) {
+ mp_err(log, "Error while parsing HEIGHT!\n");
return false;
}
- out->transform = (struct gl_transform){{{sx, 0}, {0, sy}}, {ox, oy}};
continue;
}