mirror of
https://github.com/mpv-player/mpv
synced 2025-01-25 00:53:22 +00:00
aac04c0d64
Actually GL-specific parts go into gl_utils.c/h, the shader cache (gl_sc*) into shader_cache.c/h. No semantic changes of any kind, except that the VAO helper is made public again as part of gl_utils.c (all while the goal for gl_utils.c itself is to be included by GL-specific code).
121 lines
3.4 KiB
C
121 lines
3.4 KiB
C
#include "common/msg.h"
|
|
#include "utils.h"
|
|
|
|
// Standard parallel 2D projection, except y1 < y0 means that the coordinate
|
|
// system is flipped, not the projection.
|
|
void gl_transform_ortho(struct gl_transform *t, float x0, float x1,
|
|
float y0, float y1)
|
|
{
|
|
if (y1 < y0) {
|
|
float tmp = y0;
|
|
y0 = tmp - y1;
|
|
y1 = tmp;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// Apply the effects of one transformation to another, transforming it in the
|
|
// process. In other words: post-composes t onto x
|
|
void gl_transform_trans(struct gl_transform t, struct gl_transform *x)
|
|
{
|
|
struct gl_transform xt = *x;
|
|
x->m[0][0] = t.m[0][0] * xt.m[0][0] + t.m[0][1] * xt.m[1][0];
|
|
x->m[1][0] = t.m[1][0] * xt.m[0][0] + t.m[1][1] * xt.m[1][0];
|
|
x->m[0][1] = t.m[0][0] * xt.m[0][1] + t.m[0][1] * xt.m[1][1];
|
|
x->m[1][1] = t.m[1][0] * xt.m[0][1] + t.m[1][1] * xt.m[1][1];
|
|
gl_transform_vec(t, &x->t[0], &x->t[1]);
|
|
}
|
|
|
|
// Create a texture and a FBO using the texture as color attachments.
|
|
// fmt: texture internal format
|
|
// Returns success.
|
|
bool fbotex_init(struct fbotex *fbo, struct ra *ra, struct mp_log *log,
|
|
int w, int h, const struct ra_format *fmt)
|
|
{
|
|
assert(!fbo->tex);
|
|
return fbotex_change(fbo, ra, log, w, h, fmt, 0);
|
|
}
|
|
|
|
// Like fbotex_init(), except it can be called on an already initialized FBO;
|
|
// and if the parameters are the same as the previous call, do not touch it.
|
|
// flags can be 0, or a combination of FBOTEX_FUZZY_W and FBOTEX_FUZZY_H.
|
|
// Enabling FUZZY for W or H means the w or h does not need to be exact.
|
|
bool fbotex_change(struct fbotex *fbo, struct ra *ra, struct mp_log *log,
|
|
int w, int h, const struct ra_format *fmt, int flags)
|
|
{
|
|
if (fbo->tex) {
|
|
int cw = w, ch = h;
|
|
int rw = fbo->tex->params.w, rh = fbo->tex->params.h;
|
|
|
|
if ((flags & FBOTEX_FUZZY_W) && cw < rw)
|
|
cw = rw;
|
|
if ((flags & FBOTEX_FUZZY_H) && ch < rh)
|
|
ch = rh;
|
|
|
|
if (rw == cw && rh == ch && fbo->tex->params.format == fmt) {
|
|
fbo->lw = w;
|
|
fbo->lh = h;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
int lw = w, lh = h;
|
|
|
|
if (flags & FBOTEX_FUZZY_W)
|
|
w = MP_ALIGN_UP(w, 256);
|
|
if (flags & FBOTEX_FUZZY_H)
|
|
h = MP_ALIGN_UP(h, 256);
|
|
|
|
mp_verbose(log, "Create FBO: %dx%d (%dx%d)\n", lw, lh, w, h);
|
|
|
|
if (!fmt || !fmt->renderable || !fmt->linear_filter) {
|
|
mp_err(log, "Format %s not supported.\n", fmt ? fmt->name : "(unset)");
|
|
return false;
|
|
}
|
|
|
|
fbotex_uninit(fbo);
|
|
|
|
*fbo = (struct fbotex) {
|
|
.ra = ra,
|
|
.rw = w,
|
|
.rh = h,
|
|
.lw = lw,
|
|
.lh = lh,
|
|
};
|
|
|
|
struct ra_tex_params params = {
|
|
.dimensions = 2,
|
|
.w = w,
|
|
.h = h,
|
|
.d = 1,
|
|
.format = fmt,
|
|
.src_linear = true,
|
|
.render_src = true,
|
|
.render_dst = true,
|
|
};
|
|
|
|
fbo->tex = ra_tex_create(fbo->ra, ¶ms);
|
|
|
|
if (!fbo->tex) {
|
|
mp_err(log, "Error: framebuffer could not be created.\n");
|
|
fbotex_uninit(fbo);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void fbotex_uninit(struct fbotex *fbo)
|
|
{
|
|
if (fbo->ra) {
|
|
ra_tex_free(fbo->ra, &fbo->tex);
|
|
*fbo = (struct fbotex) {0};
|
|
}
|
|
}
|