mirror of
https://github.com/mpv-player/mpv
synced 2025-01-11 17:39:38 +00:00
vo_opengl: replace float array with a struct
Slightly less painful, because C arrays suck.
This commit is contained in:
parent
697fb963c2
commit
add208c58a
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user