summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/gl_osd.c25
-rw-r--r--video/out/gl_utils.c21
-rw-r--r--video/out/gl_utils.h21
-rw-r--r--video/out/gl_video.c56
4 files changed, 64 insertions, 59 deletions
diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c
index 7a9532d416..5c203ea626 100644
--- a/video/out/gl_osd.c
+++ b/video/out/gl_osd.c
@@ -294,13 +294,13 @@ static void gen_osd_cb(void *pctx, struct sub_bitmaps *imgs)
osd->num_subparts * sizeof(osd->subparts[0]));
}
-static void write_quad(struct vertex *va, float matrix[3][2],
+static void write_quad(struct vertex *va, struct gl_transform t,
float x0, float y0, float x1, float y1,
float tx0, float ty0, float tx1, float ty1,
float tex_w, float tex_h, const uint8_t color[4])
{
- gl_matrix_mul_vec(matrix, &x0, &y0);
- gl_matrix_mul_vec(matrix, &x1, &y1);
+ gl_transform_vec(t, &x0, &y0);
+ gl_transform_vec(t, &x1, &y1);
#define COLOR_INIT {color[0], color[1], color[2], color[3]}
va[0] = (struct vertex){ {x0, y0}, {tx0 / tex_w, ty0 / tex_h}, COLOR_INIT };
@@ -312,7 +312,7 @@ static void write_quad(struct vertex *va, float matrix[3][2],
#undef COLOR_INIT
}
-static int generate_verts(struct mpgl_osd_part *part, float matrix[3][2])
+static int generate_verts(struct mpgl_osd_part *part, struct gl_transform t)
{
int num_vertices = part->num_subparts * 6;
MP_TARRAY_GROW(part, part->vertices, num_vertices);
@@ -328,7 +328,7 @@ static int generate_verts(struct mpgl_osd_part *part, float matrix[3][2])
uint8_t color[4] = { c >> 24, (c >> 16) & 0xff,
(c >> 8) & 0xff, 255 - (c & 0xff) };
- write_quad(&va[n * 6], matrix,
+ write_quad(&va[n * 6], t,
b->x, b->y, b->x + b->dw, b->y + b->dh,
pos.x, pos.y, pos.x + b->w, pos.y + b->h,
part->w, part->h, color);
@@ -337,12 +337,12 @@ static int generate_verts(struct mpgl_osd_part *part, float matrix[3][2])
return num_vertices;
}
-static void draw_part(struct mpgl_osd *ctx, int index, float matrix[3][2])
+static void draw_part(struct mpgl_osd *ctx, int index, struct gl_transform t)
{
GL *gl = ctx->gl;
struct mpgl_osd_part *part = ctx->parts[index];
- int num_vertices = generate_verts(part, matrix);
+ int num_vertices = generate_verts(part, t);
if (!num_vertices)
return;
@@ -377,16 +377,15 @@ void mpgl_osd_draw_part(struct mpgl_osd *ctx, int vp_w, int vp_h, int index)
for (int x = 0; x < div[0]; x++) {
for (int y = 0; y < div[1]; y++) {
- float matrix[3][2];
-
- gl_matrix_ortho2d(matrix, 0, vp_w, 0, vp_h);
+ struct gl_transform t;
+ gl_transform_ortho(&t, 0, vp_w, 0, vp_h);
float a_x = ctx->display_size[0] * x;
float a_y = ctx->display_size[1] * y;
- matrix[2][0] += a_x * matrix[0][0] + a_y * matrix[1][0];
- matrix[2][1] += a_x * matrix[0][1] + a_y * matrix[1][1];
+ t.t[0] += a_x * t.m[0][0] + a_y * t.m[1][0];
+ t.t[1] += a_x * t.m[0][1] + a_y * t.m[1][1];
- draw_part(ctx, index, matrix);
+ draw_part(ctx, index, t);
}
}
}
diff --git a/video/out/gl_utils.c b/video/out/gl_utils.c
index 9429655bd0..3056ce10cc 100644
--- a/video/out/gl_utils.c
+++ b/video/out/gl_utils.c
@@ -418,20 +418,21 @@ void fbotex_uninit(struct fbotex *fbo)
// Standard parallel 2D projection, except y1 < y0 means that the coordinate
// system is flipped, not the projection.
-void gl_matrix_ortho2d(float m[3][2], float x0, float x1, float y0, float y1)
+void gl_transform_ortho(struct gl_transform *t, float x0, float x1,
+ float y0, float y1)
{
if (y1 < y0) {
- float t = y0;
- y0 = t - y1;
- y1 = t;
+ float tmp = y0;
+ y0 = tmp - y1;
+ y1 = tmp;
}
- m[0][0] = 2.0f / (x1 - x0);
- m[0][1] = 0.0f;
- m[1][0] = 0.0f;
- m[1][1] = 2.0f / (y1 - y0);
- m[2][0] = -(x1 + x0) / (x1 - x0);
- m[2][1] = -(y1 + y0) / (y1 - y0);
+ t->m[0][0] = 2.0f / (x1 - x0);
+ t->m[0][1] = 0.0f;
+ t->m[1][0] = 0.0f;
+ t->m[1][1] = 2.0f / (y1 - y0);
+ t->t[0] = -(x1 + x0) / (x1 - x0);
+ t->t[1] = -(y1 + y0) / (y1 - y0);
}
static void GLAPIENTRY gl_debug_cb(GLenum source, GLenum type, GLuint id,
diff --git a/video/out/gl_utils.h b/video/out/gl_utils.h
index b4f5650ea6..c55ee8acfa 100644
--- a/video/out/gl_utils.h
+++ b/video/out/gl_utils.h
@@ -86,25 +86,32 @@ bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
#define FBOTEX_FUZZY_H 2
void fbotex_set_filter(struct fbotex *fbo, GLenum gl_filter);
-void gl_matrix_ortho2d(float m[3][2], float x0, float x1, float y0, float y1);
+// A 3x2 matrix, with the translation part separate.
+struct gl_transform {
+ float m[2][2];
+ float t[2];
+};
+
+void gl_transform_ortho(struct gl_transform *t, float x0, float x1,
+ float y0, float y1);
// This treats m as an affine transformation, in other words m[2][n] gets
// added to the output.
-static inline void gl_matrix_mul_vec(float m[3][2], float *x, float *y)
+static inline void gl_transform_vec(struct gl_transform t, float *x, float *y)
{
float vx = *x, vy = *y;
- *x = vx * m[0][0] + vy * m[1][0] + m[2][0];
- *y = vx * m[0][1] + vy * m[1][1] + m[2][1];
+ *x = vx * t.m[0][0] + vy * t.m[1][0] + t.t[0];
+ *y = vx * t.m[0][1] + vy * t.m[1][1] + t.t[1];
}
struct mp_rect_f {
float x0, y0, x1, y1;
};
-static inline void gl_matrix_mul_rect(float m[3][2], struct mp_rect_f *r)
+static inline void gl_transform_rect(struct gl_transform t, struct mp_rect_f *r)
{
- gl_matrix_mul_vec(m, &r->x0, &r->y0);
- gl_matrix_mul_vec(m, &r->x1, &r->y1);
+ gl_transform_vec(t, &r->x0, &r->y0);
+ gl_transform_vec(t, &r->x1, &r->y1);
}
void gl_set_debug_logger(GL *gl, struct mp_log *log);
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 0dcd53c2af..c731c3f38d 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -572,9 +572,10 @@ static void pass_load_fbotex(struct gl_video *p, struct fbotex *src_fbo, int id,
}
static void pass_set_image_textures(struct gl_video *p, struct video_image *vimg,
- float chroma[3][2])
+ struct gl_transform *chroma)
{
GLuint imgtex[4] = {0};
+ *chroma = (struct gl_transform){{{0}}};
assert(vimg->mpi);
@@ -592,20 +593,17 @@ static void pass_set_image_textures(struct gl_video *p, struct video_image *vimg
// so that the luma and chroma sample line up exactly.
// For 4:4:4, setting chroma location should have no effect at all.
// luma sample size (in chroma coord. space)
- chroma[2][0] = ls_w < 1 ? ls_w * -cx / 2 : 0;
- chroma[2][1] = ls_h < 1 ? ls_h * -cy / 2 : 0;
- } else {
- chroma[2][0] = chroma[2][1] = 0.0;
+ chroma->t[0] = ls_w < 1 ? ls_w * -cx / 2 : 0;
+ chroma->t[1] = ls_h < 1 ? ls_h * -cy / 2 : 0;
}
// Make sure luma/chroma sizes are aligned.
// Example: For 4:2:0 with size 3x3, the subsampled chroma plane is 2x2
// so luma (3,3) has to align with chroma (2,2).
- chroma[0][0] = ls_w * (float)vimg->planes[0].tex_w
+ chroma->m[0][0] = ls_w * (float)vimg->planes[0].tex_w
/ vimg->planes[1].tex_w;
- chroma[1][1] = ls_h * (float)vimg->planes[0].tex_h
+ chroma->m[1][1] = ls_h * (float)vimg->planes[0].tex_h
/ vimg->planes[1].tex_h;
- chroma[0][1] = chroma[1][0] = 0.0; // No rotation etc.
if (p->hwdec_active) {
p->hwdec->driver->map_image(p->hwdec, vimg->mpi, imgtex);
@@ -768,13 +766,13 @@ static void render_pass_quad(struct gl_video *p, int vp_w, int vp_h,
{
struct vertex va[4];
- float matrix[3][2];
- gl_matrix_ortho2d(matrix, 0, vp_w, 0, vp_h);
+ struct gl_transform t;
+ gl_transform_ortho(&t, 0, vp_w, 0, vp_h);
float x[2] = {dst->x0, dst->x1};
float y[2] = {dst->y0, dst->y1};
- gl_matrix_mul_vec(matrix, &x[0], &y[0]);
- gl_matrix_mul_vec(matrix, &x[1], &y[1]);
+ gl_transform_vec(t, &x[0], &y[0]);
+ gl_transform_vec(t, &x[1], &y[1]);
for (int n = 0; n < 4; n++) {
struct vertex *v = &va[n];
@@ -1005,11 +1003,11 @@ static void pass_sample_separated_gen(struct gl_video *p, struct scaler *scaler,
static void pass_sample_separated(struct gl_video *p, int src_tex,
struct scaler *scaler, int w, int h,
- float transform[3][2])
+ struct gl_transform transform)
{
// Keep the x components untouched for the first pass
struct mp_rect_f src_new = p->pass_tex[src_tex].src;
- gl_matrix_mul_rect(transform, &src_new);
+ gl_transform_rect(transform, &src_new);
GLSLF("// pass 1\n");
p->pass_tex[src_tex].src.y0 = src_new.y0;
p->pass_tex[src_tex].src.y1 = src_new.y1;
@@ -1168,7 +1166,7 @@ static void pass_sample_sharpen5(struct gl_video *p, struct scaler *scaler)
// thrashing, the scaler unit should usually use the same parameters.
static void pass_sample(struct gl_video *p, int src_tex,
int scaler_unit, const char *name, double scale_factor,
- int w, int h, float transform[3][2])
+ int w, int h, struct gl_transform transform)
{
struct scaler *scaler = &p->scalers[scaler_unit];
reinit_scaler(p, scaler_unit, name, scale_factor);
@@ -1180,7 +1178,7 @@ static void pass_sample(struct gl_video *p, int src_tex,
// Set up the transformation for everything other than separated scaling
if (!scaler->kernel || scaler->kernel->polar)
- gl_matrix_mul_rect(transform, &p->pass_tex[src_tex].src);
+ gl_transform_rect(transform, &p->pass_tex[src_tex].src);
// Dispatch the scaler. They're all wildly different.
if (strcmp(scaler->name, "bilinear") == 0) {
@@ -1208,8 +1206,8 @@ static void pass_sample(struct gl_video *p, int src_tex,
// sample from video textures, set "color" variable to yuv value
static void pass_read_video(struct gl_video *p)
{
- float chromafix[3][2];
- pass_set_image_textures(p, &p->image, chromafix);
+ struct gl_transform chromafix;
+ pass_set_image_textures(p, &p->image, &chromafix);
if (p->plane_count == 1) {
GLSL(vec4 color = texture(texture0, texcoord0);)
@@ -1244,11 +1242,11 @@ static void pass_read_video(struct gl_video *p)
} else {
GLSL(vec4 color;)
if (p->plane_count == 2) {
- gl_matrix_mul_rect(chromafix, &p->pass_tex[1].src);
+ gl_transform_rect(chromafix, &p->pass_tex[1].src);
GLSL(vec2 chroma = texture(texture1, texcoord0).rg;) // NV formats
} else {
- gl_matrix_mul_rect(chromafix, &p->pass_tex[1].src);
- gl_matrix_mul_rect(chromafix, &p->pass_tex[2].src);
+ gl_transform_rect(chromafix, &p->pass_tex[1].src);
+ gl_transform_rect(chromafix, &p->pass_tex[2].src);
GLSL(vec2 chroma = vec2(texture(texture1, texcoord1).r,
texture(texture2, texcoord2).r);)
}
@@ -1436,15 +1434,16 @@ static void pass_render_main(struct gl_video *p)
sy = (p->src_rect.y1 - p->src_rect.y0) / (float)p->image_h,
ox = p->src_rect.x0,
oy = p->src_rect.y0;
- float transform[3][2] = {{sx,0.0}, {0.0,sy}, {ox,oy}};
+ struct gl_transform transform = {{{sx,0.0}, {0.0,sy}}, {ox,oy}};
int xc = 0, yc = 1,
vp_w = p->dst_rect.x1 - p->dst_rect.x0,
vp_h = p->dst_rect.y1 - p->dst_rect.y0;
if ((p->image_params.rotate % 180) == 90) {
- for (int n = 0; n < 3; n++)
- MPSWAP(float, transform[n][xc], transform[n][yc]);
+ MPSWAP(float, transform.m[0][xc], transform.m[0][yc]);
+ MPSWAP(float, transform.m[1][xc], transform.m[1][yc]);
+ MPSWAP(float, transform.t[0], transform.t[1]);
MPSWAP(int, xc, yc);
MPSWAP(int, vp_w, vp_h);
}
@@ -1456,13 +1455,12 @@ static void pass_render_main(struct gl_video *p)
// chroma planes (everything except luma=tex0), to make sure the offset
// is scaled to the correct reference frame (in the case of subsampled
// input)
- float tchroma[3][2];
- memcpy(tchroma, transform, sizeof(float[3][2]));
- tchroma[2][xc] /= 1 << p->image_desc.chroma_xs;
- tchroma[2][yc] /= 1 << p->image_desc.chroma_ys;
+ struct gl_transform tchroma = transform;
+ tchroma.t[xc] /= 1 << p->image_desc.chroma_xs;
+ tchroma.t[yc] /= 1 << p->image_desc.chroma_ys;
for (int n = 0; n < p->plane_count; n++)
- gl_matrix_mul_rect(n>0 ? tchroma : transform, &p->pass_tex[n].src);
+ gl_transform_rect(n > 0 ? tchroma : transform, &p->pass_tex[n].src);
} else {
finish_pass_fbo(p, &p->indirect_fbo, p->image_w, p->image_h, 0, 0);
pass_sample(p, 0, 0, scaler, scale_factor, vp_w, vp_h, transform);