blob: f56bcfaeb6d5426d99ced0a1b36ad001f3ee8ef5 [file] [log] [blame]
Anthony Barbier7068f992017-10-26 15:23:08 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2017-2018 Arm Limited.
Anthony Barbier7068f992017-10-26 15:23:08 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#include "arm_compute/core/GLES_COMPUTE/OpenGLES.h"
26
27#include <dlfcn.h>
28#include <iostream>
29#include <vector>
30
31using eglGetProcAddress_func = __eglMustCastToProperFunctionPointerType EGLAPIENTRY (*)(const char *procname);
32using eglBindAPI_func = EGLBoolean EGLAPIENTRY (*)(EGLenum api);
33using eglChooseConfig_func = EGLBoolean EGLAPIENTRY (*)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
34using eglCreateContext_func = EGLContext EGLAPIENTRY (*)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
35using eglDestroyContext_func = EGLBoolean EGLAPIENTRY (*)(EGLDisplay dpy, EGLContext ctx);
36using eglGetDisplay_func = EGLDisplay EGLAPIENTRY (*)(EGLNativeDisplayType display_id);
37using eglInitialize_func = EGLBoolean EGLAPIENTRY (*)(EGLDisplay dpy, EGLint *major, EGLint *minor);
38using eglMakeCurrent_func = EGLBoolean EGLAPIENTRY (*)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
39using eglTerminate_func = EGLBoolean EGLAPIENTRY (*)(EGLDisplay dpy);
40using eglGetError_func = EGLint EGLAPIENTRY (*)();
41using eglQueryString_func = char const * EGLAPIENTRY (*)(EGLDisplay dpy, EGLint name);
42using glAttachShader_func = void GL_APIENTRY (*)(GLuint program, GLuint shader);
43using glCompileShader_func = void GL_APIENTRY (*)(GLuint shader);
44using glCreateProgram_func = GLuint GL_APIENTRY (*)();
45using glCreateShader_func = GLuint GL_APIENTRY (*)(GLenum type);
46using glDeleteProgram_func = void GL_APIENTRY (*)(GLuint program);
47using glDeleteShader_func = void GL_APIENTRY (*)(GLuint shader);
48using glDetachShader_func = void GL_APIENTRY (*)(GLuint program, GLuint shader);
49using glGetProgramInfoLog_func = void GL_APIENTRY (*)(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog);
50using glGetProgramiv_func = void GL_APIENTRY (*)(GLuint program, GLenum pname, GLint *params);
51using glGetShaderInfoLog_func = void GL_APIENTRY (*)(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog);
52using glGetShaderiv_func = void GL_APIENTRY (*)(GLuint shader, GLenum pname, GLint *params);
53using glLinkProgram_func = void GL_APIENTRY (*)(GLuint program);
54using glShaderSource_func = void GL_APIENTRY (*)(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length);
55using glUseProgram_func = void GL_APIENTRY (*)(GLuint program);
56using glBindBuffer_func = void GL_APIENTRY (*)(GLenum target, GLuint buffer);
57using glBindBufferBase_func = void GL_APIENTRY (*)(GLenum target, GLuint index, GLuint buffer);
58using glBufferData_func = void GL_APIENTRY (*)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
59using glDeleteBuffers_func = void GL_APIENTRY (*)(GLsizei n, const GLuint *buffers);
60using glDispatchCompute_func = void GL_APIENTRY (*)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
61using glFlush_func = void GL_APIENTRY (*)();
62using glGenBuffers_func = void GL_APIENTRY (*)(GLsizei n, GLuint *buffers);
63using glGetProgramResourceIndex_func = GLuint GL_APIENTRY (*)(GLuint program, GLenum programInterface, const GLchar *name);
64using glGetUniformLocation_func = GLint GL_APIENTRY (*)(GLuint program, const GLchar *name);
65using glMapBufferRange_func = void *GL_APIENTRY (*)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
66using glMemoryBarrier_func = void GL_APIENTRY (*)(GLbitfield barriers);
67using glUniform1ui_func = void GL_APIENTRY (*)(GLint location, GLuint v0);
68using glUnmapBuffer_func = GLboolean GL_APIENTRY (*)(GLenum target);
Michele Di Giorgiob8fc60f2018-04-25 11:58:07 +010069using glGetError_func = GLenum GL_APIENTRY (*)();
70using glGetString_func = const GLubyte * GL_APIENTRY (*)(GLenum name);
Anthony Barbier7068f992017-10-26 15:23:08 +010071using glGetActiveUniformBlockiv_func = void GL_APIENTRY (*)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
72using glUniformBlockBinding_func = void GL_APIENTRY (*)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
73using glGetUniformBlockIndex_func = GLuint GL_APIENTRY (*)(GLuint program, const GLchar *uniformBlockName);
74using glGenTextures_func = void GL_APIENTRY (*)(GLsizei n, GLuint *textures);
75using glDeleteTextures_func = void GL_APIENTRY (*)(GLsizei n, const GLuint *textures);
76using glBindTexture_func = void GL_APIENTRY (*)(GLenum target, GLuint texture);
77using glTexImage2D_func = void GL_APIENTRY (*)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type,
78 const GLvoid *pixels);
79using glGenFramebuffers_func = void GL_APIENTRY (*)(GLsizei n, GLuint *framebuffers);
80using glDeleteFramebuffers_func = void GL_APIENTRY (*)(GLsizei n, const GLuint *framebuffers);
81using glBindFramebuffer_func = void GL_APIENTRY (*)(GLenum target, GLuint framebuffer);
82using glFramebufferTexture2D_func = void GL_APIENTRY (*)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
83
84class GLESSymbols
85{
86private:
87 void init()
88 {
89 void *egl_handle = dlopen("libEGL.so", RTLD_LAZY | RTLD_LOCAL);
90 void *glesv2_handle = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_LOCAL);
91 void *glesv3_handle = dlopen("libGLESv3.so", RTLD_LAZY | RTLD_LOCAL);
92 if(egl_handle == nullptr)
93 {
94 std::cerr << "Can't load libEGL.so: " << dlerror() << std::endl;
95 }
96 else
97 {
98#undef EGL_ENTRY
99#define EGL_ENTRY(_api) _api = reinterpret_cast<_api##_func>(dlsym(egl_handle, #_api));
100#include "./egl_entries.in"
101#undef EGL_ENTRY
102
103 if(eglGetProcAddress != nullptr)
104 {
105#undef EGL_ENTRY
106#define EGL_ENTRY(_api) \
107 if((_api) == nullptr) \
108 (_api) = reinterpret_cast<_api##_func>(eglGetProcAddress(#_api));
109#include "./egl_entries.in"
110#undef EGL_ENTRY
111
112#undef GL_ENTRY
113#define GL_ENTRY(_api) _api = reinterpret_cast<_api##_func>(eglGetProcAddress(#_api));
114#include "./gl_entries.in"
115#undef GL_ENTRY
116 }
117
118 std::vector<void *> handles = { glesv3_handle, glesv2_handle };
119 for(auto &handle : handles)
120 {
121 if(handle != nullptr)
122 {
123#undef GL_ENTRY
124#define GL_ENTRY(_api) \
125 if((_api) == nullptr) \
126 (_api) = reinterpret_cast<_api##_func>(dlsym(handle, #_api));
127#include "./gl_entries.in"
128#undef GL_ENTRY
129 }
130 }
131
Anthony Barbier7b43d312017-12-14 10:58:47 +0000132 //Don't call dlclose(handle) or all the symbols will be unloaded !
Anthony Barbier7068f992017-10-26 15:23:08 +0100133 }
134 }
135 bool _initialized = false;
136
137public:
138 static GLESSymbols &get()
139 {
140 static GLESSymbols symbols = GLESSymbols();
141 if(!symbols._initialized)
142 {
143 symbols._initialized = true;
144 symbols.init();
145 }
146
147 return symbols;
148 }
149
150#undef EGL_ENTRY
151#undef GL_ENTRY
152#define EGL_ENTRY(_api) _api##_func _api = nullptr;
153#define GL_ENTRY(_api) EGL_ENTRY(_api)
154#include "./egl_entries.in"
155#include "./gl_entries.in"
156#undef EGL_ENTRY
157#undef GL_ENTRY
158};
159
160bool arm_compute::opengles31_is_available()
161{
162 return GLESSymbols::get().glDispatchCompute != nullptr;
163}
164
165__eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
166{
167 auto func = GLESSymbols::get().eglGetProcAddress;
168 if(func != nullptr)
169 {
170 return func(procname);
171 }
172 else
173 {
174 return nullptr;
175 }
176}
177
178EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
179{
180 auto func = GLESSymbols::get().eglBindAPI;
181 if(func != nullptr)
182 {
183 return func(api);
184 }
185 else
186 {
187 return EGL_FALSE;
188 }
189}
190
191EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
192{
193 auto func = GLESSymbols::get().eglChooseConfig;
194 if(func != nullptr)
195 {
196 return func(dpy, attrib_list, configs, config_size, num_config);
197 }
198 else
199 {
200 return EGL_FALSE;
201 }
202}
203
204EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
205{
206 auto func = GLESSymbols::get().eglCreateContext;
207 if(func != nullptr)
208 {
209 return func(dpy, config, share_context, attrib_list);
210 }
211 else
212 {
213 return nullptr;
214 }
215}
216
217EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
218{
219 auto func = GLESSymbols::get().eglDestroyContext;
220 if(func != nullptr)
221 {
222 return func(dpy, ctx);
223 }
224 else
225 {
226 return EGL_FALSE;
227 }
228}
229
230EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
231{
232 auto func = GLESSymbols::get().eglGetDisplay;
233 if(func != nullptr)
234 {
235 return func(display_id);
236 }
237 else
238 {
239 return nullptr;
240 }
241}
242
243EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
244{
245 auto func = GLESSymbols::get().eglInitialize;
246 if(func != nullptr)
247 {
248 return func(dpy, major, minor);
249 }
250 else
251 {
252 return EGL_FALSE;
253 }
254}
255
256EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
257{
258 auto func = GLESSymbols::get().eglMakeCurrent;
259 if(func != nullptr)
260 {
261 return func(dpy, draw, read, ctx);
262 }
263 else
264 {
265 return EGL_FALSE;
266 }
267}
268
269EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
270{
271 auto func = GLESSymbols::get().eglTerminate;
272 if(func != nullptr)
273 {
274 return func(dpy);
275 }
276 else
277 {
278 return EGL_FALSE;
279 }
280}
281
282EGLint EGLAPIENTRY eglGetError()
283{
284 auto func = GLESSymbols::get().eglGetError;
285 if(func != nullptr)
286 {
287 return func();
288 }
289 else
290 {
291 return GL_NO_ERROR;
292 }
293}
294
295char const *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
296{
297 auto func = GLESSymbols::get().eglQueryString;
298 if(func != nullptr)
299 {
300 return func(dpy, name);
301 }
302 else
303 {
304 return nullptr;
305 }
306}
307
308void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
309{
310 auto func = GLESSymbols::get().glAttachShader;
311 if(func != nullptr)
312 {
313 return func(program, shader);
314 }
315 else
316 {
317 return;
318 }
319}
320
321void GL_APIENTRY glCompileShader(GLuint shader)
322{
323 auto func = GLESSymbols::get().glCompileShader;
324 if(func != nullptr)
325 {
326 return func(shader);
327 }
328 else
329 {
330 return;
331 }
332}
333
334GLuint GL_APIENTRY glCreateProgram()
335{
336 auto func = GLESSymbols::get().glCreateProgram;
337 if(func != nullptr)
338 {
339 return func();
340 }
341 else
342 {
343 return 0;
344 }
345}
346
347GLuint GL_APIENTRY glCreateShader(GLenum type)
348{
349 auto func = GLESSymbols::get().glCreateShader;
350 if(func != nullptr)
351 {
352 return func(type);
353 }
354 else
355 {
356 return 0;
357 }
358}
359
360void GL_APIENTRY glDeleteProgram(GLuint program)
361{
362 auto func = GLESSymbols::get().glDeleteProgram;
363 if(func != nullptr)
364 {
365 return func(program);
366 }
367 else
368 {
369 return;
370 }
371}
372
373void GL_APIENTRY glDeleteShader(GLuint shader)
374{
375 auto func = GLESSymbols::get().glDeleteShader;
376 if(func != nullptr)
377 {
378 return func(shader);
379 }
380 else
381 {
382 return;
383 }
384}
385
386void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
387{
388 auto func = GLESSymbols::get().glDetachShader;
389 if(func != nullptr)
390 {
391 return func(program, shader);
392 }
393 else
394 {
395 return;
396 }
397}
398
399void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
400{
401 auto func = GLESSymbols::get().glGetProgramInfoLog;
402 if(func != nullptr)
403 {
404 return func(program, bufSize, length, infoLog);
405 }
406 else
407 {
408 return;
409 }
410}
411
412void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint *params)
413{
414 auto func = GLESSymbols::get().glGetProgramiv;
415 if(func != nullptr)
416 {
417 return func(program, pname, params);
418 }
419 else
420 {
421 return;
422 }
423}
424
425void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
426{
427 auto func = GLESSymbols::get().glGetShaderInfoLog;
428 if(func != nullptr)
429 {
430 return func(shader, bufSize, length, infoLog);
431 }
432 else
433 {
434 return;
435 }
436}
437
438void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
439{
440 auto func = GLESSymbols::get().glGetShaderiv;
441 if(func != nullptr)
442 {
443 return func(shader, pname, params);
444 }
445 else
446 {
447 return;
448 }
449}
450
451void GL_APIENTRY glLinkProgram(GLuint program)
452{
453 auto func = GLESSymbols::get().glLinkProgram;
454 if(func != nullptr)
455 {
456 return func(program);
457 }
458 else
459 {
460 return;
461 }
462}
463
464void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
465{
466 auto func = GLESSymbols::get().glShaderSource;
467 if(func != nullptr)
468 {
469 return func(shader, count, string, length);
470 }
471 else
472 {
473 return;
474 }
475}
476
477void GL_APIENTRY glUseProgram(GLuint program)
478{
479 auto func = GLESSymbols::get().glUseProgram;
480 if(func != nullptr)
481 {
482 return func(program);
483 }
484 else
485 {
486 return;
487 }
488}
489
490void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
491{
492 auto func = GLESSymbols::get().glBindBuffer;
493 if(func != nullptr)
494 {
495 return func(target, buffer);
496 }
497 else
498 {
499 return;
500 }
501}
502
503void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
504{
505 auto func = GLESSymbols::get().glBindBufferBase;
506 if(func != nullptr)
507 {
508 return func(target, index, buffer);
509 }
510 else
511 {
512 return;
513 }
514}
515
516void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
517{
518 auto func = GLESSymbols::get().glBufferData;
519 if(func != nullptr)
520 {
521 return func(target, size, data, usage);
522 }
523 else
524 {
525 return;
526 }
527}
528
529void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint *buffers)
530{
531 auto func = GLESSymbols::get().glDeleteBuffers;
532 if(func != nullptr)
533 {
534 return func(n, buffers);
535 }
536 else
537 {
538 return;
539 }
540}
541
542void GL_APIENTRY glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
543{
544 auto func = GLESSymbols::get().glDispatchCompute;
545 if(func != nullptr)
546 {
547 return func(num_groups_x, num_groups_y, num_groups_z);
548 }
549 else
550 {
551 return;
552 }
553}
554
555void GL_APIENTRY glFlush(void)
556{
557 auto func = GLESSymbols::get().glFlush;
558 if(func != nullptr)
559 {
560 return func();
561 }
562 else
563 {
564 return;
565 }
566}
567
568void GL_APIENTRY glGenBuffers(GLsizei n, GLuint *buffers)
569{
570 auto func = GLESSymbols::get().glGenBuffers;
571 if(func != nullptr)
572 {
573 return func(n, buffers);
574 }
575 else
576 {
577 return;
578 }
579}
580
581GLuint GL_APIENTRY glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
582{
583 auto func = GLESSymbols::get().glGetProgramResourceIndex;
584 if(func != nullptr)
585 {
586 return func(program, programInterface, name);
587 }
588 else
589 {
590 return GL_INVALID_INDEX;
591 }
592}
593
594GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar *name)
595{
596 auto func = GLESSymbols::get().glGetUniformLocation;
597 if(func != nullptr)
598 {
599 return func(program, name);
600 }
601 else
602 {
603 return -1;
604 }
605}
606
607void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
608{
609 auto func = GLESSymbols::get().glMapBufferRange;
610 if(func != nullptr)
611 {
612 return func(target, offset, length, access);
613 }
614 else
615 {
616 return nullptr;
617 }
618}
619
620void GL_APIENTRY glMemoryBarrier(GLbitfield barriers)
621{
622 auto func = GLESSymbols::get().glMemoryBarrier;
623 if(func != nullptr)
624 {
625 return func(barriers);
626 }
627 else
628 {
629 return;
630 }
631}
632
633void GL_APIENTRY glUniform1ui(GLint location, GLuint v0)
634{
635 auto func = GLESSymbols::get().glUniform1ui;
636 if(func != nullptr)
637 {
638 return func(location, v0);
639 }
640 else
641 {
642 return;
643 }
644}
645
646GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)
647{
648 auto func = GLESSymbols::get().glUnmapBuffer;
649 if(func != nullptr)
650 {
651 return func(target);
652 }
653 else
654 {
655 return GL_FALSE;
656 }
657}
658
659GLenum GL_APIENTRY glGetError(void)
660{
661 auto func = GLESSymbols::get().glGetError;
662 if(func != nullptr)
663 {
664 return func();
665 }
666 else
667 {
668 return GL_NO_ERROR;
669 }
670}
671
Michele Di Giorgiob8fc60f2018-04-25 11:58:07 +0100672const GLubyte *GL_APIENTRY glGetString(GLenum name)
673{
674 auto func = GLESSymbols::get().glGetString;
675 if(func != nullptr)
676 {
677 return func(name);
678 }
679 else
680 {
681 return nullptr;
682 }
683}
684
Anthony Barbier7068f992017-10-26 15:23:08 +0100685void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)
686{
687 auto func = GLESSymbols::get().glGetActiveUniformBlockiv;
688 if(func != nullptr)
689 {
690 return func(program, uniformBlockIndex, pname, params);
691 }
692 else
693 {
694 return;
695 }
696}
697
698void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
699{
700 auto func = GLESSymbols::get().glUniformBlockBinding;
701 if(func != nullptr)
702 {
703 return func(program, uniformBlockIndex, uniformBlockBinding);
704 }
705 else
706 {
707 return;
708 }
709}
710
711GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
712{
713 auto func = GLESSymbols::get().glGetUniformBlockIndex;
714 if(func != nullptr)
715 {
716 return func(program, uniformBlockName);
717 }
718 else
719 {
720 return GL_INVALID_INDEX;
721 }
722}
723
724void GL_APIENTRY glGenTextures(GLsizei n, GLuint *textures)
725{
726 auto func = GLESSymbols::get().glGenTextures;
727 if(func != nullptr)
728 {
729 return func(n, textures);
730 }
731 else
732 {
733 return;
734 }
735}
736
737void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
738{
739 auto func = GLESSymbols::get().glDeleteTextures;
740 if(func != nullptr)
741 {
742 return func(n, textures);
743 }
744 else
745 {
746 return;
747 }
748}
749
750void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
751{
752 auto func = GLESSymbols::get().glBindTexture;
753 if(func != nullptr)
754 {
755 return func(target, texture);
756 }
757 else
758 {
759 return;
760 }
761}
762
763void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
764{
765 auto func = GLESSymbols::get().glTexImage2D;
766 if(func != nullptr)
767 {
768 return func(target, level, internalformat, width, height, border, format, type, pixels);
769 }
770 else
771 {
772 return;
773 }
774}
775
776void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers)
777{
778 auto func = GLESSymbols::get().glGenFramebuffers;
779 if(func != nullptr)
780 {
781 return func(n, framebuffers);
782 }
783 else
784 {
785 return;
786 }
787}
788
789void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
790{
791 auto func = GLESSymbols::get().glDeleteFramebuffers;
792 if(func != nullptr)
793 {
794 return func(n, framebuffers);
795 }
796 else
797 {
798 return;
799 }
800}
801
802void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
803{
804 auto func = GLESSymbols::get().glBindFramebuffer;
805 if(func != nullptr)
806 {
807 return func(target, framebuffer);
808 }
809 else
810 {
811 return;
812 }
813}
814
815void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
816{
817 auto func = GLESSymbols::get().glFramebufferTexture2D;
818 if(func != nullptr)
819 {
820 return func(target, attachment, textarget, texture, level);
821 }
822 else
823 {
824 return;
825 }
826}