[vlc-devel] [PATCH] OpenGL: implement by-hand unpack row functionality
Ilkka Ollakka
ileoo at videolan.org
Thu Oct 4 13:23:20 CEST 2012
This uses multiple memcpy so it is really slow, but it should
be faster than uploading line by line to gpu.
---
modules/video_output/opengl.c | 42 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index f099f63..133bb98 100644
--- a/modules/video_output/opengl.c
+++ b/modules/video_output/opengl.c
@@ -181,6 +181,9 @@ struct vout_display_opengl_t {
/* Non-power-of-2 texture size support */
bool supports_npot;
+
+ /* UNPACK_ROW_LENGTH supported */
+ bool supports_unpack;
};
static inline int GetAlignedSize(unsigned size)
@@ -334,6 +337,13 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
vgl->supports_npot = HasExtension( extensions, "GL_ARB_texture_non_power_of_two" ) ||
HasExtension( extensions, "GL_APPLE_texture_2D_limited_npot" );
+#if GL_UNPACK_ROW_LENGTH
+ vgl->supports_unpack = true;
+#else
+ /* Some opengl ES 2 devices have UNPACK_ROW_LENGTH supported via extension, check that */
+ vgl->supports_unpack = HasExtension( extensions, "EXT_unpack_subimage");
+#endif
+
if( !vgl->CreateShader || !vgl->ShaderSource || !vgl->CreateProgram )
{
fprintf(stderr, "Looks like you don't have all the opengl we need. Driver is %s, giving up\n", glGetString(GL_VERSION));
@@ -662,12 +672,37 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
vgl->ClientActiveTexture(GL_TEXTURE0 + j);
}
glBindTexture(vgl->tex_target, vgl->texture[0][j]);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, picture->p[j].i_pitch / picture->p[j].i_pixel_pitch);
- glTexSubImage2D(vgl->tex_target, 0,
+ if( vgl->supports_unpack )
+ {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, picture->p[j].i_pitch / picture->p[j].i_pixel_pitch);
+ glTexSubImage2D(vgl->tex_target, 0,
0, 0,
vgl->fmt.i_width * vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den,
vgl->fmt.i_height * vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den,
vgl->tex_format, vgl->tex_type, picture->p[j].p_pixels);
+ } else if ( (picture->p[j].i_pitch / picture->p[j].i_pixel_pitch) != (vgl->fmt.i_width * vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den) ) {
+ uint8_t *new_plane = malloc( picture->p[j].i_pitch*picture->p[j].i_pixel_pitch *vgl->fmt.i_height * vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den);
+ uint8_t *destination = new_plane;
+ const uint8_t *source = picture->p[j].p_pixels;
+ for( unsigned height = 0; height < vgl->fmt.i_height * vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den; height++ )
+ {
+ memcpy( destination, source, vgl->fmt.i_width * vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den );
+ source += picture->p[j].i_pitch*picture->p[j].i_pixel_pitch;
+ destination += vgl->fmt.i_width * vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den;
+ }
+ glTexSubImage2D( vgl->tex_target, 0,
+ 0, 0,
+ vgl->fmt.i_width * vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den,
+ vgl->fmt.i_height * vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den,
+ vgl->tex_format, vgl->tex_type, new_plane );
+ free( new_plane );
+ } else {
+ glTexSubImage2D(vgl->tex_target, 0,
+ 0, 0,
+ vgl->fmt.i_width * vgl->chroma->p[j].w.num / vgl->chroma->p[j].w.den,
+ vgl->fmt.i_height * vgl->chroma->p[j].h.num / vgl->chroma->p[j].h.den,
+ vgl->tex_format, vgl->tex_type, picture->p[j].p_pixels);
+ }
}
int last_count = vgl->region_count;
@@ -827,7 +862,6 @@ static void draw_with_shaders( vout_display_opengl_t *vgl, float *left, float *t
right[j], bottom[j],
};
vgl->ActiveTexture( GL_TEXTURE0+j);
- vgl->ClientActiveTexture( GL_TEXTURE0+j);
glEnable(vgl->tex_target);
glBindTexture(vgl->tex_target, vgl->texture[0][j]);
if(asprintf( &attribute, "MultiTexCoord%1d", j ) == -1 )
@@ -839,7 +873,6 @@ static void draw_with_shaders( vout_display_opengl_t *vgl, float *left, float *t
attribute = NULL;
}
vgl->ActiveTexture(GL_TEXTURE0 + 0);
- vgl->ClientActiveTexture(GL_TEXTURE0 + 0);
vgl->EnableVertexAttribArray( vgl->GetAttribLocation( vgl->program[0], "vertex_position"));
vgl->VertexAttribPointer( vgl->GetAttribLocation( vgl->program[0], "vertex_position"), 2, GL_FLOAT, 0, 0, vertexCoord);
@@ -898,7 +931,6 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl,
}
vgl->ActiveTexture(GL_TEXTURE0 + 0);
- vgl->ClientActiveTexture(GL_TEXTURE0 + 0);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
--
1.7.12.1
More information about the vlc-devel
mailing list