1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * This file is part of openfx-supportext <https://github.com/devernay/openfx-supportext>,
4 * Copyright (C) 2013-2018 INRIA
5 *
6 * openfx-supportext is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * openfx-supportext 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 General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with openfx-supportext. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
18 * ***** END LICENSE BLOCK ***** */
19
20 #include "ofxsOGLUtilities.h"
21
22 #include "ofxsOGLFunctions.h"
23
24 #include "ofxsMultiThread.h"
25 #ifndef OFX_USE_MULTITHREAD_MUTEX
26 // some OFX hosts do not have mutex handling in the MT-Suite (e.g. Sony Catalyst Edit)
27 // prefer using the fast mutex by Marcus Geelnard http://tinythreadpp.bitsnbites.eu/
28 #include "fast_mutex.h"
29 #endif
30 #ifdef OFX_USE_MULTITHREAD_MUTEX
31 typedef OFX::MultiThread::Mutex Mutex;
32 typedef OFX::MultiThread::AutoMutex AutoMutex;
33 #else
34 typedef tthread::fast_mutex Mutex;
35 typedef OFX::MultiThread::AutoMutexT<tthread::fast_mutex> AutoMutex;
36 #endif
37
38 static Mutex g_glLoadOnceMutex;
39 static bool g_glLoaded = false;
40
41 extern "C" {
42 extern int gladLoadGL(void);
43 struct gladGLversionStruct
44 {
45 int major;
46 int minor;
47 };
48
49 typedef void (* GLADcallback)(const char *name, void *funcptr, int len_args, ...);
50 extern void glad_set_pre_callback(GLADcallback);
51 extern void glad_set_post_callback(GLADcallback);
52 extern gladGLversionStruct GLVersion;
53 extern int GLAD_GL_ARB_vertex_buffer_object;
54 extern int GLAD_GL_ARB_framebuffer_object;
55 extern int GLAD_GL_ARB_pixel_buffer_object;
56 extern int GLAD_GL_ARB_vertex_array_object;
57 extern int GLAD_GL_ARB_texture_float;
58 extern int GLAD_GL_EXT_framebuffer_object;
59 extern int GLAD_GL_APPLE_vertex_array_object;
60
61 typedef GLboolean (* PFNGLISRENDERBUFFEREXTPROC)(GLuint renderbuffer);
62 extern PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT;
63 extern PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbuffer;
64
65 typedef void (* PFNGLBINDRENDERBUFFEREXTPROC)(GLenum target, GLuint renderbuffer);
66 extern PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT;
67 extern PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
68
69 typedef void (* PFNGLDELETERENDERBUFFERSEXTPROC)(GLsizei n, const GLuint* renderbuffers);
70 extern PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT;
71 extern PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffers;
72
73
74 typedef void (* PFNGLGENRENDERBUFFERSEXTPROC)(GLsizei n, GLuint* renderbuffers);
75 extern PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT;
76 extern PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffers;
77
78 typedef void (* PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
79 extern PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT;
80 extern PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorage;
81
82 typedef void (* PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)(GLenum target, GLenum pname, GLint* params);
83 extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT;
84 extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameteriv;
85
86
87 typedef void (* PFNGLBINDFRAMEBUFFEREXTPROC)(GLenum target, GLuint framebuffer);
88 extern PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT;
89 extern PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebuffer;
90
91
92 typedef GLboolean (* PFNGLISFRAMEBUFFEREXTPROC)(GLuint framebuffer);
93 extern PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT;
94 extern PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebuffer;
95
96
97 typedef void (* PFNGLDELETEFRAMEBUFFERSEXTPROC)(GLsizei n, const GLuint* framebuffers);
98 extern PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT;
99 extern PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffers;
100
101
102 typedef void (* PFNGLGENFRAMEBUFFERSEXTPROC)(GLsizei n, GLuint* framebuffers);
103 extern PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT;
104 extern PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffers;
105
106
107 typedef GLenum (* PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)(GLenum target);
108 extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT;
109 extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatus;
110
111
112 typedef void (* PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
113 extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT;
114 extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1D;
115
116
117 typedef void (* PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
118 extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT;
119 extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2D;
120
121
122 typedef void (* PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
123 extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT;
124 extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3D;
125
126
127 typedef void (* PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
128 extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT;
129 extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbuffer;
130
131
132 typedef void (* PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
133 extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT;
134 extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameteriv;
135
136 typedef void (* PFNGLGENERATEMIPMAPEXTPROC)(GLenum target);
137 extern PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT;
138 extern PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmap;
139
140 typedef void (* PFNGLBINDVERTEXARRAYAPPLEPROC)(GLuint array);
141 extern PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE;
142 extern PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArray;
143
144 typedef void (* PFNGLDELETEVERTEXARRAYSAPPLEPROC)(GLsizei n, const GLuint* arrays);
145 extern PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE;
146 extern PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArrays;
147
148 typedef void (* PFNGLGENVERTEXARRAYSAPPLEPROC)(GLsizei n, GLuint* arrays);
149 extern PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE;
150 extern PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArrays;
151
152 typedef GLboolean (* PFNGLISVERTEXARRAYAPPLEPROC)(GLuint array);
153 extern PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE;
154 extern PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArray;
155 } // extern "C"
156
157 namespace OFX {
158 bool
ofxsLoadOpenGLOnce()159 ofxsLoadOpenGLOnce()
160 {
161 // Ensure that OpenGL functions loading is thread-safe
162 AutoMutex locker(&g_glLoadOnceMutex);
163
164 if (g_glLoaded) {
165 // Already loaded, don't do it again
166 return true;
167 }
168
169 // Reasons for failure might be:
170 // - opengl32.dll was not found, or libGL.so was not found or OpenGL.framework was not found
171 // - glGetString does not return a valid version
172 // Note: It does NOT check that required extensions and functions have actually been found
173 bool glLoaded = gladLoadGL();
174
175 g_glLoaded = glLoaded;
176
177 // If only EXT_framebuffer is present and not ARB link functions
178 if (glLoaded && GLAD_GL_EXT_framebuffer_object && !GLAD_GL_ARB_framebuffer_object) {
179 glad_glIsRenderbuffer = glad_glIsRenderbufferEXT;
180 glad_glBindRenderbuffer = glad_glBindRenderbufferEXT;
181 glad_glDeleteRenderbuffers = glad_glDeleteRenderbuffersEXT;
182 glad_glGenRenderbuffers = glad_glGenRenderbuffersEXT;
183 glad_glRenderbufferStorage = glad_glRenderbufferStorageEXT;
184 glad_glGetRenderbufferParameteriv = glad_glGetRenderbufferParameterivEXT;
185 glad_glBindFramebuffer = glad_glBindFramebufferEXT;
186 glad_glIsFramebuffer = glad_glIsFramebufferEXT;
187 glad_glDeleteFramebuffers = glad_glDeleteFramebuffersEXT;
188 glad_glGenFramebuffers = glad_glGenFramebuffersEXT;
189 glad_glCheckFramebufferStatus = glad_glCheckFramebufferStatusEXT;
190 glad_glFramebufferTexture1D = glad_glFramebufferTexture1DEXT;
191 glad_glFramebufferTexture2D = glad_glFramebufferTexture2DEXT;
192 glad_glFramebufferTexture3D = glad_glFramebufferTexture3DEXT;
193 glad_glFramebufferRenderbuffer = glad_glFramebufferRenderbufferEXT;
194 glad_glGetFramebufferAttachmentParameteriv = glad_glGetFramebufferAttachmentParameterivEXT;
195 glad_glGenerateMipmap = glad_glGenerateMipmapEXT;
196 }
197
198 if (glLoaded && GLAD_GL_APPLE_vertex_array_object && !GLAD_GL_ARB_vertex_buffer_object) {
199 glad_glBindVertexArray = glad_glBindVertexArrayAPPLE;
200 glad_glDeleteVertexArrays = glad_glDeleteVertexArraysAPPLE;
201 glad_glGenVertexArrays = glad_glGenVertexArraysAPPLE;
202 glad_glIsVertexArray = glad_glIsVertexArrayAPPLE;
203 }
204
205 return g_glLoaded;
206 } // ofxsLoadGLOnce
207
208 int
getOpenGLMajorVersion()209 getOpenGLMajorVersion()
210 {
211 return GLVersion.major;
212 }
213
214 int
getOpenGLMinorVersion()215 getOpenGLMinorVersion()
216 {
217 return GLVersion.minor;
218 }
219
220 bool
getOpenGLSupportsTextureFloat()221 getOpenGLSupportsTextureFloat()
222 {
223 return GLAD_GL_ARB_texture_float;
224 }
225
226 bool
getOpenGLSupportFramebuffer()227 getOpenGLSupportFramebuffer()
228 {
229 return GLAD_GL_ARB_framebuffer_object || GLAD_GL_EXT_framebuffer_object;
230 }
231
232 bool
getOpenGLSupportPixelbuffer()233 getOpenGLSupportPixelbuffer()
234 {
235 return GLAD_GL_ARB_pixel_buffer_object;
236 }
237
238 bool
getOpenGLSupportVertexArray()239 getOpenGLSupportVertexArray()
240 {
241 return GLAD_GL_ARB_vertex_array_object || GLAD_GL_APPLE_vertex_array_object;
242 }
243 } // namespace OFX
244