[vlc-commits] [Git][videolan/vlc][master] 2 commits: opengl: simplify TexSize multiplication
Romain Vimont (@rom1v)
gitlab at videolan.org
Thu Sep 23 12:11:26 UTC 2021
Romain Vimont pushed to branch master at VideoLAN / VLC
Commits:
893aa567 by Romain Vimont at 2021-09-23T11:52:37+00:00
opengl: simplify TexSize multiplication
Multiply two vec2 directly instead of multiplying their components
separately.
- - - - -
499b7ef7 by Romain Vimont at 2021-09-23T11:52:37+00:00
opengl: simplify TexCoordsMaps in sampler
The input picture may contain padding, for two reasons:
1. the rectangle defined by the picture_t offset and visible width and
height may not cover the whole picture size;
2. if the OpenGL API does not support NPOT textures, textures are
created with power-of-two dimensions.
As a consequence, for sampling, the coordinates (between 0 and 1 in both
dimensions) must be transformed to take the padding into account.
These transformations were computed and performed per-plane. Therefore,
there were _n_ "TexCoordsMaps" matrices for a picture with _n_ planes.
However, these transformations are necessarily the same for all planes:
1. the picture_t offset/sizes are defined for the whole picture (then
scaled appropriately for each plane);
2. since the ratio between different planes of the same pictures is
always a power of two (e.g. in YUV 4:2:0, the size of U and V planes
are half the size of the Y plane in both dimensions), this property
holds even if we align the dimensions of each plane texture to the
next power-of-two.
Therefore, use a single transformation matrix.
- - - - -
1 changed file:
- modules/video_output/opengl/sampler.c
Changes:
=====================================
modules/video_output/opengl/sampler.c
=====================================
@@ -48,7 +48,7 @@ struct vlc_gl_sampler_priv {
struct {
GLfloat OrientationMatrix[4*4];
- GLfloat TexCoordsMaps[PICTURE_PLANE_MAX][3*3];
+ GLfloat TexCoordsMap[3*3];
} var;
struct {
GLint Textures[PICTURE_PLANE_MAX];
@@ -58,7 +58,7 @@ struct vlc_gl_sampler_priv {
GLint TransformMatrix;
GLint OrientationMatrix;
- GLint TexCoordsMaps[PICTURE_PLANE_MAX];
+ GLint TexCoordsMap;
} uloc;
bool yuv_color;
@@ -296,19 +296,18 @@ sampler_base_fetch_locations(struct vlc_gl_sampler *sampler, GLuint program)
vt->GetUniformLocation(program, "OrientationMatrix");
assert(priv->uloc.OrientationMatrix != -1);
+ priv->uloc.TexCoordsMap = vt->GetUniformLocation(program, "TexCoordsMap");
+ assert(priv->uloc.TexCoordsMap != -1);
+
assert(sampler->tex_count < 10); /* to guarantee variable names length */
for (unsigned int i = 0; i < sampler->tex_count; ++i)
{
- char name[sizeof("TexCoordsMaps[X]")];
+ char name[sizeof("Textures[X]")];
snprintf(name, sizeof(name), "Textures[%1u]", i);
priv->uloc.Textures[i] = vt->GetUniformLocation(program, name);
assert(priv->uloc.Textures[i] != -1);
- snprintf(name, sizeof(name), "TexCoordsMaps[%1u]", i);
- priv->uloc.TexCoordsMaps[i] = vt->GetUniformLocation(program, name);
- assert(priv->uloc.TexCoordsMaps[i] != -1);
-
if (priv->tex_target == GL_TEXTURE_RECTANGLE)
{
snprintf(name, sizeof(name), "TexSizes[%1u]", i);
@@ -356,10 +355,11 @@ sampler_base_load(struct vlc_gl_sampler *sampler)
vt->ActiveTexture(GL_TEXTURE0 + i);
vt->BindTexture(priv->tex_target, priv->textures[i]);
- vt->UniformMatrix3fv(priv->uloc.TexCoordsMaps[i], 1, GL_FALSE,
- priv->var.TexCoordsMaps[i]);
}
+ vt->UniformMatrix3fv(priv->uloc.TexCoordsMap, 1, GL_FALSE,
+ priv->var.TexCoordsMap);
+
/* Return the expected transform matrix if interop == NULL */
const GLfloat *tm = GetTransformMatrix(priv->interop);
vt->UniformMatrix4fv(priv->uloc.TransformMatrix, 1, GL_FALSE, tm);
@@ -425,9 +425,8 @@ sampler_xyz12_fetch_locations(struct vlc_gl_sampler *sampler, GLuint program)
vt->GetUniformLocation(program, "OrientationMatrix");
assert(priv->uloc.OrientationMatrix != -1);
- priv->uloc.TexCoordsMaps[0] =
- vt->GetUniformLocation(program, "TexCoordsMaps[0]");
- assert(priv->uloc.TexCoordsMaps[0] != -1);
+ priv->uloc.TexCoordsMap = vt->GetUniformLocation(program, "TexCoordsMap");
+ assert(priv->uloc.TexCoordsMap != -1);
}
static void
@@ -442,8 +441,8 @@ sampler_xyz12_load(struct vlc_gl_sampler *sampler)
vt->ActiveTexture(GL_TEXTURE0);
vt->BindTexture(priv->tex_target, priv->textures[0]);
- vt->UniformMatrix3fv(priv->uloc.TexCoordsMaps[0], 1, GL_FALSE,
- priv->var.TexCoordsMaps[0]);
+ vt->UniformMatrix3fv(priv->uloc.TexCoordsMap, 1, GL_FALSE,
+ priv->var.TexCoordsMap);
/* Return the expected transform matrix if interop == NULL */
const GLfloat *tm = GetTransformMatrix(priv->interop);
@@ -482,13 +481,11 @@ xyz12_shader_init(struct vlc_gl_sampler *sampler)
"uniform mat4 TransformMatrix;\n"
"uniform mat4 OrientationMatrix;\n"
- "uniform mat3 TexCoordsMaps[1];\n"
+ "uniform mat3 TexCoordsMap;\n"
"vec4 vlc_texture(vec2 pic_coords)\n"
"{ "
" vec4 v_in, v_out;"
- /* Homogeneous (oriented) coordinates */
- " vec3 pic_hcoords = vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).st, 1.0);\n"
- " vec2 tex_coords = (TexCoordsMaps[0] * pic_hcoords).st;\n"
+ " vec2 tex_coords = (TexCoordsMap * vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).xy, 1.0)).xy;\n"
" v_in = texture2D(Textures[0], tex_coords);\n"
" v_in = pow(v_in, xyz_gamma);"
" v_out = matrix_xyz_rgb * v_in ;"
@@ -778,9 +775,8 @@ sampler_planes_fetch_locations(struct vlc_gl_sampler *sampler, GLuint program)
priv->uloc.Textures[0] = vt->GetUniformLocation(program, "Texture");
assert(priv->uloc.Textures[0] != -1);
- priv->uloc.TexCoordsMaps[0] =
- vt->GetUniformLocation(program, "TexCoordsMap");
- assert(priv->uloc.TexCoordsMaps[0] != -1);
+ priv->uloc.TexCoordsMap = vt->GetUniformLocation(program, "TexCoordsMap");
+ assert(priv->uloc.TexCoordsMap != -1);
if (priv->tex_target == GL_TEXTURE_RECTANGLE)
{
@@ -803,13 +799,8 @@ sampler_planes_load(struct vlc_gl_sampler *sampler)
vt->ActiveTexture(GL_TEXTURE0);
vt->BindTexture(priv->tex_target, priv->textures[plane]);
- /* Only one TexCoordMap matrix is necessary in the shader (its location is
- * stored in uloc.TexCoordsMaps[0]), as there is only one plane per
- * execution. However, for a single picture, there are several coords
- * mapping matrices (one per plane), so the correct one
- * (var.TexCoordsMaps[plane]) must be bound. */
- vt->UniformMatrix3fv(priv->uloc.TexCoordsMaps[0], 1, GL_FALSE,
- priv->var.TexCoordsMaps[plane]);
+ vt->UniformMatrix3fv(priv->uloc.TexCoordsMap, 1, GL_FALSE,
+ priv->var.TexCoordsMap);
/* Return the expected transform matrix if interop == NULL */
const GLfloat *tm = GetTransformMatrix(priv->interop);
@@ -851,15 +842,12 @@ sampler_planes_init(struct vlc_gl_sampler *sampler)
ADD("uniform vec2 TexSize;\n");
ADD("vec4 vlc_texture(vec2 pic_coords) {\n"
- /* Homogeneous (oriented) coordinates */
- " vec3 pic_hcoords = vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).st, 1.0);\n"
- " vec2 tex_coords = (TexCoordsMap * pic_hcoords).st;\n");
+ " vec2 tex_coords = (TexCoordsMap * vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).xy, 1.0)).xy;\n");
if (tex_target == GL_TEXTURE_RECTANGLE)
{
/* The coordinates are in texels values, not normalized */
- ADD(" tex_coords = vec2(tex_coords.x * TexSize.x,\n"
- " tex_coords.y * TexSize.y);\n");
+ ADD(" tex_coords = TexSize * tex_coords;\n");
}
ADDF(" return %s(Texture, tex_coords);\n", texture_fn);
@@ -944,7 +932,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
ADD("uniform mat4 TransformMatrix;\n"
"uniform mat4 OrientationMatrix;\n");
ADDF("uniform %s Textures[%u];\n", glsl_sampler, tex_count);
- ADDF("uniform mat3 TexCoordsMaps[%u];\n", tex_count);
+ ADD("uniform mat3 TexCoordsMap;\n");
#ifdef HAVE_LIBPLACEBO
if (priv->pl_sh) {
@@ -1034,9 +1022,7 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
ADD("uniform mat4 ConvMatrix;\n");
ADD("vec4 vlc_texture(vec2 pic_coords) {\n"
- /* Homogeneous (oriented) coordinates */
- " vec3 pic_hcoords = vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).st, 1.0);\n"
- " vec2 tex_coords;\n");
+ " vec2 tex_coords = (TexCoordsMap * vec3((TransformMatrix * OrientationMatrix * vec4(pic_coords, 0.0, 1.0)).xy, 1.0)).xy;\n");
unsigned color_count;
if (is_yuv) {
@@ -1048,14 +1034,15 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
const char *swizzle = swizzle_per_tex[i];
assert(swizzle);
size_t swizzle_count = strlen(swizzle);
- ADDF(" tex_coords = (TexCoordsMaps[%u] * pic_hcoords).st;\n", i);
if (tex_target == GL_TEXTURE_RECTANGLE)
{
/* The coordinates are in texels values, not normalized */
- ADDF(" tex_coords = vec2(tex_coords.x * TexSizes[%u].x,\n"
- " tex_coords.y * TexSizes[%u].y);\n", i, i);
+ ADDF(" texel = %s(Textures[%u], TexSizes[%u] * tex_coords);\n", lookup, i, i);
+ }
+ else
+ {
+ ADDF(" texel = %s(Textures[%u], tex_coords);\n", lookup, i);
}
- ADDF(" texel = %s(Textures[%u], tex_coords);\n", lookup, i);
for (unsigned j = 0; j < swizzle_count; ++j)
{
ADDF(" pixel[%u] = texel.%c;\n", color_idx, swizzle[j]);
@@ -1068,7 +1055,6 @@ opengl_fragment_shader_init(struct vlc_gl_sampler *sampler, GLenum tex_target,
}
else
{
- ADD(" tex_coords = (TexCoordsMaps[0] * pic_hcoords).st;\n");
if (tex_target == GL_TEXTURE_RECTANGLE)
ADD(" tex_coords *= TexSizes[0];\n");
@@ -1178,12 +1164,9 @@ CreateSampler(struct vlc_gl_interop *interop, struct vlc_gl_t *gl,
unsigned tex_count = sampler->tex_count;
assert(!interop || interop->tex_count == tex_count);
- for (unsigned i = 0; i < tex_count; ++i)
- {
- /* This might be updated in UpdatePicture for non-direct samplers */
- memcpy(&priv->var.TexCoordsMaps[i], MATRIX3_IDENTITY,
- sizeof(MATRIX3_IDENTITY));
- }
+ /* This might be updated in UpdatePicture for non-direct samplers */
+ memcpy(&priv->var.TexCoordsMap, MATRIX3_IDENTITY,
+ sizeof(MATRIX3_IDENTITY));
if (interop)
{
@@ -1275,74 +1258,74 @@ vlc_gl_sampler_UpdatePicture(struct vlc_gl_sampler *sampler, picture_t *picture)
|| source->i_visible_width != priv->last_source.i_visible_width
|| source->i_visible_height != priv->last_source.i_visible_height)
{
- memset(priv->var.TexCoordsMaps, 0, sizeof(priv->var.TexCoordsMaps));
- for (unsigned j = 0; j < interop->tex_count; j++)
- {
- float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
- / priv->tex_widths[j];
- float scale_h = (float)interop->texs[j].h.num / interop->texs[j].h.den
- / priv->tex_heights[j];
-
- /* Warning: if NPOT is not supported a larger texture is
- allocated. This will cause right and bottom coordinates to
- land on the edge of two texels with the texels to the
- right/bottom uninitialized by the call to
- glTexSubImage2D. This might cause a green line to appear on
- the right/bottom of the display.
- There are two possible solutions:
- - Manually mirror the edges of the texture.
- - Add a "-1" when computing right and bottom, however the
- last row/column might not be displayed at all.
- */
- float left = (source->i_x_offset + 0 ) * scale_w;
- float top = (source->i_y_offset + 0 ) * scale_h;
- float right = (source->i_x_offset + source->i_visible_width ) * scale_w;
- float bottom = (source->i_y_offset + source->i_visible_height) * scale_h;
-
- /**
- * This matrix converts from picture coordinates (in range [0; 1])
- * to textures coordinates where the picture is actually stored
- * (removing paddings).
- *
- * texture (in texture coordinates)
- * +----------------+--- 0.0
- * | |
- * | +---------+---|--- top
- * | | picture | |
- * | +---------+---|--- bottom
- * | . . |
- * | . . |
- * +----------------+--- 1.0
- * | . . |
- * 0.0 left right 1.0 (in texture coordinates)
- *
- * In particular:
- * - (0.0, 0.0) is mapped to (left, top)
- * - (1.0, 1.0) is mapped to (right, bottom)
- *
- * This is an affine 2D transformation, so the input coordinates
- * are given as a 3D vector in the form (x, y, 1), and the output
- * is (x', y', 1).
- *
- * The paddings are l (left), r (right), t (top) and b (bottom).
- *
- * / (r-l) 0 l \
- * matrix = | 0 (b-t) t |
- * \ 0 0 1 /
- *
- * It is stored in column-major order.
- */
- GLfloat *matrix = priv->var.TexCoordsMaps[j];
+ memset(priv->var.TexCoordsMap, 0, sizeof(priv->var.TexCoordsMap));
+
+ /* The transformation is the same for all planes, even with power-of-two
+ * textures. */
+ float scale_w = (float)interop->texs[0].w.num / interop->texs[0].w.den
+ / priv->tex_widths[0];
+ float scale_h = (float)interop->texs[0].h.num / interop->texs[0].h.den
+ / priv->tex_heights[0];
+
+ /* Warning: if NPOT is not supported a larger texture is
+ allocated. This will cause right and bottom coordinates to
+ land on the edge of two texels with the texels to the
+ right/bottom uninitialized by the call to
+ glTexSubImage2D. This might cause a green line to appear on
+ the right/bottom of the display.
+ There are two possible solutions:
+ - Manually mirror the edges of the texture.
+ - Add a "-1" when computing right and bottom, however the
+ last row/column might not be displayed at all.
+ */
+ float left = (source->i_x_offset + 0 ) * scale_w;
+ float top = (source->i_y_offset + 0 ) * scale_h;
+ float right = (source->i_x_offset + source->i_visible_width ) * scale_w;
+ float bottom = (source->i_y_offset + source->i_visible_height) * scale_h;
+
+ /**
+ * This matrix converts from picture coordinates (in range [0; 1])
+ * to textures coordinates where the picture is actually stored
+ * (removing paddings).
+ *
+ * texture (in texture coordinates)
+ * +----------------+--- 0.0
+ * | |
+ * | +---------+---|--- top
+ * | | picture | |
+ * | +---------+---|--- bottom
+ * | . . |
+ * | . . |
+ * +----------------+--- 1.0
+ * | . . |
+ * 0.0 left right 1.0 (in texture coordinates)
+ *
+ * In particular:
+ * - (0.0, 0.0) is mapped to (left, top)
+ * - (1.0, 1.0) is mapped to (right, bottom)
+ *
+ * This is an affine 2D transformation, so the input coordinates
+ * are given as a 3D vector in the form (x, y, 1), and the output
+ * is (x', y', 1).
+ *
+ * The paddings are l (left), r (right), t (top) and b (bottom).
+ *
+ * / (r-l) 0 l \
+ * matrix = | 0 (b-t) t |
+ * \ 0 0 1 /
+ *
+ * It is stored in column-major order.
+ */
+ GLfloat *matrix = priv->var.TexCoordsMap;
#define COL(x) (x*3)
#define ROW(x) (x)
- matrix[COL(0) + ROW(0)] = right - left;
- matrix[COL(1) + ROW(1)] = bottom - top;
- matrix[COL(2) + ROW(0)] = left;
- matrix[COL(2) + ROW(1)] = top;
- matrix[COL(2) + ROW(2)] = 1;
+ matrix[COL(0) + ROW(0)] = right - left;
+ matrix[COL(1) + ROW(1)] = bottom - top;
+ matrix[COL(2) + ROW(0)] = left;
+ matrix[COL(2) + ROW(1)] = top;
+ matrix[COL(2) + ROW(2)] = 1;
#undef COL
#undef ROW
- }
priv->last_source.i_x_offset = source->i_x_offset;
priv->last_source.i_y_offset = source->i_y_offset;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/48d50cdf85df551772fd3778db2933cc7aa88e81...499b7ef7aab93826765cd0dc4bdd66bebe3b6bab
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/48d50cdf85df551772fd3778db2933cc7aa88e81...499b7ef7aab93826765cd0dc4bdd66bebe3b6bab
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list