Commit 876b4634 authored by Romain Vimont's avatar Romain Vimont
Browse files

opengl: update pictures from sampler

The renderer should not know the interop, so it may not be responsible
to upload the textures.

Move the pictures update to sampler.
parent 09732d34
......@@ -783,94 +783,7 @@ int
vlc_gl_renderer_Prepare(struct vlc_gl_renderer *renderer, picture_t *picture)
{
struct vlc_gl_sampler *sampler = renderer->sampler;
const struct vlc_gl_interop *interop = sampler->interop;
const video_format_t *source = &picture->format;
if (source->i_x_offset != sampler->last_source.i_x_offset
|| source->i_y_offset != sampler->last_source.i_y_offset
|| source->i_visible_width != sampler->last_source.i_visible_width
|| source->i_visible_height != sampler->last_source.i_visible_height)
{
memset(sampler->var.TexCoordsMap, 0,
sizeof(sampler->var.TexCoordsMap));
for (unsigned j = 0; j < interop->tex_count; j++)
{
float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
/ sampler->tex_width[j];
float scale_h = (float)interop->texs[j].h.num / interop->texs[j].h.den
/ sampler->tex_height[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 = sampler->var.TexCoordsMap[j];
#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;
#undef COL
#undef ROW
}
sampler->last_source.i_x_offset = source->i_x_offset;
sampler->last_source.i_y_offset = source->i_y_offset;
sampler->last_source.i_visible_width = source->i_visible_width;
sampler->last_source.i_visible_height = source->i_visible_height;
}
/* Update the texture */
return interop->ops->update_textures(interop, sampler->textures,
sampler->tex_width,
sampler->tex_height, picture,
NULL);
return vlc_gl_sampler_Update(sampler, picture);
}
int
......
......@@ -129,3 +129,97 @@ vlc_gl_sampler_Delete(struct vlc_gl_sampler *sampler)
free(sampler);
}
int
vlc_gl_sampler_Update(struct vlc_gl_sampler *sampler, picture_t *picture)
{
const struct vlc_gl_interop *interop = sampler->interop;
const video_format_t *source = &picture->format;
if (source->i_x_offset != sampler->last_source.i_x_offset
|| source->i_y_offset != sampler->last_source.i_y_offset
|| source->i_visible_width != sampler->last_source.i_visible_width
|| source->i_visible_height != sampler->last_source.i_visible_height)
{
memset(sampler->var.TexCoordsMap, 0,
sizeof(sampler->var.TexCoordsMap));
for (unsigned j = 0; j < interop->tex_count; j++)
{
float scale_w = (float)interop->texs[j].w.num / interop->texs[j].w.den
/ sampler->tex_width[j];
float scale_h = (float)interop->texs[j].h.num / interop->texs[j].h.den
/ sampler->tex_height[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 = sampler->var.TexCoordsMap[j];
#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;
#undef COL
#undef ROW
}
sampler->last_source.i_x_offset = source->i_x_offset;
sampler->last_source.i_y_offset = source->i_y_offset;
sampler->last_source.i_visible_width = source->i_visible_width;
sampler->last_source.i_visible_height = source->i_visible_height;
}
/* Update the texture */
return interop->ops->update_textures(interop, sampler->textures,
sampler->tex_width,
sampler->tex_height, picture,
NULL);
}
......@@ -148,6 +148,17 @@ vlc_gl_sampler_New(struct vlc_gl_interop *interop);
void
vlc_gl_sampler_Delete(struct vlc_gl_sampler *sampler);
/**
* Update the input picture
*
* This changes the current input picture, available from the fragment shader.
*
* \param sampler the samplre
* \param picture the new current picture
*/
int
vlc_gl_sampler_Update(struct vlc_gl_sampler *sampler, picture_t *picture);
static inline int
vlc_gl_sampler_FetchLocations(struct vlc_gl_sampler *sampler, GLuint program)
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment