[vlc-devel] [PATCH] opengl: use buffer objects instead of host memory with glVertexAttribPointer.

Rémi Denis-Courmont remi at remlab.net
Wed Mar 26 21:35:49 CET 2014


Le mercredi 26 mars 2014, 18:33:56 Felix Abecassis a écrit :
> Previously, glVertexAttribPointer was called in function
> DrawWithShaders using an host array (textureCoord) allocated on the
> stack inside a loop. This caused stack buffer overflow afterwards.
> 
> See http://www.opengl.org/wiki/Synchronization#Asynchronous_action
> 
> Array definition could have been hoisted out of the loop but using
> buffer objects is a better solution since it is now the only option
> with recent OpenGL versions.
> ---
>  modules/video_output/opengl.c | 40 ++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 38 insertions(+), 2 deletions(-)
> 
> diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
> index 512429e..a5abdc3 100644
> --- a/modules/video_output/opengl.c
> +++ b/modules/video_output/opengl.c
> @@ -62,6 +62,10 @@
>  #   define PFNGLUSEPROGRAMPROC               typeof(glUseProgram)*
>  #   define PFNGLDELETEPROGRAMPROC            typeof(glDeleteProgram)*
>  #   define PFNGLATTACHSHADERPROC             typeof(glAttachShader)*
> +#   define PFNGLGENBUFFERSPROC               typeof(glGenBuffers)*
> +#   define PFNGLBINDBUFFERPROC               typeof(glBindBuffer)*
> +#   define PFNGLBUFFERDATAPROC               typeof(glBufferData)*
> +#   define PFNGLDELETEBUFFERSPROC            typeof(glDeleteBuffers)*
>  #if defined(__APPLE__) && USE_OPENGL_ES
>  #   import <CoreFoundation/CoreFoundation.h>
>  #endif
> @@ -140,6 +144,9 @@ struct vout_display_opengl_t {
>      int        local_count;
>      GLfloat    local_value[16];
> 
> +    GLuint vertex_buffer_object;
> +    GLuint texture_buffer_object[PICTURE_PLANE_MAX];
> +
>      /* Shader variables commands*/
>  #ifdef SUPPORTS_SHADERS
>      PFNGLGETUNIFORMLOCATIONPROC      GetUniformLocation;
> @@ -170,6 +177,11 @@ struct vout_display_opengl_t {
>      PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
>      PFNGLGETSHADERIVPROC   GetShaderiv;
>      PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
> +
> +    PFNGLGENBUFFERSPROC    GenBuffers;
> +    PFNGLBINDBUFFERPROC    BindBuffer;
> +    PFNGLBUFFERDATAPROC    BufferData;
> +    PFNGLDELETEBUFFERSPROC DeleteBuffers;
>  #endif
> 
>  #if defined(_WIN32)
> @@ -444,6 +456,12 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, vgl->LinkProgram   =
> glLinkProgram;
>      vgl->UseProgram    = glUseProgram;
>      vgl->DeleteProgram = glDeleteProgram;
> +
> +    vgl->GenBuffers    = glGenBuffers;
> +    vgl->BindBuffer    = glBindBuffer;
> +    vgl->BufferData    = glBufferData;
> +    vgl->DeleteBuffers = glDeleteBuffers;
> +
>      supports_shaders = true;
>  #elif defined(SUPPORTS_SHADERS)
>      vgl->CreateShader  =
> (PFNGLCREATESHADERPROC)vlc_gl_GetProcAddress(vgl->gl, "glCreateShader"); @@
> -472,6 +490,11 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, vgl->UseProgram    =
> (PFNGLUSEPROGRAMPROC)vlc_gl_GetProcAddress(vgl->gl, "glUseProgram");
> vgl->DeleteProgram = (PFNGLDELETEPROGRAMPROC)vlc_gl_GetProcAddress(vgl->gl,
> "glDeleteProgram");
> 
> +    vgl->GenBuffers    =
> (PFNGLGENBUFFERSPROC)vlc_gl_GetProcAddress(vgl->gl, "glGenBuffers"); +   
> vgl->BindBuffer    = (PFNGLBINDBUFFERPROC)vlc_gl_GetProcAddress(vgl->gl,
> "glBindBuffer"); +    vgl->BufferData    =
> (PFNGLBUFFERDATAPROC)vlc_gl_GetProcAddress(vgl->gl, "glBufferData"); +   
> vgl->DeleteBuffers = (PFNGLDELETEBUFFERSPROC)vlc_gl_GetProcAddress(vgl->gl,
> "glDeleteBuffers"); +
>      if (!vgl->CreateShader || !vgl->ShaderSource || !vgl->CreateProgram)
>          supports_shaders = false;
>  #endif
> @@ -657,6 +680,11 @@ vout_display_opengl_t
> *vout_display_opengl_New(video_format_t *fmt, glClearColor(0.0f, 0.0f,
> 0.0f, 1.0f);
>      glClear(GL_COLOR_BUFFER_BIT);
> 
> +#ifdef SUPPORTS_SHADERS
> +    vgl->GenBuffers(1, &vgl->vertex_buffer_object);
> +    vgl->GenBuffers(vgl->chroma->plane_count, vgl->texture_buffer_object);
> +#endif

I suspect this jump to NULL if the OpenGL version is less than 1.5...

> +
>      vlc_gl_Unlock(vgl->gl);
> 
>      /* */
> @@ -696,6 +724,8 @@ void vout_display_opengl_Delete(vout_display_opengl_t
> *vgl) for (int i = 0; i < 3; i++)
>                  vgl->DeleteShader(vgl->shader[i]);
>          }
> +        vgl->DeleteBuffers(1, &vgl->vertex_buffer_object);
> +        vgl->DeleteBuffers(vgl->chroma->plane_count,
> vgl->texture_buffer_object); #endif
> 
>          free(vgl->texture_temp_buf);
> @@ -1113,15 +1143,21 @@ static void DrawWithShaders(vout_display_opengl_t
> *vgl, glClientActiveTexture(GL_TEXTURE0+j);
>          glBindTexture(vgl->tex_target, vgl->texture[0][j]);
> 
> +        vgl->BindBuffer(GL_ARRAY_BUFFER, vgl->texture_buffer_object[j]);
> +        vgl->BufferData(GL_ARRAY_BUFFER, sizeof(textureCoord),
> textureCoord, GL_STATIC_DRAW); +
>          char attribute[20];
>          snprintf(attribute, sizeof(attribute), "MultiTexCoord%1d", j);
>         
> vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program],
> attribute)); -       
> vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program],
> attribute), 2, GL_FLOAT, 0, 0, textureCoord); +       
> vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program],
> attribute), 2, GL_FLOAT, 0, 0, 0); }
>      glActiveTexture(GL_TEXTURE0 + 0);
>      glClientActiveTexture(GL_TEXTURE0 + 0);
> +
> +    vgl->BindBuffer(GL_ARRAY_BUFFER, vgl->vertex_buffer_object);
> +    vgl->BufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord,
> GL_STATIC_DRAW);
> vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[program],
> "VertexPosition")); -   
> vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program],
> "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord); +   
> vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[program],
> "VertexPosition"), 2, GL_FLOAT, 0, 0, 0);
> 
>      vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[program],
> "RotationMatrix"), 1, GL_FALSE, transformMatrix);

-- 
Rémi Denis-Courmont
http://www.remlab.net/




More information about the vlc-devel mailing list