#include <vlc_picture_pool.h>
#include <vlc_subpicture.h>
#include <vlc_opengl.h>
+#include <vlc_memory.h>
#include "opengl.h"
# 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
int local_count;
GLfloat local_value[16];
+ GLuint vertex_buffer_object;
+ GLuint texture_buffer_object[PICTURE_PLANE_MAX];
+
+ GLuint *subpicture_buffer_object;
+ int subpicture_buffer_object_count;
+
/* Shader variables commands*/
#ifdef SUPPORTS_SHADERS
PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
PFNGLGETSHADERIVPROC GetShaderiv;
PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
+
+ PFNGLGENBUFFERSPROC GenBuffers;
+ PFNGLBINDBUFFERPROC BindBuffer;
+ PFNGLBUFFERDATAPROC BufferData;
+ PFNGLDELETEBUFFERSPROC DeleteBuffers;
#endif
#if defined(_WIN32)
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");
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
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);
+
+ /* Initial number of allocated buffer objects for subpictures, will grow dynamically. */
+ int subpicture_buffer_object_count = 8;
+ vgl->subpicture_buffer_object = malloc(subpicture_buffer_object_count * sizeof(GLuint));
+ if (!vgl->subpicture_buffer_object) {
+ vlc_gl_Unlock(vgl->gl);
+ vout_display_opengl_Delete(vgl);
+ return NULL;
+ }
+ vgl->subpicture_buffer_object_count = subpicture_buffer_object_count;
+ vgl->GenBuffers(vgl->subpicture_buffer_object_count, vgl->subpicture_buffer_object);
+#endif
+
vlc_gl_Unlock(vgl->gl);
/* */
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);
+ if (vgl->subpicture_buffer_object_count > 0)
+ vgl->DeleteBuffers(vgl->subpicture_buffer_object_count, vgl->subpicture_buffer_object);
+ free(vgl->subpicture_buffer_object);
#endif
free(vgl->texture_temp_buf);
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);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#ifdef SUPPORTS_SHADERS
+ /* We need two buffer objects for each region: for vertex and texture coordinates. */
+ if (2 * vgl->region_count > vgl->subpicture_buffer_object_count) {
+ if (vgl->subpicture_buffer_object_count > 0)
+ vgl->DeleteBuffers(vgl->subpicture_buffer_object_count, vgl->subpicture_buffer_object);
+ vgl->subpicture_buffer_object_count = 0;
+
+ int new_count = 2 * vgl->region_count;
+ vgl->subpicture_buffer_object = realloc_or_free(vgl->subpicture_buffer_object, new_count * sizeof(GLuint));
+ if (!vgl->subpicture_buffer_object) {
+ vlc_gl_Unlock(vgl->gl);
+ return VLC_ENOMEM;
+ }
+
+ vgl->subpicture_buffer_object_count = new_count;
+ vgl->GenBuffers(vgl->subpicture_buffer_object_count, vgl->subpicture_buffer_object);
+ }
+#endif
+
glActiveTexture(GL_TEXTURE0 + 0);
glClientActiveTexture(GL_TEXTURE0 + 0);
for (int i = 0; i < vgl->region_count; i++) {
if (vgl->program[1]) {
#ifdef SUPPORTS_SHADERS
vgl->Uniform4f(vgl->GetUniformLocation(vgl->program[1], "FillColor"), 1.0f, 1.0f, 1.0f, glr->alpha);
+
+ vgl->BindBuffer(GL_ARRAY_BUFFER, vgl->subpicture_buffer_object[2 * i]);
+ vgl->BufferData(GL_ARRAY_BUFFER, sizeof(textureCoord), textureCoord, GL_STATIC_DRAW);
vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[1], "MultiTexCoord0"));
- vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "MultiTexCoord0"), 2, GL_FLOAT, 0, 0, textureCoord);
+ vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "MultiTexCoord0"), 2, GL_FLOAT, 0, 0, 0);
+
+ vgl->BindBuffer(GL_ARRAY_BUFFER, vgl->subpicture_buffer_object[2 * i + 1]);
+ vgl->BufferData(GL_ARRAY_BUFFER, sizeof(vertexCoord), vertexCoord, GL_STATIC_DRAW);
vgl->EnableVertexAttribArray(vgl->GetAttribLocation(vgl->program[1], "VertexPosition"));
- vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "VertexPosition"), 2, GL_FLOAT, 0, 0, vertexCoord);
+ vgl->VertexAttribPointer(vgl->GetAttribLocation(vgl->program[1], "VertexPosition"), 2, GL_FLOAT, 0, 0, 0);
+
// Subpictures have the correct orientation:
vgl->UniformMatrix4fv(vgl->GetUniformLocation(vgl->program[1], "RotationMatrix"), 1, GL_FALSE, identity);
#endif