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