1 /*****************************************************************************
2 * converter.h: OpenGL internal header
3 *****************************************************************************
4 * Copyright (C) 2016 VLC authors and VideoLAN
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
20
21 #ifndef VLC_OPENGL_CONVERTER_H
22 #define VLC_OPENGL_CONVERTER_H
23
24 #include <vlc_plugin.h>
25 #include <vlc_common.h>
26 #include <vlc_picture_pool.h>
27 #include <vlc_opengl.h>
28
29 /* if USE_OPENGL_ES2 is defined, OpenGL ES version 2 will be used, otherwise
30 * normal OpenGL will be used */
31 #ifdef __APPLE__
32 # include <TargetConditionals.h>
33 # if !TARGET_OS_IPHONE
34 # undef USE_OPENGL_ES2
35 # define MACOS_OPENGL
36 # include <OpenGL/gl.h>
37 # else /* Force ESv2 on iOS */
38 # define USE_OPENGL_ES2
39 # include <OpenGLES/ES1/gl.h>
40 # include <OpenGLES/ES2/gl.h>
41 # include <OpenGLES/ES2/glext.h>
42 # endif
43 #else /* !defined (__APPLE__) */
44 # if defined (USE_OPENGL_ES2)
45 # include <GLES2/gl2.h>
46 # include <GLES2/gl2ext.h>
47 # else
48 # ifdef _WIN32
49 # include <GL/glew.h>
50 # endif
51 # include <GL/gl.h>
52 # endif
53 #endif
54
55 #define VLCGL_PICTURE_MAX 128
56
57 #ifndef GL_TEXTURE_RECTANGLE
58 # define GL_TEXTURE_RECTANGLE 0x84F5
59 #endif
60
61 #ifndef APIENTRY
62 # define APIENTRY
63 #endif
64
65 /* Core OpenGL/OpenGLES functions: the following functions pointers typedefs
66 * are not defined. */
67 #if !defined(_WIN32) /* Already defined on Win32 */
68 typedef void (*PFNGLACTIVETEXTUREPROC) (GLenum texture);
69 #endif
70 typedef void (APIENTRY *PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
71 typedef void (APIENTRY *PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
72 typedef void (APIENTRY *PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags);
73 typedef void (APIENTRY *PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
74 typedef void (APIENTRY *PFNGLCLEARPROC) (GLbitfield mask);
75 typedef void (APIENTRY *PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
76 typedef void (APIENTRY *PFNGLDEPTHMASKPROC) (GLboolean flag);
77 typedef void (APIENTRY *PFNGLDISABLEPROC) (GLenum cap);
78 typedef void (APIENTRY *PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count);
79 typedef void (APIENTRY *PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
80 typedef void (APIENTRY *PFNGLENABLEPROC) (GLenum cap);
81 typedef void (APIENTRY *PFNGLFINISHPROC)(void);
82 typedef void (APIENTRY *PFNGLFLUSHPROC)(void);
83 typedef void (APIENTRY *PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
84 typedef GLenum (APIENTRY *PFNGLGETERRORPROC) (void);
85 typedef void (APIENTRY *PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
86 typedef const GLubyte *(APIENTRY *PFNGLGETSTRINGPROC) (GLenum name);
87 typedef void (APIENTRY *PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params);
88 typedef void (APIENTRY *PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
89 typedef void (APIENTRY *PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param);
90 typedef void (APIENTRY *PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
91 typedef void (APIENTRY *PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
92 typedef void (APIENTRY *PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
93 typedef void (APIENTRY *PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
94 typedef void (APIENTRY *PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
95
96 /* The following are defined in glext.h but not for GLES2 or on Apple systems */
97 #if defined(USE_OPENGL_ES2) || defined(__APPLE__)
98 # define PFNGLGETPROGRAMIVPROC typeof(glGetProgramiv)*
99 # define PFNGLGETPROGRAMINFOLOGPROC typeof(glGetProgramInfoLog)*
100 # define PFNGLGETSHADERIVPROC typeof(glGetShaderiv)*
101 # define PFNGLGETSHADERINFOLOGPROC typeof(glGetShaderInfoLog)*
102 # define PFNGLGETUNIFORMLOCATIONPROC typeof(glGetUniformLocation)*
103 # define PFNGLGETATTRIBLOCATIONPROC typeof(glGetAttribLocation)*
104 # define PFNGLVERTEXATTRIBPOINTERPROC typeof(glVertexAttribPointer)*
105 # define PFNGLENABLEVERTEXATTRIBARRAYPROC typeof(glEnableVertexAttribArray)*
106 # define PFNGLUNIFORMMATRIX4FVPROC typeof(glUniformMatrix4fv)*
107 # define PFNGLUNIFORMMATRIX3FVPROC typeof(glUniformMatrix3fv)*
108 # define PFNGLUNIFORMMATRIX2FVPROC typeof(glUniformMatrix2fv)*
109 # define PFNGLUNIFORM4FVPROC typeof(glUniform4fv)*
110 # define PFNGLUNIFORM4FPROC typeof(glUniform4f)*
111 # define PFNGLUNIFORM3FPROC typeof(glUniform3f)*
112 # define PFNGLUNIFORM2FPROC typeof(glUniform2f)*
113 # define PFNGLUNIFORM1FPROC typeof(glUniform1f)*
114 # define PFNGLUNIFORM1IPROC typeof(glUniform1i)*
115 # define PFNGLCREATESHADERPROC typeof(glCreateShader)*
116 # define PFNGLSHADERSOURCEPROC typeof(glShaderSource)*
117 # define PFNGLCOMPILESHADERPROC typeof(glCompileShader)*
118 # define PFNGLDELETESHADERPROC typeof(glDeleteShader)*
119 # define PFNGLCREATEPROGRAMPROC typeof(glCreateProgram)*
120 # define PFNGLLINKPROGRAMPROC typeof(glLinkProgram)*
121 # define PFNGLUSEPROGRAMPROC typeof(glUseProgram)*
122 # define PFNGLDELETEPROGRAMPROC typeof(glDeleteProgram)*
123 # define PFNGLATTACHSHADERPROC typeof(glAttachShader)*
124 # define PFNGLGENBUFFERSPROC typeof(glGenBuffers)*
125 # define PFNGLBINDBUFFERPROC typeof(glBindBuffer)*
126 # define PFNGLBUFFERDATAPROC typeof(glBufferData)*
127 # define PFNGLBUFFERSUBDATAPROC typeof(glBufferSubData)*
128 # define PFNGLDELETEBUFFERSPROC typeof(glDeleteBuffers)*
129 # define PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC typeof(glGetFramebufferAttachmentParameteriv)*
130 #if defined(__APPLE__)
131 # import <CoreFoundation/CoreFoundation.h>
132 #endif
133 #endif
134
135 /* The following are defined in glext.h but doesn't exist in GLES2 */
136 #if defined(USE_OPENGL_ES2) || defined(__APPLE__)
137 typedef struct __GLsync *GLsync;
138 typedef uint64_t GLuint64;
139 typedef void *(APIENTRY *PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
140 typedef void (APIENTRY *PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
141 typedef GLboolean (APIENTRY *PFNGLUNMAPBUFFERPROC) (GLenum target);
142 typedef GLsync (APIENTRY *PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
143 typedef void (APIENTRY *PFNGLDELETESYNCPROC) (GLsync sync);
144 typedef GLenum (APIENTRY *PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
145 #endif
146
147 /**
148 * Structure containing function pointers to shaders commands
149 */
150 typedef struct {
151 /*
152 * GL / GLES core functions
153 */
154 PFNGLBINDTEXTUREPROC BindTexture;
155 PFNGLBLENDFUNCPROC BlendFunc;
156 PFNGLCLEARCOLORPROC ClearColor;
157 PFNGLCLEARPROC Clear;
158 PFNGLDELETETEXTURESPROC DeleteTextures;
159 PFNGLDEPTHMASKPROC DepthMask;
160 PFNGLDISABLEPROC Disable;
161 PFNGLDRAWARRAYSPROC DrawArrays;
162 PFNGLDRAWELEMENTSPROC DrawElements;
163 PFNGLENABLEPROC Enable;
164 PFNGLFINISHPROC Finish;
165 PFNGLFLUSHPROC Flush;
166 PFNGLGENTEXTURESPROC GenTextures;
167 PFNGLGETERRORPROC GetError;
168 PFNGLGETINTEGERVPROC GetIntegerv;
169 PFNGLGETSTRINGPROC GetString;
170 PFNGLPIXELSTOREIPROC PixelStorei;
171 PFNGLTEXIMAGE2DPROC TexImage2D;
172 PFNGLTEXPARAMETERFPROC TexParameterf;
173 PFNGLTEXPARAMETERIPROC TexParameteri;
174 PFNGLTEXSUBIMAGE2DPROC TexSubImage2D;
175 PFNGLVIEWPORTPROC Viewport;
176
177 /* GL only core functions: NULL for GLES2 */
178 PFNGLGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv; /* Can be NULL */
179 PFNGLTEXENVFPROC TexEnvf; /* Can be NULL */
180
181 /*
182 * GL / GLES extensions
183 */
184
185 /* Shader commands */
186 PFNGLCREATESHADERPROC CreateShader;
187 PFNGLSHADERSOURCEPROC ShaderSource;
188 PFNGLCOMPILESHADERPROC CompileShader;
189 PFNGLATTACHSHADERPROC AttachShader;
190 PFNGLDELETESHADERPROC DeleteShader;
191
192 /* Shader log commands */
193 PFNGLGETPROGRAMIVPROC GetProgramiv;
194 PFNGLGETSHADERIVPROC GetShaderiv;
195 PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
196 PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
197
198 /* Shader variables commands */
199 PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
200 PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
201 PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
202 PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
203 PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
204 PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv;
205 PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv;
206 PFNGLUNIFORM4FVPROC Uniform4fv;
207 PFNGLUNIFORM4FPROC Uniform4f;
208 PFNGLUNIFORM3FPROC Uniform3f;
209 PFNGLUNIFORM2FPROC Uniform2f;
210 PFNGLUNIFORM1FPROC Uniform1f;
211 PFNGLUNIFORM1IPROC Uniform1i;
212
213 /* Program commands */
214 PFNGLCREATEPROGRAMPROC CreateProgram;
215 PFNGLLINKPROGRAMPROC LinkProgram;
216 PFNGLUSEPROGRAMPROC UseProgram;
217 PFNGLDELETEPROGRAMPROC DeleteProgram;
218
219 /* Texture commands */
220 PFNGLACTIVETEXTUREPROC ActiveTexture;
221
222 /* Buffers commands */
223 PFNGLGENBUFFERSPROC GenBuffers;
224 PFNGLBINDBUFFERPROC BindBuffer;
225 PFNGLBUFFERDATAPROC BufferData;
226 PFNGLDELETEBUFFERSPROC DeleteBuffers;
227
228 /* Framebuffers commands */
229 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv;
230
231 /* Commands used for PBO and/or Persistent mapping */
232 PFNGLBUFFERSUBDATAPROC BufferSubData; /* can be NULL */
233 PFNGLBUFFERSTORAGEPROC BufferStorage; /* can be NULL */
234 PFNGLMAPBUFFERRANGEPROC MapBufferRange; /* can be NULL */
235 PFNGLFLUSHMAPPEDBUFFERRANGEPROC FlushMappedBufferRange; /* can be NULL */
236 PFNGLUNMAPBUFFERPROC UnmapBuffer; /* can be NULL */
237 PFNGLFENCESYNCPROC FenceSync; /* can be NULL */
238 PFNGLDELETESYNCPROC DeleteSync; /* can be NULL */
239 PFNGLCLIENTWAITSYNCPROC ClientWaitSync; /* can be NULL */
240 } opengl_vtable_t;
241
HasExtension(const char * apis,const char * api)242 static inline bool HasExtension(const char *apis, const char *api)
243 {
244 size_t apilen = strlen(api);
245 while (apis) {
246 while (*apis == ' ')
247 apis++;
248 if (!strncmp(apis, api, apilen) && memchr(" ", apis[apilen], 2))
249 return true;
250 apis = strchr(apis, ' ');
251 }
252 return false;
253 }
254
255 struct pl_context;
256 struct pl_shader;
257 struct pl_shader_res;
258
259 /*
260 * Structure that is filled by "glhw converter" module probe function
261 * The implementation should initialize every members of the struct that are
262 * not set by the caller
263 */
264 typedef struct opengl_tex_converter_t opengl_tex_converter_t;
265 struct opengl_tex_converter_t
266 {
267 VLC_COMMON_MEMBERS
268
269 module_t *p_module;
270
271 /* Pointer to object gl, set by the caller */
272 vlc_gl_t *gl;
273
274 /* libplacebo context, created by the caller (optional) */
275 struct pl_context *pl_ctx;
276
277 /* Function pointers to OpenGL functions, set by the caller */
278 const opengl_vtable_t *vt;
279
280 /* True to dump shaders, set by the caller */
281 bool b_dump_shaders;
282
283 /* Function pointer to the shader init command, set by the caller, see
284 * opengl_fragment_shader_init() documentation. */
285 GLuint (*pf_fragment_shader_init)(opengl_tex_converter_t *, GLenum,
286 vlc_fourcc_t, video_color_space_t);
287
288 /* Available gl extensions (from GL_EXTENSIONS) */
289 const char *glexts;
290
291 /* True if the current API is OpenGL ES, set by the caller */
292 bool is_gles;
293 /* GLSL version, set by the caller. 100 for GLSL ES, 120 for desktop GLSL */
294 unsigned glsl_version;
295 /* Precision header, set by the caller. In OpenGLES, the fragment language
296 * has no default precision qualifier for floating point types. */
297 const char *glsl_precision_header;
298
299 /* Can only be changed from the module open function */
300 video_format_t fmt;
301
302 /* Fragment shader, must be set from the module open function. It will be
303 * deleted by the caller. */
304 GLuint fshader;
305
306 /* Number of textures, cannot be 0 */
307 unsigned tex_count;
308
309 /* Texture mapping (usually: GL_TEXTURE_2D), cannot be 0 */
310 GLenum tex_target;
311
312 /* Set to true if textures are generated from pf_update() */
313 bool handle_texs_gen;
314
315 struct opengl_tex_cfg {
316 /* Texture scale factor, cannot be 0 */
317 vlc_rational_t w;
318 vlc_rational_t h;
319
320 /* The following is used and filled by the opengl_fragment_shader_init
321 * function. */
322 GLint internal;
323 GLenum format;
324 GLenum type;
325 } texs[PICTURE_PLANE_MAX];
326
327 /* The following is used and filled by the opengl_fragment_shader_init
328 * function. */
329 struct {
330 GLint Texture[PICTURE_PLANE_MAX];
331 GLint TexSize[PICTURE_PLANE_MAX]; /* for GL_TEXTURE_RECTANGLE */
332 GLint Coefficients;
333 GLint FillColor;
334 GLint *pl_vars; /* for pl_sh_res */
335 } uloc;
336 bool yuv_color;
337 GLfloat yuv_coefficients[16];
338
339 struct pl_shader *pl_sh;
340 const struct pl_shader_res *pl_sh_res;
341
342 /* Private context */
343 void *priv;
344
345 /*
346 * Callback to allocate data for bound textures
347 *
348 * This function pointer can be NULL. Software converters should call
349 * glTexImage2D() to allocate textures data (it will be deallocated by the
350 * caller when calling glDeleteTextures()). Won't be called if
351 * handle_texs_gen is true.
352 *
353 * \param fc OpenGL tex converter
354 * \param textures array of textures to bind (one per plane)
355 * \param tex_width array of tex width (one per plane)
356 * \param tex_height array of tex height (one per plane)
357 * \return VLC_SUCCESS or a VLC error
358 */
359 int (*pf_allocate_textures)(const opengl_tex_converter_t *tc, GLuint *textures,
360 const GLsizei *tex_width, const GLsizei *tex_height);
361
362 /*
363 * Callback to allocate a picture pool
364 *
365 * This function pointer *can* be NULL. If NULL, A generic pool with
366 * pictures allocated from the video_format_t will be used.
367 *
368 * \param fc OpenGL tex converter
369 * \param requested_count number of pictures to allocate
370 * \return the picture pool or NULL in case of error
371 */
372 picture_pool_t *(*pf_get_pool)(const opengl_tex_converter_t *fc,
373 unsigned requested_count);
374
375 /*
376 * Callback to update a picture
377 *
378 * This function pointer cannot be NULL. The implementation should upload
379 * every planes of the picture.
380 *
381 * \param fc OpenGL tex converter
382 * \param textures array of textures to bind (one per plane)
383 * \param tex_width array of tex width (one per plane)
384 * \param tex_height array of tex height (one per plane)
385 * \param pic picture to update
386 * \param plane_offset offsets of each picture planes to read data from
387 * (one per plane, can be NULL)
388 * \return VLC_SUCCESS or a VLC error
389 */
390 int (*pf_update)(const opengl_tex_converter_t *fc, GLuint *textures,
391 const GLsizei *tex_width, const GLsizei *tex_height,
392 picture_t *pic, const size_t *plane_offset);
393
394 /*
395 * Callback to fetch locations of uniform or attributes variables
396 *
397 * This function pointer cannot be NULL. This callback is called one time
398 * after init.
399 *
400 * \param fc OpenGL tex converter
401 * \param program linked program that will be used by this tex converter
402 * \return VLC_SUCCESS or a VLC error
403 */
404 int (*pf_fetch_locations)(opengl_tex_converter_t *fc, GLuint program);
405
406 /*
407 * Callback to prepare the fragment shader
408 *
409 * This function pointer cannot be NULL. This callback can be used to
410 * specify values of uniform variables.
411 *
412 * \param fc OpenGL tex converter
413 * \param tex_width array of tex width (one per plane)
414 * \param tex_height array of tex height (one per plane)
415 * \param alpha alpha value, used only for RGBA fragment shader
416 */
417 void (*pf_prepare_shader)(const opengl_tex_converter_t *fc,
418 const GLsizei *tex_width, const GLsizei *tex_height,
419 float alpha);
420 };
421
422 /*
423 * Generate a fragment shader
424 *
425 * This utility function can be used by hw opengl tex converters that need a
426 * generic fragment shader. It will compile a fragment shader generated from
427 * the chroma and the tex target. This will initialize all elements of the
428 * opengl_tex_converter_t struct except for priv, pf_allocate_texture,
429 * pf_get_pool, pf_update
430 *
431 * \param tc OpenGL tex converter
432 * \param tex_target GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE
433 * \param chroma chroma used to generate the fragment shader
434 * \param if not COLOR_SPACE_UNDEF, YUV planes will be converted to RGB
435 * according to the color space
436 * \return the compiled fragment shader or 0 in case of error
437 */
438 static inline GLuint
opengl_fragment_shader_init(opengl_tex_converter_t * tc,GLenum tex_target,vlc_fourcc_t chroma,video_color_space_t yuv_space)439 opengl_fragment_shader_init(opengl_tex_converter_t *tc, GLenum tex_target,
440 vlc_fourcc_t chroma, video_color_space_t yuv_space)
441 {
442 return tc->pf_fragment_shader_init(tc, tex_target, chroma, yuv_space);
443 }
444
445 #endif /* include-guard */
446