opengl: factorize program creation
[vlc.git] / modules / video_output / opengl / gl_util.c
blobc47a272acfe68eddfcd40e0e4481fb9a8ff55828
1 /*****************************************************************************
2 * gl_util.c
3 *****************************************************************************
4 * Copyright (C) 2020 VLC authors and VideoLAN
5 * Copyright (C) 2020 Videolabs
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20 *****************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
26 #include "gl_util.h"
28 static void
29 LogShaderErrors(vlc_object_t *obj, const opengl_vtable_t *vt, GLuint id)
31 GLint info_len;
32 vt->GetShaderiv(id, GL_INFO_LOG_LENGTH, &info_len);
33 if (info_len > 0)
35 char *info_log = malloc(info_len);
36 if (info_log)
38 GLsizei written;
39 vt->GetShaderInfoLog(id, info_len, &written, info_log);
40 msg_Err(obj, "shader: %s", info_log);
41 free(info_log);
46 static void
47 LogProgramErrors(vlc_object_t *obj, const opengl_vtable_t *vt, GLuint id)
49 GLint info_len;
50 vt->GetProgramiv(id, GL_INFO_LOG_LENGTH, &info_len);
51 if (info_len > 0)
53 char *info_log = malloc(info_len);
54 if (info_log)
56 GLsizei written;
57 vt->GetProgramInfoLog(id, info_len, &written, info_log);
58 msg_Err(obj, "program: %s", info_log);
59 free(info_log);
64 static GLuint
65 CreateShader(vlc_object_t *obj, const opengl_vtable_t *vt, GLenum type,
66 GLsizei count, const GLchar **src)
68 GLuint shader = vt->CreateShader(type);
69 if (!shader)
70 return 0;
72 vt->ShaderSource(shader, count, src, NULL);
73 vt->CompileShader(shader);
75 LogShaderErrors(obj, vt, shader);
77 GLint compiled;
78 vt->GetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
79 if (!compiled)
81 msg_Err(obj, "Failed to compile shader");
82 vt->DeleteShader(shader);
83 return 0;
86 return shader;
90 GLuint
91 vlc_gl_BuildProgram(vlc_object_t *obj, const opengl_vtable_t *vt,
92 GLsizei vstring_count, const GLchar **vstrings,
93 GLsizei fstring_count, const GLchar **fstrings)
95 GLuint program = 0;
97 GLuint vertex_shader = CreateShader(obj, vt, GL_VERTEX_SHADER,
98 vstring_count, vstrings);
99 if (!vertex_shader)
100 return 0;
102 GLuint fragment_shader = CreateShader(obj, vt, GL_FRAGMENT_SHADER,
103 fstring_count, fstrings);
104 if (!fragment_shader)
105 goto finally_1;
107 program = vt->CreateProgram();
108 if (!program)
109 goto finally_2;
111 vt->AttachShader(program, vertex_shader);
112 vt->AttachShader(program, fragment_shader);
114 vt->LinkProgram(program);
116 LogProgramErrors(obj, vt, program);
118 GLint linked;
119 vt->GetProgramiv(program, GL_LINK_STATUS, &linked);
120 if (!linked)
122 msg_Err(obj, "Failed to link program");
123 vt->DeleteProgram(program);
124 program = 0;
127 finally_2:
128 vt->DeleteShader(fragment_shader);
129 finally_1:
130 vt->DeleteShader(vertex_shader);
132 return program;