diff options
-rw-r--r-- | video/out/gl_osd.c | 25 | ||||
-rw-r--r-- | video/out/gl_utils.c | 21 | ||||
-rw-r--r-- | video/out/gl_utils.h | 21 | ||||
-rw-r--r-- | video/out/gl_video.c | 56 |
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); |